mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1036981 - Update HarfBuzz to upstream commit d5e6147 (0.9.34). r=jfkthame
This commit is contained in:
parent
228d194059
commit
a2cc85f89e
@ -0,0 +1,9 @@
|
|||||||
|
Behdad Esfahbod
|
||||||
|
Simon Hausmann
|
||||||
|
Martin Hosken
|
||||||
|
Jonathan Kew
|
||||||
|
Lars Knoll
|
||||||
|
Werner Lemberg
|
||||||
|
Roozbeh Pournader
|
||||||
|
Owen Taylor
|
||||||
|
David Turner
|
@ -1,11 +1,16 @@
|
|||||||
HarfBuzz is licensed under the so-called "Old MIT" license. Details follow.
|
HarfBuzz is licensed under the so-called "Old MIT" license. Details follow.
|
||||||
|
For parts of HarfBuzz that are licensed under different licenses see individual
|
||||||
|
files names COPYING in subdirectories where applicable.
|
||||||
|
|
||||||
Copyright © 2011 Codethink Limited
|
Copyright © 2010,2011,2012 Google, Inc.
|
||||||
Copyright © 2010,2011 Google, Inc.
|
Copyright © 2012 Mozilla Foundation
|
||||||
Copyright © 2006 Behdad Esfahbod
|
Copyright © 2011 Codethink Limited
|
||||||
|
Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies)
|
||||||
Copyright © 2009 Keith Stribley
|
Copyright © 2009 Keith Stribley
|
||||||
Copyright © 2009 Martin Hosken and SIL International
|
Copyright © 2009 Martin Hosken and SIL International
|
||||||
Copyright © 2007 Chris Wilson
|
Copyright © 2007 Chris Wilson
|
||||||
|
Copyright © 2006 Behdad Esfahbod
|
||||||
|
Copyright © 2005 David Turner
|
||||||
Copyright © 2004,2007,2008,2009,2010 Red Hat, Inc.
|
Copyright © 2004,2007,2008,2009,2010 Red Hat, Inc.
|
||||||
Copyright © 1998-2004 David Turner and Werner Lemberg
|
Copyright © 1998-2004 David Turner and Werner Lemberg
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ HBSOURCES = \
|
|||||||
hb-object-private.hh \
|
hb-object-private.hh \
|
||||||
hb-open-file-private.hh \
|
hb-open-file-private.hh \
|
||||||
hb-open-type-private.hh \
|
hb-open-type-private.hh \
|
||||||
|
hb-ot-cmap-table.hh \
|
||||||
hb-ot-head-table.hh \
|
hb-ot-head-table.hh \
|
||||||
hb-ot-hhea-table.hh \
|
hb-ot-hhea-table.hh \
|
||||||
hb-ot-hmtx-table.hh \
|
hb-ot-hmtx-table.hh \
|
||||||
@ -51,7 +52,6 @@ HBSOURCES = \
|
|||||||
hb-shaper-impl-private.hh \
|
hb-shaper-impl-private.hh \
|
||||||
hb-shaper-private.hh \
|
hb-shaper-private.hh \
|
||||||
hb-shaper.cc \
|
hb-shaper.cc \
|
||||||
hb-tt-font.cc \
|
|
||||||
hb-unicode-private.hh \
|
hb-unicode-private.hh \
|
||||||
hb-unicode.cc \
|
hb-unicode.cc \
|
||||||
hb-utf-private.hh \
|
hb-utf-private.hh \
|
||||||
@ -76,6 +76,7 @@ HBNODISTHEADERS = \
|
|||||||
|
|
||||||
if HAVE_OT
|
if HAVE_OT
|
||||||
HBSOURCES += \
|
HBSOURCES += \
|
||||||
|
hb-ot-font.cc \
|
||||||
hb-ot-layout.cc \
|
hb-ot-layout.cc \
|
||||||
hb-ot-layout-common-private.hh \
|
hb-ot-layout-common-private.hh \
|
||||||
hb-ot-layout-gdef-table.hh \
|
hb-ot-layout-gdef-table.hh \
|
||||||
@ -90,6 +91,7 @@ HBSOURCES += \
|
|||||||
hb-ot-shape-complex-arabic.cc \
|
hb-ot-shape-complex-arabic.cc \
|
||||||
hb-ot-shape-complex-arabic-fallback.hh \
|
hb-ot-shape-complex-arabic-fallback.hh \
|
||||||
hb-ot-shape-complex-arabic-table.hh \
|
hb-ot-shape-complex-arabic-table.hh \
|
||||||
|
hb-ot-shape-complex-arabic-win1256.hh \
|
||||||
hb-ot-shape-complex-default.cc \
|
hb-ot-shape-complex-default.cc \
|
||||||
hb-ot-shape-complex-hangul.cc \
|
hb-ot-shape-complex-hangul.cc \
|
||||||
hb-ot-shape-complex-hebrew.cc \
|
hb-ot-shape-complex-hebrew.cc \
|
||||||
@ -112,6 +114,7 @@ HBSOURCES += \
|
|||||||
$(NULL)
|
$(NULL)
|
||||||
HBHEADERS += \
|
HBHEADERS += \
|
||||||
hb-ot.h \
|
hb-ot.h \
|
||||||
|
hb-ot-font.h \
|
||||||
hb-ot-layout.h \
|
hb-ot-layout.h \
|
||||||
hb-ot-shape.h \
|
hb-ot-shape.h \
|
||||||
hb-ot-tag.h \
|
hb-ot-tag.h \
|
||||||
@ -279,13 +282,14 @@ indic-table: gen-indic-table.py IndicSyllabicCategory.txt IndicMatraCategory.txt
|
|||||||
mv hb-ot-shape-complex-indic-table.cc.tmp $(srcdir)/hb-ot-shape-complex-indic-table.cc || \
|
mv hb-ot-shape-complex-indic-table.cc.tmp $(srcdir)/hb-ot-shape-complex-indic-table.cc || \
|
||||||
($(RM) hb-ot-shape-complex-indic-table.cc.tmp; false)
|
($(RM) hb-ot-shape-complex-indic-table.cc.tmp; false)
|
||||||
|
|
||||||
arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt
|
arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt
|
||||||
$(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-arabic-table.hh.tmp && \
|
$(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-arabic-table.hh.tmp && \
|
||||||
mv hb-ot-shape-complex-arabic-table.hh.tmp $(srcdir)/hb-ot-shape-complex-arabic-table.hh || \
|
mv hb-ot-shape-complex-arabic-table.hh.tmp $(srcdir)/hb-ot-shape-complex-arabic-table.hh || \
|
||||||
($(RM) hb-ot-shape-complex-arabic-table.hh.tmp; false)
|
($(RM) hb-ot-shape-complex-arabic-table.hh.tmp; false)
|
||||||
|
|
||||||
|
built-sources: $(BUILT_SOURCES)
|
||||||
|
|
||||||
.PHONY: unicode-tables arabic-table indic-table
|
.PHONY: unicode-tables arabic-table indic-table built-sources
|
||||||
|
|
||||||
BUILT_SOURCES += \
|
BUILT_SOURCES += \
|
||||||
hb-buffer-deserialize-json.hh \
|
hb-buffer-deserialize-json.hh \
|
||||||
@ -302,7 +306,7 @@ EXTRA_DIST += \
|
|||||||
hb-ot-shape-complex-sea-machine.rl \
|
hb-ot-shape-complex-sea-machine.rl \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
.rl.hh:
|
.rl.hh:
|
||||||
$(AM_V_GEN)$(top_srcdir)/missing --run ragel -e -F1 -o "$@.tmp" "$<" && \
|
$(AM_V_GEN)$(RAGEL) -e -F1 -o "$@.tmp" "$<" && \
|
||||||
mv "$@.tmp" "$@" || ( $(RM) "$@.tmp" && false )
|
mv "$@.tmp" "$@" || ( $(RM) "$@.tmp" && false )
|
||||||
|
|
||||||
noinst_PROGRAMS = \
|
noinst_PROGRAMS = \
|
||||||
@ -358,6 +362,7 @@ if HAVE_INTROSPECTION
|
|||||||
INTROSPECTION_GIRS = HarfBuzz-$(HB_VERSION_MAJOR).0.gir # What does the 0 mean anyway?!
|
INTROSPECTION_GIRS = HarfBuzz-$(HB_VERSION_MAJOR).0.gir # What does the 0 mean anyway?!
|
||||||
INTROSPECTION_SCANNER_ARGS = -I$(srcdir) -n hb --identifier-prefix=hb_ --warn-all
|
INTROSPECTION_SCANNER_ARGS = -I$(srcdir) -n hb --identifier-prefix=hb_ --warn-all
|
||||||
INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir)
|
INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir)
|
||||||
|
INTROSPECTION_SCANNER_ENV = CC="$(CC)"
|
||||||
|
|
||||||
HarfBuzz-0.0.gir: libharfbuzz.la libharfbuzz-gobject.la
|
HarfBuzz-0.0.gir: libharfbuzz.la libharfbuzz-gobject.la
|
||||||
HarfBuzz_0_0_gir_INCLUDES = GObject-2.0
|
HarfBuzz_0_0_gir_INCLUDES = GObject-2.0
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
LC_ALL=C
|
|
||||||
export LC_ALL
|
|
||||||
|
|
||||||
test -z "$srcdir" && srcdir=.
|
|
||||||
test -z "$MAKE" && MAKE=make
|
|
||||||
stat=0
|
|
||||||
|
|
||||||
if which nm 2>/dev/null >/dev/null; then
|
|
||||||
:
|
|
||||||
else
|
|
||||||
echo "check-exported-symbols.sh: 'nm' not found; skipping test"
|
|
||||||
exit 77
|
|
||||||
fi
|
|
||||||
|
|
||||||
defs="harfbuzz.def"
|
|
||||||
$MAKE $defs > /dev/null
|
|
||||||
tested=false
|
|
||||||
for def in $defs; do
|
|
||||||
lib=`echo "$def" | sed 's/[.]def$//;s@.*/@@'`
|
|
||||||
so=.libs/lib${lib}.so
|
|
||||||
if test -f "$so"; then
|
|
||||||
echo "Checking that $so has the same symbol list as $def"
|
|
||||||
{
|
|
||||||
echo EXPORTS
|
|
||||||
nm "$so" | grep ' [BCDGINRSTVW] ' | grep -v ' T _fini\>\| T _init\>\| __bss_start\>\| __bss_start__\>\| __bss_end__\>\| _edata\>\| _end\>\| _bss_end__\>\| __end__\>' | cut -d' ' -f3
|
|
||||||
stat=1
|
|
||||||
# cheat: copy the last line from the def file!
|
|
||||||
tail -n1 "$def"
|
|
||||||
} | diff "$def" - >&2 || stat=1
|
|
||||||
tested=true
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if ! $tested; then
|
|
||||||
echo "check-exported-symbols.sh: libharfbuzz shared library not found; skipping test"
|
|
||||||
exit 77
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit $stat
|
|
@ -27,7 +27,7 @@ echo 'Checking that source files #include "hb-*private.hh" first (or none)'
|
|||||||
|
|
||||||
for x in $HBSOURCES; do
|
for x in $HBSOURCES; do
|
||||||
test -f "$srcdir/$x" && x="$srcdir/$x"
|
test -f "$srcdir/$x" && x="$srcdir/$x"
|
||||||
grep '#.*\<include\>' "$x" /dev/null | head -n 1
|
grep '#.*\<include\>' "$x" /dev/null | grep -v 'include _' | head -n 1
|
||||||
done |
|
done |
|
||||||
grep -v '"hb-.*private[.]hh"' |
|
grep -v '"hb-.*private[.]hh"' |
|
||||||
grep -v 'hb-private[.]hh:' |
|
grep -v 'hb-private[.]hh:' |
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
LC_ALL=C
|
|
||||||
export LC_ALL
|
|
||||||
|
|
||||||
test -z "$srcdir" && srcdir=.
|
|
||||||
stat=0
|
|
||||||
|
|
||||||
|
|
||||||
if which nm 2>/dev/null >/dev/null; then
|
|
||||||
:
|
|
||||||
else
|
|
||||||
echo "check-internal-symbols.sh: 'nm' not found; skipping test"
|
|
||||||
exit 77
|
|
||||||
fi
|
|
||||||
|
|
||||||
tested=false
|
|
||||||
for suffix in .so; do
|
|
||||||
so=`echo .libs/libharfbuzz$suffix`
|
|
||||||
if test -f "$so"; then
|
|
||||||
echo "Checking that we are not exposing internal symbols"
|
|
||||||
if nm "$so" | grep ' [BCDGINRSTVW] ' | grep -v ' T _fini\>\| T _init\>\| T hb_\| __bss_start\>\| __bss_start__\>\| __bss_end__\>\| _edata\>\| _end\>\| _bss_end__\>\| __end__\>'; then
|
|
||||||
echo "Ouch, internal symbols exposed"
|
|
||||||
stat=1
|
|
||||||
fi
|
|
||||||
tested=true
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if ! $tested; then
|
|
||||||
echo "check-internal-symbols.sh: libharfbuzz shared library not found; skipping test"
|
|
||||||
exit 77
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit $stat
|
|
@ -30,7 +30,7 @@ done
|
|||||||
|
|
||||||
echo "Checking that no object file has lazy static C++ constructors/destructors or other such stuff"
|
echo "Checking that no object file has lazy static C++ constructors/destructors or other such stuff"
|
||||||
for obj in $OBJS; do
|
for obj in $OBJS; do
|
||||||
if objdump -t "$obj" | grep '__c'; then
|
if objdump -t "$obj" | grep '__cxa_'; then
|
||||||
echo "Ouch, $obj has lazy static C++ constructors/destructors or other such stuff"
|
echo "Ouch, $obj has lazy static C++ constructors/destructors or other such stuff"
|
||||||
stat=1
|
stat=1
|
||||||
fi
|
fi
|
||||||
|
@ -18,7 +18,7 @@ echo "Checking that we are not exposing internal symbols"
|
|||||||
tested=false
|
tested=false
|
||||||
for so in `ls .libs/lib*.so .libs/lib*.dylib 2>/dev/null` ; do
|
for so in `ls .libs/lib*.so .libs/lib*.dylib 2>/dev/null` ; do
|
||||||
|
|
||||||
EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRSTVW] ' | grep -v ' _fini\>\| _init\>\| _fdata\>\| _ftext\>\| __bss_start\>\| __bss_start__\>\| __bss_end__\>\| _edata\>\| _end\>\| _bss_end__\>\| __end__\>' | cut -d' ' -f3`"
|
EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRSTVW] ' | grep -v ' _fini\>\| _init\>\| _fdata\>\| _ftext\>\| _fbss\>\| __bss_start\>\| __bss_start__\>\| __bss_end__\>\| _edata\>\| _end\>\| _bss_end__\>\| __end__\>' | cut -d' ' -f3`"
|
||||||
prefix=`basename "$so" | sed 's/libharfbuzz/hb/; s/-/_/g; s/[.].*//'`
|
prefix=`basename "$so" | sed 's/libharfbuzz/hb/; s/-/_/g; s/[.].*//'`
|
||||||
|
|
||||||
echo "Processing $so"
|
echo "Processing $so"
|
||||||
|
@ -3,34 +3,48 @@
|
|||||||
import sys
|
import sys
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
if len (sys.argv) != 3:
|
if len (sys.argv) != 4:
|
||||||
print >>sys.stderr, "usage: ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt"
|
print >>sys.stderr, "usage: ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt"
|
||||||
sys.exit (1)
|
sys.exit (1)
|
||||||
|
|
||||||
files = [file (x) for x in sys.argv[1:]]
|
files = [file (x) for x in sys.argv[1:]]
|
||||||
|
|
||||||
headers = [[files[0].readline (), files[0].readline ()]]
|
headers = [[files[0].readline (), files[0].readline ()], [files[2].readline (), files[2].readline ()]]
|
||||||
headers.append (["UnicodeData.txt does not have a header."])
|
headers.append (["UnicodeData.txt does not have a header."])
|
||||||
while files[0].readline ().find ('##################') < 0:
|
while files[0].readline ().find ('##################') < 0:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
blocks = {}
|
||||||
|
def read_blocks(f):
|
||||||
|
global blocks
|
||||||
|
for line in f:
|
||||||
|
|
||||||
|
j = line.find ('#')
|
||||||
|
if j >= 0:
|
||||||
|
line = line[:j]
|
||||||
|
|
||||||
|
fields = [x.strip () for x in line.split (';')]
|
||||||
|
if len (fields) == 1:
|
||||||
|
continue
|
||||||
|
|
||||||
|
uu = fields[0].split ('..')
|
||||||
|
start = int (uu[0], 16)
|
||||||
|
if len (uu) == 1:
|
||||||
|
end = start
|
||||||
|
else:
|
||||||
|
end = int (uu[1], 16)
|
||||||
|
|
||||||
|
t = fields[1]
|
||||||
|
|
||||||
|
for u in range (start, end + 1):
|
||||||
|
blocks[u] = t
|
||||||
|
|
||||||
def print_joining_table(f):
|
def print_joining_table(f):
|
||||||
|
|
||||||
print
|
values = {}
|
||||||
print "static const uint8_t joining_table[] ="
|
|
||||||
print "{"
|
|
||||||
|
|
||||||
min_u = 0x110000
|
|
||||||
max_u = 0
|
|
||||||
num = 0
|
|
||||||
last = -1
|
|
||||||
block = ''
|
|
||||||
for line in f:
|
for line in f:
|
||||||
|
|
||||||
if line[0] == '#':
|
if line[0] == '#':
|
||||||
if line.find (" characters"):
|
|
||||||
block = line[2:].strip ()
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
fields = [x.strip () for x in line.split (';')]
|
fields = [x.strip () for x in line.split (';')]
|
||||||
@ -38,43 +52,100 @@ def print_joining_table(f):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
u = int (fields[0], 16)
|
u = int (fields[0], 16)
|
||||||
if u == 0x200C or u == 0x200D:
|
|
||||||
continue
|
|
||||||
if u < last:
|
|
||||||
raise Exception ("Input data character not sorted", u)
|
|
||||||
min_u = min (min_u, u)
|
|
||||||
max_u = max (max_u, u)
|
|
||||||
num += 1
|
|
||||||
|
|
||||||
if block:
|
|
||||||
print "\n /* %s */\n" % block
|
|
||||||
block = ''
|
|
||||||
|
|
||||||
if last != -1:
|
|
||||||
last += 1
|
|
||||||
while last < u:
|
|
||||||
print " JOINING_TYPE_X, /* %04X */" % last
|
|
||||||
last += 1
|
|
||||||
else:
|
|
||||||
last = u
|
|
||||||
|
|
||||||
if fields[3] in ["ALAPH", "DALATH RISH"]:
|
if fields[3] in ["ALAPH", "DALATH RISH"]:
|
||||||
value = "JOINING_GROUP_" + fields[3].replace(' ', '_')
|
value = "JOINING_GROUP_" + fields[3].replace(' ', '_')
|
||||||
else:
|
else:
|
||||||
value = "JOINING_TYPE_" + fields[2]
|
value = "JOINING_TYPE_" + fields[2]
|
||||||
print " %s, /* %s */" % (value, '; '.join(fields))
|
values[u] = value
|
||||||
|
|
||||||
|
short_value = {}
|
||||||
|
for value in set([v for v in values.values()] + ['JOINING_TYPE_X']):
|
||||||
|
short = ''.join(x[0] for x in value.split('_')[2:])
|
||||||
|
assert short not in short_value.values()
|
||||||
|
short_value[value] = short
|
||||||
|
|
||||||
print
|
print
|
||||||
print "};"
|
for value,short in short_value.items():
|
||||||
|
print "#define %s %s" % (short, value)
|
||||||
|
|
||||||
|
uu = sorted(values.keys())
|
||||||
|
num = len(values)
|
||||||
|
all_blocks = set([blocks[u] for u in uu])
|
||||||
|
|
||||||
|
last = -100000
|
||||||
|
ranges = []
|
||||||
|
for u in uu:
|
||||||
|
if u - last <= 1+16*5:
|
||||||
|
ranges[-1][-1] = u
|
||||||
|
else:
|
||||||
|
ranges.append([u,u])
|
||||||
|
last = u
|
||||||
|
|
||||||
print
|
print
|
||||||
print "#define JOINING_TABLE_FIRST 0x%04X" % min_u
|
print "static const uint8_t joining_table[] ="
|
||||||
print "#define JOINING_TABLE_LAST 0x%04X" % max_u
|
print "{"
|
||||||
|
last_block = None
|
||||||
|
offset = 0
|
||||||
|
for start,end in ranges:
|
||||||
|
|
||||||
|
print
|
||||||
|
print "#define joining_offset_0x%04xu %d" % (start, offset)
|
||||||
|
|
||||||
|
for u in range(start, end+1):
|
||||||
|
|
||||||
|
block = blocks.get(u, last_block)
|
||||||
|
value = values.get(u, "JOINING_TYPE_X")
|
||||||
|
|
||||||
|
if block != last_block or u == start:
|
||||||
|
if u != start:
|
||||||
|
print
|
||||||
|
if block in all_blocks:
|
||||||
|
print "\n /* %s */" % block
|
||||||
|
else:
|
||||||
|
print "\n /* FILLER */"
|
||||||
|
last_block = block
|
||||||
|
if u % 32 != 0:
|
||||||
|
print
|
||||||
|
print " /* %04X */" % (u//32*32), " " * (u % 32),
|
||||||
|
|
||||||
|
if u % 32 == 0:
|
||||||
|
print
|
||||||
|
print " /* %04X */ " % u,
|
||||||
|
sys.stdout.write("%s," % short_value[value])
|
||||||
|
print
|
||||||
|
|
||||||
|
offset += end - start + 1
|
||||||
|
print
|
||||||
|
occupancy = num * 100. / offset
|
||||||
|
print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy)
|
||||||
print
|
print
|
||||||
|
|
||||||
occupancy = num * 100 / (max_u - min_u + 1)
|
page_bits = 12;
|
||||||
# Maintain at least 40% occupancy in the table */
|
print
|
||||||
if occupancy < 40:
|
print "static unsigned int"
|
||||||
raise Exception ("Table too sparse, please investigate: ", occupancy)
|
print "joining_type (hb_codepoint_t u)"
|
||||||
|
print "{"
|
||||||
|
print " switch (u >> %d)" % page_bits
|
||||||
|
print " {"
|
||||||
|
pages = set([u>>page_bits for u in [s for s,e in ranges]+[e for s,e in ranges]])
|
||||||
|
for p in sorted(pages):
|
||||||
|
print " case 0x%0Xu:" % p
|
||||||
|
for (start,end) in ranges:
|
||||||
|
if p not in [start>>page_bits, end>>page_bits]: continue
|
||||||
|
offset = "joining_offset_0x%04xu" % start
|
||||||
|
print " if (hb_in_range (u, 0x%04Xu, 0x%04Xu)) return joining_table[u - 0x%04Xu + %s];" % (start, end, start, offset)
|
||||||
|
print " break;"
|
||||||
|
print ""
|
||||||
|
print " default:"
|
||||||
|
print " break;"
|
||||||
|
print " }"
|
||||||
|
print " return X;"
|
||||||
|
print "}"
|
||||||
|
print
|
||||||
|
for value,short in short_value.items():
|
||||||
|
print "#undef %s" % (short)
|
||||||
|
print
|
||||||
|
|
||||||
def print_shaping_table(f):
|
def print_shaping_table(f):
|
||||||
|
|
||||||
@ -124,13 +195,13 @@ def print_shaping_table(f):
|
|||||||
for u in range (min_u, max_u + 1):
|
for u in range (min_u, max_u + 1):
|
||||||
s = [shapes[u][shape] if u in shapes and shape in shapes[u] else 0
|
s = [shapes[u][shape] if u in shapes and shape in shapes[u] else 0
|
||||||
for shape in ['initial', 'medial', 'final', 'isolated']]
|
for shape in ['initial', 'medial', 'final', 'isolated']]
|
||||||
value = ', '.join ("0x%04X" % c for c in s)
|
value = ', '.join ("0x%04Xu" % c for c in s)
|
||||||
print " {%s}, /* U+%04X %s */" % (value, u, names[u] if u in names else "")
|
print " {%s}, /* U+%04X %s */" % (value, u, names[u] if u in names else "")
|
||||||
|
|
||||||
print "};"
|
print "};"
|
||||||
print
|
print
|
||||||
print "#define SHAPING_TABLE_FIRST 0x%04X" % min_u
|
print "#define SHAPING_TABLE_FIRST 0x%04Xu" % min_u
|
||||||
print "#define SHAPING_TABLE_LAST 0x%04X" % max_u
|
print "#define SHAPING_TABLE_LAST 0x%04Xu" % max_u
|
||||||
print
|
print
|
||||||
|
|
||||||
ligas = {}
|
ligas = {}
|
||||||
@ -160,9 +231,9 @@ def print_shaping_table(f):
|
|||||||
keys.sort ()
|
keys.sort ()
|
||||||
for first in keys:
|
for first in keys:
|
||||||
|
|
||||||
print " { 0x%04X, {" % (first)
|
print " { 0x%04Xu, {" % (first)
|
||||||
for liga in ligas[first]:
|
for liga in ligas[first]:
|
||||||
print " { 0x%04X, 0x%04X }, /* %s */" % (liga[0], liga[1], names[liga[1]])
|
print " { 0x%04Xu, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]])
|
||||||
print " }},"
|
print " }},"
|
||||||
|
|
||||||
print "};"
|
print "};"
|
||||||
@ -174,7 +245,7 @@ print "/* == Start of generated table == */"
|
|||||||
print "/*"
|
print "/*"
|
||||||
print " * The following table is generated by running:"
|
print " * The following table is generated by running:"
|
||||||
print " *"
|
print " *"
|
||||||
print " * ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt"
|
print " * ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt"
|
||||||
print " *"
|
print " *"
|
||||||
print " * on files with these headers:"
|
print " * on files with these headers:"
|
||||||
print " *"
|
print " *"
|
||||||
@ -187,6 +258,7 @@ print "#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH"
|
|||||||
print "#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH"
|
print "#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH"
|
||||||
print
|
print
|
||||||
|
|
||||||
|
read_blocks (files[2])
|
||||||
print_joining_table (files[0])
|
print_joining_table (files[0])
|
||||||
print_shaping_table (files[1])
|
print_shaping_table (files[1])
|
||||||
|
|
||||||
|
@ -6,11 +6,12 @@ if len (sys.argv) != 4:
|
|||||||
print >>sys.stderr, "usage: ./gen-indic-table.py IndicSyllabicCategory.txt IndicMatraCategory.txt Blocks.txt"
|
print >>sys.stderr, "usage: ./gen-indic-table.py IndicSyllabicCategory.txt IndicMatraCategory.txt Blocks.txt"
|
||||||
sys.exit (1)
|
sys.exit (1)
|
||||||
|
|
||||||
|
BLACKLISTED_BLOCKS = ["Thai", "Lao", "Tibetan"]
|
||||||
|
|
||||||
files = [file (x) for x in sys.argv[1:]]
|
files = [file (x) for x in sys.argv[1:]]
|
||||||
|
|
||||||
headers = [[f.readline () for i in range (2)] for f in files]
|
headers = [[f.readline () for i in range (2)] for f in files]
|
||||||
|
|
||||||
blocks = {}
|
|
||||||
data = [{} for f in files]
|
data = [{} for f in files]
|
||||||
values = [{} for f in files]
|
values = [{} for f in files]
|
||||||
for i, f in enumerate (files):
|
for i, f in enumerate (files):
|
||||||
@ -35,10 +36,7 @@ for i, f in enumerate (files):
|
|||||||
|
|
||||||
for u in range (start, end + 1):
|
for u in range (start, end + 1):
|
||||||
data[i][u] = t
|
data[i][u] = t
|
||||||
values[i][t] = values[i].get (t, 0) + 1
|
values[i][t] = values[i].get (t, 0) + end - start + 1
|
||||||
|
|
||||||
if i == 2:
|
|
||||||
blocks[t] = (start, end)
|
|
||||||
|
|
||||||
# Merge data into one dict:
|
# Merge data into one dict:
|
||||||
defaults = ('Other', 'Not_Applicable', 'No_Block')
|
defaults = ('Other', 'Not_Applicable', 'No_Block')
|
||||||
@ -52,10 +50,15 @@ for i,d in enumerate (data):
|
|||||||
if not u in combined:
|
if not u in combined:
|
||||||
combined[u] = list (defaults)
|
combined[u] = list (defaults)
|
||||||
combined[u][i] = v
|
combined[u][i] = v
|
||||||
|
combined = {k:v for k,v in combined.items() if v[2] not in BLACKLISTED_BLOCKS}
|
||||||
data = combined
|
data = combined
|
||||||
del combined
|
del combined
|
||||||
num = len (data)
|
num = len (data)
|
||||||
|
|
||||||
|
for u in [0x17CD, 0x17CE, 0x17CF, 0x17D0, 0x17D3]:
|
||||||
|
if data[u][0] == 'Other':
|
||||||
|
data[u][0] = "Vowel_Dependent"
|
||||||
|
|
||||||
# Move the outliers NO-BREAK SPACE and DOTTED CIRCLE out
|
# Move the outliers NO-BREAK SPACE and DOTTED CIRCLE out
|
||||||
singles = {}
|
singles = {}
|
||||||
for u in [0x00A0, 0x25CC]:
|
for u in [0x00A0, 0x25CC]:
|
||||||
@ -81,6 +84,10 @@ print
|
|||||||
# Shorten values
|
# Shorten values
|
||||||
short = [{
|
short = [{
|
||||||
"Bindu": 'Bi',
|
"Bindu": 'Bi',
|
||||||
|
"Cantillation_Mark": 'Ca',
|
||||||
|
"Joiner": 'ZWJ',
|
||||||
|
"Non_Joiner": 'ZWNJ',
|
||||||
|
"Number": 'Nd',
|
||||||
"Visarga": 'Vs',
|
"Visarga": 'Vs',
|
||||||
"Vowel": 'Vo',
|
"Vowel": 'Vo',
|
||||||
"Vowel_Dependent": 'M',
|
"Vowel_Dependent": 'M',
|
||||||
@ -88,14 +95,14 @@ short = [{
|
|||||||
},{
|
},{
|
||||||
"Not_Applicable": 'x',
|
"Not_Applicable": 'x',
|
||||||
}]
|
}]
|
||||||
all_shorts = [[],[]]
|
all_shorts = [{},{}]
|
||||||
|
|
||||||
# Add some of the values, to make them more readable, and to avoid duplicates
|
# Add some of the values, to make them more readable, and to avoid duplicates
|
||||||
|
|
||||||
|
|
||||||
for i in range (2):
|
for i in range (2):
|
||||||
for v,s in short[i].items ():
|
for v,s in short[i].items ():
|
||||||
all_shorts[i].append (s)
|
all_shorts[i][s] = v
|
||||||
|
|
||||||
what = ["INDIC_SYLLABIC_CATEGORY", "INDIC_MATRA_CATEGORY"]
|
what = ["INDIC_SYLLABIC_CATEGORY", "INDIC_MATRA_CATEGORY"]
|
||||||
what_short = ["ISC", "IMC"]
|
what_short = ["ISC", "IMC"]
|
||||||
@ -110,8 +117,8 @@ for i in range (2):
|
|||||||
else:
|
else:
|
||||||
s = ''.join ([c for c in v_no_and if ord ('A') <= ord (c) <= ord ('Z')])
|
s = ''.join ([c for c in v_no_and if ord ('A') <= ord (c) <= ord ('Z')])
|
||||||
if s in all_shorts[i]:
|
if s in all_shorts[i]:
|
||||||
raise Exception ("Duplicate short value alias", v, s)
|
raise Exception ("Duplicate short value alias", v, all_shorts[i][s])
|
||||||
all_shorts[i].append (s)
|
all_shorts[i][s] = v
|
||||||
short[i][v] = s
|
short[i][v] = s
|
||||||
print "#define %s_%s %s_%s %s/* %3d chars; %s */" % \
|
print "#define %s_%s %s_%s %s/* %3d chars; %s */" % \
|
||||||
(what_short[i], s, what[i], v.upper (), \
|
(what_short[i], s, what[i], v.upper (), \
|
||||||
@ -124,11 +131,16 @@ print
|
|||||||
|
|
||||||
total = 0
|
total = 0
|
||||||
used = 0
|
used = 0
|
||||||
|
last_block = None
|
||||||
def print_block (block, start, end, data):
|
def print_block (block, start, end, data):
|
||||||
print
|
global total, used, last_block
|
||||||
print
|
if block and block != last_block:
|
||||||
print " /* %s (%04X..%04X) */" % (block, start, end)
|
print
|
||||||
|
print
|
||||||
|
print " /* %s */" % block
|
||||||
num = 0
|
num = 0
|
||||||
|
assert start % 8 == 0
|
||||||
|
assert (end+1) % 8 == 0
|
||||||
for u in range (start, end+1):
|
for u in range (start, end+1):
|
||||||
if u % 8 == 0:
|
if u % 8 == 0:
|
||||||
print
|
print
|
||||||
@ -138,14 +150,15 @@ def print_block (block, start, end, data):
|
|||||||
d = data.get (u, defaults)
|
d = data.get (u, defaults)
|
||||||
sys.stdout.write ("%9s" % ("_(%s,%s)," % (short[0][d[0]], short[1][d[1]])))
|
sys.stdout.write ("%9s" % ("_(%s,%s)," % (short[0][d[0]], short[1][d[1]])))
|
||||||
|
|
||||||
global total, used
|
|
||||||
total += end - start + 1
|
total += end - start + 1
|
||||||
used += num
|
used += num
|
||||||
|
if block:
|
||||||
|
last_block = block
|
||||||
|
|
||||||
uu = data.keys ()
|
uu = data.keys ()
|
||||||
uu.sort ()
|
uu.sort ()
|
||||||
|
|
||||||
last = -1
|
last = -100000
|
||||||
num = 0
|
num = 0
|
||||||
offset = 0
|
offset = 0
|
||||||
starts = []
|
starts = []
|
||||||
@ -155,11 +168,16 @@ for u in uu:
|
|||||||
if u <= last:
|
if u <= last:
|
||||||
continue
|
continue
|
||||||
block = data[u][2]
|
block = data[u][2]
|
||||||
(start, end) = blocks[block]
|
|
||||||
|
start = u//8*8
|
||||||
|
end = start+1
|
||||||
|
while end in uu and block == data[end][2]:
|
||||||
|
end += 1
|
||||||
|
end = (end-1)//8*8 + 7
|
||||||
|
|
||||||
if start != last + 1:
|
if start != last + 1:
|
||||||
if start - last <= 33:
|
if start - last <= 1+16*3:
|
||||||
print_block ("FILLER", last+1, start-1, data)
|
print_block (None, last+1, start-1, data)
|
||||||
last = start-1
|
last = start-1
|
||||||
else:
|
else:
|
||||||
if last >= 0:
|
if last >= 0:
|
||||||
@ -167,7 +185,7 @@ for u in uu:
|
|||||||
offset += ends[-1] - starts[-1]
|
offset += ends[-1] - starts[-1]
|
||||||
print
|
print
|
||||||
print
|
print
|
||||||
print "#define indic_offset_0x%04x %d" % (start, offset)
|
print "#define indic_offset_0x%04xu %d" % (start, offset)
|
||||||
starts.append (start)
|
starts.append (start)
|
||||||
|
|
||||||
print_block (block, start, end, data)
|
print_block (block, start, end, data)
|
||||||
@ -176,19 +194,30 @@ ends.append (last + 1)
|
|||||||
offset += ends[-1] - starts[-1]
|
offset += ends[-1] - starts[-1]
|
||||||
print
|
print
|
||||||
print
|
print
|
||||||
print "#define indic_offset_total %d" % offset
|
|
||||||
print
|
|
||||||
occupancy = used * 100. / total
|
occupancy = used * 100. / total
|
||||||
print "}; /* Table occupancy: %d%% */" % occupancy
|
page_bits = 12
|
||||||
|
print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy)
|
||||||
print
|
print
|
||||||
print "INDIC_TABLE_ELEMENT_TYPE"
|
print "INDIC_TABLE_ELEMENT_TYPE"
|
||||||
print "hb_indic_get_categories (hb_codepoint_t u)"
|
print "hb_indic_get_categories (hb_codepoint_t u)"
|
||||||
print "{"
|
print "{"
|
||||||
for (start,end) in zip (starts, ends):
|
print " switch (u >> %d)" % page_bits
|
||||||
offset = "indic_offset_0x%04x" % start
|
print " {"
|
||||||
print " if (0x%04X <= u && u <= 0x%04X) return indic_table[u - 0x%04X + %s];" % (start, end, start, offset)
|
pages = set([u>>page_bits for u in starts+ends+singles.keys()])
|
||||||
for u,d in singles.items ():
|
for p in sorted(pages):
|
||||||
print " if (unlikely (u == 0x%04X)) return _(%s,%s);" % (u, short[0][d[0]], short[1][d[1]])
|
print " case 0x%0Xu:" % p
|
||||||
|
for (start,end) in zip (starts, ends):
|
||||||
|
if p not in [start>>page_bits, end>>page_bits]: continue
|
||||||
|
offset = "indic_offset_0x%04xu" % start
|
||||||
|
print " if (hb_in_range (u, 0x%04Xu, 0x%04Xu)) return indic_table[u - 0x%04Xu + %s];" % (start, end, start, offset)
|
||||||
|
for u,d in singles.items ():
|
||||||
|
if p != u>>page_bits: continue
|
||||||
|
print " if (unlikely (u == 0x%04Xu)) return _(%s,%s);" % (u, short[0][d[0]], short[1][d[1]])
|
||||||
|
print " break;"
|
||||||
|
print ""
|
||||||
|
print " default:"
|
||||||
|
print " break;"
|
||||||
|
print " }"
|
||||||
print " return _(x,x);"
|
print " return _(x,x);"
|
||||||
print "}"
|
print "}"
|
||||||
print
|
print
|
||||||
|
@ -44,21 +44,24 @@
|
|||||||
|
|
||||||
#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
|
#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#if defined(__MINGW32__) && !defined(MemoryBarrier)
|
/* MinGW has a convoluted history of supporting MemoryBarrier
|
||||||
|
* properly. As such, define a function to wrap the whole
|
||||||
|
* thing. */
|
||||||
static inline void _HBMemoryBarrier (void) {
|
static inline void _HBMemoryBarrier (void) {
|
||||||
|
#if !defined(MemoryBarrier)
|
||||||
long dummy = 0;
|
long dummy = 0;
|
||||||
InterlockedExchange (&dummy, 1);
|
InterlockedExchange (&dummy, 1);
|
||||||
}
|
#else
|
||||||
# define MemoryBarrier _HBMemoryBarrier
|
MemoryBarrier ();
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
typedef LONG hb_atomic_int_t;
|
typedef LONG hb_atomic_int_t;
|
||||||
#define hb_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V))
|
#define hb_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V))
|
||||||
|
|
||||||
#define hb_atomic_ptr_get(P) (MemoryBarrier (), (void *) *(P))
|
#define hb_atomic_ptr_get(P) (_HBMemoryBarrier (), (void *) *(P))
|
||||||
#define hb_atomic_ptr_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
|
#define hb_atomic_ptr_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
|
||||||
|
|
||||||
|
|
||||||
@ -78,7 +81,7 @@ typedef int32_t hb_atomic_int_t;
|
|||||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100)
|
#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100)
|
||||||
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
|
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
|
||||||
#else
|
#else
|
||||||
#if __ppc64__ || __x86_64__ || __arm64__
|
#if __ppc64__ || __x86_64__ || __aarch64__
|
||||||
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
|
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
|
||||||
#else
|
#else
|
||||||
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))
|
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))
|
||||||
|
@ -25,7 +25,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* http://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html */
|
/* http://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html */
|
||||||
|
#ifndef _POSIX_C_SOURCE
|
||||||
#define _POSIX_C_SOURCE 199309L
|
#define _POSIX_C_SOURCE 199309L
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "hb-private.hh"
|
#include "hb-private.hh"
|
||||||
|
|
||||||
|
@ -47,14 +47,13 @@ HB_BEGIN_DECLS
|
|||||||
* - Use MODE_READONLY otherse, unless you really really
|
* - Use MODE_READONLY otherse, unless you really really
|
||||||
* really know what you are doing,
|
* really know what you are doing,
|
||||||
*
|
*
|
||||||
* - MODE_WRITABLE is appropriate if you relaly made a
|
* - MODE_WRITABLE is appropriate if you really made a
|
||||||
* copy of data solely for the purpose of passing to
|
* copy of data solely for the purpose of passing to
|
||||||
* HarfBuzz and doing that just once (no reuse!),
|
* HarfBuzz and doing that just once (no reuse!),
|
||||||
*
|
*
|
||||||
* - If the font is mmap()ed, it's ok to use
|
* - If the font is mmap()ed, it's ok to use
|
||||||
* READONLY_MAY_MAKE_WRITABLE, however, there were
|
* READONLY_MAY_MAKE_WRITABLE, however, using that mode
|
||||||
* design problems with that mode, so HarfBuzz do not
|
* correctly is very tricky. Use MODE_READONLY instead.
|
||||||
* really use it anymore. If not sure, use MODE_READONLY.
|
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
HB_MEMORY_MODE_DUPLICATE,
|
HB_MEMORY_MODE_DUPLICATE,
|
||||||
|
@ -52,6 +52,7 @@ struct hb_buffer_t {
|
|||||||
hb_unicode_funcs_t *unicode; /* Unicode functions */
|
hb_unicode_funcs_t *unicode; /* Unicode functions */
|
||||||
hb_segment_properties_t props; /* Script, language, direction */
|
hb_segment_properties_t props; /* Script, language, direction */
|
||||||
hb_buffer_flags_t flags; /* BOT / EOT / etc. */
|
hb_buffer_flags_t flags; /* BOT / EOT / etc. */
|
||||||
|
hb_codepoint_t replacement; /* U+FFFD or something else. */
|
||||||
|
|
||||||
/* Buffer contents */
|
/* Buffer contents */
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ hb_buffer_serialize_format_t
|
|||||||
hb_buffer_serialize_format_from_string (const char *str, int len)
|
hb_buffer_serialize_format_from_string (const char *str, int len)
|
||||||
{
|
{
|
||||||
/* Upper-case it. */
|
/* Upper-case it. */
|
||||||
return (hb_buffer_serialize_format_t) (hb_tag_from_string (str, len) & ~0x20202020);
|
return (hb_buffer_serialize_format_t) (hb_tag_from_string (str, len) & ~0x20202020u);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -178,6 +178,7 @@ hb_buffer_t::reset (void)
|
|||||||
|
|
||||||
hb_unicode_funcs_destroy (unicode);
|
hb_unicode_funcs_destroy (unicode);
|
||||||
unicode = hb_unicode_funcs_get_default ();
|
unicode = hb_unicode_funcs_get_default ();
|
||||||
|
replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
|
||||||
|
|
||||||
clear ();
|
clear ();
|
||||||
}
|
}
|
||||||
@ -500,6 +501,10 @@ void
|
|||||||
hb_buffer_t::merge_clusters (unsigned int start,
|
hb_buffer_t::merge_clusters (unsigned int start,
|
||||||
unsigned int end)
|
unsigned int end)
|
||||||
{
|
{
|
||||||
|
#ifdef HB_NO_MERGE_CLUSTERS
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (unlikely (end - start < 2))
|
if (unlikely (end - start < 2))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -528,6 +533,10 @@ void
|
|||||||
hb_buffer_t::merge_out_clusters (unsigned int start,
|
hb_buffer_t::merge_out_clusters (unsigned int start,
|
||||||
unsigned int end)
|
unsigned int end)
|
||||||
{
|
{
|
||||||
|
#ifdef HB_NO_MERGE_CLUSTERS
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (unlikely (end - start < 2))
|
if (unlikely (end - start < 2))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -695,6 +704,7 @@ hb_buffer_get_empty (void)
|
|||||||
const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil),
|
const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil),
|
||||||
HB_SEGMENT_PROPERTIES_DEFAULT,
|
HB_SEGMENT_PROPERTIES_DEFAULT,
|
||||||
HB_BUFFER_FLAG_DEFAULT,
|
HB_BUFFER_FLAG_DEFAULT,
|
||||||
|
HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT,
|
||||||
|
|
||||||
HB_BUFFER_CONTENT_TYPE_INVALID,
|
HB_BUFFER_CONTENT_TYPE_INVALID,
|
||||||
true, /* in_error */
|
true, /* in_error */
|
||||||
@ -1039,6 +1049,42 @@ hb_buffer_get_flags (hb_buffer_t *buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hb_buffer_set_replacement_codepoint:
|
||||||
|
* @buffer: a buffer.
|
||||||
|
* @replacement:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer,
|
||||||
|
hb_codepoint_t replacement)
|
||||||
|
{
|
||||||
|
if (unlikely (hb_object_is_inert (buffer)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
buffer->replacement = replacement;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hb_buffer_get_replacement_codepoint:
|
||||||
|
* @buffer: a buffer.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
**/
|
||||||
|
hb_codepoint_t
|
||||||
|
hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer)
|
||||||
|
{
|
||||||
|
return buffer->replacement;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hb_buffer_reset:
|
* hb_buffer_reset:
|
||||||
* @buffer: a buffer.
|
* @buffer: a buffer.
|
||||||
@ -1282,7 +1328,7 @@ hb_buffer_guess_segment_properties (hb_buffer_t *buffer)
|
|||||||
buffer->guess_segment_properties ();
|
buffer->guess_segment_properties ();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <bool validate, typename T>
|
||||||
static inline void
|
static inline void
|
||||||
hb_buffer_add_utf (hb_buffer_t *buffer,
|
hb_buffer_add_utf (hb_buffer_t *buffer,
|
||||||
const T *text,
|
const T *text,
|
||||||
@ -1290,6 +1336,9 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
|
|||||||
unsigned int item_offset,
|
unsigned int item_offset,
|
||||||
int item_length)
|
int item_length)
|
||||||
{
|
{
|
||||||
|
typedef hb_utf_t<T, true> utf_t;
|
||||||
|
const hb_codepoint_t replacement = buffer->replacement;
|
||||||
|
|
||||||
assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
|
assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
|
||||||
(!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
|
(!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
|
||||||
|
|
||||||
@ -1297,7 +1346,7 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (text_length == -1)
|
if (text_length == -1)
|
||||||
text_length = hb_utf_strlen (text);
|
text_length = utf_t::strlen (text);
|
||||||
|
|
||||||
if (item_length == -1)
|
if (item_length == -1)
|
||||||
item_length = text_length - item_offset;
|
item_length = text_length - item_offset;
|
||||||
@ -1320,7 +1369,7 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
|
|||||||
while (start < prev && buffer->context_len[0] < buffer->CONTEXT_LENGTH)
|
while (start < prev && buffer->context_len[0] < buffer->CONTEXT_LENGTH)
|
||||||
{
|
{
|
||||||
hb_codepoint_t u;
|
hb_codepoint_t u;
|
||||||
prev = hb_utf_prev (prev, start, &u);
|
prev = utf_t::prev (prev, start, &u, replacement);
|
||||||
buffer->context[0][buffer->context_len[0]++] = u;
|
buffer->context[0][buffer->context_len[0]++] = u;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1331,7 +1380,7 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
|
|||||||
{
|
{
|
||||||
hb_codepoint_t u;
|
hb_codepoint_t u;
|
||||||
const T *old_next = next;
|
const T *old_next = next;
|
||||||
next = hb_utf_next (next, end, &u);
|
next = utf_t::next (next, end, &u, replacement);
|
||||||
buffer->add (u, old_next - (const T *) text);
|
buffer->add (u, old_next - (const T *) text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1341,7 +1390,7 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
|
|||||||
while (next < end && buffer->context_len[1] < buffer->CONTEXT_LENGTH)
|
while (next < end && buffer->context_len[1] < buffer->CONTEXT_LENGTH)
|
||||||
{
|
{
|
||||||
hb_codepoint_t u;
|
hb_codepoint_t u;
|
||||||
next = hb_utf_next (next, end, &u);
|
next = utf_t::next (next, end, &u, replacement);
|
||||||
buffer->context[1][buffer->context_len[1]++] = u;
|
buffer->context[1][buffer->context_len[1]++] = u;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1367,7 +1416,7 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer,
|
|||||||
unsigned int item_offset,
|
unsigned int item_offset,
|
||||||
int item_length)
|
int item_length)
|
||||||
{
|
{
|
||||||
hb_buffer_add_utf (buffer, (const uint8_t *) text, text_length, item_offset, item_length);
|
hb_buffer_add_utf<true> (buffer, (const uint8_t *) text, text_length, item_offset, item_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1389,7 +1438,7 @@ hb_buffer_add_utf16 (hb_buffer_t *buffer,
|
|||||||
unsigned int item_offset,
|
unsigned int item_offset,
|
||||||
int item_length)
|
int item_length)
|
||||||
{
|
{
|
||||||
hb_buffer_add_utf (buffer, text, text_length, item_offset, item_length);
|
hb_buffer_add_utf<true> (buffer, text, text_length, item_offset, item_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1411,7 +1460,29 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer,
|
|||||||
unsigned int item_offset,
|
unsigned int item_offset,
|
||||||
int item_length)
|
int item_length)
|
||||||
{
|
{
|
||||||
hb_buffer_add_utf (buffer, text, text_length, item_offset, item_length);
|
hb_buffer_add_utf<true> (buffer, text, text_length, item_offset, item_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hb_buffer_add_codepoints:
|
||||||
|
* @buffer: a buffer.
|
||||||
|
* @text: (array length=text_length):
|
||||||
|
* @text_length:
|
||||||
|
* @item_offset:
|
||||||
|
* @item_length:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
hb_buffer_add_codepoints (hb_buffer_t *buffer,
|
||||||
|
const hb_codepoint_t *text,
|
||||||
|
int text_length,
|
||||||
|
unsigned int item_offset,
|
||||||
|
int item_length)
|
||||||
|
{
|
||||||
|
hb_buffer_add_utf<false> (buffer, text, text_length, item_offset, item_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -186,12 +186,25 @@ hb_buffer_flags_t
|
|||||||
hb_buffer_get_flags (hb_buffer_t *buffer);
|
hb_buffer_get_flags (hb_buffer_t *buffer);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT 0xFFFDu
|
||||||
|
|
||||||
|
/* Sets codepoint used to replace invalid UTF-8/16/32 entries.
|
||||||
|
* Default is 0xFFFDu. */
|
||||||
|
void
|
||||||
|
hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer,
|
||||||
|
hb_codepoint_t replacement);
|
||||||
|
|
||||||
|
hb_codepoint_t
|
||||||
|
hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer);
|
||||||
|
|
||||||
|
|
||||||
/* Resets the buffer. Afterwards it's as if it was just created,
|
/* Resets the buffer. Afterwards it's as if it was just created,
|
||||||
* except that it has a larger buffer allocated perhaps... */
|
* except that it has a larger buffer allocated perhaps... */
|
||||||
void
|
void
|
||||||
hb_buffer_reset (hb_buffer_t *buffer);
|
hb_buffer_reset (hb_buffer_t *buffer);
|
||||||
|
|
||||||
/* Like reset, but does NOT clear unicode_funcs. */
|
/* Like reset, but does NOT clear unicode_funcs and replacement_codepoint. */
|
||||||
void
|
void
|
||||||
hb_buffer_clear_contents (hb_buffer_t *buffer);
|
hb_buffer_clear_contents (hb_buffer_t *buffer);
|
||||||
|
|
||||||
@ -240,6 +253,14 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer,
|
|||||||
unsigned int item_offset,
|
unsigned int item_offset,
|
||||||
int item_length);
|
int item_length);
|
||||||
|
|
||||||
|
/* Like add_utf32 but does NOT check for invalid Unicode codepoints. */
|
||||||
|
void
|
||||||
|
hb_buffer_add_codepoints (hb_buffer_t *buffer,
|
||||||
|
const hb_codepoint_t *text,
|
||||||
|
int text_length,
|
||||||
|
unsigned int item_offset,
|
||||||
|
int item_length);
|
||||||
|
|
||||||
|
|
||||||
/* Clears any new items added at the end */
|
/* Clears any new items added at the end */
|
||||||
hb_bool_t
|
hb_bool_t
|
||||||
|
@ -299,9 +299,11 @@ hb_language_from_string (const char *str, int len)
|
|||||||
|
|
||||||
if (len >= 0)
|
if (len >= 0)
|
||||||
{
|
{
|
||||||
|
/* NUL-terminate it. */
|
||||||
len = MIN (len, (int) sizeof (strbuf) - 1);
|
len = MIN (len, (int) sizeof (strbuf) - 1);
|
||||||
str = (char *) memcpy (strbuf, str, len);
|
memcpy (strbuf, str, len);
|
||||||
strbuf[len] = '\0';
|
strbuf[len] = '\0';
|
||||||
|
str = strbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_language_item_t *item = lang_find_or_insert (str);
|
hb_language_item_t *item = lang_find_or_insert (str);
|
||||||
@ -369,7 +371,7 @@ hb_script_from_iso15924_tag (hb_tag_t tag)
|
|||||||
return HB_SCRIPT_INVALID;
|
return HB_SCRIPT_INVALID;
|
||||||
|
|
||||||
/* Be lenient, adjust case (one capital letter followed by three small letters) */
|
/* Be lenient, adjust case (one capital letter followed by three small letters) */
|
||||||
tag = (tag & 0xDFDFDFDF) | 0x00202020;
|
tag = (tag & 0xDFDFDFDFu) | 0x00202020u;
|
||||||
|
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
|
|
||||||
@ -389,7 +391,7 @@ hb_script_from_iso15924_tag (hb_tag_t tag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If it looks right, just use the tag as a script */
|
/* If it looks right, just use the tag as a script */
|
||||||
if (((uint32_t) tag & 0xE0E0E0E0) == 0x40606060)
|
if (((uint32_t) tag & 0xE0E0E0E0u) == 0x40606060u)
|
||||||
return (hb_script_t) tag;
|
return (hb_script_t) tag;
|
||||||
|
|
||||||
/* Otherwise, return unknown */
|
/* Otherwise, return unknown */
|
||||||
@ -482,6 +484,14 @@ hb_script_get_horizontal_direction (hb_script_t script)
|
|||||||
case HB_SCRIPT_MEROITIC_CURSIVE:
|
case HB_SCRIPT_MEROITIC_CURSIVE:
|
||||||
case HB_SCRIPT_MEROITIC_HIEROGLYPHS:
|
case HB_SCRIPT_MEROITIC_HIEROGLYPHS:
|
||||||
|
|
||||||
|
/* Unicode-7.0 additions */
|
||||||
|
case HB_SCRIPT_MANICHAEAN:
|
||||||
|
case HB_SCRIPT_MENDE_KIKAKUI:
|
||||||
|
case HB_SCRIPT_NABATAEAN:
|
||||||
|
case HB_SCRIPT_OLD_NORTH_ARABIAN:
|
||||||
|
case HB_SCRIPT_PALMYRENE:
|
||||||
|
case HB_SCRIPT_PSALTER_PAHLAVI:
|
||||||
|
|
||||||
return HB_DIRECTION_RTL;
|
return HB_DIRECTION_RTL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -559,7 +569,7 @@ hb_version_string (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hb_version_check:
|
* hb_version_atleast:
|
||||||
* @major:
|
* @major:
|
||||||
* @minor:
|
* @minor:
|
||||||
* @micro:
|
* @micro:
|
||||||
@ -571,9 +581,9 @@ hb_version_string (void)
|
|||||||
* Since: 1.0
|
* Since: 1.0
|
||||||
**/
|
**/
|
||||||
hb_bool_t
|
hb_bool_t
|
||||||
hb_version_check (unsigned int major,
|
hb_version_atleast (unsigned int major,
|
||||||
unsigned int minor,
|
unsigned int minor,
|
||||||
unsigned int micro)
|
unsigned int micro)
|
||||||
{
|
{
|
||||||
return HB_VERSION_CHECK (major, minor, micro);
|
return HB_VERSION_ATLEAST (major, minor, micro);
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,7 @@ typedef uint32_t hb_tag_t;
|
|||||||
|
|
||||||
#define HB_TAG_NONE HB_TAG(0,0,0,0)
|
#define HB_TAG_NONE HB_TAG(0,0,0,0)
|
||||||
#define HB_TAG_MAX HB_TAG(0xff,0xff,0xff,0xff)
|
#define HB_TAG_MAX HB_TAG(0xff,0xff,0xff,0xff)
|
||||||
|
#define HB_TAG_MAX_SIGNED HB_TAG(0x7f,0xff,0xff,0xff)
|
||||||
|
|
||||||
/* len=-1 means str is NUL-terminated. */
|
/* len=-1 means str is NUL-terminated. */
|
||||||
hb_tag_t
|
hb_tag_t
|
||||||
@ -270,17 +271,6 @@ typedef enum
|
|||||||
/*6.1*/ HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'),
|
/*6.1*/ HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'),
|
||||||
/*6.1*/ HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'),
|
/*6.1*/ HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'),
|
||||||
|
|
||||||
/* No script set. */
|
|
||||||
/*---*/ HB_SCRIPT_INVALID = HB_TAG_NONE,
|
|
||||||
|
|
||||||
/* Dummy value to ensure any hb_tag_t value can be passed/stored as hb_script_t
|
|
||||||
* without risking undefined behavior. */
|
|
||||||
/*---*/ _HB_SCRIPT_MAX_VALUE = HB_TAG_MAX
|
|
||||||
|
|
||||||
} hb_script_t;
|
|
||||||
|
|
||||||
/* These are moved out of hb_script_t because glib-mkenums chokes otherwise. */
|
|
||||||
#if 0
|
|
||||||
/*7.0*/ HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'),
|
/*7.0*/ HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'),
|
||||||
/*7.0*/ HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'),
|
/*7.0*/ HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'),
|
||||||
/*7.0*/ HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'),
|
/*7.0*/ HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'),
|
||||||
@ -292,19 +282,33 @@ typedef enum
|
|||||||
/*7.0*/ HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'),
|
/*7.0*/ HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'),
|
||||||
/*7.0*/ HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'),
|
/*7.0*/ HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'),
|
||||||
/*7.0*/ HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'),
|
/*7.0*/ HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'),
|
||||||
/*7.0*/ HB_SCRIPT_MODI = ???
|
/*7.0*/ HB_SCRIPT_MODI = HB_TAG ('M','o','d','i'),
|
||||||
/*7.0*/ HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'),
|
/*7.0*/ HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'),
|
||||||
/*7.0*/ HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'),
|
/*7.0*/ HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'),
|
||||||
/*7.0*/ HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'),
|
/*7.0*/ HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'),
|
||||||
/*7.0*/ HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'),
|
/*7.0*/ HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'),
|
||||||
/*7.0*/ HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'),
|
/*7.0*/ HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'),
|
||||||
/*7.0*/ HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'),
|
/*7.0*/ HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'),
|
||||||
/*7.0*/ HB_SCRIPT_PAU_CIN_HAU = ???
|
/*7.0*/ HB_SCRIPT_PAU_CIN_HAU = HB_TAG ('P','a','u','c'),
|
||||||
/*7.0*/ HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'),
|
/*7.0*/ HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'),
|
||||||
/*7.0*/ HB_SCRIPT_SIDDHAM = ???
|
/*7.0*/ HB_SCRIPT_SIDDHAM = HB_TAG ('S','i','d','d'),
|
||||||
/*7.0*/ HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'),
|
/*7.0*/ HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'),
|
||||||
/*7.0*/ HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'),
|
/*7.0*/ HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'),
|
||||||
#endif
|
|
||||||
|
/* No script set. */
|
||||||
|
HB_SCRIPT_INVALID = HB_TAG_NONE,
|
||||||
|
|
||||||
|
/* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t
|
||||||
|
* without risking undefined behavior. Include both a signed and unsigned max,
|
||||||
|
* since technically enums are int, and indeed, hb_script_t ends up being signed.
|
||||||
|
* See this thread for technicalities:
|
||||||
|
*
|
||||||
|
* http://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html
|
||||||
|
*/
|
||||||
|
_HB_SCRIPT_MAX_VALUE = HB_TAG_MAX, /*< skip >*/
|
||||||
|
_HB_SCRIPT_MAX_VALUE_SIGNED = HB_TAG_MAX_SIGNED /*< skip >*/
|
||||||
|
|
||||||
|
} hb_script_t;
|
||||||
|
|
||||||
|
|
||||||
/* Script functions */
|
/* Script functions */
|
||||||
@ -312,7 +316,7 @@ typedef enum
|
|||||||
hb_script_t
|
hb_script_t
|
||||||
hb_script_from_iso15924_tag (hb_tag_t tag);
|
hb_script_from_iso15924_tag (hb_tag_t tag);
|
||||||
|
|
||||||
/* suger for tag_from_string() then script_from_iso15924_tag */
|
/* sugar for tag_from_string() then script_from_iso15924_tag */
|
||||||
/* len=-1 means s is NUL-terminated */
|
/* len=-1 means s is NUL-terminated */
|
||||||
hb_script_t
|
hb_script_t
|
||||||
hb_script_from_string (const char *s, int len);
|
hb_script_from_string (const char *s, int len);
|
||||||
|
@ -37,6 +37,38 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
release_table_data (void *user_data)
|
||||||
|
{
|
||||||
|
CFDataRef cf_data = reinterpret_cast<CFDataRef> (user_data);
|
||||||
|
CFRelease(cf_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_blob_t *
|
||||||
|
reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
|
||||||
|
{
|
||||||
|
CGFontRef cg_font = reinterpret_cast<CGFontRef> (user_data);
|
||||||
|
CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag);
|
||||||
|
if (unlikely (!cf_data))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
const char *data = reinterpret_cast<const char*> (CFDataGetBytePtr (cf_data));
|
||||||
|
const size_t length = CFDataGetLength (cf_data);
|
||||||
|
if (!data || !length)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY,
|
||||||
|
reinterpret_cast<void *> (const_cast<__CFData *> (cf_data)),
|
||||||
|
release_table_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
hb_face_t *
|
||||||
|
hb_coretext_face_create (CGFontRef cg_font)
|
||||||
|
{
|
||||||
|
return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), (hb_destroy_func_t) CGFontRelease);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
HB_SHAPER_DATA_ENSURE_DECLARE(coretext, face)
|
HB_SHAPER_DATA_ENSURE_DECLARE(coretext, face)
|
||||||
HB_SHAPER_DATA_ENSURE_DECLARE(coretext, font)
|
HB_SHAPER_DATA_ENSURE_DECLARE(coretext, font)
|
||||||
|
|
||||||
@ -65,15 +97,22 @@ _hb_coretext_shaper_face_data_create (hb_face_t *face)
|
|||||||
if (unlikely (!data))
|
if (unlikely (!data))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
hb_blob_t *blob = hb_face_reference_blob (face);
|
if (face->destroy == (hb_destroy_func_t) CGFontRelease)
|
||||||
unsigned int blob_length;
|
{
|
||||||
const char *blob_data = hb_blob_get_data (blob, &blob_length);
|
data->cg_font = CGFontRetain ((CGFontRef) face->user_data);
|
||||||
if (unlikely (!blob_length))
|
}
|
||||||
DEBUG_MSG (CORETEXT, face, "Face has empty blob");
|
else
|
||||||
|
{
|
||||||
|
hb_blob_t *blob = hb_face_reference_blob (face);
|
||||||
|
unsigned int blob_length;
|
||||||
|
const char *blob_data = hb_blob_get_data (blob, &blob_length);
|
||||||
|
if (unlikely (!blob_length))
|
||||||
|
DEBUG_MSG (CORETEXT, face, "Face has empty blob");
|
||||||
|
|
||||||
CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data);
|
CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data);
|
||||||
data->cg_font = CGFontCreateWithDataProvider (provider);
|
data->cg_font = CGFontCreateWithDataProvider (provider);
|
||||||
CGDataProviderRelease (provider);
|
CGDataProviderRelease (provider);
|
||||||
|
}
|
||||||
|
|
||||||
if (unlikely (!data->cg_font)) {
|
if (unlikely (!data->cg_font)) {
|
||||||
DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed");
|
DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed");
|
||||||
@ -438,7 +477,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
|
|||||||
event->start = false;
|
event->start = false;
|
||||||
event->feature = feature;
|
event->feature = feature;
|
||||||
}
|
}
|
||||||
feature_events.sort ();
|
feature_events.qsort ();
|
||||||
/* Add a strategic final event. */
|
/* Add a strategic final event. */
|
||||||
{
|
{
|
||||||
active_feature_t feature;
|
active_feature_t feature;
|
||||||
@ -468,14 +507,12 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
|
|||||||
if (unlikely (!range))
|
if (unlikely (!range))
|
||||||
goto fail_features;
|
goto fail_features;
|
||||||
|
|
||||||
unsigned int offset = feature_records.len;
|
|
||||||
|
|
||||||
if (active_features.len)
|
if (active_features.len)
|
||||||
{
|
{
|
||||||
CFMutableArrayRef features_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
CFMutableArrayRef features_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
||||||
|
|
||||||
/* TODO sort and resolve conflicting features? */
|
/* TODO sort and resolve conflicting features? */
|
||||||
/* active_features.sort (); */
|
/* active_features.qsort (); */
|
||||||
for (unsigned int j = 0; j < active_features.len; j++)
|
for (unsigned int j = 0; j < active_features.len; j++)
|
||||||
{
|
{
|
||||||
CFStringRef keys[2] = {
|
CFStringRef keys[2] = {
|
||||||
@ -573,13 +610,13 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
|
|||||||
for (unsigned int i = 0; i < buffer->len; i++) {
|
for (unsigned int i = 0; i < buffer->len; i++) {
|
||||||
hb_codepoint_t c = buffer->info[i].codepoint;
|
hb_codepoint_t c = buffer->info[i].codepoint;
|
||||||
buffer->info[i].utf16_index() = chars_len;
|
buffer->info[i].utf16_index() = chars_len;
|
||||||
if (likely (c < 0x10000))
|
if (likely (c <= 0xFFFFu))
|
||||||
pchars[chars_len++] = c;
|
pchars[chars_len++] = c;
|
||||||
else if (unlikely (c >= 0x110000))
|
else if (unlikely (c > 0x10FFFFu))
|
||||||
pchars[chars_len++] = 0xFFFD;
|
pchars[chars_len++] = 0xFFFDu;
|
||||||
else {
|
else {
|
||||||
pchars[chars_len++] = 0xD800 + ((c - 0x10000) >> 10);
|
pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10);
|
||||||
pchars[chars_len++] = 0xDC00 + ((c - 0x10000) & ((1 << 10) - 1));
|
pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1 << 10) - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,7 +642,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
|
|||||||
hb_codepoint_t c = buffer->info[i].codepoint;
|
hb_codepoint_t c = buffer->info[i].codepoint;
|
||||||
unsigned int cluster = buffer->info[i].cluster;
|
unsigned int cluster = buffer->info[i].cluster;
|
||||||
log_clusters[chars_len++] = cluster;
|
log_clusters[chars_len++] = cluster;
|
||||||
if (c >= 0x10000 && c < 0x110000)
|
if (hb_in_range (c, 0x10000u, 0x10FFFFu))
|
||||||
log_clusters[chars_len++] = cluster; /* Surrogates. */
|
log_clusters[chars_len++] = cluster; /* Surrogates. */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -677,10 +714,10 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
|
|||||||
for (CFIndex j = range.location; j < range.location + range.length; j++)
|
for (CFIndex j = range.location; j < range.location + range.length; j++)
|
||||||
{
|
{
|
||||||
UniChar ch = CFStringGetCharacterAtIndex (string_ref, j);
|
UniChar ch = CFStringGetCharacterAtIndex (string_ref, j);
|
||||||
if (hb_in_range<UniChar> (ch, 0xDC00, 0xDFFF) && range.location < j)
|
if (hb_in_range<UniChar> (ch, 0xDC00u, 0xDFFFu) && range.location < j)
|
||||||
{
|
{
|
||||||
ch = CFStringGetCharacterAtIndex (string_ref, j - 1);
|
ch = CFStringGetCharacterAtIndex (string_ref, j - 1);
|
||||||
if (hb_in_range<UniChar> (ch, 0xD800, 0xDBFF))
|
if (hb_in_range<UniChar> (ch, 0xD800u, 0xDBFFu))
|
||||||
/* This is the second of a surrogate pair. Don't need .notdef
|
/* This is the second of a surrogate pair. Don't need .notdef
|
||||||
* for this one. */
|
* for this one. */
|
||||||
continue;
|
continue;
|
||||||
@ -810,3 +847,97 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AAT shaper
|
||||||
|
*/
|
||||||
|
|
||||||
|
HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, face)
|
||||||
|
HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, font)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* shaper face data
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct hb_coretext_aat_shaper_face_data_t {};
|
||||||
|
|
||||||
|
hb_coretext_aat_shaper_face_data_t *
|
||||||
|
_hb_coretext_aat_shaper_face_data_create (hb_face_t *face)
|
||||||
|
{
|
||||||
|
hb_blob_t *mort_blob = face->reference_table (HB_CORETEXT_TAG_MORT);
|
||||||
|
/* Umm, we just reference the table to check whether it exists.
|
||||||
|
* Maybe add better API for this? */
|
||||||
|
if (!hb_blob_get_length (mort_blob))
|
||||||
|
{
|
||||||
|
hb_blob_destroy (mort_blob);
|
||||||
|
mort_blob = face->reference_table (HB_CORETEXT_TAG_MORX);
|
||||||
|
if (!hb_blob_get_length (mort_blob))
|
||||||
|
{
|
||||||
|
hb_blob_destroy (mort_blob);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hb_blob_destroy (mort_blob);
|
||||||
|
|
||||||
|
return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_shaper_face_data_t *data HB_UNUSED)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* shaper font data
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct hb_coretext_aat_shaper_font_data_t {};
|
||||||
|
|
||||||
|
hb_coretext_aat_shaper_font_data_t *
|
||||||
|
_hb_coretext_aat_shaper_font_data_create (hb_font_t *font)
|
||||||
|
{
|
||||||
|
return hb_coretext_shaper_font_data_ensure (font) ? (hb_coretext_aat_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_shaper_font_data_t *data HB_UNUSED)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* shaper shape_plan data
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct hb_coretext_aat_shaper_shape_plan_data_t {};
|
||||||
|
|
||||||
|
hb_coretext_aat_shaper_shape_plan_data_t *
|
||||||
|
_hb_coretext_aat_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||||
|
const hb_feature_t *user_features HB_UNUSED,
|
||||||
|
unsigned int num_user_features HB_UNUSED)
|
||||||
|
{
|
||||||
|
return (hb_coretext_aat_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_hb_coretext_aat_shaper_shape_plan_data_destroy (hb_coretext_aat_shaper_shape_plan_data_t *data HB_UNUSED)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* shaper
|
||||||
|
*/
|
||||||
|
|
||||||
|
hb_bool_t
|
||||||
|
_hb_coretext_aat_shape (hb_shape_plan_t *shape_plan,
|
||||||
|
hb_font_t *font,
|
||||||
|
hb_buffer_t *buffer,
|
||||||
|
const hb_feature_t *features,
|
||||||
|
unsigned int num_features)
|
||||||
|
{
|
||||||
|
return _hb_coretext_shape (shape_plan, font, buffer, features, num_features);
|
||||||
|
}
|
||||||
|
@ -29,11 +29,25 @@
|
|||||||
|
|
||||||
#include "hb.h"
|
#include "hb.h"
|
||||||
|
|
||||||
#include <ApplicationServices/ApplicationServices.h>
|
#include <TargetConditionals.h>
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
# include <CoreText/CoreText.h>
|
||||||
|
# include <CoreGraphics/CoreGraphics.h>
|
||||||
|
#else
|
||||||
|
# include <ApplicationServices/ApplicationServices.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
HB_BEGIN_DECLS
|
HB_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
#define HB_CORETEXT_TAG_MORT HB_TAG('m','o','r','t')
|
||||||
|
#define HB_CORETEXT_TAG_MORX HB_TAG('m','o','r','x')
|
||||||
|
|
||||||
|
|
||||||
|
hb_face_t *
|
||||||
|
hb_coretext_face_create (CGFontRef cg_font);
|
||||||
|
|
||||||
|
|
||||||
CGFontRef
|
CGFontRef
|
||||||
hb_coretext_face_get_cg_font (hb_face_t *face);
|
hb_coretext_face_get_cg_font (hb_face_t *face);
|
||||||
|
|
||||||
|
@ -298,7 +298,7 @@ hb_face_get_user_data (hb_face_t *face,
|
|||||||
void
|
void
|
||||||
hb_face_make_immutable (hb_face_t *face)
|
hb_face_make_immutable (hb_face_t *face)
|
||||||
{
|
{
|
||||||
if (hb_object_is_inert (face))
|
if (unlikely (hb_object_is_inert (face)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
face->immutable = true;
|
face->immutable = true;
|
||||||
@ -368,7 +368,7 @@ void
|
|||||||
hb_face_set_index (hb_face_t *face,
|
hb_face_set_index (hb_face_t *face,
|
||||||
unsigned int index)
|
unsigned int index)
|
||||||
{
|
{
|
||||||
if (hb_object_is_inert (face))
|
if (face->immutable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
face->index = index;
|
face->index = index;
|
||||||
@ -403,7 +403,7 @@ void
|
|||||||
hb_face_set_upem (hb_face_t *face,
|
hb_face_set_upem (hb_face_t *face,
|
||||||
unsigned int upem)
|
unsigned int upem)
|
||||||
{
|
{
|
||||||
if (hb_object_is_inert (face))
|
if (face->immutable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
face->upem = upem;
|
face->upem = upem;
|
||||||
@ -447,7 +447,7 @@ void
|
|||||||
hb_face_set_glyph_count (hb_face_t *face,
|
hb_face_set_glyph_count (hb_face_t *face,
|
||||||
unsigned int glyph_count)
|
unsigned int glyph_count)
|
||||||
{
|
{
|
||||||
if (hb_object_is_inert (face))
|
if (face->immutable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
face->num_glyphs = glyph_count;
|
face->num_glyphs = glyph_count;
|
||||||
|
@ -105,34 +105,36 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
|
|||||||
* shaper which many people unfortunately still request.
|
* shaper which many people unfortunately still request.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool has_space;
|
|
||||||
hb_codepoint_t space;
|
hb_codepoint_t space;
|
||||||
has_space = font->get_glyph (' ', 0, &space);
|
bool has_space = font->get_glyph (' ', 0, &space);
|
||||||
|
|
||||||
buffer->clear_positions ();
|
buffer->clear_positions ();
|
||||||
|
|
||||||
|
hb_direction_t direction = buffer->props.direction;
|
||||||
|
hb_unicode_funcs_t *unicode = buffer->unicode;
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
|
hb_glyph_position_t *pos = buffer->pos;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (has_space && buffer->unicode->is_default_ignorable (buffer->info[i].codepoint)) {
|
if (has_space && unicode->is_default_ignorable (info[i].codepoint)) {
|
||||||
buffer->info[i].codepoint = space;
|
info[i].codepoint = space;
|
||||||
buffer->pos[i].x_advance = 0;
|
pos[i].x_advance = 0;
|
||||||
buffer->pos[i].y_advance = 0;
|
pos[i].y_advance = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
font->get_glyph (buffer->info[i].codepoint, 0, &buffer->info[i].codepoint);
|
font->get_glyph (info[i].codepoint, 0, &info[i].codepoint);
|
||||||
font->get_glyph_advance_for_direction (buffer->info[i].codepoint,
|
font->get_glyph_advance_for_direction (info[i].codepoint,
|
||||||
buffer->props.direction,
|
direction,
|
||||||
&buffer->pos[i].x_advance,
|
&pos[i].x_advance,
|
||||||
&buffer->pos[i].y_advance);
|
&pos[i].y_advance);
|
||||||
font->subtract_glyph_origin_for_direction (buffer->info[i].codepoint,
|
font->subtract_glyph_origin_for_direction (info[i].codepoint,
|
||||||
buffer->props.direction,
|
direction,
|
||||||
&buffer->pos[i].x_offset,
|
&pos[i].x_offset,
|
||||||
&buffer->pos[i].y_offset);
|
&pos[i].y_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
|
if (HB_DIRECTION_IS_BACKWARD (direction))
|
||||||
hb_buffer_reverse (buffer);
|
hb_buffer_reverse (buffer);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -357,7 +357,7 @@ hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs,
|
|||||||
void
|
void
|
||||||
hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
|
hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
|
||||||
{
|
{
|
||||||
if (hb_object_is_inert (ffuncs))
|
if (unlikely (hb_object_is_inert (ffuncs)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ffuncs->immutable = true;
|
ffuncs->immutable = true;
|
||||||
@ -1034,7 +1034,7 @@ hb_font_get_user_data (hb_font_t *font,
|
|||||||
void
|
void
|
||||||
hb_font_make_immutable (hb_font_t *font)
|
hb_font_make_immutable (hb_font_t *font)
|
||||||
{
|
{
|
||||||
if (hb_object_is_inert (font))
|
if (unlikely (hb_object_is_inert (font)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
font->immutable = true;
|
font->immutable = true;
|
||||||
|
@ -340,7 +340,7 @@ hb_glib_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
|||||||
void *user_data HB_UNUSED)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
#if GLIB_CHECK_VERSION(2,29,12)
|
#if GLIB_CHECK_VERSION(2,29,12)
|
||||||
return g_unichar_fully_decompose (u, TRUE, decomposed, HB_UNICODE_MAX_DECOMPOSITION_LEN);
|
return g_unichar_fully_decompose (u, true, decomposed, HB_UNICODE_MAX_DECOMPOSITION_LEN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If the user doesn't have GLib >= 2.29.12 we have to perform
|
/* If the user doesn't have GLib >= 2.29.12 we have to perform
|
||||||
|
@ -1,343 +0,0 @@
|
|||||||
|
|
||||||
/* Generated data (by glib-mkenums) */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright © 2011 Google, Inc.
|
|
||||||
*
|
|
||||||
* This is part of HarfBuzz, a text shaping library.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, without written agreement and without
|
|
||||||
* license or royalty fees, to use, copy, modify, and distribute this
|
|
||||||
* software and its documentation for any purpose, provided that the
|
|
||||||
* above copyright notice and the following two paragraphs appear in
|
|
||||||
* all copies of this software.
|
|
||||||
*
|
|
||||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
|
||||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
|
||||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
|
||||||
* DAMAGE.
|
|
||||||
*
|
|
||||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
|
||||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
|
||||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
|
||||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
|
||||||
*
|
|
||||||
* Google Author(s): Behdad Esfahbod
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "hb-private.hh"
|
|
||||||
|
|
||||||
/* g++ didn't like older gtype.h gcc-only code path. */
|
|
||||||
#include <glib.h>
|
|
||||||
#if !GLIB_CHECK_VERSION(2,29,16)
|
|
||||||
#undef __GNUC__
|
|
||||||
#undef __GNUC_MINOR__
|
|
||||||
#define __GNUC__ 2
|
|
||||||
#define __GNUC_MINOR__ 6
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "hb-gobject.h"
|
|
||||||
|
|
||||||
/* enumerations from "hb-blob.h" */
|
|
||||||
inline static /* TODO(behdad) disable these for now until we fix them... */
|
|
||||||
GType
|
|
||||||
hb_memory_mode_t_hb_memory_mode_t_get_type (void)
|
|
||||||
{
|
|
||||||
static volatile gsize g_define_type_id__volatile = 0;
|
|
||||||
|
|
||||||
if (g_once_init_enter (&g_define_type_id__volatile))
|
|
||||||
{
|
|
||||||
static const GEnumValue values[] = {
|
|
||||||
{ HB_MEMORY_MODE_DUPLICATE, "HB_MEMORY_MODE_DUPLICATE", "duplicate" },
|
|
||||||
{ HB_MEMORY_MODE_READONLY, "HB_MEMORY_MODE_READONLY", "readonly" },
|
|
||||||
{ HB_MEMORY_MODE_WRITABLE, "HB_MEMORY_MODE_WRITABLE", "writable" },
|
|
||||||
{ HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE, "HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE", "readonly-may-make-writable" },
|
|
||||||
{ 0, NULL, NULL }
|
|
||||||
};
|
|
||||||
GType g_define_type_id =
|
|
||||||
g_enum_register_static (g_intern_static_string ("hb_memory_mode_t"), values);
|
|
||||||
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_define_type_id__volatile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* enumerations from "hb-common.h" */
|
|
||||||
inline static /* TODO(behdad) disable these for now until we fix them... */
|
|
||||||
GType
|
|
||||||
hb_direction_t_hb_direction_t_get_type (void)
|
|
||||||
{
|
|
||||||
static volatile gsize g_define_type_id__volatile = 0;
|
|
||||||
|
|
||||||
if (g_once_init_enter (&g_define_type_id__volatile))
|
|
||||||
{
|
|
||||||
static const GEnumValue values[] = {
|
|
||||||
{ HB_DIRECTION_INVALID, "HB_DIRECTION_INVALID", "invalid" },
|
|
||||||
{ HB_DIRECTION_LTR, "HB_DIRECTION_LTR", "ltr" },
|
|
||||||
{ HB_DIRECTION_RTL, "HB_DIRECTION_RTL", "rtl" },
|
|
||||||
{ HB_DIRECTION_TTB, "HB_DIRECTION_TTB", "ttb" },
|
|
||||||
{ HB_DIRECTION_BTT, "HB_DIRECTION_BTT", "btt" },
|
|
||||||
{ 0, NULL, NULL }
|
|
||||||
};
|
|
||||||
GType g_define_type_id =
|
|
||||||
g_enum_register_static (g_intern_static_string ("hb_direction_t"), values);
|
|
||||||
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_define_type_id__volatile;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static /* TODO(behdad) disable these for now until we fix them... */
|
|
||||||
GType
|
|
||||||
hb_script_t_hb_script_t_get_type (void)
|
|
||||||
{
|
|
||||||
static volatile gsize g_define_type_id__volatile = 0;
|
|
||||||
|
|
||||||
if (g_once_init_enter (&g_define_type_id__volatile))
|
|
||||||
{
|
|
||||||
static const GEnumValue values[] = {
|
|
||||||
{ HB_SCRIPT_COMMON, "HB_SCRIPT_COMMON", "common" },
|
|
||||||
{ HB_SCRIPT_ARABIC, "HB_SCRIPT_ARABIC", "arabic" },
|
|
||||||
{ HB_SCRIPT_ARMENIAN, "HB_SCRIPT_ARMENIAN", "armenian" },
|
|
||||||
{ HB_SCRIPT_BENGALI, "HB_SCRIPT_BENGALI", "bengali" },
|
|
||||||
{ HB_SCRIPT_BOPOMOFO, "HB_SCRIPT_BOPOMOFO", "bopomofo" },
|
|
||||||
{ HB_SCRIPT_CANADIAN_ABORIGINAL, "HB_SCRIPT_CANADIAN_ABORIGINAL", "canadian-aboriginal" },
|
|
||||||
{ HB_SCRIPT_CHEROKEE, "HB_SCRIPT_CHEROKEE", "cherokee" },
|
|
||||||
{ HB_SCRIPT_COPTIC, "HB_SCRIPT_COPTIC", "coptic" },
|
|
||||||
{ HB_SCRIPT_CYRILLIC, "HB_SCRIPT_CYRILLIC", "cyrillic" },
|
|
||||||
{ HB_SCRIPT_DEVANAGARI, "HB_SCRIPT_DEVANAGARI", "devanagari" },
|
|
||||||
{ HB_SCRIPT_GEORGIAN, "HB_SCRIPT_GEORGIAN", "georgian" },
|
|
||||||
{ HB_SCRIPT_GREEK, "HB_SCRIPT_GREEK", "greek" },
|
|
||||||
{ HB_SCRIPT_GUJARATI, "HB_SCRIPT_GUJARATI", "gujarati" },
|
|
||||||
{ HB_SCRIPT_GURMUKHI, "HB_SCRIPT_GURMUKHI", "gurmukhi" },
|
|
||||||
{ HB_SCRIPT_HANGUL, "HB_SCRIPT_HANGUL", "hangul" },
|
|
||||||
{ HB_SCRIPT_HAN, "HB_SCRIPT_HAN", "han" },
|
|
||||||
{ HB_SCRIPT_HEBREW, "HB_SCRIPT_HEBREW", "hebrew" },
|
|
||||||
{ HB_SCRIPT_HIRAGANA, "HB_SCRIPT_HIRAGANA", "hiragana" },
|
|
||||||
{ HB_SCRIPT_INHERITED, "HB_SCRIPT_INHERITED", "inherited" },
|
|
||||||
{ HB_SCRIPT_KANNADA, "HB_SCRIPT_KANNADA", "kannada" },
|
|
||||||
{ HB_SCRIPT_KATAKANA, "HB_SCRIPT_KATAKANA", "katakana" },
|
|
||||||
{ HB_SCRIPT_LAO, "HB_SCRIPT_LAO", "lao" },
|
|
||||||
{ HB_SCRIPT_LATIN, "HB_SCRIPT_LATIN", "latin" },
|
|
||||||
{ HB_SCRIPT_MALAYALAM, "HB_SCRIPT_MALAYALAM", "malayalam" },
|
|
||||||
{ HB_SCRIPT_MONGOLIAN, "HB_SCRIPT_MONGOLIAN", "mongolian" },
|
|
||||||
{ HB_SCRIPT_OGHAM, "HB_SCRIPT_OGHAM", "ogham" },
|
|
||||||
{ HB_SCRIPT_ORIYA, "HB_SCRIPT_ORIYA", "oriya" },
|
|
||||||
{ HB_SCRIPT_RUNIC, "HB_SCRIPT_RUNIC", "runic" },
|
|
||||||
{ HB_SCRIPT_SYRIAC, "HB_SCRIPT_SYRIAC", "syriac" },
|
|
||||||
{ HB_SCRIPT_TAMIL, "HB_SCRIPT_TAMIL", "tamil" },
|
|
||||||
{ HB_SCRIPT_TELUGU, "HB_SCRIPT_TELUGU", "telugu" },
|
|
||||||
{ HB_SCRIPT_THAI, "HB_SCRIPT_THAI", "thai" },
|
|
||||||
{ HB_SCRIPT_YI, "HB_SCRIPT_YI", "yi" },
|
|
||||||
{ HB_SCRIPT_TIBETAN, "HB_SCRIPT_TIBETAN", "tibetan" },
|
|
||||||
{ HB_SCRIPT_ETHIOPIC, "HB_SCRIPT_ETHIOPIC", "ethiopic" },
|
|
||||||
{ HB_SCRIPT_KHMER, "HB_SCRIPT_KHMER", "khmer" },
|
|
||||||
{ HB_SCRIPT_MYANMAR, "HB_SCRIPT_MYANMAR", "myanmar" },
|
|
||||||
{ HB_SCRIPT_SINHALA, "HB_SCRIPT_SINHALA", "sinhala" },
|
|
||||||
{ HB_SCRIPT_THAANA, "HB_SCRIPT_THAANA", "thaana" },
|
|
||||||
{ HB_SCRIPT_DESERET, "HB_SCRIPT_DESERET", "deseret" },
|
|
||||||
{ HB_SCRIPT_GOTHIC, "HB_SCRIPT_GOTHIC", "gothic" },
|
|
||||||
{ HB_SCRIPT_OLD_ITALIC, "HB_SCRIPT_OLD_ITALIC", "old-italic" },
|
|
||||||
{ HB_SCRIPT_BUHID, "HB_SCRIPT_BUHID", "buhid" },
|
|
||||||
{ HB_SCRIPT_HANUNOO, "HB_SCRIPT_HANUNOO", "hanunoo" },
|
|
||||||
{ HB_SCRIPT_TAGALOG, "HB_SCRIPT_TAGALOG", "tagalog" },
|
|
||||||
{ HB_SCRIPT_TAGBANWA, "HB_SCRIPT_TAGBANWA", "tagbanwa" },
|
|
||||||
{ HB_SCRIPT_BRAILLE, "HB_SCRIPT_BRAILLE", "braille" },
|
|
||||||
{ HB_SCRIPT_CYPRIOT, "HB_SCRIPT_CYPRIOT", "cypriot" },
|
|
||||||
{ HB_SCRIPT_LIMBU, "HB_SCRIPT_LIMBU", "limbu" },
|
|
||||||
{ HB_SCRIPT_LINEAR_B, "HB_SCRIPT_LINEAR_B", "linear-b" },
|
|
||||||
{ HB_SCRIPT_OSMANYA, "HB_SCRIPT_OSMANYA", "osmanya" },
|
|
||||||
{ HB_SCRIPT_SHAVIAN, "HB_SCRIPT_SHAVIAN", "shavian" },
|
|
||||||
{ HB_SCRIPT_TAI_LE, "HB_SCRIPT_TAI_LE", "tai-le" },
|
|
||||||
{ HB_SCRIPT_UGARITIC, "HB_SCRIPT_UGARITIC", "ugaritic" },
|
|
||||||
{ HB_SCRIPT_BUGINESE, "HB_SCRIPT_BUGINESE", "buginese" },
|
|
||||||
{ HB_SCRIPT_GLAGOLITIC, "HB_SCRIPT_GLAGOLITIC", "glagolitic" },
|
|
||||||
{ HB_SCRIPT_KHAROSHTHI, "HB_SCRIPT_KHAROSHTHI", "kharoshthi" },
|
|
||||||
{ HB_SCRIPT_NEW_TAI_LUE, "HB_SCRIPT_NEW_TAI_LUE", "new-tai-lue" },
|
|
||||||
{ HB_SCRIPT_OLD_PERSIAN, "HB_SCRIPT_OLD_PERSIAN", "old-persian" },
|
|
||||||
{ HB_SCRIPT_SYLOTI_NAGRI, "HB_SCRIPT_SYLOTI_NAGRI", "syloti-nagri" },
|
|
||||||
{ HB_SCRIPT_TIFINAGH, "HB_SCRIPT_TIFINAGH", "tifinagh" },
|
|
||||||
{ HB_SCRIPT_BALINESE, "HB_SCRIPT_BALINESE", "balinese" },
|
|
||||||
{ HB_SCRIPT_CUNEIFORM, "HB_SCRIPT_CUNEIFORM", "cuneiform" },
|
|
||||||
{ HB_SCRIPT_NKO, "HB_SCRIPT_NKO", "nko" },
|
|
||||||
{ HB_SCRIPT_PHAGS_PA, "HB_SCRIPT_PHAGS_PA", "phags-pa" },
|
|
||||||
{ HB_SCRIPT_PHOENICIAN, "HB_SCRIPT_PHOENICIAN", "phoenician" },
|
|
||||||
{ HB_SCRIPT_UNKNOWN, "HB_SCRIPT_UNKNOWN", "unknown" },
|
|
||||||
{ HB_SCRIPT_CARIAN, "HB_SCRIPT_CARIAN", "carian" },
|
|
||||||
{ HB_SCRIPT_CHAM, "HB_SCRIPT_CHAM", "cham" },
|
|
||||||
{ HB_SCRIPT_KAYAH_LI, "HB_SCRIPT_KAYAH_LI", "kayah-li" },
|
|
||||||
{ HB_SCRIPT_LEPCHA, "HB_SCRIPT_LEPCHA", "lepcha" },
|
|
||||||
{ HB_SCRIPT_LYCIAN, "HB_SCRIPT_LYCIAN", "lycian" },
|
|
||||||
{ HB_SCRIPT_LYDIAN, "HB_SCRIPT_LYDIAN", "lydian" },
|
|
||||||
{ HB_SCRIPT_OL_CHIKI, "HB_SCRIPT_OL_CHIKI", "ol-chiki" },
|
|
||||||
{ HB_SCRIPT_REJANG, "HB_SCRIPT_REJANG", "rejang" },
|
|
||||||
{ HB_SCRIPT_SAURASHTRA, "HB_SCRIPT_SAURASHTRA", "saurashtra" },
|
|
||||||
{ HB_SCRIPT_SUNDANESE, "HB_SCRIPT_SUNDANESE", "sundanese" },
|
|
||||||
{ HB_SCRIPT_VAI, "HB_SCRIPT_VAI", "vai" },
|
|
||||||
{ HB_SCRIPT_AVESTAN, "HB_SCRIPT_AVESTAN", "avestan" },
|
|
||||||
{ HB_SCRIPT_BAMUM, "HB_SCRIPT_BAMUM", "bamum" },
|
|
||||||
{ HB_SCRIPT_EGYPTIAN_HIEROGLYPHS, "HB_SCRIPT_EGYPTIAN_HIEROGLYPHS", "egyptian-hieroglyphs" },
|
|
||||||
{ HB_SCRIPT_IMPERIAL_ARAMAIC, "HB_SCRIPT_IMPERIAL_ARAMAIC", "imperial-aramaic" },
|
|
||||||
{ HB_SCRIPT_INSCRIPTIONAL_PAHLAVI, "HB_SCRIPT_INSCRIPTIONAL_PAHLAVI", "inscriptional-pahlavi" },
|
|
||||||
{ HB_SCRIPT_INSCRIPTIONAL_PARTHIAN, "HB_SCRIPT_INSCRIPTIONAL_PARTHIAN", "inscriptional-parthian" },
|
|
||||||
{ HB_SCRIPT_JAVANESE, "HB_SCRIPT_JAVANESE", "javanese" },
|
|
||||||
{ HB_SCRIPT_KAITHI, "HB_SCRIPT_KAITHI", "kaithi" },
|
|
||||||
{ HB_SCRIPT_LISU, "HB_SCRIPT_LISU", "lisu" },
|
|
||||||
{ HB_SCRIPT_MEETEI_MAYEK, "HB_SCRIPT_MEETEI_MAYEK", "meetei-mayek" },
|
|
||||||
{ HB_SCRIPT_OLD_SOUTH_ARABIAN, "HB_SCRIPT_OLD_SOUTH_ARABIAN", "old-south-arabian" },
|
|
||||||
{ HB_SCRIPT_OLD_TURKIC, "HB_SCRIPT_OLD_TURKIC", "old-turkic" },
|
|
||||||
{ HB_SCRIPT_SAMARITAN, "HB_SCRIPT_SAMARITAN", "samaritan" },
|
|
||||||
{ HB_SCRIPT_TAI_THAM, "HB_SCRIPT_TAI_THAM", "tai-tham" },
|
|
||||||
{ HB_SCRIPT_TAI_VIET, "HB_SCRIPT_TAI_VIET", "tai-viet" },
|
|
||||||
{ HB_SCRIPT_BATAK, "HB_SCRIPT_BATAK", "batak" },
|
|
||||||
{ HB_SCRIPT_BRAHMI, "HB_SCRIPT_BRAHMI", "brahmi" },
|
|
||||||
{ HB_SCRIPT_MANDAIC, "HB_SCRIPT_MANDAIC", "mandaic" },
|
|
||||||
{ HB_SCRIPT_CHAKMA, "HB_SCRIPT_CHAKMA", "chakma" },
|
|
||||||
{ HB_SCRIPT_MEROITIC_CURSIVE, "HB_SCRIPT_MEROITIC_CURSIVE", "meroitic-cursive" },
|
|
||||||
{ HB_SCRIPT_MEROITIC_HIEROGLYPHS, "HB_SCRIPT_MEROITIC_HIEROGLYPHS", "meroitic-hieroglyphs" },
|
|
||||||
{ HB_SCRIPT_MIAO, "HB_SCRIPT_MIAO", "miao" },
|
|
||||||
{ HB_SCRIPT_SHARADA, "HB_SCRIPT_SHARADA", "sharada" },
|
|
||||||
{ HB_SCRIPT_SORA_SOMPENG, "HB_SCRIPT_SORA_SOMPENG", "sora-sompeng" },
|
|
||||||
{ HB_SCRIPT_TAKRI, "HB_SCRIPT_TAKRI", "takri" },
|
|
||||||
{ HB_SCRIPT_INVALID, "HB_SCRIPT_INVALID", "invalid" },
|
|
||||||
{ 0, NULL, NULL }
|
|
||||||
};
|
|
||||||
GType g_define_type_id =
|
|
||||||
g_enum_register_static (g_intern_static_string ("hb_script_t"), values);
|
|
||||||
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_define_type_id__volatile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* enumerations from "hb-unicode.h" */
|
|
||||||
inline static /* TODO(behdad) disable these for now until we fix them... */
|
|
||||||
GType
|
|
||||||
hb_unicode_general_category_t_hb_unicode_general_category_t_get_type (void)
|
|
||||||
{
|
|
||||||
static volatile gsize g_define_type_id__volatile = 0;
|
|
||||||
|
|
||||||
if (g_once_init_enter (&g_define_type_id__volatile))
|
|
||||||
{
|
|
||||||
static const GEnumValue values[] = {
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_CONTROL, "HB_UNICODE_GENERAL_CATEGORY_CONTROL", "control" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_FORMAT, "HB_UNICODE_GENERAL_CATEGORY_FORMAT", "format" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED, "HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED", "unassigned" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE, "HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE", "private-use" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_SURROGATE, "HB_UNICODE_GENERAL_CATEGORY_SURROGATE", "surrogate" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER, "HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER", "lowercase-letter" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER, "HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER", "modifier-letter" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER, "HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER", "other-letter" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER, "HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER", "titlecase-letter" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER, "HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER", "uppercase-letter" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK, "HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK", "spacing-mark" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK, "HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK", "enclosing-mark" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK, "HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK", "non-spacing-mark" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER, "HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER", "decimal-number" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER, "HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER", "letter-number" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER, "HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER", "other-number" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION, "HB_UNICODE_GENERAL_CATEGORY_CONNECT_PUNCTUATION", "connect-punctuation" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION, "HB_UNICODE_GENERAL_CATEGORY_DASH_PUNCTUATION", "dash-punctuation" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION, "HB_UNICODE_GENERAL_CATEGORY_CLOSE_PUNCTUATION", "close-punctuation" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION, "HB_UNICODE_GENERAL_CATEGORY_FINAL_PUNCTUATION", "final-punctuation" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION, "HB_UNICODE_GENERAL_CATEGORY_INITIAL_PUNCTUATION", "initial-punctuation" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION, "HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION", "other-punctuation" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION, "HB_UNICODE_GENERAL_CATEGORY_OPEN_PUNCTUATION", "open-punctuation" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL, "HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL", "currency-symbol" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL, "HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL", "modifier-symbol" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL, "HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL", "math-symbol" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL, "HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL", "other-symbol" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR, "HB_UNICODE_GENERAL_CATEGORY_LINE_SEPARATOR", "line-separator" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR, "HB_UNICODE_GENERAL_CATEGORY_PARAGRAPH_SEPARATOR", "paragraph-separator" },
|
|
||||||
{ HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR, "HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR", "space-separator" },
|
|
||||||
{ 0, NULL, NULL }
|
|
||||||
};
|
|
||||||
GType g_define_type_id =
|
|
||||||
g_enum_register_static (g_intern_static_string ("hb_unicode_general_category_t"), values);
|
|
||||||
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_define_type_id__volatile;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static /* TODO(behdad) disable these for now until we fix them... */
|
|
||||||
GType
|
|
||||||
hb_unicode_combining_class_t_hb_unicode_combining_class_t_get_type (void)
|
|
||||||
{
|
|
||||||
static volatile gsize g_define_type_id__volatile = 0;
|
|
||||||
|
|
||||||
if (g_once_init_enter (&g_define_type_id__volatile))
|
|
||||||
{
|
|
||||||
static const GEnumValue values[] = {
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_NOT_REORDERED, "HB_UNICODE_COMBINING_CLASS_NOT_REORDERED", "not-reordered" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_OVERLAY, "HB_UNICODE_COMBINING_CLASS_OVERLAY", "overlay" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_NUKTA, "HB_UNICODE_COMBINING_CLASS_NUKTA", "nukta" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_KANA_VOICING, "HB_UNICODE_COMBINING_CLASS_KANA_VOICING", "kana-voicing" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_VIRAMA, "HB_UNICODE_COMBINING_CLASS_VIRAMA", "virama" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC10, "HB_UNICODE_COMBINING_CLASS_CCC10", "ccc10" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC11, "HB_UNICODE_COMBINING_CLASS_CCC11", "ccc11" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC12, "HB_UNICODE_COMBINING_CLASS_CCC12", "ccc12" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC13, "HB_UNICODE_COMBINING_CLASS_CCC13", "ccc13" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC14, "HB_UNICODE_COMBINING_CLASS_CCC14", "ccc14" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC15, "HB_UNICODE_COMBINING_CLASS_CCC15", "ccc15" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC16, "HB_UNICODE_COMBINING_CLASS_CCC16", "ccc16" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC17, "HB_UNICODE_COMBINING_CLASS_CCC17", "ccc17" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC18, "HB_UNICODE_COMBINING_CLASS_CCC18", "ccc18" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC19, "HB_UNICODE_COMBINING_CLASS_CCC19", "ccc19" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC20, "HB_UNICODE_COMBINING_CLASS_CCC20", "ccc20" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC21, "HB_UNICODE_COMBINING_CLASS_CCC21", "ccc21" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC22, "HB_UNICODE_COMBINING_CLASS_CCC22", "ccc22" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC23, "HB_UNICODE_COMBINING_CLASS_CCC23", "ccc23" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC24, "HB_UNICODE_COMBINING_CLASS_CCC24", "ccc24" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC25, "HB_UNICODE_COMBINING_CLASS_CCC25", "ccc25" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC26, "HB_UNICODE_COMBINING_CLASS_CCC26", "ccc26" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC27, "HB_UNICODE_COMBINING_CLASS_CCC27", "ccc27" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC28, "HB_UNICODE_COMBINING_CLASS_CCC28", "ccc28" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC29, "HB_UNICODE_COMBINING_CLASS_CCC29", "ccc29" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC30, "HB_UNICODE_COMBINING_CLASS_CCC30", "ccc30" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC31, "HB_UNICODE_COMBINING_CLASS_CCC31", "ccc31" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC32, "HB_UNICODE_COMBINING_CLASS_CCC32", "ccc32" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC33, "HB_UNICODE_COMBINING_CLASS_CCC33", "ccc33" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC34, "HB_UNICODE_COMBINING_CLASS_CCC34", "ccc34" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC35, "HB_UNICODE_COMBINING_CLASS_CCC35", "ccc35" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC36, "HB_UNICODE_COMBINING_CLASS_CCC36", "ccc36" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC84, "HB_UNICODE_COMBINING_CLASS_CCC84", "ccc84" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC91, "HB_UNICODE_COMBINING_CLASS_CCC91", "ccc91" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC103, "HB_UNICODE_COMBINING_CLASS_CCC103", "ccc103" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC107, "HB_UNICODE_COMBINING_CLASS_CCC107", "ccc107" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC118, "HB_UNICODE_COMBINING_CLASS_CCC118", "ccc118" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC122, "HB_UNICODE_COMBINING_CLASS_CCC122", "ccc122" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC129, "HB_UNICODE_COMBINING_CLASS_CCC129", "ccc129" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC130, "HB_UNICODE_COMBINING_CLASS_CCC130", "ccc130" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_CCC133, "HB_UNICODE_COMBINING_CLASS_CCC133", "ccc133" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT, "HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT", "attached-below-left" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW, "HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW", "attached-below" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE, "HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE", "attached-above" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT, "HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT", "attached-above-right" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_BELOW_LEFT, "HB_UNICODE_COMBINING_CLASS_BELOW_LEFT", "below-left" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_BELOW, "HB_UNICODE_COMBINING_CLASS_BELOW", "below" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT, "HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT", "below-right" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_LEFT, "HB_UNICODE_COMBINING_CLASS_LEFT", "left" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_RIGHT, "HB_UNICODE_COMBINING_CLASS_RIGHT", "right" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT, "HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT", "above-left" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_ABOVE, "HB_UNICODE_COMBINING_CLASS_ABOVE", "above" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT, "HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT", "above-right" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW, "HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW", "double-below" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE, "HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE", "double-above" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_IOTA_SUBSCRIPT, "HB_UNICODE_COMBINING_CLASS_IOTA_SUBSCRIPT", "iota-subscript" },
|
|
||||||
{ HB_UNICODE_COMBINING_CLASS_INVALID, "HB_UNICODE_COMBINING_CLASS_INVALID", "invalid" },
|
|
||||||
{ 0, NULL, NULL }
|
|
||||||
};
|
|
||||||
GType g_define_type_id =
|
|
||||||
g_enum_register_static (g_intern_static_string ("hb_unicode_combining_class_t"), values);
|
|
||||||
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_define_type_id__volatile;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Generated data ends here */
|
|
||||||
|
|
@ -209,6 +209,7 @@ struct hb_graphite2_cluster_t {
|
|||||||
unsigned int num_chars;
|
unsigned int num_chars;
|
||||||
unsigned int base_glyph;
|
unsigned int base_glyph;
|
||||||
unsigned int num_glyphs;
|
unsigned int num_glyphs;
|
||||||
|
unsigned int cluster;
|
||||||
};
|
};
|
||||||
|
|
||||||
hb_bool_t
|
hb_bool_t
|
||||||
@ -299,6 +300,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
|
|||||||
memset (clusters, 0, sizeof (clusters[0]) * buffer->len);
|
memset (clusters, 0, sizeof (clusters[0]) * buffer->len);
|
||||||
|
|
||||||
hb_codepoint_t *pg = gids;
|
hb_codepoint_t *pg = gids;
|
||||||
|
clusters[0].cluster = buffer->info[0].cluster;
|
||||||
for (is = gr_seg_first_slot (seg), ic = 0; is; is = gr_slot_next_in_segment (is), ic++)
|
for (is = gr_seg_first_slot (seg), ic = 0; is; is = gr_slot_next_in_segment (is), ic++)
|
||||||
{
|
{
|
||||||
unsigned int before = gr_slot_before (is);
|
unsigned int before = gr_slot_before (is);
|
||||||
@ -316,6 +318,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
|
|||||||
{
|
{
|
||||||
hb_graphite2_cluster_t *c = clusters + ci + 1;
|
hb_graphite2_cluster_t *c = clusters + ci + 1;
|
||||||
c->base_char = clusters[ci].base_char + clusters[ci].num_chars;
|
c->base_char = clusters[ci].base_char + clusters[ci].num_chars;
|
||||||
|
c->cluster = buffer->info[c->base_char].cluster;
|
||||||
c->num_chars = before - c->base_char;
|
c->num_chars = before - c->base_char;
|
||||||
c->base_glyph = ic;
|
c->base_glyph = ic;
|
||||||
c->num_glyphs = 0;
|
c->num_glyphs = 0;
|
||||||
@ -335,7 +338,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
|
|||||||
{
|
{
|
||||||
hb_glyph_info_t *info = &buffer->info[clusters[i].base_glyph + j];
|
hb_glyph_info_t *info = &buffer->info[clusters[i].base_glyph + j];
|
||||||
info->codepoint = gids[clusters[i].base_glyph + j];
|
info->codepoint = gids[clusters[i].base_glyph + j];
|
||||||
info->cluster = gr_cinfo_base(gr_seg_cinfo(seg, clusters[i].base_char));
|
info->cluster = clusters[i].cluster;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buffer->len = glyph_count;
|
buffer->len = glyph_count;
|
||||||
|
@ -1,215 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright © 2012 Google, Inc.
|
|
||||||
*
|
|
||||||
* This is part of HarfBuzz, a text shaping library.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, without written agreement and without
|
|
||||||
* license or royalty fees, to use, copy, modify, and distribute this
|
|
||||||
* software and its documentation for any purpose, provided that the
|
|
||||||
* above copyright notice and the following two paragraphs appear in
|
|
||||||
* all copies of this software.
|
|
||||||
*
|
|
||||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
|
||||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
|
||||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
|
||||||
* DAMAGE.
|
|
||||||
*
|
|
||||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
|
||||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
|
||||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
|
||||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
|
||||||
*
|
|
||||||
* Google Author(s): Behdad Esfahbod
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define HB_SHAPER icu_le
|
|
||||||
#define hb_icu_le_shaper_font_data_t PortableFontInstance
|
|
||||||
#include "hb-shaper-impl-private.hh"
|
|
||||||
|
|
||||||
#include "hb-icu-le/PortableFontInstance.h"
|
|
||||||
|
|
||||||
#include "layout/loengine.h"
|
|
||||||
#include "unicode/unistr.h"
|
|
||||||
|
|
||||||
#include "hb-icu.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* shaper face data
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct hb_icu_le_shaper_face_data_t {};
|
|
||||||
|
|
||||||
hb_icu_le_shaper_face_data_t *
|
|
||||||
_hb_icu_le_shaper_face_data_create (hb_face_t *face HB_UNUSED)
|
|
||||||
{
|
|
||||||
return (hb_icu_le_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_hb_icu_le_shaper_face_data_destroy (hb_icu_le_shaper_face_data_t *data HB_UNUSED)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* shaper font data
|
|
||||||
*/
|
|
||||||
|
|
||||||
hb_icu_le_shaper_font_data_t *
|
|
||||||
_hb_icu_le_shaper_font_data_create (hb_font_t *font)
|
|
||||||
{
|
|
||||||
LEErrorCode status = LE_NO_ERROR;
|
|
||||||
hb_icu_le_shaper_font_data_t *data = new PortableFontInstance (font->face,
|
|
||||||
font->x_scale,
|
|
||||||
font->y_scale,
|
|
||||||
status);
|
|
||||||
if (status != LE_NO_ERROR) {
|
|
||||||
delete (data);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_hb_icu_le_shaper_font_data_destroy (hb_icu_le_shaper_font_data_t *data)
|
|
||||||
{
|
|
||||||
delete (data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* shaper shape_plan data
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct hb_icu_le_shaper_shape_plan_data_t {};
|
|
||||||
|
|
||||||
hb_icu_le_shaper_shape_plan_data_t *
|
|
||||||
_hb_icu_le_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
|
||||||
const hb_feature_t *user_features,
|
|
||||||
unsigned int num_user_features)
|
|
||||||
{
|
|
||||||
return (hb_icu_le_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_hb_icu_le_shaper_shape_plan_data_destroy (hb_icu_le_shaper_shape_plan_data_t *data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* shaper
|
|
||||||
*/
|
|
||||||
|
|
||||||
hb_bool_t
|
|
||||||
_hb_icu_le_shape (hb_shape_plan_t *shape_plan,
|
|
||||||
hb_font_t *font,
|
|
||||||
hb_buffer_t *buffer,
|
|
||||||
const hb_feature_t *features,
|
|
||||||
unsigned int num_features)
|
|
||||||
{
|
|
||||||
LEFontInstance *font_instance = HB_SHAPER_DATA_GET (font);
|
|
||||||
le_int32 script_code = hb_icu_script_from_script (shape_plan->props.script);
|
|
||||||
le_int32 language_code = -1 /* TODO */;
|
|
||||||
le_int32 typography_flags = 3; /* Needed for ligatures and kerning */
|
|
||||||
LEErrorCode status = LE_NO_ERROR;
|
|
||||||
le_engine *le = le_create ((const le_font *) font_instance,
|
|
||||||
script_code,
|
|
||||||
language_code,
|
|
||||||
typography_flags,
|
|
||||||
&status);
|
|
||||||
if (status != LE_NO_ERROR)
|
|
||||||
{ le_close (le); return false; }
|
|
||||||
|
|
||||||
retry:
|
|
||||||
|
|
||||||
unsigned int scratch_size;
|
|
||||||
char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
|
|
||||||
|
|
||||||
#define ALLOCATE_ARRAY(Type, name, len) \
|
|
||||||
Type *name = (Type *) scratch; \
|
|
||||||
scratch += (len) * sizeof ((name)[0]); \
|
|
||||||
scratch_size -= (len) * sizeof ((name)[0]);
|
|
||||||
|
|
||||||
ALLOCATE_ARRAY (LEUnicode, chars, buffer->len);
|
|
||||||
ALLOCATE_ARRAY (unsigned int, clusters, buffer->len);
|
|
||||||
|
|
||||||
/* XXX Use UTF-16 decoder! */
|
|
||||||
for (unsigned int i = 0; i < buffer->len; i++) {
|
|
||||||
chars[i] = buffer->info[i].codepoint;
|
|
||||||
clusters[i] = buffer->info[i].cluster;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int glyph_count = le_layoutChars (le,
|
|
||||||
chars,
|
|
||||||
0,
|
|
||||||
buffer->len,
|
|
||||||
buffer->len,
|
|
||||||
HB_DIRECTION_IS_BACKWARD (buffer->props.direction),
|
|
||||||
0., 0.,
|
|
||||||
&status);
|
|
||||||
if (status != LE_NO_ERROR)
|
|
||||||
{ le_close (le); return false; }
|
|
||||||
|
|
||||||
unsigned int num_glyphs = scratch_size / (sizeof (LEGlyphID) +
|
|
||||||
sizeof (le_int32) +
|
|
||||||
sizeof (float) * 2);
|
|
||||||
|
|
||||||
if (unlikely (glyph_count >= num_glyphs || glyph_count > buffer->allocated)) {
|
|
||||||
buffer->ensure (buffer->allocated * 2);
|
|
||||||
if (buffer->in_error)
|
|
||||||
{ le_close (le); return false; }
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
|
|
||||||
ALLOCATE_ARRAY (LEGlyphID, glyphs, glyph_count);
|
|
||||||
ALLOCATE_ARRAY (le_int32, indices, glyph_count);
|
|
||||||
ALLOCATE_ARRAY (float, positions, glyph_count * 2 + 2);
|
|
||||||
|
|
||||||
le_getGlyphs (le, glyphs, &status);
|
|
||||||
le_getCharIndices (le, indices, &status);
|
|
||||||
le_getGlyphPositions (le, positions, &status);
|
|
||||||
|
|
||||||
#undef ALLOCATE_ARRAY
|
|
||||||
|
|
||||||
/* Ok, we've got everything we need, now compose output buffer,
|
|
||||||
* very, *very*, carefully! */
|
|
||||||
|
|
||||||
unsigned int j = 0;
|
|
||||||
hb_glyph_info_t *info = buffer->info;
|
|
||||||
for (unsigned int i = 0; i < glyph_count; i++)
|
|
||||||
{
|
|
||||||
if (glyphs[i] >= 0xFFFE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
info[j].codepoint = glyphs[i];
|
|
||||||
info[j].cluster = clusters[indices[i]];
|
|
||||||
|
|
||||||
/* icu-le doesn't seem to have separate advance values. */
|
|
||||||
info[j].mask = positions[2 * i + 2] - positions[2 * i];
|
|
||||||
info[j].var1.u32 = 0;
|
|
||||||
info[j].var2.u32 = -positions[2 * i + 1];
|
|
||||||
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
buffer->len = j;
|
|
||||||
|
|
||||||
buffer->clear_positions ();
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < buffer->len; i++) {
|
|
||||||
hb_glyph_info_t *info = &buffer->info[i];
|
|
||||||
hb_glyph_position_t *pos = &buffer->pos[i];
|
|
||||||
|
|
||||||
/* TODO vertical */
|
|
||||||
pos->x_advance = info->mask;
|
|
||||||
pos->x_offset = info->var1.u32;
|
|
||||||
pos->y_offset = info->var2.u32;
|
|
||||||
}
|
|
||||||
|
|
||||||
le_close (le);
|
|
||||||
return true;
|
|
||||||
}
|
|
@ -323,7 +323,7 @@ hb_icu_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
|||||||
|
|
||||||
/* Copy @u into a UTF-16 array to be passed to ICU. */
|
/* Copy @u into a UTF-16 array to be passed to ICU. */
|
||||||
len = 0;
|
len = 0;
|
||||||
err = FALSE;
|
err = false;
|
||||||
U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), u, err);
|
U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), u, err);
|
||||||
if (err)
|
if (err)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -44,7 +44,6 @@
|
|||||||
|
|
||||||
#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
|
#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
typedef CRITICAL_SECTION hb_mutex_impl_t;
|
typedef CRITICAL_SECTION hb_mutex_impl_t;
|
||||||
#define HB_MUTEX_IMPL_INIT { NULL, 0, 0, NULL, NULL, 0 }
|
#define HB_MUTEX_IMPL_INIT { NULL, 0, 0, NULL, NULL, 0 }
|
||||||
|
@ -1,410 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright © 2012 Google, Inc.
|
|
||||||
*
|
|
||||||
* This is part of HarfBuzz, a text shaping library.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, without written agreement and without
|
|
||||||
* license or royalty fees, to use, copy, modify, and distribute this
|
|
||||||
* software and its documentation for any purpose, provided that the
|
|
||||||
* above copyright notice and the following two paragraphs appear in
|
|
||||||
* all copies of this software.
|
|
||||||
*
|
|
||||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
|
||||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
|
||||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
|
||||||
* DAMAGE.
|
|
||||||
*
|
|
||||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
|
||||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
|
||||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
|
||||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
|
||||||
*
|
|
||||||
* Google Author(s): Behdad Esfahbod
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define HB_SHAPER old
|
|
||||||
#define hb_old_shaper_face_data_t HB_FaceRec_
|
|
||||||
#define hb_old_shaper_font_data_t HB_Font_
|
|
||||||
#include "hb-shaper-impl-private.hh"
|
|
||||||
|
|
||||||
#include <harfbuzz.h>
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef HB_DEBUG_OLD
|
|
||||||
#define HB_DEBUG_OLD (HB_DEBUG+0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static HB_Script
|
|
||||||
hb_old_script_from_script (hb_script_t script)
|
|
||||||
{
|
|
||||||
switch ((hb_tag_t) script)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case HB_SCRIPT_COMMON: return HB_Script_Common;
|
|
||||||
case HB_SCRIPT_GREEK: return HB_Script_Greek;
|
|
||||||
case HB_SCRIPT_CYRILLIC: return HB_Script_Cyrillic;
|
|
||||||
case HB_SCRIPT_ARMENIAN: return HB_Script_Armenian;
|
|
||||||
case HB_SCRIPT_HEBREW: return HB_Script_Hebrew;
|
|
||||||
case HB_SCRIPT_ARABIC: return HB_Script_Arabic;
|
|
||||||
case HB_SCRIPT_SYRIAC: return HB_Script_Syriac;
|
|
||||||
case HB_SCRIPT_THAANA: return HB_Script_Thaana;
|
|
||||||
case HB_SCRIPT_DEVANAGARI: return HB_Script_Devanagari;
|
|
||||||
case HB_SCRIPT_BENGALI: return HB_Script_Bengali;
|
|
||||||
case HB_SCRIPT_GURMUKHI: return HB_Script_Gurmukhi;
|
|
||||||
case HB_SCRIPT_GUJARATI: return HB_Script_Gujarati;
|
|
||||||
case HB_SCRIPT_ORIYA: return HB_Script_Oriya;
|
|
||||||
case HB_SCRIPT_TAMIL: return HB_Script_Tamil;
|
|
||||||
case HB_SCRIPT_TELUGU: return HB_Script_Telugu;
|
|
||||||
case HB_SCRIPT_KANNADA: return HB_Script_Kannada;
|
|
||||||
case HB_SCRIPT_MALAYALAM: return HB_Script_Malayalam;
|
|
||||||
case HB_SCRIPT_SINHALA: return HB_Script_Sinhala;
|
|
||||||
case HB_SCRIPT_THAI: return HB_Script_Thai;
|
|
||||||
case HB_SCRIPT_LAO: return HB_Script_Lao;
|
|
||||||
case HB_SCRIPT_TIBETAN: return HB_Script_Tibetan;
|
|
||||||
case HB_SCRIPT_MYANMAR: return HB_Script_Myanmar;
|
|
||||||
case HB_SCRIPT_GEORGIAN: return HB_Script_Georgian;
|
|
||||||
case HB_SCRIPT_HANGUL: return HB_Script_Hangul;
|
|
||||||
case HB_SCRIPT_OGHAM: return HB_Script_Ogham;
|
|
||||||
case HB_SCRIPT_RUNIC: return HB_Script_Runic;
|
|
||||||
case HB_SCRIPT_KHMER: return HB_Script_Khmer;
|
|
||||||
case HB_SCRIPT_NKO: return HB_Script_Nko;
|
|
||||||
case HB_SCRIPT_INHERITED: return HB_Script_Inherited;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static HB_Bool
|
|
||||||
hb_old_convertStringToGlyphIndices (HB_Font old_font,
|
|
||||||
const HB_UChar16 *string,
|
|
||||||
hb_uint32 length,
|
|
||||||
HB_Glyph *glyphs,
|
|
||||||
hb_uint32 *numGlyphs,
|
|
||||||
HB_Bool rightToLeft)
|
|
||||||
{
|
|
||||||
hb_font_t *font = (hb_font_t *) old_font->userData;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < length; i++)
|
|
||||||
{
|
|
||||||
hb_codepoint_t u;
|
|
||||||
|
|
||||||
/* XXX Handle UTF-16. Ugh */
|
|
||||||
u = string[i];
|
|
||||||
|
|
||||||
if (rightToLeft)
|
|
||||||
u = hb_unicode_funcs_get_default ()->mirroring (u);
|
|
||||||
|
|
||||||
font->get_glyph (u, 0, &u); /* TODO Variation selectors */
|
|
||||||
|
|
||||||
glyphs[i] = u;
|
|
||||||
}
|
|
||||||
*numGlyphs = length; /* XXX */
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hb_old_getGlyphAdvances (HB_Font old_font,
|
|
||||||
const HB_Glyph *glyphs,
|
|
||||||
hb_uint32 numGlyphs,
|
|
||||||
HB_Fixed *advances,
|
|
||||||
int flags /*HB_ShaperFlag*/ HB_UNUSED)
|
|
||||||
{
|
|
||||||
hb_font_t *font = (hb_font_t *) old_font->userData;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < numGlyphs; i++)
|
|
||||||
advances[i] = font->get_glyph_h_advance (glyphs[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static HB_Bool
|
|
||||||
hb_old_canRender (HB_Font old_font,
|
|
||||||
const HB_UChar16 *string,
|
|
||||||
hb_uint32 length)
|
|
||||||
{
|
|
||||||
return true; /* TODO */
|
|
||||||
}
|
|
||||||
|
|
||||||
static HB_Error
|
|
||||||
hb_old_getPointInOutline (HB_Font old_font,
|
|
||||||
HB_Glyph glyph,
|
|
||||||
int flags /*HB_ShaperFlag*/,
|
|
||||||
hb_uint32 point,
|
|
||||||
HB_Fixed *xpos,
|
|
||||||
HB_Fixed *ypos,
|
|
||||||
hb_uint32 *nPoints)
|
|
||||||
{
|
|
||||||
return HB_Err_Ok; /* TODO */
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
hb_old_getGlyphMetrics (HB_Font old_font,
|
|
||||||
HB_Glyph glyph,
|
|
||||||
HB_GlyphMetrics *metrics)
|
|
||||||
{
|
|
||||||
hb_font_t *font = (hb_font_t *) old_font->userData;
|
|
||||||
|
|
||||||
hb_glyph_extents_t extents;
|
|
||||||
|
|
||||||
font->get_glyph_extents (glyph, &extents);
|
|
||||||
|
|
||||||
metrics->x = extents.x_bearing;
|
|
||||||
metrics->y = extents.y_bearing;
|
|
||||||
metrics->width = extents.width;
|
|
||||||
metrics->height = extents.height;
|
|
||||||
metrics->xOffset = font->get_glyph_h_advance (glyph);
|
|
||||||
metrics->yOffset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HB_Fixed
|
|
||||||
hb_old_getFontMetric (HB_Font old_font,
|
|
||||||
HB_FontMetric metric)
|
|
||||||
{
|
|
||||||
hb_font_t *font = (hb_font_t *) old_font->userData;
|
|
||||||
|
|
||||||
switch (metric)
|
|
||||||
{
|
|
||||||
case HB_FontAscent:
|
|
||||||
return font->y_scale; /* XXX We don't have ascent data yet. */
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const HB_FontClass hb_old_font_class = {
|
|
||||||
hb_old_convertStringToGlyphIndices,
|
|
||||||
hb_old_getGlyphAdvances,
|
|
||||||
hb_old_canRender,
|
|
||||||
hb_old_getPointInOutline,
|
|
||||||
hb_old_getGlyphMetrics,
|
|
||||||
hb_old_getFontMetric
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static HB_Error
|
|
||||||
table_func (void *font, HB_Tag tag, HB_Byte *buffer, HB_UInt *length)
|
|
||||||
{
|
|
||||||
hb_face_t *face = (hb_face_t *) font;
|
|
||||||
hb_blob_t *blob = face->reference_table ((hb_tag_t) tag);
|
|
||||||
unsigned int capacity = *length;
|
|
||||||
*length = hb_blob_get_length (blob);
|
|
||||||
memcpy (buffer, hb_blob_get_data (blob, NULL), MIN (capacity, *length));
|
|
||||||
hb_blob_destroy (blob);
|
|
||||||
return HB_Err_Ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* shaper face data
|
|
||||||
*/
|
|
||||||
|
|
||||||
hb_old_shaper_face_data_t *
|
|
||||||
_hb_old_shaper_face_data_create (hb_face_t *face)
|
|
||||||
{
|
|
||||||
return HB_NewFace (face, table_func);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_hb_old_shaper_face_data_destroy (hb_old_shaper_face_data_t *data)
|
|
||||||
{
|
|
||||||
HB_FreeFace (data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* shaper font data
|
|
||||||
*/
|
|
||||||
|
|
||||||
hb_old_shaper_font_data_t *
|
|
||||||
_hb_old_shaper_font_data_create (hb_font_t *font)
|
|
||||||
{
|
|
||||||
HB_FontRec *data = (HB_FontRec *) calloc (1, sizeof (HB_FontRec));
|
|
||||||
if (unlikely (!data)) {
|
|
||||||
DEBUG_MSG (OLD, font, "malloc()ing HB_Font failed");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
data->klass = &hb_old_font_class;
|
|
||||||
data->x_ppem = font->x_ppem;
|
|
||||||
data->y_ppem = font->y_ppem;
|
|
||||||
data->x_scale = font->x_scale; /* XXX */
|
|
||||||
data->y_scale = font->y_scale; /* XXX */
|
|
||||||
data->userData = font;
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_hb_old_shaper_font_data_destroy (hb_old_shaper_font_data_t *data)
|
|
||||||
{
|
|
||||||
free (data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* shaper shape_plan data
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct hb_old_shaper_shape_plan_data_t {};
|
|
||||||
|
|
||||||
hb_old_shaper_shape_plan_data_t *
|
|
||||||
_hb_old_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
|
||||||
const hb_feature_t *user_features HB_UNUSED,
|
|
||||||
unsigned int num_user_features HB_UNUSED)
|
|
||||||
{
|
|
||||||
return (hb_old_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_hb_old_shaper_shape_plan_data_destroy (hb_old_shaper_shape_plan_data_t *data HB_UNUSED)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* shaper
|
|
||||||
*/
|
|
||||||
|
|
||||||
hb_bool_t
|
|
||||||
_hb_old_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
|
|
||||||
hb_font_t *font,
|
|
||||||
hb_buffer_t *buffer,
|
|
||||||
const hb_feature_t *features,
|
|
||||||
unsigned int num_features)
|
|
||||||
{
|
|
||||||
hb_face_t *face = font->face;
|
|
||||||
HB_Face old_face = HB_SHAPER_DATA_GET (face);
|
|
||||||
HB_Font old_font = HB_SHAPER_DATA_GET (font);
|
|
||||||
|
|
||||||
bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
|
|
||||||
|
|
||||||
retry:
|
|
||||||
|
|
||||||
unsigned int scratch_size;
|
|
||||||
char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
|
|
||||||
|
|
||||||
#define utf16_index() var1.u32
|
|
||||||
HB_UChar16 *pchars = (HB_UChar16 *) scratch;
|
|
||||||
unsigned int chars_len = 0;
|
|
||||||
for (unsigned int i = 0; i < buffer->len; i++) {
|
|
||||||
hb_codepoint_t c = buffer->info[i].codepoint;
|
|
||||||
buffer->info[i].utf16_index() = chars_len;
|
|
||||||
if (likely (c < 0x10000))
|
|
||||||
pchars[chars_len++] = c;
|
|
||||||
else if (unlikely (c >= 0x110000))
|
|
||||||
pchars[chars_len++] = 0xFFFD;
|
|
||||||
else {
|
|
||||||
pchars[chars_len++] = 0xD800 + ((c - 0x10000) >> 10);
|
|
||||||
pchars[chars_len++] = 0xDC00 + ((c - 0x10000) & ((1 << 10) - 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define ALLOCATE_ARRAY(Type, name, len) \
|
|
||||||
name = (Type *) scratch; \
|
|
||||||
scratch += (len) * sizeof ((name)[0]); \
|
|
||||||
scratch_size -= (len) * sizeof ((name)[0]);
|
|
||||||
|
|
||||||
|
|
||||||
HB_ShaperItem item = {0};
|
|
||||||
|
|
||||||
ALLOCATE_ARRAY (const HB_UChar16, item.string, chars_len);
|
|
||||||
ALLOCATE_ARRAY (unsigned short, item.log_clusters, chars_len + 2);
|
|
||||||
item.stringLength = chars_len;
|
|
||||||
item.item.pos = 0;
|
|
||||||
item.item.length = item.stringLength;
|
|
||||||
item.item.script = hb_old_script_from_script (buffer->props.script);
|
|
||||||
item.item.bidiLevel = backward ? 1 : 0;
|
|
||||||
|
|
||||||
item.font = old_font;
|
|
||||||
item.face = old_face;
|
|
||||||
item.shaperFlags = 0;
|
|
||||||
|
|
||||||
item.glyphIndicesPresent = false;
|
|
||||||
|
|
||||||
/* TODO Alignment. */
|
|
||||||
unsigned int num_glyphs = scratch_size / (sizeof (HB_Glyph) +
|
|
||||||
sizeof (HB_GlyphAttributes) +
|
|
||||||
sizeof (HB_Fixed) +
|
|
||||||
sizeof (HB_FixedPoint) +
|
|
||||||
sizeof (uint32_t));
|
|
||||||
|
|
||||||
item.num_glyphs = num_glyphs;
|
|
||||||
ALLOCATE_ARRAY (HB_Glyph, item.glyphs, num_glyphs);
|
|
||||||
ALLOCATE_ARRAY (HB_GlyphAttributes, item.attributes, num_glyphs);
|
|
||||||
ALLOCATE_ARRAY (HB_Fixed, item.advances, num_glyphs);
|
|
||||||
ALLOCATE_ARRAY (HB_FixedPoint, item.offsets, num_glyphs);
|
|
||||||
/* Apparently in some cases the offsets array will not be fully assigned to.
|
|
||||||
* Clear it. */
|
|
||||||
memset (item.offsets, 0, num_glyphs * sizeof (item.offsets[0]));
|
|
||||||
uint32_t *vis_clusters;
|
|
||||||
ALLOCATE_ARRAY (uint32_t, vis_clusters, num_glyphs);
|
|
||||||
|
|
||||||
#undef ALLOCATE_ARRAY
|
|
||||||
|
|
||||||
if (!HB_ShapeItem (&item))
|
|
||||||
{
|
|
||||||
if (unlikely (item.num_glyphs > num_glyphs))
|
|
||||||
{
|
|
||||||
buffer->ensure (buffer->allocated * 2);
|
|
||||||
if (buffer->in_error)
|
|
||||||
return false;
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
num_glyphs = item.num_glyphs;
|
|
||||||
|
|
||||||
/* Ok, we've got everything we need, now compose output buffer,
|
|
||||||
* very, *very*, carefully! */
|
|
||||||
|
|
||||||
/* Calculate visual-clusters. That's what we ship. */
|
|
||||||
for (unsigned int i = 0; i < num_glyphs; i++)
|
|
||||||
vis_clusters[i] = -1;
|
|
||||||
for (unsigned int i = 0; i < buffer->len; i++) {
|
|
||||||
uint32_t *p = &vis_clusters[item.log_clusters[buffer->info[i].utf16_index()]];
|
|
||||||
*p = MIN (*p, buffer->info[i].cluster);
|
|
||||||
}
|
|
||||||
for (unsigned int i = 1; i < num_glyphs; i++)
|
|
||||||
if (vis_clusters[i] == (uint32_t) -1)
|
|
||||||
vis_clusters[i] = vis_clusters[i - 1];
|
|
||||||
|
|
||||||
#undef utf16_index
|
|
||||||
|
|
||||||
buffer->ensure (num_glyphs);
|
|
||||||
if (buffer->in_error)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
|
|
||||||
buffer->len = num_glyphs;
|
|
||||||
hb_glyph_info_t *info = buffer->info;
|
|
||||||
for (unsigned int i = 0; i < num_glyphs; i++)
|
|
||||||
{
|
|
||||||
info[i].codepoint = item.glyphs[i];
|
|
||||||
info[i].cluster = vis_clusters[i];
|
|
||||||
|
|
||||||
info[i].mask = item.advances[i];
|
|
||||||
info[i].var1.u32 = item.offsets[i].x;
|
|
||||||
info[i].var2.u32 = item.offsets[i].y;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer->clear_positions ();
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < num_glyphs; ++i) {
|
|
||||||
hb_glyph_info_t *info = &buffer->info[i];
|
|
||||||
hb_glyph_position_t *pos = &buffer->pos[i];
|
|
||||||
|
|
||||||
/* TODO vertical */
|
|
||||||
pos->x_advance = info->mask;
|
|
||||||
pos->x_offset = info->var1.u32;
|
|
||||||
pos->y_offset = info->var2.u32;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
|
|
||||||
buffer->reverse ();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
@ -110,9 +110,9 @@ typedef struct OffsetTable
|
|||||||
protected:
|
protected:
|
||||||
Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */
|
Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */
|
||||||
USHORT numTables; /* Number of tables. */
|
USHORT numTables; /* Number of tables. */
|
||||||
USHORT searchRange; /* (Maximum power of 2 <= numTables) x 16 */
|
USHORT searchRangeZ; /* (Maximum power of 2 <= numTables) x 16 */
|
||||||
USHORT entrySelector; /* Log2(maximum power of 2 <= numTables). */
|
USHORT entrySelectorZ; /* Log2(maximum power of 2 <= numTables). */
|
||||||
USHORT rangeShift; /* NumTables x 16-searchRange. */
|
USHORT rangeShiftZ; /* NumTables x 16-searchRange. */
|
||||||
TableRecord tables[VAR]; /* TableRecord entries. numTables items */
|
TableRecord tables[VAR]; /* TableRecord entries. numTables items */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (12, tables);
|
DEFINE_SIZE_ARRAY (12, tables);
|
||||||
@ -138,8 +138,8 @@ struct TTCHeaderVersion1
|
|||||||
protected:
|
protected:
|
||||||
Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
|
Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
|
||||||
FixedVersion version; /* Version of the TTC Header (1.0),
|
FixedVersion version; /* Version of the TTC Header (1.0),
|
||||||
* 0x00010000 */
|
* 0x00010000u */
|
||||||
LongOffsetLongArrayOf<OffsetTable>
|
ArrayOf<OffsetTo<OffsetTable, ULONG>, ULONG>
|
||||||
table; /* Array of offsets to the OffsetTable for each font
|
table; /* Array of offsets to the OffsetTable for each font
|
||||||
* from the beginning of the file */
|
* from the beginning of the file */
|
||||||
public:
|
public:
|
||||||
@ -184,7 +184,7 @@ struct TTCHeader
|
|||||||
struct {
|
struct {
|
||||||
Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
|
Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
|
||||||
FixedVersion version; /* Version of the TTC Header (1.0 or 2.0),
|
FixedVersion version; /* Version of the TTC Header (1.0 or 2.0),
|
||||||
* 0x00010000 or 0x00020000 */
|
* 0x00010000u or 0x00020000u */
|
||||||
} header;
|
} header;
|
||||||
TTCHeaderVersion1 version1;
|
TTCHeaderVersion1 version1;
|
||||||
} u;
|
} u;
|
||||||
|
@ -42,36 +42,36 @@ namespace OT {
|
|||||||
|
|
||||||
/* Cast to struct T, reference to reference */
|
/* Cast to struct T, reference to reference */
|
||||||
template<typename Type, typename TObject>
|
template<typename Type, typename TObject>
|
||||||
inline const Type& CastR(const TObject &X)
|
static inline const Type& CastR(const TObject &X)
|
||||||
{ return reinterpret_cast<const Type&> (X); }
|
{ return reinterpret_cast<const Type&> (X); }
|
||||||
template<typename Type, typename TObject>
|
template<typename Type, typename TObject>
|
||||||
inline Type& CastR(TObject &X)
|
static inline Type& CastR(TObject &X)
|
||||||
{ return reinterpret_cast<Type&> (X); }
|
{ return reinterpret_cast<Type&> (X); }
|
||||||
|
|
||||||
/* Cast to struct T, pointer to pointer */
|
/* Cast to struct T, pointer to pointer */
|
||||||
template<typename Type, typename TObject>
|
template<typename Type, typename TObject>
|
||||||
inline const Type* CastP(const TObject *X)
|
static inline const Type* CastP(const TObject *X)
|
||||||
{ return reinterpret_cast<const Type*> (X); }
|
{ return reinterpret_cast<const Type*> (X); }
|
||||||
template<typename Type, typename TObject>
|
template<typename Type, typename TObject>
|
||||||
inline Type* CastP(TObject *X)
|
static inline Type* CastP(TObject *X)
|
||||||
{ return reinterpret_cast<Type*> (X); }
|
{ return reinterpret_cast<Type*> (X); }
|
||||||
|
|
||||||
/* StructAtOffset<T>(P,Ofs) returns the struct T& that is placed at memory
|
/* StructAtOffset<T>(P,Ofs) returns the struct T& that is placed at memory
|
||||||
* location pointed to by P plus Ofs bytes. */
|
* location pointed to by P plus Ofs bytes. */
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
inline const Type& StructAtOffset(const void *P, unsigned int offset)
|
static inline const Type& StructAtOffset(const void *P, unsigned int offset)
|
||||||
{ return * reinterpret_cast<const Type*> ((const char *) P + offset); }
|
{ return * reinterpret_cast<const Type*> ((const char *) P + offset); }
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
inline Type& StructAtOffset(void *P, unsigned int offset)
|
static inline Type& StructAtOffset(void *P, unsigned int offset)
|
||||||
{ return * reinterpret_cast<Type*> ((char *) P + offset); }
|
{ return * reinterpret_cast<Type*> ((char *) P + offset); }
|
||||||
|
|
||||||
/* StructAfter<T>(X) returns the struct T& that is placed after X.
|
/* StructAfter<T>(X) returns the struct T& that is placed after X.
|
||||||
* Works with X of variable size also. X must implement get_size() */
|
* Works with X of variable size also. X must implement get_size() */
|
||||||
template<typename Type, typename TObject>
|
template<typename Type, typename TObject>
|
||||||
inline const Type& StructAfter(const TObject &X)
|
static inline const Type& StructAfter(const TObject &X)
|
||||||
{ return StructAtOffset<Type>(&X, X.get_size()); }
|
{ return StructAtOffset<Type>(&X, X.get_size()); }
|
||||||
template<typename Type, typename TObject>
|
template<typename Type, typename TObject>
|
||||||
inline Type& StructAfter(TObject &X)
|
static inline Type& StructAfter(TObject &X)
|
||||||
{ return StructAtOffset<Type>(&X, X.get_size()); }
|
{ return StructAtOffset<Type>(&X, X.get_size()); }
|
||||||
|
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ inline Type& StructAfter(TObject &X)
|
|||||||
|
|
||||||
/* Global nul-content Null pool. Enlarge as necessary. */
|
/* Global nul-content Null pool. Enlarge as necessary. */
|
||||||
/* TODO This really should be a extern HB_INTERNAL and defined somewhere... */
|
/* TODO This really should be a extern HB_INTERNAL and defined somewhere... */
|
||||||
static const void *_NullPool[64 / sizeof (void *)];
|
static const void *_NullPool[(256+8) / sizeof (void *)];
|
||||||
|
|
||||||
/* Generic nul-content Null objects. */
|
/* Generic nul-content Null objects. */
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
@ -145,7 +145,7 @@ static inline const Type& Null (void) {
|
|||||||
#define DEFINE_NULL_DATA(Type, data) \
|
#define DEFINE_NULL_DATA(Type, data) \
|
||||||
static const char _Null##Type[sizeof (Type) + 1] = data; /* +1 is for nul-termination in data */ \
|
static const char _Null##Type[sizeof (Type) + 1] = data; /* +1 is for nul-termination in data */ \
|
||||||
template <> \
|
template <> \
|
||||||
inline const Type& Null<Type> (void) { \
|
/*static*/ inline const Type& Null<Type> (void) { \
|
||||||
return *CastP<Type> (_Null##Type); \
|
return *CastP<Type> (_Null##Type); \
|
||||||
} /* The following line really exists such that we end in a place needing semicolon */ \
|
} /* The following line really exists such that we end in a place needing semicolon */ \
|
||||||
ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type))
|
ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type))
|
||||||
@ -266,6 +266,15 @@ struct hb_sanitize_context_t
|
|||||||
return TRACE_RETURN (this->writable);
|
return TRACE_RETURN (this->writable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Type, typename ValueType>
|
||||||
|
inline bool try_set (Type *obj, const ValueType &v) {
|
||||||
|
if (this->may_edit (obj, obj->static_size)) {
|
||||||
|
obj->set (v);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
mutable unsigned int debug_depth;
|
mutable unsigned int debug_depth;
|
||||||
const char *start, *end;
|
const char *start, *end;
|
||||||
bool writable;
|
bool writable;
|
||||||
@ -280,7 +289,7 @@ template <typename Type>
|
|||||||
struct Sanitizer
|
struct Sanitizer
|
||||||
{
|
{
|
||||||
static hb_blob_t *sanitize (hb_blob_t *blob) {
|
static hb_blob_t *sanitize (hb_blob_t *blob) {
|
||||||
hb_sanitize_context_t c[1] = {{0}};
|
hb_sanitize_context_t c[1] = {{0, NULL, NULL, false, 0, NULL}};
|
||||||
bool sane;
|
bool sane;
|
||||||
|
|
||||||
/* TODO is_sane() stuff */
|
/* TODO is_sane() stuff */
|
||||||
@ -572,6 +581,7 @@ struct IntType
|
|||||||
DEFINE_SIZE_STATIC (Size);
|
DEFINE_SIZE_STATIC (Size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef uint8_t BYTE; /* 8-bit unsigned integer. */
|
||||||
typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */
|
typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */
|
||||||
typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */
|
typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */
|
||||||
typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */
|
typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */
|
||||||
@ -616,24 +626,17 @@ typedef USHORT GlyphID;
|
|||||||
|
|
||||||
/* Script/language-system/feature index */
|
/* Script/language-system/feature index */
|
||||||
struct Index : USHORT {
|
struct Index : USHORT {
|
||||||
static const unsigned int NOT_FOUND_INDEX = 0xFFFF;
|
static const unsigned int NOT_FOUND_INDEX = 0xFFFFu;
|
||||||
};
|
};
|
||||||
DEFINE_NULL_DATA (Index, "\xff\xff");
|
DEFINE_NULL_DATA (Index, "\xff\xff");
|
||||||
|
|
||||||
/* Offset to a table, same as uint16 (length = 16 bits), Null offset = 0x0000 */
|
/* Offset, Null offset = 0 */
|
||||||
struct Offset : USHORT
|
template <typename Type=USHORT>
|
||||||
|
struct Offset : Type
|
||||||
{
|
{
|
||||||
inline bool is_null (void) const { return 0 == *this; }
|
inline bool is_null (void) const { return 0 == *this; }
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (2);
|
DEFINE_SIZE_STATIC (sizeof(Type));
|
||||||
};
|
|
||||||
|
|
||||||
/* LongOffset to a table, same as uint32 (length = 32 bits), Null offset = 0x00000000 */
|
|
||||||
struct LongOffset : ULONG
|
|
||||||
{
|
|
||||||
inline bool is_null (void) const { return 0 == *this; }
|
|
||||||
public:
|
|
||||||
DEFINE_SIZE_STATIC (4);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -682,12 +685,12 @@ struct FixedVersion
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Template subclasses of Offset and LongOffset that do the dereferencing.
|
* Template subclasses of Offset that do the dereferencing.
|
||||||
* Use: (base+offset)
|
* Use: (base+offset)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <typename OffsetType, typename Type>
|
template <typename Type, typename OffsetType=USHORT>
|
||||||
struct GenericOffsetTo : OffsetType
|
struct OffsetTo : Offset<OffsetType>
|
||||||
{
|
{
|
||||||
inline const Type& operator () (const void *base) const
|
inline const Type& operator () (const void *base) const
|
||||||
{
|
{
|
||||||
@ -721,40 +724,25 @@ struct GenericOffsetTo : OffsetType
|
|||||||
return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c));
|
return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool try_set (hb_sanitize_context_t *c, const OffsetType &v) {
|
|
||||||
if (c->may_edit (this, this->static_size)) {
|
|
||||||
this->set (v);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
/* Set the offset to Null */
|
/* Set the offset to Null */
|
||||||
inline bool neuter (hb_sanitize_context_t *c) {
|
inline bool neuter (hb_sanitize_context_t *c) {
|
||||||
if (c->may_edit (this, this->static_size)) {
|
return c->try_set (this, 0);
|
||||||
this->set (0); /* 0 is Null offset */
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
DEFINE_SIZE_STATIC (sizeof(OffsetType));
|
||||||
};
|
};
|
||||||
template <typename Base, typename OffsetType, typename Type>
|
template <typename Base, typename OffsetType, typename Type>
|
||||||
inline const Type& operator + (const Base &base, const GenericOffsetTo<OffsetType, Type> &offset) { return offset (base); }
|
static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType> &offset) { return offset (base); }
|
||||||
template <typename Base, typename OffsetType, typename Type>
|
template <typename Base, typename OffsetType, typename Type>
|
||||||
inline Type& operator + (Base &base, GenericOffsetTo<OffsetType, Type> &offset) { return offset (base); }
|
static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset) { return offset (base); }
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
struct OffsetTo : GenericOffsetTo<Offset, Type> {};
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
struct LongOffsetTo : GenericOffsetTo<LongOffset, Type> {};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Array Types
|
* Array Types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <typename LenType, typename Type>
|
/* An array with a number of elements. */
|
||||||
struct GenericArrayOf
|
template <typename Type, typename LenType=USHORT>
|
||||||
|
struct ArrayOf
|
||||||
{
|
{
|
||||||
const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const
|
const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const
|
||||||
{
|
{
|
||||||
@ -837,6 +825,16 @@ struct GenericArrayOf
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename SearchType>
|
||||||
|
inline int lsearch (const SearchType &x) const
|
||||||
|
{
|
||||||
|
unsigned int count = len;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
if (!this->array[i].cmp (x))
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline bool sanitize_shallow (hb_sanitize_context_t *c) {
|
inline bool sanitize_shallow (hb_sanitize_context_t *c) {
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
@ -850,26 +848,10 @@ struct GenericArrayOf
|
|||||||
DEFINE_SIZE_ARRAY (sizeof (LenType), array);
|
DEFINE_SIZE_ARRAY (sizeof (LenType), array);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* An array with a USHORT number of elements. */
|
|
||||||
template <typename Type>
|
|
||||||
struct ArrayOf : GenericArrayOf<USHORT, Type> {};
|
|
||||||
|
|
||||||
/* An array with a ULONG number of elements. */
|
|
||||||
template <typename Type>
|
|
||||||
struct LongArrayOf : GenericArrayOf<ULONG, Type> {};
|
|
||||||
|
|
||||||
/* Array of Offset's */
|
/* Array of Offset's */
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
struct OffsetArrayOf : ArrayOf<OffsetTo<Type> > {};
|
struct OffsetArrayOf : ArrayOf<OffsetTo<Type> > {};
|
||||||
|
|
||||||
/* Array of LongOffset's */
|
|
||||||
template <typename Type>
|
|
||||||
struct LongOffsetArrayOf : ArrayOf<LongOffsetTo<Type> > {};
|
|
||||||
|
|
||||||
/* LongArray of LongOffset's */
|
|
||||||
template <typename Type>
|
|
||||||
struct LongOffsetLongArrayOf : LongArrayOf<LongOffsetTo<Type> > {};
|
|
||||||
|
|
||||||
/* Array of offsets relative to the beginning of the array itself. */
|
/* Array of offsets relative to the beginning of the array itself. */
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
struct OffsetListOf : OffsetArrayOf<Type>
|
struct OffsetListOf : OffsetArrayOf<Type>
|
||||||
@ -892,9 +874,8 @@ struct OffsetListOf : OffsetArrayOf<Type>
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* An array with a USHORT number of elements,
|
/* An array starting at second element. */
|
||||||
* starting at second element. */
|
template <typename Type, typename LenType=USHORT>
|
||||||
template <typename Type>
|
|
||||||
struct HeadlessArrayOf
|
struct HeadlessArrayOf
|
||||||
{
|
{
|
||||||
inline const Type& operator [] (unsigned int i) const
|
inline const Type& operator [] (unsigned int i) const
|
||||||
@ -941,19 +922,19 @@ struct HeadlessArrayOf
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
USHORT len;
|
LenType len;
|
||||||
Type array[VAR];
|
Type array[VAR];
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (sizeof (USHORT), array);
|
DEFINE_SIZE_ARRAY (sizeof (LenType), array);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* An array with sorted elements. Supports binary searching. */
|
/* An array with sorted elements. Supports binary searching. */
|
||||||
template <typename Type>
|
template <typename Type, typename LenType=USHORT>
|
||||||
struct SortedArrayOf : ArrayOf<Type> {
|
struct SortedArrayOf : ArrayOf<Type, LenType>
|
||||||
|
{
|
||||||
template <typename SearchType>
|
template <typename SearchType>
|
||||||
inline int search (const SearchType &x) const
|
inline int bsearch (const SearchType &x) const
|
||||||
{
|
{
|
||||||
/* Hand-coded bsearch here since this is in the hot inner loop. */
|
/* Hand-coded bsearch here since this is in the hot inner loop. */
|
||||||
int min = 0, max = (int) this->len - 1;
|
int min = 0, max = (int) this->len - 1;
|
||||||
|
517
gfx/harfbuzz/src/hb-ot-cmap-table.hh
Normal file
517
gfx/harfbuzz/src/hb-ot-cmap-table.hh
Normal file
@ -0,0 +1,517 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2014 Google, Inc.
|
||||||
|
*
|
||||||
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, without written agreement and without
|
||||||
|
* license or royalty fees, to use, copy, modify, and distribute this
|
||||||
|
* software and its documentation for any purpose, provided that the
|
||||||
|
* above copyright notice and the following two paragraphs appear in
|
||||||
|
* all copies of this software.
|
||||||
|
*
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||||
|
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||||
|
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||||
|
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||||
|
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
|
*
|
||||||
|
* Google Author(s): Behdad Esfahbod
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HB_OT_CMAP_TABLE_HH
|
||||||
|
#define HB_OT_CMAP_TABLE_HH
|
||||||
|
|
||||||
|
#include "hb-open-type-private.hh"
|
||||||
|
|
||||||
|
|
||||||
|
namespace OT {
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cmap -- Character To Glyph Index Mapping Table
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define HB_OT_TAG_cmap HB_TAG('c','m','a','p')
|
||||||
|
|
||||||
|
|
||||||
|
struct CmapSubtableFormat0
|
||||||
|
{
|
||||||
|
inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
|
||||||
|
{
|
||||||
|
hb_codepoint_t gid = codepoint < 256 ? glyphIdArray[codepoint] : 0;
|
||||||
|
if (!gid)
|
||||||
|
return false;
|
||||||
|
*glyph = gid;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
return TRACE_RETURN (c->check_struct (this));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
USHORT format; /* Format number is set to 0. */
|
||||||
|
USHORT lengthZ; /* Byte length of this subtable. */
|
||||||
|
USHORT languageZ; /* Ignore. */
|
||||||
|
BYTE glyphIdArray[256];/* An array that maps character
|
||||||
|
* code to glyph index values. */
|
||||||
|
public:
|
||||||
|
DEFINE_SIZE_STATIC (6 + 256);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CmapSubtableFormat4
|
||||||
|
{
|
||||||
|
inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
|
||||||
|
{
|
||||||
|
unsigned int segCount;
|
||||||
|
const USHORT *endCount;
|
||||||
|
const USHORT *startCount;
|
||||||
|
const USHORT *idDelta;
|
||||||
|
const USHORT *idRangeOffset;
|
||||||
|
const USHORT *glyphIdArray;
|
||||||
|
unsigned int glyphIdArrayLength;
|
||||||
|
|
||||||
|
segCount = this->segCountX2 / 2;
|
||||||
|
endCount = this->values;
|
||||||
|
startCount = endCount + segCount + 1;
|
||||||
|
idDelta = startCount + segCount;
|
||||||
|
idRangeOffset = idDelta + segCount;
|
||||||
|
glyphIdArray = idRangeOffset + segCount;
|
||||||
|
glyphIdArrayLength = (this->length - 16 - 8 * segCount) / 2;
|
||||||
|
|
||||||
|
/* Custom two-array bsearch. */
|
||||||
|
int min = 0, max = (int) segCount - 1;
|
||||||
|
unsigned int i;
|
||||||
|
while (min <= max)
|
||||||
|
{
|
||||||
|
int mid = (min + max) / 2;
|
||||||
|
if (codepoint < startCount[mid])
|
||||||
|
max = mid - 1;
|
||||||
|
else if (codepoint > endCount[mid])
|
||||||
|
min = mid + 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i = mid;
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
found:
|
||||||
|
hb_codepoint_t gid;
|
||||||
|
unsigned int rangeOffset = idRangeOffset[i];
|
||||||
|
if (rangeOffset == 0)
|
||||||
|
gid = codepoint + idDelta[i];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Somebody has been smoking... */
|
||||||
|
unsigned int index = rangeOffset / 2 + (codepoint - startCount[i]) + i - segCount;
|
||||||
|
if (unlikely (index >= glyphIdArrayLength))
|
||||||
|
return false;
|
||||||
|
gid = glyphIdArray[index];
|
||||||
|
if (unlikely (!gid))
|
||||||
|
return false;
|
||||||
|
gid += idDelta[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
*glyph = gid & 0xFFFFu;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c)
|
||||||
|
{
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
if (unlikely (!c->check_struct (this)))
|
||||||
|
return TRACE_RETURN (false);
|
||||||
|
|
||||||
|
if (unlikely (!c->check_range (this, length)))
|
||||||
|
{
|
||||||
|
/* Some broken fonts have too long of a "length" value.
|
||||||
|
* If that is the case, just change the value to truncate
|
||||||
|
* the subtable at the end of the blob. */
|
||||||
|
uint16_t new_length = (uint16_t) MIN ((uintptr_t) 65535,
|
||||||
|
(uintptr_t) (c->end -
|
||||||
|
(char *) this));
|
||||||
|
if (!c->try_set (&length, new_length))
|
||||||
|
return TRACE_RETURN (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRACE_RETURN (16 + 4 * (unsigned int) segCountX2 <= length);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
USHORT format; /* Format number is set to 4. */
|
||||||
|
USHORT length; /* This is the length in bytes of the
|
||||||
|
* subtable. */
|
||||||
|
USHORT languageZ; /* Ignore. */
|
||||||
|
USHORT segCountX2; /* 2 x segCount. */
|
||||||
|
USHORT searchRangeZ; /* 2 * (2**floor(log2(segCount))) */
|
||||||
|
USHORT entrySelectorZ; /* log2(searchRange/2) */
|
||||||
|
USHORT rangeShiftZ; /* 2 x segCount - searchRange */
|
||||||
|
|
||||||
|
USHORT values[VAR];
|
||||||
|
#if 0
|
||||||
|
USHORT endCount[segCount]; /* End characterCode for each segment,
|
||||||
|
* last=0xFFFFu. */
|
||||||
|
USHORT reservedPad; /* Set to 0. */
|
||||||
|
USHORT startCount[segCount]; /* Start character code for each segment. */
|
||||||
|
SHORT idDelta[segCount]; /* Delta for all character codes in segment. */
|
||||||
|
USHORT idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */
|
||||||
|
USHORT glyphIdArray[VAR]; /* Glyph index array (arbitrary length) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
DEFINE_SIZE_ARRAY (14, values);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CmapSubtableLongGroup
|
||||||
|
{
|
||||||
|
friend struct CmapSubtableFormat12;
|
||||||
|
friend struct CmapSubtableFormat13;
|
||||||
|
|
||||||
|
int cmp (hb_codepoint_t codepoint) const
|
||||||
|
{
|
||||||
|
if (codepoint < startCharCode) return -1;
|
||||||
|
if (codepoint > endCharCode) return +1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
return TRACE_RETURN (c->check_struct (this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ULONG startCharCode; /* First character code in this group. */
|
||||||
|
ULONG endCharCode; /* Last character code in this group. */
|
||||||
|
ULONG glyphID; /* Glyph index; interpretation depends on
|
||||||
|
* subtable format. */
|
||||||
|
public:
|
||||||
|
DEFINE_SIZE_STATIC (12);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename UINT>
|
||||||
|
struct CmapSubtableTrimmed
|
||||||
|
{
|
||||||
|
inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
|
||||||
|
{
|
||||||
|
/* Rely on our implicit array bound-checking. */
|
||||||
|
hb_codepoint_t gid = glyphIdArray[codepoint - startCharCode];
|
||||||
|
if (!gid)
|
||||||
|
return false;
|
||||||
|
*glyph = gid;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
return TRACE_RETURN (c->check_struct (this) && glyphIdArray.sanitize (c));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
UINT formatReserved; /* Subtable format and (maybe) padding. */
|
||||||
|
UINT lengthZ; /* Byte length of this subtable. */
|
||||||
|
UINT languageZ; /* Ignore. */
|
||||||
|
UINT startCharCode; /* First character code covered. */
|
||||||
|
ArrayOf<GlyphID, UINT>
|
||||||
|
glyphIdArray; /* Array of glyph index values for character
|
||||||
|
* codes in the range. */
|
||||||
|
public:
|
||||||
|
DEFINE_SIZE_ARRAY (5 * sizeof (UINT), glyphIdArray);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CmapSubtableFormat6 : CmapSubtableTrimmed<USHORT> {};
|
||||||
|
struct CmapSubtableFormat10 : CmapSubtableTrimmed<ULONG > {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct CmapSubtableLongSegmented
|
||||||
|
{
|
||||||
|
inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
|
||||||
|
{
|
||||||
|
int i = groups.bsearch (codepoint);
|
||||||
|
if (i == -1)
|
||||||
|
return false;
|
||||||
|
*glyph = T::group_get_glyph (groups[i], codepoint);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
return TRACE_RETURN (c->check_struct (this) && groups.sanitize (c));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
USHORT format; /* Subtable format; set to 12. */
|
||||||
|
USHORT reservedZ; /* Reserved; set to 0. */
|
||||||
|
ULONG lengthZ; /* Byte length of this subtable. */
|
||||||
|
ULONG languageZ; /* Ignore. */
|
||||||
|
SortedArrayOf<CmapSubtableLongGroup, ULONG>
|
||||||
|
groups; /* Groupings. */
|
||||||
|
public:
|
||||||
|
DEFINE_SIZE_ARRAY (16, groups);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
|
||||||
|
{
|
||||||
|
static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
|
||||||
|
hb_codepoint_t u)
|
||||||
|
{ return group.glyphID + (u - group.startCharCode); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CmapSubtableFormat13 : CmapSubtableLongSegmented<CmapSubtableFormat13>
|
||||||
|
{
|
||||||
|
static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
|
||||||
|
hb_codepoint_t u HB_UNUSED)
|
||||||
|
{ return group.glyphID; }
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GLYPH_VARIANT_NOT_FOUND = 0,
|
||||||
|
GLYPH_VARIANT_FOUND = 1,
|
||||||
|
GLYPH_VARIANT_USE_DEFAULT = 2
|
||||||
|
} glyph_variant_t;
|
||||||
|
|
||||||
|
struct UnicodeValueRange
|
||||||
|
{
|
||||||
|
inline int cmp (const hb_codepoint_t &codepoint) const
|
||||||
|
{
|
||||||
|
if (codepoint < startUnicodeValue) return -1;
|
||||||
|
if (codepoint > startUnicodeValue + additionalCount) return +1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
return TRACE_RETURN (c->check_struct (this));
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT24 startUnicodeValue; /* First value in this range. */
|
||||||
|
BYTE additionalCount; /* Number of additional values in this
|
||||||
|
* range. */
|
||||||
|
public:
|
||||||
|
DEFINE_SIZE_STATIC (4);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef SortedArrayOf<UnicodeValueRange, ULONG> DefaultUVS;
|
||||||
|
|
||||||
|
struct UVSMapping
|
||||||
|
{
|
||||||
|
inline int cmp (const hb_codepoint_t &codepoint) const
|
||||||
|
{
|
||||||
|
return unicodeValue.cmp (codepoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
return TRACE_RETURN (c->check_struct (this));
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT24 unicodeValue; /* Base Unicode value of the UVS */
|
||||||
|
GlyphID glyphID; /* Glyph ID of the UVS */
|
||||||
|
public:
|
||||||
|
DEFINE_SIZE_STATIC (5);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef SortedArrayOf<UVSMapping, ULONG> NonDefaultUVS;
|
||||||
|
|
||||||
|
struct VariationSelectorRecord
|
||||||
|
{
|
||||||
|
inline glyph_variant_t get_glyph (hb_codepoint_t codepoint,
|
||||||
|
hb_codepoint_t *glyph,
|
||||||
|
const void *base) const
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const DefaultUVS &defaults = base+defaultUVS;
|
||||||
|
i = defaults.bsearch (codepoint);
|
||||||
|
if (i != -1)
|
||||||
|
return GLYPH_VARIANT_USE_DEFAULT;
|
||||||
|
const NonDefaultUVS &nonDefaults = base+nonDefaultUVS;
|
||||||
|
i = nonDefaults.bsearch (codepoint);
|
||||||
|
if (i != -1)
|
||||||
|
{
|
||||||
|
*glyph = nonDefaults[i].glyphID;
|
||||||
|
return GLYPH_VARIANT_FOUND;
|
||||||
|
}
|
||||||
|
return GLYPH_VARIANT_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int cmp (const hb_codepoint_t &variation_selector) const
|
||||||
|
{
|
||||||
|
return varSelector.cmp (variation_selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
return TRACE_RETURN (c->check_struct (this) &&
|
||||||
|
defaultUVS.sanitize (c, base) &&
|
||||||
|
nonDefaultUVS.sanitize (c, base));
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT24 varSelector; /* Variation selector. */
|
||||||
|
OffsetTo<DefaultUVS, ULONG>
|
||||||
|
defaultUVS; /* Offset to Default UVS Table. May be 0. */
|
||||||
|
OffsetTo<NonDefaultUVS, ULONG>
|
||||||
|
nonDefaultUVS; /* Offset to Non-Default UVS Table. May be 0. */
|
||||||
|
public:
|
||||||
|
DEFINE_SIZE_STATIC (11);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CmapSubtableFormat14
|
||||||
|
{
|
||||||
|
inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint,
|
||||||
|
hb_codepoint_t variation_selector,
|
||||||
|
hb_codepoint_t *glyph) const
|
||||||
|
{
|
||||||
|
return record[record.bsearch(variation_selector)].get_glyph (codepoint, glyph, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
return TRACE_RETURN (c->check_struct (this) &&
|
||||||
|
record.sanitize (c, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
USHORT format; /* Format number is set to 0. */
|
||||||
|
ULONG lengthZ; /* Byte length of this subtable. */
|
||||||
|
SortedArrayOf<VariationSelectorRecord, ULONG>
|
||||||
|
record; /* Variation selector records; sorted
|
||||||
|
* in increasing order of `varSelector'. */
|
||||||
|
public:
|
||||||
|
DEFINE_SIZE_ARRAY (10, record);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CmapSubtable
|
||||||
|
{
|
||||||
|
/* Note: We intentionally do NOT implement subtable formats 2 and 8. */
|
||||||
|
|
||||||
|
inline bool get_glyph (hb_codepoint_t codepoint,
|
||||||
|
hb_codepoint_t *glyph) const
|
||||||
|
{
|
||||||
|
switch (u.format) {
|
||||||
|
case 0: return u.format0 .get_glyph(codepoint, glyph);
|
||||||
|
case 4: return u.format4 .get_glyph(codepoint, glyph);
|
||||||
|
case 6: return u.format6 .get_glyph(codepoint, glyph);
|
||||||
|
case 10: return u.format10.get_glyph(codepoint, glyph);
|
||||||
|
case 12: return u.format12.get_glyph(codepoint, glyph);
|
||||||
|
case 13: return u.format13.get_glyph(codepoint, glyph);
|
||||||
|
case 14:
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint,
|
||||||
|
hb_codepoint_t variation_selector,
|
||||||
|
hb_codepoint_t *glyph) const
|
||||||
|
{
|
||||||
|
switch (u.format) {
|
||||||
|
case 14: return u.format14.get_glyph_variant(codepoint, variation_selector, glyph);
|
||||||
|
default: return GLYPH_VARIANT_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
||||||
|
switch (u.format) {
|
||||||
|
case 0: return TRACE_RETURN (u.format0 .sanitize (c));
|
||||||
|
case 4: return TRACE_RETURN (u.format4 .sanitize (c));
|
||||||
|
case 6: return TRACE_RETURN (u.format6 .sanitize (c));
|
||||||
|
case 10: return TRACE_RETURN (u.format10.sanitize (c));
|
||||||
|
case 12: return TRACE_RETURN (u.format12.sanitize (c));
|
||||||
|
case 13: return TRACE_RETURN (u.format13.sanitize (c));
|
||||||
|
case 14: return TRACE_RETURN (u.format14.sanitize (c));
|
||||||
|
default:return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
union {
|
||||||
|
USHORT format; /* Format identifier */
|
||||||
|
CmapSubtableFormat0 format0;
|
||||||
|
CmapSubtableFormat4 format4;
|
||||||
|
CmapSubtableFormat6 format6;
|
||||||
|
CmapSubtableFormat10 format10;
|
||||||
|
CmapSubtableFormat12 format12;
|
||||||
|
CmapSubtableFormat13 format13;
|
||||||
|
CmapSubtableFormat14 format14;
|
||||||
|
} u;
|
||||||
|
public:
|
||||||
|
DEFINE_SIZE_UNION (2, format);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct EncodingRecord
|
||||||
|
{
|
||||||
|
inline int cmp (const EncodingRecord &other) const
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ret = platformID.cmp (other.platformID);
|
||||||
|
if (ret) return ret;
|
||||||
|
ret = encodingID.cmp (other.encodingID);
|
||||||
|
if (ret) return ret;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
return TRACE_RETURN (c->check_struct (this) &&
|
||||||
|
subtable.sanitize (c, base));
|
||||||
|
}
|
||||||
|
|
||||||
|
USHORT platformID; /* Platform ID. */
|
||||||
|
USHORT encodingID; /* Platform-specific encoding ID. */
|
||||||
|
OffsetTo<CmapSubtable, ULONG>
|
||||||
|
subtable; /* Byte offset from beginning of table to the subtable for this encoding. */
|
||||||
|
public:
|
||||||
|
DEFINE_SIZE_STATIC (8);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cmap
|
||||||
|
{
|
||||||
|
static const hb_tag_t tableTag = HB_OT_TAG_cmap;
|
||||||
|
|
||||||
|
inline const CmapSubtable *find_subtable (unsigned int platform_id,
|
||||||
|
unsigned int encoding_id) const
|
||||||
|
{
|
||||||
|
EncodingRecord key;
|
||||||
|
key.platformID.set (platform_id);
|
||||||
|
key.encodingID.set (encoding_id);
|
||||||
|
|
||||||
|
/* Note: We can use bsearch, but since it has no performance
|
||||||
|
* implications, we use lsearch and as such accept fonts with
|
||||||
|
* unsorted subtable list. */
|
||||||
|
int result = encodingRecord./*bsearch*/lsearch (key);
|
||||||
|
if (result == -1 || !encodingRecord[result].subtable)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return &(this+encodingRecord[result].subtable);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
return TRACE_RETURN (c->check_struct (this) &&
|
||||||
|
likely (version == 0) &&
|
||||||
|
encodingRecord.sanitize (c, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
USHORT version; /* Table version number (0). */
|
||||||
|
SortedArrayOf<EncodingRecord>
|
||||||
|
encodingRecord; /* Encoding tables. */
|
||||||
|
public:
|
||||||
|
DEFINE_SIZE_ARRAY (4, encodingRecord);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace OT */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* HB_OT_CMAP_TABLE_HH */
|
289
gfx/harfbuzz/src/hb-ot-font.cc
Normal file
289
gfx/harfbuzz/src/hb-ot-font.cc
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2011,2014 Google, Inc.
|
||||||
|
*
|
||||||
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, without written agreement and without
|
||||||
|
* license or royalty fees, to use, copy, modify, and distribute this
|
||||||
|
* software and its documentation for any purpose, provided that the
|
||||||
|
* above copyright notice and the following two paragraphs appear in
|
||||||
|
* all copies of this software.
|
||||||
|
*
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||||
|
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||||
|
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||||
|
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||||
|
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
|
*
|
||||||
|
* Google Author(s): Behdad Esfahbod, Roozbeh Pournader
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hb-private.hh"
|
||||||
|
|
||||||
|
#include "hb-ot.h"
|
||||||
|
|
||||||
|
#include "hb-font-private.hh"
|
||||||
|
|
||||||
|
#include "hb-ot-cmap-table.hh"
|
||||||
|
#include "hb-ot-hhea-table.hh"
|
||||||
|
#include "hb-ot-hmtx-table.hh"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct hb_ot_font_t
|
||||||
|
{
|
||||||
|
unsigned int num_glyphs;
|
||||||
|
unsigned int num_hmetrics;
|
||||||
|
const OT::hmtx *hmtx;
|
||||||
|
hb_blob_t *hmtx_blob;
|
||||||
|
|
||||||
|
const OT::CmapSubtable *cmap;
|
||||||
|
const OT::CmapSubtable *cmap_uvs;
|
||||||
|
hb_blob_t *cmap_blob;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static hb_ot_font_t *
|
||||||
|
_hb_ot_font_create (hb_font_t *font)
|
||||||
|
{
|
||||||
|
hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t));
|
||||||
|
|
||||||
|
if (unlikely (!ot_font))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ot_font->num_glyphs = font->face->get_num_glyphs ();
|
||||||
|
|
||||||
|
{
|
||||||
|
hb_blob_t *hhea_blob = OT::Sanitizer<OT::hhea>::sanitize (font->face->reference_table (HB_OT_TAG_hhea));
|
||||||
|
const OT::hhea *hhea = OT::Sanitizer<OT::hhea>::lock_instance (hhea_blob);
|
||||||
|
ot_font->num_hmetrics = hhea->numberOfHMetrics;
|
||||||
|
hb_blob_destroy (hhea_blob);
|
||||||
|
}
|
||||||
|
ot_font->hmtx_blob = OT::Sanitizer<OT::hmtx>::sanitize (font->face->reference_table (HB_OT_TAG_hmtx));
|
||||||
|
if (unlikely (!ot_font->num_hmetrics ||
|
||||||
|
2 * (ot_font->num_hmetrics + ot_font->num_glyphs) < hb_blob_get_length (ot_font->hmtx_blob)))
|
||||||
|
{
|
||||||
|
hb_blob_destroy (ot_font->hmtx_blob);
|
||||||
|
free (ot_font);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ot_font->hmtx = OT::Sanitizer<OT::hmtx>::lock_instance (ot_font->hmtx_blob);
|
||||||
|
|
||||||
|
ot_font->cmap_blob = OT::Sanitizer<OT::cmap>::sanitize (font->face->reference_table (HB_OT_TAG_cmap));
|
||||||
|
const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (ot_font->cmap_blob);
|
||||||
|
const OT::CmapSubtable *subtable = NULL;
|
||||||
|
const OT::CmapSubtable *subtable_uvs = NULL;
|
||||||
|
|
||||||
|
/* 32-bit subtables. */
|
||||||
|
if (!subtable) subtable = cmap->find_subtable (0, 6);
|
||||||
|
if (!subtable) subtable = cmap->find_subtable (0, 4);
|
||||||
|
if (!subtable) subtable = cmap->find_subtable (3, 10);
|
||||||
|
/* 16-bit subtables. */
|
||||||
|
if (!subtable) subtable = cmap->find_subtable (0, 3);
|
||||||
|
if (!subtable) subtable = cmap->find_subtable (3, 1);
|
||||||
|
/* Meh. */
|
||||||
|
if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
|
||||||
|
|
||||||
|
/* UVS subtable. */
|
||||||
|
if (!subtable_uvs) subtable_uvs = cmap->find_subtable (0, 5);
|
||||||
|
/* Meh. */
|
||||||
|
if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtable);
|
||||||
|
|
||||||
|
ot_font->cmap = subtable;
|
||||||
|
ot_font->cmap_uvs = subtable_uvs;
|
||||||
|
|
||||||
|
return ot_font;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_hb_ot_font_destroy (hb_ot_font_t *ot_font)
|
||||||
|
{
|
||||||
|
hb_blob_destroy (ot_font->cmap_blob);
|
||||||
|
hb_blob_destroy (ot_font->hmtx_blob);
|
||||||
|
|
||||||
|
free (ot_font);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static hb_bool_t
|
||||||
|
hb_ot_get_glyph (hb_font_t *font HB_UNUSED,
|
||||||
|
void *font_data,
|
||||||
|
hb_codepoint_t unicode,
|
||||||
|
hb_codepoint_t variation_selector,
|
||||||
|
hb_codepoint_t *glyph,
|
||||||
|
void *user_data HB_UNUSED)
|
||||||
|
|
||||||
|
{
|
||||||
|
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||||
|
|
||||||
|
if (unlikely (variation_selector))
|
||||||
|
{
|
||||||
|
switch (ot_font->cmap_uvs->get_glyph_variant (unicode,
|
||||||
|
variation_selector,
|
||||||
|
glyph))
|
||||||
|
{
|
||||||
|
case OT::GLYPH_VARIANT_NOT_FOUND: return false;
|
||||||
|
case OT::GLYPH_VARIANT_FOUND: return true;
|
||||||
|
case OT::GLYPH_VARIANT_USE_DEFAULT: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ot_font->cmap->get_glyph (unicode, glyph);
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_position_t
|
||||||
|
hb_ot_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
|
||||||
|
void *font_data,
|
||||||
|
hb_codepoint_t glyph,
|
||||||
|
void *user_data HB_UNUSED)
|
||||||
|
{
|
||||||
|
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||||
|
|
||||||
|
if (unlikely (glyph >= ot_font->num_glyphs))
|
||||||
|
return 0; /* Maybe better to return notdef's advance instead? */
|
||||||
|
|
||||||
|
if (glyph >= ot_font->num_hmetrics)
|
||||||
|
glyph = ot_font->num_hmetrics - 1;
|
||||||
|
|
||||||
|
return font->em_scale_x (ot_font->hmtx->longHorMetric[glyph].advanceWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_position_t
|
||||||
|
hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
|
||||||
|
void *font_data,
|
||||||
|
hb_codepoint_t glyph,
|
||||||
|
void *user_data HB_UNUSED)
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_bool_t
|
||||||
|
hb_ot_get_glyph_h_origin (hb_font_t *font HB_UNUSED,
|
||||||
|
void *font_data HB_UNUSED,
|
||||||
|
hb_codepoint_t glyph HB_UNUSED,
|
||||||
|
hb_position_t *x HB_UNUSED,
|
||||||
|
hb_position_t *y HB_UNUSED,
|
||||||
|
void *user_data HB_UNUSED)
|
||||||
|
{
|
||||||
|
/* We always work in the horizontal coordinates. */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_bool_t
|
||||||
|
hb_ot_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
|
||||||
|
void *font_data,
|
||||||
|
hb_codepoint_t glyph,
|
||||||
|
hb_position_t *x,
|
||||||
|
hb_position_t *y,
|
||||||
|
void *user_data HB_UNUSED)
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_position_t
|
||||||
|
hb_ot_get_glyph_h_kerning (hb_font_t *font,
|
||||||
|
void *font_data,
|
||||||
|
hb_codepoint_t left_glyph,
|
||||||
|
hb_codepoint_t right_glyph,
|
||||||
|
void *user_data HB_UNUSED)
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_position_t
|
||||||
|
hb_ot_get_glyph_v_kerning (hb_font_t *font HB_UNUSED,
|
||||||
|
void *font_data HB_UNUSED,
|
||||||
|
hb_codepoint_t top_glyph HB_UNUSED,
|
||||||
|
hb_codepoint_t bottom_glyph HB_UNUSED,
|
||||||
|
void *user_data HB_UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_bool_t
|
||||||
|
hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED,
|
||||||
|
void *font_data,
|
||||||
|
hb_codepoint_t glyph,
|
||||||
|
hb_glyph_extents_t *extents,
|
||||||
|
void *user_data HB_UNUSED)
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_bool_t
|
||||||
|
hb_ot_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
|
||||||
|
void *font_data,
|
||||||
|
hb_codepoint_t glyph,
|
||||||
|
unsigned int point_index,
|
||||||
|
hb_position_t *x,
|
||||||
|
hb_position_t *y,
|
||||||
|
void *user_data HB_UNUSED)
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_bool_t
|
||||||
|
hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED,
|
||||||
|
void *font_data,
|
||||||
|
hb_codepoint_t glyph,
|
||||||
|
char *name, unsigned int size,
|
||||||
|
void *user_data HB_UNUSED)
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_bool_t
|
||||||
|
hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
|
||||||
|
void *font_data,
|
||||||
|
const char *name, int len, /* -1 means nul-terminated */
|
||||||
|
hb_codepoint_t *glyph,
|
||||||
|
void *user_data HB_UNUSED)
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static hb_font_funcs_t *
|
||||||
|
_hb_ot_get_font_funcs (void)
|
||||||
|
{
|
||||||
|
static const hb_font_funcs_t ot_ffuncs = {
|
||||||
|
HB_OBJECT_HEADER_STATIC,
|
||||||
|
|
||||||
|
true, /* immutable */
|
||||||
|
|
||||||
|
{
|
||||||
|
#define HB_FONT_FUNC_IMPLEMENT(name) hb_ot_get_##name,
|
||||||
|
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
|
||||||
|
#undef HB_FONT_FUNC_IMPLEMENT
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return const_cast<hb_font_funcs_t *> (&ot_ffuncs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
hb_ot_font_set_funcs (hb_font_t *font)
|
||||||
|
{
|
||||||
|
hb_ot_font_t *ot_font = _hb_ot_font_create (font);
|
||||||
|
if (unlikely (!ot_font))
|
||||||
|
return;
|
||||||
|
|
||||||
|
hb_font_set_funcs (font,
|
||||||
|
_hb_ot_get_font_funcs (),
|
||||||
|
ot_font,
|
||||||
|
(hb_destroy_func_t) _hb_ot_font_destroy);
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2012 Google, Inc.
|
* Copyright © 2014 Google, Inc.
|
||||||
*
|
*
|
||||||
* This is part of HarfBuzz, a text shaping library.
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
*
|
*
|
||||||
@ -21,31 +21,21 @@
|
|||||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
*
|
*
|
||||||
* Google Author(s): Behdad Esfahbod
|
* Google Author(s): Behdad Esfahbod, Roozbeh Pournader
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hb-ot-shape-complex-indic-private.hh"
|
#ifndef HB_OT_FONT_H
|
||||||
|
#define HB_OT_FONT_H
|
||||||
|
|
||||||
int
|
#include "hb.h"
|
||||||
main (void)
|
|
||||||
{
|
|
||||||
hb_unicode_funcs_t *funcs = hb_unicode_funcs_get_default ();
|
|
||||||
|
|
||||||
printf ("There are split matras without a Unicode decomposition:\n");
|
HB_BEGIN_DECLS
|
||||||
for (hb_codepoint_t u = 0; u < 0x110000; u++)
|
|
||||||
{
|
|
||||||
unsigned int type = get_indic_categories (u);
|
|
||||||
|
|
||||||
unsigned int category = type & 0x0F;
|
|
||||||
unsigned int position = type >> 4;
|
|
||||||
|
|
||||||
hb_unicode_general_category_t cat = hb_unicode_general_category (funcs, u);
|
void
|
||||||
unsigned int ccc = hb_unicode_combining_class (funcs, u);
|
hb_ot_font_set_funcs (hb_font_t *font);
|
||||||
if (category == OT_M && ccc)
|
|
||||||
printf ("U+%04X %d\n", u, ccc);
|
|
||||||
|
|
||||||
// hb_codepoint_t a, b;
|
|
||||||
// if (!hb_unicode_decompose (funcs, u, &a, &b))
|
HB_END_DECLS
|
||||||
// printf ("U+%04X %x %x\n", u, category, position);
|
|
||||||
}
|
#endif /* HB_OT_FONT_H */
|
||||||
}
|
|
@ -58,12 +58,12 @@ struct head
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
FixedVersion version; /* Version of the head table--currently
|
FixedVersion version; /* Version of the head table--currently
|
||||||
* 0x00010000 for version 1.0. */
|
* 0x00010000u for version 1.0. */
|
||||||
FixedVersion fontRevision; /* Set by font manufacturer. */
|
FixedVersion fontRevision; /* Set by font manufacturer. */
|
||||||
ULONG checkSumAdjustment; /* To compute: set it to 0, sum the
|
ULONG checkSumAdjustment; /* To compute: set it to 0, sum the
|
||||||
* entire font as ULONG, then store
|
* entire font as ULONG, then store
|
||||||
* 0xB1B0AFBA - sum. */
|
* 0xB1B0AFBAu - sum. */
|
||||||
ULONG magicNumber; /* Set to 0x5F0F3CF5. */
|
ULONG magicNumber; /* Set to 0x5F0F3CF5u. */
|
||||||
USHORT flags; /* Bit 0: Baseline for font at y=0;
|
USHORT flags; /* Bit 0: Baseline for font at y=0;
|
||||||
* Bit 1: Left sidebearing point at x=0;
|
* Bit 1: Left sidebearing point at x=0;
|
||||||
* Bit 2: Instructions may depend on point size;
|
* Bit 2: Instructions may depend on point size;
|
||||||
|
@ -49,8 +49,8 @@ struct hhea
|
|||||||
return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1));
|
return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
public:
|
||||||
FixedVersion version; /* 0x00010000 for version 1.0. */
|
FixedVersion version; /* 0x00010000u for version 1.0. */
|
||||||
FWORD ascender; /* Typographic ascent. <a
|
FWORD ascender; /* Typographic ascent. <a
|
||||||
* href="http://developer.apple.com/fonts/TTRefMan/RM06/Chap6hhea.html">
|
* href="http://developer.apple.com/fonts/TTRefMan/RM06/Chap6hhea.html">
|
||||||
* (Distance from baseline of highest
|
* (Distance from baseline of highest
|
||||||
|
@ -59,7 +59,7 @@ struct hmtx
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
public:
|
||||||
LongHorMetric longHorMetric[VAR]; /* Paired advance width and left side
|
LongHorMetric longHorMetric[VAR]; /* Paired advance width and left side
|
||||||
* bearing values for each glyph. The
|
* bearing values for each glyph. The
|
||||||
* value numOfHMetrics comes from
|
* value numOfHMetrics comes from
|
||||||
|
@ -103,7 +103,8 @@ struct RecordArrayOf : SortedArrayOf<Record<Type> > {
|
|||||||
}
|
}
|
||||||
inline bool find_index (hb_tag_t tag, unsigned int *index) const
|
inline bool find_index (hb_tag_t tag, unsigned int *index) const
|
||||||
{
|
{
|
||||||
int i = this->search (tag);
|
/* If we want to allow non-sorted data, we can lsearch(). */
|
||||||
|
int i = this->/*lsearch*/bsearch (tag);
|
||||||
if (i != -1) {
|
if (i != -1) {
|
||||||
if (index) *index = i;
|
if (index) *index = i;
|
||||||
return true;
|
return true;
|
||||||
@ -189,10 +190,10 @@ struct LangSys
|
|||||||
unsigned int *feature_indexes /* OUT */) const
|
unsigned int *feature_indexes /* OUT */) const
|
||||||
{ return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); }
|
{ return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); }
|
||||||
|
|
||||||
inline bool has_required_feature (void) const { return reqFeatureIndex != 0xffff; }
|
inline bool has_required_feature (void) const { return reqFeatureIndex != 0xFFFFu; }
|
||||||
inline unsigned int get_required_feature_index (void) const
|
inline unsigned int get_required_feature_index (void) const
|
||||||
{
|
{
|
||||||
if (reqFeatureIndex == 0xffff)
|
if (reqFeatureIndex == 0xFFFFu)
|
||||||
return Index::NOT_FOUND_INDEX;
|
return Index::NOT_FOUND_INDEX;
|
||||||
return reqFeatureIndex;;
|
return reqFeatureIndex;;
|
||||||
}
|
}
|
||||||
@ -203,11 +204,11 @@ struct LangSys
|
|||||||
return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c));
|
return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c));
|
||||||
}
|
}
|
||||||
|
|
||||||
Offset lookupOrder; /* = Null (reserved for an offset to a
|
Offset<> lookupOrderZ; /* = Null (reserved for an offset to a
|
||||||
* reordering table) */
|
* reordering table) */
|
||||||
USHORT reqFeatureIndex;/* Index of a feature required for this
|
USHORT reqFeatureIndex;/* Index of a feature required for this
|
||||||
* language system--if no required features
|
* language system--if no required features
|
||||||
* = 0xFFFF */
|
* = 0xFFFFu */
|
||||||
IndexArray featureIndex; /* Array of indices into the FeatureList */
|
IndexArray featureIndex; /* Array of indices into the FeatureList */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (6, featureIndex);
|
DEFINE_SIZE_ARRAY (6, featureIndex);
|
||||||
@ -447,9 +448,9 @@ struct FeatureParams
|
|||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (tag == HB_TAG ('s','i','z','e'))
|
if (tag == HB_TAG ('s','i','z','e'))
|
||||||
return TRACE_RETURN (u.size.sanitize (c));
|
return TRACE_RETURN (u.size.sanitize (c));
|
||||||
if ((tag & 0xFFFF0000) == HB_TAG ('s','s','\0','\0')) /* ssXX */
|
if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
|
||||||
return TRACE_RETURN (u.stylisticSet.sanitize (c));
|
return TRACE_RETURN (u.stylisticSet.sanitize (c));
|
||||||
if ((tag & 0xFFFF0000) == HB_TAG ('c','v','\0','\0')) /* cvXX */
|
if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
|
||||||
return TRACE_RETURN (u.characterVariants.sanitize (c));
|
return TRACE_RETURN (u.characterVariants.sanitize (c));
|
||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
@ -501,11 +502,11 @@ struct Feature
|
|||||||
* Adobe tools, only the 'size' feature had FeatureParams defined.
|
* Adobe tools, only the 'size' feature had FeatureParams defined.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Offset orig_offset = featureParams;
|
OffsetTo<FeatureParams> orig_offset = featureParams;
|
||||||
if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)))
|
if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)))
|
||||||
return TRACE_RETURN (false);
|
return TRACE_RETURN (false);
|
||||||
|
|
||||||
if (likely (!orig_offset))
|
if (likely (orig_offset.is_null ()))
|
||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
|
|
||||||
if (featureParams == 0 && closure &&
|
if (featureParams == 0 && closure &&
|
||||||
@ -513,13 +514,13 @@ struct Feature
|
|||||||
closure->list_base && closure->list_base < this)
|
closure->list_base && closure->list_base < this)
|
||||||
{
|
{
|
||||||
unsigned int new_offset_int = (unsigned int) orig_offset -
|
unsigned int new_offset_int = (unsigned int) orig_offset -
|
||||||
((char *) this - (char *) closure->list_base);
|
(((char *) this) - ((char *) closure->list_base));
|
||||||
|
|
||||||
Offset new_offset;
|
OffsetTo<FeatureParams> new_offset;
|
||||||
/* Check that it did not overflow. */
|
/* Check that it did not overflow. */
|
||||||
new_offset.set (new_offset_int);
|
new_offset.set (new_offset_int);
|
||||||
if (new_offset == new_offset_int &&
|
if (new_offset == new_offset_int &&
|
||||||
featureParams.try_set (c, new_offset) &&
|
c->try_set (&featureParams, new_offset) &&
|
||||||
!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))
|
!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))
|
||||||
return TRACE_RETURN (false);
|
return TRACE_RETURN (false);
|
||||||
}
|
}
|
||||||
@ -584,7 +585,7 @@ struct Lookup
|
|||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
|
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
|
||||||
lookupType.set (lookup_type);
|
lookupType.set (lookup_type);
|
||||||
lookupFlag.set (lookup_props & 0xFFFF);
|
lookupFlag.set (lookup_props & 0xFFFFu);
|
||||||
if (unlikely (!subTable.serialize (c, num_subtables))) return TRACE_RETURN (false);
|
if (unlikely (!subTable.serialize (c, num_subtables))) return TRACE_RETURN (false);
|
||||||
if (lookupFlag & LookupFlag::UseMarkFilteringSet)
|
if (lookupFlag & LookupFlag::UseMarkFilteringSet)
|
||||||
{
|
{
|
||||||
@ -608,7 +609,7 @@ struct Lookup
|
|||||||
|
|
||||||
USHORT lookupType; /* Different enumerations for GSUB and GPOS */
|
USHORT lookupType; /* Different enumerations for GSUB and GPOS */
|
||||||
USHORT lookupFlag; /* Lookup qualifiers */
|
USHORT lookupFlag; /* Lookup qualifiers */
|
||||||
ArrayOf<Offset>
|
ArrayOf<Offset<> >
|
||||||
subTable; /* Array of SubTables */
|
subTable; /* Array of SubTables */
|
||||||
USHORT markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets
|
USHORT markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets
|
||||||
* structure. This field is only present if bit
|
* structure. This field is only present if bit
|
||||||
@ -631,7 +632,7 @@ struct CoverageFormat1
|
|||||||
private:
|
private:
|
||||||
inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
|
inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
|
||||||
{
|
{
|
||||||
int i = glyphArray.search (glyph_id);
|
int i = glyphArray.bsearch (glyph_id);
|
||||||
ASSERT_STATIC (((unsigned int) -1) == NOT_COVERED);
|
ASSERT_STATIC (((unsigned int) -1) == NOT_COVERED);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -696,7 +697,7 @@ struct CoverageFormat2
|
|||||||
private:
|
private:
|
||||||
inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
|
inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
|
||||||
{
|
{
|
||||||
int i = rangeRecord.search (glyph_id);
|
int i = rangeRecord.bsearch (glyph_id);
|
||||||
if (i != -1) {
|
if (i != -1) {
|
||||||
const RangeRecord &range = rangeRecord[i];
|
const RangeRecord &range = rangeRecord[i];
|
||||||
return (unsigned int) range.value + (glyph_id - range.start);
|
return (unsigned int) range.value + (glyph_id - range.start);
|
||||||
@ -992,7 +993,7 @@ struct ClassDefFormat2
|
|||||||
private:
|
private:
|
||||||
inline unsigned int get_class (hb_codepoint_t glyph_id) const
|
inline unsigned int get_class (hb_codepoint_t glyph_id) const
|
||||||
{
|
{
|
||||||
int i = rangeRecord.search (glyph_id);
|
int i = rangeRecord.bsearch (glyph_id);
|
||||||
if (i != -1)
|
if (i != -1)
|
||||||
return rangeRecord[i].value;
|
return rangeRecord[i].value;
|
||||||
return 0;
|
return 0;
|
||||||
@ -1130,7 +1131,7 @@ struct Device
|
|||||||
|
|
||||||
unsigned int byte = deltaValue[s >> (4 - f)];
|
unsigned int byte = deltaValue[s >> (4 - f)];
|
||||||
unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f)));
|
unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f)));
|
||||||
unsigned int mask = (0xFFFF >> (16 - (1 << f)));
|
unsigned int mask = (0xFFFFu >> (16 - (1 << f)));
|
||||||
|
|
||||||
int delta = bits & mask;
|
int delta = bits & mask;
|
||||||
|
|
||||||
|
@ -282,7 +282,7 @@ struct MarkGlyphSetsFormat1
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
USHORT format; /* Format identifier--format = 1 */
|
USHORT format; /* Format identifier--format = 1 */
|
||||||
LongOffsetArrayOf<Coverage>
|
ArrayOf<OffsetTo<Coverage, ULONG> >
|
||||||
coverage; /* Array of long offsets to mark set
|
coverage; /* Array of long offsets to mark set
|
||||||
* coverage tables */
|
* coverage tables */
|
||||||
public:
|
public:
|
||||||
@ -360,9 +360,9 @@ struct GDEF
|
|||||||
hb_position_t *caret_array /* OUT */) const
|
hb_position_t *caret_array /* OUT */) const
|
||||||
{ return (this+ligCaretList).get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array); }
|
{ return (this+ligCaretList).get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array); }
|
||||||
|
|
||||||
inline bool has_mark_sets (void) const { return version.to_int () >= 0x00010002 && markGlyphSetsDef[0] != 0; }
|
inline bool has_mark_sets (void) const { return version.to_int () >= 0x00010002u && markGlyphSetsDef[0] != 0; }
|
||||||
inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
|
inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
|
||||||
{ return version.to_int () >= 0x00010002 && (this+markGlyphSetsDef[0]).covers (set_index, glyph_id); }
|
{ return version.to_int () >= 0x00010002u && (this+markGlyphSetsDef[0]).covers (set_index, glyph_id); }
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
@ -372,7 +372,7 @@ struct GDEF
|
|||||||
attachList.sanitize (c, this) &&
|
attachList.sanitize (c, this) &&
|
||||||
ligCaretList.sanitize (c, this) &&
|
ligCaretList.sanitize (c, this) &&
|
||||||
markAttachClassDef.sanitize (c, this) &&
|
markAttachClassDef.sanitize (c, this) &&
|
||||||
(version.to_int () < 0x00010002 || markGlyphSetsDef[0].sanitize (c, this)));
|
(version.to_int () < 0x00010002u || markGlyphSetsDef[0].sanitize (c, this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -400,7 +400,7 @@ struct GDEF
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
FixedVersion version; /* Version of the GDEF table--currently
|
FixedVersion version; /* Version of the GDEF table--currently
|
||||||
* 0x00010002 */
|
* 0x00010002u */
|
||||||
OffsetTo<ClassDef>
|
OffsetTo<ClassDef>
|
||||||
glyphClassDef; /* Offset to class definition table
|
glyphClassDef; /* Offset to class definition table
|
||||||
* for glyph type--from beginning of
|
* for glyph type--from beginning of
|
||||||
|
@ -49,18 +49,18 @@ typedef Value ValueRecord[VAR];
|
|||||||
struct ValueFormat : USHORT
|
struct ValueFormat : USHORT
|
||||||
{
|
{
|
||||||
enum Flags {
|
enum Flags {
|
||||||
xPlacement = 0x0001, /* Includes horizontal adjustment for placement */
|
xPlacement = 0x0001u, /* Includes horizontal adjustment for placement */
|
||||||
yPlacement = 0x0002, /* Includes vertical adjustment for placement */
|
yPlacement = 0x0002u, /* Includes vertical adjustment for placement */
|
||||||
xAdvance = 0x0004, /* Includes horizontal adjustment for advance */
|
xAdvance = 0x0004u, /* Includes horizontal adjustment for advance */
|
||||||
yAdvance = 0x0008, /* Includes vertical adjustment for advance */
|
yAdvance = 0x0008u, /* Includes vertical adjustment for advance */
|
||||||
xPlaDevice = 0x0010, /* Includes horizontal Device table for placement */
|
xPlaDevice = 0x0010u, /* Includes horizontal Device table for placement */
|
||||||
yPlaDevice = 0x0020, /* Includes vertical Device table for placement */
|
yPlaDevice = 0x0020u, /* Includes vertical Device table for placement */
|
||||||
xAdvDevice = 0x0040, /* Includes horizontal Device table for advance */
|
xAdvDevice = 0x0040u, /* Includes horizontal Device table for advance */
|
||||||
yAdvDevice = 0x0080, /* Includes vertical Device table for advance */
|
yAdvDevice = 0x0080u, /* Includes vertical Device table for advance */
|
||||||
ignored = 0x0F00, /* Was used in TrueType Open for MM fonts */
|
ignored = 0x0F00u, /* Was used in TrueType Open for MM fonts */
|
||||||
reserved = 0xF000, /* For future use */
|
reserved = 0xF000u, /* For future use */
|
||||||
|
|
||||||
devices = 0x00F0 /* Mask for having any Device table */
|
devices = 0x00F0u /* Mask for having any Device table */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* All fields are options. Only those available advance the value pointer. */
|
/* All fields are options. Only those available advance the value pointer. */
|
||||||
@ -1589,6 +1589,8 @@ GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
|
|||||||
void
|
void
|
||||||
GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
|
GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
|
_hb_buffer_assert_gsubgpos_vars (buffer);
|
||||||
|
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
|
hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
|
||||||
hb_direction_t direction = buffer->props.direction;
|
hb_direction_t direction = buffer->props.direction;
|
||||||
@ -1600,22 +1602,20 @@ GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
|
|||||||
/* Handle attachments */
|
/* Handle attachments */
|
||||||
for (unsigned int i = 0; i < len; i++)
|
for (unsigned int i = 0; i < len; i++)
|
||||||
fix_mark_attachment (pos, i, direction);
|
fix_mark_attachment (pos, i, direction);
|
||||||
|
|
||||||
_hb_buffer_deallocate_gsubgpos_vars (buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Out-of-class implementation for methods recursing */
|
/* Out-of-class implementation for methods recursing */
|
||||||
|
|
||||||
template <typename context_t>
|
template <typename context_t>
|
||||||
inline typename context_t::return_t PosLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
|
/*static*/ inline typename context_t::return_t PosLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
|
||||||
{
|
{
|
||||||
const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos);
|
const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos);
|
||||||
const PosLookup &l = gpos.get_lookup (lookup_index);
|
const PosLookup &l = gpos.get_lookup (lookup_index);
|
||||||
return l.dispatch (c);
|
return l.dispatch (c);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index)
|
/*static*/ inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index)
|
||||||
{
|
{
|
||||||
const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos);
|
const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos);
|
||||||
const PosLookup &l = gpos.get_lookup (lookup_index);
|
const PosLookup &l = gpos.get_lookup (lookup_index);
|
||||||
|
@ -44,7 +44,7 @@ struct SingleSubstFormat1
|
|||||||
for (iter.init (this+coverage); iter.more (); iter.next ()) {
|
for (iter.init (this+coverage); iter.more (); iter.next ()) {
|
||||||
hb_codepoint_t glyph_id = iter.get_glyph ();
|
hb_codepoint_t glyph_id = iter.get_glyph ();
|
||||||
if (c->glyphs->has (glyph_id))
|
if (c->glyphs->has (glyph_id))
|
||||||
c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFF);
|
c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFFu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ struct SingleSubstFormat1
|
|||||||
for (iter.init (this+coverage); iter.more (); iter.next ()) {
|
for (iter.init (this+coverage); iter.more (); iter.next ()) {
|
||||||
hb_codepoint_t glyph_id = iter.get_glyph ();
|
hb_codepoint_t glyph_id = iter.get_glyph ();
|
||||||
c->input->add (glyph_id);
|
c->input->add (glyph_id);
|
||||||
c->output->add ((glyph_id + deltaGlyphID) & 0xFFFF);
|
c->output->add ((glyph_id + deltaGlyphID) & 0xFFFFu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ struct SingleSubstFormat1
|
|||||||
|
|
||||||
/* According to the Adobe Annotated OpenType Suite, result is always
|
/* According to the Adobe Annotated OpenType Suite, result is always
|
||||||
* limited to 16bit. */
|
* limited to 16bit. */
|
||||||
glyph_id = (glyph_id + deltaGlyphID) & 0xFFFF;
|
glyph_id = (glyph_id + deltaGlyphID) & 0xFFFFu;
|
||||||
c->replace_glyph (glyph_id);
|
c->replace_glyph (glyph_id);
|
||||||
|
|
||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
@ -270,23 +270,34 @@ struct Sequence
|
|||||||
inline bool apply (hb_apply_context_t *c) const
|
inline bool apply (hb_apply_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_APPLY (this);
|
TRACE_APPLY (this);
|
||||||
if (unlikely (!substitute.len)) return TRACE_RETURN (false);
|
unsigned int count = substitute.len;
|
||||||
|
|
||||||
|
/* TODO:
|
||||||
|
* Testing shows that Uniscribe actually allows zero-len susbstitute,
|
||||||
|
* which essentially deletes a glyph. We don't allow for now. It
|
||||||
|
* can be confusing to the client since the cluster from the deleted
|
||||||
|
* glyph won't be merged with any output cluster... Also, currently
|
||||||
|
* buffer->move_to() makes assumptions about this too. Perhaps fix
|
||||||
|
* in the future after figuring out what to do with the clusters.
|
||||||
|
*/
|
||||||
|
if (unlikely (!count)) return TRACE_RETURN (false);
|
||||||
|
|
||||||
|
/* Special-case to make it in-place and not consider this
|
||||||
|
* as a "multiplied" substitution. */
|
||||||
|
if (unlikely (count == 1))
|
||||||
|
{
|
||||||
|
c->replace_glyph (substitute.array[0]);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ?
|
unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ?
|
||||||
HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
|
HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
|
||||||
unsigned int count = substitute.len;
|
|
||||||
if (count == 1) /* Special-case to make it in-place. */
|
for (unsigned int i = 0; i < count; i++) {
|
||||||
{
|
_hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i);
|
||||||
c->replace_glyph (substitute.array[0]);
|
c->output_glyph_for_component (substitute.array[i], klass);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (unsigned int i = 0; i < count; i++) {
|
|
||||||
_hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i);
|
|
||||||
c->output_glyph (substitute.array[i], klass);
|
|
||||||
}
|
|
||||||
c->buffer->skip_glyph ();
|
|
||||||
}
|
}
|
||||||
|
c->buffer->skip_glyph ();
|
||||||
|
|
||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
@ -624,7 +635,16 @@ struct Ligature
|
|||||||
{
|
{
|
||||||
TRACE_APPLY (this);
|
TRACE_APPLY (this);
|
||||||
unsigned int count = component.len;
|
unsigned int count = component.len;
|
||||||
if (unlikely (count < 1)) return TRACE_RETURN (false);
|
|
||||||
|
if (unlikely (!count)) return TRACE_RETURN (false);
|
||||||
|
|
||||||
|
/* Special-case to make it in-place and not consider this
|
||||||
|
* as a "ligated" substitution. */
|
||||||
|
if (unlikely (count == 1))
|
||||||
|
{
|
||||||
|
c->replace_glyph (ligGlyph);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
bool is_mark_ligature = false;
|
bool is_mark_ligature = false;
|
||||||
unsigned int total_component_count = 0;
|
unsigned int total_component_count = 0;
|
||||||
@ -1318,7 +1338,7 @@ struct GSUB : GSUBGPOS
|
|||||||
void
|
void
|
||||||
GSUB::substitute_start (hb_font_t *font, hb_buffer_t *buffer)
|
GSUB::substitute_start (hb_font_t *font, hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
_hb_buffer_allocate_gsubgpos_vars (buffer);
|
_hb_buffer_assert_gsubgpos_vars (buffer);
|
||||||
|
|
||||||
const GDEF &gdef = *hb_ot_layout_from_face (font->face)->gdef;
|
const GDEF &gdef = *hb_ot_layout_from_face (font->face)->gdef;
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
@ -1338,7 +1358,7 @@ GSUB::substitute_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSE
|
|||||||
|
|
||||||
/* Out-of-class implementation for methods recursing */
|
/* Out-of-class implementation for methods recursing */
|
||||||
|
|
||||||
inline bool ExtensionSubst::is_reverse (void) const
|
/*static*/ inline bool ExtensionSubst::is_reverse (void) const
|
||||||
{
|
{
|
||||||
unsigned int type = get_type ();
|
unsigned int type = get_type ();
|
||||||
if (unlikely (type == SubstLookupSubTable::Extension))
|
if (unlikely (type == SubstLookupSubTable::Extension))
|
||||||
@ -1347,14 +1367,14 @@ inline bool ExtensionSubst::is_reverse (void) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename context_t>
|
template <typename context_t>
|
||||||
inline typename context_t::return_t SubstLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
|
/*static*/ inline typename context_t::return_t SubstLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
|
||||||
{
|
{
|
||||||
const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub);
|
const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub);
|
||||||
const SubstLookup &l = gsub.get_lookup (lookup_index);
|
const SubstLookup &l = gsub.get_lookup (lookup_index);
|
||||||
return l.dispatch (c);
|
return l.dispatch (c);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool SubstLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index)
|
/*static*/ inline bool SubstLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index)
|
||||||
{
|
{
|
||||||
const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub);
|
const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub);
|
||||||
const SubstLookup &l = gsub.get_lookup (lookup_index);
|
const SubstLookup &l = gsub.get_lookup (lookup_index);
|
||||||
|
@ -349,11 +349,7 @@ struct hb_apply_context_t
|
|||||||
may_skip (const hb_apply_context_t *c,
|
may_skip (const hb_apply_context_t *c,
|
||||||
const hb_glyph_info_t &info) const
|
const hb_glyph_info_t &info) const
|
||||||
{
|
{
|
||||||
unsigned int property;
|
if (!c->check_glyph_property (&info, lookup_props))
|
||||||
|
|
||||||
property = _hb_glyph_info_get_glyph_props (&info);
|
|
||||||
|
|
||||||
if (!c->match_properties (info.codepoint, property, lookup_props))
|
|
||||||
return SKIP_YES;
|
return SKIP_YES;
|
||||||
|
|
||||||
if (unlikely (_hb_glyph_info_is_default_ignorable (&info) &&
|
if (unlikely (_hb_glyph_info_is_default_ignorable (&info) &&
|
||||||
@ -487,7 +483,6 @@ struct hb_apply_context_t
|
|||||||
const hb_glyph_info_t &info = c->buffer->out_info[idx];
|
const hb_glyph_info_t &info = c->buffer->out_info[idx];
|
||||||
|
|
||||||
matcher_t::may_skip_t skip = matcher.may_skip (c, info);
|
matcher_t::may_skip_t skip = matcher.may_skip (c, info);
|
||||||
|
|
||||||
if (unlikely (skip == matcher_t::SKIP_YES))
|
if (unlikely (skip == matcher_t::SKIP_YES))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -538,10 +533,12 @@ struct hb_apply_context_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
match_properties (hb_codepoint_t glyph,
|
check_glyph_property (const hb_glyph_info_t *info,
|
||||||
unsigned int glyph_props,
|
unsigned int lookup_props) const
|
||||||
unsigned int lookup_props) const
|
|
||||||
{
|
{
|
||||||
|
hb_codepoint_t glyph = info->codepoint;
|
||||||
|
unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info);
|
||||||
|
|
||||||
/* Not covered, if, for example, glyph class is ligature and
|
/* Not covered, if, for example, glyph class is ligature and
|
||||||
* lookup_props includes LookupFlags::IgnoreLigatures
|
* lookup_props includes LookupFlags::IgnoreLigatures
|
||||||
*/
|
*/
|
||||||
@ -554,26 +551,27 @@ struct hb_apply_context_t
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
|
||||||
check_glyph_property (hb_glyph_info_t *info,
|
|
||||||
unsigned int lookup_props) const
|
|
||||||
{
|
|
||||||
unsigned int property;
|
|
||||||
|
|
||||||
property = _hb_glyph_info_get_glyph_props (info);
|
|
||||||
|
|
||||||
return match_properties (info->codepoint, property, lookup_props);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void _set_glyph_props (hb_codepoint_t glyph_index,
|
inline void _set_glyph_props (hb_codepoint_t glyph_index,
|
||||||
unsigned int class_guess = 0,
|
unsigned int class_guess = 0,
|
||||||
bool ligature = false) const
|
bool ligature = false,
|
||||||
|
bool component = false) const
|
||||||
{
|
{
|
||||||
unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) &
|
unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) &
|
||||||
HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
|
HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
|
||||||
add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
|
add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
|
||||||
if (ligature)
|
if (ligature)
|
||||||
|
{
|
||||||
add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
|
add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
|
||||||
|
/* In the only place that the MULTIPLIED bit is used, Uniscribe
|
||||||
|
* seems to only care about the "last" transformation between
|
||||||
|
* Ligature and Multiple substitions. Ie. if you ligate, expand,
|
||||||
|
* and ligate again, it forgives the multiplication and acts as
|
||||||
|
* if only ligation happened. As such, clear MULTIPLIED bit.
|
||||||
|
*/
|
||||||
|
add_in &= ~HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
|
||||||
|
}
|
||||||
|
if (component)
|
||||||
|
add_in |= HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
|
||||||
if (likely (has_glyph_classes))
|
if (likely (has_glyph_classes))
|
||||||
_hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index));
|
_hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index));
|
||||||
else if (class_guess)
|
else if (class_guess)
|
||||||
@ -596,10 +594,10 @@ struct hb_apply_context_t
|
|||||||
_set_glyph_props (glyph_index, class_guess, true);
|
_set_glyph_props (glyph_index, class_guess, true);
|
||||||
buffer->replace_glyph (glyph_index);
|
buffer->replace_glyph (glyph_index);
|
||||||
}
|
}
|
||||||
inline void output_glyph (hb_codepoint_t glyph_index,
|
inline void output_glyph_for_component (hb_codepoint_t glyph_index,
|
||||||
unsigned int class_guess) const
|
unsigned int class_guess) const
|
||||||
{
|
{
|
||||||
_set_glyph_props (glyph_index, class_guess);
|
_set_glyph_props (glyph_index, class_guess, false, true);
|
||||||
buffer->output_glyph (glyph_index);
|
buffer->output_glyph (glyph_index);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -882,6 +880,7 @@ static inline void ligate_input (hb_apply_context_t *c,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool match_backtrack (hb_apply_context_t *c,
|
static inline bool match_backtrack (hb_apply_context_t *c,
|
||||||
@ -994,7 +993,9 @@ static inline bool apply_lookup (hb_apply_context_t *c,
|
|||||||
|
|
||||||
/* Recursed lookup changed buffer len. Adjust. */
|
/* Recursed lookup changed buffer len. Adjust. */
|
||||||
|
|
||||||
/* end can't go back past the current match position. */
|
/* end can't go back past the current match position.
|
||||||
|
* Note: this is only true because we do NOT allow MultipleSubst
|
||||||
|
* with zero sequence len. */
|
||||||
end = MAX ((int) match_positions[idx] + 1, int (end) + delta);
|
end = MAX ((int) match_positions[idx] + 1, int (end) + delta);
|
||||||
|
|
||||||
unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */
|
unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */
|
||||||
@ -2253,8 +2254,8 @@ struct GSUBGPOS
|
|||||||
|
|
||||||
inline unsigned int get_feature_count (void) const
|
inline unsigned int get_feature_count (void) const
|
||||||
{ return (this+featureList).len; }
|
{ return (this+featureList).len; }
|
||||||
inline const Tag& get_feature_tag (unsigned int i) const
|
inline hb_tag_t get_feature_tag (unsigned int i) const
|
||||||
{ return (this+featureList).get_tag (i); }
|
{ return i == Index::NOT_FOUND_INDEX ? HB_TAG_NONE : (this+featureList).get_tag (i); }
|
||||||
inline unsigned int get_feature_tags (unsigned int start_offset,
|
inline unsigned int get_feature_tags (unsigned int start_offset,
|
||||||
unsigned int *feature_count /* IN/OUT */,
|
unsigned int *feature_count /* IN/OUT */,
|
||||||
hb_tag_t *feature_tags /* OUT */) const
|
hb_tag_t *feature_tags /* OUT */) const
|
||||||
@ -2279,7 +2280,7 @@ struct GSUBGPOS
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
FixedVersion version; /* Version of the GSUB/GPOS table--initially set
|
FixedVersion version; /* Version of the GSUB/GPOS table--initially set
|
||||||
* to 0x00010000 */
|
* to 0x00010000u */
|
||||||
OffsetTo<ScriptList>
|
OffsetTo<ScriptList>
|
||||||
scriptList; /* ScriptList table */
|
scriptList; /* ScriptList table */
|
||||||
OffsetTo<FeatureList>
|
OffsetTo<FeatureList>
|
||||||
|
@ -214,7 +214,7 @@ struct JSTF
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
FixedVersion version; /* Version of the JSTF table--initially set
|
FixedVersion version; /* Version of the JSTF table--initially set
|
||||||
* to 0x00010000 */
|
* to 0x00010000u */
|
||||||
RecordArrayOf<JstfScript>
|
RecordArrayOf<JstfScript>
|
||||||
scriptList; /* Array of JstfScripts--listed
|
scriptList; /* Array of JstfScripts--listed
|
||||||
* alphabetically by ScriptTag */
|
* alphabetically by ScriptTag */
|
||||||
|
@ -50,9 +50,11 @@ typedef enum
|
|||||||
/* The following are used internally; not derived from GDEF. */
|
/* The following are used internally; not derived from GDEF. */
|
||||||
HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED = 0x10u,
|
HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED = 0x10u,
|
||||||
HB_OT_LAYOUT_GLYPH_PROPS_LIGATED = 0x20u,
|
HB_OT_LAYOUT_GLYPH_PROPS_LIGATED = 0x20u,
|
||||||
|
HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED = 0x40u,
|
||||||
|
|
||||||
HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED |
|
HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED |
|
||||||
HB_OT_LAYOUT_GLYPH_PROPS_LIGATED
|
HB_OT_LAYOUT_GLYPH_PROPS_LIGATED |
|
||||||
|
HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED
|
||||||
} hb_ot_layout_glyph_class_mask_t;
|
} hb_ot_layout_glyph_class_mask_t;
|
||||||
|
|
||||||
|
|
||||||
@ -125,7 +127,7 @@ struct hb_ot_layout_lookup_accelerator_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename TLookup>
|
template <typename TLookup>
|
||||||
inline void fini (const TLookup &lookup)
|
inline void fini (const TLookup &lookup HB_UNUSED)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,62 +184,62 @@ enum {
|
|||||||
MASK0_GEN_CAT = 0x1Fu
|
MASK0_GEN_CAT = 0x1Fu
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void
|
static inline void
|
||||||
_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
|
_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
|
||||||
{
|
{
|
||||||
/* XXX This shouldn't be inlined, or at least not while is_default_ignorable() is inline. */
|
/* XXX This shouldn't be inlined, or at least not while is_default_ignorable() is inline. */
|
||||||
info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) |
|
info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) |
|
||||||
(unicode->is_default_ignorable (info->codepoint) ? MASK0_IGNORABLE : 0) |
|
(unicode->is_default_ignorable (info->codepoint) ? MASK0_IGNORABLE : 0) |
|
||||||
(info->codepoint == 0x200C ? MASK0_ZWNJ : 0) |
|
(info->codepoint == 0x200Cu ? MASK0_ZWNJ : 0) |
|
||||||
(info->codepoint == 0x200D ? MASK0_ZWJ : 0);
|
(info->codepoint == 0x200Du ? MASK0_ZWJ : 0);
|
||||||
info->unicode_props1() = unicode->modified_combining_class (info->codepoint);
|
info->unicode_props1() = unicode->modified_combining_class (info->codepoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
static inline void
|
||||||
_hb_glyph_info_set_general_category (hb_glyph_info_t *info,
|
_hb_glyph_info_set_general_category (hb_glyph_info_t *info,
|
||||||
hb_unicode_general_category_t gen_cat)
|
hb_unicode_general_category_t gen_cat)
|
||||||
{
|
{
|
||||||
info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~MASK0_GEN_CAT);
|
info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~MASK0_GEN_CAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline hb_unicode_general_category_t
|
static inline hb_unicode_general_category_t
|
||||||
_hb_glyph_info_get_general_category (const hb_glyph_info_t *info)
|
_hb_glyph_info_get_general_category (const hb_glyph_info_t *info)
|
||||||
{
|
{
|
||||||
return (hb_unicode_general_category_t) (info->unicode_props0() & MASK0_GEN_CAT);
|
return (hb_unicode_general_category_t) (info->unicode_props0() & MASK0_GEN_CAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
static inline void
|
||||||
_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info,
|
_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info,
|
||||||
unsigned int modified_class)
|
unsigned int modified_class)
|
||||||
{
|
{
|
||||||
info->unicode_props1() = modified_class;
|
info->unicode_props1() = modified_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned int
|
static inline unsigned int
|
||||||
_hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
|
_hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
|
||||||
{
|
{
|
||||||
return info->unicode_props1();
|
return info->unicode_props1();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline hb_bool_t
|
static inline hb_bool_t
|
||||||
_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
|
_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
|
||||||
{
|
{
|
||||||
return !!(info->unicode_props0() & MASK0_IGNORABLE);
|
return !!(info->unicode_props0() & MASK0_IGNORABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline hb_bool_t
|
static inline hb_bool_t
|
||||||
_hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
|
_hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
|
||||||
{
|
{
|
||||||
return !!(info->unicode_props0() & MASK0_ZWNJ);
|
return !!(info->unicode_props0() & MASK0_ZWNJ);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline hb_bool_t
|
static inline hb_bool_t
|
||||||
_hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
|
_hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
|
||||||
{
|
{
|
||||||
return !!(info->unicode_props0() & MASK0_ZWJ);
|
return !!(info->unicode_props0() & MASK0_ZWJ);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
static inline void
|
||||||
_hb_glyph_info_flip_joiners (hb_glyph_info_t *info)
|
_hb_glyph_info_flip_joiners (hb_glyph_info_t *info)
|
||||||
{
|
{
|
||||||
info->unicode_props0() ^= MASK0_ZWNJ | MASK0_ZWJ;
|
info->unicode_props0() ^= MASK0_ZWNJ | MASK0_ZWJ;
|
||||||
@ -339,31 +341,31 @@ _hb_allocate_lig_id (hb_buffer_t *buffer) {
|
|||||||
|
|
||||||
/* glyph_props: */
|
/* glyph_props: */
|
||||||
|
|
||||||
inline void
|
static inline void
|
||||||
_hb_glyph_info_set_glyph_props (hb_glyph_info_t *info, unsigned int props)
|
_hb_glyph_info_set_glyph_props (hb_glyph_info_t *info, unsigned int props)
|
||||||
{
|
{
|
||||||
info->glyph_props() = props;
|
info->glyph_props() = props;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned int
|
static inline unsigned int
|
||||||
_hb_glyph_info_get_glyph_props (const hb_glyph_info_t *info)
|
_hb_glyph_info_get_glyph_props (const hb_glyph_info_t *info)
|
||||||
{
|
{
|
||||||
return info->glyph_props();
|
return info->glyph_props();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
static inline bool
|
||||||
_hb_glyph_info_is_base_glyph (const hb_glyph_info_t *info)
|
_hb_glyph_info_is_base_glyph (const hb_glyph_info_t *info)
|
||||||
{
|
{
|
||||||
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
|
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
static inline bool
|
||||||
_hb_glyph_info_is_ligature (const hb_glyph_info_t *info)
|
_hb_glyph_info_is_ligature (const hb_glyph_info_t *info)
|
||||||
{
|
{
|
||||||
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE);
|
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
static inline bool
|
||||||
_hb_glyph_info_is_mark (const hb_glyph_info_t *info)
|
_hb_glyph_info_is_mark (const hb_glyph_info_t *info)
|
||||||
{
|
{
|
||||||
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
|
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
|
||||||
@ -381,23 +383,50 @@ _hb_glyph_info_ligated (const hb_glyph_info_t *info)
|
|||||||
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED);
|
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
_hb_glyph_info_multiplied (const hb_glyph_info_t *info)
|
||||||
|
{
|
||||||
|
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
_hb_glyph_info_ligated_and_didnt_multiply (const hb_glyph_info_t *info)
|
||||||
|
{
|
||||||
|
return _hb_glyph_info_ligated (info) && !_hb_glyph_info_multiplied (info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_hb_glyph_info_clear_ligated_and_multiplied (hb_glyph_info_t *info)
|
||||||
|
{
|
||||||
|
info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_LIGATED |
|
||||||
|
HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Allocation / deallocation. */
|
/* Allocation / deallocation. */
|
||||||
|
|
||||||
inline void
|
static inline void
|
||||||
_hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer)
|
_hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props0);
|
HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props0);
|
||||||
HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props1);
|
HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props1);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
static inline void
|
||||||
_hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer)
|
_hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props0);
|
HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props0);
|
||||||
HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props1);
|
HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props1);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
static inline void
|
||||||
|
_hb_buffer_assert_unicode_vars (hb_buffer_t *buffer)
|
||||||
|
{
|
||||||
|
HB_BUFFER_ASSERT_VAR (buffer, unicode_props0);
|
||||||
|
HB_BUFFER_ASSERT_VAR (buffer, unicode_props1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
_hb_buffer_allocate_gsubgpos_vars (hb_buffer_t *buffer)
|
_hb_buffer_allocate_gsubgpos_vars (hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props);
|
HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props);
|
||||||
@ -405,7 +434,7 @@ _hb_buffer_allocate_gsubgpos_vars (hb_buffer_t *buffer)
|
|||||||
HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
|
HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
static inline void
|
||||||
_hb_buffer_deallocate_gsubgpos_vars (hb_buffer_t *buffer)
|
_hb_buffer_deallocate_gsubgpos_vars (hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
|
HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
|
||||||
@ -413,6 +442,14 @@ _hb_buffer_deallocate_gsubgpos_vars (hb_buffer_t *buffer)
|
|||||||
HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props);
|
HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_hb_buffer_assert_gsubgpos_vars (hb_buffer_t *buffer)
|
||||||
|
{
|
||||||
|
HB_BUFFER_ASSERT_VAR (buffer, glyph_props);
|
||||||
|
HB_BUFFER_ASSERT_VAR (buffer, lig_props);
|
||||||
|
HB_BUFFER_ASSERT_VAR (buffer, syllable);
|
||||||
|
}
|
||||||
|
|
||||||
/* Make sure no one directly touches our props... */
|
/* Make sure no one directly touches our props... */
|
||||||
#undef unicode_props0
|
#undef unicode_props0
|
||||||
#undef unicode_props1
|
#undef unicode_props1
|
||||||
|
@ -327,9 +327,28 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
|
|||||||
unsigned int language_index,
|
unsigned int language_index,
|
||||||
unsigned int *feature_index)
|
unsigned int *feature_index)
|
||||||
{
|
{
|
||||||
const OT::LangSys &l = get_gsubgpos_table (face, table_tag).get_script (script_index).get_lang_sys (language_index);
|
return hb_ot_layout_language_get_required_feature (face,
|
||||||
|
table_tag,
|
||||||
|
script_index,
|
||||||
|
language_index,
|
||||||
|
feature_index,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (feature_index) *feature_index = l.get_required_feature_index ();
|
hb_bool_t
|
||||||
|
hb_ot_layout_language_get_required_feature (hb_face_t *face,
|
||||||
|
hb_tag_t table_tag,
|
||||||
|
unsigned int script_index,
|
||||||
|
unsigned int language_index,
|
||||||
|
unsigned int *feature_index,
|
||||||
|
hb_tag_t *feature_tag)
|
||||||
|
{
|
||||||
|
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
|
||||||
|
const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
|
||||||
|
|
||||||
|
unsigned int index = l.get_required_feature_index ();
|
||||||
|
if (feature_index) *feature_index = index;
|
||||||
|
if (feature_tag) *feature_tag = g.get_feature_tag (index);
|
||||||
|
|
||||||
return l.has_required_feature ();
|
return l.has_required_feature ();
|
||||||
}
|
}
|
||||||
@ -468,11 +487,12 @@ _hb_ot_layout_collect_lookups_features (hb_face_t *face,
|
|||||||
if (!features)
|
if (!features)
|
||||||
{
|
{
|
||||||
unsigned int required_feature_index;
|
unsigned int required_feature_index;
|
||||||
if (hb_ot_layout_language_get_required_feature_index (face,
|
if (hb_ot_layout_language_get_required_feature (face,
|
||||||
table_tag,
|
table_tag,
|
||||||
script_index,
|
script_index,
|
||||||
language_index,
|
language_index,
|
||||||
&required_feature_index))
|
&required_feature_index,
|
||||||
|
NULL))
|
||||||
_hb_ot_layout_collect_lookups_lookups (face,
|
_hb_ot_layout_collect_lookups_lookups (face,
|
||||||
table_tag,
|
table_tag,
|
||||||
required_feature_index,
|
required_feature_index,
|
||||||
|
@ -92,9 +92,9 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font,
|
|||||||
* GSUB/GPOS feature query and enumeration interface
|
* GSUB/GPOS feature query and enumeration interface
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define HB_OT_LAYOUT_NO_SCRIPT_INDEX ((unsigned int) 0xFFFF)
|
#define HB_OT_LAYOUT_NO_SCRIPT_INDEX 0xFFFFu
|
||||||
#define HB_OT_LAYOUT_NO_FEATURE_INDEX ((unsigned int) 0xFFFF)
|
#define HB_OT_LAYOUT_NO_FEATURE_INDEX 0xFFFFu
|
||||||
#define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX ((unsigned int) 0xFFFF)
|
#define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX 0xFFFFu
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
hb_ot_layout_table_get_script_tags (hb_face_t *face,
|
hb_ot_layout_table_get_script_tags (hb_face_t *face,
|
||||||
@ -146,6 +146,14 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
|
|||||||
unsigned int language_index,
|
unsigned int language_index,
|
||||||
unsigned int *feature_index);
|
unsigned int *feature_index);
|
||||||
|
|
||||||
|
hb_bool_t
|
||||||
|
hb_ot_layout_language_get_required_feature (hb_face_t *face,
|
||||||
|
hb_tag_t table_tag,
|
||||||
|
unsigned int script_index,
|
||||||
|
unsigned int language_index,
|
||||||
|
unsigned int *feature_index,
|
||||||
|
hb_tag_t *feature_tag);
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
|
hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
|
||||||
hb_tag_t table_tag,
|
hb_tag_t table_tag,
|
||||||
|
@ -153,26 +153,26 @@ struct hb_ot_map_t
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum hb_ot_map_feature_flags_t {
|
enum hb_ot_map_feature_flags_t {
|
||||||
F_NONE = 0x0000,
|
F_NONE = 0x0000u,
|
||||||
F_GLOBAL = 0x0001,
|
F_GLOBAL = 0x0001u,
|
||||||
F_HAS_FALLBACK = 0x0002,
|
F_HAS_FALLBACK = 0x0002u,
|
||||||
F_MANUAL_ZWJ = 0x0004
|
F_MANUAL_ZWJ = 0x0004u
|
||||||
};
|
};
|
||||||
/* Macro version for where const is desired. */
|
/* Macro version for where const is desired. */
|
||||||
#define F_COMBINE(l,r) (hb_ot_map_feature_flags_t ((unsigned int) (l) | (unsigned int) (r)))
|
#define F_COMBINE(l,r) (hb_ot_map_feature_flags_t ((unsigned int) (l) | (unsigned int) (r)))
|
||||||
inline hb_ot_map_feature_flags_t
|
static inline hb_ot_map_feature_flags_t
|
||||||
operator | (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r)
|
operator | (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r)
|
||||||
{ return hb_ot_map_feature_flags_t ((unsigned int) l | (unsigned int) r); }
|
{ return hb_ot_map_feature_flags_t ((unsigned int) l | (unsigned int) r); }
|
||||||
inline hb_ot_map_feature_flags_t
|
static inline hb_ot_map_feature_flags_t
|
||||||
operator & (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r)
|
operator & (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r)
|
||||||
{ return hb_ot_map_feature_flags_t ((unsigned int) l & (unsigned int) r); }
|
{ return hb_ot_map_feature_flags_t ((unsigned int) l & (unsigned int) r); }
|
||||||
inline hb_ot_map_feature_flags_t
|
static inline hb_ot_map_feature_flags_t
|
||||||
operator ~ (hb_ot_map_feature_flags_t r)
|
operator ~ (hb_ot_map_feature_flags_t r)
|
||||||
{ return hb_ot_map_feature_flags_t (~(unsigned int) r); }
|
{ return hb_ot_map_feature_flags_t (~(unsigned int) r); }
|
||||||
inline hb_ot_map_feature_flags_t&
|
static inline hb_ot_map_feature_flags_t&
|
||||||
operator |= (hb_ot_map_feature_flags_t &l, hb_ot_map_feature_flags_t r)
|
operator |= (hb_ot_map_feature_flags_t &l, hb_ot_map_feature_flags_t r)
|
||||||
{ l = l | r; return l; }
|
{ l = l | r; return l; }
|
||||||
inline hb_ot_map_feature_flags_t&
|
static inline hb_ot_map_feature_flags_t&
|
||||||
operator &= (hb_ot_map_feature_flags_t& l, hb_ot_map_feature_flags_t r)
|
operator &= (hb_ot_map_feature_flags_t& l, hb_ot_map_feature_flags_t r)
|
||||||
{ l = l & r; return l; }
|
{ l = l & r; return l; }
|
||||||
|
|
||||||
|
@ -99,6 +99,7 @@ void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value,
|
|||||||
{
|
{
|
||||||
feature_info_t *info = feature_infos.push();
|
feature_info_t *info = feature_infos.push();
|
||||||
if (unlikely (!info)) return;
|
if (unlikely (!info)) return;
|
||||||
|
if (unlikely (!tag)) return;
|
||||||
info->tag = tag;
|
info->tag = tag;
|
||||||
info->seq = feature_infos.len;
|
info->seq = feature_infos.len;
|
||||||
info->max_value = value;
|
info->max_value = value;
|
||||||
@ -131,9 +132,25 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
|
|||||||
{
|
{
|
||||||
m.global_mask = 1;
|
m.global_mask = 1;
|
||||||
|
|
||||||
for (unsigned int table_index = 0; table_index < 2; table_index++) {
|
unsigned int required_feature_index[2];
|
||||||
|
hb_tag_t required_feature_tag[2];
|
||||||
|
/* We default to applying required feature in stage 0. If the required
|
||||||
|
* feature has a tag that is known to the shaper, we apply required feature
|
||||||
|
* in the stage for that tag.
|
||||||
|
*/
|
||||||
|
unsigned int required_feature_stage[2] = {0, 0};
|
||||||
|
|
||||||
|
for (unsigned int table_index = 0; table_index < 2; table_index++)
|
||||||
|
{
|
||||||
m.chosen_script[table_index] = chosen_script[table_index];
|
m.chosen_script[table_index] = chosen_script[table_index];
|
||||||
m.found_script[table_index] = found_script[table_index];
|
m.found_script[table_index] = found_script[table_index];
|
||||||
|
|
||||||
|
hb_ot_layout_language_get_required_feature (face,
|
||||||
|
table_tags[table_index],
|
||||||
|
script_index[table_index],
|
||||||
|
language_index[table_index],
|
||||||
|
&required_feature_index[table_index],
|
||||||
|
&required_feature_tag[table_index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!feature_infos.len)
|
if (!feature_infos.len)
|
||||||
@ -141,7 +158,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
|
|||||||
|
|
||||||
/* Sort features and merge duplicates */
|
/* Sort features and merge duplicates */
|
||||||
{
|
{
|
||||||
feature_infos.sort ();
|
feature_infos.qsort ();
|
||||||
unsigned int j = 0;
|
unsigned int j = 0;
|
||||||
for (unsigned int i = 1; i < feature_infos.len; i++)
|
for (unsigned int i = 1; i < feature_infos.len; i++)
|
||||||
if (feature_infos[i].tag != feature_infos[j].tag)
|
if (feature_infos[i].tag != feature_infos[j].tag)
|
||||||
@ -166,7 +183,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
|
|||||||
|
|
||||||
/* Allocate bits now */
|
/* Allocate bits now */
|
||||||
unsigned int next_bit = 1;
|
unsigned int next_bit = 1;
|
||||||
for (unsigned int i = 0; i < feature_infos.len; i++) {
|
for (unsigned int i = 0; i < feature_infos.len; i++)
|
||||||
|
{
|
||||||
const feature_info_t *info = &feature_infos[i];
|
const feature_info_t *info = &feature_infos[i];
|
||||||
|
|
||||||
unsigned int bits_needed;
|
unsigned int bits_needed;
|
||||||
@ -184,12 +202,20 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
|
|||||||
hb_bool_t found = false;
|
hb_bool_t found = false;
|
||||||
unsigned int feature_index[2];
|
unsigned int feature_index[2];
|
||||||
for (unsigned int table_index = 0; table_index < 2; table_index++)
|
for (unsigned int table_index = 0; table_index < 2; table_index++)
|
||||||
|
{
|
||||||
|
if (required_feature_tag[table_index] == info->tag)
|
||||||
|
{
|
||||||
|
required_feature_stage[table_index] = info->stage[table_index];
|
||||||
|
found = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
found |= hb_ot_layout_language_find_feature (face,
|
found |= hb_ot_layout_language_find_feature (face,
|
||||||
table_tags[table_index],
|
table_tags[table_index],
|
||||||
script_index[table_index],
|
script_index[table_index],
|
||||||
language_index[table_index],
|
language_index[table_index],
|
||||||
info->tag,
|
info->tag,
|
||||||
&feature_index[table_index]);
|
&feature_index[table_index]);
|
||||||
|
}
|
||||||
if (!found && !(info->flags & F_HAS_FALLBACK))
|
if (!found && !(info->flags & F_HAS_FALLBACK))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -224,23 +250,21 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
|
|||||||
add_gsub_pause (NULL);
|
add_gsub_pause (NULL);
|
||||||
add_gpos_pause (NULL);
|
add_gpos_pause (NULL);
|
||||||
|
|
||||||
for (unsigned int table_index = 0; table_index < 2; table_index++) {
|
for (unsigned int table_index = 0; table_index < 2; table_index++)
|
||||||
hb_tag_t table_tag = table_tags[table_index];
|
{
|
||||||
|
|
||||||
/* Collect lookup indices for features */
|
/* Collect lookup indices for features */
|
||||||
|
|
||||||
unsigned int required_feature_index;
|
|
||||||
if (hb_ot_layout_language_get_required_feature_index (face,
|
|
||||||
table_tag,
|
|
||||||
script_index[table_index],
|
|
||||||
language_index[table_index],
|
|
||||||
&required_feature_index))
|
|
||||||
m.add_lookups (face, table_index, required_feature_index, 1, true);
|
|
||||||
|
|
||||||
unsigned int stage_index = 0;
|
unsigned int stage_index = 0;
|
||||||
unsigned int last_num_lookups = 0;
|
unsigned int last_num_lookups = 0;
|
||||||
for (unsigned stage = 0; stage < current_stage[table_index]; stage++)
|
for (unsigned stage = 0; stage < current_stage[table_index]; stage++)
|
||||||
{
|
{
|
||||||
|
if (required_feature_index[table_index] != HB_OT_LAYOUT_NO_FEATURE_INDEX &&
|
||||||
|
required_feature_stage[table_index] == stage)
|
||||||
|
m.add_lookups (face, table_index,
|
||||||
|
required_feature_index[table_index],
|
||||||
|
1 /* mask */,
|
||||||
|
true /* auto_zwj */);
|
||||||
|
|
||||||
for (unsigned i = 0; i < m.features.len; i++)
|
for (unsigned i = 0; i < m.features.len; i++)
|
||||||
if (m.features[i].stage[table_index] == stage)
|
if (m.features[i].stage[table_index] == stage)
|
||||||
m.add_lookups (face, table_index,
|
m.add_lookups (face, table_index,
|
||||||
@ -251,7 +275,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
|
|||||||
/* Sort lookups and merge duplicates */
|
/* Sort lookups and merge duplicates */
|
||||||
if (last_num_lookups < m.lookups[table_index].len)
|
if (last_num_lookups < m.lookups[table_index].len)
|
||||||
{
|
{
|
||||||
m.lookups[table_index].sort (last_num_lookups, m.lookups[table_index].len);
|
m.lookups[table_index].qsort (last_num_lookups, m.lookups[table_index].len);
|
||||||
|
|
||||||
unsigned int j = last_num_lookups;
|
unsigned int j = last_num_lookups;
|
||||||
for (unsigned int i = j + 1; i < m.lookups[table_index].len; i++)
|
for (unsigned int i = j + 1; i < m.lookups[table_index].len; i++)
|
||||||
|
@ -50,13 +50,13 @@ struct maxp
|
|||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) &&
|
return TRACE_RETURN (c->check_struct (this) &&
|
||||||
likely (version.major == 1 || (version.major == 0 && version.minor == 0x5000)));
|
likely (version.major == 1 || (version.major == 0 && version.minor == 0x5000u)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We only implement version 0.5 as none of the extra fields in version 1.0 are useful. */
|
/* We only implement version 0.5 as none of the extra fields in version 1.0 are useful. */
|
||||||
protected:
|
protected:
|
||||||
FixedVersion version; /* Version of the maxp table (0.5 or 1.0),
|
FixedVersion version; /* Version of the maxp table (0.5 or 1.0),
|
||||||
* 0x00005000 or 0x00010000. */
|
* 0x00005000u or 0x00010000u. */
|
||||||
USHORT numGlyphs; /* The number of glyphs in the font. */
|
USHORT numGlyphs; /* The number of glyphs in the font. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (6);
|
DEFINE_SIZE_STATIC (6);
|
||||||
|
@ -121,7 +121,7 @@ struct name
|
|||||||
/* We only implement format 0 for now. */
|
/* We only implement format 0 for now. */
|
||||||
USHORT format; /* Format selector (=0/1). */
|
USHORT format; /* Format selector (=0/1). */
|
||||||
USHORT count; /* Number of name records. */
|
USHORT count; /* Number of name records. */
|
||||||
Offset stringOffset; /* Offset to start of string storage (from start of table). */
|
Offset<> stringOffset; /* Offset to start of string storage (from start of table). */
|
||||||
NameRecord nameRecord[VAR]; /* The name records where count is the number of records. */
|
NameRecord nameRecord[VAR]; /* The name records where count is the number of records. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (6, nameRecord);
|
DEFINE_SIZE_ARRAY (6, nameRecord);
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
#include "hb-ot-layout-gsub-table.hh"
|
#include "hb-ot-layout-gsub-table.hh"
|
||||||
|
|
||||||
|
|
||||||
|
/* Features ordered the same as the entries in shaping_table rows,
|
||||||
|
* followed by rlig. Don't change. */
|
||||||
static const hb_tag_t arabic_fallback_features[] =
|
static const hb_tag_t arabic_fallback_features[] =
|
||||||
{
|
{
|
||||||
HB_TAG('i','n','i','t'),
|
HB_TAG('i','n','i','t'),
|
||||||
@ -42,16 +44,6 @@ static const hb_tag_t arabic_fallback_features[] =
|
|||||||
HB_TAG('r','l','i','g'),
|
HB_TAG('r','l','i','g'),
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Same order as the fallback feature array */
|
|
||||||
enum {
|
|
||||||
FALLBACK_INIT,
|
|
||||||
FALLBACK_MEDI,
|
|
||||||
FALLBACK_FINA,
|
|
||||||
FALLBACK_ISOL,
|
|
||||||
FALLBACK_RLIG,
|
|
||||||
ARABIC_NUM_FALLBACK_FEATURES
|
|
||||||
};
|
|
||||||
|
|
||||||
static OT::SubstLookup *
|
static OT::SubstLookup *
|
||||||
arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||||
hb_font_t *font,
|
hb_font_t *font,
|
||||||
@ -71,7 +63,7 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
|
|||||||
!hb_font_get_glyph (font, u, 0, &u_glyph) ||
|
!hb_font_get_glyph (font, u, 0, &u_glyph) ||
|
||||||
!hb_font_get_glyph (font, s, 0, &s_glyph) ||
|
!hb_font_get_glyph (font, s, 0, &s_glyph) ||
|
||||||
u_glyph == s_glyph ||
|
u_glyph == s_glyph ||
|
||||||
u_glyph > 0xFFFF || s_glyph > 0xFFFF)
|
u_glyph > 0xFFFFu || s_glyph > 0xFFFFu)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
glyphs[num_glyphs].set (u_glyph);
|
glyphs[num_glyphs].set (u_glyph);
|
||||||
@ -80,6 +72,9 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
|
|||||||
num_glyphs++;
|
num_glyphs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!num_glyphs)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* Bubble-sort!
|
/* Bubble-sort!
|
||||||
* May not be good-enough for presidential candidate interviews, but good-enough for us... */
|
* May not be good-enough for presidential candidate interviews, but good-enough for us... */
|
||||||
hb_bubble_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]);
|
hb_bubble_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]);
|
||||||
@ -157,6 +152,9 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!num_ligatures)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
OT::Supplier<OT::GlyphID> first_glyphs_supplier (first_glyphs, num_first_glyphs);
|
OT::Supplier<OT::GlyphID> first_glyphs_supplier (first_glyphs, num_first_glyphs);
|
||||||
OT::Supplier<unsigned int > ligature_per_first_glyph_count_supplier (ligature_per_first_glyph_count_list, num_first_glyphs);
|
OT::Supplier<unsigned int > ligature_per_first_glyph_count_supplier (ligature_per_first_glyph_count_list, num_first_glyphs);
|
||||||
OT::Supplier<OT::GlyphID> ligatures_supplier (ligature_list, num_ligatures);
|
OT::Supplier<OT::GlyphID> ligatures_supplier (ligature_list, num_ligatures);
|
||||||
@ -193,17 +191,108 @@ arabic_fallback_synthesize_lookup (const hb_ot_shape_plan_t *plan,
|
|||||||
return arabic_fallback_synthesize_lookup_ligature (plan, font);
|
return arabic_fallback_synthesize_lookup_ligature (plan, font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ARABIC_FALLBACK_MAX_LOOKUPS 5
|
||||||
|
|
||||||
struct arabic_fallback_plan_t
|
struct arabic_fallback_plan_t
|
||||||
{
|
{
|
||||||
ASSERT_POD ();
|
ASSERT_POD ();
|
||||||
|
|
||||||
hb_mask_t mask_array[ARABIC_NUM_FALLBACK_FEATURES];
|
unsigned int num_lookups;
|
||||||
OT::SubstLookup *lookup_array[ARABIC_NUM_FALLBACK_FEATURES];
|
bool free_lookups;
|
||||||
hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_NUM_FALLBACK_FEATURES];
|
|
||||||
|
hb_mask_t mask_array[ARABIC_FALLBACK_MAX_LOOKUPS];
|
||||||
|
OT::SubstLookup *lookup_array[ARABIC_FALLBACK_MAX_LOOKUPS];
|
||||||
|
hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_FALLBACK_MAX_LOOKUPS];
|
||||||
};
|
};
|
||||||
|
|
||||||
static const arabic_fallback_plan_t arabic_fallback_plan_nil = {};
|
static const arabic_fallback_plan_t arabic_fallback_plan_nil = {};
|
||||||
|
|
||||||
|
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_WITH_WIN1256)
|
||||||
|
#define HB_WITH_WIN1256
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HB_WITH_WIN1256
|
||||||
|
#include "hb-ot-shape-complex-arabic-win1256.hh"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct ManifestLookup {
|
||||||
|
OT::Tag tag;
|
||||||
|
OT::OffsetTo<OT::SubstLookup> lookupOffset;
|
||||||
|
};
|
||||||
|
typedef OT::ArrayOf<ManifestLookup> Manifest;
|
||||||
|
|
||||||
|
static bool
|
||||||
|
arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan,
|
||||||
|
const hb_ot_shape_plan_t *plan,
|
||||||
|
hb_font_t *font)
|
||||||
|
{
|
||||||
|
#ifdef HB_WITH_WIN1256
|
||||||
|
/* Does this font look like it's Windows-1256-encoded? */
|
||||||
|
hb_codepoint_t g;
|
||||||
|
if (!(hb_font_get_glyph (font, 0x0627u, 0, &g) && g == 199 /* ALEF */ &&
|
||||||
|
hb_font_get_glyph (font, 0x0644u, 0, &g) && g == 225 /* LAM */ &&
|
||||||
|
hb_font_get_glyph (font, 0x0649u, 0, &g) && g == 236 /* ALEF MAKSURA */ &&
|
||||||
|
hb_font_get_glyph (font, 0x064Au, 0, &g) && g == 237 /* YEH */ &&
|
||||||
|
hb_font_get_glyph (font, 0x0652u, 0, &g) && g == 250 /* SUKUN */))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const Manifest &manifest = reinterpret_cast<const Manifest&> (arabic_win1256_gsub_lookups.manifest);
|
||||||
|
ASSERT_STATIC (sizeof (arabic_win1256_gsub_lookups.manifestData) / sizeof (ManifestLookup)
|
||||||
|
<= ARABIC_FALLBACK_MAX_LOOKUPS);
|
||||||
|
/* TODO sanitize the table? */
|
||||||
|
|
||||||
|
unsigned j = 0;
|
||||||
|
unsigned int count = manifest.len;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
fallback_plan->mask_array[j] = plan->map.get_1_mask (manifest[i].tag);
|
||||||
|
if (fallback_plan->mask_array[j])
|
||||||
|
{
|
||||||
|
fallback_plan->lookup_array[j] = const_cast<OT::SubstLookup*> (&(&manifest+manifest[i].lookupOffset));
|
||||||
|
if (fallback_plan->lookup_array[j])
|
||||||
|
{
|
||||||
|
fallback_plan->accel_array[j].init (*fallback_plan->lookup_array[j]);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fallback_plan->num_lookups = j;
|
||||||
|
fallback_plan->free_lookups = false;
|
||||||
|
|
||||||
|
return j > 0;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
arabic_fallback_plan_init_unicode (arabic_fallback_plan_t *fallback_plan,
|
||||||
|
const hb_ot_shape_plan_t *plan,
|
||||||
|
hb_font_t *font)
|
||||||
|
{
|
||||||
|
ASSERT_STATIC (ARRAY_LENGTH_CONST(arabic_fallback_features) <= ARABIC_FALLBACK_MAX_LOOKUPS);
|
||||||
|
unsigned int j = 0;
|
||||||
|
for (unsigned int i = 0; i < ARRAY_LENGTH(arabic_fallback_features) ; i++)
|
||||||
|
{
|
||||||
|
fallback_plan->mask_array[j] = plan->map.get_1_mask (arabic_fallback_features[i]);
|
||||||
|
if (fallback_plan->mask_array[j])
|
||||||
|
{
|
||||||
|
fallback_plan->lookup_array[j] = arabic_fallback_synthesize_lookup (plan, font, i);
|
||||||
|
if (fallback_plan->lookup_array[j])
|
||||||
|
{
|
||||||
|
fallback_plan->accel_array[j].init (*fallback_plan->lookup_array[j]);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fallback_plan->num_lookups = j;
|
||||||
|
fallback_plan->free_lookups = true;
|
||||||
|
|
||||||
|
return j > 0;
|
||||||
|
}
|
||||||
|
|
||||||
static arabic_fallback_plan_t *
|
static arabic_fallback_plan_t *
|
||||||
arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan,
|
arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan,
|
||||||
hb_font_t *font)
|
hb_font_t *font)
|
||||||
@ -212,17 +301,21 @@ arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan,
|
|||||||
if (unlikely (!fallback_plan))
|
if (unlikely (!fallback_plan))
|
||||||
return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil);
|
return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++)
|
fallback_plan->num_lookups = 0;
|
||||||
{
|
fallback_plan->free_lookups = false;
|
||||||
fallback_plan->mask_array[i] = plan->map.get_1_mask (arabic_fallback_features[i]);
|
|
||||||
if (fallback_plan->mask_array[i]) {
|
|
||||||
fallback_plan->lookup_array[i] = arabic_fallback_synthesize_lookup (plan, font, i);
|
|
||||||
if (fallback_plan->lookup_array[i])
|
|
||||||
fallback_plan->accel_array[i].init (*fallback_plan->lookup_array[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fallback_plan;
|
/* Try synthesizing GSUB table using Unicode Arabic Presentation Forms,
|
||||||
|
* in case the font has cmap entries for the presentation-forms characters. */
|
||||||
|
if (arabic_fallback_plan_init_unicode (fallback_plan, plan, font))
|
||||||
|
return fallback_plan;
|
||||||
|
|
||||||
|
/* See if this looks like a Windows-1256-encoded font. If it does, use a
|
||||||
|
* hand-coded GSUB table. */
|
||||||
|
if (arabic_fallback_plan_init_win1256 (fallback_plan, plan, font))
|
||||||
|
return fallback_plan;
|
||||||
|
|
||||||
|
free (fallback_plan);
|
||||||
|
return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -231,11 +324,12 @@ arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan)
|
|||||||
if (!fallback_plan || fallback_plan == &arabic_fallback_plan_nil)
|
if (!fallback_plan || fallback_plan == &arabic_fallback_plan_nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++)
|
for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
|
||||||
if (fallback_plan->lookup_array[i])
|
if (fallback_plan->lookup_array[i])
|
||||||
{
|
{
|
||||||
fallback_plan->accel_array[i].fini (fallback_plan->lookup_array[i]);
|
fallback_plan->accel_array[i].fini (fallback_plan->lookup_array[i]);
|
||||||
free (fallback_plan->lookup_array[i]);
|
if (fallback_plan->free_lookups)
|
||||||
|
free (fallback_plan->lookup_array[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (fallback_plan);
|
free (fallback_plan);
|
||||||
@ -247,7 +341,7 @@ arabic_fallback_plan_shape (arabic_fallback_plan_t *fallback_plan,
|
|||||||
hb_buffer_t *buffer)
|
hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
OT::hb_apply_context_t c (0, font, buffer);
|
OT::hb_apply_context_t c (0, font, buffer);
|
||||||
for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++)
|
for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
|
||||||
if (fallback_plan->lookup_array[i]) {
|
if (fallback_plan->lookup_array[i]) {
|
||||||
c.set_lookup_mask (fallback_plan->mask_array[i]);
|
c.set_lookup_mask (fallback_plan->mask_array[i]);
|
||||||
hb_ot_layout_substitute_lookup (&c,
|
hb_ot_layout_substitute_lookup (&c,
|
||||||
|
File diff suppressed because it is too large
Load Diff
321
gfx/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh
Normal file
321
gfx/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh
Normal file
@ -0,0 +1,321 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2014 Google, Inc.
|
||||||
|
*
|
||||||
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, without written agreement and without
|
||||||
|
* license or royalty fees, to use, copy, modify, and distribute this
|
||||||
|
* software and its documentation for any purpose, provided that the
|
||||||
|
* above copyright notice and the following two paragraphs appear in
|
||||||
|
* all copies of this software.
|
||||||
|
*
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||||
|
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||||
|
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||||
|
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||||
|
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
|
*
|
||||||
|
* Google Author(s): Behdad Esfahbod
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The macros in the first part of this file are generic macros that can
|
||||||
|
* be used to define the bytes for OpenType table data in code in a
|
||||||
|
* readable manner. We can move the macros to reside with their respective
|
||||||
|
* struct types, but since we only use these to define one data table, the
|
||||||
|
* Windows-1256 Arabic shaping table in this file, we keep them here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* First we measure, then we cut. */
|
||||||
|
#ifndef OT_MEASURE
|
||||||
|
#define OT_MEASURE
|
||||||
|
#define OT_TABLE_START static const struct TABLE_NAME {
|
||||||
|
#define OT_TABLE_END }
|
||||||
|
#define OT_LABEL_START(Name) unsigned char Name[
|
||||||
|
#define OT_LABEL_END ];
|
||||||
|
#define OT_BYTE(u8) +1/*byte*/
|
||||||
|
#define OT_USHORT(u16) +2/*bytes*/
|
||||||
|
#else
|
||||||
|
#undef OT_MEASURE
|
||||||
|
#define OT_TABLE_START TABLE_NAME = {
|
||||||
|
#define OT_TABLE_END };
|
||||||
|
#define OT_LABEL_START(Name) {
|
||||||
|
#define OT_LABEL_END },
|
||||||
|
#define OT_BYTE(u8) (u8),
|
||||||
|
#define OT_USHORT(u16) (unsigned char)((u16)>>8), (unsigned char)((u16)&0xFFu),
|
||||||
|
#define OT_COUNT(Name, ItemSize) ((unsigned int) sizeof(((struct TABLE_NAME*)0)->Name) \
|
||||||
|
/ (unsigned int)(ItemSize) \
|
||||||
|
/* OT_ASSERT it's divisible (and positive). */)
|
||||||
|
#define OT_DISTANCE(From,To) ((unsigned int) \
|
||||||
|
((char*)(&((struct TABLE_NAME*)0)->To) - \
|
||||||
|
(char*)(&((struct TABLE_NAME*)0)->From)) \
|
||||||
|
/* OT_ASSERT it's positive. */)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define OT_LABEL(Name) \
|
||||||
|
OT_LABEL_END \
|
||||||
|
OT_LABEL_START(Name)
|
||||||
|
|
||||||
|
/* Whenever we receive an argument that is a list, it will expand to
|
||||||
|
* contain commas. That cannot be passed to another macro because the
|
||||||
|
* commas will throw off the preprocessor. The solution is to wrap
|
||||||
|
* the passed-in argument in OT_LIST() before passing to the next macro.
|
||||||
|
* Unfortunately this trick requires vararg macros. */
|
||||||
|
#define OT_LIST(...) __VA_ARGS__
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Basic Types
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define OT_TAG(a,b,c,d) \
|
||||||
|
OT_BYTE(a) OT_BYTE(b) OT_BYTE(c) OT_BYTE(d)
|
||||||
|
|
||||||
|
#define OT_OFFSET(From, To) /* Offset from From to To in bytes */ \
|
||||||
|
OT_USHORT(OT_DISTANCE(From, To))
|
||||||
|
|
||||||
|
#define OT_GLYPHID /* GlyphID */ \
|
||||||
|
OT_USHORT
|
||||||
|
|
||||||
|
#define OT_UARRAY(Name, Items) \
|
||||||
|
OT_LABEL_START(Name) \
|
||||||
|
OT_USHORT(OT_COUNT(Name##Data, 2)) \
|
||||||
|
OT_LABEL(Name##Data) \
|
||||||
|
Items \
|
||||||
|
OT_LABEL_END
|
||||||
|
|
||||||
|
#define OT_UHEADLESSARRAY(Name, Items) \
|
||||||
|
OT_LABEL_START(Name) \
|
||||||
|
OT_USHORT(OT_COUNT(Name##Data, 2) + 1) \
|
||||||
|
OT_LABEL(Name##Data) \
|
||||||
|
Items \
|
||||||
|
OT_LABEL_END
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common Types
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define OT_LOOKUP_FLAG_IGNORE_MARKS 0x08u
|
||||||
|
|
||||||
|
#define OT_LOOKUP(Name, LookupType, LookupFlag, SubLookupOffsets) \
|
||||||
|
OT_LABEL_START(Name) \
|
||||||
|
OT_USHORT(LookupType) \
|
||||||
|
OT_USHORT(LookupFlag) \
|
||||||
|
OT_LABEL_END \
|
||||||
|
OT_UARRAY(Name##SubLookupOffsetsArray, OT_LIST(SubLookupOffsets))
|
||||||
|
|
||||||
|
#define OT_SUBLOOKUP(Name, SubFormat, Items) \
|
||||||
|
OT_LABEL_START(Name) \
|
||||||
|
OT_USHORT(SubFormat) \
|
||||||
|
Items
|
||||||
|
|
||||||
|
#define OT_COVERAGE1(Name, Items) \
|
||||||
|
OT_LABEL_START(Name) \
|
||||||
|
OT_USHORT(1) \
|
||||||
|
OT_LABEL_END \
|
||||||
|
OT_UARRAY(Name##Glyphs, OT_LIST(Items))
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GSUB
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define OT_LOOKUP_TYPE_SUBST_SINGLE 1u
|
||||||
|
#define OT_LOOKUP_TYPE_SUBST_MULTIPLE 2u
|
||||||
|
#define OT_LOOKUP_TYPE_SUBST_LIGATURE 4u
|
||||||
|
|
||||||
|
#define OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(Name, FromGlyphs, ToGlyphs) \
|
||||||
|
OT_SUBLOOKUP(Name, 2, \
|
||||||
|
OT_OFFSET(Name, Name##Coverage) \
|
||||||
|
OT_LABEL_END \
|
||||||
|
OT_UARRAY(Name##Substitute, OT_LIST(ToGlyphs)) \
|
||||||
|
) \
|
||||||
|
OT_COVERAGE1(Name##Coverage, OT_LIST(FromGlyphs)) \
|
||||||
|
/* ASSERT_STATIC_EXPR len(FromGlyphs) == len(ToGlyphs) */
|
||||||
|
|
||||||
|
#define OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(Name, FirstGlyphs, LigatureSetOffsets) \
|
||||||
|
OT_SUBLOOKUP(Name, 1, \
|
||||||
|
OT_OFFSET(Name, Name##Coverage) \
|
||||||
|
OT_LABEL_END \
|
||||||
|
OT_UARRAY(Name##LigatureSetOffsetsArray, OT_LIST(LigatureSetOffsets)) \
|
||||||
|
) \
|
||||||
|
OT_COVERAGE1(Name##Coverage, OT_LIST(FirstGlyphs)) \
|
||||||
|
/* ASSERT_STATIC_EXPR len(FirstGlyphs) == len(LigatureSetOffsets) */
|
||||||
|
|
||||||
|
#define OT_LIGATURE_SET(Name, LigatureSetOffsets) \
|
||||||
|
OT_UARRAY(Name, OT_LIST(LigatureSetOffsets))
|
||||||
|
|
||||||
|
#define OT_LIGATURE(Name, Components, LigGlyph) \
|
||||||
|
OT_LABEL_START(Name) \
|
||||||
|
LigGlyph \
|
||||||
|
OT_LABEL_END \
|
||||||
|
OT_UHEADLESSARRAY(Name##ComponentsArray, OT_LIST(Components))
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Start of Windows-1256 shaping table.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Table name. */
|
||||||
|
#define TABLE_NAME arabic_win1256_gsub_lookups
|
||||||
|
|
||||||
|
/* Table manifest. */
|
||||||
|
#define MANIFEST(Items) \
|
||||||
|
OT_LABEL_START(manifest) \
|
||||||
|
OT_USHORT(OT_COUNT(manifestData, 6)) \
|
||||||
|
OT_LABEL(manifestData) \
|
||||||
|
Items \
|
||||||
|
OT_LABEL_END
|
||||||
|
|
||||||
|
#define MANIFEST_LOOKUP(Tag, Name) \
|
||||||
|
Tag \
|
||||||
|
OT_OFFSET(manifest, Name)
|
||||||
|
|
||||||
|
/* Shorthand. */
|
||||||
|
#define G OT_GLYPHID
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table Start
|
||||||
|
*/
|
||||||
|
OT_TABLE_START
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Manifest
|
||||||
|
*/
|
||||||
|
MANIFEST(
|
||||||
|
MANIFEST_LOOKUP(OT_TAG('r','l','i','g'), rligLookup)
|
||||||
|
MANIFEST_LOOKUP(OT_TAG('i','n','i','t'), initLookup)
|
||||||
|
MANIFEST_LOOKUP(OT_TAG('m','e','d','i'), mediLookup)
|
||||||
|
MANIFEST_LOOKUP(OT_TAG('f','i','n','a'), finaLookup)
|
||||||
|
MANIFEST_LOOKUP(OT_TAG('r','l','i','g'), rligMarksLookup)
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lookups
|
||||||
|
*/
|
||||||
|
OT_LOOKUP(initLookup, OT_LOOKUP_TYPE_SUBST_SINGLE, OT_LOOKUP_FLAG_IGNORE_MARKS,
|
||||||
|
OT_OFFSET(initLookup, initmediSubLookup)
|
||||||
|
OT_OFFSET(initLookup, initSubLookup)
|
||||||
|
)
|
||||||
|
OT_LOOKUP(mediLookup, OT_LOOKUP_TYPE_SUBST_SINGLE, OT_LOOKUP_FLAG_IGNORE_MARKS,
|
||||||
|
OT_OFFSET(mediLookup, initmediSubLookup)
|
||||||
|
OT_OFFSET(mediLookup, mediSubLookup)
|
||||||
|
OT_OFFSET(mediLookup, medifinaLamAlefSubLookup)
|
||||||
|
)
|
||||||
|
OT_LOOKUP(finaLookup, OT_LOOKUP_TYPE_SUBST_SINGLE, OT_LOOKUP_FLAG_IGNORE_MARKS,
|
||||||
|
OT_OFFSET(finaLookup, finaSubLookup)
|
||||||
|
/* We don't need this one currently as the sequence inherits masks
|
||||||
|
* from the first item. Just in case we change that in the future
|
||||||
|
* to be smart about Arabic masks when ligating... */
|
||||||
|
OT_OFFSET(finaLookup, medifinaLamAlefSubLookup)
|
||||||
|
)
|
||||||
|
OT_LOOKUP(rligLookup, OT_LOOKUP_TYPE_SUBST_LIGATURE, OT_LOOKUP_FLAG_IGNORE_MARKS,
|
||||||
|
OT_OFFSET(rligLookup, lamAlefLigaturesSubLookup)
|
||||||
|
)
|
||||||
|
OT_LOOKUP(rligMarksLookup, OT_LOOKUP_TYPE_SUBST_LIGATURE, 0,
|
||||||
|
OT_OFFSET(rligMarksLookup, shaddaLigaturesSubLookup)
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* init/medi/fina forms
|
||||||
|
*/
|
||||||
|
OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(initmediSubLookup,
|
||||||
|
G(198) G(200) G(201) G(202) G(203) G(204) G(205) G(206) G(211)
|
||||||
|
G(212) G(213) G(214) G(223) G(225) G(227) G(228) G(236) G(237),
|
||||||
|
G(162) G(4) G(5) G(5) G(6) G(7) G(9) G(11) G(13)
|
||||||
|
G(14) G(15) G(26) G(140) G(141) G(142) G(143) G(154) G(154)
|
||||||
|
)
|
||||||
|
OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(initSubLookup,
|
||||||
|
G(218) G(219) G(221) G(222) G(229),
|
||||||
|
G(27) G(30) G(128) G(131) G(144)
|
||||||
|
)
|
||||||
|
OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(mediSubLookup,
|
||||||
|
G(218) G(219) G(221) G(222) G(229),
|
||||||
|
G(28) G(31) G(129) G(138) G(149)
|
||||||
|
)
|
||||||
|
OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(finaSubLookup,
|
||||||
|
G(194) G(195) G(197) G(198) G(199) G(201) G(204) G(205) G(206)
|
||||||
|
G(218) G(219) G(229) G(236) G(237),
|
||||||
|
G(2) G(1) G(3) G(181) G(0) G(159) G(8) G(10) G(12)
|
||||||
|
G(29) G(127) G(152) G(160) G(156)
|
||||||
|
)
|
||||||
|
OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(medifinaLamAlefSubLookup,
|
||||||
|
G(165) G(178) G(180) G(252),
|
||||||
|
G(170) G(179) G(185) G(255)
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lam+Alef ligatures
|
||||||
|
*/
|
||||||
|
OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(lamAlefLigaturesSubLookup,
|
||||||
|
G(225),
|
||||||
|
OT_OFFSET(lamAlefLigaturesSubLookup, lamLigatureSet)
|
||||||
|
)
|
||||||
|
OT_LIGATURE_SET(lamLigatureSet,
|
||||||
|
OT_OFFSET(lamLigatureSet, lamInitLigature1)
|
||||||
|
OT_OFFSET(lamLigatureSet, lamInitLigature2)
|
||||||
|
OT_OFFSET(lamLigatureSet, lamInitLigature3)
|
||||||
|
OT_OFFSET(lamLigatureSet, lamInitLigature4)
|
||||||
|
)
|
||||||
|
OT_LIGATURE(lamInitLigature1, G(199), G(165))
|
||||||
|
OT_LIGATURE(lamInitLigature2, G(195), G(178))
|
||||||
|
OT_LIGATURE(lamInitLigature3, G(194), G(180))
|
||||||
|
OT_LIGATURE(lamInitLigature4, G(197), G(252))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shadda ligatures
|
||||||
|
*/
|
||||||
|
OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(shaddaLigaturesSubLookup,
|
||||||
|
G(248),
|
||||||
|
OT_OFFSET(shaddaLigaturesSubLookup, shaddaLigatureSet)
|
||||||
|
)
|
||||||
|
OT_LIGATURE_SET(shaddaLigatureSet,
|
||||||
|
OT_OFFSET(shaddaLigatureSet, shaddaLigature1)
|
||||||
|
OT_OFFSET(shaddaLigatureSet, shaddaLigature2)
|
||||||
|
OT_OFFSET(shaddaLigatureSet, shaddaLigature3)
|
||||||
|
)
|
||||||
|
OT_LIGATURE(shaddaLigature1, G(243), G(172))
|
||||||
|
OT_LIGATURE(shaddaLigature2, G(245), G(173))
|
||||||
|
OT_LIGATURE(shaddaLigature3, G(246), G(175))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table end
|
||||||
|
*/
|
||||||
|
OT_TABLE_END
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clean up
|
||||||
|
*/
|
||||||
|
#undef OT_TABLE_START
|
||||||
|
#undef OT_TABLE_END
|
||||||
|
#undef OT_LABEL_START
|
||||||
|
#undef OT_LABEL_END
|
||||||
|
#undef OT_BYTE
|
||||||
|
#undef OT_USHORT
|
||||||
|
#undef OT_DISTANCE
|
||||||
|
#undef OT_COUNT
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Include a second time to get the table data...
|
||||||
|
*/
|
||||||
|
#ifdef OT_MEASURE
|
||||||
|
#include __FILE__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH
|
||||||
|
#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH */
|
@ -57,68 +57,41 @@ enum {
|
|||||||
|
|
||||||
static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat)
|
static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat)
|
||||||
{
|
{
|
||||||
if (likely (hb_in_range<hb_codepoint_t> (u, JOINING_TABLE_FIRST, JOINING_TABLE_LAST))) {
|
unsigned int j_type = joining_type(u);
|
||||||
unsigned int j_type = joining_table[u - JOINING_TABLE_FIRST];
|
if (likely (j_type != JOINING_TYPE_X))
|
||||||
if (likely (j_type != JOINING_TYPE_X))
|
return j_type;
|
||||||
return j_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mongolian joining data is not in ArabicJoining.txt yet. */
|
return (FLAG(gen_cat) &
|
||||||
if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x1800, 0x18AF)))
|
(FLAG(HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) |
|
||||||
{
|
FLAG(HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) |
|
||||||
if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x1880, 0x1886)))
|
FLAG(HB_UNICODE_GENERAL_CATEGORY_FORMAT))
|
||||||
return JOINING_TYPE_U;
|
) ? JOINING_TYPE_T : JOINING_TYPE_U;
|
||||||
|
|
||||||
/* All letters, SIBE SYLLABLE BOUNDARY MARKER, and NIRUGU are D */
|
|
||||||
if ((FLAG(gen_cat) & (FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) |
|
|
||||||
FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER)))
|
|
||||||
|| u == 0x1807 || u == 0x180A)
|
|
||||||
return JOINING_TYPE_D;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 'Phags-pa joining data is not in ArabicJoining.txt yet. */
|
|
||||||
if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xA840, 0xA872)))
|
|
||||||
{
|
|
||||||
if (unlikely (u == 0xA872))
|
|
||||||
return JOINING_TYPE_L;
|
|
||||||
|
|
||||||
return JOINING_TYPE_D;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x200C, 0x200D)))
|
|
||||||
{
|
|
||||||
return u == 0x200C ? JOINING_TYPE_U : JOINING_TYPE_C;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (FLAG(gen_cat) & (FLAG(HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEGORY_FORMAT))) ?
|
|
||||||
JOINING_TYPE_T : JOINING_TYPE_U;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define FEATURE_IS_SYRIAC(tag) hb_in_range<unsigned char> ((unsigned char) (tag), '2', '3')
|
||||||
|
|
||||||
static const hb_tag_t arabic_features[] =
|
static const hb_tag_t arabic_features[] =
|
||||||
{
|
{
|
||||||
HB_TAG('i','n','i','t'),
|
|
||||||
HB_TAG('m','e','d','i'),
|
|
||||||
HB_TAG('f','i','n','a'),
|
|
||||||
HB_TAG('i','s','o','l'),
|
HB_TAG('i','s','o','l'),
|
||||||
/* Syriac */
|
HB_TAG('f','i','n','a'),
|
||||||
HB_TAG('m','e','d','2'),
|
|
||||||
HB_TAG('f','i','n','2'),
|
HB_TAG('f','i','n','2'),
|
||||||
HB_TAG('f','i','n','3'),
|
HB_TAG('f','i','n','3'),
|
||||||
|
HB_TAG('m','e','d','i'),
|
||||||
|
HB_TAG('m','e','d','2'),
|
||||||
|
HB_TAG('i','n','i','t'),
|
||||||
HB_TAG_NONE
|
HB_TAG_NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Same order as the feature array */
|
/* Same order as the feature array */
|
||||||
enum {
|
enum {
|
||||||
INIT,
|
|
||||||
MEDI,
|
|
||||||
FINA,
|
|
||||||
ISOL,
|
ISOL,
|
||||||
|
FINA,
|
||||||
/* Syriac */
|
|
||||||
MED2,
|
|
||||||
FIN2,
|
FIN2,
|
||||||
FIN3,
|
FIN3,
|
||||||
|
MEDI,
|
||||||
|
MED2,
|
||||||
|
INIT,
|
||||||
|
|
||||||
NONE,
|
NONE,
|
||||||
|
|
||||||
@ -171,14 +144,23 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
|
|||||||
{
|
{
|
||||||
hb_ot_map_builder_t *map = &plan->map;
|
hb_ot_map_builder_t *map = &plan->map;
|
||||||
|
|
||||||
/* For Language forms (in ArabicOT speak), we do the iso/fina/medi/init together,
|
/* We apply features according to the Arabic spec, with pauses
|
||||||
* then rlig and calt each in their own stage. This makes IranNastaliq's ALLAH
|
* in between most.
|
||||||
* ligature work correctly. It's unfortunate though...
|
|
||||||
*
|
*
|
||||||
* This also makes Arial Bold in Windows7 work. See:
|
* The pause between init/medi/... and rlig is required. See eg:
|
||||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=644184
|
* https://bugzilla.mozilla.org/show_bug.cgi?id=644184
|
||||||
*
|
*
|
||||||
* TODO: Add test cases for these two.
|
* The pauses between init/medi/... themselves are not necessarily
|
||||||
|
* needed as only one of those features is applied to any character.
|
||||||
|
* The only difference it makes is when fonts have contextual
|
||||||
|
* substitutions. We now follow the order of the spec, which makes
|
||||||
|
* for better experience if that's what Uniscribe is doing.
|
||||||
|
*
|
||||||
|
* At least for Arabic, looks like Uniscribe has a pause between
|
||||||
|
* rlig and calt. Otherwise the IranNastaliq's ALLAH ligature won't
|
||||||
|
* work. However, testing shows that rlig and calt are applied
|
||||||
|
* together for Mongolian in Uniscribe. As such, we only add a
|
||||||
|
* pause for Arabic, not other scripts.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
map->add_gsub_pause (nuke_joiners);
|
map->add_gsub_pause (nuke_joiners);
|
||||||
@ -189,16 +171,28 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
|
|||||||
map->add_gsub_pause (NULL);
|
map->add_gsub_pause (NULL);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++)
|
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++)
|
||||||
map->add_feature (arabic_features[i], 1, i < 4 ? F_HAS_FALLBACK : F_NONE); /* The first four features have fallback. */
|
{
|
||||||
|
bool has_fallback = plan->props.script == HB_SCRIPT_ARABIC && !FEATURE_IS_SYRIAC (arabic_features[i]);
|
||||||
map->add_gsub_pause (NULL);
|
map->add_feature (arabic_features[i], 1, has_fallback ? F_HAS_FALLBACK : F_NONE);
|
||||||
|
map->add_gsub_pause (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK);
|
map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK);
|
||||||
map->add_gsub_pause (arabic_fallback_shape);
|
if (plan->props.script == HB_SCRIPT_ARABIC)
|
||||||
|
map->add_gsub_pause (arabic_fallback_shape);
|
||||||
|
|
||||||
map->add_global_bool_feature (HB_TAG('c','a','l','t'));
|
map->add_global_bool_feature (HB_TAG('c','a','l','t'));
|
||||||
map->add_gsub_pause (NULL);
|
map->add_gsub_pause (NULL);
|
||||||
|
|
||||||
|
/* The spec includes 'cswh'. Earlier versions of Windows
|
||||||
|
* used to enable this by default, but testing suggests
|
||||||
|
* that Windows 8 and later do not enable it by default,
|
||||||
|
* and spec now says 'Off by default'.
|
||||||
|
* We disabled this in ae23c24c32.
|
||||||
|
* Note that IranNastaliq uses this feature extensively
|
||||||
|
* to fixup broken glyph sequences. Oh well...
|
||||||
|
* Test case: U+0643,U+0640,U+0631. */
|
||||||
|
//map->add_global_bool_feature (HB_TAG('c','s','w','h'));
|
||||||
map->add_global_bool_feature (HB_TAG('m','s','e','t'));
|
map->add_global_bool_feature (HB_TAG('m','s','e','t'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,8 +222,9 @@ data_create_arabic (const hb_ot_shape_plan_t *plan)
|
|||||||
arabic_plan->do_fallback = plan->props.script == HB_SCRIPT_ARABIC;
|
arabic_plan->do_fallback = plan->props.script == HB_SCRIPT_ARABIC;
|
||||||
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) {
|
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) {
|
||||||
arabic_plan->mask_array[i] = plan->map.get_1_mask (arabic_features[i]);
|
arabic_plan->mask_array[i] = plan->map.get_1_mask (arabic_features[i]);
|
||||||
if (i < 4)
|
arabic_plan->do_fallback = arabic_plan->do_fallback &&
|
||||||
arabic_plan->do_fallback = arabic_plan->do_fallback && plan->map.needs_fallback (arabic_features[i]);
|
(FEATURE_IS_SYRIAC (arabic_features[i]) ||
|
||||||
|
plan->map.needs_fallback (arabic_features[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return arabic_plan;
|
return arabic_plan;
|
||||||
@ -249,61 +244,65 @@ static void
|
|||||||
arabic_joining (hb_buffer_t *buffer)
|
arabic_joining (hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
unsigned int prev = (unsigned int) -1, state = 0;
|
unsigned int prev = (unsigned int) -1, state = 0;
|
||||||
|
|
||||||
HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action);
|
|
||||||
|
|
||||||
/* Check pre-context */
|
/* Check pre-context */
|
||||||
if (!(buffer->flags & HB_BUFFER_FLAG_BOT))
|
for (unsigned int i = 0; i < buffer->context_len[0]; i++)
|
||||||
for (unsigned int i = 0; i < buffer->context_len[0]; i++)
|
{
|
||||||
{
|
unsigned int this_type = get_joining_type (buffer->context[0][i], buffer->unicode->general_category (buffer->context[0][i]));
|
||||||
unsigned int this_type = get_joining_type (buffer->context[0][i], buffer->unicode->general_category (buffer->context[0][i]));
|
|
||||||
|
|
||||||
if (unlikely (this_type == JOINING_TYPE_T))
|
if (unlikely (this_type == JOINING_TYPE_T))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
|
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
|
||||||
state = entry->next_state;
|
state = entry->next_state;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
unsigned int this_type = get_joining_type (buffer->info[i].codepoint, _hb_glyph_info_get_general_category (&buffer->info[i]));
|
unsigned int this_type = get_joining_type (info[i].codepoint, _hb_glyph_info_get_general_category (&info[i]));
|
||||||
|
|
||||||
if (unlikely (this_type == JOINING_TYPE_T)) {
|
if (unlikely (this_type == JOINING_TYPE_T)) {
|
||||||
buffer->info[i].arabic_shaping_action() = NONE;
|
info[i].arabic_shaping_action() = NONE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
|
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
|
||||||
|
|
||||||
if (entry->prev_action != NONE && prev != (unsigned int) -1)
|
if (entry->prev_action != NONE && prev != (unsigned int) -1)
|
||||||
for (; prev < i; prev++)
|
info[prev].arabic_shaping_action() = entry->prev_action;
|
||||||
buffer->info[prev].arabic_shaping_action() = entry->prev_action;
|
|
||||||
|
|
||||||
buffer->info[i].arabic_shaping_action() = entry->curr_action;
|
info[i].arabic_shaping_action() = entry->curr_action;
|
||||||
|
|
||||||
prev = i;
|
prev = i;
|
||||||
state = entry->next_state;
|
state = entry->next_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(buffer->flags & HB_BUFFER_FLAG_EOT))
|
for (unsigned int i = 0; i < buffer->context_len[1]; i++)
|
||||||
for (unsigned int i = 0; i < buffer->context_len[1]; i++)
|
{
|
||||||
{
|
unsigned int this_type = get_joining_type (buffer->context[1][i], buffer->unicode->general_category (buffer->context[1][i]));
|
||||||
unsigned int this_type = get_joining_type (buffer->context[1][i], buffer->unicode->general_category (buffer->context[1][i]));
|
|
||||||
|
|
||||||
if (unlikely (this_type == JOINING_TYPE_T))
|
if (unlikely (this_type == JOINING_TYPE_T))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
|
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
|
||||||
if (entry->prev_action != NONE && prev != (unsigned int) -1)
|
if (entry->prev_action != NONE && prev != (unsigned int) -1)
|
||||||
buffer->info[prev].arabic_shaping_action() = entry->prev_action;
|
info[prev].arabic_shaping_action() = entry->prev_action;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
|
mongolian_variation_selectors (hb_buffer_t *buffer)
|
||||||
|
{
|
||||||
|
/* Copy arabic_shaping_action() from base to Mongolian variation selectors. */
|
||||||
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
|
for (unsigned int i = 1; i < count; i++)
|
||||||
|
if (unlikely (hb_in_range (info[i].codepoint, 0x180Bu, 0x180Du)))
|
||||||
|
info[i].arabic_shaping_action() = info[i - 1].arabic_shaping_action();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -311,12 +310,20 @@ setup_masks_arabic (const hb_ot_shape_plan_t *plan,
|
|||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
hb_font_t *font HB_UNUSED)
|
hb_font_t *font HB_UNUSED)
|
||||||
{
|
{
|
||||||
|
HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action);
|
||||||
|
|
||||||
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
|
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
|
||||||
|
|
||||||
arabic_joining (buffer);
|
arabic_joining (buffer);
|
||||||
|
if (plan->props.script == HB_SCRIPT_MONGOLIAN)
|
||||||
|
mongolian_variation_selectors (buffer);
|
||||||
|
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
buffer->info[i].mask |= arabic_plan->mask_array[buffer->info[i].arabic_shaping_action()];
|
info[i].mask |= arabic_plan->mask_array[info[i].arabic_shaping_action()];
|
||||||
|
|
||||||
|
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -326,9 +333,10 @@ nuke_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||||||
hb_buffer_t *buffer)
|
hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (_hb_glyph_info_is_zwj (&buffer->info[i]))
|
if (_hb_glyph_info_is_zwj (&info[i]))
|
||||||
_hb_glyph_info_flip_joiners (&buffer->info[i]);
|
_hb_glyph_info_flip_joiners (&info[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -59,6 +59,15 @@ collect_features_hangul (hb_ot_shape_planner_t *plan)
|
|||||||
map->add_feature (hangul_features[i], 1, F_NONE);
|
map->add_feature (hangul_features[i], 1, F_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
override_features_hangul (hb_ot_shape_planner_t *plan)
|
||||||
|
{
|
||||||
|
/* Uniscribe does not apply 'calt' for Hangul, and certain fonts
|
||||||
|
* (Noto Sans CJK, Source Sans Han, etc) apply all of jamo lookups
|
||||||
|
* in calt, which is not desirable. */
|
||||||
|
plan->map.add_feature (HB_TAG('c','a','l','t'), 0, F_GLOBAL);
|
||||||
|
}
|
||||||
|
|
||||||
struct hangul_shape_plan_t
|
struct hangul_shape_plan_t
|
||||||
{
|
{
|
||||||
ASSERT_POD ();
|
ASSERT_POD ();
|
||||||
@ -86,26 +95,26 @@ data_destroy_hangul (void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Constants for algorithmic hangul syllable [de]composition. */
|
/* Constants for algorithmic hangul syllable [de]composition. */
|
||||||
#define LBase 0x1100
|
#define LBase 0x1100u
|
||||||
#define VBase 0x1161
|
#define VBase 0x1161u
|
||||||
#define TBase 0x11A7
|
#define TBase 0x11A7u
|
||||||
#define LCount 19
|
#define LCount 19u
|
||||||
#define VCount 21
|
#define VCount 21u
|
||||||
#define TCount 28
|
#define TCount 28u
|
||||||
#define SBase 0xAC00
|
#define SBase 0xAC00u
|
||||||
#define NCount (VCount * TCount)
|
#define NCount (VCount * TCount)
|
||||||
#define SCount (LCount * NCount)
|
#define SCount (LCount * NCount)
|
||||||
|
|
||||||
#define isCombiningL(u) (hb_in_range<hb_codepoint_t> ((u), LBase, LBase+LCount-1))
|
#define isCombiningL(u) (hb_in_range ((u), LBase, LBase+LCount-1))
|
||||||
#define isCombiningV(u) (hb_in_range<hb_codepoint_t> ((u), VBase, VBase+VCount-1))
|
#define isCombiningV(u) (hb_in_range ((u), VBase, VBase+VCount-1))
|
||||||
#define isCombiningT(u) (hb_in_range<hb_codepoint_t> ((u), TBase+1, TBase+TCount-1))
|
#define isCombiningT(u) (hb_in_range ((u), TBase+1, TBase+TCount-1))
|
||||||
#define isCombinedS(u) (hb_in_range<hb_codepoint_t> ((u), SBase, SBase+SCount-1))
|
#define isCombinedS(u) (hb_in_range ((u), SBase, SBase+SCount-1))
|
||||||
|
|
||||||
#define isL(u) (hb_in_ranges<hb_codepoint_t> ((u), 0x1100, 0x115F, 0xA960, 0xA97C))
|
#define isL(u) (hb_in_ranges ((u), 0x1100u, 0x115Fu, 0xA960u, 0xA97Cu))
|
||||||
#define isV(u) (hb_in_ranges<hb_codepoint_t> ((u), 0x1160, 0x11A7, 0xD7B0, 0xD7C6))
|
#define isV(u) (hb_in_ranges ((u), 0x1160u, 0x11A7u, 0xD7B0u, 0xD7C6u))
|
||||||
#define isT(u) (hb_in_ranges<hb_codepoint_t> ((u), 0x11A8, 0x11FF, 0xD7CB, 0xD7FB))
|
#define isT(u) (hb_in_ranges ((u), 0x11A8u, 0x11FFu, 0xD7CBu, 0xD7FBu))
|
||||||
|
|
||||||
#define isHangulTone(u) (hb_in_range<hb_codepoint_t> ((u), 0x302e, 0x302f))
|
#define isHangulTone(u) (hb_in_range ((u), 0x302Eu, 0x302Fu))
|
||||||
|
|
||||||
/* buffer var allocations */
|
/* buffer var allocations */
|
||||||
#define hangul_shaping_feature() complex_var_u8_0() /* hangul jamo shaping feature */
|
#define hangul_shaping_feature() complex_var_u8_0() /* hangul jamo shaping feature */
|
||||||
@ -211,14 +220,14 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* No valid syllable as base for tone mark; try to insert dotted circle. */
|
/* No valid syllable as base for tone mark; try to insert dotted circle. */
|
||||||
if (font->has_glyph (0x25cc))
|
if (font->has_glyph (0x25CCu))
|
||||||
{
|
{
|
||||||
hb_codepoint_t chars[2];
|
hb_codepoint_t chars[2];
|
||||||
if (!is_zero_width_char (font, u)) {
|
if (!is_zero_width_char (font, u)) {
|
||||||
chars[0] = u;
|
chars[0] = u;
|
||||||
chars[1] = 0x25cc;
|
chars[1] = 0x25CCu;
|
||||||
} else {
|
} else {
|
||||||
chars[0] = 0x25cc;
|
chars[0] = 0x25CCu;
|
||||||
chars[1] = u;
|
chars[1] = u;
|
||||||
}
|
}
|
||||||
buffer->replace_glyphs (1, 2, chars);
|
buffer->replace_glyphs (1, 2, chars);
|
||||||
@ -404,7 +413,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hangul =
|
|||||||
{
|
{
|
||||||
"hangul",
|
"hangul",
|
||||||
collect_features_hangul,
|
collect_features_hangul,
|
||||||
NULL, /* override_features */
|
override_features_hangul,
|
||||||
data_create_hangul, /* data_create */
|
data_create_hangul, /* data_create */
|
||||||
data_destroy_hangul, /* data_destroy */
|
data_destroy_hangul, /* data_destroy */
|
||||||
preprocess_text_hangul,
|
preprocess_text_hangul,
|
||||||
|
@ -35,116 +35,116 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c,
|
|||||||
{
|
{
|
||||||
/* Hebrew presentation-form shaping.
|
/* Hebrew presentation-form shaping.
|
||||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=728866
|
* https://bugzilla.mozilla.org/show_bug.cgi?id=728866
|
||||||
* Hebrew presentation forms with dagesh, for characters 0x05D0..0x05EA;
|
* Hebrew presentation forms with dagesh, for characters U+05D0..05EA;
|
||||||
* Note that some letters do not have a dagesh presForm encoded.
|
* Note that some letters do not have a dagesh presForm encoded.
|
||||||
*/
|
*/
|
||||||
static const hb_codepoint_t sDageshForms[0x05EA - 0x05D0 + 1] = {
|
static const hb_codepoint_t sDageshForms[0x05EAu - 0x05D0u + 1] = {
|
||||||
0xFB30, /* ALEF */
|
0xFB30u, /* ALEF */
|
||||||
0xFB31, /* BET */
|
0xFB31u, /* BET */
|
||||||
0xFB32, /* GIMEL */
|
0xFB32u, /* GIMEL */
|
||||||
0xFB33, /* DALET */
|
0xFB33u, /* DALET */
|
||||||
0xFB34, /* HE */
|
0xFB34u, /* HE */
|
||||||
0xFB35, /* VAV */
|
0xFB35u, /* VAV */
|
||||||
0xFB36, /* ZAYIN */
|
0xFB36u, /* ZAYIN */
|
||||||
0x0000, /* HET */
|
0x0000u, /* HET */
|
||||||
0xFB38, /* TET */
|
0xFB38u, /* TET */
|
||||||
0xFB39, /* YOD */
|
0xFB39u, /* YOD */
|
||||||
0xFB3A, /* FINAL KAF */
|
0xFB3Au, /* FINAL KAF */
|
||||||
0xFB3B, /* KAF */
|
0xFB3Bu, /* KAF */
|
||||||
0xFB3C, /* LAMED */
|
0xFB3Cu, /* LAMED */
|
||||||
0x0000, /* FINAL MEM */
|
0x0000u, /* FINAL MEM */
|
||||||
0xFB3E, /* MEM */
|
0xFB3Eu, /* MEM */
|
||||||
0x0000, /* FINAL NUN */
|
0x0000u, /* FINAL NUN */
|
||||||
0xFB40, /* NUN */
|
0xFB40u, /* NUN */
|
||||||
0xFB41, /* SAMEKH */
|
0xFB41u, /* SAMEKH */
|
||||||
0x0000, /* AYIN */
|
0x0000u, /* AYIN */
|
||||||
0xFB43, /* FINAL PE */
|
0xFB43u, /* FINAL PE */
|
||||||
0xFB44, /* PE */
|
0xFB44u, /* PE */
|
||||||
0x0000, /* FINAL TSADI */
|
0x0000u, /* FINAL TSADI */
|
||||||
0xFB46, /* TSADI */
|
0xFB46u, /* TSADI */
|
||||||
0xFB47, /* QOF */
|
0xFB47u, /* QOF */
|
||||||
0xFB48, /* RESH */
|
0xFB48u, /* RESH */
|
||||||
0xFB49, /* SHIN */
|
0xFB49u, /* SHIN */
|
||||||
0xFB4A /* TAV */
|
0xFB4Au /* TAV */
|
||||||
};
|
};
|
||||||
|
|
||||||
bool found = c->unicode->compose (a, b, ab);
|
bool found = c->unicode->compose (a, b, ab);
|
||||||
|
|
||||||
if (!found)
|
if (!found && !c->plan->has_mark)
|
||||||
{
|
{
|
||||||
/* Special-case Hebrew presentation forms that are excluded from
|
/* Special-case Hebrew presentation forms that are excluded from
|
||||||
* standard normalization, but wanted for old fonts. */
|
* standard normalization, but wanted for old fonts. */
|
||||||
switch (b) {
|
switch (b) {
|
||||||
case 0x05B4: /* HIRIQ */
|
case 0x05B4u: /* HIRIQ */
|
||||||
if (a == 0x05D9) { /* YOD */
|
if (a == 0x05D9u) { /* YOD */
|
||||||
*ab = 0xFB1D;
|
*ab = 0xFB1Du;
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x05B7: /* patah */
|
case 0x05B7u: /* patah */
|
||||||
if (a == 0x05F2) { /* YIDDISH YOD YOD */
|
if (a == 0x05F2u) { /* YIDDISH YOD YOD */
|
||||||
*ab = 0xFB1F;
|
*ab = 0xFB1Fu;
|
||||||
found = true;
|
found = true;
|
||||||
} else if (a == 0x05D0) { /* ALEF */
|
} else if (a == 0x05D0u) { /* ALEF */
|
||||||
*ab = 0xFB2E;
|
*ab = 0xFB2Eu;
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x05B8: /* QAMATS */
|
case 0x05B8u: /* QAMATS */
|
||||||
if (a == 0x05D0) { /* ALEF */
|
if (a == 0x05D0u) { /* ALEF */
|
||||||
*ab = 0xFB2F;
|
*ab = 0xFB2Fu;
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x05B9: /* HOLAM */
|
case 0x05B9u: /* HOLAM */
|
||||||
if (a == 0x05D5) { /* VAV */
|
if (a == 0x05D5u) { /* VAV */
|
||||||
*ab = 0xFB4B;
|
*ab = 0xFB4Bu;
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x05BC: /* DAGESH */
|
case 0x05BCu: /* DAGESH */
|
||||||
if (a >= 0x05D0 && a <= 0x05EA) {
|
if (a >= 0x05D0u && a <= 0x05EAu) {
|
||||||
*ab = sDageshForms[a - 0x05D0];
|
*ab = sDageshForms[a - 0x05D0u];
|
||||||
found = (*ab != 0);
|
found = (*ab != 0);
|
||||||
} else if (a == 0xFB2A) { /* SHIN WITH SHIN DOT */
|
} else if (a == 0xFB2Au) { /* SHIN WITH SHIN DOT */
|
||||||
*ab = 0xFB2C;
|
*ab = 0xFB2Cu;
|
||||||
found = true;
|
found = true;
|
||||||
} else if (a == 0xFB2B) { /* SHIN WITH SIN DOT */
|
} else if (a == 0xFB2Bu) { /* SHIN WITH SIN DOT */
|
||||||
*ab = 0xFB2D;
|
*ab = 0xFB2Du;
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x05BF: /* RAFE */
|
case 0x05BFu: /* RAFE */
|
||||||
switch (a) {
|
switch (a) {
|
||||||
case 0x05D1: /* BET */
|
case 0x05D1u: /* BET */
|
||||||
*ab = 0xFB4C;
|
*ab = 0xFB4Cu;
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
case 0x05DB: /* KAF */
|
case 0x05DBu: /* KAF */
|
||||||
*ab = 0xFB4D;
|
*ab = 0xFB4Du;
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
case 0x05E4: /* PE */
|
case 0x05E4u: /* PE */
|
||||||
*ab = 0xFB4E;
|
*ab = 0xFB4Eu;
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x05C1: /* SHIN DOT */
|
case 0x05C1u: /* SHIN DOT */
|
||||||
if (a == 0x05E9) { /* SHIN */
|
if (a == 0x05E9u) { /* SHIN */
|
||||||
*ab = 0xFB2A;
|
*ab = 0xFB2Au;
|
||||||
found = true;
|
found = true;
|
||||||
} else if (a == 0xFB49) { /* SHIN WITH DAGESH */
|
} else if (a == 0xFB49u) { /* SHIN WITH DAGESH */
|
||||||
*ab = 0xFB2C;
|
*ab = 0xFB2Cu;
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x05C2: /* SIN DOT */
|
case 0x05C2u: /* SIN DOT */
|
||||||
if (a == 0x05E9) { /* SHIN */
|
if (a == 0x05E9u) { /* SHIN */
|
||||||
*ab = 0xFB2B;
|
*ab = 0xFB2Bu;
|
||||||
found = true;
|
found = true;
|
||||||
} else if (a == 0xFB49) { /* SHIN WITH DAGESH */
|
} else if (a == 0xFB49u) { /* SHIN WITH DAGESH */
|
||||||
*ab = 0xFB2D;
|
*ab = 0xFB2Du;
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -167,6 +167,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew =
|
|||||||
NULL, /* decompose */
|
NULL, /* decompose */
|
||||||
compose_hebrew,
|
compose_hebrew,
|
||||||
NULL, /* setup_masks */
|
NULL, /* setup_masks */
|
||||||
HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT,
|
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
|
||||||
true, /* fallback_position */
|
true, /* fallback_position */
|
||||||
};
|
};
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -49,14 +49,14 @@ M = 7;
|
|||||||
SM = 8;
|
SM = 8;
|
||||||
VD = 9;
|
VD = 9;
|
||||||
A = 10;
|
A = 10;
|
||||||
NBSP = 11;
|
PLACEHOLDER = 11;
|
||||||
DOTTEDCIRCLE = 12;
|
DOTTEDCIRCLE = 12;
|
||||||
RS = 13;
|
RS = 13;
|
||||||
Coeng = 14;
|
Coeng = 14;
|
||||||
Repha = 15;
|
Repha = 15;
|
||||||
Ra = 16;
|
Ra = 16;
|
||||||
CM = 17;
|
CM = 17;
|
||||||
Avag = 18;
|
Symbol= 18;
|
||||||
CM2 = 31;
|
CM2 = 31;
|
||||||
|
|
||||||
c = (C | Ra); # is_consonant
|
c = (C | Ra); # is_consonant
|
||||||
@ -67,21 +67,20 @@ reph = (Ra H | Repha); # possible reph
|
|||||||
|
|
||||||
cn = c.ZWJ?.n?;
|
cn = c.ZWJ?.n?;
|
||||||
forced_rakar = ZWJ H ZWJ Ra;
|
forced_rakar = ZWJ H ZWJ Ra;
|
||||||
avagraha = Avag.N?;
|
symbol = Symbol.N?;
|
||||||
matra_group = z{0,3}.M.N?.(H | forced_rakar)?;
|
matra_group = z{0,3}.M.N?.(H | forced_rakar)?;
|
||||||
syllable_tail2 = (SM.SM?.ZWNJ?)? (A.A?)? VD?;
|
syllable_tail = (SM.SM?.ZWNJ?)? A{0,3}? VD{0,2};
|
||||||
syllable_tail = (Coeng (cn|V))? avagraha? syllable_tail2;
|
place_holder = PLACEHOLDER | DOTTEDCIRCLE;
|
||||||
place_holder = NBSP | DOTTEDCIRCLE;
|
|
||||||
halant_group = (z?.h.(ZWJ.N?)?);
|
halant_group = (z?.h.(ZWJ.N?)?);
|
||||||
final_halant_group = halant_group | h.ZWNJ;
|
final_halant_group = halant_group | h.ZWNJ;
|
||||||
medial_group = CM?.CM2?;
|
medial_group = CM?.CM2?;
|
||||||
halant_or_matra_group = (final_halant_group | (h.ZWJ)? matra_group{0,4});
|
halant_or_matra_group = (final_halant_group | (h.ZWJ)? matra_group{0,4}) (Coeng (cn|V))?;
|
||||||
|
|
||||||
|
|
||||||
consonant_syllable = Repha? (cn.halant_group){0,4} cn medial_group halant_or_matra_group syllable_tail;
|
consonant_syllable = Repha? (cn.halant_group){0,4} cn medial_group halant_or_matra_group syllable_tail;
|
||||||
vowel_syllable = reph? V.n? (ZWJ | (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail);
|
vowel_syllable = reph? V.n? (ZWJ | (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail);
|
||||||
standalone_cluster = reph? place_holder.n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
|
standalone_cluster = (Repha? PLACEHOLDER | reph? DOTTEDCIRCLE).n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
|
||||||
avagraha_cluster = avagraha syllable_tail2;
|
symbol_cluster = symbol syllable_tail;
|
||||||
broken_cluster = reph? n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
|
broken_cluster = reph? n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
|
||||||
other = any;
|
other = any;
|
||||||
|
|
||||||
@ -89,7 +88,7 @@ main := |*
|
|||||||
consonant_syllable => { found_syllable (consonant_syllable); };
|
consonant_syllable => { found_syllable (consonant_syllable); };
|
||||||
vowel_syllable => { found_syllable (vowel_syllable); };
|
vowel_syllable => { found_syllable (vowel_syllable); };
|
||||||
standalone_cluster => { found_syllable (standalone_cluster); };
|
standalone_cluster => { found_syllable (standalone_cluster); };
|
||||||
avagraha_cluster => { found_syllable (avagraha_cluster); };
|
symbol_cluster => { found_syllable (symbol_cluster); };
|
||||||
broken_cluster => { found_syllable (broken_cluster); };
|
broken_cluster => { found_syllable (broken_cluster); };
|
||||||
other => { found_syllable (non_indic_cluster); };
|
other => { found_syllable (non_indic_cluster); };
|
||||||
*|;
|
*|;
|
||||||
|
@ -53,17 +53,29 @@ enum indic_category_t {
|
|||||||
OT_SM = 8,
|
OT_SM = 8,
|
||||||
OT_VD = 9,
|
OT_VD = 9,
|
||||||
OT_A = 10,
|
OT_A = 10,
|
||||||
OT_NBSP = 11,
|
OT_PLACEHOLDER = 11,
|
||||||
OT_DOTTEDCIRCLE = 12,
|
OT_DOTTEDCIRCLE = 12,
|
||||||
OT_RS = 13, /* Register Shifter, used in Khmer OT spec. */
|
OT_RS = 13, /* Register Shifter, used in Khmer OT spec. */
|
||||||
OT_Coeng = 14, /* Khmer-style Virama. */
|
OT_Coeng = 14, /* Khmer-style Virama. */
|
||||||
OT_Repha = 15, /* Atomically-encoded logical or visual repha. */
|
OT_Repha = 15, /* Atomically-encoded logical or visual repha. */
|
||||||
OT_Ra = 16,
|
OT_Ra = 16,
|
||||||
OT_CM = 17, /* Consonant-Medial. */
|
OT_CM = 17, /* Consonant-Medial. */
|
||||||
OT_Avag = 18, /* Avagraha. */
|
OT_Symbol = 18, /* Avagraha, etc that take marks (SM,A,VD). */
|
||||||
OT_CM2 = 31 /* Consonant-Medial, second slot. */
|
OT_CM2 = 31 /* Consonant-Medial, second slot. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MEDIAL_FLAGS (FLAG (OT_CM) | FLAG (OT_CM2))
|
||||||
|
|
||||||
|
/* Note:
|
||||||
|
*
|
||||||
|
* We treat Vowels and placeholders as if they were consonants. This is safe because Vowels
|
||||||
|
* cannot happen in a consonant syllable. The plus side however is, we can call the
|
||||||
|
* consonant syllable logic from the vowel syllable function and get it all right! */
|
||||||
|
#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_PLACEHOLDER) | FLAG (OT_DOTTEDCIRCLE))
|
||||||
|
#define JOINER_FLAGS (FLAG (OT_ZWJ) | FLAG (OT_ZWNJ))
|
||||||
|
#define HALANT_OR_COENG_FLAGS (FLAG (OT_H) | FLAG (OT_Coeng))
|
||||||
|
|
||||||
|
|
||||||
/* Visual positions in a syllable from left to right. */
|
/* Visual positions in a syllable from left to right. */
|
||||||
enum indic_position_t {
|
enum indic_position_t {
|
||||||
POS_START,
|
POS_START,
|
||||||
@ -93,57 +105,74 @@ enum indic_position_t {
|
|||||||
|
|
||||||
/* Categories used in IndicSyllabicCategory.txt from UCD. */
|
/* Categories used in IndicSyllabicCategory.txt from UCD. */
|
||||||
enum indic_syllabic_category_t {
|
enum indic_syllabic_category_t {
|
||||||
INDIC_SYLLABIC_CATEGORY_OTHER = OT_X,
|
INDIC_SYLLABIC_CATEGORY_OTHER = OT_X,
|
||||||
|
|
||||||
INDIC_SYLLABIC_CATEGORY_AVAGRAHA = OT_Avag,
|
INDIC_SYLLABIC_CATEGORY_AVAGRAHA = OT_Symbol,
|
||||||
INDIC_SYLLABIC_CATEGORY_BINDU = OT_SM,
|
INDIC_SYLLABIC_CATEGORY_BINDU = OT_SM,
|
||||||
INDIC_SYLLABIC_CATEGORY_CONSONANT = OT_C,
|
INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER = OT_PLACEHOLDER, /* TODO */
|
||||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD = OT_C,
|
INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK = OT_A,
|
||||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL = OT_CM,
|
INDIC_SYLLABIC_CATEGORY_CONSONANT = OT_C,
|
||||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER = OT_C,
|
INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD = OT_C,
|
||||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL = OT_CM,
|
INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL = OT_CM,
|
||||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER = OT_NBSP,
|
INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER = OT_C,
|
||||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_CM,
|
INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL = OT_CM,
|
||||||
INDIC_SYLLABIC_CATEGORY_CONSONANT_REPHA = OT_Repha,
|
INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER = OT_PLACEHOLDER,
|
||||||
INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER = OT_X,
|
INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA = OT_Repha,
|
||||||
INDIC_SYLLABIC_CATEGORY_NUKTA = OT_N,
|
INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_CM,
|
||||||
INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER = OT_RS,
|
INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA = OT_N,
|
||||||
INDIC_SYLLABIC_CATEGORY_TONE_LETTER = OT_X,
|
INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK = OT_SM,
|
||||||
INDIC_SYLLABIC_CATEGORY_TONE_MARK = OT_N,
|
INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER = OT_H, /* TODO */
|
||||||
INDIC_SYLLABIC_CATEGORY_VIRAMA = OT_H,
|
INDIC_SYLLABIC_CATEGORY_JOINER = OT_ZWJ,
|
||||||
INDIC_SYLLABIC_CATEGORY_VISARGA = OT_SM,
|
INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER = OT_X,
|
||||||
INDIC_SYLLABIC_CATEGORY_VOWEL = OT_V,
|
INDIC_SYLLABIC_CATEGORY_NON_JOINER = OT_ZWNJ,
|
||||||
INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT = OT_M,
|
INDIC_SYLLABIC_CATEGORY_NUKTA = OT_N,
|
||||||
INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT = OT_V
|
INDIC_SYLLABIC_CATEGORY_NUMBER = OT_PLACEHOLDER,
|
||||||
|
INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER = OT_PLACEHOLDER, /* TODO */
|
||||||
|
INDIC_SYLLABIC_CATEGORY_PURE_KILLER = OT_H, /* TODO */
|
||||||
|
INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER = OT_RS,
|
||||||
|
INDIC_SYLLABIC_CATEGORY_TONE_LETTER = OT_X,
|
||||||
|
INDIC_SYLLABIC_CATEGORY_TONE_MARK = OT_N,
|
||||||
|
INDIC_SYLLABIC_CATEGORY_VIRAMA = OT_H,
|
||||||
|
INDIC_SYLLABIC_CATEGORY_VISARGA = OT_SM,
|
||||||
|
INDIC_SYLLABIC_CATEGORY_VOWEL = OT_V,
|
||||||
|
INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT = OT_M,
|
||||||
|
INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT = OT_V
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Categories used in IndicSMatraCategory.txt from UCD */
|
/* Categories used in IndicSMatraCategory.txt from UCD */
|
||||||
enum indic_matra_category_t {
|
enum indic_matra_category_t {
|
||||||
INDIC_MATRA_CATEGORY_NOT_APPLICABLE = POS_END,
|
INDIC_MATRA_CATEGORY_NOT_APPLICABLE = POS_END,
|
||||||
|
|
||||||
INDIC_MATRA_CATEGORY_LEFT = POS_PRE_C,
|
INDIC_MATRA_CATEGORY_LEFT = POS_PRE_C,
|
||||||
INDIC_MATRA_CATEGORY_TOP = POS_ABOVE_C,
|
INDIC_MATRA_CATEGORY_TOP = POS_ABOVE_C,
|
||||||
INDIC_MATRA_CATEGORY_BOTTOM = POS_BELOW_C,
|
INDIC_MATRA_CATEGORY_BOTTOM = POS_BELOW_C,
|
||||||
INDIC_MATRA_CATEGORY_RIGHT = POS_POST_C,
|
INDIC_MATRA_CATEGORY_RIGHT = POS_POST_C,
|
||||||
|
|
||||||
/* These should resolve to the position of the last part of the split sequence. */
|
/* These should resolve to the position of the last part of the split sequence. */
|
||||||
INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
||||||
INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
||||||
INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM = INDIC_MATRA_CATEGORY_BOTTOM,
|
INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM = INDIC_MATRA_CATEGORY_BOTTOM,
|
||||||
INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
||||||
INDIC_MATRA_CATEGORY_TOP_AND_LEFT = INDIC_MATRA_CATEGORY_TOP,
|
INDIC_MATRA_CATEGORY_TOP_AND_LEFT = INDIC_MATRA_CATEGORY_TOP,
|
||||||
INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
||||||
INDIC_MATRA_CATEGORY_TOP_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
INDIC_MATRA_CATEGORY_TOP_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
|
||||||
|
|
||||||
INDIC_MATRA_CATEGORY_INVISIBLE = INDIC_MATRA_CATEGORY_NOT_APPLICABLE,
|
INDIC_MATRA_CATEGORY_OVERSTRUCK = POS_AFTER_MAIN,
|
||||||
INDIC_MATRA_CATEGORY_OVERSTRUCK = POS_AFTER_MAIN,
|
INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT = POS_PRE_M
|
||||||
INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT = POS_PRE_M
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Note: We use ASSERT_STATIC_EXPR_ZERO() instead of ASSERT_STATIC_EXPR() and the comma operation
|
/* Note: We use ASSERT_STATIC_EXPR_ZERO() instead of ASSERT_STATIC_EXPR() and the comma operation
|
||||||
* because gcc fails to optimize the latter and fills the table in at runtime. */
|
* because gcc fails to optimize the latter and fills the table in at runtime. */
|
||||||
#define INDIC_COMBINE_CATEGORIES(S,M) \
|
#define INDIC_COMBINE_CATEGORIES(S,M) \
|
||||||
(ASSERT_STATIC_EXPR_ZERO (M == INDIC_MATRA_CATEGORY_NOT_APPLICABLE || (S == INDIC_SYLLABIC_CATEGORY_VIRAMA || S == INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT)) + \
|
(ASSERT_STATIC_EXPR_ZERO (M == INDIC_MATRA_CATEGORY_NOT_APPLICABLE || \
|
||||||
|
( \
|
||||||
|
S == INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL || \
|
||||||
|
S == INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK || \
|
||||||
|
S == INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER || \
|
||||||
|
S == INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA || \
|
||||||
|
S == INDIC_SYLLABIC_CATEGORY_VIRAMA || \
|
||||||
|
S == INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT || \
|
||||||
|
false)) + \
|
||||||
ASSERT_STATIC_EXPR_ZERO (S < 255 && M < 255) + \
|
ASSERT_STATIC_EXPR_ZERO (S < 255 && M < 255) + \
|
||||||
((M << 8) | S))
|
((M << 8) | S))
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,872 +0,0 @@
|
|||||||
/* == Start of generated table == */
|
|
||||||
/*
|
|
||||||
* The following table is generated by running:
|
|
||||||
*
|
|
||||||
* ./gen-indic-table.py IndicSyllabicCategory.txt IndicMatraCategory.txt Blocks.txt
|
|
||||||
*
|
|
||||||
* on files with these headers:
|
|
||||||
*
|
|
||||||
* # IndicSyllabicCategory-6.2.0.txt
|
|
||||||
* # Date: 2012-05-15, 21:12:00 GMT [KW]
|
|
||||||
* # IndicMatraCategory-6.2.0.txt
|
|
||||||
* # Date: 2012-05-15, 21:10:00 GMT [KW]
|
|
||||||
* # Blocks-6.2.0.txt
|
|
||||||
* # Date: 2012-05-14, 22:42:00 GMT [KW, LI]
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HB_OT_SHAPE_COMPLEX_INDIC_TABLE_HH
|
|
||||||
#define HB_OT_SHAPE_COMPLEX_INDIC_TABLE_HH
|
|
||||||
|
|
||||||
|
|
||||||
#define ISC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 11 chars; Avagraha */
|
|
||||||
#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 34 chars; Bindu */
|
|
||||||
#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 123 chars; Consonant */
|
|
||||||
#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 2 chars; Consonant_Dead */
|
|
||||||
#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 17 chars; Consonant_Final */
|
|
||||||
#define ISC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 1 chars; Consonant_Head_Letter */
|
|
||||||
#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 12 chars; Consonant_Medial */
|
|
||||||
#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 4 chars; Consonant_Placeholder */
|
|
||||||
#define ISC_CR INDIC_SYLLABIC_CATEGORY_CONSONANT_REPHA /* 5 chars; Consonant_Repha */
|
|
||||||
#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 10 chars; Consonant_Subjoined */
|
|
||||||
#define ISC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER /* 1 chars; Modifying_Letter */
|
|
||||||
#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 12 chars; Nukta */
|
|
||||||
#define ISC_x INDIC_SYLLABIC_CATEGORY_OTHER /* 1 chars; Other */
|
|
||||||
#define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 1 chars; Register_Shifter */
|
|
||||||
#define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 3 chars; Tone_Letter */
|
|
||||||
#define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK /* 16 chars; Tone_Mark */
|
|
||||||
#define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 34 chars; Virama */
|
|
||||||
#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 25 chars; Visarga */
|
|
||||||
#define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 5 chars; Vowel */
|
|
||||||
#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 165 chars; Vowel_Dependent */
|
|
||||||
#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 59 chars; Vowel_Independent */
|
|
||||||
|
|
||||||
#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 65 chars; Bottom */
|
|
||||||
#define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT /* 2 chars; Bottom_And_Right */
|
|
||||||
#define IMC_I INDIC_MATRA_CATEGORY_INVISIBLE /* 6 chars; Invisible */
|
|
||||||
#define IMC_L INDIC_MATRA_CATEGORY_LEFT /* 30 chars; Left */
|
|
||||||
#define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT /* 8 chars; Left_And_Right */
|
|
||||||
#define IMC_x INDIC_MATRA_CATEGORY_NOT_APPLICABLE /* 1 chars; Not_Applicable */
|
|
||||||
#define IMC_O INDIC_MATRA_CATEGORY_OVERSTRUCK /* 2 chars; Overstruck */
|
|
||||||
#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 75 chars; Right */
|
|
||||||
#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 83 chars; Top */
|
|
||||||
#define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM /* 6 chars; Top_And_Bottom */
|
|
||||||
#define IMC_TBR INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT /* 1 chars; Top_And_Bottom_And_Right */
|
|
||||||
#define IMC_TL INDIC_MATRA_CATEGORY_TOP_AND_LEFT /* 4 chars; Top_And_Left */
|
|
||||||
#define IMC_TLR INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT /* 2 chars; Top_And_Left_And_Right */
|
|
||||||
#define IMC_TR INDIC_MATRA_CATEGORY_TOP_AND_RIGHT /* 8 chars; Top_And_Right */
|
|
||||||
#define IMC_VOL INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT /* 5 chars; Visual_Order_Left */
|
|
||||||
|
|
||||||
#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)
|
|
||||||
|
|
||||||
|
|
||||||
static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {
|
|
||||||
|
|
||||||
|
|
||||||
#define indic_offset_0x0900 0
|
|
||||||
|
|
||||||
|
|
||||||
/* Devanagari (0900..097F) */
|
|
||||||
|
|
||||||
/* 0900 */ _(Bi,x), _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 0908 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 0910 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0920 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0928 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0930 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0938 */ _(C,x), _(C,x), _(M,T), _(M,R), _(N,x), _(A,x), _(M,R), _(M,L),
|
|
||||||
/* 0940 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(M,T), _(M,T),
|
|
||||||
/* 0948 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(V,B), _(M,L), _(M,R),
|
|
||||||
/* 0950 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,B), _(M,B),
|
|
||||||
/* 0958 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0960 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0968 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0970 */ _(x,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 0978 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
|
|
||||||
/* Bengali (0980..09FF) */
|
|
||||||
|
|
||||||
/* 0980 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 0988 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x),
|
|
||||||
/* 0990 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 09A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 09A8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 09B0 */ _(C,x), _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x),
|
|
||||||
/* 09B8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,L),
|
|
||||||
/* 09C0 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), _(M,L),
|
|
||||||
/* 09C8 */ _(M,L), _(x,x), _(x,x), _(M,LR), _(M,LR), _(V,B), _(CD,x), _(x,x),
|
|
||||||
/* 09D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
|
|
||||||
/* 09D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x),
|
|
||||||
/* 09E0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 09E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 09F0 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 09F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Gurmukhi (0A00..0A7F) */
|
|
||||||
|
|
||||||
/* 0A00 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 0A08 */ _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(x,x), _(x,x), _(VI,x),
|
|
||||||
/* 0A10 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0A18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0A28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0A30 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(x,x),
|
|
||||||
/* 0A38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(x,x), _(M,R), _(M,L),
|
|
||||||
/* 0A40 */ _(M,R), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T),
|
|
||||||
/* 0A48 */ _(M,T), _(x,x), _(x,x), _(M,T), _(M,T), _(V,B), _(x,x), _(x,x),
|
|
||||||
/* 0A50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0A58 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x),
|
|
||||||
/* 0A60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0A68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0A70 */ _(Bi,x), _(x,x), _(CP,x), _(CP,x), _(x,x), _(CM,x), _(x,x), _(x,x),
|
|
||||||
/* 0A78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Gujarati (0A80..0AFF) */
|
|
||||||
|
|
||||||
/* 0A80 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 0A88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x),
|
|
||||||
/* 0A90 */ _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0A98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0AA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0AA8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0AB0 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0AB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,L),
|
|
||||||
/* 0AC0 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(x,x), _(M,T),
|
|
||||||
/* 0AC8 */ _(M,T), _(M,TR), _(x,x), _(M,R), _(M,R), _(V,B), _(x,x), _(x,x),
|
|
||||||
/* 0AD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0AD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0AE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0AE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0AF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0AF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Oriya (0B00..0B7F) */
|
|
||||||
|
|
||||||
/* 0B00 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 0B08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x),
|
|
||||||
/* 0B10 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0B18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0B20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0B28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0B30 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0B38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,T),
|
|
||||||
/* 0B40 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), _(M,L),
|
|
||||||
/* 0B48 */ _(M,TL), _(x,x), _(x,x), _(M,LR),_(M,TLR), _(V,B), _(x,x), _(x,x),
|
|
||||||
/* 0B50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,TR),
|
|
||||||
/* 0B58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x),
|
|
||||||
/* 0B60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0B68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0B70 */ _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0B78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Tamil (0B80..0BFF) */
|
|
||||||
|
|
||||||
/* 0B80 */ _(x,x), _(x,x), _(Bi,x), _(ML,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 0B88 */ _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(x,x), _(VI,x), _(VI,x),
|
|
||||||
/* 0B90 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(x,x), _(x,x),
|
|
||||||
/* 0B98 */ _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(C,x), _(C,x),
|
|
||||||
/* 0BA0 */ _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0BA8 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x),
|
|
||||||
/* 0BB0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0BB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), _(M,R),
|
|
||||||
/* 0BC0 */ _(M,T), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(M,L), _(M,L),
|
|
||||||
/* 0BC8 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T), _(x,x), _(x,x),
|
|
||||||
/* 0BD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
|
|
||||||
/* 0BD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0BE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0BE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0BF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0BF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Telugu (0C00..0C7F) */
|
|
||||||
|
|
||||||
/* 0C00 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 0C08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
|
|
||||||
/* 0C10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0C18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0C20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0C28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0C30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0C38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(A,x), _(M,T), _(M,T),
|
|
||||||
/* 0C40 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,T),
|
|
||||||
/* 0C48 */ _(M,TB), _(x,x), _(M,T), _(M,T), _(M,T), _(V,T), _(x,x), _(x,x),
|
|
||||||
/* 0C50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,B), _(x,x),
|
|
||||||
/* 0C58 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0C60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0C68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0C70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0C78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Kannada (0C80..0CFF) */
|
|
||||||
|
|
||||||
/* 0C80 */ _(x,x), _(x,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 0C88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
|
|
||||||
/* 0C90 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0C98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0CA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0CA8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0CB0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0CB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,T),
|
|
||||||
/* 0CC0 */ _(M,TR), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,TR),
|
|
||||||
/* 0CC8 */ _(M,TR), _(x,x), _(M,TR), _(M,TR), _(M,T), _(V,T), _(x,x), _(x,x),
|
|
||||||
/* 0CD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), _(M,R), _(x,x),
|
|
||||||
/* 0CD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(x,x),
|
|
||||||
/* 0CE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0CE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0CF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0CF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Malayalam (0D00..0D7F) */
|
|
||||||
|
|
||||||
/* 0D00 */ _(x,x), _(x,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 0D08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x),
|
|
||||||
/* 0D10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0D18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0D20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0D28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0D30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0D38 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(A,x), _(M,R), _(M,R),
|
|
||||||
/* 0D40 */ _(M,R), _(M,R), _(M,R), _(M,B), _(M,B), _(x,x), _(M,L), _(M,L),
|
|
||||||
/* 0D48 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T), _(CR,x), _(x,x),
|
|
||||||
/* 0D50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
|
|
||||||
/* 0D58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0D60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0D68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0D70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0D78 */ _(x,x), _(x,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x), _(CD,x),
|
|
||||||
|
|
||||||
/* Sinhala (0D80..0DFF) */
|
|
||||||
|
|
||||||
/* 0D80 */ _(x,x), _(x,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 0D88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 0D90 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x),
|
|
||||||
/* 0D98 */ _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0DA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0DA8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0DB0 */ _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0DB8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(x,x),
|
|
||||||
/* 0DC0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x),
|
|
||||||
/* 0DC8 */ _(x,x), _(x,x), _(V,T), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R),
|
|
||||||
/* 0DD0 */ _(M,R), _(M,R), _(M,T), _(M,T), _(M,B), _(x,x), _(M,B), _(x,x),
|
|
||||||
/* 0DD8 */ _(M,R), _(M,L), _(M,TL), _(M,L), _(M,LR), _(M,LR), _(M,LR), _(M,R),
|
|
||||||
/* 0DE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0DE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0DF0 */ _(x,x), _(x,x), _(M,R), _(M,R), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0DF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Thai (0E00..0E7F) */
|
|
||||||
|
|
||||||
/* 0E00 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0E08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0E10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0E18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0E20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0E28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x),
|
|
||||||
/* 0E30 */ _(M,R), _(M,T), _(M,R), _(M,R), _(M,T), _(M,T), _(M,T), _(M,T),
|
|
||||||
/* 0E38 */ _(M,B), _(M,B), _(V,B), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0E40 */_(M,VOL),_(M,VOL),_(M,VOL),_(M,VOL),_(M,VOL), _(M,R), _(x,x), _(M,T),
|
|
||||||
/* 0E48 */ _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(x,x), _(Bi,x), _(V,T), _(x,x),
|
|
||||||
/* 0E50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0E58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0E60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0E68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0E70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0E78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Lao (0E80..0EFF) */
|
|
||||||
|
|
||||||
/* 0E80 */ _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(x,x), _(C,x),
|
|
||||||
/* 0E88 */ _(C,x), _(x,x), _(C,x), _(x,x), _(x,x), _(C,x), _(x,x), _(x,x),
|
|
||||||
/* 0E90 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0E98 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0EA0 */ _(x,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(C,x),
|
|
||||||
/* 0EA8 */ _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(x,x),
|
|
||||||
/* 0EB0 */ _(M,R), _(M,T), _(M,R), _(M,R), _(M,T), _(M,T), _(M,T), _(M,T),
|
|
||||||
/* 0EB8 */ _(M,B), _(M,B), _(x,x), _(M,T), _(CM,x), _(CM,x), _(x,x), _(x,x),
|
|
||||||
/* 0EC0 */_(M,VOL),_(M,VOL),_(M,VOL),_(M,VOL),_(M,VOL), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0EC8 */ _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(x,x), _(Bi,x), _(x,x), _(x,x),
|
|
||||||
/* 0ED0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0ED8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(x,x), _(x,x),
|
|
||||||
/* 0EE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0EE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0EF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0EF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Tibetan (0F00..0FFF) */
|
|
||||||
|
|
||||||
/* 0F00 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0F08 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0F10 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0F18 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0F20 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0F28 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0F30 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0F38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0F40 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0F48 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0F50 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0F58 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0F60 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 0F68 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0F70 */ _(x,x), _(M,B), _(M,T), _(M,TB), _(M,B), _(M,B), _(M,TB), _(M,TB),
|
|
||||||
/* 0F78 */ _(M,TB), _(M,TB), _(M,T), _(M,T), _(M,T), _(M,T), _(Bi,x), _(Vs,x),
|
|
||||||
/* 0F80 */ _(M,T), _(M,TB), _(Bi,x), _(Bi,x), _(V,B), _(A,x), _(x,x), _(x,x),
|
|
||||||
/* 0F88 */_(CHL,x),_(CHL,x),_(CHL,x),_(CHL,x),_(CHL,x), _(CS,x), _(CS,x), _(CS,x),
|
|
||||||
/* 0F90 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x),
|
|
||||||
/* 0F98 */ _(x,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x),
|
|
||||||
/* 0FA0 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x),
|
|
||||||
/* 0FA8 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x),
|
|
||||||
/* 0FB0 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x),
|
|
||||||
/* 0FB8 */ _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(CS,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0FC0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0FC8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0FD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0FD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0FE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0FE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0FF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 0FF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Myanmar (1000..109F) */
|
|
||||||
|
|
||||||
/* 1000 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1008 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1010 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1018 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1020 */ _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 1028 */ _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R), _(M,T), _(M,T), _(M,B),
|
|
||||||
/* 1030 */ _(M,B), _(M,L), _(M,T), _(M,T), _(M,T), _(M,T), _(Bi,x), _(TM,x),
|
|
||||||
/* 1038 */ _(Vs,x), _(V,I), _(V,T), _(CM,x), _(CM,x), _(CM,x), _(CM,x), _(C,x),
|
|
||||||
/* 1040 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1048 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1050 */ _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R),
|
|
||||||
/* 1058 */ _(M,B), _(M,B), _(C,x), _(C,x), _(C,x), _(C,x), _(CM,x), _(CM,x),
|
|
||||||
/* 1060 */ _(CM,x), _(C,x), _(M,R), _(TM,x), _(TM,x), _(C,x), _(C,x), _(M,R),
|
|
||||||
/* 1068 */ _(M,R), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(C,x), _(C,x),
|
|
||||||
/* 1070 */ _(C,x), _(M,T), _(M,T), _(M,T), _(M,T), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1078 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1080 */ _(C,x), _(C,x), _(CM,x), _(M,R), _(M,L), _(M,T), _(M,T), _(TM,x),
|
|
||||||
/* 1088 */ _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(C,x), _(TM,x),
|
|
||||||
/* 1090 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1098 */ _(x,x), _(x,x), _(TM,x), _(TM,x), _(M,R), _(M,T), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
#define indic_offset_0x1700 1952
|
|
||||||
|
|
||||||
|
|
||||||
/* Tagalog (1700..171F) */
|
|
||||||
|
|
||||||
/* 1700 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1708 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x),
|
|
||||||
/* 1710 */ _(C,x), _(C,x), _(M,T), _(M,B), _(V,B), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1718 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Hanunoo (1720..173F) */
|
|
||||||
|
|
||||||
/* 1720 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1728 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1730 */ _(C,x), _(C,x), _(M,T), _(M,B), _(V,B), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1738 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Buhid (1740..175F) */
|
|
||||||
|
|
||||||
/* 1740 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1748 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1750 */ _(C,x), _(C,x), _(M,T), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1758 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Tagbanwa (1760..177F) */
|
|
||||||
|
|
||||||
/* 1760 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1768 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x),
|
|
||||||
/* 1770 */ _(C,x), _(x,x), _(M,T), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1778 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Khmer (1780..17FF) */
|
|
||||||
|
|
||||||
/* 1780 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1788 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1790 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1798 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 17A0 */ _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 17A8 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 17B0 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(M,R), _(M,T),
|
|
||||||
/* 17B8 */ _(M,T), _(M,T), _(M,T), _(M,B), _(M,B), _(M,B), _(M,TL),_(M,TLR),
|
|
||||||
/* 17C0 */ _(M,LR), _(M,L), _(M,L), _(M,L), _(M,LR), _(M,LR), _(Bi,x), _(Vs,x),
|
|
||||||
/* 17C8 */ _(M,R), _(RS,x), _(RS,x), _(x,x), _(CR,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 17D0 */ _(x,x), _(V,T), _(V,I), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 17D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(A,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 17E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 17E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 17F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 17F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
#define indic_offset_0x1900 2208
|
|
||||||
|
|
||||||
|
|
||||||
/* Limbu (1900..194F) */
|
|
||||||
|
|
||||||
/* 1900 */ _(CP,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1908 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1910 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1920 */ _(M,T), _(M,T), _(M,B), _(M,R), _(M,R), _(M,TR), _(M,TR), _(M,T),
|
|
||||||
/* 1928 */ _(M,T), _(CS,x), _(CS,x), _(CS,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1930 */ _(CF,x), _(CF,x), _(Bi,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),
|
|
||||||
/* 1938 */ _(CF,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1940 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1948 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Tai Le (1950..197F) */
|
|
||||||
|
|
||||||
/* 1950 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1958 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1960 */ _(C,x), _(C,x), _(C,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x),
|
|
||||||
/* 1968 */ _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(x,x), _(x,x),
|
|
||||||
/* 1970 */ _(TL,x), _(TL,x), _(TL,x), _(TL,x), _(TL,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1978 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* New Tai Lue (1980..19DF) */
|
|
||||||
|
|
||||||
/* 1980 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1988 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1990 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 19A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 19A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 19B0 */ _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,L), _(M,L), _(M,L),
|
|
||||||
/* 19B8 */ _(M,R), _(M,R), _(M,L), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R),
|
|
||||||
/* 19C0 */ _(M,R), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),
|
|
||||||
/* 19C8 */ _(TM,x), _(TM,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 19D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 19D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* FILLER (19E0..19FF) */
|
|
||||||
|
|
||||||
/* 19E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 19E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 19F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 19F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Buginese (1A00..1A1F) */
|
|
||||||
|
|
||||||
/* 1A00 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1A08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1A10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,T),
|
|
||||||
/* 1A18 */ _(M,B), _(M,L), _(M,R), _(M,L), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Tai Tham (1A20..1AAF) */
|
|
||||||
|
|
||||||
/* 1A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1A28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1A30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1A38 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1A40 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1A48 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 1A50 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(CM,x), _(CM,x), _(CF,x),
|
|
||||||
/* 1A58 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(x,x),
|
|
||||||
/* 1A60 */ _(V,I), _(M,R), _(M,T), _(M,R), _(M,R), _(M,T), _(M,T), _(M,T),
|
|
||||||
/* 1A68 */ _(M,T), _(M,B), _(M,B), _(M,T), _(M,B), _(M,R), _(M,L), _(M,L),
|
|
||||||
/* 1A70 */ _(M,L), _(M,L), _(M,L), _(M,T), _(M,T), _(TM,x), _(TM,x), _(TM,x),
|
|
||||||
/* 1A78 */ _(TM,x), _(TM,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1A80 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1A88 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1A90 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1A98 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1AA0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1AA8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
#define indic_offset_0x1b00 2640
|
|
||||||
|
|
||||||
|
|
||||||
/* Balinese (1B00..1B7F) */
|
|
||||||
|
|
||||||
/* 1B00 */ _(Bi,x), _(Bi,x), _(Bi,x), _(CR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 1B08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 1B10 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1B18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1B20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1B28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1B30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(N,x), _(M,R), _(M,T), _(M,T),
|
|
||||||
/* 1B38 */ _(M,B), _(M,B), _(M,B), _(M,BR), _(M,TB),_(M,TBR), _(M,L), _(M,L),
|
|
||||||
/* 1B40 */ _(M,LR), _(M,LR), _(M,T), _(M,TR), _(V,R), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1B48 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1B50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1B58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1B60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1B68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1B70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1B78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Sundanese (1B80..1BBF) */
|
|
||||||
|
|
||||||
/* 1B80 */ _(Bi,x), _(CR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 1B88 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1B90 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1B98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1BA0 */ _(C,x), _(CS,x), _(CS,x), _(CS,x), _(M,T), _(M,B), _(M,L), _(M,R),
|
|
||||||
/* 1BA8 */ _(M,T), _(M,T), _(V,R), _(V,x), _(CS,x), _(CS,x), _(C,x), _(C,x),
|
|
||||||
/* 1BB0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1BB8 */ _(x,x), _(x,x), _(A,x), _(C,x), _(C,x), _(C,x), _(CF,x), _(CF,x),
|
|
||||||
|
|
||||||
/* Batak (1BC0..1BFF) */
|
|
||||||
|
|
||||||
/* 1BC0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1BC8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1BD0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1BD8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1BE0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(N,x), _(M,x),
|
|
||||||
/* 1BE8 */ _(M,x), _(M,x), _(M,x), _(M,x), _(M,x), _(M,x), _(M,x), _(M,x),
|
|
||||||
/* 1BF0 */ _(CF,x), _(CF,x), _(V,R), _(V,R), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1BF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Lepcha (1C00..1C4F) */
|
|
||||||
|
|
||||||
/* 1C00 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1C08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1C10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1C18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 1C20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(CS,x), _(CS,x), _(M,R), _(M,L),
|
|
||||||
/* 1C28 */ _(M,L), _(M,TL), _(M,R), _(M,R), _(M,B), _(CF,x), _(CF,x), _(CF,x),
|
|
||||||
/* 1C30 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(Bi,x), _(Bi,x), _(x,x), _(N,x),
|
|
||||||
/* 1C38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1C40 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1C48 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
|
|
||||||
#define indic_offset_0x1cd0 2976
|
|
||||||
|
|
||||||
|
|
||||||
/* Vedic Extensions (1CD0..1CFF) */
|
|
||||||
|
|
||||||
/* 1CD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1CD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1CE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1CE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1CF0 */ _(x,x), _(x,x), _(Vs,x), _(Vs,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 1CF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
#define indic_offset_0xa800 3024
|
|
||||||
|
|
||||||
|
|
||||||
/* Syloti Nagri (A800..A82F) */
|
|
||||||
|
|
||||||
/* A800 */ _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(V,T), _(C,x),
|
|
||||||
/* A808 */ _(C,x), _(C,x), _(C,x), _(Bi,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A810 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A818 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A820 */ _(C,x), _(C,x), _(C,x), _(M,R), _(M,R), _(M,B), _(M,T), _(M,R),
|
|
||||||
/* A828 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* FILLER (A830..A83F) */
|
|
||||||
|
|
||||||
/* A830 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A838 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Phags-pa (A840..A87F) */
|
|
||||||
|
|
||||||
/* A840 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A848 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A850 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A858 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(Vo,x), _(Vo,x),
|
|
||||||
/* A860 */ _(Vo,x), _(Vo,x), _(C,x), _(C,x), _(C,x), _(C,x), _(Vo,x), _(CS,x),
|
|
||||||
/* A868 */ _(CS,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A870 */ _(C,x), _(CS,x), _(C,x), _(Bi,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A878 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Saurashtra (A880..A8DF) */
|
|
||||||
|
|
||||||
/* A880 */ _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* A888 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* A890 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A898 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A8A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A8A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A8B0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(CF,x), _(M,R), _(M,R), _(M,R),
|
|
||||||
/* A8B8 */ _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R),
|
|
||||||
/* A8C0 */ _(M,R), _(M,R), _(M,R), _(M,R), _(V,B), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A8C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A8D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A8D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* FILLER (A8E0..A8FF) */
|
|
||||||
|
|
||||||
/* A8E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A8E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A8F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A8F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Kayah Li (A900..A92F) */
|
|
||||||
|
|
||||||
/* A900 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A908 */ _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A910 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A920 */ _(C,x), _(C,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x),
|
|
||||||
/* A928 */ _(Vo,x), _(Vo,x), _(Vo,x), _(TM,x), _(TM,x), _(TM,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Rejang (A930..A95F) */
|
|
||||||
|
|
||||||
/* A930 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A938 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A940 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,B),
|
|
||||||
/* A948 */ _(M,B), _(M,B), _(M,T), _(M,B), _(M,B), _(M,B), _(M,B), _(CF,x),
|
|
||||||
/* A950 */ _(CF,x), _(CF,x), _(CF,x), _(V,R), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A958 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* FILLER (A960..A97F) */
|
|
||||||
|
|
||||||
/* A960 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A968 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A970 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A978 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Javanese (A980..A9DF) */
|
|
||||||
|
|
||||||
/* A980 */ _(Bi,x), _(Bi,x), _(CR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* A988 */ _(VI,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(C,x),
|
|
||||||
/* A990 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A9A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A9A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* A9B0 */ _(C,x), _(C,x), _(C,x), _(N,x), _(M,R), _(M,R), _(M,T), _(M,T),
|
|
||||||
/* A9B8 */ _(M,B), _(M,B), _(M,L), _(M,L), _(M,T), _(CS,x), _(CM,x), _(CM,x),
|
|
||||||
/* A9C0 */ _(V,BR), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A9C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A9D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A9D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* FILLER (A9E0..A9FF) */
|
|
||||||
|
|
||||||
/* A9E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A9E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A9F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* A9F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Cham (AA00..AA5F) */
|
|
||||||
|
|
||||||
/* AA00 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x),
|
|
||||||
/* AA08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* AA10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* AA18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* AA20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* AA28 */ _(C,x), _(M,T), _(M,T), _(M,T), _(M,T), _(M,B), _(M,T), _(M,L),
|
|
||||||
/* AA30 */ _(M,L), _(M,T), _(M,B), _(CM,x), _(CM,x), _(CM,x), _(CM,x), _(x,x),
|
|
||||||
/* AA38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* AA40 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),
|
|
||||||
/* AA48 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(x,x), _(x,x),
|
|
||||||
/* AA50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* AA58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Myanmar Extended-A (AA60..AA7F) */
|
|
||||||
|
|
||||||
/* AA60 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* AA68 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* AA70 */ _(x,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* AA78 */ _(x,x), _(x,x), _(C,x), _(TM,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Tai Viet (AA80..AADF) */
|
|
||||||
|
|
||||||
/* AA80 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* AA88 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* AA90 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* AA98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* AAA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* AAA8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* AAB0 */ _(M,T), _(M,R), _(M,T), _(M,T), _(M,B),_(M,VOL),_(M,VOL), _(M,T),
|
|
||||||
/* AAB8 */ _(M,T),_(M,VOL), _(M,R),_(M,VOL),_(M,VOL), _(M,R), _(M,T), _(TM,x),
|
|
||||||
/* AAC0 */ _(TL,x), _(TM,x), _(TL,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* AAC8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* AAD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* AAD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Meetei Mayek Extensions (AAE0..AAFF) */
|
|
||||||
|
|
||||||
/* AAE0 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* AAE8 */ _(C,x), _(C,x), _(C,x), _(M,L), _(M,B), _(M,T), _(M,L), _(M,R),
|
|
||||||
/* AAF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Vs,x), _(V,I), _(x,x),
|
|
||||||
/* AAF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
#define indic_offset_0xabc0 3792
|
|
||||||
|
|
||||||
|
|
||||||
/* Meetei Mayek (ABC0..ABFF) */
|
|
||||||
|
|
||||||
/* ABC0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* ABC8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x),
|
|
||||||
/* ABD0 */ _(C,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* ABD8 */ _(C,x), _(C,x), _(C,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x),
|
|
||||||
/* ABE0 */ _(CF,x), _(CF,x), _(CF,x), _(M,R), _(M,R), _(M,T), _(M,R), _(M,R),
|
|
||||||
/* ABE8 */ _(M,B), _(M,R), _(M,R), _(x,x), _(TM,x), _(V,B), _(x,x), _(x,x),
|
|
||||||
/* ABF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* ABF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
#define indic_offset_0x10a00 3856
|
|
||||||
|
|
||||||
|
|
||||||
/* Kharoshthi (10A00..10A5F) */
|
|
||||||
|
|
||||||
/* 10A00 */ _(C,x), _(M,O), _(M,B), _(M,B), _(x,x), _(M,T), _(M,O), _(x,x),
|
|
||||||
/* 10A08 */ _(x,x), _(x,x), _(x,x), _(x,x), _(M,B), _(x,x), _(Bi,x), _(Vs,x),
|
|
||||||
/* 10A10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 10A18 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 10A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 10A28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 10A30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 10A38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(V,I),
|
|
||||||
/* 10A40 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 10A48 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 10A50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 10A58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
#define indic_offset_0x11000 3952
|
|
||||||
|
|
||||||
|
|
||||||
/* Brahmi (11000..1107F) */
|
|
||||||
|
|
||||||
/* 11000 */ _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 11008 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 11010 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 11018 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 11020 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 11028 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 11030 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 11038 */ _(M,T), _(M,T), _(M,T), _(M,T), _(M,B), _(M,B), _(M,B), _(M,B),
|
|
||||||
/* 11040 */ _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), _(M,T), _(V,T), _(x,x),
|
|
||||||
/* 11048 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 11050 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 11058 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 11060 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 11068 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 11070 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 11078 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
/* Kaithi (11080..110CF) */
|
|
||||||
|
|
||||||
/* 11080 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 11088 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 11090 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 11098 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 110A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 110A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 110B0 */ _(M,R), _(M,L), _(M,R), _(M,B), _(M,B), _(M,T), _(M,T), _(M,R),
|
|
||||||
/* 110B8 */ _(M,R), _(V,B), _(N,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 110C0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 110C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
#define indic_offset_0x11100 4160
|
|
||||||
|
|
||||||
|
|
||||||
/* Chakma (11100..1114F) */
|
|
||||||
|
|
||||||
/* 11100 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x),
|
|
||||||
/* 11108 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 11110 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 11118 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 11120 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,T),
|
|
||||||
/* 11128 */ _(M,T), _(M,T), _(M,B), _(M,B), _(M,L), _(M,T), _(M,TB), _(M,TB),
|
|
||||||
/* 11130 */ _(M,T), _(M,B), _(M,B), _(V,I), _(V,T), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 11138 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 11140 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 11148 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
#define indic_offset_0x11180 4240
|
|
||||||
|
|
||||||
|
|
||||||
/* Sharada (11180..111DF) */
|
|
||||||
|
|
||||||
/* 11180 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 11188 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 11190 */ _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 11198 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 111A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 111A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 111B0 */ _(C,x), _(C,x), _(C,x), _(M,R), _(M,L), _(M,R), _(M,B), _(M,B),
|
|
||||||
/* 111B8 */ _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), _(M,TR),
|
|
||||||
/* 111C0 */ _(V,R), _(A,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 111C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 111D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 111D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
#define indic_offset_0x11680 4336
|
|
||||||
|
|
||||||
|
|
||||||
/* Takri (11680..116CF) */
|
|
||||||
|
|
||||||
/* 11680 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x),
|
|
||||||
/* 11688 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 11690 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 11698 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 116A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x),
|
|
||||||
/* 116A8 */ _(C,x), _(C,x), _(C,x), _(Bi,x), _(Vs,x), _(M,T), _(M,L), _(M,R),
|
|
||||||
/* 116B0 */ _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), _(M,T), _(V,T), _(N,x),
|
|
||||||
/* 116B8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 116C0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
/* 116C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x),
|
|
||||||
|
|
||||||
#define indic_offset_total 4416
|
|
||||||
|
|
||||||
}; /* Table occupancy: 60% */
|
|
||||||
|
|
||||||
static INDIC_TABLE_ELEMENT_TYPE
|
|
||||||
get_indic_categories (hb_codepoint_t u)
|
|
||||||
{
|
|
||||||
if (0x0900 <= u && u <= 0x10A0) return indic_table[u - 0x0900 + indic_offset_0x0900];
|
|
||||||
if (0x1700 <= u && u <= 0x1800) return indic_table[u - 0x1700 + indic_offset_0x1700];
|
|
||||||
if (0x1900 <= u && u <= 0x1AB0) return indic_table[u - 0x1900 + indic_offset_0x1900];
|
|
||||||
if (0x1B00 <= u && u <= 0x1C50) return indic_table[u - 0x1B00 + indic_offset_0x1b00];
|
|
||||||
if (0x1CD0 <= u && u <= 0x1D00) return indic_table[u - 0x1CD0 + indic_offset_0x1cd0];
|
|
||||||
if (0xA800 <= u && u <= 0xAB00) return indic_table[u - 0xA800 + indic_offset_0xa800];
|
|
||||||
if (0xABC0 <= u && u <= 0xAC00) return indic_table[u - 0xABC0 + indic_offset_0xabc0];
|
|
||||||
if (0x10A00 <= u && u <= 0x10A60) return indic_table[u - 0x10A00 + indic_offset_0x10a00];
|
|
||||||
if (0x11000 <= u && u <= 0x110D0) return indic_table[u - 0x11000 + indic_offset_0x11000];
|
|
||||||
if (0x11100 <= u && u <= 0x11150) return indic_table[u - 0x11100 + indic_offset_0x11100];
|
|
||||||
if (0x11180 <= u && u <= 0x111E0) return indic_table[u - 0x11180 + indic_offset_0x11180];
|
|
||||||
if (0x11680 <= u && u <= 0x116D0) return indic_table[u - 0x11680 + indic_offset_0x11680];
|
|
||||||
if (unlikely (u == 0x00A0)) return _(CP,x);
|
|
||||||
if (unlikely (u == 0x25CC)) return _(CP,x);
|
|
||||||
return _(x,x);
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef _
|
|
||||||
|
|
||||||
#undef ISC_A
|
|
||||||
#undef ISC_Bi
|
|
||||||
#undef ISC_C
|
|
||||||
#undef ISC_CD
|
|
||||||
#undef ISC_CF
|
|
||||||
#undef ISC_CHL
|
|
||||||
#undef ISC_CM
|
|
||||||
#undef ISC_CP
|
|
||||||
#undef ISC_CR
|
|
||||||
#undef ISC_CS
|
|
||||||
#undef ISC_ML
|
|
||||||
#undef ISC_N
|
|
||||||
#undef ISC_x
|
|
||||||
#undef ISC_RS
|
|
||||||
#undef ISC_TL
|
|
||||||
#undef ISC_TM
|
|
||||||
#undef ISC_V
|
|
||||||
#undef ISC_Vs
|
|
||||||
#undef ISC_Vo
|
|
||||||
#undef ISC_M
|
|
||||||
#undef ISC_VI
|
|
||||||
|
|
||||||
#undef IMC_B
|
|
||||||
#undef IMC_BR
|
|
||||||
#undef IMC_I
|
|
||||||
#undef IMC_L
|
|
||||||
#undef IMC_LR
|
|
||||||
#undef IMC_x
|
|
||||||
#undef IMC_O
|
|
||||||
#undef IMC_R
|
|
||||||
#undef IMC_T
|
|
||||||
#undef IMC_TB
|
|
||||||
#undef IMC_TBR
|
|
||||||
#undef IMC_TL
|
|
||||||
#undef IMC_TLR
|
|
||||||
#undef IMC_TR
|
|
||||||
#undef IMC_VOL
|
|
||||||
|
|
||||||
#endif /* HB_OT_SHAPE_COMPLEX_INDIC_TABLE_HH */
|
|
||||||
|
|
||||||
/* == End of generated table == */
|
|
@ -37,19 +37,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define IN_HALF_BLOCK(u, Base) (((u) & ~0x7F) == (Base))
|
#define IN_HALF_BLOCK(u, Base) (((u) & ~0x7Fu) == (Base))
|
||||||
|
|
||||||
#define IS_DEVA(u) (IN_HALF_BLOCK (u, 0x0900))
|
#define IS_DEVA(u) (IN_HALF_BLOCK (u, 0x0900u))
|
||||||
#define IS_BENG(u) (IN_HALF_BLOCK (u, 0x0980))
|
#define IS_BENG(u) (IN_HALF_BLOCK (u, 0x0980u))
|
||||||
#define IS_GURU(u) (IN_HALF_BLOCK (u, 0x0A00))
|
#define IS_GURU(u) (IN_HALF_BLOCK (u, 0x0A00u))
|
||||||
#define IS_GUJR(u) (IN_HALF_BLOCK (u, 0x0A80))
|
#define IS_GUJR(u) (IN_HALF_BLOCK (u, 0x0A80u))
|
||||||
#define IS_ORYA(u) (IN_HALF_BLOCK (u, 0x0B00))
|
#define IS_ORYA(u) (IN_HALF_BLOCK (u, 0x0B00u))
|
||||||
#define IS_TAML(u) (IN_HALF_BLOCK (u, 0x0B80))
|
#define IS_TAML(u) (IN_HALF_BLOCK (u, 0x0B80u))
|
||||||
#define IS_TELU(u) (IN_HALF_BLOCK (u, 0x0C00))
|
#define IS_TELU(u) (IN_HALF_BLOCK (u, 0x0C00u))
|
||||||
#define IS_KNDA(u) (IN_HALF_BLOCK (u, 0x0C80))
|
#define IS_KNDA(u) (IN_HALF_BLOCK (u, 0x0C80u))
|
||||||
#define IS_MLYM(u) (IN_HALF_BLOCK (u, 0x0D00))
|
#define IS_MLYM(u) (IN_HALF_BLOCK (u, 0x0D00u))
|
||||||
#define IS_SINH(u) (IN_HALF_BLOCK (u, 0x0D80))
|
#define IS_SINH(u) (IN_HALF_BLOCK (u, 0x0D80u))
|
||||||
#define IS_KHMR(u) (IN_HALF_BLOCK (u, 0x1780))
|
#define IS_KHMR(u) (IN_HALF_BLOCK (u, 0x1780u))
|
||||||
|
|
||||||
|
|
||||||
#define MATRA_POS_LEFT(u) POS_PRE_M
|
#define MATRA_POS_LEFT(u) POS_PRE_M
|
||||||
@ -60,8 +60,8 @@
|
|||||||
IS_GUJR(u) ? POS_AFTER_POST : \
|
IS_GUJR(u) ? POS_AFTER_POST : \
|
||||||
IS_ORYA(u) ? POS_AFTER_POST : \
|
IS_ORYA(u) ? POS_AFTER_POST : \
|
||||||
IS_TAML(u) ? POS_AFTER_POST : \
|
IS_TAML(u) ? POS_AFTER_POST : \
|
||||||
IS_TELU(u) ? (u <= 0x0C42 ? POS_BEFORE_SUB : POS_AFTER_SUB) : \
|
IS_TELU(u) ? (u <= 0x0C42u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \
|
||||||
IS_KNDA(u) ? (u < 0x0CC3 || u > 0xCD6 ? POS_BEFORE_SUB : POS_AFTER_SUB) : \
|
IS_KNDA(u) ? (u < 0x0CC3u || u > 0xCD6u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \
|
||||||
IS_MLYM(u) ? POS_AFTER_POST : \
|
IS_MLYM(u) ? POS_AFTER_POST : \
|
||||||
IS_SINH(u) ? POS_AFTER_SUB : \
|
IS_SINH(u) ? POS_AFTER_SUB : \
|
||||||
IS_KHMR(u) ? POS_AFTER_POST : \
|
IS_KHMR(u) ? POS_AFTER_POST : \
|
||||||
@ -112,20 +112,20 @@ matra_position (hb_codepoint_t u, indic_position_t side)
|
|||||||
* Or completely remove it and just check in the tables.
|
* Or completely remove it and just check in the tables.
|
||||||
*/
|
*/
|
||||||
static const hb_codepoint_t ra_chars[] = {
|
static const hb_codepoint_t ra_chars[] = {
|
||||||
0x0930, /* Devanagari */
|
0x0930u, /* Devanagari */
|
||||||
0x09B0, /* Bengali */
|
0x09B0u, /* Bengali */
|
||||||
0x09F0, /* Bengali */
|
0x09F0u, /* Bengali */
|
||||||
0x0A30, /* Gurmukhi */ /* No Reph */
|
0x0A30u, /* Gurmukhi */ /* No Reph */
|
||||||
0x0AB0, /* Gujarati */
|
0x0AB0u, /* Gujarati */
|
||||||
0x0B30, /* Oriya */
|
0x0B30u, /* Oriya */
|
||||||
0x0BB0, /* Tamil */ /* No Reph */
|
0x0BB0u, /* Tamil */ /* No Reph */
|
||||||
0x0C30, /* Telugu */ /* Reph formed only with ZWJ */
|
0x0C30u, /* Telugu */ /* Reph formed only with ZWJ */
|
||||||
0x0CB0, /* Kannada */
|
0x0CB0u, /* Kannada */
|
||||||
0x0D30, /* Malayalam */ /* No Reph, Logical Repha */
|
0x0D30u, /* Malayalam */ /* No Reph, Logical Repha */
|
||||||
|
|
||||||
0x0DBB, /* Sinhala */ /* Reph formed only with ZWJ */
|
0x0DBBu, /* Sinhala */ /* Reph formed only with ZWJ */
|
||||||
|
|
||||||
0x179A, /* Khmer */ /* No Reph, Visual Repha */
|
0x179Au, /* Khmer */ /* No Reph, Visual Repha */
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
@ -145,28 +145,18 @@ is_one_of (const hb_glyph_info_t &info, unsigned int flags)
|
|||||||
return !!(FLAG (info.indic_category()) & flags);
|
return !!(FLAG (info.indic_category()) & flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define JOINER_FLAGS (FLAG (OT_ZWJ) | FLAG (OT_ZWNJ))
|
|
||||||
static inline bool
|
static inline bool
|
||||||
is_joiner (const hb_glyph_info_t &info)
|
is_joiner (const hb_glyph_info_t &info)
|
||||||
{
|
{
|
||||||
return is_one_of (info, JOINER_FLAGS);
|
return is_one_of (info, JOINER_FLAGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MEDIAL_FLAGS (FLAG (OT_CM) | FLAG (OT_CM2))
|
|
||||||
|
|
||||||
/* Note:
|
|
||||||
*
|
|
||||||
* We treat Vowels and placeholders as if they were consonants. This is safe because Vowels
|
|
||||||
* cannot happen in a consonant syllable. The plus side however is, we can call the
|
|
||||||
* consonant syllable logic from the vowel syllable function and get it all right! */
|
|
||||||
#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_NBSP) | FLAG (OT_DOTTEDCIRCLE))
|
|
||||||
static inline bool
|
static inline bool
|
||||||
is_consonant (const hb_glyph_info_t &info)
|
is_consonant (const hb_glyph_info_t &info)
|
||||||
{
|
{
|
||||||
return is_one_of (info, CONSONANT_FLAGS);
|
return is_one_of (info, CONSONANT_FLAGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HALANT_OR_COENG_FLAGS (FLAG (OT_H) | FLAG (OT_Coeng))
|
|
||||||
static inline bool
|
static inline bool
|
||||||
is_halant_or_coeng (const hb_glyph_info_t &info)
|
is_halant_or_coeng (const hb_glyph_info_t &info)
|
||||||
{
|
{
|
||||||
@ -178,7 +168,7 @@ set_indic_properties (hb_glyph_info_t &info)
|
|||||||
{
|
{
|
||||||
hb_codepoint_t u = info.codepoint;
|
hb_codepoint_t u = info.codepoint;
|
||||||
unsigned int type = hb_indic_get_categories (u);
|
unsigned int type = hb_indic_get_categories (u);
|
||||||
indic_category_t cat = (indic_category_t) (type & 0x7F);
|
indic_category_t cat = (indic_category_t) (type & 0x7Fu);
|
||||||
indic_position_t pos = (indic_position_t) (type >> 8);
|
indic_position_t pos = (indic_position_t) (type >> 8);
|
||||||
|
|
||||||
|
|
||||||
@ -188,48 +178,59 @@ set_indic_properties (hb_glyph_info_t &info)
|
|||||||
|
|
||||||
|
|
||||||
/* The spec says U+0952 is OT_A. However, testing shows that Uniscribe
|
/* The spec says U+0952 is OT_A. However, testing shows that Uniscribe
|
||||||
* treats U+0951..U+0954 all behave similarly.
|
* treats a whole bunch of characters similarly.
|
||||||
* TESTS:
|
* TESTS: For example, for U+0951:
|
||||||
* U+092E,U+0947,U+0952
|
* U+092E,U+0947,U+0952
|
||||||
* U+092E,U+0952,U+0947
|
* U+092E,U+0952,U+0947
|
||||||
* U+092E,U+0947,U+0951
|
* U+092E,U+0947,U+0951
|
||||||
* U+092E,U+0951,U+0947
|
* U+092E,U+0951,U+0947
|
||||||
|
* U+092E,U+0951,U+0952
|
||||||
|
* U+092E,U+0952,U+0951
|
||||||
*/
|
*/
|
||||||
if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x0951, 0x0954)))
|
if (unlikely (hb_in_ranges (u, 0x0951u, 0x0952u,
|
||||||
|
0x1CD0u, 0x1CD2u,
|
||||||
|
0x1CD4u, 0x1CE1u) ||
|
||||||
|
u == 0x1CF4u))
|
||||||
cat = OT_A;
|
cat = OT_A;
|
||||||
|
/* The following act more like the Bindus. */
|
||||||
if (unlikely (u == 0x17D1))
|
else if (unlikely (hb_in_range (u, 0x0953u, 0x0954u)))
|
||||||
cat = OT_X;
|
cat = OT_SM;
|
||||||
if (cat == OT_X &&
|
/* The following act like consonants. */
|
||||||
unlikely (hb_in_range<hb_codepoint_t> (u, 0x17CB, 0x17D3))) /* Khmer Various signs */
|
else if (unlikely (hb_in_ranges (u, 0x0A72u, 0x0A73u,
|
||||||
|
0x1CF5u, 0x1CF6u)))
|
||||||
|
cat = OT_C;
|
||||||
|
/* TODO: The following should only be allowed after a Visarga.
|
||||||
|
* For now, just treat them like regular tone marks. */
|
||||||
|
else if (unlikely (hb_in_range (u, 0x1CE2u, 0x1CE8u)))
|
||||||
|
cat = OT_A;
|
||||||
|
/* TODO: The following should only be allowed after some of
|
||||||
|
* the nasalization marks, maybe only for U+1CE9..U+1CF1.
|
||||||
|
* For now, just treat them like tone marks. */
|
||||||
|
else if (unlikely (u == 0x1CEDu))
|
||||||
|
cat = OT_A;
|
||||||
|
/* The following take marks in standalone clusters, similar to Avagraha. */
|
||||||
|
else if (unlikely (hb_in_ranges (u, 0xA8F2u, 0xA8F7u,
|
||||||
|
0x1CE9u, 0x1CECu,
|
||||||
|
0x1CEEu, 0x1CF1u)))
|
||||||
|
{
|
||||||
|
cat = OT_Symbol;
|
||||||
|
ASSERT_STATIC ((int) INDIC_SYLLABIC_CATEGORY_AVAGRAHA == OT_Symbol);
|
||||||
|
}
|
||||||
|
else if (unlikely (hb_in_range (u, 0x17CDu, 0x17D1u) ||
|
||||||
|
u == 0x17CBu || u == 0x17D3u || u == 0x17DDu)) /* Khmer Various signs */
|
||||||
{
|
{
|
||||||
/* These are like Top Matras. */
|
/* These are like Top Matras. */
|
||||||
cat = OT_M;
|
cat = OT_M;
|
||||||
pos = POS_ABOVE_C;
|
pos = POS_ABOVE_C;
|
||||||
}
|
}
|
||||||
if (u == 0x17C6) /* Khmer Bindu doesn't like to be repositioned. */
|
else if (unlikely (u == 0x17C6u)) cat = OT_N; /* Khmer Bindu doesn't like to be repositioned. */
|
||||||
cat = OT_N;
|
else if (unlikely (u == 0x17D2u)) cat = OT_Coeng; /* Khmer coeng */
|
||||||
|
else if (unlikely (hb_in_range (u, 0x2010u, 0x2011u)))
|
||||||
if (unlikely (u == 0x17D2)) cat = OT_Coeng; /* Khmer coeng */
|
cat = OT_PLACEHOLDER;
|
||||||
else if (unlikely (u == 0x200C)) cat = OT_ZWNJ;
|
else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE;
|
||||||
else if (unlikely (u == 0x200D)) cat = OT_ZWJ;
|
else if (unlikely (u == 0xA982u)) cat = OT_SM; /* Javanese repha. */
|
||||||
else if (unlikely (u == 0x25CC)) cat = OT_DOTTEDCIRCLE;
|
else if (unlikely (u == 0xA9BEu)) cat = OT_CM2; /* Javanese medial ya. */
|
||||||
else if (unlikely (u == 0x0A71)) cat = OT_SM; /* GURMUKHI ADDAK. Move it to the end. */
|
else if (unlikely (u == 0xA9BDu)) { cat = OT_M; pos = POS_POST_C; } /* Javanese vocalic r. */
|
||||||
else if (unlikely (u == 0xA982)) cat = OT_SM; /* Javanese repha. */
|
|
||||||
else if (unlikely (u == 0xA9BE)) cat = OT_CM2; /* Javanese medial ya. */
|
|
||||||
else if (unlikely (u == 0xA9BD)) { cat = OT_M; pos = POS_POST_C; } /* Javanese vocalic r. */
|
|
||||||
|
|
||||||
if (cat == OT_Repha) {
|
|
||||||
/* There are two kinds of characters marked as Repha:
|
|
||||||
* - The ones that are GenCat=Mn are already positioned visually, ie. after base. (eg. Khmer)
|
|
||||||
* - The ones that are GenCat=Lo is encoded logically, ie. beginning of syllable. (eg. Malayalam)
|
|
||||||
*
|
|
||||||
* We recategorize the first kind to look like a Nukta and attached to the base directly.
|
|
||||||
*/
|
|
||||||
if (_hb_glyph_info_get_general_category (&info) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
|
|
||||||
cat = OT_N;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -246,12 +247,12 @@ set_indic_properties (hb_glyph_info_t &info)
|
|||||||
{
|
{
|
||||||
pos = matra_position (u, pos);
|
pos = matra_position (u, pos);
|
||||||
}
|
}
|
||||||
else if ((FLAG (cat) & (FLAG (OT_SM) | FLAG (OT_VD) | FLAG (OT_A) | FLAG (OT_Avag))))
|
else if ((FLAG (cat) & (FLAG (OT_SM) | FLAG (OT_VD) | FLAG (OT_A) | FLAG (OT_Symbol))))
|
||||||
{
|
{
|
||||||
pos = POS_SMVD;
|
pos = POS_SMVD;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely (u == 0x0B01)) pos = POS_BEFORE_SUB; /* Oriya Bindu is BeforeSub in the spec. */
|
if (unlikely (u == 0x0B01u)) pos = POS_BEFORE_SUB; /* Oriya Bindu is BeforeSub in the spec. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -315,20 +316,20 @@ struct indic_config_t
|
|||||||
static const indic_config_t indic_configs[] =
|
static const indic_config_t indic_configs[] =
|
||||||
{
|
{
|
||||||
/* Default. Should be first. */
|
/* Default. Should be first. */
|
||||||
{HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_1},
|
{HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_1},
|
||||||
{HB_SCRIPT_DEVANAGARI,true, 0x094D,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
|
{HB_SCRIPT_DEVANAGARI,true, 0x094Du,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
|
||||||
{HB_SCRIPT_BENGALI, true, 0x09CD,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
|
{HB_SCRIPT_BENGALI, true, 0x09CDu,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
|
||||||
{HB_SCRIPT_GURMUKHI, true, 0x0A4D,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
|
{HB_SCRIPT_GURMUKHI, true, 0x0A4Du,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
|
||||||
{HB_SCRIPT_GUJARATI, true, 0x0ACD,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
|
{HB_SCRIPT_GUJARATI, true, 0x0ACDu,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
|
||||||
{HB_SCRIPT_ORIYA, true, 0x0B4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
|
{HB_SCRIPT_ORIYA, true, 0x0B4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
|
||||||
{HB_SCRIPT_TAMIL, true, 0x0BCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
|
{HB_SCRIPT_TAMIL, true, 0x0BCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
|
||||||
{HB_SCRIPT_TELUGU, true, 0x0C4D,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY, PREF_LEN_2},
|
{HB_SCRIPT_TELUGU, true, 0x0C4Du,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY, PREF_LEN_2},
|
||||||
{HB_SCRIPT_KANNADA, true, 0x0CCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY, PREF_LEN_2},
|
{HB_SCRIPT_KANNADA, true, 0x0CCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY, PREF_LEN_2},
|
||||||
{HB_SCRIPT_MALAYALAM, true, 0x0D4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
|
{HB_SCRIPT_MALAYALAM, true, 0x0D4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
|
||||||
{HB_SCRIPT_SINHALA, false,0x0DCA,BASE_POS_LAST_SINHALA,
|
{HB_SCRIPT_SINHALA, false,0x0DCAu,BASE_POS_LAST_SINHALA,
|
||||||
REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
|
REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
|
||||||
{HB_SCRIPT_KHMER, false,0x17D2,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
|
{HB_SCRIPT_KHMER, false,0x17D2u,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
|
||||||
{HB_SCRIPT_JAVANESE, false,0xA9C0,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_1},
|
{HB_SCRIPT_JAVANESE, false,0xA9C0u,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_1},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -552,12 +553,12 @@ data_create_indic (const hb_ot_shape_plan_t *plan)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FF) != '2');
|
indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FFu) != '2');
|
||||||
indic_plan->virama_glyph = (hb_codepoint_t) -1;
|
indic_plan->virama_glyph = (hb_codepoint_t) -1;
|
||||||
|
|
||||||
/* Use zero-context would_substitute() matching for new-spec of the main
|
/* Use zero-context would_substitute() matching for new-spec of the main
|
||||||
* Indic scripts, but not for old-spec or scripts with one spec only. */
|
* Indic scripts, and scripts with one spec only, but not for old-specs. */
|
||||||
bool zero_context = indic_plan->config->has_old_spec || !indic_plan->is_old_spec;
|
bool zero_context = !indic_plan->is_old_spec;
|
||||||
indic_plan->rphf.init (&plan->map, HB_TAG('r','p','h','f'), zero_context);
|
indic_plan->rphf.init (&plan->map, HB_TAG('r','p','h','f'), zero_context);
|
||||||
indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'), zero_context);
|
indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'), zero_context);
|
||||||
indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'), zero_context);
|
indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'), zero_context);
|
||||||
@ -614,7 +615,7 @@ enum syllable_type_t {
|
|||||||
consonant_syllable,
|
consonant_syllable,
|
||||||
vowel_syllable,
|
vowel_syllable,
|
||||||
standalone_cluster,
|
standalone_cluster,
|
||||||
avagraha_cluster,
|
symbol_cluster,
|
||||||
broken_cluster,
|
broken_cluster,
|
||||||
non_indic_cluster,
|
non_indic_cluster,
|
||||||
};
|
};
|
||||||
@ -634,8 +635,9 @@ setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||||||
* and setup masks later on in a pause-callback. */
|
* and setup masks later on in a pause-callback. */
|
||||||
|
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
set_indic_properties (buffer->info[i]);
|
set_indic_properties (info[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -672,10 +674,12 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan,
|
|||||||
{
|
{
|
||||||
hb_face_t *face = font->face;
|
hb_face_t *face = font->face;
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (buffer->info[i].indic_position() == POS_BASE_C) {
|
if (info[i].indic_position() == POS_BASE_C)
|
||||||
hb_codepoint_t consonant = buffer->info[i].codepoint;
|
{
|
||||||
buffer->info[i].indic_position() = consonant_position_from_face (indic_plan, consonant, virama, face);
|
hb_codepoint_t consonant = info[i].codepoint;
|
||||||
|
info[i].indic_position() = consonant_position_from_face (indic_plan, consonant, virama, face);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -725,8 +729,13 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
|||||||
))
|
))
|
||||||
{
|
{
|
||||||
/* See if it matches the 'rphf' feature. */
|
/* See if it matches the 'rphf' feature. */
|
||||||
hb_codepoint_t glyphs[2] = {info[start].codepoint, info[start + 1].codepoint};
|
hb_codepoint_t glyphs[3] = {info[start].codepoint,
|
||||||
if (indic_plan->rphf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face))
|
info[start + 1].codepoint,
|
||||||
|
indic_plan->config->reph_mode == REPH_MODE_EXPLICIT ?
|
||||||
|
info[start + 2].codepoint : 0};
|
||||||
|
if (indic_plan->rphf.would_substitute (glyphs, 2, face) ||
|
||||||
|
(indic_plan->config->reph_mode == REPH_MODE_EXPLICIT &&
|
||||||
|
indic_plan->rphf.would_substitute (glyphs, 3, face)))
|
||||||
{
|
{
|
||||||
limit += 2;
|
limit += 2;
|
||||||
while (limit < end && is_joiner (info[limit]))
|
while (limit < end && is_joiner (info[limit]))
|
||||||
@ -801,7 +810,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
|||||||
case BASE_POS_LAST_SINHALA:
|
case BASE_POS_LAST_SINHALA:
|
||||||
{
|
{
|
||||||
/* Sinhala base positioning is slightly different from main Indic, in that:
|
/* Sinhala base positioning is slightly different from main Indic, in that:
|
||||||
* 1. It's ZWJ behavior is different,
|
* 1. Its ZWJ behavior is different,
|
||||||
* 2. We don't need to look into the font for consonant positions.
|
* 2. We don't need to look into the font for consonant positions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -912,14 +921,32 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
|||||||
info[start].indic_position() = POS_RA_TO_BECOME_REPH;
|
info[start].indic_position() = POS_RA_TO_BECOME_REPH;
|
||||||
|
|
||||||
/* For old-style Indic script tags, move the first post-base Halant after
|
/* For old-style Indic script tags, move the first post-base Halant after
|
||||||
* last consonant. Only do this if there is *not* a Halant after last
|
* last consonant.
|
||||||
* consonant. Otherwise it becomes messy. */
|
*
|
||||||
if (indic_plan->is_old_spec) {
|
* Reports suggest that in some scripts Uniscribe does this only if there
|
||||||
|
* is *not* a Halant after last consonant already (eg. Kannada), while it
|
||||||
|
* does it unconditionally in other scripts (eg. Malayalam). We don't
|
||||||
|
* currently know about other scripts, so we single out Malayalam for now.
|
||||||
|
*
|
||||||
|
* Kannada test case:
|
||||||
|
* U+0C9A,U+0CCD,U+0C9A,U+0CCD
|
||||||
|
* With some versions of Lohit Kannada.
|
||||||
|
* https://bugs.freedesktop.org/show_bug.cgi?id=59118
|
||||||
|
*
|
||||||
|
* Malayalam test case:
|
||||||
|
* U+0D38,U+0D4D,U+0D31,U+0D4D,U+0D31,U+0D4D
|
||||||
|
* With lohit-ttf-20121122/Lohit-Malayalam.ttf
|
||||||
|
*/
|
||||||
|
if (indic_plan->is_old_spec)
|
||||||
|
{
|
||||||
|
bool disallow_double_halants = buffer->props.script != HB_SCRIPT_MALAYALAM;
|
||||||
for (unsigned int i = base + 1; i < end; i++)
|
for (unsigned int i = base + 1; i < end; i++)
|
||||||
if (info[i].indic_category() == OT_H) {
|
if (info[i].indic_category() == OT_H)
|
||||||
|
{
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
for (j = end - 1; j > i; j--)
|
for (j = end - 1; j > i; j--)
|
||||||
if (is_consonant (info[j]) || info[j].indic_category() == OT_H)
|
if (is_consonant (info[j]) ||
|
||||||
|
(disallow_double_halants && info[j].indic_category() == OT_H))
|
||||||
break;
|
break;
|
||||||
if (info[j].indic_category() != OT_H && j > i) {
|
if (info[j].indic_category() != OT_H && j > i) {
|
||||||
/* Move Halant to after last consonant. */
|
/* Move Halant to after last consonant. */
|
||||||
@ -1151,8 +1178,8 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
|
|||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
unsigned int start, unsigned int end)
|
unsigned int start, unsigned int end)
|
||||||
{
|
{
|
||||||
/* We treat NBSP/dotted-circle as if they are consonants, so we should just chain.
|
/* We treat placeholder/dotted-circle as if they are consonants, so we
|
||||||
* Only if not in compatibility mode that is... */
|
* should just chain. Only if not in compatibility mode that is... */
|
||||||
|
|
||||||
if (hb_options ().uniscribe_bug_compatible)
|
if (hb_options ().uniscribe_bug_compatible)
|
||||||
{
|
{
|
||||||
@ -1177,10 +1204,10 @@ initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
initial_reordering_avagraha_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
initial_reordering_symbol_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||||
hb_face_t *face HB_UNUSED,
|
hb_face_t *face HB_UNUSED,
|
||||||
hb_buffer_t *buffer HB_UNUSED,
|
hb_buffer_t *buffer HB_UNUSED,
|
||||||
unsigned int start HB_UNUSED, unsigned int end HB_UNUSED)
|
unsigned int start HB_UNUSED, unsigned int end HB_UNUSED)
|
||||||
{
|
{
|
||||||
/* Nothing to do right now. If we ever switch to using the output
|
/* Nothing to do right now. If we ever switch to using the output
|
||||||
* buffer in the reordering process, we'd need to next_glyph() here. */
|
* buffer in the reordering process, we'd need to next_glyph() here. */
|
||||||
@ -1208,7 +1235,7 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||||||
case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return;
|
case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return;
|
||||||
case vowel_syllable: initial_reordering_vowel_syllable (plan, face, buffer, start, end); return;
|
case vowel_syllable: initial_reordering_vowel_syllable (plan, face, buffer, start, end); return;
|
||||||
case standalone_cluster: initial_reordering_standalone_cluster (plan, face, buffer, start, end); return;
|
case standalone_cluster: initial_reordering_standalone_cluster (plan, face, buffer, start, end); return;
|
||||||
case avagraha_cluster: initial_reordering_avagraha_cluster (plan, face, buffer, start, end); return;
|
case symbol_cluster: initial_reordering_symbol_cluster (plan, face, buffer, start, end); return;
|
||||||
case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return;
|
case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return;
|
||||||
case non_indic_cluster: initial_reordering_non_indic_cluster (plan, face, buffer, start, end); return;
|
case non_indic_cluster: initial_reordering_non_indic_cluster (plan, face, buffer, start, end); return;
|
||||||
}
|
}
|
||||||
@ -1222,8 +1249,10 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||||||
/* Note: This loop is extra overhead, but should not be measurable. */
|
/* Note: This loop is extra overhead, but should not be measurable. */
|
||||||
bool has_broken_syllables = false;
|
bool has_broken_syllables = false;
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if ((buffer->info[i].syllable() & 0x0F) == broken_cluster) {
|
if ((info[i].syllable() & 0x0F) == broken_cluster)
|
||||||
|
{
|
||||||
has_broken_syllables = true;
|
has_broken_syllables = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1232,11 +1261,11 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||||||
|
|
||||||
|
|
||||||
hb_codepoint_t dottedcircle_glyph;
|
hb_codepoint_t dottedcircle_glyph;
|
||||||
if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph))
|
if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hb_glyph_info_t dottedcircle = {0};
|
hb_glyph_info_t dottedcircle = {0};
|
||||||
dottedcircle.codepoint = 0x25CC;
|
dottedcircle.codepoint = 0x25CCu;
|
||||||
set_indic_properties (dottedcircle);
|
set_indic_properties (dottedcircle);
|
||||||
dottedcircle.codepoint = dottedcircle_glyph;
|
dottedcircle.codepoint = dottedcircle_glyph;
|
||||||
|
|
||||||
@ -1256,6 +1285,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||||||
info.cluster = buffer->cur().cluster;
|
info.cluster = buffer->cur().cluster;
|
||||||
info.mask = buffer->cur().mask;
|
info.mask = buffer->cur().mask;
|
||||||
info.syllable() = buffer->cur().syllable();
|
info.syllable() = buffer->cur().syllable();
|
||||||
|
/* TODO Set glyph_props? */
|
||||||
|
|
||||||
/* Insert dottedcircle after possible Repha. */
|
/* Insert dottedcircle after possible Repha. */
|
||||||
while (buffer->idx < buffer->len &&
|
while (buffer->idx < buffer->len &&
|
||||||
@ -1302,6 +1332,27 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||||||
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
|
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
|
||||||
hb_glyph_info_t *info = buffer->info;
|
hb_glyph_info_t *info = buffer->info;
|
||||||
|
|
||||||
|
|
||||||
|
/* This function relies heavily on halant glyphs. Lots of ligation
|
||||||
|
* and possibly multiplication substitutions happened prior to this
|
||||||
|
* phase, and that might have messed up our properties. Recover
|
||||||
|
* from a particular case of that where we're fairly sure that a
|
||||||
|
* class of OT_H is desired but has been lost. */
|
||||||
|
if (indic_plan->virama_glyph)
|
||||||
|
{
|
||||||
|
unsigned int virama_glyph = indic_plan->virama_glyph;
|
||||||
|
for (unsigned int i = start; i < end; i++)
|
||||||
|
if (info[i].codepoint == virama_glyph &&
|
||||||
|
_hb_glyph_info_ligated (&info[i]) &&
|
||||||
|
_hb_glyph_info_multiplied (&info[i]))
|
||||||
|
{
|
||||||
|
/* This will make sure that this glyph passes is_halant_or_coeng() test. */
|
||||||
|
info[i].indic_category() = OT_H;
|
||||||
|
_hb_glyph_info_clear_ligated_and_multiplied (&info[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* 4. Final reordering:
|
/* 4. Final reordering:
|
||||||
*
|
*
|
||||||
* After the localized forms and basic shaping forms GSUB features have been
|
* After the localized forms and basic shaping forms GSUB features have been
|
||||||
@ -1310,21 +1361,45 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||||||
* cluster.
|
* cluster.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
bool try_pref = !!indic_plan->mask_array[PREF];
|
||||||
|
|
||||||
/* Find base again */
|
/* Find base again */
|
||||||
unsigned int base;
|
unsigned int base;
|
||||||
for (base = start; base < end; base++)
|
for (base = start; base < end; base++)
|
||||||
if (info[base].indic_position() >= POS_BASE_C) {
|
if (info[base].indic_position() >= POS_BASE_C)
|
||||||
|
{
|
||||||
|
if (try_pref && base + 1 < end && indic_plan->config->pref_len == 2)
|
||||||
|
{
|
||||||
|
for (unsigned int i = base + 1; i < end; i++)
|
||||||
|
if ((info[i].mask & indic_plan->mask_array[PREF]) != 0)
|
||||||
|
{
|
||||||
|
if (!(_hb_glyph_info_substituted (&info[i]) &&
|
||||||
|
_hb_glyph_info_ligated_and_didnt_multiply (&info[i])))
|
||||||
|
{
|
||||||
|
/* Ok, this was a 'pref' candidate but didn't form any.
|
||||||
|
* Base is around here... */
|
||||||
|
base = i;
|
||||||
|
while (base < end && is_halant_or_coeng (info[base]))
|
||||||
|
base++;
|
||||||
|
info[base].indic_position() = POS_BASE_C;
|
||||||
|
|
||||||
|
try_pref = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (start < base && info[base].indic_position() > POS_BASE_C)
|
if (start < base && info[base].indic_position() > POS_BASE_C)
|
||||||
base--;
|
base--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (base == end && start < base &&
|
if (base == end && start < base &&
|
||||||
info[base - 1].indic_category() != OT_ZWJ)
|
is_one_of (info[base - 1], FLAG (OT_ZWJ)))
|
||||||
base--;
|
|
||||||
while (start < base &&
|
|
||||||
(info[base].indic_category() == OT_H ||
|
|
||||||
info[base].indic_category() == OT_N))
|
|
||||||
base--;
|
base--;
|
||||||
|
if (base < end)
|
||||||
|
while (start < base &&
|
||||||
|
is_one_of (info[base], (FLAG (OT_N) | HALANT_OR_COENG_FLAGS)))
|
||||||
|
base--;
|
||||||
|
|
||||||
|
|
||||||
/* o Reorder matras:
|
/* o Reorder matras:
|
||||||
@ -1349,7 +1424,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||||||
if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL)
|
if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL)
|
||||||
{
|
{
|
||||||
while (new_pos > start &&
|
while (new_pos > start &&
|
||||||
!(is_one_of (info[new_pos], (FLAG (OT_M) | FLAG (OT_H) | FLAG (OT_Coeng)))))
|
!(is_one_of (info[new_pos], (FLAG (OT_M) | HALANT_OR_COENG_FLAGS))))
|
||||||
new_pos--;
|
new_pos--;
|
||||||
|
|
||||||
/* If we found no Halant we are done.
|
/* If we found no Halant we are done.
|
||||||
@ -1412,7 +1487,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||||||
if (start + 1 < end &&
|
if (start + 1 < end &&
|
||||||
info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
|
info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
|
||||||
((info[start].indic_category() == OT_Repha) ^
|
((info[start].indic_category() == OT_Repha) ^
|
||||||
_hb_glyph_info_ligated (&info[start])))
|
_hb_glyph_info_ligated_and_didnt_multiply (&info[start])))
|
||||||
{
|
{
|
||||||
unsigned int new_reph_pos;
|
unsigned int new_reph_pos;
|
||||||
reph_position_t reph_pos = indic_plan->config->reph_pos;
|
reph_position_t reph_pos = indic_plan->config->reph_pos;
|
||||||
@ -1549,7 +1624,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||||||
* the following rules:
|
* the following rules:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (indic_plan->mask_array[PREF] && base + 1 < end) /* Otherwise there can't be any pre-base reordering Ra. */
|
if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base reordering Ra. */
|
||||||
{
|
{
|
||||||
unsigned int pref_len = indic_plan->config->pref_len;
|
unsigned int pref_len = indic_plan->config->pref_len;
|
||||||
for (unsigned int i = base + 1; i < end; i++)
|
for (unsigned int i = base + 1; i < end; i++)
|
||||||
@ -1565,7 +1640,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||||||
* If pref len is longer than one, then only reorder if it ligated. If
|
* If pref len is longer than one, then only reorder if it ligated. If
|
||||||
* pref len is one, only reorder if it didn't ligate with other things. */
|
* pref len is one, only reorder if it didn't ligate with other things. */
|
||||||
if (_hb_glyph_info_substituted (&info[i]) &&
|
if (_hb_glyph_info_substituted (&info[i]) &&
|
||||||
((pref_len == 1) ^ _hb_glyph_info_ligated (&info[i])))
|
((pref_len == 1) ^ _hb_glyph_info_ligated_and_didnt_multiply (&info[i])))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* 2. Try to find a target position the same way as for pre-base matra.
|
* 2. Try to find a target position the same way as for pre-base matra.
|
||||||
@ -1699,37 +1774,37 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c,
|
|||||||
switch (ab)
|
switch (ab)
|
||||||
{
|
{
|
||||||
/* Don't decompose these. */
|
/* Don't decompose these. */
|
||||||
case 0x0931 : return false;
|
case 0x0931u : return false;
|
||||||
case 0x0B94 : return false;
|
case 0x0B94u : return false;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decompose split matras that don't have Unicode decompositions.
|
* Decompose split matras that don't have Unicode decompositions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case 0x0F77 : *a = 0x0FB2; *b= 0x0F81; return true;
|
case 0x0F77u : *a = 0x0FB2u; *b= 0x0F81u; return true;
|
||||||
case 0x0F79 : *a = 0x0FB3; *b= 0x0F81; return true;
|
case 0x0F79u : *a = 0x0FB3u; *b= 0x0F81u; return true;
|
||||||
case 0x17BE : *a = 0x17C1; *b= 0x17BE; return true;
|
case 0x17BEu : *a = 0x17C1u; *b= 0x17BEu; return true;
|
||||||
case 0x17BF : *a = 0x17C1; *b= 0x17BF; return true;
|
case 0x17BFu : *a = 0x17C1u; *b= 0x17BFu; return true;
|
||||||
case 0x17C0 : *a = 0x17C1; *b= 0x17C0; return true;
|
case 0x17C0u : *a = 0x17C1u; *b= 0x17C0u; return true;
|
||||||
case 0x17C4 : *a = 0x17C1; *b= 0x17C4; return true;
|
case 0x17C4u : *a = 0x17C1u; *b= 0x17C4u; return true;
|
||||||
case 0x17C5 : *a = 0x17C1; *b= 0x17C5; return true;
|
case 0x17C5u : *a = 0x17C1u; *b= 0x17C5u; return true;
|
||||||
case 0x1925 : *a = 0x1920; *b= 0x1923; return true;
|
case 0x1925u : *a = 0x1920u; *b= 0x1923u; return true;
|
||||||
case 0x1926 : *a = 0x1920; *b= 0x1924; return true;
|
case 0x1926u : *a = 0x1920u; *b= 0x1924u; return true;
|
||||||
case 0x1B3C : *a = 0x1B42; *b= 0x1B3C; return true;
|
case 0x1B3Cu : *a = 0x1B42u; *b= 0x1B3Cu; return true;
|
||||||
case 0x1112E : *a = 0x11127; *b= 0x11131; return true;
|
case 0x1112Eu : *a = 0x11127u; *b= 0x11131u; return true;
|
||||||
case 0x1112F : *a = 0x11127; *b= 0x11132; return true;
|
case 0x1112Fu : *a = 0x11127u; *b= 0x11132u; return true;
|
||||||
#if 0
|
#if 0
|
||||||
/* This one has no decomposition in Unicode, but needs no decomposition either. */
|
/* This one has no decomposition in Unicode, but needs no decomposition either. */
|
||||||
/* case 0x0AC9 : return false; */
|
/* case 0x0AC9u : return false; */
|
||||||
case 0x0B57 : *a = no decomp, -> RIGHT; return true;
|
case 0x0B57u : *a = no decomp, -> RIGHT; return true;
|
||||||
case 0x1C29 : *a = no decomp, -> LEFT; return true;
|
case 0x1C29u : *a = no decomp, -> LEFT; return true;
|
||||||
case 0xA9C0 : *a = no decomp, -> RIGHT; return true;
|
case 0xA9C0u : *a = no decomp, -> RIGHT; return true;
|
||||||
case 0x111BF : *a = no decomp, -> ABOVE; return true;
|
case 0x111BuF : *a = no decomp, -> ABOVE; return true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ab == 0x0DDA || hb_in_range<hb_codepoint_t> (ab, 0x0DDC, 0x0DDE)))
|
if ((ab == 0x0DDAu || hb_in_range (ab, 0x0DDCu, 0x0DDEu)))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Sinhala split matras... Let the fun begin.
|
* Sinhala split matras... Let the fun begin.
|
||||||
@ -1766,7 +1841,7 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c,
|
|||||||
indic_plan->pstf.would_substitute (&glyph, 1, c->font->face)))
|
indic_plan->pstf.would_substitute (&glyph, 1, c->font->face)))
|
||||||
{
|
{
|
||||||
/* Ok, safe to use Uniscribe-style decomposition. */
|
/* Ok, safe to use Uniscribe-style decomposition. */
|
||||||
*a = 0x0DD9;
|
*a = 0x0DD9u;
|
||||||
*b = ab;
|
*b = ab;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1786,7 +1861,7 @@ compose_indic (const hb_ot_shape_normalize_context_t *c,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Composition-exclusion exceptions that we want to recompose. */
|
/* Composition-exclusion exceptions that we want to recompose. */
|
||||||
if (a == 0x09AF && b == 0x09BC) { *ab = 0x09DF; return true; }
|
if (a == 0x09AFu && b == 0x09BCu) { *ab = 0x09DFu; return true; }
|
||||||
|
|
||||||
return c->unicode->compose (a, b, ab);
|
return c->unicode->compose (a, b, ab);
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ static const short _myanmar_syllable_machine_index_offsets[] = {
|
|||||||
|
|
||||||
static const char _myanmar_syllable_machine_indicies[] = {
|
static const char _myanmar_syllable_machine_indicies[] = {
|
||||||
1, 1, 2, 3, 4, 4, 0, 5,
|
1, 1, 2, 3, 4, 4, 0, 5,
|
||||||
0, 6, 0, 1, 0, 0, 0, 7,
|
0, 6, 1, 0, 0, 0, 0, 7,
|
||||||
0, 8, 1, 0, 9, 10, 11, 12,
|
0, 8, 1, 0, 9, 10, 11, 12,
|
||||||
13, 14, 15, 16, 17, 18, 19, 0,
|
13, 14, 15, 16, 17, 18, 19, 0,
|
||||||
21, 22, 23, 23, 20, 24, 20, 25,
|
21, 22, 23, 23, 20, 24, 20, 25,
|
||||||
@ -119,14 +119,14 @@ static const char _myanmar_syllable_machine_indicies[] = {
|
|||||||
20, 20, 20, 20, 20, 20, 20, 20,
|
20, 20, 20, 20, 20, 20, 20, 20,
|
||||||
20, 31, 20, 33, 20, 35, 20, 21,
|
20, 31, 20, 33, 20, 35, 20, 21,
|
||||||
20, 23, 23, 20, 24, 20, 25, 20,
|
20, 23, 23, 20, 24, 20, 25, 20,
|
||||||
20, 20, 20, 20, 20, 20, 20, 20,
|
20, 20, 20, 20, 20, 20, 34, 20,
|
||||||
20, 27, 20, 29, 20, 31, 32, 33,
|
20, 27, 20, 29, 20, 31, 32, 33,
|
||||||
34, 35, 20, 21, 20, 23, 23, 20,
|
34, 35, 20, 21, 20, 23, 23, 20,
|
||||||
24, 20, 25, 20, 20, 20, 20, 20,
|
24, 20, 25, 20, 20, 20, 20, 20,
|
||||||
20, 20, 34, 20, 20, 27, 20, 20,
|
20, 20, 34, 20, 20, 27, 20, 20,
|
||||||
20, 31, 32, 33, 34, 35, 20, 21,
|
20, 31, 32, 33, 34, 35, 20, 21,
|
||||||
20, 23, 23, 20, 24, 20, 25, 20,
|
20, 23, 23, 20, 24, 20, 25, 20,
|
||||||
20, 20, 20, 20, 20, 20, 20, 20,
|
20, 20, 20, 20, 20, 20, 34, 20,
|
||||||
20, 27, 28, 29, 20, 31, 32, 33,
|
20, 27, 28, 29, 20, 31, 32, 33,
|
||||||
34, 35, 20, 21, 22, 23, 23, 20,
|
34, 35, 20, 21, 22, 23, 23, 20,
|
||||||
24, 20, 25, 20, 20, 20, 20, 20,
|
24, 20, 25, 20, 20, 20, 20, 20,
|
||||||
@ -169,8 +169,8 @@ static const char _myanmar_syllable_machine_indicies[] = {
|
|||||||
25, 20, 20, 20, 20, 20, 20, 20,
|
25, 20, 20, 20, 20, 20, 20, 20,
|
||||||
26, 20, 20, 27, 28, 29, 30, 31,
|
26, 20, 20, 27, 28, 29, 30, 31,
|
||||||
32, 33, 34, 35, 20, 1, 1, 2,
|
32, 33, 34, 35, 20, 1, 1, 2,
|
||||||
3, 3, 3, 42, 5, 42, 6, 42,
|
3, 3, 3, 42, 5, 42, 6, 1,
|
||||||
1, 42, 42, 42, 1, 42, 8, 1,
|
42, 42, 42, 42, 1, 42, 8, 1,
|
||||||
42, 9, 10, 11, 12, 13, 14, 15,
|
42, 9, 10, 11, 12, 13, 14, 15,
|
||||||
16, 17, 18, 42, 2, 42, 3, 3,
|
16, 17, 18, 42, 2, 42, 3, 3,
|
||||||
42, 5, 42, 6, 42, 42, 42, 42,
|
42, 5, 42, 6, 42, 42, 42, 42,
|
||||||
@ -191,14 +191,14 @@ static const char _myanmar_syllable_machine_indicies[] = {
|
|||||||
42, 42, 42, 42, 42, 42, 42, 42,
|
42, 42, 42, 42, 42, 42, 42, 42,
|
||||||
42, 42, 13, 42, 15, 42, 17, 42,
|
42, 42, 13, 42, 15, 42, 17, 42,
|
||||||
2, 42, 3, 3, 42, 5, 42, 6,
|
2, 42, 3, 3, 42, 5, 42, 6,
|
||||||
42, 42, 42, 42, 42, 42, 42, 42,
|
42, 42, 42, 42, 42, 42, 42, 16,
|
||||||
42, 42, 9, 42, 11, 42, 13, 14,
|
42, 42, 9, 42, 11, 42, 13, 14,
|
||||||
15, 16, 17, 42, 2, 42, 3, 3,
|
15, 16, 17, 42, 2, 42, 3, 3,
|
||||||
42, 5, 42, 6, 42, 42, 42, 42,
|
42, 5, 42, 6, 42, 42, 42, 42,
|
||||||
42, 42, 42, 16, 42, 42, 9, 42,
|
42, 42, 42, 16, 42, 42, 9, 42,
|
||||||
42, 42, 13, 14, 15, 16, 17, 42,
|
42, 42, 13, 14, 15, 16, 17, 42,
|
||||||
2, 42, 3, 3, 42, 5, 42, 6,
|
2, 42, 3, 3, 42, 5, 42, 6,
|
||||||
42, 42, 42, 42, 42, 42, 42, 42,
|
42, 42, 42, 42, 42, 42, 42, 16,
|
||||||
42, 42, 9, 10, 11, 42, 13, 14,
|
42, 42, 9, 10, 11, 42, 13, 14,
|
||||||
15, 16, 17, 42, 2, 3, 3, 3,
|
15, 16, 17, 42, 2, 3, 3, 3,
|
||||||
42, 5, 42, 6, 42, 42, 42, 42,
|
42, 5, 42, 6, 42, 42, 42, 42,
|
||||||
|
@ -44,7 +44,7 @@ C = 1;
|
|||||||
D = 19;
|
D = 19;
|
||||||
D0 = 20;
|
D0 = 20;
|
||||||
DB = 3;
|
DB = 3;
|
||||||
GB = 12;
|
GB = 11;
|
||||||
H = 4;
|
H = 4;
|
||||||
IV = 2;
|
IV = 2;
|
||||||
MH = 21;
|
MH = 21;
|
||||||
@ -68,7 +68,7 @@ k = (Ra As H); # Kinzi
|
|||||||
|
|
||||||
c = C|Ra; # is_consonant
|
c = C|Ra; # is_consonant
|
||||||
|
|
||||||
medial_group = MY? MR? ((MW MH? | MH) As?)?;
|
medial_group = MY? MR? MW? MH? As?;
|
||||||
main_vowel_group = VPre* VAbv* VBlw* A* (DB As?)?;
|
main_vowel_group = VPre* VAbv* VBlw* A* (DB As?)?;
|
||||||
post_vowel_group = VPst MH? As* VAbv* A* (DB As?)?;
|
post_vowel_group = VPst MH? As* VAbv* A* (DB As?)?;
|
||||||
pwo_tone_group = PT A* DB? As?;
|
pwo_tone_group = PT A* DB? As?;
|
||||||
|
@ -134,7 +134,7 @@ enum myanmar_category_t {
|
|||||||
OT_D = 19, /* Digits except zero */
|
OT_D = 19, /* Digits except zero */
|
||||||
OT_D0 = 20, /* Digit zero */
|
OT_D0 = 20, /* Digit zero */
|
||||||
OT_DB = OT_N, /* Dot below */
|
OT_DB = OT_N, /* Dot below */
|
||||||
OT_GB = OT_DOTTEDCIRCLE,
|
OT_GB = OT_PLACEHOLDER,
|
||||||
OT_MH = 21, /* Various consonant medial types */
|
OT_MH = 21, /* Various consonant medial types */
|
||||||
OT_MR = 22, /* Various consonant medial types */
|
OT_MR = 22, /* Various consonant medial types */
|
||||||
OT_MW = 23, /* Various consonant medial types */
|
OT_MW = 23, /* Various consonant medial types */
|
||||||
@ -157,12 +157,6 @@ is_one_of (const hb_glyph_info_t &info, unsigned int flags)
|
|||||||
return !!(FLAG (info.myanmar_category()) & flags);
|
return !!(FLAG (info.myanmar_category()) & flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note:
|
|
||||||
*
|
|
||||||
* We treat Vowels and placeholders as if they were consonants. This is safe because Vowels
|
|
||||||
* cannot happen in a consonant syllable. The plus side however is, we can call the
|
|
||||||
* consonant syllable logic from the vowel syllable function and get it all right! */
|
|
||||||
#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CM) | FLAG (OT_Ra) | FLAG (OT_V) | FLAG (OT_NBSP) | FLAG (OT_GB))
|
|
||||||
static inline bool
|
static inline bool
|
||||||
is_consonant (const hb_glyph_info_t &info)
|
is_consonant (const hb_glyph_info_t &info)
|
||||||
{
|
{
|
||||||
@ -175,82 +169,80 @@ set_myanmar_properties (hb_glyph_info_t &info)
|
|||||||
{
|
{
|
||||||
hb_codepoint_t u = info.codepoint;
|
hb_codepoint_t u = info.codepoint;
|
||||||
unsigned int type = hb_indic_get_categories (u);
|
unsigned int type = hb_indic_get_categories (u);
|
||||||
indic_category_t cat = (indic_category_t) (type & 0x7F);
|
indic_category_t cat = (indic_category_t) (type & 0x7Fu);
|
||||||
indic_position_t pos = (indic_position_t) (type >> 8);
|
indic_position_t pos = (indic_position_t) (type >> 8);
|
||||||
|
|
||||||
/* Myanmar
|
/* Myanmar
|
||||||
* http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm#analyze
|
* http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm#analyze
|
||||||
*/
|
*/
|
||||||
if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xFE00, 0xFE0F)))
|
if (unlikely (hb_in_range (u, 0xFE00u, 0xFE0Fu)))
|
||||||
cat = (indic_category_t) OT_VS;
|
cat = (indic_category_t) OT_VS;
|
||||||
else if (unlikely (u == 0x200C)) cat = (indic_category_t) OT_ZWNJ;
|
|
||||||
else if (unlikely (u == 0x200D)) cat = (indic_category_t) OT_ZWJ;
|
|
||||||
|
|
||||||
switch (u)
|
switch (u)
|
||||||
{
|
{
|
||||||
case 0x104E:
|
case 0x104Eu:
|
||||||
cat = (indic_category_t) OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */
|
cat = (indic_category_t) OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x002D: case 0x00A0: case 0x00D7: case 0x2012:
|
case 0x002Du: case 0x00A0u: case 0x00D7u: case 0x2012u:
|
||||||
case 0x2013: case 0x2014: case 0x2015: case 0x2022:
|
case 0x2013u: case 0x2014u: case 0x2015u: case 0x2022u:
|
||||||
case 0x25CC: case 0x25FB: case 0x25FC: case 0x25FD:
|
case 0x25CCu: case 0x25FBu: case 0x25FCu: case 0x25FDu:
|
||||||
case 0x25FE:
|
case 0x25FEu:
|
||||||
cat = (indic_category_t) OT_GB;
|
cat = (indic_category_t) OT_GB;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1004: case 0x101B: case 0x105A:
|
case 0x1004u: case 0x101Bu: case 0x105Au:
|
||||||
cat = (indic_category_t) OT_Ra;
|
cat = (indic_category_t) OT_Ra;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1032: case 0x1036:
|
case 0x1032u: case 0x1036u:
|
||||||
cat = (indic_category_t) OT_A;
|
cat = (indic_category_t) OT_A;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x103A:
|
case 0x103Au:
|
||||||
cat = (indic_category_t) OT_As;
|
cat = (indic_category_t) OT_As;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1041: case 0x1042: case 0x1043: case 0x1044:
|
case 0x1041u: case 0x1042u: case 0x1043u: case 0x1044u:
|
||||||
case 0x1045: case 0x1046: case 0x1047: case 0x1048:
|
case 0x1045u: case 0x1046u: case 0x1047u: case 0x1048u:
|
||||||
case 0x1049: case 0x1090: case 0x1091: case 0x1092:
|
case 0x1049u: case 0x1090u: case 0x1091u: case 0x1092u:
|
||||||
case 0x1093: case 0x1094: case 0x1095: case 0x1096:
|
case 0x1093u: case 0x1094u: case 0x1095u: case 0x1096u:
|
||||||
case 0x1097: case 0x1098: case 0x1099:
|
case 0x1097u: case 0x1098u: case 0x1099u:
|
||||||
cat = (indic_category_t) OT_D;
|
cat = (indic_category_t) OT_D;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1040:
|
case 0x1040u:
|
||||||
cat = (indic_category_t) OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */
|
cat = (indic_category_t) OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x103E: case 0x1060:
|
case 0x103Eu: case 0x1060u:
|
||||||
cat = (indic_category_t) OT_MH;
|
cat = (indic_category_t) OT_MH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x103C:
|
case 0x103Cu:
|
||||||
cat = (indic_category_t) OT_MR;
|
cat = (indic_category_t) OT_MR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x103D: case 0x1082:
|
case 0x103Du: case 0x1082u:
|
||||||
cat = (indic_category_t) OT_MW;
|
cat = (indic_category_t) OT_MW;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x103B: case 0x105E: case 0x105F:
|
case 0x103Bu: case 0x105Eu: case 0x105Fu:
|
||||||
cat = (indic_category_t) OT_MY;
|
cat = (indic_category_t) OT_MY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1063: case 0x1064: case 0x1069: case 0x106A:
|
case 0x1063u: case 0x1064u: case 0x1069u: case 0x106Au:
|
||||||
case 0x106B: case 0x106C: case 0x106D: case 0xAA7B:
|
case 0x106Bu: case 0x106Cu: case 0x106Du: case 0xAA7Bu:
|
||||||
cat = (indic_category_t) OT_PT;
|
cat = (indic_category_t) OT_PT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1038: case 0x1087: case 0x1088: case 0x1089:
|
case 0x1038u: case 0x1087u: case 0x1088u: case 0x1089u:
|
||||||
case 0x108A: case 0x108B: case 0x108C: case 0x108D:
|
case 0x108Au: case 0x108Bu: case 0x108Cu: case 0x108Du:
|
||||||
case 0x108F: case 0x109A: case 0x109B: case 0x109C:
|
case 0x108Fu: case 0x109Au: case 0x109Bu: case 0x109Cu:
|
||||||
cat = (indic_category_t) OT_SM;
|
cat = (indic_category_t) OT_SM;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x104A: case 0x104B:
|
case 0x104Au: case 0x104Bu:
|
||||||
cat = (indic_category_t) OT_P;
|
cat = (indic_category_t) OT_P;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -285,8 +277,9 @@ setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||||||
* and setup masks later on in a pause-callback. */
|
* and setup masks later on in a pause-callback. */
|
||||||
|
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
set_myanmar_properties (buffer->info[i]);
|
set_myanmar_properties (info[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -459,8 +452,10 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||||||
/* Note: This loop is extra overhead, but should not be measurable. */
|
/* Note: This loop is extra overhead, but should not be measurable. */
|
||||||
bool has_broken_syllables = false;
|
bool has_broken_syllables = false;
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if ((buffer->info[i].syllable() & 0x0F) == broken_cluster) {
|
if ((info[i].syllable() & 0x0F) == broken_cluster)
|
||||||
|
{
|
||||||
has_broken_syllables = true;
|
has_broken_syllables = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -469,11 +464,11 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||||||
|
|
||||||
|
|
||||||
hb_codepoint_t dottedcircle_glyph;
|
hb_codepoint_t dottedcircle_glyph;
|
||||||
if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph))
|
if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hb_glyph_info_t dottedcircle = {0};
|
hb_glyph_info_t dottedcircle = {0};
|
||||||
dottedcircle.codepoint = 0x25CC;
|
dottedcircle.codepoint = 0x25CCu;
|
||||||
set_myanmar_properties (dottedcircle);
|
set_myanmar_properties (dottedcircle);
|
||||||
dottedcircle.codepoint = dottedcircle_glyph;
|
dottedcircle.codepoint = dottedcircle_glyph;
|
||||||
|
|
||||||
@ -541,6 +536,24 @@ final_reordering (const hb_ot_shape_plan_t *plan,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Uniscribe seems to have a shaper for 'mymr' that is like the
|
||||||
|
* generic shaper, except that it zeros mark advances GDEF_LATE. */
|
||||||
|
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_old =
|
||||||
|
{
|
||||||
|
"default",
|
||||||
|
NULL, /* collect_features */
|
||||||
|
NULL, /* override_features */
|
||||||
|
NULL, /* data_create */
|
||||||
|
NULL, /* data_destroy */
|
||||||
|
NULL, /* preprocess_text */
|
||||||
|
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
|
||||||
|
NULL, /* decompose */
|
||||||
|
NULL, /* compose */
|
||||||
|
NULL, /* setup_masks */
|
||||||
|
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
|
||||||
|
true, /* fallback_position */
|
||||||
|
};
|
||||||
|
|
||||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
|
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
|
||||||
{
|
{
|
||||||
"myanmar",
|
"myanmar",
|
||||||
|
@ -56,6 +56,7 @@ enum hb_ot_shape_zero_width_marks_type_t {
|
|||||||
HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \
|
HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \
|
||||||
HB_COMPLEX_SHAPER_IMPLEMENT (hangul) \
|
HB_COMPLEX_SHAPER_IMPLEMENT (hangul) \
|
||||||
HB_COMPLEX_SHAPER_IMPLEMENT (hebrew) \
|
HB_COMPLEX_SHAPER_IMPLEMENT (hebrew) \
|
||||||
|
HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_old) \
|
||||||
HB_COMPLEX_SHAPER_IMPLEMENT (indic) \
|
HB_COMPLEX_SHAPER_IMPLEMENT (indic) \
|
||||||
HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \
|
HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \
|
||||||
HB_COMPLEX_SHAPER_IMPLEMENT (sea) \
|
HB_COMPLEX_SHAPER_IMPLEMENT (sea) \
|
||||||
@ -173,6 +174,10 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
|
|||||||
/* Unicode-6.0 additions */
|
/* Unicode-6.0 additions */
|
||||||
case HB_SCRIPT_MANDAIC:
|
case HB_SCRIPT_MANDAIC:
|
||||||
|
|
||||||
|
/* Unicode-7.0 additions */
|
||||||
|
case HB_SCRIPT_MANICHAEAN:
|
||||||
|
case HB_SCRIPT_PSALTER_PAHLAVI:
|
||||||
|
|
||||||
/* For Arabic script, use the Arabic shaper even if no OT script tag was found.
|
/* For Arabic script, use the Arabic shaper even if no OT script tag was found.
|
||||||
* This is because we do fallback shaping for Arabic script (and not others). */
|
* This is because we do fallback shaping for Arabic script (and not others). */
|
||||||
if (planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT ||
|
if (planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT ||
|
||||||
@ -325,10 +330,10 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
|
|||||||
return &_hb_ot_complex_shaper_default;
|
return &_hb_ot_complex_shaper_default;
|
||||||
|
|
||||||
case HB_SCRIPT_MYANMAR:
|
case HB_SCRIPT_MYANMAR:
|
||||||
/* For Myanmar, we only want to use the Myanmar shaper if the "new" script
|
|
||||||
* tag is found. For "old" script tag we want to use the default shaper. */
|
|
||||||
if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2'))
|
if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2'))
|
||||||
return &_hb_ot_complex_shaper_myanmar;
|
return &_hb_ot_complex_shaper_myanmar;
|
||||||
|
else if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','r'))
|
||||||
|
return &_hb_ot_complex_shaper_myanmar_old;
|
||||||
else
|
else
|
||||||
return &_hb_ot_complex_shaper_default;
|
return &_hb_ot_complex_shaper_default;
|
||||||
|
|
||||||
|
@ -139,11 +139,11 @@ set_sea_properties (hb_glyph_info_t &info)
|
|||||||
{
|
{
|
||||||
hb_codepoint_t u = info.codepoint;
|
hb_codepoint_t u = info.codepoint;
|
||||||
unsigned int type = hb_indic_get_categories (u);
|
unsigned int type = hb_indic_get_categories (u);
|
||||||
indic_category_t cat = (indic_category_t) (type & 0x7F);
|
indic_category_t cat = (indic_category_t) (type & 0x7Fu);
|
||||||
indic_position_t pos = (indic_position_t) (type >> 8);
|
indic_position_t pos = (indic_position_t) (type >> 8);
|
||||||
|
|
||||||
/* Medial Ra */
|
/* Medial Ra */
|
||||||
if (u == 0x1A55 || u == 0xAA34)
|
if (u == 0x1A55u || u == 0xAA34u)
|
||||||
cat = (indic_category_t) OT_MR;
|
cat = (indic_category_t) OT_MR;
|
||||||
|
|
||||||
if (cat == OT_M)
|
if (cat == OT_M)
|
||||||
@ -174,8 +174,9 @@ setup_masks_sea (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||||||
* and setup masks later on in a pause-callback. */
|
* and setup masks later on in a pause-callback. */
|
||||||
|
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
set_sea_properties (buffer->info[i]);
|
set_sea_properties (info[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -278,8 +279,10 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||||||
/* Note: This loop is extra overhead, but should not be measurable. */
|
/* Note: This loop is extra overhead, but should not be measurable. */
|
||||||
bool has_broken_syllables = false;
|
bool has_broken_syllables = false;
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if ((buffer->info[i].syllable() & 0x0F) == broken_cluster) {
|
if ((info[i].syllable() & 0x0F) == broken_cluster)
|
||||||
|
{
|
||||||
has_broken_syllables = true;
|
has_broken_syllables = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -288,11 +291,11 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||||||
|
|
||||||
|
|
||||||
hb_codepoint_t dottedcircle_glyph;
|
hb_codepoint_t dottedcircle_glyph;
|
||||||
if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph))
|
if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hb_glyph_info_t dottedcircle = {0};
|
hb_glyph_info_t dottedcircle = {0};
|
||||||
dottedcircle.codepoint = 0x25CC;
|
dottedcircle.codepoint = 0x25CCu;
|
||||||
set_sea_properties (dottedcircle);
|
set_sea_properties (dottedcircle);
|
||||||
dottedcircle.codepoint = dottedcircle_glyph;
|
dottedcircle.codepoint = dottedcircle_glyph;
|
||||||
|
|
||||||
|
@ -46,13 +46,13 @@ enum thai_consonant_type_t
|
|||||||
static thai_consonant_type_t
|
static thai_consonant_type_t
|
||||||
get_consonant_type (hb_codepoint_t u)
|
get_consonant_type (hb_codepoint_t u)
|
||||||
{
|
{
|
||||||
if (u == 0x0E1B || u == 0x0E1D || u == 0x0E1F/* || u == 0x0E2C*/)
|
if (u == 0x0E1Bu || u == 0x0E1Du || u == 0x0E1Fu/* || u == 0x0E2Cu*/)
|
||||||
return AC;
|
return AC;
|
||||||
if (u == 0x0E0D || u == 0x0E10)
|
if (u == 0x0E0Du || u == 0x0E10u)
|
||||||
return RC;
|
return RC;
|
||||||
if (u == 0x0E0E || u == 0x0E0F)
|
if (u == 0x0E0Eu || u == 0x0E0Fu)
|
||||||
return DC;
|
return DC;
|
||||||
if (hb_in_range<hb_codepoint_t> (u, 0x0E01, 0x0E2E))
|
if (hb_in_range (u, 0x0E01u, 0x0E2Eu))
|
||||||
return NC;
|
return NC;
|
||||||
return NOT_CONSONANT;
|
return NOT_CONSONANT;
|
||||||
}
|
}
|
||||||
@ -70,12 +70,12 @@ enum thai_mark_type_t
|
|||||||
static thai_mark_type_t
|
static thai_mark_type_t
|
||||||
get_mark_type (hb_codepoint_t u)
|
get_mark_type (hb_codepoint_t u)
|
||||||
{
|
{
|
||||||
if (u == 0x0E31 || hb_in_range<hb_codepoint_t> (u, 0x0E34, 0x0E37) ||
|
if (u == 0x0E31u || hb_in_range (u, 0x0E34u, 0x0E37u) ||
|
||||||
u == 0x0E47 || hb_in_range<hb_codepoint_t> (u, 0x0E4D, 0x0E4E))
|
u == 0x0E47u || hb_in_range (u, 0x0E4Du, 0x0E4Eu))
|
||||||
return AV;
|
return AV;
|
||||||
if (hb_in_range<hb_codepoint_t> (u, 0x0E38, 0x0E3A))
|
if (hb_in_range (u, 0x0E38u, 0x0E3Au))
|
||||||
return BV;
|
return BV;
|
||||||
if (hb_in_range<hb_codepoint_t> (u, 0x0E48, 0x0E4C))
|
if (hb_in_range (u, 0x0E48u, 0x0E4Cu))
|
||||||
return T;
|
return T;
|
||||||
return NOT_MARK;
|
return NOT_MARK;
|
||||||
}
|
}
|
||||||
@ -99,43 +99,43 @@ thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font)
|
|||||||
hb_codepoint_t mac_pua;
|
hb_codepoint_t mac_pua;
|
||||||
} const *pua_mappings = NULL;
|
} const *pua_mappings = NULL;
|
||||||
static const thai_pua_mapping_t SD_mappings[] = {
|
static const thai_pua_mapping_t SD_mappings[] = {
|
||||||
{0x0E48, 0xF70A, 0xF88B}, /* MAI EK */
|
{0x0E48u, 0xF70Au, 0xF88Bu}, /* MAI EK */
|
||||||
{0x0E49, 0xF70B, 0xF88E}, /* MAI THO */
|
{0x0E49u, 0xF70Bu, 0xF88Eu}, /* MAI THO */
|
||||||
{0x0E4A, 0xF70C, 0xF891}, /* MAI TRI */
|
{0x0E4Au, 0xF70Cu, 0xF891u}, /* MAI TRI */
|
||||||
{0x0E4B, 0xF70D, 0xF894}, /* MAI CHATTAWA */
|
{0x0E4Bu, 0xF70Du, 0xF894u}, /* MAI CHATTAWA */
|
||||||
{0x0E4C, 0xF70E, 0xF897}, /* THANTHAKHAT */
|
{0x0E4Cu, 0xF70Eu, 0xF897u}, /* THANTHAKHAT */
|
||||||
{0x0E38, 0xF718, 0xF89B}, /* SARA U */
|
{0x0E38u, 0xF718u, 0xF89Bu}, /* SARA U */
|
||||||
{0x0E39, 0xF719, 0xF89C}, /* SARA UU */
|
{0x0E39u, 0xF719u, 0xF89Cu}, /* SARA UU */
|
||||||
{0x0E3A, 0xF71A, 0xF89D}, /* PHINTHU */
|
{0x0E3Au, 0xF71Au, 0xF89Du}, /* PHINTHU */
|
||||||
{0x0000, 0x0000, 0x0000}
|
{0x0000u, 0x0000u, 0x0000u}
|
||||||
};
|
};
|
||||||
static const thai_pua_mapping_t SDL_mappings[] = {
|
static const thai_pua_mapping_t SDL_mappings[] = {
|
||||||
{0x0E48, 0xF705, 0xF88C}, /* MAI EK */
|
{0x0E48u, 0xF705u, 0xF88Cu}, /* MAI EK */
|
||||||
{0x0E49, 0xF706, 0xF88F}, /* MAI THO */
|
{0x0E49u, 0xF706u, 0xF88Fu}, /* MAI THO */
|
||||||
{0x0E4A, 0xF707, 0xF892}, /* MAI TRI */
|
{0x0E4Au, 0xF707u, 0xF892u}, /* MAI TRI */
|
||||||
{0x0E4B, 0xF708, 0xF895}, /* MAI CHATTAWA */
|
{0x0E4Bu, 0xF708u, 0xF895u}, /* MAI CHATTAWA */
|
||||||
{0x0E4C, 0xF709, 0xF898}, /* THANTHAKHAT */
|
{0x0E4Cu, 0xF709u, 0xF898u}, /* THANTHAKHAT */
|
||||||
{0x0000, 0x0000, 0x0000}
|
{0x0000u, 0x0000u, 0x0000u}
|
||||||
};
|
};
|
||||||
static const thai_pua_mapping_t SL_mappings[] = {
|
static const thai_pua_mapping_t SL_mappings[] = {
|
||||||
{0x0E48, 0xF713, 0xF88A}, /* MAI EK */
|
{0x0E48u, 0xF713u, 0xF88Au}, /* MAI EK */
|
||||||
{0x0E49, 0xF714, 0xF88D}, /* MAI THO */
|
{0x0E49u, 0xF714u, 0xF88Du}, /* MAI THO */
|
||||||
{0x0E4A, 0xF715, 0xF890}, /* MAI TRI */
|
{0x0E4Au, 0xF715u, 0xF890u}, /* MAI TRI */
|
||||||
{0x0E4B, 0xF716, 0xF893}, /* MAI CHATTAWA */
|
{0x0E4Bu, 0xF716u, 0xF893u}, /* MAI CHATTAWA */
|
||||||
{0x0E4C, 0xF717, 0xF896}, /* THANTHAKHAT */
|
{0x0E4Cu, 0xF717u, 0xF896u}, /* THANTHAKHAT */
|
||||||
{0x0E31, 0xF710, 0xF884}, /* MAI HAN-AKAT */
|
{0x0E31u, 0xF710u, 0xF884u}, /* MAI HAN-AKAT */
|
||||||
{0x0E34, 0xF701, 0xF885}, /* SARA I */
|
{0x0E34u, 0xF701u, 0xF885u}, /* SARA I */
|
||||||
{0x0E35, 0xF702, 0xF886}, /* SARA II */
|
{0x0E35u, 0xF702u, 0xF886u}, /* SARA II */
|
||||||
{0x0E36, 0xF703, 0xF887}, /* SARA UE */
|
{0x0E36u, 0xF703u, 0xF887u}, /* SARA UE */
|
||||||
{0x0E37, 0xF704, 0xF888}, /* SARA UEE */
|
{0x0E37u, 0xF704u, 0xF888u}, /* SARA UEE */
|
||||||
{0x0E47, 0xF712, 0xF889}, /* MAITAIKHU */
|
{0x0E47u, 0xF712u, 0xF889u}, /* MAITAIKHU */
|
||||||
{0x0E4D, 0xF711, 0xF899}, /* NIKHAHIT */
|
{0x0E4Du, 0xF711u, 0xF899u}, /* NIKHAHIT */
|
||||||
{0x0000, 0x0000, 0x0000}
|
{0x0000u, 0x0000u, 0x0000u}
|
||||||
};
|
};
|
||||||
static const thai_pua_mapping_t RD_mappings[] = {
|
static const thai_pua_mapping_t RD_mappings[] = {
|
||||||
{0x0E0D, 0xF70F, 0xF89A}, /* YO YING */
|
{0x0E0Du, 0xF70Fu, 0xF89Au}, /* YO YING */
|
||||||
{0x0E10, 0xF700, 0xF89E}, /* THO THAN */
|
{0x0E10u, 0xF700u, 0xF89Eu}, /* THO THAN */
|
||||||
{0x0000, 0x0000, 0x0000}
|
{0x0000u, 0x0000u, 0x0000u}
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
@ -308,10 +308,10 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
|
|||||||
|
|
||||||
/* We only get one script at a time, so a script-agnostic implementation
|
/* We only get one script at a time, so a script-agnostic implementation
|
||||||
* is adequate here. */
|
* is adequate here. */
|
||||||
#define IS_SARA_AM(x) (((x) & ~0x0080) == 0x0E33)
|
#define IS_SARA_AM(x) (((x) & ~0x0080u) == 0x0E33u)
|
||||||
#define NIKHAHIT_FROM_SARA_AM(x) ((x) - 0xE33 + 0xE4D)
|
#define NIKHAHIT_FROM_SARA_AM(x) ((x) - 0x0E33u + 0x0E4Du)
|
||||||
#define SARA_AA_FROM_SARA_AM(x) ((x) - 1)
|
#define SARA_AA_FROM_SARA_AM(x) ((x) - 1)
|
||||||
#define IS_TONE_MARK(x) (hb_in_ranges<hb_codepoint_t> ((x) & ~0x0080, 0x0E34, 0x0E37, 0x0E47, 0x0E4E, 0x0E31, 0x0E31))
|
#define IS_TONE_MARK(x) (hb_in_ranges ((x) & ~0x0080u, 0x0E34u, 0x0E37u, 0x0E47u, 0x0E4Eu, 0x0E31u, 0x0E31u))
|
||||||
|
|
||||||
buffer->clear_output ();
|
buffer->clear_output ();
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
@ -35,42 +35,42 @@ recategorize_combining_class (hb_codepoint_t u,
|
|||||||
return klass;
|
return klass;
|
||||||
|
|
||||||
/* Thai / Lao need some per-character work. */
|
/* Thai / Lao need some per-character work. */
|
||||||
if ((u & ~0xFF) == 0x0E00)
|
if ((u & ~0xFF) == 0x0E00u)
|
||||||
{
|
{
|
||||||
if (unlikely (klass == 0))
|
if (unlikely (klass == 0))
|
||||||
{
|
{
|
||||||
switch (u)
|
switch (u)
|
||||||
{
|
{
|
||||||
case 0x0E31:
|
case 0x0E31u:
|
||||||
case 0x0E34:
|
case 0x0E34u:
|
||||||
case 0x0E35:
|
case 0x0E35u:
|
||||||
case 0x0E36:
|
case 0x0E36u:
|
||||||
case 0x0E37:
|
case 0x0E37u:
|
||||||
case 0x0E47:
|
case 0x0E47u:
|
||||||
case 0x0E4C:
|
case 0x0E4Cu:
|
||||||
case 0x0E4D:
|
case 0x0E4Du:
|
||||||
case 0x0E4E:
|
case 0x0E4Eu:
|
||||||
klass = HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT;
|
klass = HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0EB1:
|
case 0x0EB1u:
|
||||||
case 0x0EB4:
|
case 0x0EB4u:
|
||||||
case 0x0EB5:
|
case 0x0EB5u:
|
||||||
case 0x0EB6:
|
case 0x0EB6u:
|
||||||
case 0x0EB7:
|
case 0x0EB7u:
|
||||||
case 0x0EBB:
|
case 0x0EBBu:
|
||||||
case 0x0ECC:
|
case 0x0ECCu:
|
||||||
case 0x0ECD:
|
case 0x0ECDu:
|
||||||
klass = HB_UNICODE_COMBINING_CLASS_ABOVE;
|
klass = HB_UNICODE_COMBINING_CLASS_ABOVE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0EBC:
|
case 0x0EBCu:
|
||||||
klass = HB_UNICODE_COMBINING_CLASS_BELOW;
|
klass = HB_UNICODE_COMBINING_CLASS_BELOW;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Thai virama is below-right */
|
/* Thai virama is below-right */
|
||||||
if (u == 0x0E3A)
|
if (u == 0x0E3Au)
|
||||||
klass = HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT;
|
klass = HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,11 +167,12 @@ _hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *pla
|
|||||||
hb_buffer_t *buffer)
|
hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) {
|
if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) {
|
||||||
unsigned int combining_class = _hb_glyph_info_get_modified_combining_class (&buffer->info[i]);
|
unsigned int combining_class = _hb_glyph_info_get_modified_combining_class (&info[i]);
|
||||||
combining_class = recategorize_combining_class (buffer->info[i].codepoint, combining_class);
|
combining_class = recategorize_combining_class (info[i].codepoint, combining_class);
|
||||||
_hb_glyph_info_set_modified_combining_class (&buffer->info[i], combining_class);
|
_hb_glyph_info_set_modified_combining_class (&info[i], combining_class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,8 +182,9 @@ zero_mark_advances (hb_buffer_t *buffer,
|
|||||||
unsigned int start,
|
unsigned int start,
|
||||||
unsigned int end)
|
unsigned int end)
|
||||||
{
|
{
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = start; i < end; i++)
|
for (unsigned int i = start; i < end; i++)
|
||||||
if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
|
if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
|
||||||
{
|
{
|
||||||
buffer->pos[i].x_advance = 0;
|
buffer->pos[i].x_advance = 0;
|
||||||
buffer->pos[i].y_advance = 0;
|
buffer->pos[i].y_advance = 0;
|
||||||
@ -327,12 +329,13 @@ position_around_base (const hb_ot_shape_plan_t *plan,
|
|||||||
unsigned int last_lig_component = (unsigned int) -1;
|
unsigned int last_lig_component = (unsigned int) -1;
|
||||||
unsigned int last_combining_class = 255;
|
unsigned int last_combining_class = 255;
|
||||||
hb_glyph_extents_t cluster_extents = base_extents; /* Initialization is just to shut gcc up. */
|
hb_glyph_extents_t cluster_extents = base_extents; /* Initialization is just to shut gcc up. */
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = base + 1; i < end; i++)
|
for (unsigned int i = base + 1; i < end; i++)
|
||||||
if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]))
|
if (_hb_glyph_info_get_modified_combining_class (&info[i]))
|
||||||
{
|
{
|
||||||
if (num_lig_components > 1) {
|
if (num_lig_components > 1) {
|
||||||
unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[i]);
|
unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&info[i]);
|
||||||
unsigned int this_lig_component = _hb_glyph_info_get_lig_comp (&buffer->info[i]) - 1;
|
unsigned int this_lig_component = _hb_glyph_info_get_lig_comp (&info[i]) - 1;
|
||||||
/* Conditions for attaching to the last component. */
|
/* Conditions for attaching to the last component. */
|
||||||
if (!lig_id || lig_id != this_lig_id || this_lig_component >= num_lig_components)
|
if (!lig_id || lig_id != this_lig_id || this_lig_component >= num_lig_components)
|
||||||
this_lig_component = num_lig_components - 1;
|
this_lig_component = num_lig_components - 1;
|
||||||
@ -355,7 +358,7 @@ position_around_base (const hb_ot_shape_plan_t *plan,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int this_combining_class = _hb_glyph_info_get_modified_combining_class (&buffer->info[i]);
|
unsigned int this_combining_class = _hb_glyph_info_get_modified_combining_class (&info[i]);
|
||||||
if (last_combining_class != this_combining_class)
|
if (last_combining_class != this_combining_class)
|
||||||
{
|
{
|
||||||
last_combining_class = this_combining_class;
|
last_combining_class = this_combining_class;
|
||||||
@ -391,13 +394,14 @@ position_cluster (const hb_ot_shape_plan_t *plan,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Find the base glyph */
|
/* Find the base glyph */
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = start; i < end; i++)
|
for (unsigned int i = start; i < end; i++)
|
||||||
if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[i])))
|
if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))
|
||||||
{
|
{
|
||||||
/* Find mark glyphs */
|
/* Find mark glyphs */
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
for (j = i + 1; j < end; j++)
|
for (j = i + 1; j < end; j++)
|
||||||
if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[j])))
|
if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[j])))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
position_around_base (plan, font, buffer, i, j);
|
position_around_base (plan, font, buffer, i, j);
|
||||||
@ -411,6 +415,8 @@ _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
|
|||||||
hb_font_t *font,
|
hb_font_t *font,
|
||||||
hb_buffer_t *buffer)
|
hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
|
_hb_buffer_assert_gsubgpos_vars (buffer);
|
||||||
|
|
||||||
unsigned int start = 0;
|
unsigned int start = 0;
|
||||||
unsigned int last_cluster = buffer->info[0].cluster;
|
unsigned int last_cluster = buffer->info[0].cluster;
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
@ -432,15 +438,13 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
|
|||||||
{
|
{
|
||||||
if (!plan->has_kern) return;
|
if (!plan->has_kern) return;
|
||||||
|
|
||||||
unsigned int count = buffer->len;
|
|
||||||
|
|
||||||
OT::hb_apply_context_t c (1, font, buffer);
|
OT::hb_apply_context_t c (1, font, buffer);
|
||||||
c.set_lookup_mask (plan->kern_mask);
|
c.set_lookup_mask (plan->kern_mask);
|
||||||
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
|
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
|
||||||
|
|
||||||
|
unsigned int count = buffer->len;
|
||||||
hb_glyph_info_t *info = buffer->info;
|
hb_glyph_info_t *info = buffer->info;
|
||||||
hb_glyph_position_t *pos = buffer->pos;
|
hb_glyph_position_t *pos = buffer->pos;
|
||||||
|
|
||||||
for (unsigned int idx = 0; idx < count;)
|
for (unsigned int idx = 0; idx < count;)
|
||||||
{
|
{
|
||||||
OT::hb_apply_context_t::skipping_forward_iterator_t skippy_iter (&c, idx, 1);
|
OT::hb_apply_context_t::skipping_forward_iterator_t skippy_iter (&c, idx, 1);
|
||||||
|
@ -289,6 +289,8 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
|
|||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
hb_font_t *font)
|
hb_font_t *font)
|
||||||
{
|
{
|
||||||
|
_hb_buffer_assert_unicode_vars (buffer);
|
||||||
|
|
||||||
hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference;
|
hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference;
|
||||||
const hb_ot_shape_normalize_context_t c = {
|
const hb_ot_shape_normalize_context_t c = {
|
||||||
plan,
|
plan,
|
||||||
|
@ -44,6 +44,7 @@ struct hb_ot_shape_plan_t
|
|||||||
hb_mask_t kern_mask;
|
hb_mask_t kern_mask;
|
||||||
unsigned int has_frac : 1;
|
unsigned int has_frac : 1;
|
||||||
unsigned int has_kern : 1;
|
unsigned int has_kern : 1;
|
||||||
|
unsigned int has_mark : 1;
|
||||||
|
|
||||||
inline void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const
|
inline void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const
|
||||||
{
|
{
|
||||||
@ -92,6 +93,7 @@ struct hb_ot_shape_planner_t
|
|||||||
|
|
||||||
plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask);
|
plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask);
|
||||||
plan.has_kern = !!plan.kern_mask;
|
plan.has_kern = !!plan.kern_mask;
|
||||||
|
plan.has_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -37,12 +37,12 @@
|
|||||||
#include "hb-ot-shape-normalize-private.hh"
|
#include "hb-ot-shape-normalize-private.hh"
|
||||||
|
|
||||||
#include "hb-ot-layout-private.hh"
|
#include "hb-ot-layout-private.hh"
|
||||||
|
#include "hb-unicode-private.hh"
|
||||||
#include "hb-set-private.hh"
|
#include "hb-set-private.hh"
|
||||||
|
|
||||||
|
|
||||||
static hb_tag_t common_features[] = {
|
static hb_tag_t common_features[] = {
|
||||||
HB_TAG('c','c','m','p'),
|
HB_TAG('c','c','m','p'),
|
||||||
HB_TAG('l','i','g','a'),
|
|
||||||
HB_TAG('l','o','c','l'),
|
HB_TAG('l','o','c','l'),
|
||||||
HB_TAG('m','a','r','k'),
|
HB_TAG('m','a','r','k'),
|
||||||
HB_TAG('m','k','m','k'),
|
HB_TAG('m','k','m','k'),
|
||||||
@ -55,6 +55,7 @@ static hb_tag_t horizontal_features[] = {
|
|||||||
HB_TAG('c','l','i','g'),
|
HB_TAG('c','l','i','g'),
|
||||||
HB_TAG('c','u','r','s'),
|
HB_TAG('c','u','r','s'),
|
||||||
HB_TAG('k','e','r','n'),
|
HB_TAG('k','e','r','n'),
|
||||||
|
HB_TAG('l','i','g','a'),
|
||||||
HB_TAG('r','c','l','t'),
|
HB_TAG('r','c','l','t'),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -226,23 +227,25 @@ static void
|
|||||||
hb_set_unicode_props (hb_buffer_t *buffer)
|
hb_set_unicode_props (hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
_hb_glyph_info_set_unicode_props (&buffer->info[i], buffer->unicode);
|
_hb_glyph_info_set_unicode_props (&info[i], buffer->unicode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
|
hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
|
||||||
{
|
{
|
||||||
if (!(buffer->flags & HB_BUFFER_FLAG_BOT) ||
|
if (!(buffer->flags & HB_BUFFER_FLAG_BOT) ||
|
||||||
|
buffer->context_len[0] ||
|
||||||
_hb_glyph_info_get_general_category (&buffer->info[0]) !=
|
_hb_glyph_info_get_general_category (&buffer->info[0]) !=
|
||||||
HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
|
HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!font->has_glyph (0x25CC))
|
if (!font->has_glyph (0x25CCu))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hb_glyph_info_t dottedcircle;
|
hb_glyph_info_t dottedcircle = {0};
|
||||||
dottedcircle.codepoint = 0x25CC;
|
dottedcircle.codepoint = 0x25CCu;
|
||||||
_hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode);
|
_hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode);
|
||||||
|
|
||||||
buffer->clear_output ();
|
buffer->clear_output ();
|
||||||
@ -262,8 +265,9 @@ static void
|
|||||||
hb_form_clusters (hb_buffer_t *buffer)
|
hb_form_clusters (hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = 1; i < count; i++)
|
for (unsigned int i = 1; i < count; i++)
|
||||||
if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[i])))
|
if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))
|
||||||
buffer->merge_clusters (i - 1, i + 1);
|
buffer->merge_clusters (i - 1, i + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,7 +325,7 @@ hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c)
|
|||||||
hb_glyph_info_t *info = buffer->info;
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (info[i].codepoint == 0x2044) /* FRACTION SLASH */
|
if (info[i].codepoint == 0x2044u) /* FRACTION SLASH */
|
||||||
{
|
{
|
||||||
unsigned int start = i, end = i + 1;
|
unsigned int start = i, end = i + 1;
|
||||||
while (start &&
|
while (start &&
|
||||||
@ -381,8 +385,9 @@ hb_ot_map_glyphs_fast (hb_buffer_t *buffer)
|
|||||||
{
|
{
|
||||||
/* Normalization process sets up glyph_index(), we just copy it. */
|
/* Normalization process sets up glyph_index(), we just copy it. */
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
buffer->info[i].codepoint = buffer->info[i].glyph_index();
|
info[i].codepoint = info[i].glyph_index();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -391,11 +396,24 @@ hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
|
|||||||
unsigned int count = c->buffer->len;
|
unsigned int count = c->buffer->len;
|
||||||
hb_glyph_info_t *info = c->buffer->info;
|
hb_glyph_info_t *info = c->buffer->info;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
_hb_glyph_info_set_glyph_props (&info[i],
|
{
|
||||||
_hb_glyph_info_get_general_category (&info[i])
|
hb_ot_layout_glyph_class_mask_t klass;
|
||||||
== HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ?
|
|
||||||
HB_OT_LAYOUT_GLYPH_PROPS_MARK :
|
/* Never mark default-ignorables as marks.
|
||||||
HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
|
* They won't get in the way of lookups anyway,
|
||||||
|
* but having them as mark will cause them to be skipped
|
||||||
|
* over if the lookup-flag says so, but at least for the
|
||||||
|
* Mongolian variation selectors, looks like Uniscribe
|
||||||
|
* marks them as non-mark. Some Mongolian fonts without
|
||||||
|
* GDEF rely on this. Another notable character that
|
||||||
|
* this applies to is COMBINING GRAPHEME JOINER. */
|
||||||
|
klass = (_hb_glyph_info_get_general_category (&info[i]) !=
|
||||||
|
HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ||
|
||||||
|
_hb_glyph_info_is_default_ignorable (&info[i])) ?
|
||||||
|
HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH :
|
||||||
|
HB_OT_LAYOUT_GLYPH_PROPS_MARK;
|
||||||
|
_hb_glyph_info_set_glyph_props (&info[i], klass);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -430,6 +448,7 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c)
|
|||||||
{
|
{
|
||||||
hb_buffer_t *buffer = c->buffer;
|
hb_buffer_t *buffer = c->buffer;
|
||||||
|
|
||||||
|
_hb_buffer_allocate_gsubgpos_vars (buffer);
|
||||||
hb_ot_layout_substitute_start (c->font, buffer);
|
hb_ot_layout_substitute_start (c->font, buffer);
|
||||||
|
|
||||||
if (!hb_ot_layout_has_glyph_classes (c->face))
|
if (!hb_ot_layout_has_glyph_classes (c->face))
|
||||||
@ -469,8 +488,9 @@ static inline void
|
|||||||
zero_mark_widths_by_unicode (hb_buffer_t *buffer, bool adjust_offsets)
|
zero_mark_widths_by_unicode (hb_buffer_t *buffer, bool adjust_offsets)
|
||||||
{
|
{
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
|
if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
|
||||||
{
|
{
|
||||||
if (adjust_offsets)
|
if (adjust_offsets)
|
||||||
adjust_mark_offsets (&buffer->pos[i]);
|
adjust_mark_offsets (&buffer->pos[i]);
|
||||||
@ -482,8 +502,9 @@ static inline void
|
|||||||
zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets)
|
zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets)
|
||||||
{
|
{
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (_hb_glyph_info_is_mark (&buffer->info[i]))
|
if (_hb_glyph_info_is_mark (&info[i]))
|
||||||
{
|
{
|
||||||
if (adjust_offsets)
|
if (adjust_offsets)
|
||||||
adjust_mark_offsets (&buffer->pos[i]);
|
adjust_mark_offsets (&buffer->pos[i]);
|
||||||
@ -518,6 +539,15 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
|
|||||||
bool ret = false;
|
bool ret = false;
|
||||||
unsigned int count = c->buffer->len;
|
unsigned int count = c->buffer->len;
|
||||||
bool has_positioning = hb_ot_layout_has_positioning (c->face);
|
bool has_positioning = hb_ot_layout_has_positioning (c->face);
|
||||||
|
/* If the font has no GPOS, AND, no fallback positioning will
|
||||||
|
* happen, AND, direction is forward, then when zeroing mark
|
||||||
|
* widths, we shift the mark with it, such that the mark
|
||||||
|
* is positioned hanging over the previous glyph. When
|
||||||
|
* direction is backward we don't shift and it will end up
|
||||||
|
* hanging over the next glyph after the final reordering.
|
||||||
|
* If fallback positinoing happens or GPOS is present, we don't
|
||||||
|
* care.
|
||||||
|
*/
|
||||||
bool adjust_offsets_when_zeroing = !(has_positioning || c->plan->shaper->fallback_position ||
|
bool adjust_offsets_when_zeroing = !(has_positioning || c->plan->shaper->fallback_position ||
|
||||||
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction));
|
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction));
|
||||||
|
|
||||||
@ -607,6 +637,8 @@ hb_ot_position (hb_ot_shape_context_t *c)
|
|||||||
|
|
||||||
if (fallback)
|
if (fallback)
|
||||||
_hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
|
_hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
|
||||||
|
|
||||||
|
_hb_buffer_deallocate_gsubgpos_vars (c->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -750,8 +782,9 @@ hb_ot_shape_glyphs_closure (hb_font_t *font,
|
|||||||
bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_DIRECTION_RTL;
|
bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_DIRECTION_RTL;
|
||||||
|
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
hb_glyph_info_t *info = buffer->info;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
add_char (font, buffer->unicode, mirror, buffer->info[i].codepoint, glyphs);
|
add_char (font, buffer->unicode, mirror, info[i].codepoint, glyphs);
|
||||||
|
|
||||||
hb_set_t lookups;
|
hb_set_t lookups;
|
||||||
lookups.init ();
|
lookups.init ();
|
||||||
|
@ -24,31 +24,30 @@
|
|||||||
* Red Hat Author(s): Behdad Esfahbod
|
* Red Hat Author(s): Behdad Esfahbod
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef HB_OT_H_IN
|
||||||
|
#error "Include <hb-ot.h> instead."
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef HB_OT_SHAPE_H
|
#ifndef HB_OT_SHAPE_H
|
||||||
#define HB_OT_SHAPE_H
|
#define HB_OT_SHAPE_H
|
||||||
#define HB_OT_SHAPE_H_IN
|
|
||||||
|
|
||||||
#include "hb.h"
|
#include "hb.h"
|
||||||
|
|
||||||
#include "hb-ot-layout.h"
|
|
||||||
#include "hb-ot-tag.h"
|
|
||||||
|
|
||||||
HB_BEGIN_DECLS
|
HB_BEGIN_DECLS
|
||||||
|
|
||||||
/* TODO port to shape-plan / set. */
|
/* TODO port to shape-plan / set. */
|
||||||
void
|
void
|
||||||
hb_ot_shape_glyphs_closure (hb_font_t *font,
|
hb_ot_shape_glyphs_closure (hb_font_t *font,
|
||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
const hb_feature_t *features,
|
const hb_feature_t *features,
|
||||||
unsigned int num_features,
|
unsigned int num_features,
|
||||||
hb_set_t *glyphs);
|
hb_set_t *glyphs);
|
||||||
|
|
||||||
void
|
void
|
||||||
hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
|
hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
|
||||||
hb_tag_t table_tag,
|
hb_tag_t table_tag,
|
||||||
hb_set_t *lookup_indexes /* OUT */);
|
hb_set_t *lookup_indexes /* OUT */);
|
||||||
|
|
||||||
HB_END_DECLS
|
HB_END_DECLS
|
||||||
|
|
||||||
#undef HB_OT_SHAPE_H_IN
|
|
||||||
#endif /* HB_OT_SHAPE_H */
|
#endif /* HB_OT_SHAPE_H */
|
||||||
|
@ -57,7 +57,7 @@ hb_ot_old_tag_from_script (hb_script_t script)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Else, just change first char to lowercase and return */
|
/* Else, just change first char to lowercase and return */
|
||||||
return ((hb_tag_t) script) | 0x20000000;
|
return ((hb_tag_t) script) | 0x20000000u;
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_script_t
|
static hb_script_t
|
||||||
@ -70,13 +70,13 @@ hb_ot_old_tag_to_script (hb_tag_t tag)
|
|||||||
|
|
||||||
/* Any spaces at the end of the tag are replaced by repeating the last
|
/* Any spaces at the end of the tag are replaced by repeating the last
|
||||||
* letter. Eg 'nko ' -> 'Nkoo' */
|
* letter. Eg 'nko ' -> 'Nkoo' */
|
||||||
if (unlikely ((tag & 0x0000FF00) == 0x00002000))
|
if (unlikely ((tag & 0x0000FF00u) == 0x00002000u))
|
||||||
tag |= (tag >> 8) & 0x0000FF00; /* Copy second letter to third */
|
tag |= (tag >> 8) & 0x0000FF00u; /* Copy second letter to third */
|
||||||
if (unlikely ((tag & 0x000000FF) == 0x00000020))
|
if (unlikely ((tag & 0x000000FFu) == 0x00000020u))
|
||||||
tag |= (tag >> 8) & 0x000000FF; /* Copy third letter to fourth */
|
tag |= (tag >> 8) & 0x000000FFu; /* Copy third letter to fourth */
|
||||||
|
|
||||||
/* Change first char to uppercase and return */
|
/* Change first char to uppercase and return */
|
||||||
return (hb_script_t) (tag & ~0x20000000);
|
return (hb_script_t) (tag & ~0x20000000u);
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_tag_t
|
static hb_tag_t
|
||||||
@ -146,7 +146,7 @@ hb_ot_tags_from_script (hb_script_t script,
|
|||||||
hb_script_t
|
hb_script_t
|
||||||
hb_ot_tag_to_script (hb_tag_t tag)
|
hb_ot_tag_to_script (hb_tag_t tag)
|
||||||
{
|
{
|
||||||
if (unlikely ((tag & 0x000000FF) == '2'))
|
if (unlikely ((tag & 0x000000FFu) == '2'))
|
||||||
return hb_ot_new_tag_to_script (tag);
|
return hb_ot_new_tag_to_script (tag);
|
||||||
|
|
||||||
return hb_ot_old_tag_to_script (tag);
|
return hb_ot_old_tag_to_script (tag);
|
||||||
@ -156,7 +156,7 @@ hb_ot_tag_to_script (hb_tag_t tag)
|
|||||||
/* hb_language_t */
|
/* hb_language_t */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char language[6];
|
char language[4];
|
||||||
hb_tag_t tag;
|
hb_tag_t tag;
|
||||||
} LangTag;
|
} LangTag;
|
||||||
|
|
||||||
@ -763,12 +763,18 @@ static const LangTag ot_languages[] = {
|
|||||||
/*{"??", HB_TAG('Z','H','P',' ')},*/ /* Chinese Phonetic */
|
/*{"??", HB_TAG('Z','H','P',' ')},*/ /* Chinese Phonetic */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const LangTag ot_languages_zh[] = {
|
typedef struct {
|
||||||
|
char language[8];
|
||||||
|
hb_tag_t tag;
|
||||||
|
} LangTagLong;
|
||||||
|
static const LangTagLong ot_languages_zh[] = {
|
||||||
{"zh-cn", HB_TAG('Z','H','S',' ')}, /* Chinese (China) */
|
{"zh-cn", HB_TAG('Z','H','S',' ')}, /* Chinese (China) */
|
||||||
{"zh-hk", HB_TAG('Z','H','H',' ')}, /* Chinese (Hong Kong) */
|
{"zh-hk", HB_TAG('Z','H','H',' ')}, /* Chinese (Hong Kong) */
|
||||||
{"zh-mo", HB_TAG('Z','H','T',' ')}, /* Chinese (Macao) */
|
{"zh-mo", HB_TAG('Z','H','T',' ')}, /* Chinese (Macao) */
|
||||||
{"zh-sg", HB_TAG('Z','H','S',' ')}, /* Chinese (Singapore) */
|
{"zh-sg", HB_TAG('Z','H','S',' ')}, /* Chinese (Singapore) */
|
||||||
{"zh-tw", HB_TAG('Z','H','T',' ')} /* Chinese (Taiwan) */
|
{"zh-tw", HB_TAG('Z','H','T',' ')}, /* Chinese (Taiwan) */
|
||||||
|
{"zh-hans", HB_TAG('Z','H','S',' ')}, /* Chinese (Simplified) */
|
||||||
|
{"zh-hant", HB_TAG('Z','H','T',' ')}, /* Chinese (Traditional) */
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -800,7 +806,6 @@ hb_tag_t
|
|||||||
hb_ot_tag_from_language (hb_language_t language)
|
hb_ot_tag_from_language (hb_language_t language)
|
||||||
{
|
{
|
||||||
const char *lang_str, *s;
|
const char *lang_str, *s;
|
||||||
const LangTag *lang_tag;
|
|
||||||
|
|
||||||
if (language == HB_LANGUAGE_INVALID)
|
if (language == HB_LANGUAGE_INVALID)
|
||||||
return HB_OT_TAG_DEFAULT_LANGUAGE;
|
return HB_OT_TAG_DEFAULT_LANGUAGE;
|
||||||
@ -822,11 +827,14 @@ hb_ot_tag_from_language (hb_language_t language)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Find a language matching in the first component */
|
/* Find a language matching in the first component */
|
||||||
lang_tag = (LangTag *) bsearch (lang_str, ot_languages,
|
{
|
||||||
ARRAY_LENGTH (ot_languages), sizeof (LangTag),
|
const LangTag *lang_tag;
|
||||||
(hb_compare_func_t) lang_compare_first_component);
|
lang_tag = (LangTag *) bsearch (lang_str, ot_languages,
|
||||||
if (lang_tag)
|
ARRAY_LENGTH (ot_languages), sizeof (LangTag),
|
||||||
return lang_tag->tag;
|
(hb_compare_func_t) lang_compare_first_component);
|
||||||
|
if (lang_tag)
|
||||||
|
return lang_tag->tag;
|
||||||
|
}
|
||||||
|
|
||||||
/* Otherwise, check the Chinese ones */
|
/* Otherwise, check the Chinese ones */
|
||||||
if (0 == lang_compare_first_component (lang_str, "zh"))
|
if (0 == lang_compare_first_component (lang_str, "zh"))
|
||||||
@ -835,8 +843,9 @@ hb_ot_tag_from_language (hb_language_t language)
|
|||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH (ot_languages_zh); i++)
|
for (i = 0; i < ARRAY_LENGTH (ot_languages_zh); i++)
|
||||||
{
|
{
|
||||||
|
const LangTagLong *lang_tag;
|
||||||
lang_tag = &ot_languages_zh[i];
|
lang_tag = &ot_languages_zh[i];
|
||||||
if (lang_matches (lang_tag->language, lang_str))
|
if (lang_matches (lang_str, lang_tag->language))
|
||||||
return lang_tag->tag;
|
return lang_tag->tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -849,7 +858,7 @@ hb_ot_tag_from_language (hb_language_t language)
|
|||||||
s = lang_str + strlen (lang_str);
|
s = lang_str + strlen (lang_str);
|
||||||
if (s - lang_str == 3) {
|
if (s - lang_str == 3) {
|
||||||
/* Assume it's ISO-639-3 and upper-case and use it. */
|
/* Assume it's ISO-639-3 and upper-case and use it. */
|
||||||
return hb_tag_from_string (lang_str, s - lang_str) & ~0x20202000;
|
return hb_tag_from_string (lang_str, s - lang_str) & ~0x20202000u;
|
||||||
}
|
}
|
||||||
|
|
||||||
return HB_OT_TAG_DEFAULT_LANGUAGE;
|
return HB_OT_TAG_DEFAULT_LANGUAGE;
|
||||||
@ -868,21 +877,12 @@ hb_ot_tag_to_language (hb_tag_t tag)
|
|||||||
return hb_language_from_string (ot_languages[i].language, -1);
|
return hb_language_from_string (ot_languages[i].language, -1);
|
||||||
|
|
||||||
/* If tag starts with ZH, it's Chinese */
|
/* If tag starts with ZH, it's Chinese */
|
||||||
if ((tag & 0xFFFF0000) == 0x5A480000) {
|
if ((tag & 0xFFFF0000u) == 0x5A480000u) {
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case HB_TAG('Z','H','H',' '): return hb_language_from_string ("zh-hk", -1); /* Hong Kong */
|
case HB_TAG('Z','H','H',' '): return hb_language_from_string ("zh-hk", -1); /* Hong Kong */
|
||||||
default: {
|
case HB_TAG('Z','H','S',' '): return hb_language_from_string ("zh-Hans", -1); /* Simplified */
|
||||||
/* Encode the tag... */
|
case HB_TAG('Z','H','T',' '): return hb_language_from_string ("zh-Hant", -1); /* Traditional */
|
||||||
unsigned char buf[14] = "zh-x-hbot";
|
default: break; /* Fall through */
|
||||||
buf[9] = tag >> 24;
|
|
||||||
buf[10] = (tag >> 16) & 0xFF;
|
|
||||||
buf[11] = (tag >> 8) & 0xFF;
|
|
||||||
buf[12] = tag & 0xFF;
|
|
||||||
if (buf[12] == 0x20)
|
|
||||||
buf[12] = '\0';
|
|
||||||
buf[13] = '\0';
|
|
||||||
return hb_language_from_string ((char *) buf, -1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "hb.h"
|
#include "hb.h"
|
||||||
|
|
||||||
|
#include "hb-ot-font.h"
|
||||||
#include "hb-ot-layout.h"
|
#include "hb-ot-layout.h"
|
||||||
#include "hb-ot-tag.h"
|
#include "hb-ot-tag.h"
|
||||||
#include "hb-ot-shape.h"
|
#include "hb-ot-shape.h"
|
||||||
|
@ -54,23 +54,90 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Compiler attributes */
|
||||||
|
|
||||||
/* Essentials */
|
|
||||||
|
|
||||||
#ifndef NULL
|
#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
|
||||||
# define NULL ((void *) 0)
|
#define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0)
|
||||||
|
#define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1))
|
||||||
|
#define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0))
|
||||||
|
#else
|
||||||
|
#define likely(expr) (expr)
|
||||||
|
#define unlikely(expr) (expr)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef __GNUC__
|
||||||
|
#undef __attribute__
|
||||||
|
#define __attribute__(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Void! */
|
#if __GNUC__ >= 3
|
||||||
struct _hb_void_t {};
|
#define HB_PURE_FUNC __attribute__((pure))
|
||||||
typedef const _hb_void_t &hb_void_t;
|
#define HB_CONST_FUNC __attribute__((const))
|
||||||
#define HB_VOID (* (const _hb_void_t *) NULL)
|
#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx)))
|
||||||
|
#else
|
||||||
|
#define HB_PURE_FUNC
|
||||||
|
#define HB_CONST_FUNC
|
||||||
|
#define HB_PRINTF_FUNC(format_idx, arg_idx)
|
||||||
|
#endif
|
||||||
|
#if __GNUC__ >= 4
|
||||||
|
#define HB_UNUSED __attribute__((unused))
|
||||||
|
#else
|
||||||
|
#define HB_UNUSED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HB_INTERNAL
|
||||||
|
# if !defined(__MINGW32__) && !defined(__CYGWIN__)
|
||||||
|
# define HB_INTERNAL __attribute__((__visibility__("hidden")))
|
||||||
|
# else
|
||||||
|
# define HB_INTERNAL
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER)
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#undef inline
|
||||||
|
#define inline __inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __STRICT_ANSI__
|
||||||
|
#undef inline
|
||||||
|
#define inline __inline__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __GNUC__ >= 3
|
||||||
|
#define HB_FUNC __PRETTY_FUNCTION__
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define HB_FUNC __FUNCSIG__
|
||||||
|
#else
|
||||||
|
#define HB_FUNC __func__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
/* We need Windows Vista for both Uniscribe backend and for
|
||||||
|
* MemoryBarrier. We don't support compiling on Windows XP,
|
||||||
|
* though we run on it fine. */
|
||||||
|
# if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600
|
||||||
|
# undef _WIN32_WINNT
|
||||||
|
# endif
|
||||||
|
# ifndef _WIN32_WINNT
|
||||||
|
# define _WIN32_WINNT 0x0600
|
||||||
|
# endif
|
||||||
|
# define WIN32_LEAN_AND_MEAN
|
||||||
|
# define STRICT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Basics */
|
/* Basics */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
# define NULL ((void *) 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef MIN
|
#undef MIN
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
|
static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
|
||||||
@ -92,7 +159,7 @@ static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
|
|||||||
#define HB_STMT_START do
|
#define HB_STMT_START do
|
||||||
#define HB_STMT_END while (0)
|
#define HB_STMT_END while (0)
|
||||||
|
|
||||||
#define _ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1]
|
#define _ASSERT_STATIC1(_line, _cond) HB_UNUSED typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1]
|
||||||
#define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond))
|
#define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond))
|
||||||
#define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond))
|
#define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond))
|
||||||
|
|
||||||
@ -139,7 +206,7 @@ ASSERT_STATIC (sizeof (hb_var_int_t) == 4);
|
|||||||
|
|
||||||
/* Check _assertion in a method environment */
|
/* Check _assertion in a method environment */
|
||||||
#define _ASSERT_POD1(_line) \
|
#define _ASSERT_POD1(_line) \
|
||||||
inline void _static_assertion_on_line_##_line (void) const \
|
HB_UNUSED inline void _static_assertion_on_line_##_line (void) const \
|
||||||
{ _ASSERT_INSTANCE_POD1 (_line, *this); /* Make sure it's POD. */ }
|
{ _ASSERT_INSTANCE_POD1 (_line, *this); /* Make sure it's POD. */ }
|
||||||
# define _ASSERT_POD0(_line) _ASSERT_POD1 (_line)
|
# define _ASSERT_POD0(_line) _ASSERT_POD1 (_line)
|
||||||
# define ASSERT_POD() _ASSERT_POD0 (__LINE__)
|
# define ASSERT_POD() _ASSERT_POD0 (__LINE__)
|
||||||
@ -148,68 +215,10 @@ ASSERT_STATIC (sizeof (hb_var_int_t) == 4);
|
|||||||
|
|
||||||
/* Misc */
|
/* Misc */
|
||||||
|
|
||||||
|
/* Void! */
|
||||||
#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
|
struct _hb_void_t {};
|
||||||
#define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0)
|
typedef const _hb_void_t &hb_void_t;
|
||||||
#define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1))
|
#define HB_VOID (* (const _hb_void_t *) NULL)
|
||||||
#define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0))
|
|
||||||
#else
|
|
||||||
#define likely(expr) (expr)
|
|
||||||
#define unlikely(expr) (expr)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __GNUC__
|
|
||||||
#undef __attribute__
|
|
||||||
#define __attribute__(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __GNUC__ >= 3
|
|
||||||
#define HB_PURE_FUNC __attribute__((pure))
|
|
||||||
#define HB_CONST_FUNC __attribute__((const))
|
|
||||||
#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx)))
|
|
||||||
#else
|
|
||||||
#define HB_PURE_FUNC
|
|
||||||
#define HB_CONST_FUNC
|
|
||||||
#define HB_PRINTF_FUNC(format_idx, arg_idx)
|
|
||||||
#endif
|
|
||||||
#if __GNUC__ >= 4
|
|
||||||
#define HB_UNUSED __attribute__((unused))
|
|
||||||
#else
|
|
||||||
#define HB_UNUSED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HB_INTERNAL
|
|
||||||
# ifndef __MINGW32__
|
|
||||||
# define HB_INTERNAL __attribute__((__visibility__("hidden")))
|
|
||||||
# else
|
|
||||||
# define HB_INTERNAL
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER)
|
|
||||||
#define snprintf _snprintf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#undef inline
|
|
||||||
#define inline __inline
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __STRICT_ANSI__
|
|
||||||
#undef inline
|
|
||||||
#define inline __inline__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if __GNUC__ >= 3
|
|
||||||
#define HB_FUNC __PRETTY_FUNCTION__
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#define HB_FUNC __FUNCSIG__
|
|
||||||
#else
|
|
||||||
#define HB_FUNC __func__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Return the number of 1 bits in mask. */
|
/* Return the number of 1 bits in mask. */
|
||||||
static inline HB_CONST_FUNC unsigned int
|
static inline HB_CONST_FUNC unsigned int
|
||||||
@ -275,8 +284,8 @@ typedef int (*hb_compare_func_t) (const void *, const void *);
|
|||||||
/* arrays and maps */
|
/* arrays and maps */
|
||||||
|
|
||||||
|
|
||||||
#define HB_PREALLOCED_ARRAY_INIT {0}
|
#define HB_PREALLOCED_ARRAY_INIT {0, 0, NULL}
|
||||||
template <typename Type, unsigned int StaticSize>
|
template <typename Type, unsigned int StaticSize=16>
|
||||||
struct hb_prealloced_array_t
|
struct hb_prealloced_array_t
|
||||||
{
|
{
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
@ -357,14 +366,14 @@ struct hb_prealloced_array_t
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void sort (void)
|
inline void qsort (void)
|
||||||
{
|
{
|
||||||
qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
|
::qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void sort (unsigned int start, unsigned int end)
|
inline void qsort (unsigned int start, unsigned int end)
|
||||||
{
|
{
|
||||||
qsort (array + start, end - start, sizeof (Type), (hb_compare_func_t) Type::cmp);
|
::qsort (array + start, end - start, sizeof (Type), (hb_compare_func_t) Type::cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -387,12 +396,11 @@ struct hb_prealloced_array_t
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define HB_AUTO_ARRAY_PREALLOCED 16
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
struct hb_auto_array_t : hb_prealloced_array_t <Type, HB_AUTO_ARRAY_PREALLOCED>
|
struct hb_auto_array_t : hb_prealloced_array_t <Type>
|
||||||
{
|
{
|
||||||
hb_auto_array_t (void) { hb_prealloced_array_t<Type, HB_AUTO_ARRAY_PREALLOCED>::init (); }
|
hb_auto_array_t (void) { hb_prealloced_array_t<Type>::init (); }
|
||||||
~hb_auto_array_t (void) { hb_prealloced_array_t<Type, HB_AUTO_ARRAY_PREALLOCED>::finish (); }
|
~hb_auto_array_t (void) { hb_prealloced_array_t<Type>::finish (); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -725,7 +733,7 @@ static inline void _hb_warn_no_return (bool returned)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED)
|
/*static*/ inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
template <int max_level, typename ret_t>
|
template <int max_level, typename ret_t>
|
||||||
@ -791,20 +799,23 @@ struct hb_auto_trace_t<0, ret_t> {
|
|||||||
|
|
||||||
/* Misc */
|
/* Misc */
|
||||||
|
|
||||||
|
template <typename T> class hb_assert_unsigned_t;
|
||||||
|
template <> class hb_assert_unsigned_t<unsigned char> {};
|
||||||
|
template <> class hb_assert_unsigned_t<unsigned short> {};
|
||||||
|
template <> class hb_assert_unsigned_t<unsigned int> {};
|
||||||
|
template <> class hb_assert_unsigned_t<unsigned long> {};
|
||||||
|
|
||||||
/* Pre-mature optimization:
|
|
||||||
* Checks for lo <= u <= hi but with an optimization if lo and hi
|
|
||||||
* are only different in a contiguous set of lower-most bits.
|
|
||||||
*/
|
|
||||||
template <typename T> static inline bool
|
template <typename T> static inline bool
|
||||||
hb_in_range (T u, T lo, T hi)
|
hb_in_range (T u, T lo, T hi)
|
||||||
{
|
{
|
||||||
if ( ((lo^hi) & lo) == 0 &&
|
/* The sizeof() is here to force template instantiation.
|
||||||
((lo^hi) & hi) == (lo^hi) &&
|
* I'm sure there are better ways to do this but can't think of
|
||||||
((lo^hi) & ((lo^hi) + 1)) == 0 )
|
* one right now. Declaring a variable won't work as HB_UNUSED
|
||||||
return (u & ~(lo^hi)) == lo;
|
* is unsable on some platforms and unused types are less likely
|
||||||
else
|
* to generate a warning than unused variables. */
|
||||||
return lo <= u && u <= hi;
|
ASSERT_STATIC (sizeof (hb_assert_unsigned_t<T>) >= 0);
|
||||||
|
|
||||||
|
return (u - lo) <= (hi - lo);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> static inline bool
|
template <typename T> static inline bool
|
||||||
|
@ -104,8 +104,6 @@ hb_shape_plan_create (hb_face_t *face,
|
|||||||
unsigned int num_user_features,
|
unsigned int num_user_features,
|
||||||
const char * const *shaper_list)
|
const char * const *shaper_list)
|
||||||
{
|
{
|
||||||
assert (props->direction != HB_DIRECTION_INVALID);
|
|
||||||
|
|
||||||
hb_shape_plan_t *shape_plan;
|
hb_shape_plan_t *shape_plan;
|
||||||
hb_feature_t *features = NULL;
|
hb_feature_t *features = NULL;
|
||||||
|
|
||||||
@ -120,6 +118,8 @@ hb_shape_plan_create (hb_face_t *face,
|
|||||||
return hb_shape_plan_get_empty ();
|
return hb_shape_plan_get_empty ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert (props->direction != HB_DIRECTION_INVALID);
|
||||||
|
|
||||||
hb_face_make_immutable (face);
|
hb_face_make_immutable (face);
|
||||||
shape_plan->default_shaper_list = shaper_list == NULL;
|
shape_plan->default_shaper_list = shaper_list == NULL;
|
||||||
shape_plan->face_unsafe = face;
|
shape_plan->face_unsafe = face;
|
||||||
|
@ -34,15 +34,15 @@
|
|||||||
#include "hb-font-private.hh"
|
#include "hb-font-private.hh"
|
||||||
|
|
||||||
|
|
||||||
static void
|
static bool
|
||||||
parse_space (const char **pp, const char *end)
|
parse_space (const char **pp, const char *end)
|
||||||
{
|
{
|
||||||
char c;
|
while (*pp < end && ISSPACE (**pp))
|
||||||
while (*pp < end && (c = **pp, ISSPACE (c)))
|
|
||||||
(*pp)++;
|
(*pp)++;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_bool_t
|
static bool
|
||||||
parse_char (const char **pp, const char *end, char c)
|
parse_char (const char **pp, const char *end, char c)
|
||||||
{
|
{
|
||||||
parse_space (pp, end);
|
parse_space (pp, end);
|
||||||
@ -54,7 +54,7 @@ parse_char (const char **pp, const char *end, char c)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_bool_t
|
static bool
|
||||||
parse_uint (const char **pp, const char *end, unsigned int *pv)
|
parse_uint (const char **pp, const char *end, unsigned int *pv)
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
@ -78,7 +78,27 @@ parse_uint (const char **pp, const char *end, unsigned int *pv)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_bool_t
|
static bool
|
||||||
|
parse_bool (const char **pp, const char *end, unsigned int *pv)
|
||||||
|
{
|
||||||
|
parse_space (pp, end);
|
||||||
|
|
||||||
|
const char *p = *pp;
|
||||||
|
while (*pp < end && ISALPHA(**pp))
|
||||||
|
(*pp)++;
|
||||||
|
|
||||||
|
/* CSS allows on/off as aliases 1/0. */
|
||||||
|
if (*pp - p == 2 || 0 == strncmp (p, "on", 2))
|
||||||
|
*pv = 1;
|
||||||
|
else if (*pp - p == 3 || 0 == strncmp (p, "off", 2))
|
||||||
|
*pv = 0;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
parse_feature_value_prefix (const char **pp, const char *end, hb_feature_t *feature)
|
parse_feature_value_prefix (const char **pp, const char *end, hb_feature_t *feature)
|
||||||
{
|
{
|
||||||
if (parse_char (pp, end, '-'))
|
if (parse_char (pp, end, '-'))
|
||||||
@ -91,32 +111,48 @@ parse_feature_value_prefix (const char **pp, const char *end, hb_feature_t *feat
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_bool_t
|
static bool
|
||||||
parse_feature_tag (const char **pp, const char *end, hb_feature_t *feature)
|
parse_feature_tag (const char **pp, const char *end, hb_feature_t *feature)
|
||||||
{
|
{
|
||||||
const char *p = *pp;
|
|
||||||
char c;
|
|
||||||
|
|
||||||
parse_space (pp, end);
|
parse_space (pp, end);
|
||||||
|
|
||||||
#define ISALNUM(c) (('a' <= (c) && (c) <= 'z') || ('A' <= (c) && (c) <= 'Z') || ('0' <= (c) && (c) <= '9'))
|
char quote = 0;
|
||||||
while (*pp < end && (c = **pp, ISALNUM(c)))
|
|
||||||
(*pp)++;
|
|
||||||
#undef ISALNUM
|
|
||||||
|
|
||||||
if (p == *pp)
|
if (*pp < end && (**pp == '\'' || **pp == '"'))
|
||||||
|
{
|
||||||
|
quote = **pp;
|
||||||
|
(*pp)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *p = *pp;
|
||||||
|
while (*pp < end && ISALNUM(**pp))
|
||||||
|
(*pp)++;
|
||||||
|
|
||||||
|
if (p == *pp || *pp - p > 4)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
feature->tag = hb_tag_from_string (p, *pp - p);
|
feature->tag = hb_tag_from_string (p, *pp - p);
|
||||||
|
|
||||||
|
if (quote)
|
||||||
|
{
|
||||||
|
/* CSS expects exactly four bytes. And we only allow quotations for
|
||||||
|
* CSS compatibility. So, enforce the length. */
|
||||||
|
if (*pp - p != 4)
|
||||||
|
return false;
|
||||||
|
if (*pp == end || **pp != quote)
|
||||||
|
return false;
|
||||||
|
(*pp)++;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_bool_t
|
static bool
|
||||||
parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature)
|
parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature)
|
||||||
{
|
{
|
||||||
parse_space (pp, end);
|
parse_space (pp, end);
|
||||||
|
|
||||||
hb_bool_t has_start;
|
bool has_start;
|
||||||
|
|
||||||
feature->start = 0;
|
feature->start = 0;
|
||||||
feature->end = (unsigned int) -1;
|
feature->end = (unsigned int) -1;
|
||||||
@ -136,20 +172,27 @@ parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature)
|
|||||||
return parse_char (pp, end, ']');
|
return parse_char (pp, end, ']');
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_bool_t
|
static bool
|
||||||
parse_feature_value_postfix (const char **pp, const char *end, hb_feature_t *feature)
|
parse_feature_value_postfix (const char **pp, const char *end, hb_feature_t *feature)
|
||||||
{
|
{
|
||||||
return !parse_char (pp, end, '=') || parse_uint (pp, end, &feature->value);
|
bool had_equal = parse_char (pp, end, '=');
|
||||||
|
bool had_value = parse_uint (pp, end, &feature->value) ||
|
||||||
|
parse_bool (pp, end, &feature->value);
|
||||||
|
/* CSS doesn't use equal-sign between tag and value.
|
||||||
|
* If there was an equal-sign, then there *must* be a value.
|
||||||
|
* A value without an eqaul-sign is ok, but not required. */
|
||||||
|
return !had_equal || had_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static hb_bool_t
|
static bool
|
||||||
parse_one_feature (const char **pp, const char *end, hb_feature_t *feature)
|
parse_one_feature (const char **pp, const char *end, hb_feature_t *feature)
|
||||||
{
|
{
|
||||||
return parse_feature_value_prefix (pp, end, feature) &&
|
return parse_feature_value_prefix (pp, end, feature) &&
|
||||||
parse_feature_tag (pp, end, feature) &&
|
parse_feature_tag (pp, end, feature) &&
|
||||||
parse_feature_indices (pp, end, feature) &&
|
parse_feature_indices (pp, end, feature) &&
|
||||||
parse_feature_value_postfix (pp, end, feature) &&
|
parse_feature_value_postfix (pp, end, feature) &&
|
||||||
|
parse_space (pp, end) &&
|
||||||
*pp == end;
|
*pp == end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +200,7 @@ parse_one_feature (const char **pp, const char *end, hb_feature_t *feature)
|
|||||||
* hb_feature_from_string:
|
* hb_feature_from_string:
|
||||||
* @str: (array length=len):
|
* @str: (array length=len):
|
||||||
* @len:
|
* @len:
|
||||||
* @feature: (out):
|
* @feature: (out) (allow-none):
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
@ -169,10 +212,21 @@ hb_bool_t
|
|||||||
hb_feature_from_string (const char *str, int len,
|
hb_feature_from_string (const char *str, int len,
|
||||||
hb_feature_t *feature)
|
hb_feature_t *feature)
|
||||||
{
|
{
|
||||||
|
hb_feature_t feat;
|
||||||
|
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
len = strlen (str);
|
len = strlen (str);
|
||||||
|
|
||||||
return parse_one_feature (&str, str + len, feature);
|
if (likely (parse_one_feature (&str, str + len, &feat)))
|
||||||
|
{
|
||||||
|
if (feature)
|
||||||
|
*feature = feat;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (feature)
|
||||||
|
memset (feature, 0, sizeof (*feature));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -203,18 +257,18 @@ hb_feature_to_string (hb_feature_t *feature,
|
|||||||
{
|
{
|
||||||
s[len++] = '[';
|
s[len++] = '[';
|
||||||
if (feature->start)
|
if (feature->start)
|
||||||
len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->start));
|
len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start));
|
||||||
if (feature->end != feature->start + 1) {
|
if (feature->end != feature->start + 1) {
|
||||||
s[len++] = ':';
|
s[len++] = ':';
|
||||||
if (feature->end != (unsigned int) -1)
|
if (feature->end != (unsigned int) -1)
|
||||||
len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->end));
|
len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end));
|
||||||
}
|
}
|
||||||
s[len++] = ']';
|
s[len++] = ']';
|
||||||
}
|
}
|
||||||
if (feature->value > 1)
|
if (feature->value > 1)
|
||||||
{
|
{
|
||||||
s[len++] = '=';
|
s[len++] = '=';
|
||||||
len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%d", feature->value));
|
len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value));
|
||||||
}
|
}
|
||||||
assert (len < ARRAY_LENGTH (s));
|
assert (len < ARRAY_LENGTH (s));
|
||||||
len = MIN (len, size - 1);
|
len = MIN (len, size - 1);
|
||||||
|
@ -34,17 +34,15 @@
|
|||||||
/* Only picks up fonts that have a "Silf" table. */
|
/* Only picks up fonts that have a "Silf" table. */
|
||||||
HB_SHAPER_IMPLEMENT (graphite2)
|
HB_SHAPER_IMPLEMENT (graphite2)
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_CORETEXT
|
||||||
|
/* Only picks up fonts that have a "mort" or "morx" table. */
|
||||||
|
HB_SHAPER_IMPLEMENT (coretext_aat)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_OT
|
#ifdef HAVE_OT
|
||||||
HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
|
HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_HB_OLD
|
|
||||||
HB_SHAPER_IMPLEMENT (old)
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_ICU_LE
|
|
||||||
HB_SHAPER_IMPLEMENT (icu_le)
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_UNISCRIBE
|
#ifdef HAVE_UNISCRIBE
|
||||||
HB_SHAPER_IMPLEMENT (uniscribe)
|
HB_SHAPER_IMPLEMENT (uniscribe)
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright © 2011 Google, Inc.
|
|
||||||
*
|
|
||||||
* This is part of HarfBuzz, a text shaping library.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, without written agreement and without
|
|
||||||
* license or royalty fees, to use, copy, modify, and distribute this
|
|
||||||
* software and its documentation for any purpose, provided that the
|
|
||||||
* above copyright notice and the following two paragraphs appear in
|
|
||||||
* all copies of this software.
|
|
||||||
*
|
|
||||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
|
||||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
|
||||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
|
||||||
* DAMAGE.
|
|
||||||
*
|
|
||||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
|
||||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
|
||||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
|
||||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
|
||||||
*
|
|
||||||
* Google Author(s): Behdad Esfahbod
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "hb-font-private.hh" /* Shall be first since may include windows.h */
|
|
||||||
|
|
||||||
#include "hb-open-type-private.hh"
|
|
||||||
|
|
||||||
#include "hb-ot-hhea-table.hh"
|
|
||||||
#include "hb-ot-hmtx-table.hh"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
struct hb_tt_font_t
|
|
||||||
{
|
|
||||||
const struct hhea *hhea;
|
|
||||||
hb_blob_t *hhea_blob;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static hb_tt_font_t *
|
|
||||||
_hb_tt_font_create (hb_font_t *font)
|
|
||||||
{
|
|
||||||
/* TODO Remove this object altogether */
|
|
||||||
hb_tt_font_t *tt = (hb_tt_font_t *) calloc (1, sizeof (hb_tt_font_t));
|
|
||||||
|
|
||||||
tt->hhea_blob = Sanitizer<hhea>::sanitize (font->face->reference_table (HB_OT_TAG_hhea));
|
|
||||||
tt->hhea = Sanitizer<hhea>::lock_instance (tt->hhea_blob);
|
|
||||||
|
|
||||||
return tt;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_hb_tt_font_destroy (hb_tt_font_t *tt)
|
|
||||||
{
|
|
||||||
hb_blob_destroy (tt->hhea_blob);
|
|
||||||
|
|
||||||
free (tt);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const hhea&
|
|
||||||
_get_hhea (hb_face_t *face)
|
|
||||||
{
|
|
||||||
return likely (face->tt && face->tt->hhea) ? *face->tt->hhea : Null(hhea);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* hb_tt_font_funcs_t
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif
|
|
@ -125,6 +125,29 @@ static const hb_script_t ucdn_script_translate[] =
|
|||||||
HB_SCRIPT_SORA_SOMPENG,
|
HB_SCRIPT_SORA_SOMPENG,
|
||||||
HB_SCRIPT_TAKRI,
|
HB_SCRIPT_TAKRI,
|
||||||
HB_SCRIPT_UNKNOWN,
|
HB_SCRIPT_UNKNOWN,
|
||||||
|
HB_SCRIPT_BASSA_VAH,
|
||||||
|
HB_SCRIPT_CAUCASIAN_ALBANIAN,
|
||||||
|
HB_SCRIPT_DUPLOYAN,
|
||||||
|
HB_SCRIPT_ELBASAN,
|
||||||
|
HB_SCRIPT_GRANTHA,
|
||||||
|
HB_SCRIPT_KHOJKI,
|
||||||
|
HB_SCRIPT_KHUDAWADI,
|
||||||
|
HB_SCRIPT_LINEAR_A,
|
||||||
|
HB_SCRIPT_MAHAJANI,
|
||||||
|
HB_SCRIPT_MANICHAEAN,
|
||||||
|
HB_SCRIPT_MENDE_KIKAKUI,
|
||||||
|
HB_SCRIPT_MODI,
|
||||||
|
HB_SCRIPT_MRO,
|
||||||
|
HB_SCRIPT_NABATAEAN,
|
||||||
|
HB_SCRIPT_OLD_NORTH_ARABIAN,
|
||||||
|
HB_SCRIPT_OLD_PERMIC,
|
||||||
|
HB_SCRIPT_PAHAWH_HMONG,
|
||||||
|
HB_SCRIPT_PALMYRENE,
|
||||||
|
HB_SCRIPT_PAU_CIN_HAU,
|
||||||
|
HB_SCRIPT_PSALTER_PAHLAVI,
|
||||||
|
HB_SCRIPT_SIDDHAM,
|
||||||
|
HB_SCRIPT_TIRHUTA,
|
||||||
|
HB_SCRIPT_WARANG_CITI,
|
||||||
};
|
};
|
||||||
|
|
||||||
static hb_unicode_combining_class_t
|
static hb_unicode_combining_class_t
|
||||||
|
@ -102,72 +102,70 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int
|
inline unsigned int
|
||||||
modified_combining_class (hb_codepoint_t unicode)
|
modified_combining_class (hb_codepoint_t unicode)
|
||||||
{
|
{
|
||||||
/* XXX This hack belongs to the Myanmar shaper. */
|
/* XXX This hack belongs to the Myanmar shaper. */
|
||||||
if (unlikely (unicode == 0x1037)) unicode = 0x103A;
|
if (unlikely (unicode == 0x1037u)) unicode = 0x103Au;
|
||||||
|
|
||||||
/* XXX This hack belongs to the SEA shaper (for Tai Tham):
|
/* XXX This hack belongs to the SEA shaper (for Tai Tham):
|
||||||
* Reorder SAKOT to ensure it comes after any tone marks. */
|
* Reorder SAKOT to ensure it comes after any tone marks. */
|
||||||
if (unlikely (unicode == 0x1A60)) return 254;
|
if (unlikely (unicode == 0x1A60u)) return 254;
|
||||||
|
|
||||||
|
/* XXX This hack belongs to the Tibetan shaper:
|
||||||
|
* Reorder PADMA to ensure it comes after any vowel marks. */
|
||||||
|
if (unlikely (unicode == 0x0FC6u)) return 254;
|
||||||
|
|
||||||
return _hb_modified_combining_class[combining_class (unicode)];
|
return _hb_modified_combining_class[combining_class (unicode)];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline hb_bool_t
|
static inline hb_bool_t
|
||||||
is_variation_selector (hb_codepoint_t unicode)
|
is_variation_selector (hb_codepoint_t unicode)
|
||||||
{
|
{
|
||||||
return unlikely (hb_in_ranges<hb_codepoint_t> (unicode,
|
/* U+180B..180D MONGOLIAN FREE VARIATION SELECTORs are handled in the
|
||||||
0x180B, 0x180D, /* MONGOLIAN FREE VARIATION SELECTOR ONE..THREE */
|
* Arabic shaper. No need to match them here. */
|
||||||
0xFE00, 0xFE0F, /* VARIATION SELECTOR-1..16 */
|
return unlikely (hb_in_ranges (unicode,
|
||||||
0xE0100, 0xE01EF)); /* VARIATION SELECTOR-17..256 */
|
0xFE00u, 0xFE0Fu, /* VARIATION SELECTOR-1..16 */
|
||||||
|
0xE0100u, 0xE01EFu)); /* VARIATION SELECTOR-17..256 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Default_Ignorable codepoints:
|
/* Default_Ignorable codepoints:
|
||||||
*
|
|
||||||
* Note that as of Oct 2012 (Unicode 6.2), U+180E MONGOLIAN VOWEL SEPARATOR
|
|
||||||
* is NOT Default_Ignorable, but it really behaves in a way that it should
|
|
||||||
* be. That has been reported to the Unicode Technical Committee for
|
|
||||||
* consideration. As such, we include it here, since Uniscribe removes it.
|
|
||||||
* It *is* in Unicode 6.3 however. U+061C ARABIC LETTER MARK from Unicode
|
|
||||||
* 6.3 is also added manually. The new Unicode 6.3 bidi formatting
|
|
||||||
* characters are encoded in a block that was Default_Ignorable already.
|
|
||||||
*
|
*
|
||||||
* Note: While U+115F, U+1160, U+3164 and U+FFA0 are Default_Ignorable,
|
* Note: While U+115F, U+1160, U+3164 and U+FFA0 are Default_Ignorable,
|
||||||
* we do NOT want to hide them, as the way Uniscribe has implemented them
|
* we do NOT want to hide them, as the way Uniscribe has implemented them
|
||||||
* is with regular spacing glyphs, and that's the way fonts are made to work.
|
* is with regular spacing glyphs, and that's the way fonts are made to work.
|
||||||
* As such, we make exceptions for those four.
|
* As such, we make exceptions for those four.
|
||||||
*
|
*
|
||||||
* Gathered from:
|
* Unicode 7.0:
|
||||||
* http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:DI:]&abb=on&ucd=on&esc=on
|
* $ grep '; Default_Ignorable_Code_Point ' DerivedCoreProperties.txt | sed 's/;.*#/#/'
|
||||||
*
|
* 00AD # Cf SOFT HYPHEN
|
||||||
* Last updated to the page with the following versions:
|
* 034F # Mn COMBINING GRAPHEME JOINER
|
||||||
* Version 3.6; ICU version: 50.0.1.0; Unicode version: 6.1.0.0
|
* 061C # Cf ARABIC LETTER MARK
|
||||||
*
|
* 115F..1160 # Lo [2] HANGUL CHOSEONG FILLER..HANGUL JUNGSEONG FILLER
|
||||||
* 4,167 Code Points
|
* 17B4..17B5 # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
|
||||||
*
|
* 180B..180D # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
|
||||||
* [\u00AD\u034F\u115F\u1160\u17B4\u17B5\u180B-\u180D\u200B-\u200F\u202A-\u202E\u2060-\u206F\u3164\uFE00-\uFE0F\uFEFF\uFFA0\uFFF0-\uFFF8\U0001D173-\U0001D17A\U000E0000-\U000E0FFF]
|
* 180E # Cf MONGOLIAN VOWEL SEPARATOR
|
||||||
*
|
* 200B..200F # Cf [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK
|
||||||
* 00AD ;SOFT HYPHEN
|
* 202A..202E # Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
|
||||||
* 034F ;COMBINING GRAPHEME JOINER
|
* 2060..2064 # Cf [5] WORD JOINER..INVISIBLE PLUS
|
||||||
* #115F ;HANGUL CHOSEONG FILLER
|
* 2065 # Cn <reserved-2065>
|
||||||
* #1160 ;HANGUL JUNGSEONG FILLER
|
* 2066..206F # Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES
|
||||||
* 17B4 ;KHMER VOWEL INHERENT AQ
|
* 3164 # Lo HANGUL FILLER
|
||||||
* 17B5 ;KHMER VOWEL INHERENT AA
|
* FE00..FE0F # Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16
|
||||||
* 180B..180D ;MONGOLIAN FREE VARIATION SELECTOR THREE
|
* FEFF # Cf ZERO WIDTH NO-BREAK SPACE
|
||||||
* 200B..200F ;RIGHT-TO-LEFT MARK
|
* FFA0 # Lo HALFWIDTH HANGUL FILLER
|
||||||
* 202A..202E ;RIGHT-TO-LEFT OVERRIDE
|
* FFF0..FFF8 # Cn [9] <reserved-FFF0>..<reserved-FFF8>
|
||||||
* 2060..206F ;NOMINAL DIGIT SHAPES
|
* 1BCA0..1BCA3 # Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP
|
||||||
* #3164 ;HANGUL FILLER
|
* 1D173..1D17A # Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE
|
||||||
* FE00..FE0F ;VARIATION SELECTOR-16
|
* E0000 # Cn <reserved-E0000>
|
||||||
* FEFF ;ZERO WIDTH NO-BREAK SPACE
|
* E0001 # Cf LANGUAGE TAG
|
||||||
* #FFA0 ;HALFWIDTH HANGUL FILLER
|
* E0002..E001F # Cn [30] <reserved-E0002>..<reserved-E001F>
|
||||||
* FFF0..FFF8 ;<unassigned-FFF8>
|
* E0020..E007F # Cf [96] TAG SPACE..CANCEL TAG
|
||||||
* 1D173..1D17A ;MUSICAL SYMBOL END PHRASE
|
* E0080..E00FF # Cn [128] <reserved-E0080>..<reserved-E00FF>
|
||||||
* E0000..E0FFF ;<unassigned-E0FFF>
|
* E0100..E01EF # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
|
||||||
|
* E01F0..E0FFF # Cn [3600] <reserved-E01F0>..<reserved-E0FFF>
|
||||||
*/
|
*/
|
||||||
inline hb_bool_t
|
static inline hb_bool_t
|
||||||
is_default_ignorable (hb_codepoint_t ch)
|
is_default_ignorable (hb_codepoint_t ch)
|
||||||
{
|
{
|
||||||
hb_codepoint_t plane = ch >> 16;
|
hb_codepoint_t plane = ch >> 16;
|
||||||
@ -176,16 +174,16 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
|
|||||||
/* BMP */
|
/* BMP */
|
||||||
hb_codepoint_t page = ch >> 8;
|
hb_codepoint_t page = ch >> 8;
|
||||||
switch (page) {
|
switch (page) {
|
||||||
case 0x00: return unlikely (ch == 0x00AD);
|
case 0x00: return unlikely (ch == 0x00ADu);
|
||||||
case 0x03: return unlikely (ch == 0x034F);
|
case 0x03: return unlikely (ch == 0x034Fu);
|
||||||
case 0x06: return unlikely (ch == 0x061C);
|
case 0x06: return unlikely (ch == 0x061Cu);
|
||||||
case 0x17: return hb_in_range<hb_codepoint_t> (ch, 0x17B4, 0x17B5);
|
case 0x17: return hb_in_range (ch, 0x17B4u, 0x17B5u);
|
||||||
case 0x18: return hb_in_range<hb_codepoint_t> (ch, 0x180B, 0x180E);
|
case 0x18: return hb_in_range (ch, 0x180Bu, 0x180Eu);
|
||||||
case 0x20: return hb_in_ranges<hb_codepoint_t> (ch, 0x200B, 0x200F,
|
case 0x20: return hb_in_ranges (ch, 0x200Bu, 0x200Fu,
|
||||||
0x202A, 0x202E,
|
0x202Au, 0x202Eu,
|
||||||
0x2060, 0x206F);
|
0x2060u, 0x206Fu);
|
||||||
case 0xFE: return hb_in_range<hb_codepoint_t> (ch, 0xFE00, 0xFE0F) || ch == 0xFEFF;
|
case 0xFE: return hb_in_range (ch, 0xFE00u, 0xFE0Fu) || ch == 0xFEFFu;
|
||||||
case 0xFF: return hb_in_range<hb_codepoint_t> (ch, 0xFFF0, 0xFFF8);
|
case 0xFF: return hb_in_range (ch, 0xFFF0u, 0xFFF8u);
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,8 +191,9 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
|
|||||||
{
|
{
|
||||||
/* Other planes */
|
/* Other planes */
|
||||||
switch (plane) {
|
switch (plane) {
|
||||||
case 0x01: return hb_in_range<hb_codepoint_t> (ch, 0x0001D173, 0x0001D17A);
|
case 0x01: return hb_in_ranges (ch, 0x1BCA0u, 0x1BCA3u,
|
||||||
case 0x0E: return hb_in_range<hb_codepoint_t> (ch, 0x000E0000, 0x000E0FFF);
|
0x1D173u, 0x1D17Au);
|
||||||
|
case 0x0E: return hb_in_range (ch, 0xE0000u, 0xE0FFFu);
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ hb_unicode_funcs_get_default (void)
|
|||||||
|
|
||||||
#ifdef HAVE_GLIB
|
#ifdef HAVE_GLIB
|
||||||
HB_UNICODE_FUNCS_IMPLEMENT(glib)
|
HB_UNICODE_FUNCS_IMPLEMENT(glib)
|
||||||
#elif 0 && defined(HAVE_ICU)
|
#elif defined(HAVE_ICU) && defined(HAVE_ICU_BUILTIN)
|
||||||
HB_UNICODE_FUNCS_IMPLEMENT(icu)
|
HB_UNICODE_FUNCS_IMPLEMENT(icu)
|
||||||
#elif defined(HAVE_UCDN)
|
#elif defined(HAVE_UCDN)
|
||||||
HB_UNICODE_FUNCS_IMPLEMENT(ucdn)
|
HB_UNICODE_FUNCS_IMPLEMENT(ucdn)
|
||||||
@ -146,8 +146,13 @@ hb_unicode_funcs_get_default (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL)
|
#if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL)
|
||||||
#pragma message("Could not find any Unicode functions implementation, you have to provide your own.")
|
#ifdef _MSC_VER
|
||||||
#pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS.")
|
#pragma message("Could not find any Unicode functions implementation, you have to provide your own")
|
||||||
|
#pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS")
|
||||||
|
#else
|
||||||
|
#warning "Could not find any Unicode functions implementation, you have to provide your own"
|
||||||
|
#warning "To suppress this warning, define HB_NO_UNICODE_FUNCS"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -305,7 +310,7 @@ hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
|
|||||||
void
|
void
|
||||||
hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
|
hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
|
||||||
{
|
{
|
||||||
if (hb_object_is_inert (ufuncs))
|
if (unlikely (hb_object_is_inert (ufuncs)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ufuncs->immutable = true;
|
ufuncs->immutable = true;
|
||||||
|
@ -24,9 +24,6 @@
|
|||||||
* Google Author(s): Behdad Esfahbod
|
* Google Author(s): Behdad Esfahbod
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _WIN32_WINNT 0x0600
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
|
|
||||||
#define HB_SHAPER uniscribe
|
#define HB_SHAPER uniscribe
|
||||||
#include "hb-shaper-impl-private.hh"
|
#include "hb-shaper-impl-private.hh"
|
||||||
|
|
||||||
@ -313,6 +310,7 @@ _hb_generate_unique_face_name (wchar_t *face_name, unsigned int *plen)
|
|||||||
const char *enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-";
|
const char *enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-";
|
||||||
UUID id;
|
UUID id;
|
||||||
UuidCreate ((UUID*) &id);
|
UuidCreate ((UUID*) &id);
|
||||||
|
ASSERT_STATIC (2 + 3 * (16/2) < LF_FACESIZE);
|
||||||
unsigned int name_str_len = 0;
|
unsigned int name_str_len = 0;
|
||||||
face_name[name_str_len++] = 'F';
|
face_name[name_str_len++] = 'F';
|
||||||
face_name[name_str_len++] = '_';
|
face_name[name_str_len++] = '_';
|
||||||
@ -379,7 +377,7 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name)
|
|||||||
OT::NameRecord &record = name.nameRecord[i];
|
OT::NameRecord &record = name.nameRecord[i];
|
||||||
record.platformID.set (3);
|
record.platformID.set (3);
|
||||||
record.encodingID.set (1);
|
record.encodingID.set (1);
|
||||||
record.languageID.set (0x0409); /* English */
|
record.languageID.set (0x0409u); /* English */
|
||||||
record.nameID.set (name_IDs[i]);
|
record.nameID.set (name_IDs[i]);
|
||||||
record.length.set (name_str_len * 2);
|
record.length.set (name_str_len * 2);
|
||||||
record.offset.set (0);
|
record.offset.set (0);
|
||||||
@ -631,7 +629,7 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan,
|
|||||||
event->start = false;
|
event->start = false;
|
||||||
event->feature = feature;
|
event->feature = feature;
|
||||||
}
|
}
|
||||||
feature_events.sort ();
|
feature_events.qsort ();
|
||||||
/* Add a strategic final event. */
|
/* Add a strategic final event. */
|
||||||
{
|
{
|
||||||
active_feature_t feature;
|
active_feature_t feature;
|
||||||
@ -663,7 +661,7 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan,
|
|||||||
|
|
||||||
unsigned int offset = feature_records.len;
|
unsigned int offset = feature_records.len;
|
||||||
|
|
||||||
active_features.sort ();
|
active_features.qsort ();
|
||||||
for (unsigned int j = 0; j < active_features.len; j++)
|
for (unsigned int j = 0; j < active_features.len; j++)
|
||||||
{
|
{
|
||||||
if (!j || active_features[j].rec.tagFeature != feature_records[feature_records.len - 1].tagFeature)
|
if (!j || active_features[j].rec.tagFeature != feature_records[feature_records.len - 1].tagFeature)
|
||||||
@ -749,13 +747,13 @@ retry:
|
|||||||
{
|
{
|
||||||
hb_codepoint_t c = buffer->info[i].codepoint;
|
hb_codepoint_t c = buffer->info[i].codepoint;
|
||||||
buffer->info[i].utf16_index() = chars_len;
|
buffer->info[i].utf16_index() = chars_len;
|
||||||
if (likely (c < 0x10000))
|
if (likely (c <= 0xFFFFu))
|
||||||
pchars[chars_len++] = c;
|
pchars[chars_len++] = c;
|
||||||
else if (unlikely (c >= 0x110000))
|
else if (unlikely (c > 0x10FFFFu))
|
||||||
pchars[chars_len++] = 0xFFFD;
|
pchars[chars_len++] = 0xFFFDu;
|
||||||
else {
|
else {
|
||||||
pchars[chars_len++] = 0xD800 + ((c - 0x10000) >> 10);
|
pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10);
|
||||||
pchars[chars_len++] = 0xDC00 + ((c - 0x10000) & ((1 << 10) - 1));
|
pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1 << 10) - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,7 +769,7 @@ retry:
|
|||||||
hb_codepoint_t c = buffer->info[i].codepoint;
|
hb_codepoint_t c = buffer->info[i].codepoint;
|
||||||
unsigned int cluster = buffer->info[i].cluster;
|
unsigned int cluster = buffer->info[i].cluster;
|
||||||
log_clusters[chars_len++] = cluster;
|
log_clusters[chars_len++] = cluster;
|
||||||
if (c >= 0x10000 && c < 0x110000)
|
if (hb_in_range (c, 0x10000u, 0x10FFFFu))
|
||||||
log_clusters[chars_len++] = cluster; /* Surrogates. */
|
log_clusters[chars_len++] = cluster; /* Surrogates. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,6 @@
|
|||||||
|
|
||||||
#include "hb.h"
|
#include "hb.h"
|
||||||
|
|
||||||
#ifndef _WIN32_WINNT
|
|
||||||
#define _WIN32_WINNT 0x0600
|
|
||||||
#endif
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
HB_BEGIN_DECLS
|
HB_BEGIN_DECLS
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2011,2012 Google, Inc.
|
* Copyright © 2011,2012,2014 Google, Inc.
|
||||||
*
|
*
|
||||||
* This is part of HarfBuzz, a text shaping library.
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
*
|
*
|
||||||
@ -29,176 +29,221 @@
|
|||||||
|
|
||||||
#include "hb-private.hh"
|
#include "hb-private.hh"
|
||||||
|
|
||||||
|
template <typename T, bool validate=true> struct hb_utf_t;
|
||||||
|
|
||||||
|
|
||||||
/* UTF-8 */
|
/* UTF-8 */
|
||||||
|
|
||||||
#define HB_UTF8_COMPUTE(Char, Mask, Len) \
|
template <>
|
||||||
if (Char < 128) { Len = 1; Mask = 0x7f; } \
|
struct hb_utf_t<uint8_t, true>
|
||||||
else if ((Char & 0xe0) == 0xc0) { Len = 2; Mask = 0x1f; } \
|
|
||||||
else if ((Char & 0xf0) == 0xe0) { Len = 3; Mask = 0x0f; } \
|
|
||||||
else if ((Char & 0xf8) == 0xf0) { Len = 4; Mask = 0x07; } \
|
|
||||||
else Len = 0;
|
|
||||||
|
|
||||||
static inline const uint8_t *
|
|
||||||
hb_utf_next (const uint8_t *text,
|
|
||||||
const uint8_t *end,
|
|
||||||
hb_codepoint_t *unicode)
|
|
||||||
{
|
{
|
||||||
hb_codepoint_t c = *text, mask;
|
static inline const uint8_t *
|
||||||
unsigned int len;
|
next (const uint8_t *text,
|
||||||
|
const uint8_t *end,
|
||||||
|
hb_codepoint_t *unicode,
|
||||||
|
hb_codepoint_t replacement)
|
||||||
|
{
|
||||||
|
/* Written to only accept well-formed sequences.
|
||||||
|
* Based on ideas from ICU's U8_NEXT.
|
||||||
|
* Generates one "replacement" for each ill-formed byte. */
|
||||||
|
|
||||||
/* TODO check for overlong sequences? */
|
hb_codepoint_t c = *text++;
|
||||||
|
|
||||||
HB_UTF8_COMPUTE (c, mask, len);
|
if (c > 0x7Fu)
|
||||||
if (unlikely (!len || (unsigned int) (end - text) < len)) {
|
{
|
||||||
*unicode = -1;
|
if (hb_in_range (c, 0xC2u, 0xDFu)) /* Two-byte */
|
||||||
return text + 1;
|
|
||||||
} else {
|
|
||||||
hb_codepoint_t result;
|
|
||||||
unsigned int i;
|
|
||||||
result = c & mask;
|
|
||||||
for (i = 1; i < len; i++)
|
|
||||||
{
|
{
|
||||||
if (unlikely ((text[i] & 0xc0) != 0x80))
|
unsigned int t1;
|
||||||
{
|
if (likely (text < end &&
|
||||||
*unicode = -1;
|
(t1 = text[0] - 0x80u) <= 0x3Fu))
|
||||||
return text + 1;
|
{
|
||||||
}
|
c = ((c&0x1Fu)<<6) | t1;
|
||||||
result <<= 6;
|
text++;
|
||||||
result |= (text[i] & 0x3f);
|
}
|
||||||
|
else
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
*unicode = result;
|
else if (hb_in_range (c, 0xE0u, 0xEFu)) /* Three-byte */
|
||||||
return text + len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const uint8_t *
|
|
||||||
hb_utf_prev (const uint8_t *text,
|
|
||||||
const uint8_t *start,
|
|
||||||
hb_codepoint_t *unicode)
|
|
||||||
{
|
|
||||||
const uint8_t *end = text--;
|
|
||||||
while (start < text && (*text & 0xc0) == 0x80 && end - text < 4)
|
|
||||||
text--;
|
|
||||||
|
|
||||||
hb_codepoint_t c = *text, mask;
|
|
||||||
unsigned int len;
|
|
||||||
|
|
||||||
/* TODO check for overlong sequences? */
|
|
||||||
|
|
||||||
HB_UTF8_COMPUTE (c, mask, len);
|
|
||||||
if (unlikely (!len || (unsigned int) (end - text) != len)) {
|
|
||||||
*unicode = -1;
|
|
||||||
return end - 1;
|
|
||||||
} else {
|
|
||||||
hb_codepoint_t result;
|
|
||||||
unsigned int i;
|
|
||||||
result = c & mask;
|
|
||||||
for (i = 1; i < len; i++)
|
|
||||||
{
|
{
|
||||||
result <<= 6;
|
unsigned int t1, t2;
|
||||||
result |= (text[i] & 0x3f);
|
if (likely (1 < end - text &&
|
||||||
|
(t1 = text[0] - 0x80u) <= 0x3Fu &&
|
||||||
|
(t2 = text[1] - 0x80u) <= 0x3Fu))
|
||||||
|
{
|
||||||
|
c = ((c&0xFu)<<12) | (t1<<6) | t2;
|
||||||
|
if (unlikely (c < 0x0800u || hb_in_range (c, 0xD800u, 0xDFFFu)))
|
||||||
|
goto error;
|
||||||
|
text += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
*unicode = result;
|
else if (hb_in_range (c, 0xF0u, 0xF4u)) /* Four-byte */
|
||||||
|
{
|
||||||
|
unsigned int t1, t2, t3;
|
||||||
|
if (likely (2 < end - text &&
|
||||||
|
(t1 = text[0] - 0x80u) <= 0x3Fu &&
|
||||||
|
(t2 = text[1] - 0x80u) <= 0x3Fu &&
|
||||||
|
(t3 = text[2] - 0x80u) <= 0x3Fu))
|
||||||
|
{
|
||||||
|
c = ((c&0x7u)<<18) | (t1<<12) | (t2<<6) | t3;
|
||||||
|
if (unlikely (!hb_in_range (c, 0x10000u, 0x10FFFFu)))
|
||||||
|
goto error;
|
||||||
|
text += 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
*unicode = c;
|
||||||
|
return text;
|
||||||
|
|
||||||
|
error:
|
||||||
|
*unicode = replacement;
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
static inline const uint8_t *
|
||||||
|
prev (const uint8_t *text,
|
||||||
|
const uint8_t *start,
|
||||||
|
hb_codepoint_t *unicode,
|
||||||
|
hb_codepoint_t replacement)
|
||||||
|
{
|
||||||
|
const uint8_t *end = text--;
|
||||||
|
while (start < text && (*text & 0xc0) == 0x80 && end - text < 4)
|
||||||
|
text--;
|
||||||
|
|
||||||
static inline unsigned int
|
if (likely (next (text, end, unicode, replacement) == end))
|
||||||
hb_utf_strlen (const uint8_t *text)
|
return text;
|
||||||
{
|
|
||||||
return strlen ((const char *) text);
|
*unicode = replacement;
|
||||||
}
|
return end - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned int
|
||||||
|
strlen (const uint8_t *text)
|
||||||
|
{
|
||||||
|
return ::strlen ((const char *) text);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* UTF-16 */
|
/* UTF-16 */
|
||||||
|
|
||||||
static inline const uint16_t *
|
template <>
|
||||||
hb_utf_next (const uint16_t *text,
|
struct hb_utf_t<uint16_t, true>
|
||||||
const uint16_t *end,
|
|
||||||
hb_codepoint_t *unicode)
|
|
||||||
{
|
{
|
||||||
hb_codepoint_t c = *text++;
|
static inline const uint16_t *
|
||||||
|
next (const uint16_t *text,
|
||||||
if (unlikely (hb_in_range<hb_codepoint_t> (c, 0xd800, 0xdbff)))
|
const uint16_t *end,
|
||||||
|
hb_codepoint_t *unicode,
|
||||||
|
hb_codepoint_t replacement)
|
||||||
{
|
{
|
||||||
/* high surrogate */
|
hb_codepoint_t c = *text++;
|
||||||
hb_codepoint_t l;
|
|
||||||
if (text < end && ((l = *text), likely (hb_in_range<hb_codepoint_t> (l, 0xdc00, 0xdfff))))
|
if (likely (!hb_in_range (c, 0xD800u, 0xDFFFu)))
|
||||||
{
|
{
|
||||||
/* low surrogate */
|
*unicode = c;
|
||||||
*unicode = (c << 10) + l - ((0xd800 << 10) - 0x10000 + 0xdc00);
|
return text;
|
||||||
text++;
|
}
|
||||||
} else
|
|
||||||
*unicode = -1;
|
|
||||||
} else
|
|
||||||
*unicode = c;
|
|
||||||
|
|
||||||
return text;
|
if (likely (hb_in_range (c, 0xD800u, 0xDBFFu)))
|
||||||
}
|
{
|
||||||
|
/* High-surrogate in c */
|
||||||
|
hb_codepoint_t l;
|
||||||
|
if (text < end && ((l = *text), likely (hb_in_range (l, 0xDC00u, 0xDFFFu))))
|
||||||
|
{
|
||||||
|
/* Low-surrogate in l */
|
||||||
|
*unicode = (c << 10) + l - ((0xD800u << 10) - 0x10000u + 0xDC00u);
|
||||||
|
text++;
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline const uint16_t *
|
/* Lonely / out-of-order surrogate. */
|
||||||
hb_utf_prev (const uint16_t *text,
|
*unicode = replacement;
|
||||||
const uint16_t *start,
|
return text;
|
||||||
hb_codepoint_t *unicode)
|
}
|
||||||
{
|
|
||||||
hb_codepoint_t c = *--text;
|
|
||||||
|
|
||||||
if (unlikely (hb_in_range<hb_codepoint_t> (c, 0xdc00, 0xdfff)))
|
static inline const uint16_t *
|
||||||
|
prev (const uint16_t *text,
|
||||||
|
const uint16_t *start,
|
||||||
|
hb_codepoint_t *unicode,
|
||||||
|
hb_codepoint_t replacement)
|
||||||
{
|
{
|
||||||
/* low surrogate */
|
const uint16_t *end = text--;
|
||||||
hb_codepoint_t h;
|
hb_codepoint_t c = *text;
|
||||||
if (start < text && ((h = *(text - 1)), likely (hb_in_range<hb_codepoint_t> (h, 0xd800, 0xdbff))))
|
|
||||||
|
if (likely (!hb_in_range (c, 0xD800u, 0xDFFFu)))
|
||||||
{
|
{
|
||||||
/* high surrogate */
|
*unicode = c;
|
||||||
*unicode = (h << 10) + c - ((0xd800 << 10) - 0x10000 + 0xdc00);
|
return text;
|
||||||
text--;
|
}
|
||||||
} else
|
|
||||||
*unicode = -1;
|
|
||||||
} else
|
|
||||||
*unicode = c;
|
|
||||||
|
|
||||||
return text;
|
if (likely (start < text && hb_in_range (c, 0xDC00u, 0xDFFFu)))
|
||||||
}
|
text--;
|
||||||
|
|
||||||
|
if (likely (next (text, end, unicode, replacement) == end))
|
||||||
|
return text;
|
||||||
|
|
||||||
|
*unicode = replacement;
|
||||||
|
return end - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline unsigned int
|
static inline unsigned int
|
||||||
hb_utf_strlen (const uint16_t *text)
|
strlen (const uint16_t *text)
|
||||||
{
|
{
|
||||||
unsigned int l = 0;
|
unsigned int l = 0;
|
||||||
while (*text++) l++;
|
while (*text++) l++;
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* UTF-32 */
|
/* UTF-32 */
|
||||||
|
|
||||||
static inline const uint32_t *
|
template <bool validate>
|
||||||
hb_utf_next (const uint32_t *text,
|
struct hb_utf_t<uint32_t, validate>
|
||||||
const uint32_t *end HB_UNUSED,
|
|
||||||
hb_codepoint_t *unicode)
|
|
||||||
{
|
{
|
||||||
*unicode = *text++;
|
static inline const uint32_t *
|
||||||
return text;
|
next (const uint32_t *text,
|
||||||
}
|
const uint32_t *end HB_UNUSED,
|
||||||
|
hb_codepoint_t *unicode,
|
||||||
|
hb_codepoint_t replacement)
|
||||||
|
{
|
||||||
|
hb_codepoint_t c = *text++;
|
||||||
|
if (validate && unlikely (c > 0x10FFFFu || hb_in_range (c, 0xD800u, 0xDFFFu)))
|
||||||
|
goto error;
|
||||||
|
*unicode = c;
|
||||||
|
return text;
|
||||||
|
|
||||||
static inline const uint32_t *
|
error:
|
||||||
hb_utf_prev (const uint32_t *text,
|
*unicode = replacement;
|
||||||
const uint32_t *start HB_UNUSED,
|
return text;
|
||||||
hb_codepoint_t *unicode)
|
}
|
||||||
{
|
|
||||||
*unicode = *--text;
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned int
|
static inline const uint32_t *
|
||||||
hb_utf_strlen (const uint32_t *text)
|
prev (const uint32_t *text,
|
||||||
{
|
const uint32_t *start HB_UNUSED,
|
||||||
unsigned int l = 0;
|
hb_codepoint_t *unicode,
|
||||||
while (*text++) l++;
|
hb_codepoint_t replacement)
|
||||||
return l;
|
{
|
||||||
}
|
next (text - 1, text, unicode, replacement);
|
||||||
|
return text - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned int
|
||||||
|
strlen (const uint32_t *text)
|
||||||
|
{
|
||||||
|
unsigned int l = 0;
|
||||||
|
while (*text++) l++;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* HB_UTF_PRIVATE_HH */
|
#endif /* HB_UTF_PRIVATE_HH */
|
||||||
|
@ -38,12 +38,12 @@ HB_BEGIN_DECLS
|
|||||||
|
|
||||||
#define HB_VERSION_MAJOR 0
|
#define HB_VERSION_MAJOR 0
|
||||||
#define HB_VERSION_MINOR 9
|
#define HB_VERSION_MINOR 9
|
||||||
#define HB_VERSION_MICRO 25
|
#define HB_VERSION_MICRO 34
|
||||||
|
|
||||||
#define HB_VERSION_STRING "0.9.25"
|
#define HB_VERSION_STRING "0.9.34"
|
||||||
|
|
||||||
#define HB_VERSION_CHECK(major,minor,micro) \
|
#define HB_VERSION_ATLEAST(major,minor,micro) \
|
||||||
((major)*10000+(minor)*100+(micro) >= \
|
((major)*10000+(minor)*100+(micro) <= \
|
||||||
HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO)
|
HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO)
|
||||||
|
|
||||||
|
|
||||||
@ -56,9 +56,9 @@ const char *
|
|||||||
hb_version_string (void);
|
hb_version_string (void);
|
||||||
|
|
||||||
hb_bool_t
|
hb_bool_t
|
||||||
hb_version_check (unsigned int major,
|
hb_version_atleast (unsigned int major,
|
||||||
unsigned int minor,
|
unsigned int minor,
|
||||||
unsigned int micro);
|
unsigned int micro);
|
||||||
|
|
||||||
|
|
||||||
HB_END_DECLS
|
HB_END_DECLS
|
||||||
|
@ -42,8 +42,8 @@ HB_BEGIN_DECLS
|
|||||||
|
|
||||||
#define HB_VERSION_STRING "@HB_VERSION@"
|
#define HB_VERSION_STRING "@HB_VERSION@"
|
||||||
|
|
||||||
#define HB_VERSION_CHECK(major,minor,micro) \
|
#define HB_VERSION_ATLEAST(major,minor,micro) \
|
||||||
((major)*10000+(minor)*100+(micro) >= \
|
((major)*10000+(minor)*100+(micro) <= \
|
||||||
HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO)
|
HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO)
|
||||||
|
|
||||||
|
|
||||||
@ -56,9 +56,9 @@ const char *
|
|||||||
hb_version_string (void);
|
hb_version_string (void);
|
||||||
|
|
||||||
hb_bool_t
|
hb_bool_t
|
||||||
hb_version_check (unsigned int major,
|
hb_version_atleast (unsigned int major,
|
||||||
unsigned int minor,
|
unsigned int minor,
|
||||||
unsigned int micro);
|
unsigned int micro);
|
||||||
|
|
||||||
|
|
||||||
HB_END_DECLS
|
HB_END_DECLS
|
||||||
|
@ -53,14 +53,3 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "hb-unicode-private.hh"
|
|
||||||
|
|
||||||
#if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL)
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma message("Could not find any Unicode functions implementation, you have to provide your own")
|
|
||||||
#pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS")
|
|
||||||
#else
|
|
||||||
#warning "Could not find any Unicode functions implementation, you have to provide your own"
|
|
||||||
#warning "To suppress this warning, define HB_NO_UNICODE_FUNCS"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
@ -131,8 +131,11 @@ main (int argc, char **argv)
|
|||||||
else
|
else
|
||||||
printf (" Language System %2d of %2d: %.4s\n", n_langsys, num_langsys,
|
printf (" Language System %2d of %2d: %.4s\n", n_langsys, num_langsys,
|
||||||
(const char *)script.get_lang_sys_tag (n_langsys));
|
(const char *)script.get_lang_sys_tag (n_langsys));
|
||||||
if (langsys.get_required_feature_index () == Index::NOT_FOUND_INDEX)
|
if (!langsys.has_required_feature ())
|
||||||
printf (" No required feature\n");
|
printf (" No required feature\n");
|
||||||
|
else
|
||||||
|
printf (" Required feature index: %d\n",
|
||||||
|
langsys.get_required_feature_index ());
|
||||||
|
|
||||||
int num_features = langsys.get_feature_count ();
|
int num_features = langsys.get_feature_count ();
|
||||||
printf (" %d feature(s) found in language system\n", num_features);
|
printf (" %d feature(s) found in language system\n", num_features);
|
||||||
@ -147,11 +150,10 @@ main (int argc, char **argv)
|
|||||||
printf (" %d feature(s) found in table\n", num_features);
|
printf (" %d feature(s) found in table\n", num_features);
|
||||||
for (int n_feature = 0; n_feature < num_features; n_feature++) {
|
for (int n_feature = 0; n_feature < num_features; n_feature++) {
|
||||||
const Feature &feature = g.get_feature (n_feature);
|
const Feature &feature = g.get_feature (n_feature);
|
||||||
printf (" Feature %2d of %2d: %.4s; %d lookup(s)\n", n_feature, num_features,
|
|
||||||
(const char *)g.get_feature_tag(n_feature),
|
|
||||||
feature.get_lookup_count());
|
|
||||||
|
|
||||||
int num_lookups = feature.get_lookup_count ();
|
int num_lookups = feature.get_lookup_count ();
|
||||||
|
printf (" Feature %2d of %2d: %c%c%c%c\n", n_feature, num_features,
|
||||||
|
HB_UNTAG(g.get_feature_tag(n_feature)));
|
||||||
|
|
||||||
printf (" %d lookup(s) found in feature\n", num_lookups);
|
printf (" %d lookup(s) found in feature\n", num_lookups);
|
||||||
for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) {
|
for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) {
|
||||||
printf (" Lookup index %2d of %2d: %d\n", n_lookup, num_lookups,
|
printf (" Lookup index %2d of %2d: %d\n", n_lookup, num_lookups,
|
||||||
|
@ -11,6 +11,7 @@ EXPORTS.harfbuzz += [
|
|||||||
'hb-deprecated.h',
|
'hb-deprecated.h',
|
||||||
'hb-face.h',
|
'hb-face.h',
|
||||||
'hb-font.h',
|
'hb-font.h',
|
||||||
|
'hb-ot-font.h',
|
||||||
'hb-ot-layout.h',
|
'hb-ot-layout.h',
|
||||||
'hb-ot-shape.h',
|
'hb-ot-shape.h',
|
||||||
'hb-ot-tag.h',
|
'hb-ot-tag.h',
|
||||||
|
Loading…
Reference in New Issue
Block a user