From e2c95116e1423f83a692d6170553d0cc95733d24 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 20 Jul 2015 11:32:48 +0100 Subject: [PATCH 01/43] [USE] Add Universal Shaping Engine to Makefile --- src/Makefile.am | 23 ++- src/gen-use-table.py | 237 +++++++++++++++++++++++++ src/hb-ot-shape-complex-use-machine.rl | 0 src/hb-ot-shape-complex-use-private.hh | 0 src/hb-ot-shape-complex-use-table.cc | 0 src/hb-ot-shape-complex-use.cc | 0 6 files changed, 254 insertions(+), 6 deletions(-) create mode 100755 src/gen-use-table.py create mode 100644 src/hb-ot-shape-complex-use-machine.rl create mode 100644 src/hb-ot-shape-complex-use-private.hh create mode 100644 src/hb-ot-shape-complex-use-table.cc create mode 100644 src/hb-ot-shape-complex-use.cc diff --git a/src/Makefile.am b/src/Makefile.am index c99967f69..ceb3eba25 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -108,6 +108,10 @@ HBSOURCES += \ hb-ot-shape-complex-sea-machine.hh \ hb-ot-shape-complex-thai.cc \ hb-ot-shape-complex-tibetan.cc \ + hb-ot-shape-complex-use.cc \ + hb-ot-shape-complex-use-machine.hh \ + hb-ot-shape-complex-use-private.hh \ + hb-ot-shape-complex-use-table.cc \ hb-ot-shape-complex-private.hh \ hb-ot-shape-normalize-private.hh \ hb-ot-shape-normalize.cc \ @@ -276,22 +280,27 @@ harfbuzz.def: $(HBHEADERS) $(HBNODISTHEADERS) GENERATORS = \ gen-arabic-table.py \ gen-indic-table.py \ + gen-use-table.py \ $(NULL) EXTRA_DIST += $(GENERATORS) -unicode-tables: arabic-table indic-table - -indic-table: gen-indic-table.py IndicSyllabicCategory.txt IndicMatraCategory.txt Blocks.txt - $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-indic-table.cc \ - || ($(RM) hb-ot-shape-complex-indic-table.cc; false) +unicode-tables: arabic-table indic-table use-table arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-arabic-table.hh \ || ($(RM) hb-ot-shape-complex-arabic-table.hh; false) +indic-table: gen-indic-table.py IndicSyllabicCategory-7.0.0.txt IndicMatraCategory-7.0.0.txt Blocks.txt + $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-indic-table.cc \ + || ($(RM) hb-ot-shape-complex-indic-table.cc; false) + +use-table: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt + $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-use-table.cc \ + || ($(RM) hb-ot-shape-complex-use-table.cc; false) + built-sources: $(BUILT_SOURCES) -.PHONY: unicode-tables arabic-table indic-table built-sources +.PHONY: unicode-tables arabic-table indic-table use-table built-sources RAGEL_GENERATED = \ $(srcdir)/hb-buffer-deserialize-json.hh \ @@ -299,6 +308,7 @@ RAGEL_GENERATED = \ $(srcdir)/hb-ot-shape-complex-indic-machine.hh \ $(srcdir)/hb-ot-shape-complex-myanmar-machine.hh \ $(srcdir)/hb-ot-shape-complex-sea-machine.hh \ + $(srcdir)/hb-ot-shape-complex-use-machine.hh \ $(NULL) BUILT_SOURCES += $(RAGEL_GENERATED) EXTRA_DIST += \ @@ -307,6 +317,7 @@ EXTRA_DIST += \ hb-ot-shape-complex-indic-machine.rl \ hb-ot-shape-complex-myanmar-machine.rl \ hb-ot-shape-complex-sea-machine.rl \ + hb-ot-shape-complex-use-machine.rl \ $(NULL) MAINTAINERCLEANFILES += $(RAGEL_GENERATED) $(srcdir)/%.hh: $(srcdir)/%.rl diff --git a/src/gen-use-table.py b/src/gen-use-table.py new file mode 100755 index 000000000..f5716bda7 --- /dev/null +++ b/src/gen-use-table.py @@ -0,0 +1,237 @@ +#!/usr/bin/python + +import sys + +if len (sys.argv) != 4: + print >>sys.stderr, "usage: ./gen-indic-table.py IndicSyllabicCategory.txt IndicMatraCategory.txt Blocks.txt" + sys.exit (1) + +BLACKLISTED_BLOCKS = ["Thai", "Lao", "Tibetan"] + +files = [file (x) for x in sys.argv[1:]] + +headers = [[f.readline () for i in range (2)] for f in files] + +data = [{} for f in files] +values = [{} for f in files] +for i, f in enumerate (files): + 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): + data[i][u] = t + values[i][t] = values[i].get (t, 0) + end - start + 1 + +# Merge data into one dict: +defaults = ('Other', 'Not_Applicable', 'No_Block') +for i,v in enumerate (defaults): + values[i][v] = values[i].get (v, 0) + 1 +combined = {} +for i,d in enumerate (data): + for u,v in d.items (): + if i == 2 and not u in combined: + continue + if not u in combined: + combined[u] = list (defaults) + combined[u][i] = v +combined = {k:v for k,v in combined.items() if v[2] not in BLACKLISTED_BLOCKS} +data = combined +del combined +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 +singles = {} +for u in [0x00A0, 0x25CC]: + singles[u] = data[u] + del data[u] + +print "/* == Start of generated table == */" +print "/*" +print " * The following table is generated by running:" +print " *" +print " * ./gen-indic-table.py IndicSyllabicCategory.txt IndicMatraCategory.txt Blocks.txt" +print " *" +print " * on files with these headers:" +print " *" +for h in headers: + for l in h: + print " * %s" % (l.strip()) +print " */" +print +print '#include "hb-ot-shape-complex-indic-private.hh"' +print + +# Shorten values +short = [{ + "Bindu": 'Bi', + "Cantillation_Mark": 'Ca', + "Joiner": 'ZWJ', + "Non_Joiner": 'ZWNJ', + "Number": 'Nd', + "Visarga": 'Vs', + "Vowel": 'Vo', + "Vowel_Dependent": 'M', + "Other": 'x', +},{ + "Not_Applicable": 'x', +}] +all_shorts = [{},{}] + +# Add some of the values, to make them more readable, and to avoid duplicates + + +for i in range (2): + for v,s in short[i].items (): + all_shorts[i][s] = v + +what = ["INDIC_SYLLABIC_CATEGORY", "INDIC_MATRA_CATEGORY"] +what_short = ["ISC", "IMC"] +for i in range (2): + print + vv = values[i].keys () + vv.sort () + for v in vv: + v_no_and = v.replace ('_And_', '_') + if v in short[i]: + s = short[i][v] + else: + s = ''.join ([c for c in v_no_and if ord ('A') <= ord (c) <= ord ('Z')]) + if s in all_shorts[i]: + raise Exception ("Duplicate short value alias", v, all_shorts[i][s]) + all_shorts[i][s] = v + short[i][v] = s + print "#define %s_%s %s_%s %s/* %3d chars; %s */" % \ + (what_short[i], s, what[i], v.upper (), \ + ' '* ((48-1 - len (what[i]) - 1 - len (v)) / 8), \ + values[i][v], v) +print +print "#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)" +print +print + +total = 0 +used = 0 +last_block = None +def print_block (block, start, end, data): + global total, used, last_block + if block and block != last_block: + print + print + print " /* %s */" % block + num = 0 + assert start % 8 == 0 + assert (end+1) % 8 == 0 + for u in range (start, end+1): + if u % 8 == 0: + print + print " /* %04X */" % u, + if u in data: + num += 1 + d = data.get (u, defaults) + sys.stdout.write ("%9s" % ("_(%s,%s)," % (short[0][d[0]], short[1][d[1]]))) + + total += end - start + 1 + used += num + if block: + last_block = block + +uu = data.keys () +uu.sort () + +last = -100000 +num = 0 +offset = 0 +starts = [] +ends = [] +print "static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {" +for u in uu: + if u <= last: + continue + block = data[u][2] + + 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+16*3: + print_block (None, last+1, start-1, data) + last = start-1 + else: + if last >= 0: + ends.append (last + 1) + offset += ends[-1] - starts[-1] + print + print + print "#define indic_offset_0x%04xu %d" % (start, offset) + starts.append (start) + + print_block (block, start, end, data) + last = end +ends.append (last + 1) +offset += ends[-1] - starts[-1] +print +print +occupancy = used * 100. / total +page_bits = 12 +print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy) +print +print "INDIC_TABLE_ELEMENT_TYPE" +print "hb_indic_get_categories (hb_codepoint_t u)" +print "{" +print " switch (u >> %d)" % page_bits +print " {" +pages = set([u>>page_bits for u in starts+ends+singles.keys()]) +for p in sorted(pages): + 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-1, 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 "}" +print +print "#undef _" +for i in range (2): + print + vv = values[i].keys () + vv.sort () + for v in vv: + print "#undef %s_%s" % \ + (what_short[i], short[i][v]) +print +print "/* == End of generated table == */" + +# Maintain at least 30% occupancy in the table */ +if occupancy < 30: + raise Exception ("Table too sparse, please investigate: ", occupancy) diff --git a/src/hb-ot-shape-complex-use-machine.rl b/src/hb-ot-shape-complex-use-machine.rl new file mode 100644 index 000000000..e69de29bb diff --git a/src/hb-ot-shape-complex-use-private.hh b/src/hb-ot-shape-complex-use-private.hh new file mode 100644 index 000000000..e69de29bb diff --git a/src/hb-ot-shape-complex-use-table.cc b/src/hb-ot-shape-complex-use-table.cc new file mode 100644 index 000000000..e69de29bb diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc new file mode 100644 index 000000000..e69de29bb From c48ff288522f33dc6c78520de0a0a74306630895 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 20 Jul 2015 11:46:17 +0100 Subject: [PATCH 02/43] [USE] Build Universal Shaping Engine data table from Unicode 8 files --- src/gen-use-table.py | 35 +- src/hb-ot-shape-complex-use-table.cc | 1016 ++++++++++++++++++++++++++ 2 files changed, 1032 insertions(+), 19 deletions(-) diff --git a/src/gen-use-table.py b/src/gen-use-table.py index f5716bda7..e4914ad99 100755 --- a/src/gen-use-table.py +++ b/src/gen-use-table.py @@ -3,7 +3,7 @@ import sys if len (sys.argv) != 4: - print >>sys.stderr, "usage: ./gen-indic-table.py IndicSyllabicCategory.txt IndicMatraCategory.txt Blocks.txt" + print >>sys.stderr, "usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt" sys.exit (1) BLACKLISTED_BLOCKS = ["Thai", "Lao", "Tibetan"] @@ -55,13 +55,9 @@ data = combined del combined 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 +# Remove the outliers singles = {} -for u in [0x00A0, 0x25CC]: +for u in []: # TODO [0x00A0, 0x200C, 0x200D, 0x25CC, 0x1107F]: singles[u] = data[u] del data[u] @@ -69,7 +65,7 @@ print "/* == Start of generated table == */" print "/*" print " * The following table is generated by running:" print " *" -print " * ./gen-indic-table.py IndicSyllabicCategory.txt IndicMatraCategory.txt Blocks.txt" +print " * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt" print " *" print " * on files with these headers:" print " *" @@ -78,7 +74,7 @@ for h in headers: print " * %s" % (l.strip()) print " */" print -print '#include "hb-ot-shape-complex-indic-private.hh"' +print '#include "hb-ot-shape-complex-use-private.hh"' print # Shorten values @@ -92,6 +88,7 @@ short = [{ "Vowel": 'Vo', "Vowel_Dependent": 'M', "Other": 'x', + "Consonant_Placeholder":'GB', },{ "Not_Applicable": 'x', }] @@ -104,8 +101,8 @@ for i in range (2): for v,s in short[i].items (): all_shorts[i][s] = v -what = ["INDIC_SYLLABIC_CATEGORY", "INDIC_MATRA_CATEGORY"] -what_short = ["ISC", "IMC"] +what = ["INDIC_SYLLABIC_CATEGORY", "INDIC_POSITIONAL_CATEGORY"] +what_short = ["SC", "PC"] for i in range (2): print vv = values[i].keys () @@ -122,10 +119,10 @@ for i in range (2): short[i][v] = s print "#define %s_%s %s_%s %s/* %3d chars; %s */" % \ (what_short[i], s, what[i], v.upper (), \ - ' '* ((48-1 - len (what[i]) - 1 - len (v)) / 8), \ + ' '* ((56-1 - len (what[i]) - 1 - len (v)) / 8), \ values[i][v], v) print -print "#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)" +print "#define _(S,M) USE_COMBINE_CATEGORIES (SC_##S, PC_##M)" print print @@ -163,7 +160,7 @@ num = 0 offset = 0 starts = [] ends = [] -print "static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {" +print "static const USE_TABLE_ELEMENT_TYPE use_table[] = {" for u in uu: if u <= last: continue @@ -185,7 +182,7 @@ for u in uu: offset += ends[-1] - starts[-1] print print - print "#define indic_offset_0x%04xu %d" % (start, offset) + print "#define use_offset_0x%04xu %d" % (start, offset) starts.append (start) print_block (block, start, end, data) @@ -198,8 +195,8 @@ occupancy = used * 100. / total page_bits = 12 print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy) print -print "INDIC_TABLE_ELEMENT_TYPE" -print "hb_indic_get_categories (hb_codepoint_t u)" +print "USE_TABLE_ELEMENT_TYPE" +print "hb_use_get_categories (hb_codepoint_t u)" print "{" print " switch (u >> %d)" % page_bits print " {" @@ -208,8 +205,8 @@ for p in sorted(pages): 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-1, start, offset) + offset = "use_offset_0x%04xu" % start + print " if (hb_in_range (u, 0x%04Xu, 0x%04Xu)) return use_table[u - 0x%04Xu + %s];" % (start, end-1, 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]]) diff --git a/src/hb-ot-shape-complex-use-table.cc b/src/hb-ot-shape-complex-use-table.cc index e69de29bb..9aa48c11b 100644 --- a/src/hb-ot-shape-complex-use-table.cc +++ b/src/hb-ot-shape-complex-use-table.cc @@ -0,0 +1,1016 @@ +/* == Start of generated table == */ +/* + * The following table is generated by running: + * + * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt + * + * on files with these headers: + * + * # IndicSyllabicCategory-8.0.0.txt + * # Date: 2015-05-12, 10:00:00 GMT [RP, KW, LI] + * # IndicPositionalCategory-8.0.0.txt + * # Date: 2015-05-12, 10:00:00 GMT [RP, KW, LI] + * # Blocks-8.0.0.txt + * # Date: 2014-11-10, 23:04:00 GMT [KW] + */ + +#include "hb-ot-shape-complex-use-private.hh" + + +#define SC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 13 chars; Avagraha */ +#define SC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 60 chars; Bindu */ +#define SC_BJN INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER /* 20 chars; Brahmi_Joining_Number */ +#define SC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 52 chars; Cantillation_Mark */ +#define SC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 1805 chars; Consonant */ +#define SC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 7 chars; Consonant_Dead */ +#define SC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 62 chars; Consonant_Final */ +#define SC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 5 chars; Consonant_Head_Letter */ +#define SC_CK INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER /* 2 chars; Consonant_Killer */ +#define SC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 22 chars; Consonant_Medial */ +#define SC_GB INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 13 chars; Consonant_Placeholder */ +#define SC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA /* 1 chars; Consonant_Preceding_Repha */ +#define SC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED /* 2 chars; Consonant_Prefixed */ +#define SC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 61 chars; Consonant_Subjoined */ +#define SC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 4 chars; Consonant_Succeeding_Repha */ +#define SC_CWS INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER /* 4 chars; Consonant_With_Stacker */ +#define SC_GM INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK /* 2 chars; Gemination_Mark */ +#define SC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER /* 7 chars; Invisible_Stacker */ +#define SC_ZWJ INDIC_SYLLABIC_CATEGORY_JOINER /* 1 chars; Joiner */ +#define SC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER /* 1 chars; Modifying_Letter */ +#define SC_ZWNJ INDIC_SYLLABIC_CATEGORY_NON_JOINER /* 1 chars; Non_Joiner */ +#define SC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 23 chars; Nukta */ +#define SC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 420 chars; Number */ +#define SC_NJ INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER /* 1 chars; Number_Joiner */ +#define SC_x INDIC_SYLLABIC_CATEGORY_OTHER /* 1 chars; Other */ +#define SC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 16 chars; Pure_Killer */ +#define SC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 2 chars; Register_Shifter */ +#define SC_SM INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER /* 20 chars; Syllable_Modifier */ +#define SC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 7 chars; Tone_Letter */ +#define SC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK /* 42 chars; Tone_Mark */ +#define SC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 22 chars; Virama */ +#define SC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 29 chars; Visarga */ +#define SC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 30 chars; Vowel */ +#define SC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 572 chars; Vowel_Dependent */ +#define SC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 404 chars; Vowel_Independent */ + +#define PC_B INDIC_POSITIONAL_CATEGORY_BOTTOM /* 256 chars; Bottom */ +#define PC_BR INDIC_POSITIONAL_CATEGORY_BOTTOM_AND_RIGHT /* 2 chars; Bottom_And_Right */ +#define PC_L INDIC_POSITIONAL_CATEGORY_LEFT /* 55 chars; Left */ +#define PC_LR INDIC_POSITIONAL_CATEGORY_LEFT_AND_RIGHT /* 21 chars; Left_And_Right */ +#define PC_x INDIC_POSITIONAL_CATEGORY_NOT_APPLICABLE /* 1 chars; Not_Applicable */ +#define PC_O INDIC_POSITIONAL_CATEGORY_OVERSTRUCK /* 10 chars; Overstruck */ +#define PC_R INDIC_POSITIONAL_CATEGORY_RIGHT /* 249 chars; Right */ +#define PC_T INDIC_POSITIONAL_CATEGORY_TOP /* 324 chars; Top */ +#define PC_TB INDIC_POSITIONAL_CATEGORY_TOP_AND_BOTTOM /* 10 chars; Top_And_Bottom */ +#define PC_TBR INDIC_POSITIONAL_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT /* 1 chars; Top_And_Bottom_And_Right */ +#define PC_TL INDIC_POSITIONAL_CATEGORY_TOP_AND_LEFT /* 6 chars; Top_And_Left */ +#define PC_TLR INDIC_POSITIONAL_CATEGORY_TOP_AND_LEFT_AND_RIGHT /* 4 chars; Top_And_Left_And_Right */ +#define PC_TR INDIC_POSITIONAL_CATEGORY_TOP_AND_RIGHT /* 13 chars; Top_And_Right */ +#define PC_VOL INDIC_POSITIONAL_CATEGORY_VISUAL_ORDER_LEFT /* 19 chars; Visual_Order_Left */ + +#define _(S,M) USE_COMBINE_CATEGORIES (SC_##S, PC_##M) + + +static const USE_TABLE_ELEMENT_TYPE use_table[] = { + + +#define use_offset_0x0028u 0 + + + /* Basic Latin */ + + /* 0028 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(GB,x), _(x,x), _(x,x), + /* 0030 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 0038 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + +#define use_offset_0x00a0u 24 + + + /* Latin-1 Supplement */ + + /* 00A0 */ _(GB,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 00A8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 00B0 */ _(x,x), _(x,x), _(SM,x), _(SM,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 00B8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 00C0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 00C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 00D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(GB,x), + +#define use_offset_0x0900u 80 + + + /* Devanagari */ + + /* 0900 */ _(Bi,T), _(Bi,T), _(Bi,T), _(Vs,R), _(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,B), _(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), _(Ca,T), _(Ca,B), _(x,T), _(x,T), _(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), _(Nd,x), _(Nd,x), + /* 0968 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 0970 */ _(x,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), + /* 0978 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + + /* Bengali */ + + /* 0980 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(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,B), _(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), _(Nd,x), _(Nd,x), + /* 09E8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,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 */ _(x,x), _(Bi,T), _(Bi,T), _(Vs,R), _(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,B), _(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), _(Nd,x), _(Nd,x), + /* 0A68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 0A70 */ _(Bi,T), _(GM,T), _(GB,x), _(GB,x), _(x,x), _(CM,B), _(x,x), _(x,x), + /* 0A78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Gujarati */ + + /* 0A80 */ _(x,x), _(Bi,T), _(Bi,T), _(Vs,R), _(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,B), _(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), _(Nd,x), _(Nd,x), + /* 0AE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 0AF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 0AF8 */ _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Oriya */ + + /* 0B00 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(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,B), _(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), _(Nd,x), _(Nd,x), + /* 0B68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,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 */ _(x,x), _(x,x), _(Bi,T), _(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,R), _(M,R), _(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), _(Nd,x), _(Nd,x), + /* 0BE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,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 */ _(Bi,T), _(Bi,R), _(Bi,R), _(Vs,R), _(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), _(C,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), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 0C60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), + /* 0C68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,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 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(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,B), _(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), _(Nd,x), _(Nd,x), + /* 0CE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 0CF0 */ _(x,x),_(CWS,x),_(CWS,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 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(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),_(CPR,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), _(VI,x), + /* 0D60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), + /* 0D68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,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 */ _(x,x), _(x,x), _(Bi,R), _(Vs,R), _(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,TLR), _(M,LR), _(M,R), + /* 0DE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x), + /* 0DE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 0DF0 */ _(x,x), _(x,x), _(M,R), _(M,R), _(x,x), _(x,x), _(x,x), _(x,x), + +#define use_offset_0x1000u 1352 + + + /* Myanmar */ + + /* 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,T), _(TM,B), + /* 1038 */ _(Vs,R), _(IS,x), _(PK,T), _(CM,R), _(CM,x), _(CM,B), _(CM,B), _(C,x), + /* 1040 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 1048 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(GB,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,B), _(CM,B), + /* 1060 */ _(CM,B), _(C,x), _(M,R), _(TM,R), _(TM,R), _(C,x), _(C,x), _(M,R), + /* 1068 */ _(M,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(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,B), _(M,R), _(M,L), _(M,T), _(M,T), _(TM,R), + /* 1088 */ _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,B), _(C,x), _(TM,R), + /* 1090 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 1098 */ _(Nd,x), _(Nd,x), _(TM,R), _(TM,R), _(M,R), _(M,T), _(x,x), _(x,x), + +#define use_offset_0x1700u 1512 + + + /* Tagalog */ + + /* 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), _(PK,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 */ _(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), _(PK,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 */ _(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 */ _(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 */ _(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,T), _(Vs,R), + /* 17C8 */ _(M,R), _(RS,T), _(RS,T), _(SM,T),_(CSR,T), _(CK,T), _(SM,T), _(SM,T), + /* 17D0 */ _(SM,T), _(PK,T), _(IS,x), _(SM,T), _(x,x), _(x,x), _(x,x), _(x,x), + /* 17D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(A,x), _(x,T), _(x,x), _(x,x), + /* 17E0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 17E8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + +#define use_offset_0x1900u 1752 + + + /* Limbu */ + + /* 1900 */ _(GB,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), _(C,x), _(C,x), _(x,x), + /* 1920 */ _(M,T), _(M,T), _(M,B), _(M,R), _(M,R), _(M,TR), _(M,TR), _(M,T), + /* 1928 */ _(M,T), _(CS,R), _(CS,R), _(CS,R), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1930 */ _(CF,R), _(CF,R), _(Bi,B), _(CF,R), _(CF,R), _(CF,R), _(CF,R), _(CF,R), + /* 1938 */ _(CF,R), _(CF,B), _(M,T), _(SM,B), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1940 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x), + /* 1948 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + + /* Tai Le */ + + /* 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 */ _(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,VOL),_(M,VOL),_(M,VOL), + /* 19B8 */ _(M,R), _(M,R),_(M,VOL), _(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,R), _(TM,R), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 19D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 19D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 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 */ _(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,T), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Tai Tham */ + + /* 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,L), _(CM,B), _(CF,R), + /* 1A58 */ _(CF,T), _(CF,T), _(CF,T), _(CF,B), _(CF,B), _(CF,B), _(CF,B), _(x,x), + /* 1A60 */ _(IS,x), _(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,T), _(TM,T), _(TM,T), + /* 1A78 */ _(TM,T), _(TM,T), _(SM,T), _(SM,T), _(SM,T), _(x,x), _(x,x), _(SM,B), + /* 1A80 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 1A88 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1A90 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 1A98 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + +#define use_offset_0x1b00u 2168 + + + /* Balinese */ + + /* 1B00 */ _(Bi,T), _(Bi,T), _(Bi,T),_(CSR,T), _(Vs,R), _(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,T), _(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 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 1B58 */ _(Nd,x), _(Nd,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,T), _(x,B), _(x,T), _(x,T), _(x,T), + /* 1B70 */ _(x,T), _(x,T), _(x,T), _(x,T), _(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 */ _(Bi,T),_(CSR,T), _(Vs,R), _(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,R), _(CS,B), _(CS,B), _(M,T), _(M,B), _(M,L), _(M,R), + /* 1BA8 */ _(M,T), _(M,T), _(PK,R), _(IS,x), _(CS,B), _(CS,B), _(C,x), _(C,x), + /* 1BB0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 1BB8 */ _(Nd,x), _(Nd,x), _(A,x), _(C,x), _(C,x), _(C,x), _(CF,x), _(CF,x), + + /* Batak */ + + /* 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,T), _(M,R), + /* 1BE8 */ _(M,T), _(M,T), _(M,R), _(M,R), _(M,R), _(M,T), _(M,R), _(M,T), + /* 1BF0 */ _(CF,T), _(CF,T), _(PK,R), _(PK,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 */ _(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,R), _(CS,R), _(M,R), _(M,L), + /* 1C28 */ _(M,L), _(M,TL), _(M,R), _(M,R), _(M,B), _(CF,T), _(CF,T), _(CF,T), + /* 1C30 */ _(CF,T), _(CF,T), _(CF,T), _(CF,T), _(Bi,L), _(Bi,L), _(SM,T), _(N,B), + /* 1C38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1C40 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 1C48 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), + +#define use_offset_0x1cd0u 2504 + + + /* Vedic Extensions */ + + /* 1CD0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(x,x), _(Ca,O), _(Ca,B), _(Ca,B), _(Ca,B), + /* 1CD8 */ _(Ca,B), _(Ca,B), _(Ca,T), _(Ca,T), _(Ca,B), _(Ca,B), _(Ca,B), _(Ca,B), + /* 1CE0 */ _(Ca,T), _(Ca,R), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O), + /* 1CE8 */ _(x,O), _(x,x), _(x,x), _(x,x), _(x,x), _(x,B), _(x,x), _(x,x), + /* 1CF0 */ _(x,x), _(x,x), _(Vs,x), _(Vs,x), _(Ca,T), _(x,x), _(x,x), _(x,x), + /* 1CF8 */ _(Ca,x), _(Ca,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + +#define use_offset_0x2008u 2552 + + + /* General Punctuation */ + + /* 2008 */ _(x,x), _(x,x), _(x,x), _(x,x),_(ZWNJ,x),_(ZWJ,x), _(x,x), _(x,x), + /* 2010 */ _(GB,x), _(GB,x), _(GB,x), _(GB,x), _(GB,x), _(x,x), _(x,x), _(x,x), + +#define use_offset_0x2070u 2568 + + + /* Superscripts and Subscripts */ + + /* 2070 */ _(x,x), _(x,x), _(x,x), _(x,x), _(SM,x), _(x,x), _(x,x), _(x,x), + /* 2078 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 2080 */ _(x,x), _(x,x), _(SM,x), _(SM,x), _(SM,x), _(x,x), _(x,x), _(x,x), + +#define use_offset_0x25c8u 2592 + + + /* Geometric Shapes */ + + /* 25C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(GB,x), _(x,x), _(x,x), _(x,x), + +#define use_offset_0xa800u 2600 + + + /* Syloti Nagri */ + + /* A800 */ _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(PK,T), _(C,x), + /* A808 */ _(C,x), _(C,x), _(C,x), _(Bi,T), _(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), + /* 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 */ _(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 */ _(Bi,R), _(Vs,R), _(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,R), _(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 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* A8D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Devanagari Extended */ + + /* A8E0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), + /* A8E8 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), + /* A8F0 */ _(Ca,T), _(Ca,T), _(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 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* A908 */ _(Nd,x), _(Nd,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,B), _(TM,B), _(TM,B), _(x,x), _(x,x), + + /* Rejang */ + + /* 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,T), + /* A950 */ _(CF,T), _(CF,T), _(CF,R), _(PK,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), + /* 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 */ _(Bi,T), _(Bi,T),_(CSR,T), _(Vs,R), _(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,T), _(M,R), _(M,R), _(M,T), _(M,T), + /* A9B8 */ _(M,B), _(M,B), _(M,L), _(M,L), _(M,T), _(CS,R), _(CM,R), _(CM,R), + /* 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 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* A9D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Myanmar Extended-B */ + + /* A9E0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,T), _(x,x), _(C,x), + /* A9E8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* A9F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* A9F8 */ _(Nd,x), _(Nd,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), + + /* Cham */ + + /* 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,R), _(CM,L), _(CM,B), _(CM,B), _(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,T), _(CF,x), _(CF,x), _(CF,x), _(CF,x), + /* AA48 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,T), _(CF,R), _(x,x), _(x,x), + /* AA50 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* AA58 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Myanmar Extended-A */ + + /* 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,R), _(TM,T), _(TM,R), _(C,x), _(C,x), + + /* Tai Viet */ + + /* 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,T), + /* AAC0 */ _(TL,x), _(TM,T), _(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 */ _(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,R), _(IS,x), _(x,x), + +#define use_offset_0xabc0u 3360 + + + /* Meetei Mayek */ + + /* 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,R), _(PK,B), _(x,x), _(x,x), + /* ABF0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* ABF8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + +#define use_offset_0x10a00u 3424 + + + /* Kharoshthi */ + + /* 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), _(M,B), _(Bi,B), _(Vs,T), + /* 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 */ _(N,T), _(N,B), _(N,B), _(x,x), _(x,x), _(x,x), _(x,x), _(IS,x), + /* 10A40 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + +#define use_offset_0x11000u 3496 + + + /* Brahmi */ + + /* 11000 */ _(Bi,R), _(Bi,T), _(Vs,R),_(CWS,x),_(CWS,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),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x), + /* 11058 */_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x), + /* 11060 */_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x), _(Nd,x), _(Nd,x), + /* 11068 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,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), _(NJ,x), + + /* Kaithi */ + + /* 11080 */ _(Bi,T), _(Bi,T), _(Vs,R), _(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,B), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + +#define use_offset_0x11100u 3688 + + + /* Chakma */ + + /* 11100 */ _(Bi,T), _(Bi,T), _(Vs,T), _(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), _(IS,x), _(PK,T), _(x,x), _(Nd,x), _(Nd,x), + /* 11138 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,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), + + /* Mahajani */ + + /* 11150 */ _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(C,x), _(C,x), _(C,x), + /* 11158 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11160 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11168 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11170 */ _(C,x), _(C,x), _(C,x), _(N,B), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11178 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Sharada */ + + /* 11180 */ _(Bi,T), _(Bi,T), _(Vs,R), _(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), _(CP,x), _(CP,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 111C8 */ _(x,x), _(x,x), _(N,x), _(M,T), _(M,B), _(x,x), _(x,x), _(x,x), + /* 111D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 111D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Sinhala Archaic Numbers */ + + /* 111E0 */ _(x,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 111E8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 111F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), + /* 111F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Khojki */ + + /* 11200 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), + /* 11208 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11210 */ _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11218 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11220 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11228 */ _(C,x), _(C,x), _(C,x), _(C,x), _(M,R), _(M,R), _(M,R), _(M,B), + /* 11230 */ _(M,T), _(M,T), _(M,TR), _(M,TR), _(Bi,T), _(V,R), _(N,T), _(GM,T), + +#define use_offset_0x11280u 4000 + + + /* Multani */ + + /* 11280 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(x,x), + /* 11288 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), + /* 11290 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11298 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), + /* 112A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 112A8 */ _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Khudawadi */ + + /* 112B0 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), + /* 112B8 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 112C0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 112C8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 112D0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 112D8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(Bi,T), + /* 112E0 */ _(M,R), _(M,L), _(M,R), _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), + /* 112E8 */ _(M,T), _(N,B), _(PK,B), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 112F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 112F8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Grantha */ + + /* 11300 */ _(Bi,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 11308 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x), + /* 11310 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), + /* 11318 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11320 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11328 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11330 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), + /* 11338 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,R), + /* 11340 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(x,x), _(M,L), + /* 11348 */ _(M,L), _(x,x), _(x,x), _(M,LR), _(M,LR), _(V,R), _(x,x), _(x,x), + /* 11350 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), + /* 11358 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11360 */ _(VI,x), _(VI,x), _(M,R), _(M,R), _(x,x), _(x,x), _(Ca,T), _(Ca,T), + /* 11368 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(x,x), _(x,x), _(x,x), + /* 11370 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(x,x), _(x,x), _(x,x), + +#define use_offset_0x11480u 4248 + + + /* Tirhuta */ + + /* 11480 */ _(x,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), + /* 11488 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), + /* 11490 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11498 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 114A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 114A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 114B0 */ _(M,R), _(M,L), _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,B), + /* 114B8 */ _(M,B), _(M,L), _(M,T), _(M,TL), _(M,LR), _(M,R), _(M,LR), _(Bi,T), + /* 114C0 */ _(Bi,T), _(Vs,R), _(V,B), _(N,B), _(A,x), _(x,x), _(x,x), _(x,x), + /* 114C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 114D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 114D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + +#define use_offset_0x11580u 4344 + + + /* Siddham */ + + /* 11580 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), + /* 11588 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), + /* 11590 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11598 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 115A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 115A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,R), + /* 115B0 */ _(M,L), _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), + /* 115B8 */ _(M,L), _(M,TL), _(M,LR),_(M,TLR), _(Bi,T), _(Bi,T), _(Vs,R), _(V,B), + /* 115C0 */ _(N,B), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 115C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 115D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 115D8 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), + /* 115E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 115E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 115F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 115F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Modi */ + + /* 11600 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), + /* 11608 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), + /* 11610 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11618 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11620 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11628 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11630 */ _(M,R), _(M,R), _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,B), + /* 11638 */ _(M,B), _(M,T), _(M,T), _(M,R), _(M,R), _(Bi,T), _(Vs,R), _(V,B), + /* 11640 */ _(M,T), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11648 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11650 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 11658 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11660 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11668 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11670 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11678 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Takri */ + + /* 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,T), _(Vs,R), _(M,T), _(M,L), _(M,R), + /* 116B0 */ _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), _(M,T), _(V,R), _(N,B), + /* 116B8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 116C0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 116C8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 116D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 116D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 116E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 116E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 116F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 116F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + + /* Ahom */ + + /* 11700 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11708 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11710 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 11718 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(CM,B), _(CM,x), _(CM,T), + /* 11720 */ _(M,R), _(M,R), _(M,T), _(M,T), _(M,B), _(M,B), _(M,L), _(M,T), + /* 11728 */ _(M,B), _(M,T), _(M,T), _(PK,T), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11730 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 11738 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), + +}; /* Table items: 4792; occupancy: 72% */ + +USE_TABLE_ELEMENT_TYPE +hb_use_get_categories (hb_codepoint_t u) +{ + switch (u >> 12) + { + case 0x0u: + if (hb_in_range (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u]; + if (hb_in_range (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u]; + if (hb_in_range (u, 0x0900u, 0x0DF7u)) return use_table[u - 0x0900u + use_offset_0x0900u]; + break; + + case 0x1u: + if (hb_in_range (u, 0x1000u, 0x109Fu)) return use_table[u - 0x1000u + use_offset_0x1000u]; + if (hb_in_range (u, 0x1700u, 0x17EFu)) return use_table[u - 0x1700u + use_offset_0x1700u]; + if (hb_in_range (u, 0x1900u, 0x1A9Fu)) return use_table[u - 0x1900u + use_offset_0x1900u]; + if (hb_in_range (u, 0x1B00u, 0x1C4Fu)) return use_table[u - 0x1B00u + use_offset_0x1b00u]; + if (hb_in_range (u, 0x1CD0u, 0x1CFFu)) return use_table[u - 0x1CD0u + use_offset_0x1cd0u]; + break; + + case 0x2u: + if (hb_in_range (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u]; + if (hb_in_range (u, 0x2070u, 0x2087u)) return use_table[u - 0x2070u + use_offset_0x2070u]; + if (hb_in_range (u, 0x25C8u, 0x25CFu)) return use_table[u - 0x25C8u + use_offset_0x25c8u]; + break; + + case 0xAu: + if (hb_in_range (u, 0xA800u, 0xAAF7u)) return use_table[u - 0xA800u + use_offset_0xa800u]; + if (hb_in_range (u, 0xABC0u, 0xABFFu)) return use_table[u - 0xABC0u + use_offset_0xabc0u]; + break; + + case 0x10u: + if (hb_in_range (u, 0x10A00u, 0x10A47u)) return use_table[u - 0x10A00u + use_offset_0x10a00u]; + break; + + case 0x11u: + if (hb_in_range (u, 0x11000u, 0x110BFu)) return use_table[u - 0x11000u + use_offset_0x11000u]; + if (hb_in_range (u, 0x11100u, 0x11237u)) return use_table[u - 0x11100u + use_offset_0x11100u]; + if (hb_in_range (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u]; + if (hb_in_range (u, 0x11480u, 0x114DFu)) return use_table[u - 0x11480u + use_offset_0x11480u]; + if (hb_in_range (u, 0x11580u, 0x1173Fu)) return use_table[u - 0x11580u + use_offset_0x11580u]; + break; + + default: + break; + } + return _(x,x); +} + +#undef _ + +#undef SC_A +#undef SC_Bi +#undef SC_BJN +#undef SC_Ca +#undef SC_C +#undef SC_CD +#undef SC_CF +#undef SC_CHL +#undef SC_CK +#undef SC_CM +#undef SC_GB +#undef SC_CPR +#undef SC_CP +#undef SC_CS +#undef SC_CSR +#undef SC_CWS +#undef SC_GM +#undef SC_IS +#undef SC_ZWJ +#undef SC_ML +#undef SC_ZWNJ +#undef SC_N +#undef SC_Nd +#undef SC_NJ +#undef SC_x +#undef SC_PK +#undef SC_RS +#undef SC_SM +#undef SC_TL +#undef SC_TM +#undef SC_V +#undef SC_Vs +#undef SC_Vo +#undef SC_M +#undef SC_VI + +#undef PC_B +#undef PC_BR +#undef PC_L +#undef PC_LR +#undef PC_x +#undef PC_O +#undef PC_R +#undef PC_T +#undef PC_TB +#undef PC_TBR +#undef PC_TL +#undef PC_TLR +#undef PC_TR +#undef PC_VOL + +/* == End of generated table == */ From 14b12f92a9ef7db57c5252ef0442239319ce4bca Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 20 Jul 2015 11:57:44 +0100 Subject: [PATCH 03/43] [USE] Add Kharoshti test data from Unicode proposal --- test/shaping/texts/in-tree/MANIFEST | 1 + .../shaping/texts/in-tree/shaper-use/MANIFEST | 1 + .../shaper-use/script-kharoshti/MANIFEST | 1 + .../shaper-use/script-kharoshti/misc.txt | 36 +++++++++++++++++++ 4 files changed, 39 insertions(+) create mode 100644 test/shaping/texts/in-tree/shaper-use/MANIFEST create mode 100644 test/shaping/texts/in-tree/shaper-use/script-kharoshti/MANIFEST create mode 100644 test/shaping/texts/in-tree/shaper-use/script-kharoshti/misc.txt diff --git a/test/shaping/texts/in-tree/MANIFEST b/test/shaping/texts/in-tree/MANIFEST index f7a7a969a..5733ddfdd 100644 --- a/test/shaping/texts/in-tree/MANIFEST +++ b/test/shaping/texts/in-tree/MANIFEST @@ -7,3 +7,4 @@ shaper-myanmar shaper-sea shaper-thai shaper-tibetan +shaper-use diff --git a/test/shaping/texts/in-tree/shaper-use/MANIFEST b/test/shaping/texts/in-tree/shaper-use/MANIFEST new file mode 100644 index 000000000..88e14954f --- /dev/null +++ b/test/shaping/texts/in-tree/shaper-use/MANIFEST @@ -0,0 +1 @@ +script-kharoshti diff --git a/test/shaping/texts/in-tree/shaper-use/script-kharoshti/MANIFEST b/test/shaping/texts/in-tree/shaper-use/script-kharoshti/MANIFEST new file mode 100644 index 000000000..29cfb2f28 --- /dev/null +++ b/test/shaping/texts/in-tree/shaper-use/script-kharoshti/MANIFEST @@ -0,0 +1 @@ +misc.txt diff --git a/test/shaping/texts/in-tree/shaper-use/script-kharoshti/misc.txt b/test/shaping/texts/in-tree/shaper-use/script-kharoshti/misc.txt new file mode 100644 index 000000000..0a8d5229e --- /dev/null +++ b/test/shaping/texts/in-tree/shaper-use/script-kharoshti/misc.txt @@ -0,0 +1,36 @@ +10a24 10a2a 10a0c 10a2a 10a3f 10a17 10a38 10a05 10a0c 10a0f +10a00 10a01 +10a10 10a01 +10a20 10a01 +10a00 10a02 +10a31 10a02 +10a28 10a02 +10a00 10a03 +10a28 10a03 +10a00 10a05 +10a10 10a05 +10a20 10a05 +10a21 10a05 +10a00 10a06 +10a24 10a06 +10a28 10a0c +10a2f 10a0d +10a00 10a0e +10a10 10a0f +10a17 10a38 +10a12 10a39 +10a28 10a3a +10a22 10a01 10a10 10a3f +10a10 10a3f 10a2e +10a28 10a3f 10a2a +10a2c 10a3f 10a31 +10a2f 10a3f 10a1f +10a2f 10a3f 10a29 +10a2a 10a3f 10a1f +10a1f 10a3f 10a2a +10a2b 10a3f 10a24 +10a24 10a3f 10a2b +10a10 10a3f 10a2b +10a1f 10a3f 10a2c +10a10 10a3f 10a1f +10a11 10a3f 10a10 10a3f 10a2e From 5e5c8560cca3cb9c6be90c7c18ecb77d5cca0c0f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 20 Jul 2015 12:01:20 +0100 Subject: [PATCH 04/43] [USE] Minor optimization of USE table --- src/gen-use-table.py | 2 +- src/hb-ot-shape-complex-use-table.cc | 30 +++++++++++----------------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/gen-use-table.py b/src/gen-use-table.py index e4914ad99..73aa379d5 100755 --- a/src/gen-use-table.py +++ b/src/gen-use-table.py @@ -57,7 +57,7 @@ num = len (data) # Remove the outliers singles = {} -for u in []: # TODO [0x00A0, 0x200C, 0x200D, 0x25CC, 0x1107F]: +for u in [0x25CC, 0x1107F]: singles[u] = data[u] del data[u] diff --git a/src/hb-ot-shape-complex-use-table.cc b/src/hb-ot-shape-complex-use-table.cc index 9aa48c11b..0ca4cc49f 100644 --- a/src/hb-ot-shape-complex-use-table.cc +++ b/src/hb-ot-shape-complex-use-table.cc @@ -518,14 +518,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 2078 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 2080 */ _(x,x), _(x,x), _(SM,x), _(SM,x), _(SM,x), _(x,x), _(x,x), _(x,x), -#define use_offset_0x25c8u 2592 - - - /* Geometric Shapes */ - - /* 25C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(GB,x), _(x,x), _(x,x), _(x,x), - -#define use_offset_0xa800u 2600 +#define use_offset_0xa800u 2592 /* Syloti Nagri */ @@ -659,7 +652,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 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,R), _(IS,x), _(x,x), -#define use_offset_0xabc0u 3360 +#define use_offset_0xabc0u 3352 /* Meetei Mayek */ @@ -673,7 +666,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* ABF0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), /* ABF8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), -#define use_offset_0x10a00u 3424 +#define use_offset_0x10a00u 3416 /* Kharoshthi */ @@ -688,7 +681,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 10A38 */ _(N,T), _(N,B), _(N,B), _(x,x), _(x,x), _(x,x), _(x,x), _(IS,x), /* 10A40 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), -#define use_offset_0x11000u 3496 +#define use_offset_0x11000u 3488 /* Brahmi */ @@ -708,7 +701,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11060 */_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x), _(Nd,x), _(Nd,x), /* 11068 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,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), _(NJ,x), + /* 11078 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* Kaithi */ @@ -721,7 +714,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 110B0 */ _(M,R), _(M,L), _(M,R), _(M,B), _(M,B), _(M,T), _(M,T), _(M,R), /* 110B8 */ _(M,R), _(V,B), _(N,B), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), -#define use_offset_0x11100u 3688 +#define use_offset_0x11100u 3680 /* Chakma */ @@ -778,7 +771,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11228 */ _(C,x), _(C,x), _(C,x), _(C,x), _(M,R), _(M,R), _(M,R), _(M,B), /* 11230 */ _(M,T), _(M,T), _(M,TR), _(M,TR), _(Bi,T), _(V,R), _(N,T), _(GM,T), -#define use_offset_0x11280u 4000 +#define use_offset_0x11280u 3992 /* Multani */ @@ -821,7 +814,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11368 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(x,x), _(x,x), _(x,x), /* 11370 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(x,x), _(x,x), _(x,x), -#define use_offset_0x11480u 4248 +#define use_offset_0x11480u 4240 /* Tirhuta */ @@ -839,7 +832,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 114D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), /* 114D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), -#define use_offset_0x11580u 4344 +#define use_offset_0x11580u 4336 /* Siddham */ @@ -910,7 +903,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11730 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), /* 11738 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), -}; /* Table items: 4792; occupancy: 72% */ +}; /* Table items: 4784; occupancy: 72% */ USE_TABLE_ELEMENT_TYPE hb_use_get_categories (hb_codepoint_t u) @@ -934,7 +927,7 @@ hb_use_get_categories (hb_codepoint_t u) case 0x2u: if (hb_in_range (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u]; if (hb_in_range (u, 0x2070u, 0x2087u)) return use_table[u - 0x2070u + use_offset_0x2070u]; - if (hb_in_range (u, 0x25C8u, 0x25CFu)) return use_table[u - 0x25C8u + use_offset_0x25c8u]; + if (unlikely (u == 0x25CCu)) return _(GB,x); break; case 0xAu: @@ -952,6 +945,7 @@ hb_use_get_categories (hb_codepoint_t u) if (hb_in_range (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u]; if (hb_in_range (u, 0x11480u, 0x114DFu)) return use_table[u - 0x11480u + use_offset_0x11480u]; if (hb_in_range (u, 0x11580u, 0x1173Fu)) return use_table[u - 0x11580u + use_offset_0x11580u]; + if (unlikely (u == 0x1107Fu)) return _(NJ,x); break; default: From fd74b939b176f47d34d34b3d33e2a09d255c2d9e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 20 Jul 2015 13:30:45 +0100 Subject: [PATCH 05/43] Minor --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index ceb3eba25..44de2b694 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,7 +14,7 @@ DISTCHECK_CONFIGURE_FLAGS = --enable-introspection #AM_CXXFLAGS = # Convenience targets: -lib: libharfbuzz.la +lib: $(BUILT_SOURCES) libharfbuzz.la lib_LTLIBRARIES = libharfbuzz.la From e0eabd7f67462ac34fbfc749d897be478fbd1224 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 20 Jul 2015 13:30:51 +0100 Subject: [PATCH 06/43] [USE] Put a Ragel machine together Grammar from the spec! --- src/hb-ot-shape-complex-use-machine.rl | 169 +++++++++++++++++++++++++ src/hb-ot-shape-complex-use-private.hh | 160 +++++++++++++++++++++++ 2 files changed, 329 insertions(+) diff --git a/src/hb-ot-shape-complex-use-machine.rl b/src/hb-ot-shape-complex-use-machine.rl index e69de29bb..0ea71acf9 100644 --- a/src/hb-ot-shape-complex-use-machine.rl +++ b/src/hb-ot-shape-complex-use-machine.rl @@ -0,0 +1,169 @@ +/* + * Copyright © 2015 Mozilla Foundation. + * Copyright © 2015 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. + * + * Mozilla Author(s): Jonathan Kew + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH +#define HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH + +#include "hb-private.hh" + +%%{ + machine use_syllable_machine; + alphtype unsigned char; + write data; +}%% + +%%{ + +# Same order as enum use_category_t. Not sure how to avoid duplication. + +O = 0; # OTHER + +B = 1; # BASE +IV = 2; # BASE_VOWEL +IND = 3; # BASE_IND +N = 4; # BASE_NUM +GB = 5; # BASE_OTHER +CGJ = 6; # CGJ +#F = 7; # CONS_FINAL +FM = 8; # CONS_FINAL_MOD +#M = 9; # CONS_MED +#CM = 10; # CONS_MOD +SUB = 11; # CONS_SUB +H = 12; # HALANT +HN = 13; # HALANT_NUM +ZWNJ = 14; # Zero width non-joiner +ZWJ = 15; # Zero width joiner +WJ = 16; # Word joiner +Rsv = 17; # Reserved characters +R = 18; # REPHA +S = 19; # SYM +#SM = 20; # SYM_MOD +VS = 21; # VARIATION_SELECTOR +#V = 22; # VOWEL +#VM = 23; # VOWEL_MOD + +FAbv = 24; # CONS_FINAL_ABOVE +FBlw = 25; # CONS_FINAL_BELOW +FPst = 26; # CONS_FINAL_POST +MAbv = 27; # CONS_MED_ABOVE +MBlw = 28; # CONS_MED_BELOW +MPst = 29; # CONS_MED_POST +MPre = 30; # CONS_MED_PRE +CMAbv = 31; # CONS_MOD_ABOVE +CMBlw = 32; # CONS_MOD_BELOW +VAbv = 33; # VOWEL_ABOVE / VOWEL_ABOVE_BELOW / VOWEL_ABOVE_BELOW_POST / VOWEL_ABOVE_POST +VBlw = 34; # VOWEL_BELOW / VOWEL_BELOW_POST +VPst = 35; # VOWEL_POST UIPC = Right +VPre = 36; # VOWEL_PRE / VOWEL_PRE_ABOVE / VOWEL_PRE_ABOVE_POST / VOWEL_PRE_POST +VMAbv = 37; # VOWEL_MOD_ABOVE +VMBlw = 38; # VOWEL_MOD_BELOW +VMPst = 39; # VOWEL_MOD_POST +VMPre = 40; # VOWEL_MOD_PRE +SMAbv = 41; # SYM_MOD_ABOVE +SMBlw = 42; # SYM_MOD_BELOW + + +consonant_modifiers = CMAbv* CMBlw* ((H B | SUB) VS? CMAbv? CMBlw*)*; +medial_consonants = MPre? MAbv? MBlw? MPst?; +dependent_vowels = VPre* VAbv* VBlw* VPst*; +vowel_modifiers = VMPre* VMAbv* VMBlw* VMPst*; +final_consonants = FAbv* FBlw* FPst* FM?; + +virama_terminated_cluster = + R? (B | GB | IV) VS? + consonant_modifiers + H +; +consonant_cluster = + R? (B | GB) VS? + consonant_modifiers + medial_consonants + dependent_vowels + vowel_modifiers + final_consonants +; +vowel_cluster = + R? (IV) VS? + consonant_modifiers + medial_consonants + vowel_modifiers + final_consonants +; + +number_joiner_terminated_cluster = N VS? (H N VS?)* H; +numeral_cluster = N VS? (H N VS?)*; +symbol_cluster = S VS? SMAbv* SMBlw*; +independent_cluster = (IND | O | Rsv | WJ) VS?; + +main := |* + independent_cluster => { found_syllable (independent_cluster); }; + virama_terminated_cluster => { found_syllable (virama_terminated_cluster); }; + consonant_cluster => { found_syllable (consonant_cluster); }; + vowel_cluster => { found_syllable (vowel_cluster); }; + number_joiner_terminated_cluster => { found_syllable (number_joiner_terminated_cluster); }; + numeral_cluster => { found_syllable (numeral_cluster); }; + symbol_cluster => { found_syllable (symbol_cluster); }; +*|; + + +}%% + +#define found_syllable(syllable_type) \ + HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ + for (unsigned int i = last; i < p+1; i++) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + last = p+1; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + } HB_STMT_END + +static void +find_syllables (hb_buffer_t *buffer) +{ + unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; + int cs; + hb_glyph_info_t *info = buffer->info; + %%{ + write init; + getkey info[p].use_category(); + }%% + + p = 0; + pe = eof = buffer->len; + + unsigned int last = 0; + unsigned int syllable_serial = 1; + %%{ + write exec; + }%% +} + +#undef found_syllable + +#endif /* HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH */ diff --git a/src/hb-ot-shape-complex-use-private.hh b/src/hb-ot-shape-complex-use-private.hh index e69de29bb..73ecc3bfd 100644 --- a/src/hb-ot-shape-complex-use-private.hh +++ b/src/hb-ot-shape-complex-use-private.hh @@ -0,0 +1,160 @@ +/* + * Copyright © 2015 Mozilla Foundation. + * Copyright © 2015 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. + * + * Mozilla Author(s): Jonathan Kew + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPE_COMPLEX_USE_PRIVATE_HH +#define HB_OT_SHAPE_COMPLEX_USE_PRIVATE_HH + +#include "hb-private.hh" + + +#include "hb-ot-shape-complex-private.hh" + + +#define USE_TABLE_ELEMENT_TYPE uint16_t + +/* Cateories used in the Universal Shaping Engine spec: + * https://www.microsoft.com/typography/OpenTypeDev/USE/intro.htm + */ +/* Note: This enum is duplicated in the -machine.rl source file. + * Not sure how to avoid duplication. */ +enum use_category_t { + USE_O = 0, /* OTHER */ + + USE_B = 1, /* BASE */ + USE_IV = 2, /* BASE_VOWEL */ + USE_IND = 3, /* BASE_IND */ + USE_N = 4, /* BASE_NUM */ + USE_GB = 5, /* BASE_OTHER */ + USE_CGJ = 6, /* CGJ */ +// USE_F = 7, /* CONS_FINAL */ + USE_FM = 8, /* CONS_FINAL_MOD */ +// USE_M = 9, /* CONS_MED */ +// USE_CM = 10, /* CONS_MOD */ + USE_SUB = 11, /* CONS_SUB */ + USE_H = 12, /* HALANT */ + USE_HN = 13, /* HALANT_NUM */ + USE_ZWNJ = 14, /* Zero width non-joiner */ + USE_ZWJ = 15, /* Zero width joiner */ + USE_WJ = 16, /* Word joiner */ + USE_Rsv = 17, /* Reserved characters */ + USE_R = 18, /* REPHA */ + USE_S = 19, /* SYM */ +// USE_SM = 20, /* SYM_MOD */ + USE_VS = 21, /* VARIATION_SELECTOR */ +// USE_V = 22, /* VOWEL */ +// USE_VM = 23, /* VOWEL_MOD */ + + USE_FAbv = 24, /* CONS_FINAL_ABOVE */ + USE_FBlw = 25, /* CONS_FINAL_BELOW */ + USE_FPst = 26, /* CONS_FINAL_POST */ + USE_MAbv = 27, /* CONS_MED_ABOVE */ + USE_MBlw = 28, /* CONS_MED_BELOW */ + USE_MPst = 29, /* CONS_MED_POST */ + USE_MPre = 30, /* CONS_MED_PRE */ + USE_CMAbv = 31, /* CONS_MOD_ABOVE */ + USE_CMBlw = 32, /* CONS_MOD_BELOW */ + USE_VAbv = 33, /* VOWEL_ABOVE / VOWEL_ABOVE_BELOW / VOWEL_ABOVE_BELOW_POST / VOWEL_ABOVE_POST */ + USE_VBlw = 34, /* VOWEL_BELOW / VOWEL_BELOW_POST */ + USE_VPst = 35, /* VOWEL_POST UIPC = Right */ + USE_VPre = 36, /* VOWEL_PRE / VOWEL_PRE_ABOVE / VOWEL_PRE_ABOVE_POST / VOWEL_PRE_POST */ + USE_VMAbv = 37, /* VOWEL_MOD_ABOVE */ + USE_VMBlw = 38, /* VOWEL_MOD_BELOW */ + USE_VMPst = 39, /* VOWEL_MOD_POST */ + USE_VMPre = 40, /* VOWEL_MOD_PRE */ + USE_SMAbv = 41, /* SYM_MOD_ABOVE */ + USE_SMBlw = 42 /* SYM_MOD_BELOW */ +}; + +/* Categories used in IndicSyllabicCategory.txt from UCD. */ +enum indic_syllabic_category_t +{ + INDIC_SYLLABIC_CATEGORY_AVAGRAHA, + INDIC_SYLLABIC_CATEGORY_BINDU, + INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER, + INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK, + INDIC_SYLLABIC_CATEGORY_CONSONANT, + INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD, + INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL, + INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER, + INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER, + INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL, + INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER, + INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA, + INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED, + INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED, + INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA, + INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER, + INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK, + INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER, + INDIC_SYLLABIC_CATEGORY_JOINER, + INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER, + INDIC_SYLLABIC_CATEGORY_NON_JOINER, + INDIC_SYLLABIC_CATEGORY_NUKTA, + INDIC_SYLLABIC_CATEGORY_NUMBER, + INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER, + INDIC_SYLLABIC_CATEGORY_OTHER, + INDIC_SYLLABIC_CATEGORY_PURE_KILLER, + INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER, + INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER, + INDIC_SYLLABIC_CATEGORY_TONE_LETTER, + INDIC_SYLLABIC_CATEGORY_TONE_MARK, + INDIC_SYLLABIC_CATEGORY_VIRAMA, + INDIC_SYLLABIC_CATEGORY_VISARGA, + INDIC_SYLLABIC_CATEGORY_VOWEL, + INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT, + INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT, +}; + +/* Categories used in IndicPositionalCategory.txt from UCD */ +enum indic_matra_category_t { + INDIC_POSITIONAL_CATEGORY_BOTTOM, + INDIC_POSITIONAL_CATEGORY_BOTTOM_AND_RIGHT, + INDIC_POSITIONAL_CATEGORY_LEFT, + INDIC_POSITIONAL_CATEGORY_LEFT_AND_RIGHT, + INDIC_POSITIONAL_CATEGORY_NOT_APPLICABLE, + INDIC_POSITIONAL_CATEGORY_OVERSTRUCK, + INDIC_POSITIONAL_CATEGORY_RIGHT, + INDIC_POSITIONAL_CATEGORY_TOP, + INDIC_POSITIONAL_CATEGORY_TOP_AND_BOTTOM, + INDIC_POSITIONAL_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT, + INDIC_POSITIONAL_CATEGORY_TOP_AND_LEFT, + INDIC_POSITIONAL_CATEGORY_TOP_AND_LEFT_AND_RIGHT, + INDIC_POSITIONAL_CATEGORY_TOP_AND_RIGHT, + INDIC_POSITIONAL_CATEGORY_VISUAL_ORDER_LEFT, +}; + +/* 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. */ +#define USE_COMBINE_CATEGORIES(S,P) \ + (ASSERT_STATIC_EXPR_ZERO (S < 255 && P < 255) + \ + ((P << 8) | S)) + +HB_INTERNAL USE_TABLE_ELEMENT_TYPE +hb_use_get_categories (hb_codepoint_t u); + +#endif /* HB_OT_SHAPE_COMPLEX_USE_PRIVATE_HH */ From a9663958fe861950b6f389b389f146232b2cd909 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 20 Jul 2015 14:24:55 +0100 Subject: [PATCH 07/43] [USE] Start putting together the shaper body --- src/hb-ot-shape-complex-use-private.hh | 2 +- src/hb-ot-shape-complex-use.cc | 339 +++++++++++++++++++++++++ 2 files changed, 340 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-shape-complex-use-private.hh b/src/hb-ot-shape-complex-use-private.hh index 73ecc3bfd..835dbaf75 100644 --- a/src/hb-ot-shape-complex-use-private.hh +++ b/src/hb-ot-shape-complex-use-private.hh @@ -131,7 +131,7 @@ enum indic_syllabic_category_t }; /* Categories used in IndicPositionalCategory.txt from UCD */ -enum indic_matra_category_t { +enum indic_positional_category_t { INDIC_POSITIONAL_CATEGORY_BOTTOM, INDIC_POSITIONAL_CATEGORY_BOTTOM_AND_RIGHT, INDIC_POSITIONAL_CATEGORY_LEFT, diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index e69de29bb..d8ce4517f 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -0,0 +1,339 @@ +/* + * Copyright © 2015 Mozilla Foundation. + * Copyright © 2015 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. + * + * Mozilla Author(s): Jonathan Kew + * Google Author(s): Behdad Esfahbod + */ + +#include "hb-ot-shape-complex-use-private.hh" + +/* buffer var allocations */ +#define use_category() complex_var_u8_0() + + +/* + * Universal Shaping Engine. + * https://www.microsoft.com/typography/OpenTypeDev/USE/intro.htm + */ + +static const hb_tag_t +basic_features[] = +{ + /* + * Basic features. + * These features are applied in order, one at a time, after initial_reordering. + */ + HB_TAG('p','r','e','f'), + HB_TAG('a','b','v','f'), + HB_TAG('b','l','w','f'), + HB_TAG('p','s','t','f'), +}; +static const hb_tag_t +other_features[] = +{ + /* + * Other features. + * These features are applied all at once, after final_reordering. + */ + HB_TAG('p','r','e','s'), + HB_TAG('a','b','v','s'), + HB_TAG('b','l','w','s'), + HB_TAG('p','s','t','s'), + /* Positioning features, though we don't care about the types. */ + HB_TAG('d','i','s','t'), +}; + +static void +setup_syllables (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); +static void +reordering (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); + +static void +collect_features_use (hb_ot_shape_planner_t *plan) +{ + hb_ot_map_builder_t *map = &plan->map; + + /* Do this before any lookups have been applied. */ + map->add_gsub_pause (setup_syllables); + + map->add_global_bool_feature (HB_TAG('l','o','c','l')); + /* The Indic specs do not require ccmp, but we apply it here since if + * there is a use of it, it's typically at the beginning. */ + map->add_global_bool_feature (HB_TAG('c','c','m','p')); + + for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++) + { + map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); + map->add_gsub_pause (NULL); + } + map->add_gsub_pause (reordering); + for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++) + map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); +} + +static void +override_features_use (hb_ot_shape_planner_t *plan) +{ + plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL); +} + + +enum syllable_type_t { + independent_cluster, + virama_terminated_cluster, + consonant_cluster, + vowel_cluster, + number_joiner_terminated_cluster, + numeral_cluster, + symbol_cluster, +}; + +#include "hb-ot-shape-complex-use-machine.hh" + + +static inline void +set_use_properties (hb_glyph_info_t &info) +{ + hb_codepoint_t u = info.codepoint; + unsigned int type = hb_use_get_categories (u); + indic_syllabic_category_t cat = (indic_syllabic_category_t) (type & 0x7Fu); + indic_positional_category_t pos = (indic_positional_category_t) (type >> 8); + use_category_t use = USE_O; + + switch (cat) + { + /* TODO */ + } + + info.use_category() = use; +} + + +static void +setup_masks_use (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_buffer_t *buffer, + hb_font_t *font HB_UNUSED) +{ + HB_BUFFER_ALLOCATE_VAR (buffer, use_category); + + /* We cannot setup masks here. We save information about characters + * and setup masks later on in a pause-callback. */ + + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 0; i < count; i++) + set_use_properties (info[i]); +} + +static void +setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) +{ + find_syllables (buffer); +} + + +static void +reorder_virama_terminated_cluster (const hb_ot_shape_plan_t *plan, + hb_face_t *face, + hb_buffer_t *buffer, + unsigned int start, unsigned int end) +{ +} + +static void +reorder_consonant_cluster (const hb_ot_shape_plan_t *plan, + hb_face_t *face, + hb_buffer_t *buffer, + unsigned int start, unsigned int end) +{ + hb_glyph_info_t *info = buffer->info; + + /* Reorder! */ +#if 0 + unsigned int i = start; + for (; i < base; i++) + info[i].use_position() = POS_PRE_C; + if (i < end) + { + info[i].use_position() = POS_BASE_C; + i++; + } + for (; i < end; i++) + { + if (info[i].use_category() == OT_MR) /* Pre-base reordering */ + { + info[i].use_position() = POS_PRE_C; + continue; + } + if (info[i].use_category() == OT_VPre) /* Left matra */ + { + info[i].use_position() = POS_PRE_M; + continue; + } + + info[i].use_position() = POS_AFTER_MAIN; + } + + buffer->merge_clusters (start, end); + /* Sit tight, rock 'n roll! */ + hb_bubble_sort (info + start, end - start, compare_use_order); +#endif +} + +static void +reorder_vowel_cluster (const hb_ot_shape_plan_t *plan, + hb_face_t *face, + hb_buffer_t *buffer, + unsigned int start, unsigned int end) +{ + reorder_consonant_cluster (plan, face, buffer, start, end); +} + +static void +reorder_syllable (const hb_ot_shape_plan_t *plan, + hb_face_t *face, + hb_buffer_t *buffer, + unsigned int start, unsigned int end) +{ + syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F); + switch (syllable_type) { +#define HANDLE(X) case X: reorder_##X (plan, face, buffer, start, end); return + HANDLE (virama_terminated_cluster); + HANDLE (consonant_cluster); + HANDLE (vowel_cluster); +#undef HANDLE +#define HANDLE(X) case X: return + HANDLE (number_joiner_terminated_cluster); + HANDLE (numeral_cluster); + HANDLE (symbol_cluster); + HANDLE (independent_cluster); +#undef HANDLE + } +} + +static inline void +insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font, + hb_buffer_t *buffer) +{ +#if 0 + /* Note: This loop is extra overhead, but should not be measurable. */ + bool has_broken_syllables = false; + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 0; i < count; i++) + if ((info[i].syllable() & 0x0F) == broken_cluster) + { + has_broken_syllables = true; + break; + } + if (likely (!has_broken_syllables)) + return; + + + hb_codepoint_t dottedcircle_glyph; + if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph)) + return; + + hb_glyph_info_t dottedcircle = {0}; + dottedcircle.codepoint = 0x25CCu; + set_use_properties (dottedcircle); + dottedcircle.codepoint = dottedcircle_glyph; + + buffer->clear_output (); + + buffer->idx = 0; + unsigned int last_syllable = 0; + while (buffer->idx < buffer->len) + { + unsigned int syllable = buffer->cur().syllable(); + syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F); + if (unlikely (last_syllable != syllable && syllable_type == broken_cluster)) + { + last_syllable = syllable; + + hb_glyph_info_t info = dottedcircle; + info.cluster = buffer->cur().cluster; + info.mask = buffer->cur().mask; + info.syllable() = buffer->cur().syllable(); + + buffer->output_info (info); + } + else + buffer->next_glyph (); + } + + buffer->swap_buffers (); +#endif +} + +static void +reordering (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + insert_dotted_circles (plan, font, buffer); + + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + if (unlikely (!count)) return; + unsigned int last = 0; + unsigned int last_syllable = info[0].syllable(); + for (unsigned int i = 1; i < count; i++) + if (last_syllable != info[i].syllable()) { + reorder_syllable (plan, font->face, buffer, last, i); + last = i; + last_syllable = info[last].syllable(); + } + reorder_syllable (plan, font->face, buffer, last, count); + + /* Zero syllables now... */ + for (unsigned int i = 0; i < count; i++) + info[i].syllable() = 0; + + HB_BUFFER_DEALLOCATE_VAR (buffer, use_category); +} + + +const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use = +{ + "use", + collect_features_use, + override_features_use, + NULL, /* data_create */ + NULL, /* data_destroy */ + NULL, /* preprocess_text */ + HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, + NULL, /* decompose */ + NULL, /* compose */ + setup_masks_use, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, + false, /* fallback_position */ +}; From eb74535cc2c0d0de41e54e75bdc71825ec969523 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 20 Jul 2015 15:33:25 +0100 Subject: [PATCH 08/43] [USE] Fix Number clusters The spec wrongly has "H" where "HN" is meant. --- src/hb-ot-shape-complex-use-machine.rl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-shape-complex-use-machine.rl b/src/hb-ot-shape-complex-use-machine.rl index 0ea71acf9..77068bdff 100644 --- a/src/hb-ot-shape-complex-use-machine.rl +++ b/src/hb-ot-shape-complex-use-machine.rl @@ -115,8 +115,8 @@ vowel_cluster = final_consonants ; -number_joiner_terminated_cluster = N VS? (H N VS?)* H; -numeral_cluster = N VS? (H N VS?)*; +number_joiner_terminated_cluster = N VS? (HN N VS?)* H; +numeral_cluster = N VS? (HN N VS?)*; symbol_cluster = S VS? SMAbv* SMBlw*; independent_cluster = (IND | O | Rsv | WJ) VS?; From 20e246e674155d5fb6527722fc3ef3accf2413df Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 20 Jul 2015 15:56:19 +0100 Subject: [PATCH 09/43] [USE] Start moving Unicode-to-USE mapping into Python code --- src/Makefile.am | 2 +- src/gen-use-table.py | 176 +++++++++++++++++++++++++-- src/hb-ot-shape-complex-use-table.cc | 3 +- 3 files changed, 169 insertions(+), 12 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 44de2b694..947d279ac 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -294,7 +294,7 @@ indic-table: gen-indic-table.py IndicSyllabicCategory-7.0.0.txt IndicMatraCatego $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-indic-table.cc \ || ($(RM) hb-ot-shape-complex-indic-table.cc; false) -use-table: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt +use-table: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-use-table.cc \ || ($(RM) hb-ot-shape-complex-use-table.cc; false) diff --git a/src/gen-use-table.py b/src/gen-use-table.py index 73aa379d5..a79becb72 100755 --- a/src/gen-use-table.py +++ b/src/gen-use-table.py @@ -2,15 +2,16 @@ import sys -if len (sys.argv) != 4: - print >>sys.stderr, "usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt" +if len (sys.argv) != 5: + print >>sys.stderr, "usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt" sys.exit (1) BLACKLISTED_BLOCKS = ["Thai", "Lao", "Tibetan"] 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 j,f in enumerate(files) if j != 2] +headers.append (["UnicodeData.txt does not have a header."]) data = [{} for f in files] values = [{} for f in files] @@ -32,29 +33,184 @@ for i, f in enumerate (files): else: end = int (uu[1], 16) - t = fields[1] + t = fields[1 if i != 2 else 2] for u in range (start, end + 1): data[i][u] = t values[i][t] = values[i].get (t, 0) + end - start + 1 # Merge data into one dict: -defaults = ('Other', 'Not_Applicable', 'No_Block') +defaults = ('Other', 'Not_Applicable', 'Cn', 'No_Block') for i,v in enumerate (defaults): values[i][v] = values[i].get (v, 0) + 1 combined = {} for i,d in enumerate (data): for u,v in d.items (): - if i == 2 and not u in combined: + if i >= 2 and not u in combined: continue if not u in combined: combined[u] = list (defaults) combined[u][i] = v -combined = {k:v for k,v in combined.items() if v[2] not in BLACKLISTED_BLOCKS} +combined = {k:v for k,v in combined.items() if v[3] not in BLACKLISTED_BLOCKS} data = combined del combined num = len (data) + +property_names = [ + # General_Category + 'Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu', 'Mc', + 'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf', 'Pi', 'Po', + 'Ps', 'Sc', 'Sk', 'Sm', 'So', 'Zl', 'Zp', 'Zs', + # Indic_Syllabic_Category + 'Bindu', + 'Visarga', + 'Avagraha', + 'Nukta', + 'Virama', + 'Pure_Killer', + 'Invisible_Stacker', + 'Vowel_Independent', + 'Vowel_Dependent', + 'Vowel', + 'Consonant_Placeholder', + 'Consonant', + 'Consonant_Dead', + 'Consonant_With_Stacker', + 'Consonant_Prefixed', + 'Consonant_Preceding_Repha', + 'Consonant_Succeeding_Repha', + 'Consonant_Subjoined', + 'Consonant_Medial', + 'Consonant_Final', + 'Consonant_Head_Letter', + 'Modifying_Letter', + 'Tone_Letter', + 'Tone_Mark', + 'Gemination_Mark', + 'Cantillation_Mark', + 'Register_Shifter', + 'Syllable_Modifier', + 'Consonant_Killer', + 'Non_Joiner', + 'Joiner', + 'Number_Joiner', + 'Number', + 'Brahmi_Joining_Number', + # Indic_Positional_Category + 'Right', + 'Left', + 'Visual_Order_Left', + 'Left_And_Right', + 'Top', + 'Bottom', + 'Top_And_Bottom', + 'Top_And_Right', + 'Top_And_Left', + 'Top_And_Left_And_Right', + 'Bottom_And_Right', + 'Top_And_Bottom_And_Right', + 'Overstruck', +] + +class PropertyValue(object): + def __init__(self, name_): + self.name = name_ + +property_values = {} + +for name in property_names: + value = PropertyValue(name) + assert value not in property_values + assert value not in globals() + property_values[name] = value +globals().update(property_values) + + +def is_BASE(U, UISC, UGC): + return (UISC in [Number, Consonant, Consonant_Head_Letter, Consonant_Placeholder, Tone_Letter] or + (UGC == Lo and UISC in [Avagraha, Bindu, Consonant_Final, Consonant_Medial, + Consonant_Subjoined, Vowel, Vowel_Dependent])) +def is_BASE_VOWEL(U, UISC, UGC): + return UISC == Vowel_Independent +def is_BASE_IND(U, UISC, UGC): + return (UISC in [Consonant_Dead, Modifying_Letter] or UGC == Po) +def is_BASE_NUM(U, UISC, UGC): + return UISC == Brahmi_Joining_Number +def is_BASE_OTHER(U, UISC, UGC): + return U in [0x00A0, 0x00D7, 0x2015, 0x2022, 0x25CC, + 0x25FB, 0x25FC, 0x25FD, 0x25FE] +def is_CGJ(U, UISC, UGC): + return U == 0x034F +def is_CONS_FINAL(U, UISC, UGC): + return ((UISC == Consonant_Final and UGC != Lo) or + UISC == Consonant_Succeeding_Repha) +def is_CONS_FINAL_MOD(U, UISC, UGC): + return UISC in [Consonant_Final_Modifier, Syllable_Modifier] +def is_CONS_MED(U, UISC, UGC): + return UISC == Consonant_Medial and UGC != Lo +def is_CONS_MOD(U, UISC, UGC): + return UISC in [Nukta, Gemination_Mark, Consonant_Killer] +def is_CONS_SUB(U, UISC, UGC): + return UISC == Consonant_Subjoined +def is_HALANT(U, UISC, UGC): + return UISC in [Virama, Invisible_Stacker] +def is_HALANT_NUM(U, UISC, UGC): + return UISC == Number_Joiner +def is_ZWNJ(U, UISC, UGC): + return UISC == Non_Joiner +def is_ZWJ(U, UISC, UGC): + return UISC == Joiner +def is_Word_Joiner(U, UISC, UGC): + return U == 0x2060 +def is_OTHER(U, UISC, UGC): + return UGC == Zs # or any other SCRIPT_COMMON characters +def is_Reserved(U, UISC, UGC): + return UGC == 'Cn' +def is_REPHA(U, UISC, UGC): + return UISC == Consonant_Preceding_Repha +def is_SYM(U, UISC, UGC): + return UGC in [So, Sc] or UISC == Symbol_Letter +def is_SYM_MOD(U, UISC, UGC): + return U in [0x1B6B, 0x1B6C, 0x1B6D, 0x1B6E, 0x1B6F, 0x1B70, 0x1B71, 0x1B72, 0x1B73] +def is_VARIATION_SELECTOR(U, UISC, UGC): + return 0xFE00 <= U <= 0xFE0F +def is_VOWEL(U, UISC, UGC): + return (UISC == Pure_Killer or + (UGC != Lo and UISC in [Vowel, Vowel_Dependent])) +def is_VOWEL_MOD(U, UISC, UGC): + return (UISC in [Tone_Mark, Cantillation_Mark, Register_Shifter, Visarga] or + (UGC != Lo and UISC == Bindu)) + +use_mapping = { + 'B': is_BASE, + 'IV': is_BASE_VOWEL, + 'IND': is_BASE_IND, + 'N': is_BASE_NUM, + 'GB': is_BASE_OTHER, + 'CGJ': is_CGJ, + 'F': is_CONS_FINAL, + 'FM': is_CONS_FINAL_MOD, + 'M': is_CONS_MED, + 'CM': is_CONS_MOD, + 'SUB': is_CONS_SUB, + 'H': is_HALANT, + 'HN': is_HALANT_NUM, + 'ZWNJ': is_ZWNJ, + 'ZWJ': is_ZWJ, + 'WJ': is_Word_Joiner, + 'O': is_OTHER, + 'Rsv': is_Reserved, + 'R': is_REPHA, + 'S': is_SYM, + 'SM': is_SYM_MOD, + 'VS': is_VARIATION_SELECTOR, + 'V': is_VOWEL, + 'VM': is_VOWEL_MOD, +} + +#data = map_to_use(data) + # Remove the outliers singles = {} for u in [0x25CC, 0x1107F]: @@ -65,7 +221,7 @@ print "/* == Start of generated table == */" print "/*" print " * The following table is generated by running:" print " *" -print " * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt" +print " * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt" print " *" print " * on files with these headers:" print " *" @@ -164,11 +320,11 @@ print "static const USE_TABLE_ELEMENT_TYPE use_table[] = {" for u in uu: if u <= last: continue - block = data[u][2] + block = data[u][3] start = u//8*8 end = start+1 - while end in uu and block == data[end][2]: + while end in uu and block == data[end][3]: end += 1 end = (end-1)//8*8 + 7 diff --git a/src/hb-ot-shape-complex-use-table.cc b/src/hb-ot-shape-complex-use-table.cc index 0ca4cc49f..8f5234c60 100644 --- a/src/hb-ot-shape-complex-use-table.cc +++ b/src/hb-ot-shape-complex-use-table.cc @@ -2,7 +2,7 @@ /* * The following table is generated by running: * - * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt + * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt * * on files with these headers: * @@ -12,6 +12,7 @@ * # Date: 2015-05-12, 10:00:00 GMT [RP, KW, LI] * # Blocks-8.0.0.txt * # Date: 2014-11-10, 23:04:00 GMT [KW] + * UnicodeData.txt does not have a header. */ #include "hb-ot-shape-complex-use-private.hh" From ad725552521273a1f571f04bc96a04221c3e067a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 20 Jul 2015 17:00:06 +0100 Subject: [PATCH 10/43] [USE] Map from Unicode data to USE syllabic categories Positional sub-categories not applied yet. --- src/gen-use-table.py | 128 ++-- src/hb-ot-shape-complex-use-table.cc | 1062 +++++++++----------------- 2 files changed, 409 insertions(+), 781 deletions(-) diff --git a/src/gen-use-table.py b/src/gen-use-table.py index a79becb72..f1484fdba 100755 --- a/src/gen-use-table.py +++ b/src/gen-use-table.py @@ -63,6 +63,7 @@ property_names = [ 'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf', 'Pi', 'Po', 'Ps', 'Sc', 'Sk', 'Sm', 'So', 'Zl', 'Zp', 'Zs', # Indic_Syllabic_Category + 'Other', 'Bindu', 'Visarga', 'Avagraha', @@ -98,6 +99,7 @@ property_names = [ 'Number', 'Brahmi_Joining_Number', # Indic_Positional_Category + 'Not_Applicable' 'Right', 'Left', 'Visual_Order_Left', @@ -116,6 +118,13 @@ property_names = [ class PropertyValue(object): def __init__(self, name_): self.name = name_ + def __str__(self): + return self.name + def __eq__(self, other): + assert isinstance(other, basestring) + return self.name == other + def __ne__(self, other): + return not (self == other) property_values = {} @@ -128,16 +137,21 @@ globals().update(property_values) def is_BASE(U, UISC, UGC): - return (UISC in [Number, Consonant, Consonant_Head_Letter, Consonant_Placeholder, Tone_Letter] or + return (UISC in [Number, Consonant, Consonant_Head_Letter, + #SPEC-OUTDATED Consonant_Placeholder, + Tone_Letter] or (UGC == Lo and UISC in [Avagraha, Bindu, Consonant_Final, Consonant_Medial, Consonant_Subjoined, Vowel, Vowel_Dependent])) def is_BASE_VOWEL(U, UISC, UGC): return UISC == Vowel_Independent def is_BASE_IND(U, UISC, UGC): - return (UISC in [Consonant_Dead, Modifying_Letter] or UGC == Po) + #SPEC-BROKEN return (UISC in [Consonant_Dead, Modifying_Letter] or UGC == Po) + return (UISC in [Consonant_Dead, Modifying_Letter] or + (UGC == Po and not is_BASE_OTHER(U, UISC, UGC))) # for 104E def is_BASE_NUM(U, UISC, UGC): return UISC == Brahmi_Joining_Number def is_BASE_OTHER(U, UISC, UGC): + if UISC == Consonant_Placeholder: return True #SPEC-OUTDATED return U in [0x00A0, 0x00D7, 0x2015, 0x2022, 0x25CC, 0x25FB, 0x25FC, 0x25FD, 0x25FE] def is_CGJ(U, UISC, UGC): @@ -146,13 +160,15 @@ def is_CONS_FINAL(U, UISC, UGC): return ((UISC == Consonant_Final and UGC != Lo) or UISC == Consonant_Succeeding_Repha) def is_CONS_FINAL_MOD(U, UISC, UGC): - return UISC in [Consonant_Final_Modifier, Syllable_Modifier] + #SPEC-OUTDATED return UISC in [Consonant_Final_Modifier, Syllable_Modifier] + return UISC == Syllable_Modifier def is_CONS_MED(U, UISC, UGC): return UISC == Consonant_Medial and UGC != Lo def is_CONS_MOD(U, UISC, UGC): return UISC in [Nukta, Gemination_Mark, Consonant_Killer] def is_CONS_SUB(U, UISC, UGC): - return UISC == Consonant_Subjoined + #SPEC-OUTDATED return UISC == Consonant_Subjoined + return UISC == Consonant_Subjoined and UGC != Lo def is_HALANT(U, UISC, UGC): return UISC in [Virama, Invisible_Stacker] def is_HALANT_NUM(U, UISC, UGC): @@ -164,13 +180,18 @@ def is_ZWJ(U, UISC, UGC): def is_Word_Joiner(U, UISC, UGC): return U == 0x2060 def is_OTHER(U, UISC, UGC): - return UGC == Zs # or any other SCRIPT_COMMON characters + #SPEC-OUTDATED return UGC == Zs # or any other SCRIPT_COMMON characters + return UISC == Other and not is_SYM_MOD(U, UISC, UGC) def is_Reserved(U, UISC, UGC): return UGC == 'Cn' def is_REPHA(U, UISC, UGC): - return UISC == Consonant_Preceding_Repha + #return UISC == Consonant_Preceding_Repha + #SPEC-OUTDATED hack to categorize Consonant_With_Stacker and Consonant_Prefixed + return UISC in [Consonant_Preceding_Repha, Consonant_With_Stacker, Consonant_Prefixed] def is_SYM(U, UISC, UGC): - return UGC in [So, Sc] or UISC == Symbol_Letter + if U == 0x25CC: return False #SPEC-OUTDATED + #SPEC-OUTDATED return UGC in [So, Sc] or UISC == Symbol_Letter + return UGC in [So, Sc] def is_SYM_MOD(U, UISC, UGC): return U in [0x1B6B, 0x1B6C, 0x1B6D, 0x1B6E, 0x1B6F, 0x1B70, 0x1B71, 0x1B72, 0x1B73] def is_VARIATION_SELECTOR(U, UISC, UGC): @@ -209,7 +230,18 @@ use_mapping = { 'VM': is_VOWEL_MOD, } -#data = map_to_use(data) +def map_to_use(data): + out = {} + items = use_mapping.items() + for U,(UISC,UIPC,UGC,UBlock) in data.items(): + evals = [(k, v(U,UISC,UGC)) for k,v in items] + values = [k for k,v in evals if v] + assert len(values) == 1, "%s %s %s %s" % (hex(U), UISC, UGC, values) + out[U] = (values[0], UBlock) + return out + +defaults = ('O', 'No_Block') +data = map_to_use(data) # Remove the outliers singles = {} @@ -233,55 +265,6 @@ print print '#include "hb-ot-shape-complex-use-private.hh"' print -# Shorten values -short = [{ - "Bindu": 'Bi', - "Cantillation_Mark": 'Ca', - "Joiner": 'ZWJ', - "Non_Joiner": 'ZWNJ', - "Number": 'Nd', - "Visarga": 'Vs', - "Vowel": 'Vo', - "Vowel_Dependent": 'M', - "Other": 'x', - "Consonant_Placeholder":'GB', -},{ - "Not_Applicable": 'x', -}] -all_shorts = [{},{}] - -# Add some of the values, to make them more readable, and to avoid duplicates - - -for i in range (2): - for v,s in short[i].items (): - all_shorts[i][s] = v - -what = ["INDIC_SYLLABIC_CATEGORY", "INDIC_POSITIONAL_CATEGORY"] -what_short = ["SC", "PC"] -for i in range (2): - print - vv = values[i].keys () - vv.sort () - for v in vv: - v_no_and = v.replace ('_And_', '_') - if v in short[i]: - s = short[i][v] - else: - s = ''.join ([c for c in v_no_and if ord ('A') <= ord (c) <= ord ('Z')]) - if s in all_shorts[i]: - raise Exception ("Duplicate short value alias", v, all_shorts[i][s]) - all_shorts[i][s] = v - short[i][v] = s - print "#define %s_%s %s_%s %s/* %3d chars; %s */" % \ - (what_short[i], s, what[i], v.upper (), \ - ' '* ((56-1 - len (what[i]) - 1 - len (v)) / 8), \ - values[i][v], v) -print -print "#define _(S,M) USE_COMBINE_CATEGORIES (SC_##S, PC_##M)" -print -print - total = 0 used = 0 last_block = None @@ -291,17 +274,19 @@ def print_block (block, start, end, data): print print print " /* %s */" % block + if start % 16: + print ' ' * (20 + (start % 16 * 4)), num = 0 assert start % 8 == 0 assert (end+1) % 8 == 0 for u in range (start, end+1): - if u % 8 == 0: + if u % 16 == 0: print print " /* %04X */" % u, if u in data: num += 1 d = data.get (u, defaults) - sys.stdout.write ("%9s" % ("_(%s,%s)," % (short[0][d[0]], short[1][d[1]]))) + sys.stdout.write ("%4s," % d[0]) total += end - start + 1 used += num @@ -316,15 +301,18 @@ num = 0 offset = 0 starts = [] ends = [] +for k,v in sorted(use_mapping.items()): + print "#define %s USE_%s /* %s */" % (k, k, v.__name__[3:]) +print "" print "static const USE_TABLE_ELEMENT_TYPE use_table[] = {" for u in uu: if u <= last: continue - block = data[u][3] + block = data[u][1] start = u//8*8 end = start+1 - while end in uu and block == data[end][3]: + while end in uu and block == data[end][1]: end += 1 end = (end-1)//8*8 + 7 @@ -365,7 +353,7 @@ for p in sorted(pages): print " if (hb_in_range (u, 0x%04Xu, 0x%04Xu)) return use_table[u - 0x%04Xu + %s];" % (start, end-1, 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 " if (unlikely (u == 0x%04Xu)) return %s;" % (u, d[0]) print " break;" print "" print " default:" @@ -373,18 +361,12 @@ print " break;" print " }" print " return _(x,x);" print "}" -print -print "#undef _" -for i in range (2): - print - vv = values[i].keys () - vv.sort () - for v in vv: - print "#undef %s_%s" % \ - (what_short[i], short[i][v]) +print "" +for k in sorted(use_mapping.keys()): + print "#undef %s" % k print print "/* == End of generated table == */" -# Maintain at least 30% occupancy in the table */ -if occupancy < 30: +# Maintain at least 50% occupancy in the table */ +if occupancy < 50: raise Exception ("Table too sparse, please investigate: ", occupancy) diff --git a/src/hb-ot-shape-complex-use-table.cc b/src/hb-ot-shape-complex-use-table.cc index 8f5234c60..1eb054a3b 100644 --- a/src/hb-ot-shape-complex-use-table.cc +++ b/src/hb-ot-shape-complex-use-table.cc @@ -17,60 +17,30 @@ #include "hb-ot-shape-complex-use-private.hh" - -#define SC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 13 chars; Avagraha */ -#define SC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 60 chars; Bindu */ -#define SC_BJN INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER /* 20 chars; Brahmi_Joining_Number */ -#define SC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 52 chars; Cantillation_Mark */ -#define SC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 1805 chars; Consonant */ -#define SC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 7 chars; Consonant_Dead */ -#define SC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 62 chars; Consonant_Final */ -#define SC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 5 chars; Consonant_Head_Letter */ -#define SC_CK INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER /* 2 chars; Consonant_Killer */ -#define SC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 22 chars; Consonant_Medial */ -#define SC_GB INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 13 chars; Consonant_Placeholder */ -#define SC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA /* 1 chars; Consonant_Preceding_Repha */ -#define SC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED /* 2 chars; Consonant_Prefixed */ -#define SC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 61 chars; Consonant_Subjoined */ -#define SC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 4 chars; Consonant_Succeeding_Repha */ -#define SC_CWS INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER /* 4 chars; Consonant_With_Stacker */ -#define SC_GM INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK /* 2 chars; Gemination_Mark */ -#define SC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER /* 7 chars; Invisible_Stacker */ -#define SC_ZWJ INDIC_SYLLABIC_CATEGORY_JOINER /* 1 chars; Joiner */ -#define SC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER /* 1 chars; Modifying_Letter */ -#define SC_ZWNJ INDIC_SYLLABIC_CATEGORY_NON_JOINER /* 1 chars; Non_Joiner */ -#define SC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 23 chars; Nukta */ -#define SC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 420 chars; Number */ -#define SC_NJ INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER /* 1 chars; Number_Joiner */ -#define SC_x INDIC_SYLLABIC_CATEGORY_OTHER /* 1 chars; Other */ -#define SC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 16 chars; Pure_Killer */ -#define SC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 2 chars; Register_Shifter */ -#define SC_SM INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER /* 20 chars; Syllable_Modifier */ -#define SC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 7 chars; Tone_Letter */ -#define SC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK /* 42 chars; Tone_Mark */ -#define SC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 22 chars; Virama */ -#define SC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 29 chars; Visarga */ -#define SC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 30 chars; Vowel */ -#define SC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 572 chars; Vowel_Dependent */ -#define SC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 404 chars; Vowel_Independent */ - -#define PC_B INDIC_POSITIONAL_CATEGORY_BOTTOM /* 256 chars; Bottom */ -#define PC_BR INDIC_POSITIONAL_CATEGORY_BOTTOM_AND_RIGHT /* 2 chars; Bottom_And_Right */ -#define PC_L INDIC_POSITIONAL_CATEGORY_LEFT /* 55 chars; Left */ -#define PC_LR INDIC_POSITIONAL_CATEGORY_LEFT_AND_RIGHT /* 21 chars; Left_And_Right */ -#define PC_x INDIC_POSITIONAL_CATEGORY_NOT_APPLICABLE /* 1 chars; Not_Applicable */ -#define PC_O INDIC_POSITIONAL_CATEGORY_OVERSTRUCK /* 10 chars; Overstruck */ -#define PC_R INDIC_POSITIONAL_CATEGORY_RIGHT /* 249 chars; Right */ -#define PC_T INDIC_POSITIONAL_CATEGORY_TOP /* 324 chars; Top */ -#define PC_TB INDIC_POSITIONAL_CATEGORY_TOP_AND_BOTTOM /* 10 chars; Top_And_Bottom */ -#define PC_TBR INDIC_POSITIONAL_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT /* 1 chars; Top_And_Bottom_And_Right */ -#define PC_TL INDIC_POSITIONAL_CATEGORY_TOP_AND_LEFT /* 6 chars; Top_And_Left */ -#define PC_TLR INDIC_POSITIONAL_CATEGORY_TOP_AND_LEFT_AND_RIGHT /* 4 chars; Top_And_Left_And_Right */ -#define PC_TR INDIC_POSITIONAL_CATEGORY_TOP_AND_RIGHT /* 13 chars; Top_And_Right */ -#define PC_VOL INDIC_POSITIONAL_CATEGORY_VISUAL_ORDER_LEFT /* 19 chars; Visual_Order_Left */ - -#define _(S,M) USE_COMBINE_CATEGORIES (SC_##S, PC_##M) - +#define B USE_B /* BASE */ +#define CGJ USE_CGJ /* CGJ */ +#define CM USE_CM /* CONS_MOD */ +#define F USE_F /* CONS_FINAL */ +#define FM USE_FM /* CONS_FINAL_MOD */ +#define GB USE_GB /* BASE_OTHER */ +#define H USE_H /* HALANT */ +#define HN USE_HN /* HALANT_NUM */ +#define IND USE_IND /* BASE_IND */ +#define IV USE_IV /* BASE_VOWEL */ +#define M USE_M /* CONS_MED */ +#define N USE_N /* BASE_NUM */ +#define O USE_O /* OTHER */ +#define R USE_R /* REPHA */ +#define Rsv USE_Rsv /* Reserved */ +#define S USE_S /* SYM */ +#define SM USE_SM /* SYM_MOD */ +#define SUB USE_SUB /* CONS_SUB */ +#define V USE_V /* VOWEL */ +#define VM USE_VM /* VOWEL_MOD */ +#define VS USE_VS /* VARIATION_SELECTOR */ +#define WJ USE_WJ /* Word_Joiner */ +#define ZWJ USE_ZWJ /* ZWJ */ +#define ZWNJ USE_ZWNJ /* ZWNJ */ static const USE_TABLE_ELEMENT_TYPE use_table[] = { @@ -79,830 +49,534 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Basic Latin */ - - /* 0028 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(GB,x), _(x,x), _(x,x), - /* 0030 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0038 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + O, O, O, O, O, GB, O, O, + /* 0030 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, #define use_offset_0x00a0u 24 /* Latin-1 Supplement */ - /* 00A0 */ _(GB,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 00A8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 00B0 */ _(x,x), _(x,x), _(SM,x), _(SM,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 00B8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 00C0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 00C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 00D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(GB,x), + /* 00A0 */ GB, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 00B0 */ O, O, FM, FM, O, O, O, O, O, O, O, O, O, O, O, O, + /* 00C0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 00D0 */ O, O, O, O, O, O, O, GB, #define use_offset_0x0900u 80 /* Devanagari */ - /* 0900 */ _(Bi,T), _(Bi,T), _(Bi,T), _(Vs,R), _(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,B), _(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), _(Ca,T), _(Ca,B), _(x,T), _(x,T), _(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), _(Nd,x), _(Nd,x), - /* 0968 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0970 */ _(x,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 0978 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), + /* 0900 */ VM, VM, VM, VM, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 0910 */ IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 0930 */ B, B, B, B, B, B, B, B, B, B, V, V, CM, B, V, V, + /* 0940 */ V, V, V, V, V, V, V, V, V, V, V, V, V, H, V, V, + /* 0950 */ O, VM, VM, O, O, V, V, V, B, B, B, B, B, B, B, B, + /* 0960 */ IV, IV, V, V, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0970 */ O, O, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, /* Bengali */ - /* 0980 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(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,B), _(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), _(Nd,x), _(Nd,x), - /* 09E8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,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), + /* 0980 */ O, VM, VM, VM, O, IV, IV, IV, IV, IV, IV, IV, IV, O, O, IV, + /* 0990 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 09A0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 09B0 */ B, O, B, O, O, O, B, B, B, B, O, O, CM, B, V, V, + /* 09C0 */ V, V, V, V, V, O, O, V, V, O, O, V, V, H, IND, O, + /* 09D0 */ O, O, O, O, O, O, O, V, O, O, O, O, B, B, O, B, + /* 09E0 */ IV, IV, V, V, O, O, B, B, B, B, B, B, B, B, B, B, + /* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Gurmukhi */ - /* 0A00 */ _(x,x), _(Bi,T), _(Bi,T), _(Vs,R), _(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,B), _(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), _(Nd,x), _(Nd,x), - /* 0A68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0A70 */ _(Bi,T), _(GM,T), _(GB,x), _(GB,x), _(x,x), _(CM,B), _(x,x), _(x,x), - /* 0A78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 0A00 */ O, VM, VM, VM, O, IV, IV, IV, IV, IV, IV, O, O, O, O, IV, + /* 0A10 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0A20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 0A30 */ B, O, B, B, O, B, B, O, B, B, O, O, CM, O, V, V, + /* 0A40 */ V, V, V, O, O, O, O, V, V, O, O, V, V, H, O, O, + /* 0A50 */ O, O, O, O, O, O, O, O, O, B, B, B, B, O, B, O, + /* 0A60 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0A70 */ VM, CM, GB, GB, O, M, O, O, O, O, O, O, O, O, O, O, /* Gujarati */ - /* 0A80 */ _(x,x), _(Bi,T), _(Bi,T), _(Vs,R), _(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,B), _(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), _(Nd,x), _(Nd,x), - /* 0AE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0AF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0AF8 */ _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 0A80 */ O, VM, VM, VM, O, IV, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, + /* 0A90 */ IV, IV, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0AA0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 0AB0 */ B, O, B, B, O, B, B, B, B, B, O, O, CM, B, V, V, + /* 0AC0 */ V, V, V, V, V, V, O, V, V, V, O, V, V, H, O, O, + /* 0AD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 0AE0 */ IV, IV, V, V, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0AF0 */ O, O, O, O, O, O, O, O, O, B, O, O, O, O, O, O, /* Oriya */ - /* 0B00 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(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,B), _(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), _(Nd,x), _(Nd,x), - /* 0B68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,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), + /* 0B00 */ O, VM, VM, VM, O, IV, IV, IV, IV, IV, IV, IV, IV, O, O, IV, + /* 0B10 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0B20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 0B30 */ B, O, B, B, O, B, B, B, B, B, O, O, CM, B, V, V, + /* 0B40 */ V, V, V, V, V, O, O, V, V, O, O, V, V, H, O, O, + /* 0B50 */ O, O, O, O, O, O, V, V, O, O, O, O, B, B, O, B, + /* 0B60 */ IV, IV, V, V, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0B70 */ O, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Tamil */ - /* 0B80 */ _(x,x), _(x,x), _(Bi,T), _(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,R), _(M,R), _(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), _(Nd,x), _(Nd,x), - /* 0BE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,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), + /* 0B80 */ O, O, VM, IND, O, IV, IV, IV, IV, IV, IV, O, O, O, IV, IV, + /* 0B90 */ IV, O, IV, IV, IV, B, O, O, O, B, B, O, B, O, B, B, + /* 0BA0 */ O, O, O, B, B, O, O, O, B, B, B, O, O, O, B, B, + /* 0BB0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, V, V, + /* 0BC0 */ V, V, V, O, O, O, V, V, V, O, V, V, V, H, O, O, + /* 0BD0 */ O, O, O, O, O, O, O, V, O, O, O, O, O, O, O, O, + /* 0BE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0BF0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Telugu */ - /* 0C00 */ _(Bi,T), _(Bi,R), _(Bi,R), _(Vs,R), _(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), _(C,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), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0C60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), - /* 0C68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,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), + /* 0C00 */ VM, VM, VM, VM, O, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, IV, + /* 0C10 */ IV, O, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0C20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 0C30 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, V, V, + /* 0C40 */ V, V, V, V, V, O, V, V, V, O, V, V, V, H, O, O, + /* 0C50 */ O, O, O, O, O, V, V, O, B, B, B, O, O, O, O, O, + /* 0C60 */ IV, IV, V, V, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0C70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Kannada */ - /* 0C80 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(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,B), _(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), _(Nd,x), _(Nd,x), - /* 0CE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0CF0 */ _(x,x),_(CWS,x),_(CWS,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), + /* 0C80 */ O, VM, VM, VM, O, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, IV, + /* 0C90 */ IV, O, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0CA0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 0CB0 */ B, B, B, B, O, B, B, B, B, B, O, O, CM, B, V, V, + /* 0CC0 */ V, V, V, V, V, O, V, V, V, O, V, V, V, H, O, O, + /* 0CD0 */ O, O, O, O, O, V, V, O, O, O, O, O, O, O, B, O, + /* 0CE0 */ IV, IV, V, V, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0CF0 */ O, R, R, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Malayalam */ - /* 0D00 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(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),_(CPR,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), _(VI,x), - /* 0D60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), - /* 0D68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,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), + /* 0D00 */ O, VM, VM, VM, O, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, IV, + /* 0D10 */ IV, O, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, O, O, B, V, V, + /* 0D40 */ V, V, V, V, V, O, V, V, V, O, V, V, V, H, R, O, + /* 0D50 */ O, O, O, O, O, O, O, V, O, O, O, O, O, O, O, IV, + /* 0D60 */ IV, IV, V, V, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0D70 */ O, O, O, O, O, O, O, O, O, O, IND, IND, IND, IND, IND, IND, /* Sinhala */ - /* 0D80 */ _(x,x), _(x,x), _(Bi,R), _(Vs,R), _(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,TLR), _(M,LR), _(M,R), - /* 0DE0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x), - /* 0DE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0DF0 */ _(x,x), _(x,x), _(M,R), _(M,R), _(x,x), _(x,x), _(x,x), _(x,x), + /* 0D80 */ O, O, VM, VM, O, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 0D90 */ IV, IV, IV, IV, IV, IV, IV, O, O, O, B, B, B, B, B, B, + /* 0DA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 0DB0 */ B, B, O, B, B, B, B, B, B, B, B, B, O, B, O, O, + /* 0DC0 */ B, B, B, B, B, B, B, O, O, O, H, O, O, O, O, V, + /* 0DD0 */ V, V, V, V, V, O, V, O, V, V, V, V, V, V, V, V, + /* 0DE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0DF0 */ O, O, V, V, O, O, O, O, #define use_offset_0x1000u 1352 /* Myanmar */ - /* 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,T), _(TM,B), - /* 1038 */ _(Vs,R), _(IS,x), _(PK,T), _(CM,R), _(CM,x), _(CM,B), _(CM,B), _(C,x), - /* 1040 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 1048 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(GB,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,B), _(CM,B), - /* 1060 */ _(CM,B), _(C,x), _(M,R), _(TM,R), _(TM,R), _(C,x), _(C,x), _(M,R), - /* 1068 */ _(M,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(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,B), _(M,R), _(M,L), _(M,T), _(M,T), _(TM,R), - /* 1088 */ _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,B), _(C,x), _(TM,R), - /* 1090 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 1098 */ _(Nd,x), _(Nd,x), _(TM,R), _(TM,R), _(M,R), _(M,T), _(x,x), _(x,x), + /* 1000 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1020 */ B, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, V, V, V, V, V, + /* 1030 */ V, V, V, V, V, V, VM, VM, VM, H, V, M, M, M, M, B, + /* 1040 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, GB, O, + /* 1050 */ B, B, IV, IV, IV, IV, V, V, V, V, B, B, B, B, M, M, + /* 1060 */ M, B, V, VM, VM, B, B, V, V, VM, VM, VM, VM, VM, B, B, + /* 1070 */ B, V, V, V, V, B, B, B, B, B, B, B, B, B, B, B, + /* 1080 */ B, B, M, V, V, V, V, VM, VM, VM, VM, VM, VM, VM, B, VM, + /* 1090 */ B, B, B, B, B, B, B, B, B, B, VM, VM, V, V, O, O, #define use_offset_0x1700u 1512 /* Tagalog */ - /* 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), _(PK,B), _(x,x), _(x,x), _(x,x), - /* 1718 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1700 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, O, B, B, + /* 1710 */ B, B, V, V, V, O, O, O, O, O, O, O, O, O, O, O, /* Hanunoo */ - /* 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), _(PK,B), _(x,x), _(x,x), _(x,x), - /* 1738 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1720 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1730 */ B, B, V, V, V, O, O, O, O, O, O, O, O, O, O, O, /* Buhid */ - /* 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), + /* 1740 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1750 */ B, B, V, V, O, O, O, O, O, O, O, O, O, O, O, O, /* Tagbanwa */ - /* 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), + /* 1760 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, O, B, B, + /* 1770 */ B, O, V, V, O, O, O, O, O, O, O, O, O, O, O, O, /* Khmer */ - /* 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,T), _(Vs,R), - /* 17C8 */ _(M,R), _(RS,T), _(RS,T), _(SM,T),_(CSR,T), _(CK,T), _(SM,T), _(SM,T), - /* 17D0 */ _(SM,T), _(PK,T), _(IS,x), _(SM,T), _(x,x), _(x,x), _(x,x), _(x,x), - /* 17D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(A,x), _(x,T), _(x,x), _(x,x), - /* 17E0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 17E8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1780 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1790 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 17A0 */ B, B, B, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 17B0 */ IV, IV, IV, IV, O, O, V, V, V, V, V, V, V, V, V, V, + /* 17C0 */ V, V, V, V, V, V, VM, VM, V, VM, VM, FM, F, CM, FM, FM, + /* 17D0 */ FM, V, H, FM, O, O, O, O, O, O, O, O, B, O, O, O, + /* 17E0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, #define use_offset_0x1900u 1752 /* Limbu */ - /* 1900 */ _(GB,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), _(C,x), _(C,x), _(x,x), - /* 1920 */ _(M,T), _(M,T), _(M,B), _(M,R), _(M,R), _(M,TR), _(M,TR), _(M,T), - /* 1928 */ _(M,T), _(CS,R), _(CS,R), _(CS,R), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1930 */ _(CF,R), _(CF,R), _(Bi,B), _(CF,R), _(CF,R), _(CF,R), _(CF,R), _(CF,R), - /* 1938 */ _(CF,R), _(CF,B), _(M,T), _(SM,B), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1940 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x), - /* 1948 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 1900 */ GB, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, + /* 1920 */ V, V, V, V, V, V, V, V, V, SUB, SUB, SUB, O, O, O, O, + /* 1930 */ F, F, VM, F, F, F, F, F, F, F, V, FM, O, O, O, O, + /* 1940 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, /* Tai Le */ - /* 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), + /* 1950 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1960 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, + /* 1970 */ B, B, B, B, B, O, O, O, O, O, O, O, O, O, O, O, /* New Tai Lue */ - /* 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,VOL),_(M,VOL),_(M,VOL), - /* 19B8 */ _(M,R), _(M,R),_(M,VOL), _(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,R), _(TM,R), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 19D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 19D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 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), + /* 1980 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 19A0 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, + /* 19B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 19C0 */ B, B, B, B, B, B, B, B, VM, VM, O, O, O, O, O, O, + /* 19D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 19E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 19F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Buginese */ - /* 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,T), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1A00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1A10 */ B, B, B, B, B, B, B, V, V, V, V, V, O, O, O, O, /* Tai Tham */ - /* 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,L), _(CM,B), _(CF,R), - /* 1A58 */ _(CF,T), _(CF,T), _(CF,T), _(CF,B), _(CF,B), _(CF,B), _(CF,B), _(x,x), - /* 1A60 */ _(IS,x), _(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,T), _(TM,T), _(TM,T), - /* 1A78 */ _(TM,T), _(TM,T), _(SM,T), _(SM,T), _(SM,T), _(x,x), _(x,x), _(SM,B), - /* 1A80 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 1A88 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1A90 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 1A98 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1A30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1A40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, IV, IV, IV, + /* 1A50 */ IV, IV, IV, B, B, M, M, F, F, F, F, F, F, F, F, O, + /* 1A60 */ H, V, V, V, V, V, V, V, V, V, V, V, V, V, V, V, + /* 1A70 */ V, V, V, V, V, VM, VM, VM, VM, VM, FM, FM, FM, O, O, FM, + /* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 1A90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, #define use_offset_0x1b00u 2168 /* Balinese */ - /* 1B00 */ _(Bi,T), _(Bi,T), _(Bi,T),_(CSR,T), _(Vs,R), _(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,T), _(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 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 1B58 */ _(Nd,x), _(Nd,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,T), _(x,B), _(x,T), _(x,T), _(x,T), - /* 1B70 */ _(x,T), _(x,T), _(x,T), _(x,T), _(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), + /* 1B00 */ VM, VM, VM, F, VM, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 1B10 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1B30 */ B, B, B, B, CM, V, V, V, V, V, V, V, V, V, V, V, + /* 1B40 */ V, V, V, V, H, B, B, B, B, B, B, B, O, O, O, O, + /* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 1B60 */ O, O, O, O, O, O, O, O, O, O, O, SM, SM, SM, SM, SM, + /* 1B70 */ SM, SM, SM, SM, O, O, O, O, O, O, O, O, O, O, O, O, /* Sundanese */ - /* 1B80 */ _(Bi,T),_(CSR,T), _(Vs,R), _(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,R), _(CS,B), _(CS,B), _(M,T), _(M,B), _(M,L), _(M,R), - /* 1BA8 */ _(M,T), _(M,T), _(PK,R), _(IS,x), _(CS,B), _(CS,B), _(C,x), _(C,x), - /* 1BB0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 1BB8 */ _(Nd,x), _(Nd,x), _(A,x), _(C,x), _(C,x), _(C,x), _(CF,x), _(CF,x), + /* 1B80 */ VM, F, VM, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, + /* 1B90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1BA0 */ B, SUB, SUB, SUB, V, V, V, V, V, V, V, H, SUB, SUB, B, B, + /* 1BB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* Batak */ - /* 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,T), _(M,R), - /* 1BE8 */ _(M,T), _(M,T), _(M,R), _(M,R), _(M,R), _(M,T), _(M,R), _(M,T), - /* 1BF0 */ _(CF,T), _(CF,T), _(PK,R), _(PK,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), + /* 1BC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1BD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1BE0 */ B, B, B, B, IV, IV, CM, V, V, V, V, V, V, V, V, V, + /* 1BF0 */ F, F, V, V, O, O, O, O, O, O, O, O, O, O, O, O, /* Lepcha */ - /* 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,R), _(CS,R), _(M,R), _(M,L), - /* 1C28 */ _(M,L), _(M,TL), _(M,R), _(M,R), _(M,B), _(CF,T), _(CF,T), _(CF,T), - /* 1C30 */ _(CF,T), _(CF,T), _(CF,T), _(CF,T), _(Bi,L), _(Bi,L), _(SM,T), _(N,B), - /* 1C38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1C40 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 1C48 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), + /* 1C00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1C20 */ B, B, B, B, SUB, SUB, V, V, V, V, V, V, V, F, F, F, + /* 1C30 */ F, F, F, F, VM, VM, FM, CM, O, O, O, O, O, O, O, O, + /* 1C40 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, B, B, #define use_offset_0x1cd0u 2504 /* Vedic Extensions */ - /* 1CD0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(x,x), _(Ca,O), _(Ca,B), _(Ca,B), _(Ca,B), - /* 1CD8 */ _(Ca,B), _(Ca,B), _(Ca,T), _(Ca,T), _(Ca,B), _(Ca,B), _(Ca,B), _(Ca,B), - /* 1CE0 */ _(Ca,T), _(Ca,R), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O), - /* 1CE8 */ _(x,O), _(x,x), _(x,x), _(x,x), _(x,x), _(x,B), _(x,x), _(x,x), - /* 1CF0 */ _(x,x), _(x,x), _(Vs,x), _(Vs,x), _(Ca,T), _(x,x), _(x,x), _(x,x), - /* 1CF8 */ _(Ca,x), _(Ca,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 1CD0 */ VM, VM, VM, O, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, + /* 1CE0 */ VM, VM, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 1CF0 */ O, O, VM, VM, VM, O, O, O, VM, VM, O, O, O, O, O, O, #define use_offset_0x2008u 2552 /* General Punctuation */ - - /* 2008 */ _(x,x), _(x,x), _(x,x), _(x,x),_(ZWNJ,x),_(ZWJ,x), _(x,x), _(x,x), - /* 2010 */ _(GB,x), _(GB,x), _(GB,x), _(GB,x), _(GB,x), _(x,x), _(x,x), _(x,x), + O, O, O, O,ZWNJ, ZWJ, O, O, + /* 2010 */ GB, GB, GB, GB, GB, O, O, O, #define use_offset_0x2070u 2568 /* Superscripts and Subscripts */ - /* 2070 */ _(x,x), _(x,x), _(x,x), _(x,x), _(SM,x), _(x,x), _(x,x), _(x,x), - /* 2078 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 2080 */ _(x,x), _(x,x), _(SM,x), _(SM,x), _(SM,x), _(x,x), _(x,x), _(x,x), + /* 2070 */ O, O, O, O, FM, O, O, O, O, O, O, O, O, O, O, O, + /* 2080 */ O, O, FM, FM, FM, O, O, O, #define use_offset_0xa800u 2592 /* Syloti Nagri */ - /* A800 */ _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(PK,T), _(C,x), - /* A808 */ _(C,x), _(C,x), _(C,x), _(Bi,T), _(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), - /* 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), + /* A800 */ IV, IV, O, IV, IV, IV, V, B, B, B, B, VM, B, B, B, B, + /* A810 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A820 */ B, B, B, V, V, V, V, V, O, O, O, O, O, O, O, O, + /* A830 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Phags-pa */ - /* 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), + /* A840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A850 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A860 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A870 */ B, B, B, B, O, O, O, O, O, O, O, O, O, O, O, O, /* Saurashtra */ - /* A880 */ _(Bi,R), _(Vs,R), _(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,R), _(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 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* A8D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* A880 */ VM, VM, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* A890 */ IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A8A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A8B0 */ B, B, B, B, F, V, V, V, V, V, V, V, V, V, V, V, + /* A8C0 */ V, V, V, V, H, O, O, O, O, O, O, O, O, O, O, O, + /* A8D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* Devanagari Extended */ - /* A8E0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), - /* A8E8 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), - /* A8F0 */ _(Ca,T), _(Ca,T), _(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), + /* A8E0 */ VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, + /* A8F0 */ VM, VM, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Kayah Li */ - /* A900 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* A908 */ _(Nd,x), _(Nd,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,B), _(TM,B), _(TM,B), _(x,x), _(x,x), + /* A900 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A920 */ B, B, B, B, B, B, V, V, V, V, V, VM, VM, VM, O, O, /* Rejang */ - /* 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,T), - /* A950 */ _(CF,T), _(CF,T), _(CF,R), _(PK,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), - /* 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), + /* A930 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A940 */ B, B, B, B, B, B, B, V, V, V, V, V, V, V, V, F, + /* A950 */ F, F, F, V, O, O, O, O, O, O, O, O, O, O, O, O, + /* A960 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* A970 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Javanese */ - /* A980 */ _(Bi,T), _(Bi,T),_(CSR,T), _(Vs,R), _(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,T), _(M,R), _(M,R), _(M,T), _(M,T), - /* A9B8 */ _(M,B), _(M,B), _(M,L), _(M,L), _(M,T), _(CS,R), _(CM,R), _(CM,R), - /* 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 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* A9D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* A980 */ VM, VM, F, VM, IV, IV, IV, IV, IV, B, B, B, IV, IV, IV, B, + /* A990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A9A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A9B0 */ B, B, B, CM, V, V, V, V, V, V, V, V, V, SUB, M, M, + /* A9C0 */ H, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* A9D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* Myanmar Extended-B */ - /* A9E0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,T), _(x,x), _(C,x), - /* A9E8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A9F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* A9F8 */ _(Nd,x), _(Nd,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), + /* A9E0 */ B, B, B, B, B, V, O, B, B, B, B, B, B, B, B, B, + /* A9F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, /* Cham */ - /* 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,R), _(CM,L), _(CM,B), _(CM,B), _(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,T), _(CF,x), _(CF,x), _(CF,x), _(CF,x), - /* AA48 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,T), _(CF,R), _(x,x), _(x,x), - /* AA50 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* AA58 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* AA00 */ IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, + /* AA10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* AA20 */ B, B, B, B, B, B, B, B, B, V, V, V, V, V, V, V, + /* AA30 */ V, V, V, M, M, M, M, O, O, O, O, O, O, O, O, O, + /* AA40 */ B, B, B, F, B, B, B, B, B, B, B, B, F, F, O, O, + /* AA50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* Myanmar Extended-A */ - /* 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,R), _(TM,T), _(TM,R), _(C,x), _(C,x), + /* AA60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* AA70 */ O, B, B, B, O, O, O, O, O, O, B, VM, VM, VM, B, B, /* Tai Viet */ - /* 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,T), - /* AAC0 */ _(TL,x), _(TM,T), _(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), + /* AA80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* AA90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* AAA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* AAB0 */ V, B, V, V, V, B, B, V, V, B, B, B, B, B, V, VM, + /* AAC0 */ B, VM, B, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* AAD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Meetei Mayek Extensions */ - /* 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,R), _(IS,x), _(x,x), + /* AAE0 */ IV, IV, B, B, B, B, B, B, B, B, B, V, V, V, V, V, + /* AAF0 */ O, O, O, O, O, VM, H, O, #define use_offset_0xabc0u 3352 /* Meetei Mayek */ - /* 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,R), _(PK,B), _(x,x), _(x,x), - /* ABF0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* ABF8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* ABC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, IV, IV, + /* ABD0 */ B, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* ABE0 */ B, B, B, V, V, V, V, V, V, V, V, O, VM, V, O, O, + /* ABF0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, #define use_offset_0x10a00u 3416 /* Kharoshthi */ - /* 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), _(M,B), _(Bi,B), _(Vs,T), - /* 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 */ _(N,T), _(N,B), _(N,B), _(x,x), _(x,x), _(x,x), _(x,x), _(IS,x), - /* 10A40 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), + /* 10A00 */ B, V, V, V, O, V, V, O, O, O, O, O, V, V, VM, VM, + /* 10A10 */ B, B, B, B, O, B, B, B, O, B, B, B, B, B, B, B, + /* 10A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 10A30 */ B, B, B, B, O, O, O, O, CM, CM, CM, O, O, O, O, H, + /* 10A40 */ B, B, B, B, B, B, B, B, #define use_offset_0x11000u 3488 /* Brahmi */ - /* 11000 */ _(Bi,R), _(Bi,T), _(Vs,R),_(CWS,x),_(CWS,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),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x), - /* 11058 */_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x), - /* 11060 */_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x), _(Nd,x), _(Nd,x), - /* 11068 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,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), + /* 11000 */ VM, VM, VM, R, R, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 11010 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11020 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11030 */ B, B, B, B, B, B, B, B, V, V, V, V, V, V, V, V, + /* 11040 */ V, V, V, V, V, V, H, O, O, O, O, O, O, O, O, O, + /* 11050 */ O, O, N, N, N, N, N, N, N, N, N, N, N, N, N, N, + /* 11060 */ N, N, N, N, N, N, B, B, B, B, B, B, B, B, B, B, + /* 11070 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Kaithi */ - /* 11080 */ _(Bi,T), _(Bi,T), _(Vs,R), _(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,B), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11080 */ VM, VM, VM, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, + /* 11090 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 110A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 110B0 */ V, V, V, V, V, V, V, V, V, H, CM, O, O, O, O, O, #define use_offset_0x11100u 3680 /* Chakma */ - /* 11100 */ _(Bi,T), _(Bi,T), _(Vs,T), _(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), _(IS,x), _(PK,T), _(x,x), _(Nd,x), _(Nd,x), - /* 11138 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,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), + /* 11100 */ VM, VM, VM, IV, IV, IV, IV, B, B, B, B, B, B, B, B, B, + /* 11110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11120 */ B, B, B, B, B, B, B, V, V, V, V, V, V, V, V, V, + /* 11130 */ V, V, V, H, V, O, B, B, B, B, B, B, B, B, B, B, + /* 11140 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Mahajani */ - /* 11150 */ _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(C,x), _(C,x), _(C,x), - /* 11158 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11160 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11168 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11170 */ _(C,x), _(C,x), _(C,x), _(N,B), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11178 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11150 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11160 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11170 */ B, B, B, CM, O, O, O, O, O, O, O, O, O, O, O, O, /* Sharada */ - /* 11180 */ _(Bi,T), _(Bi,T), _(Vs,R), _(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), _(CP,x), _(CP,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 111C8 */ _(x,x), _(x,x), _(N,x), _(M,T), _(M,B), _(x,x), _(x,x), _(x,x), - /* 111D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 111D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11180 */ VM, VM, VM, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 11190 */ IV, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 111A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 111B0 */ B, B, B, V, V, V, V, V, V, V, V, V, V, V, V, V, + /* 111C0 */ H, B, R, R, O, O, O, O, O, O, CM, V, V, O, O, O, + /* 111D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* Sinhala Archaic Numbers */ - /* 111E0 */ _(x,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 111E8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 111F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), - /* 111F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 111E0 */ O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 111F0 */ B, B, B, B, B, O, O, O, O, O, O, O, O, O, O, O, /* Khojki */ - /* 11200 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 11208 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11210 */ _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11218 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11220 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11228 */ _(C,x), _(C,x), _(C,x), _(C,x), _(M,R), _(M,R), _(M,R), _(M,B), - /* 11230 */ _(M,T), _(M,T), _(M,TR), _(M,TR), _(Bi,T), _(V,R), _(N,T), _(GM,T), + /* 11200 */ IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, + /* 11210 */ B, B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, V, V, V, V, + /* 11230 */ V, V, V, V, VM, H, CM, CM, #define use_offset_0x11280u 3992 /* Multani */ - /* 11280 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(x,x), - /* 11288 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), - /* 11290 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11298 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), - /* 112A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 112A8 */ _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11280 */ IV, IV, IV, IV, B, B, B, O, B, O, B, B, B, B, O, B, + /* 11290 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, B, + /* 112A0 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, /* Khudawadi */ - /* 112B0 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 112B8 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 112C0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 112C8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 112D0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 112D8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(Bi,T), - /* 112E0 */ _(M,R), _(M,L), _(M,R), _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), - /* 112E8 */ _(M,T), _(N,B), _(PK,B), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 112F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 112F8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 112B0 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, + /* 112C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 112D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VM, + /* 112E0 */ V, V, V, V, V, V, V, V, V, CM, V, O, O, O, O, O, + /* 112F0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* Grantha */ - /* 11300 */ _(Bi,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), - /* 11308 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x), - /* 11310 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), - /* 11318 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11320 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11328 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11330 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), - /* 11338 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,R), - /* 11340 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(x,x), _(M,L), - /* 11348 */ _(M,L), _(x,x), _(x,x), _(M,LR), _(M,LR), _(V,R), _(x,x), _(x,x), - /* 11350 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), - /* 11358 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11360 */ _(VI,x), _(VI,x), _(M,R), _(M,R), _(x,x), _(x,x), _(Ca,T), _(Ca,T), - /* 11368 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(x,x), _(x,x), _(x,x), - /* 11370 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(x,x), _(x,x), _(x,x), + /* 11300 */ VM, VM, VM, VM, O, IV, IV, IV, IV, IV, IV, IV, IV, O, O, IV, + /* 11310 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 11320 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 11330 */ B, O, B, B, O, B, B, B, B, B, O, O, CM, B, V, V, + /* 11340 */ V, V, V, V, V, O, O, V, V, O, O, V, V, H, O, O, + /* 11350 */ O, O, O, O, O, O, O, V, O, O, O, O, O, O, O, O, + /* 11360 */ IV, IV, V, V, O, O, VM, VM, VM, VM, VM, VM, VM, O, O, O, + /* 11370 */ VM, VM, VM, VM, VM, O, O, O, #define use_offset_0x11480u 4240 /* Tirhuta */ - /* 11480 */ _(x,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 11488 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), - /* 11490 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11498 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 114A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 114A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 114B0 */ _(M,R), _(M,L), _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,B), - /* 114B8 */ _(M,B), _(M,L), _(M,T), _(M,TL), _(M,LR), _(M,R), _(M,LR), _(Bi,T), - /* 114C0 */ _(Bi,T), _(Vs,R), _(V,B), _(N,B), _(A,x), _(x,x), _(x,x), _(x,x), - /* 114C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 114D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 114D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11480 */ O, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, + /* 11490 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 114A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 114B0 */ V, V, V, V, V, V, V, V, V, V, V, V, V, V, V, VM, + /* 114C0 */ VM, VM, H, CM, B, O, O, O, O, O, O, O, O, O, O, O, + /* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, #define use_offset_0x11580u 4336 /* Siddham */ - /* 11580 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 11588 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), - /* 11590 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11598 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 115A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 115A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,R), - /* 115B0 */ _(M,L), _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), - /* 115B8 */ _(M,L), _(M,TL), _(M,LR),_(M,TLR), _(Bi,T), _(Bi,T), _(Vs,R), _(V,B), - /* 115C0 */ _(N,B), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 115C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 115D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 115D8 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), - /* 115E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 115E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 115F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 115F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11580 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, + /* 11590 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 115A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, V, + /* 115B0 */ V, V, V, V, V, V, O, O, V, V, V, V, VM, VM, VM, H, + /* 115C0 */ CM, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 115D0 */ O, O, O, O, O, O, O, O, IV, IV, IV, IV, V, V, O, O, + /* 115E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 115F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Modi */ - /* 11600 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 11608 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), - /* 11610 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11618 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11620 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11628 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11630 */ _(M,R), _(M,R), _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,B), - /* 11638 */ _(M,B), _(M,T), _(M,T), _(M,R), _(M,R), _(Bi,T), _(Vs,R), _(V,B), - /* 11640 */ _(M,T), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11648 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11650 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 11658 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11660 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11668 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11670 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11678 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11600 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, + /* 11610 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11620 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11630 */ V, V, V, V, V, V, V, V, V, V, V, V, V, VM, VM, H, + /* 11640 */ V, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11650 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 11660 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11670 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Takri */ - /* 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,T), _(Vs,R), _(M,T), _(M,L), _(M,R), - /* 116B0 */ _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), _(M,T), _(V,R), _(N,B), - /* 116B8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 116C0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 116C8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 116D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 116D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 116E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 116E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 116F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 116F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11680 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, + /* 11690 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 116A0 */ B, B, B, B, B, B, B, B, B, B, B, VM, VM, V, V, V, + /* 116B0 */ V, V, V, V, V, V, H, CM, O, O, O, O, O, O, O, O, + /* 116C0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 116D0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 116E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 116F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Ahom */ - /* 11700 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11708 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11710 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11718 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(CM,B), _(CM,x), _(CM,T), - /* 11720 */ _(M,R), _(M,R), _(M,T), _(M,T), _(M,B), _(M,B), _(M,L), _(M,T), - /* 11728 */ _(M,B), _(M,T), _(M,T), _(PK,T), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11730 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 11738 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 11700 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11710 */ B, B, B, B, B, B, B, B, B, B, O, O, O, M, M, M, + /* 11720 */ V, V, V, V, V, V, V, V, V, V, V, V, O, O, O, O, + /* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, }; /* Table items: 4784; occupancy: 72% */ @@ -928,7 +602,7 @@ hb_use_get_categories (hb_codepoint_t u) case 0x2u: if (hb_in_range (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u]; if (hb_in_range (u, 0x2070u, 0x2087u)) return use_table[u - 0x2070u + use_offset_0x2070u]; - if (unlikely (u == 0x25CCu)) return _(GB,x); + if (unlikely (u == 0x25CCu)) return GB; break; case 0xAu: @@ -946,7 +620,7 @@ hb_use_get_categories (hb_codepoint_t u) if (hb_in_range (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u]; if (hb_in_range (u, 0x11480u, 0x114DFu)) return use_table[u - 0x11480u + use_offset_0x11480u]; if (hb_in_range (u, 0x11580u, 0x1173Fu)) return use_table[u - 0x11580u + use_offset_0x11580u]; - if (unlikely (u == 0x1107Fu)) return _(NJ,x); + if (unlikely (u == 0x1107Fu)) return HN; break; default: @@ -955,57 +629,29 @@ hb_use_get_categories (hb_codepoint_t u) return _(x,x); } -#undef _ - -#undef SC_A -#undef SC_Bi -#undef SC_BJN -#undef SC_Ca -#undef SC_C -#undef SC_CD -#undef SC_CF -#undef SC_CHL -#undef SC_CK -#undef SC_CM -#undef SC_GB -#undef SC_CPR -#undef SC_CP -#undef SC_CS -#undef SC_CSR -#undef SC_CWS -#undef SC_GM -#undef SC_IS -#undef SC_ZWJ -#undef SC_ML -#undef SC_ZWNJ -#undef SC_N -#undef SC_Nd -#undef SC_NJ -#undef SC_x -#undef SC_PK -#undef SC_RS -#undef SC_SM -#undef SC_TL -#undef SC_TM -#undef SC_V -#undef SC_Vs -#undef SC_Vo -#undef SC_M -#undef SC_VI - -#undef PC_B -#undef PC_BR -#undef PC_L -#undef PC_LR -#undef PC_x -#undef PC_O -#undef PC_R -#undef PC_T -#undef PC_TB -#undef PC_TBR -#undef PC_TL -#undef PC_TLR -#undef PC_TR -#undef PC_VOL +#undef B +#undef CGJ +#undef CM +#undef F +#undef FM +#undef GB +#undef H +#undef HN +#undef IND +#undef IV +#undef M +#undef N +#undef O +#undef R +#undef Rsv +#undef S +#undef SM +#undef SUB +#undef V +#undef VM +#undef VS +#undef WJ +#undef ZWJ +#undef ZWNJ /* == End of generated table == */ From 44910cef626e6d03baa4d89d8fbe2c088971902d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 20 Jul 2015 18:01:10 +0100 Subject: [PATCH 11/43] [USE] Finish converting Unicode positional categories to USE Even compiles. --- src/gen-use-table.py | 114 ++++- src/hb-ot-shape-complex-use-table.cc | 702 ++++++++++++++------------- 2 files changed, 467 insertions(+), 349 deletions(-) diff --git a/src/gen-use-table.py b/src/gen-use-table.py index f1484fdba..7293b73cd 100755 --- a/src/gen-use-table.py +++ b/src/gen-use-table.py @@ -99,7 +99,7 @@ property_names = [ 'Number', 'Brahmi_Joining_Number', # Indic_Positional_Category - 'Not_Applicable' + 'Not_Applicable', 'Right', 'Left', 'Visual_Order_Left', @@ -121,8 +121,7 @@ class PropertyValue(object): def __str__(self): return self.name def __eq__(self, other): - assert isinstance(other, basestring) - return self.name == other + return self.name == (other if isinstance(other, basestring) else other.name) def __ne__(self, other): return not (self == other) @@ -230,14 +229,95 @@ use_mapping = { 'VM': is_VOWEL_MOD, } +use_positions = { + 'F': { + 'Abv': [Top], + 'Blw': [Bottom], + 'Pst': [Right], + }, + 'M': { + 'Abv': [Top], + 'Blw': [Bottom], + 'Pst': [Right], + 'Pre': [Left], + }, + 'CM': { + 'Abv': [Top], + 'Blw': [Bottom], + }, + 'V': { + 'Abv': [Top, Top_And_Bottom, Top_And_Bottom_And_Right, Top_And_Right], + 'Blw': [Bottom, Overstruck, Bottom_And_Right], + 'Pst': [Right], + 'Pre': [Left, Top_And_Left, Top_And_Left_And_Right, Left_And_Right], + }, + 'VM': { + 'Abv': [Top], + 'Blw': [Bottom, Overstruck], + 'Pst': [Right], + 'Pre': [Left], + }, + 'SM': { + 'Abv': [Top], + 'Blw': [Bottom], + }, + 'H': None, + 'B': None, + 'FM': None, + 'SUB': None, +} + def map_to_use(data): out = {} items = use_mapping.items() for U,(UISC,UIPC,UGC,UBlock) in data.items(): + + # Resolve Indic_Syllabic_Category + + # TODO: These don't have UISC assigned in Unicode 8.0, but + # have UIPC + if U == 0x17DD: UISC = Vowel_Dependent + if 0x1CE2 <= U <= 0x1CE8: UISC = Cantillation_Mark + + # TODO: U+1CED should only be allowed after some of + # the nasalization marks, maybe only for U+1CE9..U+1CF1. + if U == 0x1CED: UISC = Tone_Mark + evals = [(k, v(U,UISC,UGC)) for k,v in items] values = [k for k,v in evals if v] assert len(values) == 1, "%s %s %s %s" % (hex(U), UISC, UGC, values) - out[U] = (values[0], UBlock) + USE = values[0] + + # Resolve Indic_Positional_Category + + # TODO: Not in Unicode 8.0 yet, but in spec. + if U == 0x1B6C: UIPC = Bottom + + # TODO: These should die, but have UIPC in Unicode 8.0 + if U in [0x953, 0x954]: UIPC = Not_Applicable + + # TODO: In USE's override list but not in Unicode 8.0 + if U == 0x103C: UIPC = Left + + # TODO: These are not in USE's override list that we have, nor are they in Unicode 8.0 + if 0xA926 <= U <= 0xA92A: UIPC = Top + if U == 0x111CA: UIPC = Bottom + if U == 0x11300: UIPC = Top + if U == 0x1133C: UIPC = Bottom + if U == 0x1171E: UIPC = Left # Correct?! + if 0x1CF2 <= U <= 0x1CF3: UIPC = Right + if 0x1CF8 <= U <= 0x1CF9: UIPC = Top + + assert (UIPC in [Not_Applicable, Visual_Order_Left] or + USE in use_positions), "%s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UGC) + + pos_mapping = use_positions.get(USE, None) + if pos_mapping: + values = [k for k,v in pos_mapping.items() if v and UIPC in v] + assert len(values) == 1, "%s %s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UGC, values) + USE = USE + values[0] + + out[U] = (USE, UBlock) return out defaults = ('O', 'No_Block') @@ -275,7 +355,7 @@ def print_block (block, start, end, data): print print " /* %s */" % block if start % 16: - print ' ' * (20 + (start % 16 * 4)), + print ' ' * (20 + (start % 16 * 6)), num = 0 assert start % 8 == 0 assert (end+1) % 8 == 0 @@ -286,7 +366,7 @@ def print_block (block, start, end, data): if u in data: num += 1 d = data.get (u, defaults) - sys.stdout.write ("%4s," % d[0]) + sys.stdout.write ("%6s," % d[0]) total += end - start + 1 used += num @@ -302,7 +382,13 @@ offset = 0 starts = [] ends = [] for k,v in sorted(use_mapping.items()): + if k in use_positions and use_positions[k]: continue print "#define %s USE_%s /* %s */" % (k, k, v.__name__[3:]) +for k,v in sorted(use_positions.items()): + if not v: continue + for suf in v.keys(): + tag = k + suf + print "#define %s USE_%s" % (tag, tag) print "" print "static const USE_TABLE_ELEMENT_TYPE use_table[] = {" for u in uu: @@ -339,6 +425,15 @@ occupancy = used * 100. / total page_bits = 12 print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy) print +for k in sorted(use_mapping.keys()): + if k in use_positions and use_positions[k]: continue + print "#undef %s" % k +for k,v in sorted(use_positions.items()): + if not v: continue + for suf in v.keys(): + tag = k + suf + print "#undef %s" % tag +print print "USE_TABLE_ELEMENT_TYPE" print "hb_use_get_categories (hb_codepoint_t u)" print "{" @@ -353,17 +448,14 @@ for p in sorted(pages): print " if (hb_in_range (u, 0x%04Xu, 0x%04Xu)) return use_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset) for u,d in singles.items (): if p != u>>page_bits: continue - print " if (unlikely (u == 0x%04Xu)) return %s;" % (u, d[0]) + print " if (unlikely (u == 0x%04Xu)) return USE_%s;" % (u, d[0]) print " break;" print "" print " default:" print " break;" print " }" -print " return _(x,x);" +print " return USE_O;" print "}" -print "" -for k in sorted(use_mapping.keys()): - print "#undef %s" % k print print "/* == End of generated table == */" diff --git a/src/hb-ot-shape-complex-use-table.cc b/src/hb-ot-shape-complex-use-table.cc index 1eb054a3b..4ce9010b2 100644 --- a/src/hb-ot-shape-complex-use-table.cc +++ b/src/hb-ot-shape-complex-use-table.cc @@ -19,28 +19,41 @@ #define B USE_B /* BASE */ #define CGJ USE_CGJ /* CGJ */ -#define CM USE_CM /* CONS_MOD */ -#define F USE_F /* CONS_FINAL */ #define FM USE_FM /* CONS_FINAL_MOD */ #define GB USE_GB /* BASE_OTHER */ #define H USE_H /* HALANT */ #define HN USE_HN /* HALANT_NUM */ #define IND USE_IND /* BASE_IND */ #define IV USE_IV /* BASE_VOWEL */ -#define M USE_M /* CONS_MED */ #define N USE_N /* BASE_NUM */ #define O USE_O /* OTHER */ #define R USE_R /* REPHA */ #define Rsv USE_Rsv /* Reserved */ #define S USE_S /* SYM */ -#define SM USE_SM /* SYM_MOD */ #define SUB USE_SUB /* CONS_SUB */ -#define V USE_V /* VOWEL */ -#define VM USE_VM /* VOWEL_MOD */ #define VS USE_VS /* VARIATION_SELECTOR */ #define WJ USE_WJ /* Word_Joiner */ #define ZWJ USE_ZWJ /* ZWJ */ #define ZWNJ USE_ZWNJ /* ZWNJ */ +#define CMBlw USE_CMBlw +#define CMAbv USE_CMAbv +#define FBlw USE_FBlw +#define FPst USE_FPst +#define FAbv USE_FAbv +#define MPre USE_MPre +#define MBlw USE_MBlw +#define MPst USE_MPst +#define MAbv USE_MAbv +#define SMBlw USE_SMBlw +#define SMAbv USE_SMAbv +#define VPre USE_VPre +#define VBlw USE_VBlw +#define VPst USE_VPst +#define VAbv USE_VAbv +#define VMPre USE_VMPre +#define VMBlw USE_VMBlw +#define VMPst USE_VMPst +#define VMAbv USE_VMAbv static const USE_TABLE_ELEMENT_TYPE use_table[] = { @@ -49,537 +62,575 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Basic Latin */ - O, O, O, O, O, GB, O, O, - /* 0030 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + O, O, O, O, O, GB, O, O, + /* 0030 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, #define use_offset_0x00a0u 24 /* Latin-1 Supplement */ - /* 00A0 */ GB, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 00B0 */ O, O, FM, FM, O, O, O, O, O, O, O, O, O, O, O, O, - /* 00C0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 00D0 */ O, O, O, O, O, O, O, GB, + /* 00A0 */ GB, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 00B0 */ O, O, FM, FM, O, O, O, O, O, O, O, O, O, O, O, O, + /* 00C0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 00D0 */ O, O, O, O, O, O, O, GB, #define use_offset_0x0900u 80 /* Devanagari */ - /* 0900 */ VM, VM, VM, VM, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, - /* 0910 */ IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, - /* 0920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0930 */ B, B, B, B, B, B, B, B, B, B, V, V, CM, B, V, V, - /* 0940 */ V, V, V, V, V, V, V, V, V, V, V, V, V, H, V, V, - /* 0950 */ O, VM, VM, O, O, V, V, V, B, B, B, B, B, B, B, B, - /* 0960 */ IV, IV, V, V, O, O, B, B, B, B, B, B, B, B, B, B, - /* 0970 */ O, O, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, + /* 0900 */ VMAbv, VMAbv, VMAbv, VMPst, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 0910 */ IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 0930 */ B, B, B, B, B, B, B, B, B, B, VAbv, VPst, CMBlw, B, VPst, VPre, + /* 0940 */ VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VPst, VPst, VPst, VPst, H, VPre, VPst, + /* 0950 */ O, VMAbv, VMBlw, O, O, VAbv, VBlw, VBlw, B, B, B, B, B, B, B, B, + /* 0960 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0970 */ O, O, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, /* Bengali */ - /* 0980 */ O, VM, VM, VM, O, IV, IV, IV, IV, IV, IV, IV, IV, O, O, IV, - /* 0990 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, - /* 09A0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, - /* 09B0 */ B, O, B, O, O, O, B, B, B, B, O, O, CM, B, V, V, - /* 09C0 */ V, V, V, V, V, O, O, V, V, O, O, V, V, H, IND, O, - /* 09D0 */ O, O, O, O, O, O, O, V, O, O, O, O, B, B, O, B, - /* 09E0 */ IV, IV, V, V, O, O, B, B, B, B, B, B, B, B, B, B, - /* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 0980 */ O, VMAbv, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, O, IV, + /* 0990 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 09A0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 09B0 */ B, O, B, O, O, O, B, B, B, B, O, O, CMBlw, B, VPst, VPre, + /* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, IND, O, + /* 09D0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, B, B, O, B, + /* 09E0 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Gurmukhi */ - /* 0A00 */ O, VM, VM, VM, O, IV, IV, IV, IV, IV, IV, O, O, O, O, IV, - /* 0A10 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, - /* 0A20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, - /* 0A30 */ B, O, B, B, O, B, B, O, B, B, O, O, CM, O, V, V, - /* 0A40 */ V, V, V, O, O, O, O, V, V, O, O, V, V, H, O, O, - /* 0A50 */ O, O, O, O, O, O, O, O, O, B, B, B, B, O, B, O, - /* 0A60 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, - /* 0A70 */ VM, CM, GB, GB, O, M, O, O, O, O, O, O, O, O, O, O, + /* 0A00 */ O, VMAbv, VMAbv, VMPst, O, IV, IV, IV, IV, IV, IV, O, O, O, O, IV, + /* 0A10 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0A20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 0A30 */ B, O, B, B, O, B, B, O, B, B, O, O, CMBlw, O, VPst, VPre, + /* 0A40 */ VPst, VBlw, VBlw, O, O, O, O, VAbv, VAbv, O, O, VAbv, VAbv, H, O, O, + /* 0A50 */ O, O, O, O, O, O, O, O, O, B, B, B, B, O, B, O, + /* 0A60 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0A70 */ VMAbv, CMAbv, GB, GB, O, MBlw, O, O, O, O, O, O, O, O, O, O, /* Gujarati */ - /* 0A80 */ O, VM, VM, VM, O, IV, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, - /* 0A90 */ IV, IV, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, - /* 0AA0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, - /* 0AB0 */ B, O, B, B, O, B, B, B, B, B, O, O, CM, B, V, V, - /* 0AC0 */ V, V, V, V, V, V, O, V, V, V, O, V, V, H, O, O, - /* 0AD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 0AE0 */ IV, IV, V, V, O, O, B, B, B, B, B, B, B, B, B, B, - /* 0AF0 */ O, O, O, O, O, O, O, O, O, B, O, O, O, O, O, O, + /* 0A80 */ O, VMAbv, VMAbv, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, + /* 0A90 */ IV, IV, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0AA0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 0AB0 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VPre, + /* 0AC0 */ VPst, VBlw, VBlw, VBlw, VBlw, VAbv, O, VAbv, VAbv, VAbv, O, VPst, VPst, H, O, O, + /* 0AD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 0AE0 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0AF0 */ O, O, O, O, O, O, O, O, O, B, O, O, O, O, O, O, /* Oriya */ - /* 0B00 */ O, VM, VM, VM, O, IV, IV, IV, IV, IV, IV, IV, IV, O, O, IV, - /* 0B10 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, - /* 0B20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, - /* 0B30 */ B, O, B, B, O, B, B, B, B, B, O, O, CM, B, V, V, - /* 0B40 */ V, V, V, V, V, O, O, V, V, O, O, V, V, H, O, O, - /* 0B50 */ O, O, O, O, O, O, V, V, O, O, O, O, B, B, O, B, - /* 0B60 */ IV, IV, V, V, O, O, B, B, B, B, B, B, B, B, B, B, - /* 0B70 */ O, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 0B00 */ O, VMAbv, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, O, IV, + /* 0B10 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0B20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 0B30 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VAbv, + /* 0B40 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O, + /* 0B50 */ O, O, O, O, O, O, VAbv, VAbv, O, O, O, O, B, B, O, B, + /* 0B60 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0B70 */ O, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Tamil */ - /* 0B80 */ O, O, VM, IND, O, IV, IV, IV, IV, IV, IV, O, O, O, IV, IV, - /* 0B90 */ IV, O, IV, IV, IV, B, O, O, O, B, B, O, B, O, B, B, - /* 0BA0 */ O, O, O, B, B, O, O, O, B, B, B, O, O, O, B, B, - /* 0BB0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, V, V, - /* 0BC0 */ V, V, V, O, O, O, V, V, V, O, V, V, V, H, O, O, - /* 0BD0 */ O, O, O, O, O, O, O, V, O, O, O, O, O, O, O, O, - /* 0BE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, - /* 0BF0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 0B80 */ O, O, VMAbv, IND, O, IV, IV, IV, IV, IV, IV, O, O, O, IV, IV, + /* 0B90 */ IV, O, IV, IV, IV, B, O, O, O, B, B, O, B, O, B, B, + /* 0BA0 */ O, O, O, B, B, O, O, O, B, B, B, O, O, O, B, B, + /* 0BB0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, VPst, VPst, + /* 0BC0 */ VAbv, VPst, VPst, O, O, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, O, O, + /* 0BD0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, O, + /* 0BE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0BF0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Telugu */ - /* 0C00 */ VM, VM, VM, VM, O, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, IV, - /* 0C10 */ IV, O, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, - /* 0C20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, - /* 0C30 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, V, V, - /* 0C40 */ V, V, V, V, V, O, V, V, V, O, V, V, V, H, O, O, - /* 0C50 */ O, O, O, O, O, V, V, O, B, B, B, O, O, O, O, O, - /* 0C60 */ IV, IV, V, V, O, O, B, B, B, B, B, B, B, B, B, B, - /* 0C70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 0C00 */ VMAbv, VMPst, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, IV, + /* 0C10 */ IV, O, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0C20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 0C30 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, VAbv, VAbv, + /* 0C40 */ VAbv, VPst, VPst, VPst, VPst, O, VAbv, VAbv, VAbv, O, VAbv, VAbv, VAbv, H, O, O, + /* 0C50 */ O, O, O, O, O, VAbv, VBlw, O, B, B, B, O, O, O, O, O, + /* 0C60 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0C70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Kannada */ - /* 0C80 */ O, VM, VM, VM, O, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, IV, - /* 0C90 */ IV, O, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, - /* 0CA0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, - /* 0CB0 */ B, B, B, B, O, B, B, B, B, B, O, O, CM, B, V, V, - /* 0CC0 */ V, V, V, V, V, O, V, V, V, O, V, V, V, H, O, O, - /* 0CD0 */ O, O, O, O, O, V, V, O, O, O, O, O, O, O, B, O, - /* 0CE0 */ IV, IV, V, V, O, O, B, B, B, B, B, B, B, B, B, B, - /* 0CF0 */ O, R, R, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 0C80 */ O, VMAbv, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, IV, + /* 0C90 */ IV, O, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0CA0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 0CB0 */ B, B, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VAbv, + /* 0CC0 */ VAbv, VPst, VPst, VPst, VPst, O, VAbv, VAbv, VAbv, O, VAbv, VAbv, VAbv, H, O, O, + /* 0CD0 */ O, O, O, O, O, VPst, VPst, O, O, O, O, O, O, O, B, O, + /* 0CE0 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0CF0 */ O, R, R, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Malayalam */ - /* 0D00 */ O, VM, VM, VM, O, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, IV, - /* 0D10 */ IV, O, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, - /* 0D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, O, O, B, V, V, - /* 0D40 */ V, V, V, V, V, O, V, V, V, O, V, V, V, H, R, O, - /* 0D50 */ O, O, O, O, O, O, O, V, O, O, O, O, O, O, O, IV, - /* 0D60 */ IV, IV, V, V, O, O, B, B, B, B, B, B, B, B, B, B, - /* 0D70 */ O, O, O, O, O, O, O, O, O, O, IND, IND, IND, IND, IND, IND, + /* 0D00 */ O, VMAbv, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, IV, + /* 0D10 */ IV, O, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, O, O, B, VPst, VPst, + /* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, R, O, + /* 0D50 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, IV, + /* 0D60 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0D70 */ O, O, O, O, O, O, O, O, O, O, IND, IND, IND, IND, IND, IND, /* Sinhala */ - /* 0D80 */ O, O, VM, VM, O, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, - /* 0D90 */ IV, IV, IV, IV, IV, IV, IV, O, O, O, B, B, B, B, B, B, - /* 0DA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0DB0 */ B, B, O, B, B, B, B, B, B, B, B, B, O, B, O, O, - /* 0DC0 */ B, B, B, B, B, B, B, O, O, O, H, O, O, O, O, V, - /* 0DD0 */ V, V, V, V, V, O, V, O, V, V, V, V, V, V, V, V, - /* 0DE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, - /* 0DF0 */ O, O, V, V, O, O, O, O, + /* 0D80 */ O, O, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 0D90 */ IV, IV, IV, IV, IV, IV, IV, O, O, O, B, B, B, B, B, B, + /* 0DA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 0DB0 */ B, B, O, B, B, B, B, B, B, B, B, B, O, B, O, O, + /* 0DC0 */ B, B, B, B, B, B, B, O, O, O, H, O, O, O, O, VPst, + /* 0DD0 */ VPst, VPst, VAbv, VAbv, VBlw, O, VBlw, O, VPst, VPre, VPre, VPre, VPre, VPre, VPre, VPst, + /* 0DE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0DF0 */ O, O, VPst, VPst, O, O, O, O, #define use_offset_0x1000u 1352 /* Myanmar */ - /* 1000 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1020 */ B, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, V, V, V, V, V, - /* 1030 */ V, V, V, V, V, V, VM, VM, VM, H, V, M, M, M, M, B, - /* 1040 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, GB, O, - /* 1050 */ B, B, IV, IV, IV, IV, V, V, V, V, B, B, B, B, M, M, - /* 1060 */ M, B, V, VM, VM, B, B, V, V, VM, VM, VM, VM, VM, B, B, - /* 1070 */ B, V, V, V, V, B, B, B, B, B, B, B, B, B, B, B, - /* 1080 */ B, B, M, V, V, V, V, VM, VM, VM, VM, VM, VM, VM, B, VM, - /* 1090 */ B, B, B, B, B, B, B, B, B, B, VM, VM, V, V, O, O, + /* 1000 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1020 */ B, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, VPst, VPst, VAbv, VAbv, VBlw, + /* 1030 */ VBlw, VPre, VAbv, VAbv, VAbv, VAbv, VMAbv, VMBlw, VMPst, H, VAbv, MPst, MPre, MBlw, MBlw, B, + /* 1040 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, GB, O, + /* 1050 */ B, B, IV, IV, IV, IV, VPst, VPst, VBlw, VBlw, B, B, B, B, MBlw, MBlw, + /* 1060 */ MBlw, B, VPst, VMPst, VMPst, B, B, VPst, VPst, VMPst, VMPst, VMPst, VMPst, VMPst, B, B, + /* 1070 */ B, VAbv, VAbv, VAbv, VAbv, B, B, B, B, B, B, B, B, B, B, B, + /* 1080 */ B, B, MBlw, VPst, VPre, VAbv, VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw, B, VMPst, + /* 1090 */ B, B, B, B, B, B, B, B, B, B, VMPst, VMPst, VPst, VAbv, O, O, #define use_offset_0x1700u 1512 /* Tagalog */ - /* 1700 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, O, B, B, - /* 1710 */ B, B, V, V, V, O, O, O, O, O, O, O, O, O, O, O, + /* 1700 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, O, B, B, + /* 1710 */ B, B, VAbv, VBlw, VBlw, O, O, O, O, O, O, O, O, O, O, O, /* Hanunoo */ - /* 1720 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1730 */ B, B, V, V, V, O, O, O, O, O, O, O, O, O, O, O, + /* 1720 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1730 */ B, B, VAbv, VBlw, VBlw, O, O, O, O, O, O, O, O, O, O, O, /* Buhid */ - /* 1740 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1750 */ B, B, V, V, O, O, O, O, O, O, O, O, O, O, O, O, + /* 1740 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1750 */ B, B, VAbv, VBlw, O, O, O, O, O, O, O, O, O, O, O, O, /* Tagbanwa */ - /* 1760 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, O, B, B, - /* 1770 */ B, O, V, V, O, O, O, O, O, O, O, O, O, O, O, O, + /* 1760 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, O, B, B, + /* 1770 */ B, O, VAbv, VBlw, O, O, O, O, O, O, O, O, O, O, O, O, /* Khmer */ - /* 1780 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1790 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 17A0 */ B, B, B, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, - /* 17B0 */ IV, IV, IV, IV, O, O, V, V, V, V, V, V, V, V, V, V, - /* 17C0 */ V, V, V, V, V, V, VM, VM, V, VM, VM, FM, F, CM, FM, FM, - /* 17D0 */ FM, V, H, FM, O, O, O, O, O, O, O, O, B, O, O, O, - /* 17E0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 1780 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1790 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 17A0 */ B, B, B, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 17B0 */ IV, IV, IV, IV, O, O, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPre, VPre, + /* 17C0 */ VPre, VPre, VPre, VPre, VPre, VPre, VMAbv, VMPst, VPst, VMAbv, VMAbv, FM, FAbv, CMAbv, FM, FM, + /* 17D0 */ FM, VAbv, H, FM, O, O, O, O, O, O, O, O, B, VAbv, O, O, + /* 17E0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, #define use_offset_0x1900u 1752 /* Limbu */ - /* 1900 */ GB, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, - /* 1920 */ V, V, V, V, V, V, V, V, V, SUB, SUB, SUB, O, O, O, O, - /* 1930 */ F, F, VM, F, F, F, F, F, F, F, V, FM, O, O, O, O, - /* 1940 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, + /* 1900 */ GB, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, + /* 1920 */ VAbv, VAbv, VBlw, VPst, VPst, VAbv, VAbv, VAbv, VAbv, SUB, SUB, SUB, O, O, O, O, + /* 1930 */ FPst, FPst, VMBlw, FPst, FPst, FPst, FPst, FPst, FPst, FBlw, VAbv, FM, O, O, O, O, + /* 1940 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, /* Tai Le */ - /* 1950 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1960 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, - /* 1970 */ B, B, B, B, B, O, O, O, O, O, O, O, O, O, O, O, + /* 1950 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1960 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, + /* 1970 */ B, B, B, B, B, O, O, O, O, O, O, O, O, O, O, O, /* New Tai Lue */ - /* 1980 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 19A0 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, - /* 19B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 19C0 */ B, B, B, B, B, B, B, B, VM, VM, O, O, O, O, O, O, - /* 19D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, - /* 19E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 19F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 1980 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 19A0 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, + /* 19B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 19C0 */ B, B, B, B, B, B, B, B, VMPst, VMPst, O, O, O, O, O, O, + /* 19D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 19E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 19F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Buginese */ - /* 1A00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1A10 */ B, B, B, B, B, B, B, V, V, V, V, V, O, O, O, O, + /* 1A00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1A10 */ B, B, B, B, B, B, B, VAbv, VBlw, VPre, VPst, VAbv, O, O, O, O, /* Tai Tham */ - /* 1A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1A30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1A40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, IV, IV, IV, - /* 1A50 */ IV, IV, IV, B, B, M, M, F, F, F, F, F, F, F, F, O, - /* 1A60 */ H, V, V, V, V, V, V, V, V, V, V, V, V, V, V, V, - /* 1A70 */ V, V, V, V, V, VM, VM, VM, VM, VM, FM, FM, FM, O, O, FM, - /* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, - /* 1A90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 1A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1A30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1A40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, IV, IV, IV, + /* 1A50 */ IV, IV, IV, B, B, MPre, MBlw, FPst, FAbv, FAbv, FAbv, FBlw, FBlw, FBlw, FBlw, O, + /* 1A60 */ H, VPst, VAbv, VPst, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VAbv, VBlw, VPst, VPre, VPre, + /* 1A70 */ VPre, VPre, VPre, VAbv, VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, FM, FM, FM, O, O, FM, + /* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 1A90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, #define use_offset_0x1b00u 2168 /* Balinese */ - /* 1B00 */ VM, VM, VM, F, VM, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, - /* 1B10 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1B30 */ B, B, B, B, CM, V, V, V, V, V, V, V, V, V, V, V, - /* 1B40 */ V, V, V, V, H, B, B, B, B, B, B, B, O, O, O, O, - /* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, - /* 1B60 */ O, O, O, O, O, O, O, O, O, O, O, SM, SM, SM, SM, SM, - /* 1B70 */ SM, SM, SM, SM, O, O, O, O, O, O, O, O, O, O, O, O, + /* 1B00 */ VMAbv, VMAbv, VMAbv, FAbv, VMPst, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 1B10 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre, + /* 1B40 */ VPre, VPre, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O, + /* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 1B60 */ O, O, O, O, O, O, O, O, O, O, O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv, + /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv, O, O, O, O, O, O, O, O, O, O, O, O, /* Sundanese */ - /* 1B80 */ VM, F, VM, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, - /* 1B90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BA0 */ B, SUB, SUB, SUB, V, V, V, V, V, V, V, H, SUB, SUB, B, B, - /* 1BB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1B80 */ VMAbv, FAbv, VMPst, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, + /* 1B90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1BA0 */ B, SUB, SUB, SUB, VAbv, VBlw, VPre, VPst, VAbv, VAbv, VPst, H, SUB, SUB, B, B, + /* 1BB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* Batak */ - /* 1BC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BE0 */ B, B, B, B, IV, IV, CM, V, V, V, V, V, V, V, V, V, - /* 1BF0 */ F, F, V, V, O, O, O, O, O, O, O, O, O, O, O, O, + /* 1BC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1BD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1BE0 */ B, B, B, B, IV, IV, CMAbv, VPst, VAbv, VAbv, VPst, VPst, VPst, VAbv, VPst, VAbv, + /* 1BF0 */ FAbv, FAbv, VPst, VPst, O, O, O, O, O, O, O, O, O, O, O, O, /* Lepcha */ - /* 1C00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1C20 */ B, B, B, B, SUB, SUB, V, V, V, V, V, V, V, F, F, F, - /* 1C30 */ F, F, F, F, VM, VM, FM, CM, O, O, O, O, O, O, O, O, - /* 1C40 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, B, B, + /* 1C00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1C20 */ B, B, B, B, SUB, SUB, VPst, VPre, VPre, VPre, VPst, VPst, VBlw, FAbv, FAbv, FAbv, + /* 1C30 */ FAbv, FAbv, FAbv, FAbv, VMPre, VMPre, FM, CMBlw, O, O, O, O, O, O, O, O, + /* 1C40 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, B, B, #define use_offset_0x1cd0u 2504 /* Vedic Extensions */ - /* 1CD0 */ VM, VM, VM, O, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, - /* 1CE0 */ VM, VM, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 1CF0 */ O, O, VM, VM, VM, O, O, O, VM, VM, O, O, O, O, O, O, + /* 1CD0 */ VMAbv, VMAbv, VMAbv, O, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMAbv, VMAbv, VMBlw, VMBlw, VMBlw, VMBlw, + /* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O, + /* 1CF0 */ O, O, VMPst, VMPst, VMAbv, O, O, O, VMAbv, VMAbv, O, O, O, O, O, O, #define use_offset_0x2008u 2552 /* General Punctuation */ - O, O, O, O,ZWNJ, ZWJ, O, O, - /* 2010 */ GB, GB, GB, GB, GB, O, O, O, + O, O, O, O, ZWNJ, ZWJ, O, O, + /* 2010 */ GB, GB, GB, GB, GB, O, O, O, #define use_offset_0x2070u 2568 /* Superscripts and Subscripts */ - /* 2070 */ O, O, O, O, FM, O, O, O, O, O, O, O, O, O, O, O, - /* 2080 */ O, O, FM, FM, FM, O, O, O, + /* 2070 */ O, O, O, O, FM, O, O, O, O, O, O, O, O, O, O, O, + /* 2080 */ O, O, FM, FM, FM, O, O, O, #define use_offset_0xa800u 2592 /* Syloti Nagri */ - /* A800 */ IV, IV, O, IV, IV, IV, V, B, B, B, B, VM, B, B, B, B, - /* A810 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A820 */ B, B, B, V, V, V, V, V, O, O, O, O, O, O, O, O, - /* A830 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* A800 */ IV, IV, O, IV, IV, IV, VAbv, B, B, B, B, VMAbv, B, B, B, B, + /* A810 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A820 */ B, B, B, VPst, VPst, VBlw, VAbv, VPst, O, O, O, O, O, O, O, O, + /* A830 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Phags-pa */ - /* A840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A850 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A860 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A870 */ B, B, B, B, O, O, O, O, O, O, O, O, O, O, O, O, + /* A840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A850 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A860 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A870 */ B, B, B, B, O, O, O, O, O, O, O, O, O, O, O, O, /* Saurashtra */ - /* A880 */ VM, VM, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, - /* A890 */ IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A8A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A8B0 */ B, B, B, B, F, V, V, V, V, V, V, V, V, V, V, V, - /* A8C0 */ V, V, V, V, H, O, O, O, O, O, O, O, O, O, O, O, - /* A8D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* A880 */ VMPst, VMPst, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* A890 */ IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A8A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A8B0 */ B, B, B, B, FPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, + /* A8C0 */ VPst, VPst, VPst, VPst, H, O, O, O, O, O, O, O, O, O, O, O, + /* A8D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* Devanagari Extended */ - /* A8E0 */ VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, VM, - /* A8F0 */ VM, VM, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* A8E0 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, + /* A8F0 */ VMAbv, VMAbv, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Kayah Li */ - /* A900 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A920 */ B, B, B, B, B, B, V, V, V, V, V, VM, VM, VM, O, O, + /* A900 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A920 */ B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VAbv, VMBlw, VMBlw, VMBlw, O, O, /* Rejang */ - /* A930 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A940 */ B, B, B, B, B, B, B, V, V, V, V, V, V, V, V, F, - /* A950 */ F, F, F, V, O, O, O, O, O, O, O, O, O, O, O, O, - /* A960 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* A970 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* A930 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A940 */ B, B, B, B, B, B, B, VBlw, VBlw, VBlw, VAbv, VBlw, VBlw, VBlw, VBlw, FAbv, + /* A950 */ FAbv, FAbv, FPst, VPst, O, O, O, O, O, O, O, O, O, O, O, O, + /* A960 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* A970 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Javanese */ - /* A980 */ VM, VM, F, VM, IV, IV, IV, IV, IV, B, B, B, IV, IV, IV, B, - /* A990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A9A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A9B0 */ B, B, B, CM, V, V, V, V, V, V, V, V, V, SUB, M, M, - /* A9C0 */ H, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* A9D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* A980 */ VMAbv, VMAbv, FAbv, VMPst, IV, IV, IV, IV, IV, B, B, B, IV, IV, IV, B, + /* A990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A9A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A9B0 */ B, B, B, CMAbv, VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VPre, VAbv, SUB, MPst, MPst, + /* A9C0 */ H, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* A9D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* Myanmar Extended-B */ - /* A9E0 */ B, B, B, B, B, V, O, B, B, B, B, B, B, B, B, B, - /* A9F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, + /* A9E0 */ B, B, B, B, B, VAbv, O, B, B, B, B, B, B, B, B, B, + /* A9F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, /* Cham */ - /* AA00 */ IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, - /* AA10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AA20 */ B, B, B, B, B, B, B, B, B, V, V, V, V, V, V, V, - /* AA30 */ V, V, V, M, M, M, M, O, O, O, O, O, O, O, O, O, - /* AA40 */ B, B, B, F, B, B, B, B, B, B, B, B, F, F, O, O, - /* AA50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* AA00 */ IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, + /* AA10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* AA20 */ B, B, B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VAbv, VPre, + /* AA30 */ VPre, VAbv, VBlw, MPst, MPre, MBlw, MBlw, O, O, O, O, O, O, O, O, O, + /* AA40 */ B, B, B, FAbv, B, B, B, B, B, B, B, B, FAbv, FPst, O, O, + /* AA50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* Myanmar Extended-A */ - /* AA60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AA70 */ O, B, B, B, O, O, O, O, O, O, B, VM, VM, VM, B, B, + /* AA60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* AA70 */ O, B, B, B, O, O, O, O, O, O, B, VMPst, VMAbv, VMPst, B, B, /* Tai Viet */ - /* AA80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AA90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AAA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AAB0 */ V, B, V, V, V, B, B, V, V, B, B, B, B, B, V, VM, - /* AAC0 */ B, VM, B, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* AAD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* AA80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* AA90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* AAA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* AAB0 */ VAbv, B, VAbv, VAbv, VBlw, B, B, VAbv, VAbv, B, B, B, B, B, VAbv, VMAbv, + /* AAC0 */ B, VMAbv, B, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* AAD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Meetei Mayek Extensions */ - /* AAE0 */ IV, IV, B, B, B, B, B, B, B, B, B, V, V, V, V, V, - /* AAF0 */ O, O, O, O, O, VM, H, O, + /* AAE0 */ IV, IV, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst, + /* AAF0 */ O, O, O, O, O, VMPst, H, O, #define use_offset_0xabc0u 3352 /* Meetei Mayek */ - /* ABC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, IV, IV, - /* ABD0 */ B, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* ABE0 */ B, B, B, V, V, V, V, V, V, V, V, O, VM, V, O, O, - /* ABF0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* ABC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, IV, IV, + /* ABD0 */ B, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* ABE0 */ B, B, B, VPst, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O, VMPst, VBlw, O, O, + /* ABF0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, #define use_offset_0x10a00u 3416 /* Kharoshthi */ - /* 10A00 */ B, V, V, V, O, V, V, O, O, O, O, O, V, V, VM, VM, - /* 10A10 */ B, B, B, B, O, B, B, B, O, B, B, B, B, B, B, B, - /* 10A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10A30 */ B, B, B, B, O, O, O, O, CM, CM, CM, O, O, O, O, H, - /* 10A40 */ B, B, B, B, B, B, B, B, + /* 10A00 */ B, VBlw, VBlw, VBlw, O, VAbv, VBlw, O, O, O, O, O, VBlw, VBlw, VMBlw, VMAbv, + /* 10A10 */ B, B, B, B, O, B, B, B, O, B, B, B, B, B, B, B, + /* 10A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 10A30 */ B, B, B, B, O, O, O, O, CMAbv, CMBlw, CMBlw, O, O, O, O, H, + /* 10A40 */ B, B, B, B, B, B, B, B, #define use_offset_0x11000u 3488 /* Brahmi */ - /* 11000 */ VM, VM, VM, R, R, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, - /* 11010 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11020 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11030 */ B, B, B, B, B, B, B, B, V, V, V, V, V, V, V, V, - /* 11040 */ V, V, V, V, V, V, H, O, O, O, O, O, O, O, O, O, - /* 11050 */ O, O, N, N, N, N, N, N, N, N, N, N, N, N, N, N, - /* 11060 */ N, N, N, N, N, N, B, B, B, B, B, B, B, B, B, B, - /* 11070 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11000 */ VMPst, VMAbv, VMPst, R, R, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 11010 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11020 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11030 */ B, B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, + /* 11040 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, O, O, O, O, O, O, O, O, O, + /* 11050 */ O, O, N, N, N, N, N, N, N, N, N, N, N, N, N, N, + /* 11060 */ N, N, N, N, N, N, B, B, B, B, B, B, B, B, B, B, + /* 11070 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Kaithi */ - /* 11080 */ VM, VM, VM, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, - /* 11090 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 110A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 110B0 */ V, V, V, V, V, V, V, V, V, H, CM, O, O, O, O, O, + /* 11080 */ VMAbv, VMAbv, VMPst, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, + /* 11090 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 110A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 110B0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VPst, VPst, H, CMBlw, O, O, O, O, O, #define use_offset_0x11100u 3680 /* Chakma */ - /* 11100 */ VM, VM, VM, IV, IV, IV, IV, B, B, B, B, B, B, B, B, B, - /* 11110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11120 */ B, B, B, B, B, B, B, V, V, V, V, V, V, V, V, V, - /* 11130 */ V, V, V, H, V, O, B, B, B, B, B, B, B, B, B, B, - /* 11140 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11100 */ VMAbv, VMAbv, VMAbv, IV, IV, IV, IV, B, B, B, B, B, B, B, B, B, + /* 11110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11120 */ B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VAbv, VAbv, + /* 11130 */ VAbv, VBlw, VBlw, H, VAbv, O, B, B, B, B, B, B, B, B, B, B, + /* 11140 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Mahajani */ - /* 11150 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11160 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11170 */ B, B, B, CM, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11150 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11160 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11170 */ B, B, B, CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, /* Sharada */ - /* 11180 */ VM, VM, VM, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, - /* 11190 */ IV, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 111A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 111B0 */ B, B, B, V, V, V, V, V, V, V, V, V, V, V, V, V, - /* 111C0 */ H, B, R, R, O, O, O, O, O, O, CM, V, V, O, O, O, - /* 111D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 11180 */ VMAbv, VMAbv, VMPst, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 11190 */ IV, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 111A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 111B0 */ B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, + /* 111C0 */ H, B, R, R, O, O, O, O, O, O, CMBlw, VAbv, VBlw, O, O, O, + /* 111D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* Sinhala Archaic Numbers */ - /* 111E0 */ O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 111F0 */ B, B, B, B, B, O, O, O, O, O, O, O, O, O, O, O, + /* 111E0 */ O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 111F0 */ B, B, B, B, B, O, O, O, O, O, O, O, O, O, O, O, /* Khojki */ - /* 11200 */ IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, - /* 11210 */ B, B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, V, V, V, V, - /* 11230 */ V, V, V, V, VM, H, CM, CM, + /* 11200 */ IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, + /* 11210 */ B, B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VBlw, + /* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, #define use_offset_0x11280u 3992 /* Multani */ - /* 11280 */ IV, IV, IV, IV, B, B, B, O, B, O, B, B, B, B, O, B, - /* 11290 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, B, - /* 112A0 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, + /* 11280 */ IV, IV, IV, IV, B, B, B, O, B, O, B, B, B, B, O, B, + /* 11290 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, B, + /* 112A0 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, /* Khudawadi */ - /* 112B0 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, - /* 112C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 112D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VM, - /* 112E0 */ V, V, V, V, V, V, V, V, V, CM, V, O, O, O, O, O, - /* 112F0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 112B0 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, + /* 112C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 112D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, + /* 112E0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, CMBlw, VBlw, O, O, O, O, O, + /* 112F0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* Grantha */ - /* 11300 */ VM, VM, VM, VM, O, IV, IV, IV, IV, IV, IV, IV, IV, O, O, IV, - /* 11310 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, - /* 11320 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, - /* 11330 */ B, O, B, B, O, B, B, B, B, B, O, O, CM, B, V, V, - /* 11340 */ V, V, V, V, V, O, O, V, V, O, O, V, V, H, O, O, - /* 11350 */ O, O, O, O, O, O, O, V, O, O, O, O, O, O, O, O, - /* 11360 */ IV, IV, V, V, O, O, VM, VM, VM, VM, VM, VM, VM, O, O, O, - /* 11370 */ VM, VM, VM, VM, VM, O, O, O, + /* 11300 */ VMAbv, VMAbv, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, O, IV, + /* 11310 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 11320 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 11330 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VPst, + /* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O, + /* 11350 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, O, + /* 11360 */ IV, IV, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, + /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, #define use_offset_0x11480u 4240 /* Tirhuta */ - /* 11480 */ O, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, - /* 11490 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 114A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 114B0 */ V, V, V, V, V, V, V, V, V, V, V, V, V, V, V, VM, - /* 114C0 */ VM, VM, H, CM, B, O, O, O, O, O, O, O, O, O, O, O, - /* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 11480 */ O, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, + /* 11490 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 114A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 114B0 */ VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VPre, VAbv, VPre, VPre, VPst, VPre, VMAbv, + /* 114C0 */ VMAbv, VMPst, H, CMBlw, B, O, O, O, O, O, O, O, O, O, O, O, + /* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, #define use_offset_0x11580u 4336 /* Siddham */ - /* 11580 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, - /* 11590 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 115A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, V, - /* 115B0 */ V, V, V, V, V, V, O, O, V, V, V, V, VM, VM, VM, H, - /* 115C0 */ CM, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 115D0 */ O, O, O, O, O, O, O, O, IV, IV, IV, IV, V, V, O, O, - /* 115E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 115F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11580 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, + /* 11590 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 115A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VPst, + /* 115B0 */ VPre, VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, VPre, VPre, VMAbv, VMAbv, VMPst, H, + /* 115C0 */ CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 115D0 */ O, O, O, O, O, O, O, O, IV, IV, IV, IV, VBlw, VBlw, O, O, + /* 115E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 115F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Modi */ - /* 11600 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, - /* 11610 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11620 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11630 */ V, V, V, V, V, V, V, V, V, V, V, V, V, VM, VM, H, - /* 11640 */ V, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 11650 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, - /* 11660 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 11670 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11600 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, + /* 11610 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11620 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11630 */ VPst, VPst, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPst, VPst, VMAbv, VMPst, H, + /* 11640 */ VAbv, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11650 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 11660 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11670 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Takri */ - /* 11680 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, - /* 11690 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 116A0 */ B, B, B, B, B, B, B, B, B, B, B, VM, VM, V, V, V, - /* 116B0 */ V, V, V, V, V, V, H, CM, O, O, O, O, O, O, O, O, - /* 116C0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, - /* 116D0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 116E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 116F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11680 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, + /* 11690 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 116A0 */ B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMPst, VAbv, VPre, VPst, + /* 116B0 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, CMBlw, O, O, O, O, O, O, O, O, + /* 116C0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 116D0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 116E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 116F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Ahom */ - /* 11700 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11710 */ B, B, B, B, B, B, B, B, B, B, O, O, O, M, M, M, - /* 11720 */ V, V, V, V, V, V, V, V, V, V, V, V, O, O, O, O, - /* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, + /* 11700 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11710 */ B, B, B, B, B, B, B, B, B, B, O, O, O, MBlw, MPre, MAbv, + /* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VAbv, O, O, O, O, + /* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, }; /* Table items: 4784; occupancy: 72% */ +#undef B +#undef CGJ +#undef FM +#undef GB +#undef H +#undef HN +#undef IND +#undef IV +#undef N +#undef O +#undef R +#undef Rsv +#undef S +#undef SUB +#undef VS +#undef WJ +#undef ZWJ +#undef ZWNJ +#undef CMBlw +#undef CMAbv +#undef FBlw +#undef FPst +#undef FAbv +#undef MPre +#undef MBlw +#undef MPst +#undef MAbv +#undef SMBlw +#undef SMAbv +#undef VPre +#undef VBlw +#undef VPst +#undef VAbv +#undef VMPre +#undef VMBlw +#undef VMPst +#undef VMAbv + USE_TABLE_ELEMENT_TYPE hb_use_get_categories (hb_codepoint_t u) { @@ -602,7 +653,7 @@ hb_use_get_categories (hb_codepoint_t u) case 0x2u: if (hb_in_range (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u]; if (hb_in_range (u, 0x2070u, 0x2087u)) return use_table[u - 0x2070u + use_offset_0x2070u]; - if (unlikely (u == 0x25CCu)) return GB; + if (unlikely (u == 0x25CCu)) return USE_GB; break; case 0xAu: @@ -620,38 +671,13 @@ hb_use_get_categories (hb_codepoint_t u) if (hb_in_range (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u]; if (hb_in_range (u, 0x11480u, 0x114DFu)) return use_table[u - 0x11480u + use_offset_0x11480u]; if (hb_in_range (u, 0x11580u, 0x1173Fu)) return use_table[u - 0x11580u + use_offset_0x11580u]; - if (unlikely (u == 0x1107Fu)) return HN; + if (unlikely (u == 0x1107Fu)) return USE_HN; break; default: break; } - return _(x,x); + return USE_O; } -#undef B -#undef CGJ -#undef CM -#undef F -#undef FM -#undef GB -#undef H -#undef HN -#undef IND -#undef IV -#undef M -#undef N -#undef O -#undef R -#undef Rsv -#undef S -#undef SM -#undef SUB -#undef V -#undef VM -#undef VS -#undef WJ -#undef ZWJ -#undef ZWNJ - /* == End of generated table == */ From b4c0829bc18b696f140a260fa2e1089d10164519 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 09:31:19 +0100 Subject: [PATCH 12/43] [USE] Remove unused Unicode data enums from USE C++ side --- src/hb-ot-shape-complex-use-private.hh | 66 +------------------------- src/hb-ot-shape-complex-use.cc | 14 +----- 2 files changed, 3 insertions(+), 77 deletions(-) diff --git a/src/hb-ot-shape-complex-use-private.hh b/src/hb-ot-shape-complex-use-private.hh index 835dbaf75..fc0cfc50b 100644 --- a/src/hb-ot-shape-complex-use-private.hh +++ b/src/hb-ot-shape-complex-use-private.hh @@ -35,7 +35,7 @@ #include "hb-ot-shape-complex-private.hh" -#define USE_TABLE_ELEMENT_TYPE uint16_t +#define USE_TABLE_ELEMENT_TYPE uint8_t /* Cateories used in the Universal Shaping Engine spec: * https://www.microsoft.com/typography/OpenTypeDev/USE/intro.htm @@ -90,70 +90,6 @@ enum use_category_t { USE_SMBlw = 42 /* SYM_MOD_BELOW */ }; -/* Categories used in IndicSyllabicCategory.txt from UCD. */ -enum indic_syllabic_category_t -{ - INDIC_SYLLABIC_CATEGORY_AVAGRAHA, - INDIC_SYLLABIC_CATEGORY_BINDU, - INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER, - INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK, - INDIC_SYLLABIC_CATEGORY_CONSONANT, - INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD, - INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL, - INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER, - INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER, - INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL, - INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER, - INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA, - INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED, - INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED, - INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA, - INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER, - INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK, - INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER, - INDIC_SYLLABIC_CATEGORY_JOINER, - INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER, - INDIC_SYLLABIC_CATEGORY_NON_JOINER, - INDIC_SYLLABIC_CATEGORY_NUKTA, - INDIC_SYLLABIC_CATEGORY_NUMBER, - INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER, - INDIC_SYLLABIC_CATEGORY_OTHER, - INDIC_SYLLABIC_CATEGORY_PURE_KILLER, - INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER, - INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER, - INDIC_SYLLABIC_CATEGORY_TONE_LETTER, - INDIC_SYLLABIC_CATEGORY_TONE_MARK, - INDIC_SYLLABIC_CATEGORY_VIRAMA, - INDIC_SYLLABIC_CATEGORY_VISARGA, - INDIC_SYLLABIC_CATEGORY_VOWEL, - INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT, - INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT, -}; - -/* Categories used in IndicPositionalCategory.txt from UCD */ -enum indic_positional_category_t { - INDIC_POSITIONAL_CATEGORY_BOTTOM, - INDIC_POSITIONAL_CATEGORY_BOTTOM_AND_RIGHT, - INDIC_POSITIONAL_CATEGORY_LEFT, - INDIC_POSITIONAL_CATEGORY_LEFT_AND_RIGHT, - INDIC_POSITIONAL_CATEGORY_NOT_APPLICABLE, - INDIC_POSITIONAL_CATEGORY_OVERSTRUCK, - INDIC_POSITIONAL_CATEGORY_RIGHT, - INDIC_POSITIONAL_CATEGORY_TOP, - INDIC_POSITIONAL_CATEGORY_TOP_AND_BOTTOM, - INDIC_POSITIONAL_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT, - INDIC_POSITIONAL_CATEGORY_TOP_AND_LEFT, - INDIC_POSITIONAL_CATEGORY_TOP_AND_LEFT_AND_RIGHT, - INDIC_POSITIONAL_CATEGORY_TOP_AND_RIGHT, - INDIC_POSITIONAL_CATEGORY_VISUAL_ORDER_LEFT, -}; - -/* 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. */ -#define USE_COMBINE_CATEGORIES(S,P) \ - (ASSERT_STATIC_EXPR_ZERO (S < 255 && P < 255) + \ - ((P << 8) | S)) - HB_INTERNAL USE_TABLE_ELEMENT_TYPE hb_use_get_categories (hb_codepoint_t u); diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index d8ce4517f..b019755f6 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -120,17 +120,7 @@ static inline void set_use_properties (hb_glyph_info_t &info) { hb_codepoint_t u = info.codepoint; - unsigned int type = hb_use_get_categories (u); - indic_syllabic_category_t cat = (indic_syllabic_category_t) (type & 0x7Fu); - indic_positional_category_t pos = (indic_positional_category_t) (type >> 8); - use_category_t use = USE_O; - - switch (cat) - { - /* TODO */ - } - - info.use_category() = use; + info.use_category() = hb_use_get_categories (u); } @@ -147,7 +137,7 @@ setup_masks_use (const hb_ot_shape_plan_t *plan HB_UNUSED, unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) - set_use_properties (info[i]); + info[i].use_category() = hb_use_get_categories (info[i].codepoint); } static void From 52a957795697085a5d379921ddd8aa6cf2f1a99d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 10:02:04 +0100 Subject: [PATCH 13/43] [USE] Hook up new scripts to USE shaper Don't reroute scripts that we were routing to other shapers before (just yet). --- src/hb-ot-shape-complex-private.hh | 71 ++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh index 4dc4f58d7..702e9522e 100644 --- a/src/hb-ot-shape-complex-private.hh +++ b/src/hb-ot-shape-complex-private.hh @@ -62,6 +62,7 @@ enum hb_ot_shape_zero_width_marks_type_t { HB_COMPLEX_SHAPER_IMPLEMENT (sea) \ HB_COMPLEX_SHAPER_IMPLEMENT (thai) \ HB_COMPLEX_SHAPER_IMPLEMENT (tibetan) \ + HB_COMPLEX_SHAPER_IMPLEMENT (use) \ /* ^--- Add new shapers here */ @@ -358,6 +359,76 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) return &_hb_ot_complex_shaper_default; else return &_hb_ot_complex_shaper_sea; + + + /* Unicode-2.0 additions */ + //case HB_SCRIPT_TIBETAN: + + /* Unicode-3.0 additions */ + //case HB_SCRIPT_MONGOLIAN: + //case HB_SCRIPT_SINHALA: + + /* Unicode-3.2 additions */ + case HB_SCRIPT_BUHID: + case HB_SCRIPT_HANUNOO: + case HB_SCRIPT_TAGALOG: + case HB_SCRIPT_TAGBANWA: + + /* Unicode-4.0 additions */ + case HB_SCRIPT_LIMBU: + case HB_SCRIPT_TAI_LE: + + /* Unicode-4.1 additions */ + //case HB_SCRIPT_BUGINESE: + case HB_SCRIPT_KHAROSHTHI: + case HB_SCRIPT_SYLOTI_NAGRI: + case HB_SCRIPT_TIFINAGH: + + /* Unicode-5.0 additions */ + //case HB_SCRIPT_BALINESE: + //case HB_SCRIPT_NKO: + //case HB_SCRIPT_PHAGS_PA: + + /* Unicode-5.1 additions */ + //case HB_SCRIPT_CHAM: + case HB_SCRIPT_KAYAH_LI: + //case HB_SCRIPT_LEPCHA: + //case HB_SCRIPT_REJANG: + case HB_SCRIPT_SAURASHTRA: + //case HB_SCRIPT_SUNDANESE: + + /* Unicode-5.2 additions */ + case HB_SCRIPT_EGYPTIAN_HIEROGLYPHS: + //case HB_SCRIPT_JAVANESE: + //case HB_SCRIPT_KAITHI: + //case HB_SCRIPT_MEETEI_MAYEK: + //case HB_SCRIPT_TAI_THAM: + //case HB_SCRIPT_TAI_VIET: + + /* Unicode-6.0 additions */ + //case HB_SCRIPT_BATAK: + case HB_SCRIPT_BRAHMI: + //case HB_SCRIPT_MANDAIC: + + /* Unicode-6.1 additions */ + //case HB_SCRIPT_CHAKMA: + //case HB_SCRIPT_SHARADA: + //case HB_SCRIPT_TAKRI: + + /* Unicode-7.0 additions */ + case HB_SCRIPT_DUPLOYAN: + case HB_SCRIPT_GRANTHA: + case HB_SCRIPT_KHOJKI: + case HB_SCRIPT_KHUDAWADI: + case HB_SCRIPT_MAHAJANI: + //case HB_SCRIPT_MANICHAEAN: + case HB_SCRIPT_MODI: + case HB_SCRIPT_PAHAWH_HMONG: + //case HB_SCRIPT_PSALTER_PAHLAVI: + case HB_SCRIPT_SIDDHAM: + case HB_SCRIPT_TIRHUTA: + + return &_hb_ot_complex_shaper_use; } } From 4febed61edc5367543e5a206ae01d3393841b612 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 10:24:32 +0100 Subject: [PATCH 14/43] [USE] Set up features --- src/hb-ot-shape-complex-use.cc | 68 +++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index b019755f6..152541b8d 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -42,26 +42,32 @@ basic_features[] = { /* * Basic features. - * These features are applied in order, one at a time, after initial_reordering. + * These features are applied all at once, before reordering. */ - HB_TAG('p','r','e','f'), + HB_TAG('r','k','r','f'), HB_TAG('a','b','v','f'), HB_TAG('b','l','w','f'), + HB_TAG('h','a','l','f'), HB_TAG('p','s','t','f'), + HB_TAG('v','a','t','u'), + HB_TAG('c','j','c','t'), }; static const hb_tag_t other_features[] = { /* * Other features. - * These features are applied all at once, after final_reordering. + * These features are applied all at once, after reordering. */ - HB_TAG('p','r','e','s'), HB_TAG('a','b','v','s'), HB_TAG('b','l','w','s'), + HB_TAG('h','a','l','n'), + HB_TAG('p','r','e','s'), HB_TAG('p','s','t','s'), /* Positioning features, though we don't care about the types. */ HB_TAG('d','i','s','t'), + HB_TAG('a','b','v','m'), + HB_TAG('b','l','w','m'), }; static void @@ -69,9 +75,9 @@ setup_syllables (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); static void -reordering (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer); +reorder (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); static void collect_features_use (hb_ot_shape_planner_t *plan) @@ -81,27 +87,33 @@ collect_features_use (hb_ot_shape_planner_t *plan) /* Do this before any lookups have been applied. */ map->add_gsub_pause (setup_syllables); + /* "Default glyph pre-processing group" */ map->add_global_bool_feature (HB_TAG('l','o','c','l')); - /* The Indic specs do not require ccmp, but we apply it here since if - * there is a use of it, it's typically at the beginning. */ map->add_global_bool_feature (HB_TAG('c','c','m','p')); + map->add_global_bool_feature (HB_TAG('n','u','k','t')); + map->add_global_bool_feature (HB_TAG('a','k','h','n')); + /* "Reordering group" */ + map->add_gsub_pause (NULL); + map->add_feature (HB_TAG('r','p','h','f'), 1, F_GLOBAL | F_MANUAL_ZWJ); + map->add_gsub_pause (NULL); + map->add_feature (HB_TAG('p','r','e','f'), 1, F_GLOBAL | F_MANUAL_ZWJ); + map->add_gsub_pause (NULL); + + /* "Orthographic unit shaping group" */ for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++) - { map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); - map->add_gsub_pause (NULL); - } - map->add_gsub_pause (reordering); + + map->add_gsub_pause (reorder); + + /* "Topographical features" */ + // TODO isol/init/medi/fina + + /* "Standard typographic presentation" and "Positional feature application" */ for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++) map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); } -static void -override_features_use (hb_ot_shape_planner_t *plan) -{ - plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL); -} - enum syllable_type_t { independent_cluster, @@ -248,14 +260,10 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, return; - hb_codepoint_t dottedcircle_glyph; - if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph)) - return; - hb_glyph_info_t dottedcircle = {0}; - dottedcircle.codepoint = 0x25CCu; - set_use_properties (dottedcircle); - dottedcircle.codepoint = dottedcircle_glyph; + if (!font->get_glyph (0x25CCu, 0, &dottedcircle.codepoint)) + return; + dottedcircle.use_category() = hb_use_get_categories (0x25CC); buffer->clear_output (); @@ -285,9 +293,9 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, } static void -reordering (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer) +reorder (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) { insert_dotted_circles (plan, font, buffer); @@ -316,7 +324,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use = { "use", collect_features_use, - override_features_use, + NULL, /* override_features */ NULL, /* data_create */ NULL, /* data_destroy */ NULL, /* preprocess_text */ From ba72801325e4bd58f7597938d4409762c9fa530c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 11:57:23 +0100 Subject: [PATCH 15/43] [USE] Add CGJ to table --- src/gen-use-table.py | 13 ++++++++++--- src/hb-ot-shape-complex-use-table.cc | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/gen-use-table.py b/src/gen-use-table.py index 7293b73cd..82108750d 100755 --- a/src/gen-use-table.py +++ b/src/gen-use-table.py @@ -39,8 +39,12 @@ for i, f in enumerate (files): data[i][u] = t values[i][t] = values[i].get (t, 0) + end - start + 1 -# Merge data into one dict: defaults = ('Other', 'Not_Applicable', 'Cn', 'No_Block') + +# TODO CGJ is not in Unicode Indic files, but used in USE +data[0][0x034F] = defaults[0] + +# Merge data into one dict: for i,v in enumerate (defaults): values[i][v] = values[i].get (v, 0) + 1 combined = {} @@ -180,7 +184,10 @@ def is_Word_Joiner(U, UISC, UGC): return U == 0x2060 def is_OTHER(U, UISC, UGC): #SPEC-OUTDATED return UGC == Zs # or any other SCRIPT_COMMON characters - return UISC == Other and not is_SYM_MOD(U, UISC, UGC) + return (UISC == Other + and not is_SYM_MOD(U, UISC, UGC) + and not is_CGJ(U, UISC, UGC) + ) def is_Reserved(U, UISC, UGC): return UGC == 'Cn' def is_REPHA(U, UISC, UGC): @@ -325,7 +332,7 @@ data = map_to_use(data) # Remove the outliers singles = {} -for u in [0x25CC, 0x1107F]: +for u in [0x034F, 0x25CC, 0x1107F]: singles[u] = data[u] del data[u] diff --git a/src/hb-ot-shape-complex-use-table.cc b/src/hb-ot-shape-complex-use-table.cc index 4ce9010b2..45c7976ae 100644 --- a/src/hb-ot-shape-complex-use-table.cc +++ b/src/hb-ot-shape-complex-use-table.cc @@ -640,6 +640,7 @@ hb_use_get_categories (hb_codepoint_t u) if (hb_in_range (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u]; if (hb_in_range (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u]; if (hb_in_range (u, 0x0900u, 0x0DF7u)) return use_table[u - 0x0900u + use_offset_0x0900u]; + if (unlikely (u == 0x034Fu)) return USE_CGJ; break; case 0x1u: From 595936ec25e9c0924851bd1aa1af5eed3723b54f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 14:15:35 +0100 Subject: [PATCH 16/43] [USE] Hook of rphf and pref custom processing Still no reordering. --- src/hb-ot-layout-private.hh | 8 ++ src/hb-ot-shape-complex-use.cc | 181 +++++++++++++++++++++++++++++++-- 2 files changed, 181 insertions(+), 8 deletions(-) diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index 47fecd216..7a8e2bf30 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -406,6 +406,14 @@ _hb_glyph_info_clear_ligated_and_multiplied (hb_glyph_info_t *info) HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED); } +static inline void +_hb_glyph_info_clear_substituted_and_ligated_and_multiplied (hb_glyph_info_t *info) +{ + info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED | + HB_OT_LAYOUT_GLYPH_PROPS_LIGATED | + HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED); +} + /* Allocation / deallocation. */ diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index 152541b8d..2cf84103e 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -75,6 +75,18 @@ setup_syllables (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); static void +clear_substitution_flags (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); +static void +record_rphf (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); +static void +record_pref (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); +static void reorder (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); @@ -94,11 +106,11 @@ collect_features_use (hb_ot_shape_planner_t *plan) map->add_global_bool_feature (HB_TAG('a','k','h','n')); /* "Reordering group" */ - map->add_gsub_pause (NULL); - map->add_feature (HB_TAG('r','p','h','f'), 1, F_GLOBAL | F_MANUAL_ZWJ); - map->add_gsub_pause (NULL); - map->add_feature (HB_TAG('p','r','e','f'), 1, F_GLOBAL | F_MANUAL_ZWJ); - map->add_gsub_pause (NULL); + map->add_gsub_pause (clear_substitution_flags); + map->add_feature (HB_TAG('r','p','h','f'), 1, F_MANUAL_ZWJ); + map->add_gsub_pause (record_rphf); + map->add_feature (HB_TAG('p','r','e','f'), 1, F_MANUAL_ZWJ); + map->add_gsub_pause (record_pref); /* "Orthographic unit shaping group" */ for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++) @@ -114,6 +126,32 @@ collect_features_use (hb_ot_shape_planner_t *plan) map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); } +struct use_shape_plan_t +{ + ASSERT_POD (); + + hb_mask_t rphf_mask; + hb_mask_t pref_mask; +}; + +static void * +data_create_use (const hb_ot_shape_plan_t *plan) +{ + use_shape_plan_t *use_plan = (use_shape_plan_t *) calloc (1, sizeof (use_shape_plan_t)); + if (unlikely (!use_plan)) + return NULL; + + use_plan->rphf_mask = plan->map.get_1_mask (HB_TAG('r','p','h','f')); + use_plan->pref_mask = plan->map.get_1_mask (HB_TAG('p','r','e','f')); + + return use_plan; +} + +static void +data_destroy_use (void *data) +{ + free (data); +} enum syllable_type_t { independent_cluster, @@ -153,13 +191,140 @@ setup_masks_use (const hb_ot_shape_plan_t *plan HB_UNUSED, } static void -setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, +setup_syllable (const use_shape_plan_t *use_plan, + hb_glyph_info_t *info, + unsigned int start, unsigned int end) +{ + unsigned int limit = info[start].use_category() == USE_R ? 1 : MIN (3u, end - start); + for (unsigned int i = start; i < start + limit; i++) + info[i].mask |= use_plan->rphf_mask | use_plan->pref_mask; + for (unsigned int i = start + limit; i < end; i++) + info[i].mask |= use_plan->pref_mask; +} + +static void +setup_syllables (const hb_ot_shape_plan_t *plan, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { find_syllables (buffer); + + /* Setup masks for 'rphf' and 'pref'. */ + const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; + if (!(use_plan->rphf_mask | use_plan->pref_mask)) return; + + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + if (unlikely (!count)) return; + unsigned int last = 0; + unsigned int last_syllable = info[0].syllable(); + for (unsigned int i = 1; i < count; i++) + if (last_syllable != info[i].syllable()) { + setup_syllable (use_plan, info, last, i); + last = i; + last_syllable = info[last].syllable(); + } + setup_syllable (use_plan, info, last, count); } +static void +clear_substitution_flags (const hb_ot_shape_plan_t *plan, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) +{ + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + for (unsigned int i = 0; i < count; i++) + _hb_glyph_info_clear_substituted_and_ligated_and_multiplied (&info[i]); +} + +static void +record_rphf_syllable (hb_glyph_info_t *info, + unsigned int start, unsigned int end, + hb_mask_t mask) +{ + unsigned int i = start; + + if (info[i].use_category() != USE_R) + for (; i < end && !_hb_glyph_info_substituted (&info[i]); i++) + info[i].mask &= ~mask; + + if (i == end) + return; + + /* Found the one. Don't clear its mask. */ + i++; + + /* Clear the mask on the rest. */ + for (; i < end; i++) + info[i].mask &= ~mask; +} + +static void +record_rphf (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; + hb_mask_t mask = use_plan->rphf_mask; + + if (!mask) return; + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + if (unlikely (!count)) return; + unsigned int last = 0; + unsigned int last_syllable = info[0].syllable(); + for (unsigned int i = 1; i < count; i++) + if (last_syllable != info[i].syllable()) { + record_rphf_syllable (info, last, i, mask); + last = i; + last_syllable = info[last].syllable(); + } + record_rphf_syllable (info, last, count, mask); +} + +static void +record_pref_syllable (hb_glyph_info_t *info, + unsigned int start, unsigned int end, + hb_mask_t mask) +{ + unsigned int i = start; + for (; i < end && !_hb_glyph_info_substituted (&info[i]); i++) + info[i].mask &= ~mask; + + if (i == end) + return; + + /* Found the one. Don't clear its mask. */ + i++; + + /* Clear the mask on the rest. */ + for (; i < end; i++) + info[i].mask &= ~mask; +} + +static void +record_pref (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; + hb_mask_t mask = use_plan->pref_mask; + + if (!mask) return; + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + if (unlikely (!count)) return; + unsigned int last = 0; + unsigned int last_syllable = info[0].syllable(); + for (unsigned int i = 1; i < count; i++) + if (last_syllable != info[i].syllable()) { + record_pref_syllable (info, last, i, mask); + last = i; + last_syllable = info[last].syllable(); + } + record_pref_syllable (info, last, count, mask); +} static void reorder_virama_terminated_cluster (const hb_ot_shape_plan_t *plan, @@ -325,8 +490,8 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use = "use", collect_features_use, NULL, /* override_features */ - NULL, /* data_create */ - NULL, /* data_destroy */ + data_create_use, + data_destroy_use, NULL, /* preprocess_text */ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, NULL, /* decompose */ From cf59c7589c2b4064f4b9f4936115f830089a8ee7 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 14:51:45 +0100 Subject: [PATCH 17/43] [USE] Use use_category() for rphf/pref memory --- src/hb-ot-shape-complex-use.cc | 63 ++++++++++++---------------------- 1 file changed, 22 insertions(+), 41 deletions(-) diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index 2cf84103e..04adaa491 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -109,7 +109,7 @@ collect_features_use (hb_ot_shape_planner_t *plan) map->add_gsub_pause (clear_substitution_flags); map->add_feature (HB_TAG('r','p','h','f'), 1, F_MANUAL_ZWJ); map->add_gsub_pause (record_rphf); - map->add_feature (HB_TAG('p','r','e','f'), 1, F_MANUAL_ZWJ); + map->add_feature (HB_TAG('p','r','e','f'), 1, F_GLOBAL | F_MANUAL_ZWJ); map->add_gsub_pause (record_pref); /* "Orthographic unit shaping group" */ @@ -131,7 +131,6 @@ struct use_shape_plan_t ASSERT_POD (); hb_mask_t rphf_mask; - hb_mask_t pref_mask; }; static void * @@ -142,7 +141,6 @@ data_create_use (const hb_ot_shape_plan_t *plan) return NULL; use_plan->rphf_mask = plan->map.get_1_mask (HB_TAG('r','p','h','f')); - use_plan->pref_mask = plan->map.get_1_mask (HB_TAG('p','r','e','f')); return use_plan; } @@ -197,9 +195,7 @@ setup_syllable (const use_shape_plan_t *use_plan, { unsigned int limit = info[start].use_category() == USE_R ? 1 : MIN (3u, end - start); for (unsigned int i = start; i < start + limit; i++) - info[i].mask |= use_plan->rphf_mask | use_plan->pref_mask; - for (unsigned int i = start + limit; i < end; i++) - info[i].mask |= use_plan->pref_mask; + info[i].mask |= use_plan->rphf_mask; } static void @@ -211,7 +207,7 @@ setup_syllables (const hb_ot_shape_plan_t *plan, /* Setup masks for 'rphf' and 'pref'. */ const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; - if (!(use_plan->rphf_mask | use_plan->pref_mask)) return; + if (!use_plan->rphf_mask) return; hb_glyph_info_t *info = buffer->info; unsigned int count = buffer->len; @@ -243,21 +239,14 @@ record_rphf_syllable (hb_glyph_info_t *info, unsigned int start, unsigned int end, hb_mask_t mask) { - unsigned int i = start; - - if (info[i].use_category() != USE_R) - for (; i < end && !_hb_glyph_info_substituted (&info[i]); i++) - info[i].mask &= ~mask; - - if (i == end) - return; - - /* Found the one. Don't clear its mask. */ - i++; - - /* Clear the mask on the rest. */ - for (; i < end; i++) - info[i].mask &= ~mask; + /* Mark a substituted repha as USE_R. */ + for (unsigned int i = start; i < end && (info[i].mask & mask); i++) + if (_hb_glyph_info_substituted (&info[i])) + { + /* Found the one. Mark it as Repha. */ + info[i].use_category() = USE_R; + return; + } } static void @@ -285,22 +274,16 @@ record_rphf (const hb_ot_shape_plan_t *plan, static void record_pref_syllable (hb_glyph_info_t *info, - unsigned int start, unsigned int end, - hb_mask_t mask) + unsigned int start, unsigned int end) { - unsigned int i = start; - for (; i < end && !_hb_glyph_info_substituted (&info[i]); i++) - info[i].mask &= ~mask; - - if (i == end) - return; - - /* Found the one. Don't clear its mask. */ - i++; - - /* Clear the mask on the rest. */ - for (; i < end; i++) - info[i].mask &= ~mask; + /* Mark a substituted pref as VPre, as they behave the same way. */ + for (unsigned int i = start; i < end; i++) + if (_hb_glyph_info_substituted (&info[i])) + { + /* Found the one. Mark it as Repha. */ + info[i].use_category() = USE_VPre; + return; + } } static void @@ -309,9 +292,7 @@ record_pref (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer) { const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; - hb_mask_t mask = use_plan->pref_mask; - if (!mask) return; hb_glyph_info_t *info = buffer->info; unsigned int count = buffer->len; if (unlikely (!count)) return; @@ -319,11 +300,11 @@ record_pref (const hb_ot_shape_plan_t *plan, unsigned int last_syllable = info[0].syllable(); for (unsigned int i = 1; i < count; i++) if (last_syllable != info[i].syllable()) { - record_pref_syllable (info, last, i, mask); + record_pref_syllable (info, last, i); last = i; last_syllable = info[last].syllable(); } - record_pref_syllable (info, last, count, mask); + record_pref_syllable (info, last, count); } static void From 1025e1a9e7785ac67cc90d05b02862e38b3e6026 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 15:05:35 +0100 Subject: [PATCH 18/43] Use unsigned in FLAG() --- src/hb-private.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-private.hh b/src/hb-private.hh index 45afc20b1..0ec0fe72c 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -847,7 +847,7 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) * For example, for testing "x ∈ {x1, x2, x3}" use: * (FLAG(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) */ -#define FLAG(x) (1<<(x)) +#define FLAG(x) (1U<<(x)) #define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x)) From d6adca9fbbbd6fc7c8906121b50c3930fbe2de8e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 15:17:27 +0100 Subject: [PATCH 19/43] Remove unused macro ASSERT_STATIC_EXPR() --- src/hb-ot-shape-complex-arabic-win1256.hh | 4 ++-- src/hb-ot-shape-complex-indic-private.hh | 2 -- src/hb-private.hh | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/hb-ot-shape-complex-arabic-win1256.hh b/src/hb-ot-shape-complex-arabic-win1256.hh index 8edd3ba80..e70c48f42 100644 --- a/src/hb-ot-shape-complex-arabic-win1256.hh +++ b/src/hb-ot-shape-complex-arabic-win1256.hh @@ -142,7 +142,7 @@ OT_UARRAY(Name##Substitute, OT_LIST(ToGlyphs)) \ ) \ OT_COVERAGE1(Name##Coverage, OT_LIST(FromGlyphs)) \ - /* ASSERT_STATIC_EXPR len(FromGlyphs) == len(ToGlyphs) */ + /* ASSERT_STATIC_EXPR_ZERO (len(FromGlyphs) == len(ToGlyphs)) */ #define OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(Name, FirstGlyphs, LigatureSetOffsets) \ OT_SUBLOOKUP(Name, 1, \ @@ -151,7 +151,7 @@ OT_UARRAY(Name##LigatureSetOffsetsArray, OT_LIST(LigatureSetOffsets)) \ ) \ OT_COVERAGE1(Name##Coverage, OT_LIST(FirstGlyphs)) \ - /* ASSERT_STATIC_EXPR len(FirstGlyphs) == len(LigatureSetOffsets) */ + /* ASSERT_STATIC_EXPR_ZERO (len(FirstGlyphs) == len(LigatureSetOffsets)) */ #define OT_LIGATURE_SET(Name, LigatureSetOffsets) \ OT_UARRAY(Name, OT_LIST(LigatureSetOffsets)) diff --git a/src/hb-ot-shape-complex-indic-private.hh b/src/hb-ot-shape-complex-indic-private.hh index d8dfc6507..559ebe498 100644 --- a/src/hb-ot-shape-complex-indic-private.hh +++ b/src/hb-ot-shape-complex-indic-private.hh @@ -161,8 +161,6 @@ enum indic_matra_category_t { 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 - * because gcc fails to optimize the latter and fills the table in at runtime. */ #define INDIC_COMBINE_CATEGORIES(S,M) \ (ASSERT_STATIC_EXPR_ZERO (M == INDIC_MATRA_CATEGORY_NOT_APPLICABLE || \ ( \ diff --git a/src/hb-private.hh b/src/hb-private.hh index 0ec0fe72c..475f72fb9 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -193,7 +193,6 @@ static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; } #define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond)) #define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond)) -#define ASSERT_STATIC_EXPR(_cond)((void) sizeof (char[(_cond) ? 1 : -1])) #define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * sizeof (char[(_cond) ? 1 : -1])) #define _PASTE1(a,b) a##b From 366aeaad006b230481a3c08ab4d239fb6b64fef8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 15:45:48 +0100 Subject: [PATCH 20/43] Add note re ASSERT_STATIC_EXPR_ZERO() --- src/hb-private.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-private.hh b/src/hb-private.hh index 475f72fb9..e941126aa 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -193,6 +193,8 @@ static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; } #define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond)) #define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond)) +/* Note: C++ allows sizeof() of variable-lengh arrays. So, if _cond is not + * constant, it still compiles (ouch!), but at least we'll get a -Wvla warning. */ #define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * sizeof (char[(_cond) ? 1 : -1])) #define _PASTE1(a,b) a##b From f8160a495966c790b79134a9f9382b6545f8c733 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 15:50:02 +0100 Subject: [PATCH 21/43] Add FLAG_SAFE() for values known to be small-enough And add check to FLAG() --- src/hb-ot-shape-complex-arabic.cc | 2 +- src/hb-ot-shape-complex-indic.cc | 12 ++++++------ src/hb-ot-shape-complex-myanmar.cc | 2 +- src/hb-private.hh | 5 +++-- src/hb-unicode-private.hh | 2 +- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc index ae9086412..fc8258111 100644 --- a/src/hb-ot-shape-complex-arabic.cc +++ b/src/hb-ot-shape-complex-arabic.cc @@ -61,7 +61,7 @@ static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_categ if (likely (j_type != JOINING_TYPE_X)) return j_type; - return (FLAG(gen_cat) & + return (FLAG_SAFE(gen_cat) & (FLAG(HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEGORY_FORMAT)) diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index 772360041..1dc84be2e 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -142,7 +142,7 @@ is_one_of (const hb_glyph_info_t &info, unsigned int flags) { /* If it ligated, all bets are off. */ if (_hb_glyph_info_ligated (&info)) return false; - return !!(FLAG (info.indic_category()) & flags); + return !!(FLAG_SAFE (info.indic_category()) & flags); } static inline bool @@ -237,7 +237,7 @@ set_indic_properties (hb_glyph_info_t &info) * Re-assign position. */ - if ((FLAG (cat) & CONSONANT_FLAGS)) + if ((FLAG_SAFE (cat) & CONSONANT_FLAGS)) { pos = POS_BASE_C; if (is_ra (u)) @@ -247,7 +247,7 @@ set_indic_properties (hb_glyph_info_t &info) { pos = matra_position (u, pos); } - else if ((FLAG (cat) & (FLAG (OT_SM) | FLAG (OT_VD) | FLAG (OT_A) | FLAG (OT_Symbol)))) + else if ((FLAG_SAFE (cat) & (FLAG (OT_SM) | FLAG (OT_VD) | FLAG (OT_A) | FLAG (OT_Symbol)))) { pos = POS_SMVD; } @@ -963,7 +963,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, indic_position_t last_pos = POS_START; for (unsigned int i = start; i < end; i++) { - if ((FLAG (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | HALANT_OR_COENG_FLAGS))) + if ((FLAG_SAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | HALANT_OR_COENG_FLAGS))) { info[i].indic_position() = last_pos; if (unlikely (info[i].indic_category() == OT_H && @@ -1550,7 +1550,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, { new_reph_pos = base; while (new_reph_pos < end && - !( FLAG (info[new_reph_pos + 1].indic_position()) & (FLAG (POS_POST_C) | FLAG (POS_AFTER_POST) | FLAG (POS_SMVD)))) + !( FLAG_SAFE (info[new_reph_pos + 1].indic_position()) & (FLAG (POS_POST_C) | FLAG (POS_AFTER_POST) | FLAG (POS_SMVD)))) new_reph_pos++; if (new_reph_pos < end) goto reph_move; @@ -1701,7 +1701,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, /* Apply 'init' to the Left Matra if it's a word start. */ if (info[start].indic_position () == POS_PRE_M && (!start || - !(FLAG (_hb_glyph_info_get_general_category (&info[start - 1])) & + !(FLAG_SAFE (_hb_glyph_info_get_general_category (&info[start - 1])) & FLAG_RANGE (HB_UNICODE_GENERAL_CATEGORY_FORMAT, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))) info[start].mask |= indic_plan->mask_array[INIT]; diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc index d016380cc..29c1ae827 100644 --- a/src/hb-ot-shape-complex-myanmar.cc +++ b/src/hb-ot-shape-complex-myanmar.cc @@ -154,7 +154,7 @@ is_one_of (const hb_glyph_info_t &info, unsigned int flags) { /* If it ligated, all bets are off. */ if (_hb_glyph_info_ligated (&info)) return false; - return !!(FLAG (info.myanmar_category()) & flags); + return !!(FLAG_SAFE (info.myanmar_category()) & flags); } static inline bool diff --git a/src/hb-private.hh b/src/hb-private.hh index e941126aa..dc67b3a49 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -846,9 +846,10 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) /* Useful for set-operations on small enums. * For example, for testing "x ∈ {x1, x2, x3}" use: - * (FLAG(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) + * (FLAG_SAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) */ -#define FLAG(x) (1U<<(x)) +#define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((x) < 32) + (1U << (x))) +#define FLAG_SAFE(x) (1U << (x)) #define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x)) diff --git a/src/hb-unicode-private.hh b/src/hb-unicode-private.hh index a2c59da27..968bca556 100644 --- a/src/hb-unicode-private.hh +++ b/src/hb-unicode-private.hh @@ -308,7 +308,7 @@ extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil; /* Misc */ #define HB_UNICODE_GENERAL_CATEGORY_IS_MARK(gen_cat) \ - (FLAG (gen_cat) & \ + (FLAG_SAFE (gen_cat) & \ (FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \ FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \ FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK))) From 5b5617e0664e59770910d04d15175f643a5ffb73 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 15:52:15 +0100 Subject: [PATCH 22/43] Add FLAG_UNSAFE() Unused right now. --- src/hb-private.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb-private.hh b/src/hb-private.hh index dc67b3a49..811293432 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -850,6 +850,7 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) */ #define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((x) < 32) + (1U << (x))) #define FLAG_SAFE(x) (1U << (x)) +#define FLAG_UNSAFE(x) ((x) < 32 ? FLAG_SAFE(x) : 0) #define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x)) From a85c4da9b1750c2f994f9f85226a3e755fafe50b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 16:07:10 +0100 Subject: [PATCH 23/43] [USE] Move rphf --- src/hb-ot-shape-complex-use.cc | 107 +++++++++++---------------------- 1 file changed, 36 insertions(+), 71 deletions(-) diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index 04adaa491..71d2ee15a 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -109,6 +109,7 @@ collect_features_use (hb_ot_shape_planner_t *plan) map->add_gsub_pause (clear_substitution_flags); map->add_feature (HB_TAG('r','p','h','f'), 1, F_MANUAL_ZWJ); map->add_gsub_pause (record_rphf); + map->add_gsub_pause (clear_substitution_flags); map->add_feature (HB_TAG('p','r','e','f'), 1, F_GLOBAL | F_MANUAL_ZWJ); map->add_gsub_pause (record_pref); @@ -291,8 +292,6 @@ record_pref (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { - const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; - hb_glyph_info_t *info = buffer->info; unsigned int count = buffer->len; if (unlikely (!count)) return; @@ -307,63 +306,6 @@ record_pref (const hb_ot_shape_plan_t *plan, record_pref_syllable (info, last, count); } -static void -reorder_virama_terminated_cluster (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) -{ -} - -static void -reorder_consonant_cluster (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) -{ - hb_glyph_info_t *info = buffer->info; - - /* Reorder! */ -#if 0 - unsigned int i = start; - for (; i < base; i++) - info[i].use_position() = POS_PRE_C; - if (i < end) - { - info[i].use_position() = POS_BASE_C; - i++; - } - for (; i < end; i++) - { - if (info[i].use_category() == OT_MR) /* Pre-base reordering */ - { - info[i].use_position() = POS_PRE_C; - continue; - } - if (info[i].use_category() == OT_VPre) /* Left matra */ - { - info[i].use_position() = POS_PRE_M; - continue; - } - - info[i].use_position() = POS_AFTER_MAIN; - } - - buffer->merge_clusters (start, end); - /* Sit tight, rock 'n roll! */ - hb_bubble_sort (info + start, end - start, compare_use_order); -#endif -} - -static void -reorder_vowel_cluster (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) -{ - reorder_consonant_cluster (plan, face, buffer, start, end); -} - static void reorder_syllable (const hb_ot_shape_plan_t *plan, hb_face_t *face, @@ -371,19 +313,42 @@ reorder_syllable (const hb_ot_shape_plan_t *plan, unsigned int start, unsigned int end) { syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F); - switch (syllable_type) { -#define HANDLE(X) case X: reorder_##X (plan, face, buffer, start, end); return - HANDLE (virama_terminated_cluster); - HANDLE (consonant_cluster); - HANDLE (vowel_cluster); -#undef HANDLE -#define HANDLE(X) case X: return - HANDLE (number_joiner_terminated_cluster); - HANDLE (numeral_cluster); - HANDLE (symbol_cluster); - HANDLE (independent_cluster); -#undef HANDLE + /* Only a few syllable types need reordering. */ + if (unlikely (!(FLAG_SAFE (syllable_type) & + (FLAG (virama_terminated_cluster) | + FLAG (consonant_cluster) | + FLAG (vowel_cluster))))) + return; + + hb_glyph_info_t *info = buffer->info; + +#define HALANT_FLAGS FLAG(USE_H) +#define BASE_FLAGS (FLAG (USE_B) | FLAG (USE_GB) | FLAG (USE_IV)) + + /* Move things forward. */ + if (info[start].use_category() == USE_R && end - start > 1) + { + /* Got a repha. Reorder it to after first base, before first halant. */ + for (unsigned int i = start + 1; i < end; i++) + if (FLAG_UNSAFE (info[i].use_category()) & (HALANT_FLAGS | BASE_FLAGS)) + { + /* If we hit a halant, move before it; otherwise it's a base: move to it's + * place, and shift things in between backward. */ + + if (info[i].use_category() == USE_H) + i--; + + hb_glyph_info_t t = info[start]; + memmove (&info[start], &info[start + 1], (i - start) * sizeof (info[0])); + info[i] = t; + buffer->merge_clusters (start, i + 1); + + break; + } } + + /* TODO move things back. */ + } static inline void From ad7178227f16abc17456f122deac1508031cbbc3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 16:43:27 +0100 Subject: [PATCH 24/43] [USE] Use a couple warnings --- src/gen-use-table.py | 20 +++--- src/hb-ot-shape-complex-use-table.cc | 100 +++++++++++++-------------- 2 files changed, 60 insertions(+), 60 deletions(-) diff --git a/src/gen-use-table.py b/src/gen-use-table.py index 82108750d..c4ec62cd5 100755 --- a/src/gen-use-table.py +++ b/src/gen-use-table.py @@ -432,15 +432,6 @@ occupancy = used * 100. / total page_bits = 12 print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy) print -for k in sorted(use_mapping.keys()): - if k in use_positions and use_positions[k]: continue - print "#undef %s" % k -for k,v in sorted(use_positions.items()): - if not v: continue - for suf in v.keys(): - tag = k + suf - print "#undef %s" % tag -print print "USE_TABLE_ELEMENT_TYPE" print "hb_use_get_categories (hb_codepoint_t u)" print "{" @@ -455,7 +446,7 @@ for p in sorted(pages): print " if (hb_in_range (u, 0x%04Xu, 0x%04Xu)) return use_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset) for u,d in singles.items (): if p != u>>page_bits: continue - print " if (unlikely (u == 0x%04Xu)) return USE_%s;" % (u, d[0]) + print " if (unlikely (u == 0x%04Xu)) return %s;" % (u, d[0]) print " break;" print "" print " default:" @@ -464,6 +455,15 @@ print " }" print " return USE_O;" print "}" print +for k in sorted(use_mapping.keys()): + if k in use_positions and use_positions[k]: continue + print "#undef %s" % k +for k,v in sorted(use_positions.items()): + if not v: continue + for suf in v.keys(): + tag = k + suf + print "#undef %s" % tag +print print "/* == End of generated table == */" # Maintain at least 50% occupancy in the table */ diff --git a/src/hb-ot-shape-complex-use-table.cc b/src/hb-ot-shape-complex-use-table.cc index 45c7976ae..17b4084ab 100644 --- a/src/hb-ot-shape-complex-use-table.cc +++ b/src/hb-ot-shape-complex-use-table.cc @@ -593,6 +593,56 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { }; /* Table items: 4784; occupancy: 72% */ +USE_TABLE_ELEMENT_TYPE +hb_use_get_categories (hb_codepoint_t u) +{ + switch (u >> 12) + { + case 0x0u: + if (hb_in_range (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u]; + if (hb_in_range (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u]; + if (hb_in_range (u, 0x0900u, 0x0DF7u)) return use_table[u - 0x0900u + use_offset_0x0900u]; + if (unlikely (u == 0x034Fu)) return CGJ; + break; + + case 0x1u: + if (hb_in_range (u, 0x1000u, 0x109Fu)) return use_table[u - 0x1000u + use_offset_0x1000u]; + if (hb_in_range (u, 0x1700u, 0x17EFu)) return use_table[u - 0x1700u + use_offset_0x1700u]; + if (hb_in_range (u, 0x1900u, 0x1A9Fu)) return use_table[u - 0x1900u + use_offset_0x1900u]; + if (hb_in_range (u, 0x1B00u, 0x1C4Fu)) return use_table[u - 0x1B00u + use_offset_0x1b00u]; + if (hb_in_range (u, 0x1CD0u, 0x1CFFu)) return use_table[u - 0x1CD0u + use_offset_0x1cd0u]; + break; + + case 0x2u: + if (hb_in_range (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u]; + if (hb_in_range (u, 0x2070u, 0x2087u)) return use_table[u - 0x2070u + use_offset_0x2070u]; + if (unlikely (u == 0x25CCu)) return GB; + break; + + case 0xAu: + if (hb_in_range (u, 0xA800u, 0xAAF7u)) return use_table[u - 0xA800u + use_offset_0xa800u]; + if (hb_in_range (u, 0xABC0u, 0xABFFu)) return use_table[u - 0xABC0u + use_offset_0xabc0u]; + break; + + case 0x10u: + if (hb_in_range (u, 0x10A00u, 0x10A47u)) return use_table[u - 0x10A00u + use_offset_0x10a00u]; + break; + + case 0x11u: + if (hb_in_range (u, 0x11000u, 0x110BFu)) return use_table[u - 0x11000u + use_offset_0x11000u]; + if (hb_in_range (u, 0x11100u, 0x11237u)) return use_table[u - 0x11100u + use_offset_0x11100u]; + if (hb_in_range (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u]; + if (hb_in_range (u, 0x11480u, 0x114DFu)) return use_table[u - 0x11480u + use_offset_0x11480u]; + if (hb_in_range (u, 0x11580u, 0x1173Fu)) return use_table[u - 0x11580u + use_offset_0x11580u]; + if (unlikely (u == 0x1107Fu)) return HN; + break; + + default: + break; + } + return USE_O; +} + #undef B #undef CGJ #undef FM @@ -631,54 +681,4 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { #undef VMPst #undef VMAbv -USE_TABLE_ELEMENT_TYPE -hb_use_get_categories (hb_codepoint_t u) -{ - switch (u >> 12) - { - case 0x0u: - if (hb_in_range (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u]; - if (hb_in_range (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u]; - if (hb_in_range (u, 0x0900u, 0x0DF7u)) return use_table[u - 0x0900u + use_offset_0x0900u]; - if (unlikely (u == 0x034Fu)) return USE_CGJ; - break; - - case 0x1u: - if (hb_in_range (u, 0x1000u, 0x109Fu)) return use_table[u - 0x1000u + use_offset_0x1000u]; - if (hb_in_range (u, 0x1700u, 0x17EFu)) return use_table[u - 0x1700u + use_offset_0x1700u]; - if (hb_in_range (u, 0x1900u, 0x1A9Fu)) return use_table[u - 0x1900u + use_offset_0x1900u]; - if (hb_in_range (u, 0x1B00u, 0x1C4Fu)) return use_table[u - 0x1B00u + use_offset_0x1b00u]; - if (hb_in_range (u, 0x1CD0u, 0x1CFFu)) return use_table[u - 0x1CD0u + use_offset_0x1cd0u]; - break; - - case 0x2u: - if (hb_in_range (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u]; - if (hb_in_range (u, 0x2070u, 0x2087u)) return use_table[u - 0x2070u + use_offset_0x2070u]; - if (unlikely (u == 0x25CCu)) return USE_GB; - break; - - case 0xAu: - if (hb_in_range (u, 0xA800u, 0xAAF7u)) return use_table[u - 0xA800u + use_offset_0xa800u]; - if (hb_in_range (u, 0xABC0u, 0xABFFu)) return use_table[u - 0xABC0u + use_offset_0xabc0u]; - break; - - case 0x10u: - if (hb_in_range (u, 0x10A00u, 0x10A47u)) return use_table[u - 0x10A00u + use_offset_0x10a00u]; - break; - - case 0x11u: - if (hb_in_range (u, 0x11000u, 0x110BFu)) return use_table[u - 0x11000u + use_offset_0x11000u]; - if (hb_in_range (u, 0x11100u, 0x11237u)) return use_table[u - 0x11100u + use_offset_0x11100u]; - if (hb_in_range (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u]; - if (hb_in_range (u, 0x11480u, 0x114DFu)) return use_table[u - 0x11480u + use_offset_0x11480u]; - if (hb_in_range (u, 0x11580u, 0x1173Fu)) return use_table[u - 0x11580u + use_offset_0x11580u]; - if (unlikely (u == 0x1107Fu)) return USE_HN; - break; - - default: - break; - } - return USE_O; -} - /* == End of generated table == */ From 2d4b62ead931b13f95f5dc0e5b740d997a8d1a8e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 16:46:37 +0100 Subject: [PATCH 25/43] [USE] Fix-up variation selectors and word joiner in table --- src/gen-use-table.py | 7 +++++- src/hb-ot-shape-complex-use-table.cc | 34 +++++++++++++++++++--------- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/gen-use-table.py b/src/gen-use-table.py index c4ec62cd5..be04e4ba4 100755 --- a/src/gen-use-table.py +++ b/src/gen-use-table.py @@ -41,8 +41,11 @@ for i, f in enumerate (files): defaults = ('Other', 'Not_Applicable', 'Cn', 'No_Block') -# TODO CGJ is not in Unicode Indic files, but used in USE +# TODO Characters that are not in Unicode Indic files, but used in USE data[0][0x034F] = defaults[0] +data[0][0x2060] = defaults[0] +for u in range (0xFE00, 0xFE0F + 1): + data[0][u] = defaults[0] # Merge data into one dict: for i,v in enumerate (defaults): @@ -187,6 +190,8 @@ def is_OTHER(U, UISC, UGC): return (UISC == Other and not is_SYM_MOD(U, UISC, UGC) and not is_CGJ(U, UISC, UGC) + and not is_Word_Joiner(U, UISC, UGC) + and not is_VARIATION_SELECTOR(U, UISC, UGC) ) def is_Reserved(U, UISC, UGC): return UGC == 'Cn' diff --git a/src/hb-ot-shape-complex-use-table.cc b/src/hb-ot-shape-complex-use-table.cc index 17b4084ab..6cd1c5db7 100644 --- a/src/hb-ot-shape-complex-use-table.cc +++ b/src/hb-ot-shape-complex-use-table.cc @@ -333,15 +333,16 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { O, O, O, O, ZWNJ, ZWJ, O, O, /* 2010 */ GB, GB, GB, GB, GB, O, O, O, -#define use_offset_0x2070u 2568 +#define use_offset_0x2060u 2568 + /* 2060 */ WJ, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Superscripts and Subscripts */ /* 2070 */ O, O, O, O, FM, O, O, O, O, O, O, O, O, O, O, O, /* 2080 */ O, O, FM, FM, FM, O, O, O, -#define use_offset_0xa800u 2592 +#define use_offset_0xa800u 2608 /* Syloti Nagri */ @@ -428,7 +429,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* AAE0 */ IV, IV, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst, /* AAF0 */ O, O, O, O, O, VMPst, H, O, -#define use_offset_0xabc0u 3352 +#define use_offset_0xabc0u 3368 /* Meetei Mayek */ @@ -438,7 +439,14 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* ABE0 */ B, B, B, VPst, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O, VMPst, VBlw, O, O, /* ABF0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0x10a00u 3416 +#define use_offset_0xfe00u 3432 + + + /* Variation Selectors */ + + /* FE00 */ VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, + +#define use_offset_0x10a00u 3448 /* Kharoshthi */ @@ -449,7 +457,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 10A30 */ B, B, B, B, O, O, O, O, CMAbv, CMBlw, CMBlw, O, O, O, O, H, /* 10A40 */ B, B, B, B, B, B, B, B, -#define use_offset_0x11000u 3488 +#define use_offset_0x11000u 3520 /* Brahmi */ @@ -470,7 +478,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 110A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 110B0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VPst, VPst, H, CMBlw, O, O, O, O, O, -#define use_offset_0x11100u 3680 +#define use_offset_0x11100u 3712 /* Chakma */ @@ -508,7 +516,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VBlw, /* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, -#define use_offset_0x11280u 3992 +#define use_offset_0x11280u 4024 /* Multani */ @@ -536,7 +544,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11360 */ IV, IV, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, -#define use_offset_0x11480u 4240 +#define use_offset_0x11480u 4272 /* Tirhuta */ @@ -548,7 +556,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 114C0 */ VMAbv, VMPst, H, CMBlw, B, O, O, O, O, O, O, O, O, O, O, O, /* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0x11580u 4336 +#define use_offset_0x11580u 4368 /* Siddham */ @@ -591,7 +599,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VAbv, O, O, O, O, /* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, -}; /* Table items: 4784; occupancy: 72% */ +}; /* Table items: 4816; occupancy: 72% */ USE_TABLE_ELEMENT_TYPE hb_use_get_categories (hb_codepoint_t u) @@ -615,7 +623,7 @@ hb_use_get_categories (hb_codepoint_t u) case 0x2u: if (hb_in_range (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u]; - if (hb_in_range (u, 0x2070u, 0x2087u)) return use_table[u - 0x2070u + use_offset_0x2070u]; + if (hb_in_range (u, 0x2060u, 0x2087u)) return use_table[u - 0x2060u + use_offset_0x2060u]; if (unlikely (u == 0x25CCu)) return GB; break; @@ -624,6 +632,10 @@ hb_use_get_categories (hb_codepoint_t u) if (hb_in_range (u, 0xABC0u, 0xABFFu)) return use_table[u - 0xABC0u + use_offset_0xabc0u]; break; + case 0xFu: + if (hb_in_range (u, 0xFE00u, 0xFE0Fu)) return use_table[u - 0xFE00u + use_offset_0xfe00u]; + break; + case 0x10u: if (hb_in_range (u, 0x10A00u, 0x10A47u)) return use_table[u - 0x10A00u + use_offset_0x10a00u]; break; From 7ce03ebe7c525919ce22d9094480847ff1b3c2b2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 16:55:26 +0100 Subject: [PATCH 26/43] [USE] Move pref --- src/hb-ot-shape-complex-use-machine.rl | 9 +++++---- src/hb-ot-shape-complex-use-private.hh | 9 +++++---- src/hb-ot-shape-complex-use.cc | 24 ++++++++++++++++++++++-- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/hb-ot-shape-complex-use-machine.rl b/src/hb-ot-shape-complex-use-machine.rl index 77068bdff..9cc9a23a9 100644 --- a/src/hb-ot-shape-complex-use-machine.rl +++ b/src/hb-ot-shape-complex-use-machine.rl @@ -55,6 +55,7 @@ FM = 8; # CONS_FINAL_MOD #CM = 10; # CONS_MOD SUB = 11; # CONS_SUB H = 12; # HALANT + HN = 13; # HALANT_NUM ZWNJ = 14; # Zero width non-joiner ZWJ = 15; # Zero width joiner @@ -64,8 +65,8 @@ R = 18; # REPHA S = 19; # SYM #SM = 20; # SYM_MOD VS = 21; # VARIATION_SELECTOR -#V = 22; # VOWEL -#VM = 23; # VOWEL_MOD +#V = 36; # VOWEL +#VM = 40; # VOWEL_MOD FAbv = 24; # CONS_FINAL_ABOVE FBlw = 25; # CONS_FINAL_BELOW @@ -79,11 +80,11 @@ CMBlw = 32; # CONS_MOD_BELOW VAbv = 33; # VOWEL_ABOVE / VOWEL_ABOVE_BELOW / VOWEL_ABOVE_BELOW_POST / VOWEL_ABOVE_POST VBlw = 34; # VOWEL_BELOW / VOWEL_BELOW_POST VPst = 35; # VOWEL_POST UIPC = Right -VPre = 36; # VOWEL_PRE / VOWEL_PRE_ABOVE / VOWEL_PRE_ABOVE_POST / VOWEL_PRE_POST +VPre = 22; # VOWEL_PRE / VOWEL_PRE_ABOVE / VOWEL_PRE_ABOVE_POST / VOWEL_PRE_POST VMAbv = 37; # VOWEL_MOD_ABOVE VMBlw = 38; # VOWEL_MOD_BELOW VMPst = 39; # VOWEL_MOD_POST -VMPre = 40; # VOWEL_MOD_PRE +VMPre = 23; # VOWEL_MOD_PRE SMAbv = 41; # SYM_MOD_ABOVE SMBlw = 42; # SYM_MOD_BELOW diff --git a/src/hb-ot-shape-complex-use-private.hh b/src/hb-ot-shape-complex-use-private.hh index fc0cfc50b..a14373621 100644 --- a/src/hb-ot-shape-complex-use-private.hh +++ b/src/hb-ot-shape-complex-use-private.hh @@ -57,6 +57,7 @@ enum use_category_t { // USE_CM = 10, /* CONS_MOD */ USE_SUB = 11, /* CONS_SUB */ USE_H = 12, /* HALANT */ + USE_HN = 13, /* HALANT_NUM */ USE_ZWNJ = 14, /* Zero width non-joiner */ USE_ZWJ = 15, /* Zero width joiner */ @@ -66,8 +67,8 @@ enum use_category_t { USE_S = 19, /* SYM */ // USE_SM = 20, /* SYM_MOD */ USE_VS = 21, /* VARIATION_SELECTOR */ -// USE_V = 22, /* VOWEL */ -// USE_VM = 23, /* VOWEL_MOD */ +// USE_V = 36, /* VOWEL */ +// USE_VM = 40, /* VOWEL_MOD */ USE_FAbv = 24, /* CONS_FINAL_ABOVE */ USE_FBlw = 25, /* CONS_FINAL_BELOW */ @@ -81,11 +82,11 @@ enum use_category_t { USE_VAbv = 33, /* VOWEL_ABOVE / VOWEL_ABOVE_BELOW / VOWEL_ABOVE_BELOW_POST / VOWEL_ABOVE_POST */ USE_VBlw = 34, /* VOWEL_BELOW / VOWEL_BELOW_POST */ USE_VPst = 35, /* VOWEL_POST UIPC = Right */ - USE_VPre = 36, /* VOWEL_PRE / VOWEL_PRE_ABOVE / VOWEL_PRE_ABOVE_POST / VOWEL_PRE_POST */ + USE_VPre = 22, /* VOWEL_PRE / VOWEL_PRE_ABOVE / VOWEL_PRE_ABOVE_POST / VOWEL_PRE_POST */ USE_VMAbv = 37, /* VOWEL_MOD_ABOVE */ USE_VMBlw = 38, /* VOWEL_MOD_BELOW */ USE_VMPst = 39, /* VOWEL_MOD_POST */ - USE_VMPre = 40, /* VOWEL_MOD_PRE */ + USE_VMPre = 23, /* VOWEL_MOD_PRE */ USE_SMAbv = 41, /* SYM_MOD_ABOVE */ USE_SMBlw = 42 /* SYM_MOD_BELOW */ }; diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index 71d2ee15a..b2c65437b 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -347,8 +347,28 @@ reorder_syllable (const hb_ot_shape_plan_t *plan, } } - /* TODO move things back. */ - + /* Move things back. */ + unsigned int j = end; + for (unsigned int i = start; i < end; i++) + { + uint32_t flag = FLAG_UNSAFE (info[i].use_category()); + if (flag & (HALANT_FLAGS | BASE_FLAGS)) + { + /* If we hit a halant, move before it; otherwise it's a base: move to it's + * place, and shift things in between backward. */ + if (info[i].use_category() == USE_H) + j = i + 1; + else + j = i; + } + else if (((flag) & (FLAG (USE_VPre) | FLAG (USE_VMPre))) && j < i) + { + hb_glyph_info_t t = info[i]; + memmove (&info[j + 1], &info[j], (i - j) * sizeof (info[0])); + info[j] = t; + buffer->merge_clusters (j, i + 1); + } + } } static inline void From 40c4a991c7ea18017273ff8993eecc3953869e69 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 17:14:54 +0100 Subject: [PATCH 27/43] [USE] Implement dotted-circle This makes USE feature-complete as far as the Indic-like features are concerned. --- src/hb-ot-shape-complex-use-machine.rl | 10 ++++++++++ src/hb-ot-shape-complex-use.cc | 18 +++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-shape-complex-use-machine.rl b/src/hb-ot-shape-complex-use-machine.rl index 9cc9a23a9..b8242bab1 100644 --- a/src/hb-ot-shape-complex-use-machine.rl +++ b/src/hb-ot-shape-complex-use-machine.rl @@ -116,6 +116,15 @@ vowel_cluster = final_consonants ; +broken_cluster = + R? + consonant_modifiers + medial_consonants + dependent_vowels + vowel_modifiers + final_consonants +; + number_joiner_terminated_cluster = N VS? (HN N VS?)* H; numeral_cluster = N VS? (HN N VS?)*; symbol_cluster = S VS? SMAbv* SMBlw*; @@ -129,6 +138,7 @@ main := |* number_joiner_terminated_cluster => { found_syllable (number_joiner_terminated_cluster); }; numeral_cluster => { found_syllable (numeral_cluster); }; symbol_cluster => { found_syllable (symbol_cluster); }; + broken_cluster => { found_syllable (broken_cluster); }; *|; diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index b2c65437b..379eec1bd 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -160,6 +160,7 @@ enum syllable_type_t { number_joiner_terminated_cluster, numeral_cluster, symbol_cluster, + broken_cluster, }; #include "hb-ot-shape-complex-use-machine.hh" @@ -317,7 +318,9 @@ reorder_syllable (const hb_ot_shape_plan_t *plan, if (unlikely (!(FLAG_SAFE (syllable_type) & (FLAG (virama_terminated_cluster) | FLAG (consonant_cluster) | - FLAG (vowel_cluster))))) + FLAG (vowel_cluster) | + FLAG (broken_cluster) | + 0)))) return; hb_glyph_info_t *info = buffer->info; @@ -376,7 +379,6 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font, hb_buffer_t *buffer) { -#if 0 /* Note: This loop is extra overhead, but should not be measurable. */ bool has_broken_syllables = false; unsigned int count = buffer->len; @@ -391,6 +393,10 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, return; + hb_codepoint_t dottedcircle_glyph; + if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph)) + return; + hb_glyph_info_t dottedcircle = {0}; if (!font->get_glyph (0x25CCu, 0, &dottedcircle.codepoint)) return; @@ -412,6 +418,13 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, info.cluster = buffer->cur().cluster; info.mask = buffer->cur().mask; info.syllable() = buffer->cur().syllable(); + /* TODO Set glyph_props? */ + + /* Insert dottedcircle after possible Repha. */ + while (buffer->idx < buffer->len && + last_syllable == buffer->cur().syllable() && + buffer->cur().use_category() == USE_R) + buffer->next_glyph (); buffer->output_info (info); } @@ -420,7 +433,6 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, } buffer->swap_buffers (); -#endif } static void From 29832d797ff2f3a96721dd44f2f03a83fb2e8dda Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 17:24:18 +0100 Subject: [PATCH 28/43] Route misc untested scripts through USE shaper instead of Indic These were never tested with Indic shaper, and indeed wouldn't work there because they didn't have their viramas and other config defined. They are all also supported by MS through USE, so route them there. --- src/hb-ot-shape-complex-private.hh | 91 ++++-------------------------- 1 file changed, 11 insertions(+), 80 deletions(-) diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh index 702e9522e..d3144857a 100644 --- a/src/hb-ot-shape-complex-private.hh +++ b/src/hb-ot-shape-complex-private.hh @@ -218,61 +218,9 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* ^--- Add new shapers here */ - #if 0 - /* Note: - * - * These disabled scripts are listed in ucd/IndicSyllabicCategory.txt, but according - * to Martin Hosken and Jonathan Kew do not require complex shaping. - * - * TODO We should automate figuring out which scripts do not need complex shaping - * - * TODO We currently keep data for these scripts in our indic table. Need to fix the - * generator to not do that. - */ - - - /* Simple? */ - - /* Unicode-3.2 additions */ - case HB_SCRIPT_BUHID: - case HB_SCRIPT_HANUNOO: - - /* Unicode-5.1 additions */ - case HB_SCRIPT_SAURASHTRA: - - /* Unicode-6.0 additions */ - case HB_SCRIPT_BATAK: - case HB_SCRIPT_BRAHMI: - - - /* Simple */ - - /* Unicode-1.1 additions */ - /* These have their own shaper now. */ - case HB_SCRIPT_LAO: - case HB_SCRIPT_THAI: - - /* Unicode-3.2 additions */ - case HB_SCRIPT_TAGALOG: - case HB_SCRIPT_TAGBANWA: - - /* Unicode-4.0 additions */ - case HB_SCRIPT_LIMBU: - case HB_SCRIPT_TAI_LE: - /* Unicode-4.1 additions */ - case HB_SCRIPT_KHAROSHTHI: case HB_SCRIPT_NEW_TAI_LUE: - case HB_SCRIPT_SYLOTI_NAGRI: - - /* Unicode-5.1 additions */ - case HB_SCRIPT_KAYAH_LI: - - /* Unicode-5.2 additions */ - case HB_SCRIPT_TAI_VIET: - - #endif /* Unicode-1.1 additions */ @@ -289,25 +237,8 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-3.0 additions */ case HB_SCRIPT_SINHALA: - /* Unicode-5.0 additions */ - case HB_SCRIPT_BALINESE: - - /* Unicode-5.1 additions */ - case HB_SCRIPT_LEPCHA: - case HB_SCRIPT_REJANG: - case HB_SCRIPT_SUNDANESE: - /* Unicode-5.2 additions */ case HB_SCRIPT_JAVANESE: - case HB_SCRIPT_KAITHI: - case HB_SCRIPT_MEETEI_MAYEK: - - /* Unicode-6.0 additions */ - - /* Unicode-6.1 additions */ - case HB_SCRIPT_CHAKMA: - case HB_SCRIPT_SHARADA: - case HB_SCRIPT_TAKRI: /* If the designer designed the font for the 'DFLT' script, * use the default shaper. Otherwise, use the Indic shaper. @@ -385,35 +316,35 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_TIFINAGH: /* Unicode-5.0 additions */ - //case HB_SCRIPT_BALINESE: + case HB_SCRIPT_BALINESE: //case HB_SCRIPT_NKO: //case HB_SCRIPT_PHAGS_PA: /* Unicode-5.1 additions */ //case HB_SCRIPT_CHAM: case HB_SCRIPT_KAYAH_LI: - //case HB_SCRIPT_LEPCHA: - //case HB_SCRIPT_REJANG: + case HB_SCRIPT_LEPCHA: + case HB_SCRIPT_REJANG: case HB_SCRIPT_SAURASHTRA: - //case HB_SCRIPT_SUNDANESE: + case HB_SCRIPT_SUNDANESE: /* Unicode-5.2 additions */ case HB_SCRIPT_EGYPTIAN_HIEROGLYPHS: //case HB_SCRIPT_JAVANESE: - //case HB_SCRIPT_KAITHI: - //case HB_SCRIPT_MEETEI_MAYEK: + case HB_SCRIPT_KAITHI: + case HB_SCRIPT_MEETEI_MAYEK: //case HB_SCRIPT_TAI_THAM: - //case HB_SCRIPT_TAI_VIET: + case HB_SCRIPT_TAI_VIET: /* Unicode-6.0 additions */ - //case HB_SCRIPT_BATAK: + case HB_SCRIPT_BATAK: case HB_SCRIPT_BRAHMI: //case HB_SCRIPT_MANDAIC: /* Unicode-6.1 additions */ - //case HB_SCRIPT_CHAKMA: - //case HB_SCRIPT_SHARADA: - //case HB_SCRIPT_TAKRI: + case HB_SCRIPT_CHAKMA: + case HB_SCRIPT_SHARADA: + case HB_SCRIPT_TAKRI: /* Unicode-7.0 additions */ case HB_SCRIPT_DUPLOYAN: From 87dde9c64753dea4017f11a7734e7528b8eecac0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 17:31:43 +0100 Subject: [PATCH 29/43] [USE] Only use USE shaper if script system is not DFLT Same logic as Indic and SEA. --- src/hb-ot-shape-complex-private.hh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh index d3144857a..e58862262 100644 --- a/src/hb-ot-shape-complex-private.hh +++ b/src/hb-ot-shape-complex-private.hh @@ -241,7 +241,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_JAVANESE: /* If the designer designed the font for the 'DFLT' script, - * use the default shaper. Otherwise, use the Indic shaper. + * use the default shaper. Otherwise, use the specific shaper. * Note that for some simple scripts, there may not be *any* * GSUB/GPOS needed, so there may be no scripts found! */ if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T')) @@ -283,7 +283,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_TAI_THAM: /* If the designer designed the font for the 'DFLT' script, - * use the default shaper. Otherwise, use the Indic shaper. + * use the default shaper. Otherwise, use the specific shaper. * Note that for some simple scripts, there may not be *any* * GSUB/GPOS needed, so there may be no scripts found! */ if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T')) @@ -359,7 +359,14 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_SIDDHAM: case HB_SCRIPT_TIRHUTA: - return &_hb_ot_complex_shaper_use; + /* If the designer designed the font for the 'DFLT' script, + * use the default shaper. Otherwise, use the specific shaper. + * Note that for some simple scripts, there may not be *any* + * GSUB/GPOS needed, so there may be no scripts found! */ + if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T')) + return &_hb_ot_complex_shaper_default; + else + return &_hb_ot_complex_shaper_use; } } From db1e9cdd41ff7c97c29b4d9b64b2351ed0ef0403 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 17:46:06 +0100 Subject: [PATCH 30/43] Retire SEA shaper in favor of USE --- src/hb-ot-shape-complex-private.hh | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh index e58862262..8d03dee51 100644 --- a/src/hb-ot-shape-complex-private.hh +++ b/src/hb-ot-shape-complex-private.hh @@ -59,7 +59,6 @@ enum hb_ot_shape_zero_width_marks_type_t { HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_old) \ HB_COMPLEX_SHAPER_IMPLEMENT (indic) \ HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \ - HB_COMPLEX_SHAPER_IMPLEMENT (sea) \ HB_COMPLEX_SHAPER_IMPLEMENT (thai) \ HB_COMPLEX_SHAPER_IMPLEMENT (tibetan) \ HB_COMPLEX_SHAPER_IMPLEMENT (use) \ @@ -273,24 +272,6 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) else return &_hb_ot_complex_shaper_default; - /* Unicode-4.1 additions */ - case HB_SCRIPT_BUGINESE: - - /* Unicode-5.1 additions */ - case HB_SCRIPT_CHAM: - - /* Unicode-5.2 additions */ - case HB_SCRIPT_TAI_THAM: - - /* If the designer designed the font for the 'DFLT' script, - * use the default shaper. Otherwise, use the specific shaper. - * Note that for some simple scripts, there may not be *any* - * GSUB/GPOS needed, so there may be no scripts found! */ - if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T')) - return &_hb_ot_complex_shaper_default; - else - return &_hb_ot_complex_shaper_sea; - /* Unicode-2.0 additions */ //case HB_SCRIPT_TIBETAN: @@ -310,7 +291,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_TAI_LE: /* Unicode-4.1 additions */ - //case HB_SCRIPT_BUGINESE: + case HB_SCRIPT_BUGINESE: case HB_SCRIPT_KHAROSHTHI: case HB_SCRIPT_SYLOTI_NAGRI: case HB_SCRIPT_TIFINAGH: @@ -321,7 +302,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) //case HB_SCRIPT_PHAGS_PA: /* Unicode-5.1 additions */ - //case HB_SCRIPT_CHAM: + case HB_SCRIPT_CHAM: case HB_SCRIPT_KAYAH_LI: case HB_SCRIPT_LEPCHA: case HB_SCRIPT_REJANG: @@ -333,7 +314,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) //case HB_SCRIPT_JAVANESE: case HB_SCRIPT_KAITHI: case HB_SCRIPT_MEETEI_MAYEK: - //case HB_SCRIPT_TAI_THAM: + case HB_SCRIPT_TAI_THAM: case HB_SCRIPT_TAI_VIET: /* Unicode-6.0 additions */ From 21cb08a417f1203523191192d6a342e8cd0ea14c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 17:47:06 +0100 Subject: [PATCH 31/43] Remove unused SEA shaper --- src/Makefile.am | 4 - src/hb-ot-shape-complex-sea-machine.rl | 102 ------- src/hb-ot-shape-complex-sea.cc | 380 ------------------------- 3 files changed, 486 deletions(-) delete mode 100644 src/hb-ot-shape-complex-sea-machine.rl delete mode 100644 src/hb-ot-shape-complex-sea.cc diff --git a/src/Makefile.am b/src/Makefile.am index 947d279ac..6258dd738 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -104,8 +104,6 @@ HBSOURCES += \ hb-ot-shape-complex-indic-table.cc \ hb-ot-shape-complex-myanmar.cc \ hb-ot-shape-complex-myanmar-machine.hh \ - hb-ot-shape-complex-sea.cc \ - hb-ot-shape-complex-sea-machine.hh \ hb-ot-shape-complex-thai.cc \ hb-ot-shape-complex-tibetan.cc \ hb-ot-shape-complex-use.cc \ @@ -307,7 +305,6 @@ RAGEL_GENERATED = \ $(srcdir)/hb-buffer-deserialize-text.hh \ $(srcdir)/hb-ot-shape-complex-indic-machine.hh \ $(srcdir)/hb-ot-shape-complex-myanmar-machine.hh \ - $(srcdir)/hb-ot-shape-complex-sea-machine.hh \ $(srcdir)/hb-ot-shape-complex-use-machine.hh \ $(NULL) BUILT_SOURCES += $(RAGEL_GENERATED) @@ -316,7 +313,6 @@ EXTRA_DIST += \ hb-buffer-deserialize-text.rl \ hb-ot-shape-complex-indic-machine.rl \ hb-ot-shape-complex-myanmar-machine.rl \ - hb-ot-shape-complex-sea-machine.rl \ hb-ot-shape-complex-use-machine.rl \ $(NULL) MAINTAINERCLEANFILES += $(RAGEL_GENERATED) diff --git a/src/hb-ot-shape-complex-sea-machine.rl b/src/hb-ot-shape-complex-sea-machine.rl deleted file mode 100644 index 46140fc4d..000000000 --- a/src/hb-ot-shape-complex-sea-machine.rl +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright © 2011,2012,2013 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_SEA_MACHINE_HH -#define HB_OT_SHAPE_COMPLEX_SEA_MACHINE_HH - -#include "hb-private.hh" - -%%{ - machine sea_syllable_machine; - alphtype unsigned char; - write data; -}%% - -%%{ - -# Same order as enum sea_category_t. Not sure how to avoid duplication. -C = 1; -GB = 12; # Generic Base -H = 4; # Halant -IV = 2; # Independent Vowel -MR = 22; # Medial Ra -CM = 17; # Consonant Medial -VAbv = 26; -VBlw = 27; -VPre = 28; -VPst = 29; -T = 3; # Tone Marks -A = 10; # Anusvara - -syllable_tail = (VPre|VAbv|VBlw|VPst|H.C|CM|MR|T|A)*; - -consonant_syllable = (C|IV|GB) syllable_tail; -broken_cluster = syllable_tail; -other = any; - -main := |* - consonant_syllable => { found_syllable (consonant_syllable); }; - broken_cluster => { found_syllable (broken_cluster); }; - other => { found_syllable (non_sea_cluster); }; -*|; - - -}%% - -#define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ - for (unsigned int i = last; i < p+1; i++) \ - info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - last = p+1; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END - -static void -find_syllables (hb_buffer_t *buffer) -{ - unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; - int cs; - hb_glyph_info_t *info = buffer->info; - %%{ - write init; - getkey info[p].sea_category(); - }%% - - p = 0; - pe = eof = buffer->len; - - unsigned int last = 0; - unsigned int syllable_serial = 1; - %%{ - write exec; - }%% -} - -#undef found_syllable - -#endif /* HB_OT_SHAPE_COMPLEX_SEA_MACHINE_HH */ diff --git a/src/hb-ot-shape-complex-sea.cc b/src/hb-ot-shape-complex-sea.cc deleted file mode 100644 index f08b7ccb9..000000000 --- a/src/hb-ot-shape-complex-sea.cc +++ /dev/null @@ -1,380 +0,0 @@ -/* - * Copyright © 2011,2012,2013 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-ot-shape-complex-indic-private.hh" - -/* buffer var allocations */ -#define sea_category() complex_var_u8_0() /* indic_category_t */ -#define sea_position() complex_var_u8_1() /* indic_position_t */ - - -/* - * South-East Asian shaper. - * Loosely based on the Myanmar spec / shaper. - * There is no OpenType spec for this. - */ - -static const hb_tag_t -basic_features[] = -{ - /* - * Basic features. - * These features are applied in order, one at a time, after initial_reordering. - */ - HB_TAG('p','r','e','f'), - HB_TAG('a','b','v','f'), - HB_TAG('b','l','w','f'), - HB_TAG('p','s','t','f'), -}; -static const hb_tag_t -other_features[] = -{ - /* - * Other features. - * These features are applied all at once, after final_reordering. - */ - HB_TAG('p','r','e','s'), - HB_TAG('a','b','v','s'), - HB_TAG('b','l','w','s'), - HB_TAG('p','s','t','s'), - /* Positioning features, though we don't care about the types. */ - HB_TAG('d','i','s','t'), -}; - -static void -setup_syllables (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer); -static void -initial_reordering (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer); -static void -final_reordering (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer); - -static void -collect_features_sea (hb_ot_shape_planner_t *plan) -{ - hb_ot_map_builder_t *map = &plan->map; - - /* Do this before any lookups have been applied. */ - map->add_gsub_pause (setup_syllables); - - map->add_global_bool_feature (HB_TAG('l','o','c','l')); - /* The Indic specs do not require ccmp, but we apply it here since if - * there is a use of it, it's typically at the beginning. */ - map->add_global_bool_feature (HB_TAG('c','c','m','p')); - - map->add_gsub_pause (initial_reordering); - for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++) - { - map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); - map->add_gsub_pause (NULL); - } - map->add_gsub_pause (final_reordering); - for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++) - map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); -} - -static void -override_features_sea (hb_ot_shape_planner_t *plan) -{ - plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL); -} - - -enum syllable_type_t { - consonant_syllable, - broken_cluster, - non_sea_cluster, -}; - -#include "hb-ot-shape-complex-sea-machine.hh" - - -/* Note: This enum is duplicated in the -machine.rl source file. - * Not sure how to avoid duplication. */ -enum sea_category_t { -// OT_C = 1, - OT_GB = 12, /* Generic Base XXX DOTTED CIRCLE only for now */ -// OT_H = 4, /* Halant */ - OT_IV = 2, /* Independent Vowel */ - OT_MR = 22, /* Medial Ra */ -// OT_CM = 17, /* Consonant Medial */ - OT_VAbv = 26, - OT_VBlw = 27, - OT_VPre = 28, - OT_VPst = 29, - OT_T = 3, /* Tone Marks */ -// OT_A = 10, /* Anusvara */ -}; - -static inline void -set_sea_properties (hb_glyph_info_t &info) -{ - hb_codepoint_t u = info.codepoint; - unsigned int type = hb_indic_get_categories (u); - indic_category_t cat = (indic_category_t) (type & 0x7Fu); - indic_position_t pos = (indic_position_t) (type >> 8); - - /* Medial Ra */ - if (u == 0x1A55u || u == 0xAA34u) - cat = (indic_category_t) OT_MR; - - if (cat == OT_M) - { - switch ((int) pos) - { - case POS_PRE_C: cat = (indic_category_t) OT_VPre; break; - case POS_ABOVE_C: cat = (indic_category_t) OT_VAbv; break; - case POS_BELOW_C: cat = (indic_category_t) OT_VBlw; break; - case POS_POST_C: cat = (indic_category_t) OT_VPst; break; - } - } - - info.sea_category() = (sea_category_t) cat; - info.sea_position() = pos; -} - - -static void -setup_masks_sea (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_buffer_t *buffer, - hb_font_t *font HB_UNUSED) -{ - HB_BUFFER_ALLOCATE_VAR (buffer, sea_category); - HB_BUFFER_ALLOCATE_VAR (buffer, sea_position); - - /* We cannot setup masks here. We save information about characters - * and setup masks later on in a pause-callback. */ - - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - set_sea_properties (info[i]); -} - -static void -setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_font_t *font HB_UNUSED, - hb_buffer_t *buffer) -{ - find_syllables (buffer); -} - -static int -compare_sea_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb) -{ - int a = pa->sea_position(); - int b = pb->sea_position(); - - return a < b ? -1 : a == b ? 0 : +1; -} - - -static void -initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) -{ - hb_glyph_info_t *info = buffer->info; - unsigned int base = start; - - /* Reorder! */ - unsigned int i = start; - for (; i < base; i++) - info[i].sea_position() = POS_PRE_C; - if (i < end) - { - info[i].sea_position() = POS_BASE_C; - i++; - } - for (; i < end; i++) - { - if (info[i].sea_category() == OT_MR) /* Pre-base reordering */ - { - info[i].sea_position() = POS_PRE_C; - continue; - } - if (info[i].sea_category() == OT_VPre) /* Left matra */ - { - info[i].sea_position() = POS_PRE_M; - continue; - } - - info[i].sea_position() = POS_AFTER_MAIN; - } - - buffer->merge_clusters (start, end); - /* Sit tight, rock 'n roll! */ - hb_bubble_sort (info + start, end - start, compare_sea_order); -} - -static void -initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) -{ - /* We already inserted dotted-circles, so just call the consonant_syllable. */ - initial_reordering_consonant_syllable (plan, face, buffer, start, end); -} - -static void -initial_reordering_non_sea_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_face_t *face HB_UNUSED, - hb_buffer_t *buffer 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 - * buffer in the reordering process, we'd need to next_glyph() here. */ -} - - -static void -initial_reordering_syllable (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) -{ - syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F); - switch (syllable_type) { - case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return; - case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return; - case non_sea_cluster: initial_reordering_non_sea_cluster (plan, face, buffer, start, end); return; - } -} - -static inline void -insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_font_t *font, - hb_buffer_t *buffer) -{ - /* Note: This loop is extra overhead, but should not be measurable. */ - bool has_broken_syllables = false; - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - if ((info[i].syllable() & 0x0F) == broken_cluster) - { - has_broken_syllables = true; - break; - } - if (likely (!has_broken_syllables)) - return; - - - hb_codepoint_t dottedcircle_glyph; - if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph)) - return; - - hb_glyph_info_t dottedcircle = {0}; - dottedcircle.codepoint = 0x25CCu; - set_sea_properties (dottedcircle); - dottedcircle.codepoint = dottedcircle_glyph; - - buffer->clear_output (); - - buffer->idx = 0; - unsigned int last_syllable = 0; - while (buffer->idx < buffer->len) - { - unsigned int syllable = buffer->cur().syllable(); - syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F); - if (unlikely (last_syllable != syllable && syllable_type == broken_cluster)) - { - last_syllable = syllable; - - hb_glyph_info_t info = dottedcircle; - info.cluster = buffer->cur().cluster; - info.mask = buffer->cur().mask; - info.syllable() = buffer->cur().syllable(); - - buffer->output_info (info); - } - else - buffer->next_glyph (); - } - - buffer->swap_buffers (); -} - -static void -initial_reordering (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer) -{ - insert_dotted_circles (plan, font, buffer); - - hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; - if (unlikely (!count)) return; - unsigned int last = 0; - unsigned int last_syllable = info[0].syllable(); - for (unsigned int i = 1; i < count; i++) - if (last_syllable != info[i].syllable()) { - initial_reordering_syllable (plan, font->face, buffer, last, i); - last = i; - last_syllable = info[last].syllable(); - } - initial_reordering_syllable (plan, font->face, buffer, last, count); -} - -static void -final_reordering (const hb_ot_shape_plan_t *plan, - hb_font_t *font HB_UNUSED, - hb_buffer_t *buffer) -{ - hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; - - /* Zero syllables now... */ - for (unsigned int i = 0; i < count; i++) - info[i].syllable() = 0; - - HB_BUFFER_DEALLOCATE_VAR (buffer, sea_category); - HB_BUFFER_DEALLOCATE_VAR (buffer, sea_position); -} - - -const hb_ot_complex_shaper_t _hb_ot_complex_shaper_sea = -{ - "sea", - collect_features_sea, - override_features_sea, - NULL, /* data_create */ - NULL, /* data_destroy */ - NULL, /* preprocess_text */ - HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, - NULL, /* decompose */ - NULL, /* compose */ - setup_masks_sea, - HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, - false, /* fallback_position */ -}; From a08a278b15c7e57a1d0a783f2bc877471b9d8229 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 18:09:40 +0100 Subject: [PATCH 32/43] [USE] Don't compose split matras Same logic as in Indic shaper. --- src/hb-ot-shape-complex-use.cc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index 379eec1bd..208da6209 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -462,6 +462,19 @@ reorder (const hb_ot_shape_plan_t *plan, HB_BUFFER_DEALLOCATE_VAR (buffer, use_category); } +static bool +compose_use (const hb_ot_shape_normalize_context_t *c, + hb_codepoint_t a, + hb_codepoint_t b, + hb_codepoint_t *ab) +{ + /* Avoid recomposing split matras. */ + if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (c->unicode->general_category (a))) + return false; + + return c->unicode->compose (a, b, ab); +} + const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use = { @@ -473,7 +486,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use = NULL, /* preprocess_text */ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, NULL, /* decompose */ - NULL, /* compose */ + compose_use, setup_masks_use, HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ From a51a661fe1dcfdd3a274a6be6ad741c68d430c8c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 21 Jul 2015 18:24:21 +0100 Subject: [PATCH 33/43] [USE] Only reorder the first component of a split left mark --- src/hb-ot-shape-complex-use.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index 208da6209..309f22198 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -364,7 +364,10 @@ reorder_syllable (const hb_ot_shape_plan_t *plan, else j = i; } - else if (((flag) & (FLAG (USE_VPre) | FLAG (USE_VMPre))) && j < i) + else if (((flag) & (FLAG (USE_VPre) | FLAG (USE_VMPre))) && + /* Only move the first component of a MultipleSubst. */ + 0 == _hb_glyph_info_get_lig_comp (&info[i]) && + j < i) { hb_glyph_info_t t = info[i]; memmove (&info[j + 1], &info[j], (i - j) * sizeof (info[0])); From 9daf2dfb6bd5683fd951bdf166c8b87938257e52 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 22 Jul 2015 10:32:30 +0100 Subject: [PATCH 34/43] Add hb-ot-shape-complex-arabic-private.hh --- src/Makefile.am | 1 + src/hb-ot-shape-complex-arabic-private.hh | 50 +++++++++++++++++++++++ src/hb-ot-shape-complex-arabic.cc | 37 ++++++++++------- 3 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 src/hb-ot-shape-complex-arabic-private.hh diff --git a/src/Makefile.am b/src/Makefile.am index 6258dd738..a528c9d63 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -93,6 +93,7 @@ HBSOURCES += \ hb-ot-shape.cc \ hb-ot-shape-complex-arabic.cc \ hb-ot-shape-complex-arabic-fallback.hh \ + hb-ot-shape-complex-arabic-private.hh \ hb-ot-shape-complex-arabic-table.hh \ hb-ot-shape-complex-arabic-win1256.hh \ hb-ot-shape-complex-default.cc \ diff --git a/src/hb-ot-shape-complex-arabic-private.hh b/src/hb-ot-shape-complex-arabic-private.hh new file mode 100644 index 000000000..fcedc7d74 --- /dev/null +++ b/src/hb-ot-shape-complex-arabic-private.hh @@ -0,0 +1,50 @@ +/* + * Copyright © 2015 Mozilla Foundation. + * Copyright © 2015 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. + * + * Mozilla Author(s): Jonathan Kew + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_PRIVATE_HH +#define HB_OT_SHAPE_COMPLEX_ARABIC_PRIVATE_HH + +#include "hb-private.hh" + +#include "hb-ot-shape-complex-private.hh" + + +struct arabic_shape_plan_t; + +HB_INTERNAL void * +data_create_arabic (const hb_ot_shape_plan_t *plan); + +HB_INTERNAL void +data_destroy_arabic (void *data); + +HB_INTERNAL void +setup_masks_arabic_plan (const arabic_shape_plan_t *arabic_plan, + hb_buffer_t *buffer, + hb_script_t script); + +#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_PRIVATE_HH */ diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc index fc8258111..cde02e0a5 100644 --- a/src/hb-ot-shape-complex-arabic.cc +++ b/src/hb-ot-shape-complex-arabic.cc @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#include "hb-ot-shape-complex-private.hh" +#include "hb-ot-shape-complex-arabic-private.hh" #include "hb-ot-shape-private.hh" @@ -32,10 +32,14 @@ #define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */ +/* + * Joining types: + */ + /* * Bits used in the joining tables */ -enum { +enum hb_arabic_joining_type_t { JOINING_TYPE_U = 0, JOINING_TYPE_L = 1, JOINING_TYPE_R = 2, @@ -49,10 +53,6 @@ enum { JOINING_TYPE_X = 8 /* means: use general-category to choose between U or T. */ }; -/* - * Joining types: - */ - #include "hb-ot-shape-complex-arabic-table.hh" static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat) @@ -212,7 +212,7 @@ struct arabic_shape_plan_t arabic_fallback_plan_t *fallback_plan; }; -static void * +void * data_create_arabic (const hb_ot_shape_plan_t *plan) { arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) calloc (1, sizeof (arabic_shape_plan_t)); @@ -230,7 +230,7 @@ data_create_arabic (const hb_ot_shape_plan_t *plan) return arabic_plan; } -static void +void data_destroy_arabic (void *data) { arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) data; @@ -305,17 +305,15 @@ mongolian_variation_selectors (hb_buffer_t *buffer) info[i].arabic_shaping_action() = info[i - 1].arabic_shaping_action(); } -static void -setup_masks_arabic (const hb_ot_shape_plan_t *plan, - hb_buffer_t *buffer, - hb_font_t *font HB_UNUSED) +void +setup_masks_arabic_plan (const arabic_shape_plan_t *arabic_plan, + hb_buffer_t *buffer, + hb_script_t script) { HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action); - const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; - arabic_joining (buffer); - if (plan->props.script == HB_SCRIPT_MONGOLIAN) + if (script == HB_SCRIPT_MONGOLIAN) mongolian_variation_selectors (buffer); unsigned int count = buffer->len; @@ -326,6 +324,15 @@ setup_masks_arabic (const hb_ot_shape_plan_t *plan, HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); } +static void +setup_masks_arabic (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer, + hb_font_t *font HB_UNUSED) +{ + const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; + setup_masks_arabic_plan (arabic_plan, buffer, plan->props.script); +} + static void nuke_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED, From 8ba9e689680f7685c04cfe7c6019222bdf0c52b0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 22 Jul 2015 11:16:01 +0100 Subject: [PATCH 35/43] [USE] Do Arabic-like shaping --- src/hb-ot-shape-complex-use.cc | 77 +++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index 309f22198..b50fc7101 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -27,6 +27,7 @@ */ #include "hb-ot-shape-complex-use-private.hh" +#include "hb-ot-shape-complex-arabic-private.hh" /* buffer var allocations */ #define use_category() complex_var_u8_0() @@ -53,6 +54,19 @@ basic_features[] = HB_TAG('c','j','c','t'), }; static const hb_tag_t +arabic_features[] = +{ + HB_TAG('i','s','o','l'), + HB_TAG('i','n','i','t'), + HB_TAG('m','e','d','i'), + HB_TAG('f','i','n','a'), + /* The spec doesn't specify these but we apply anyway, since our Arabic shaper + * does. These are only used in Syriac spec. */ + HB_TAG('m','e','d','2'), + HB_TAG('f','i','n','2'), + HB_TAG('f','i','n','3'), +}; +static const hb_tag_t other_features[] = { /* @@ -120,7 +134,10 @@ collect_features_use (hb_ot_shape_planner_t *plan) map->add_gsub_pause (reorder); /* "Topographical features" */ - // TODO isol/init/medi/fina + for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++) + map->add_feature (arabic_features[i], 1, F_NONE); + + map->add_gsub_pause (NULL); /* "Standard typographic presentation" and "Positional feature application" */ for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++) @@ -132,8 +149,41 @@ struct use_shape_plan_t ASSERT_POD (); hb_mask_t rphf_mask; + + arabic_shape_plan_t *arabic_plan; }; +static bool +has_arabic_joining (hb_script_t script) +{ + /* List of scripts that have data in arabic-table. */ + switch ((int) script) + { + /* Unicode-1.1 additions */ + case HB_SCRIPT_ARABIC: + + /* Unicode-3.0 additions */ + case HB_SCRIPT_MONGOLIAN: + case HB_SCRIPT_SYRIAC: + + /* Unicode-5.0 additions */ + case HB_SCRIPT_NKO: + case HB_SCRIPT_PHAGS_PA: + + /* Unicode-6.0 additions */ + case HB_SCRIPT_MANDAIC: + + /* Unicode-7.0 additions */ + case HB_SCRIPT_MANICHAEAN: + case HB_SCRIPT_PSALTER_PAHLAVI: + + return true; + + default: + return false; + } +} + static void * data_create_use (const hb_ot_shape_plan_t *plan) { @@ -143,12 +193,27 @@ data_create_use (const hb_ot_shape_plan_t *plan) use_plan->rphf_mask = plan->map.get_1_mask (HB_TAG('r','p','h','f')); + if (has_arabic_joining (plan->props.script)) + { + use_plan->arabic_plan = (arabic_shape_plan_t *) data_create_arabic (plan); + if (unlikely (!use_plan->arabic_plan)) + { + free (use_plan); + return NULL; + } + } + return use_plan; } static void data_destroy_use (void *data) { + use_shape_plan_t *use_plan = (use_shape_plan_t *) data; + + if (use_plan->arabic_plan) + data_destroy_arabic (use_plan->arabic_plan); + free (data); } @@ -175,10 +240,18 @@ set_use_properties (hb_glyph_info_t &info) static void -setup_masks_use (const hb_ot_shape_plan_t *plan HB_UNUSED, +setup_masks_use (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, hb_font_t *font HB_UNUSED) { + const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; + + /* Do this before allocating use_category(). */ + if (use_plan->arabic_plan) + { + setup_masks_arabic_plan (use_plan->arabic_plan, buffer, plan->props.script); + } + HB_BUFFER_ALLOCATE_VAR (buffer, use_category); /* We cannot setup masks here. We save information about characters From ac596511a8c9eeaeb455ca16b5b9c5f1b9923b3a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 22 Jul 2015 11:54:02 +0100 Subject: [PATCH 36/43] Add foreach_syllable Use it in USE. --- src/hb-ot-layout-private.hh | 24 ++++++ src/hb-ot-shape-complex-use.cc | 129 ++++++++++----------------------- 2 files changed, 64 insertions(+), 89 deletions(-) diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index 7a8e2bf30..3a482fff3 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -179,6 +179,30 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout); #define lig_props() var1.u8[2] /* GSUB/GPOS ligature tracking */ #define syllable() var1.u8[3] /* GSUB/GPOS shaping boundaries */ + +/* loop over syllables */ + +#define foreach_syllable(buffer, start, end) \ + for (unsigned int \ + _count = buffer->len, \ + start = 0, end = _count ? _next_syllable (buffer, 0) : 0; \ + start < _count; \ + start = end, end = _next_syllable (buffer, start)) + +static inline unsigned int +_next_syllable (hb_buffer_t *buffer, unsigned int start) +{ + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + + unsigned int syllable = info[start].syllable(); + while (++start < count && syllable == info[start].syllable()) + ; + + return start; +} + + /* unicode_props */ enum { diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index b50fc7101..ba4c04cb3 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -263,16 +263,6 @@ setup_masks_use (const hb_ot_shape_plan_t *plan, info[i].use_category() = hb_use_get_categories (info[i].codepoint); } -static void -setup_syllable (const use_shape_plan_t *use_plan, - hb_glyph_info_t *info, - unsigned int start, unsigned int end) -{ - unsigned int limit = info[start].use_category() == USE_R ? 1 : MIN (3u, end - start); - for (unsigned int i = start; i < start + limit; i++) - info[i].mask |= use_plan->rphf_mask; -} - static void setup_syllables (const hb_ot_shape_plan_t *plan, hb_font_t *font HB_UNUSED, @@ -280,22 +270,21 @@ setup_syllables (const hb_ot_shape_plan_t *plan, { find_syllables (buffer); - /* Setup masks for 'rphf' and 'pref'. */ + /* Setup 'rphf' mask. */ + const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; - if (!use_plan->rphf_mask) return; + + hb_mask_t mask = use_plan->rphf_mask; + if (!mask) return; hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; - if (unlikely (!count)) return; - unsigned int last = 0; - unsigned int last_syllable = info[0].syllable(); - for (unsigned int i = 1; i < count; i++) - if (last_syllable != info[i].syllable()) { - setup_syllable (use_plan, info, last, i); - last = i; - last_syllable = info[last].syllable(); - } - setup_syllable (use_plan, info, last, count); + + foreach_syllable (buffer, start, end) + { + unsigned int limit = info[start].use_category() == USE_R ? 1 : MIN (3u, end - start); + for (unsigned int i = start; i < start + limit; i++) + info[i].mask |= mask; + } } static void @@ -309,56 +298,27 @@ clear_substitution_flags (const hb_ot_shape_plan_t *plan, _hb_glyph_info_clear_substituted_and_ligated_and_multiplied (&info[i]); } -static void -record_rphf_syllable (hb_glyph_info_t *info, - unsigned int start, unsigned int end, - hb_mask_t mask) -{ - /* Mark a substituted repha as USE_R. */ - for (unsigned int i = start; i < end && (info[i].mask & mask); i++) - if (_hb_glyph_info_substituted (&info[i])) - { - /* Found the one. Mark it as Repha. */ - info[i].use_category() = USE_R; - return; - } -} - static void record_rphf (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; - hb_mask_t mask = use_plan->rphf_mask; + hb_mask_t mask = use_plan->rphf_mask; if (!mask) return; hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; - if (unlikely (!count)) return; - unsigned int last = 0; - unsigned int last_syllable = info[0].syllable(); - for (unsigned int i = 1; i < count; i++) - if (last_syllable != info[i].syllable()) { - record_rphf_syllable (info, last, i, mask); - last = i; - last_syllable = info[last].syllable(); - } - record_rphf_syllable (info, last, count, mask); -} -static void -record_pref_syllable (hb_glyph_info_t *info, - unsigned int start, unsigned int end) -{ - /* Mark a substituted pref as VPre, as they behave the same way. */ - for (unsigned int i = start; i < end; i++) - if (_hb_glyph_info_substituted (&info[i])) - { - /* Found the one. Mark it as Repha. */ - info[i].use_category() = USE_VPre; - return; - } + foreach_syllable (buffer, start, end) + { + /* Mark a substituted repha as USE_R. */ + for (unsigned int i = start; i < end && (info[i].mask & mask); i++) + if (_hb_glyph_info_substituted (&info[i])) + { + info[i].use_category() = USE_R; + break; + } + } } static void @@ -367,24 +327,21 @@ record_pref (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer) { hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; - if (unlikely (!count)) return; - unsigned int last = 0; - unsigned int last_syllable = info[0].syllable(); - for (unsigned int i = 1; i < count; i++) - if (last_syllable != info[i].syllable()) { - record_pref_syllable (info, last, i); - last = i; - last_syllable = info[last].syllable(); - } - record_pref_syllable (info, last, count); + + foreach_syllable (buffer, start, end) + { + /* Mark a substituted pref as VPre, as they behave the same way. */ + for (unsigned int i = start; i < end; i++) + if (_hb_glyph_info_substituted (&info[i])) + { + info[i].use_category() = USE_VPre; + break; + } + } } static void -reorder_syllable (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) +reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) { syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F); /* Only a few syllable types need reordering. */ @@ -481,6 +438,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, buffer->clear_output (); buffer->idx = 0; + unsigned int last_syllable = 0; while (buffer->idx < buffer->len) { @@ -519,19 +477,12 @@ reorder (const hb_ot_shape_plan_t *plan, insert_dotted_circles (plan, font, buffer); hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; - if (unlikely (!count)) return; - unsigned int last = 0; - unsigned int last_syllable = info[0].syllable(); - for (unsigned int i = 1; i < count; i++) - if (last_syllable != info[i].syllable()) { - reorder_syllable (plan, font->face, buffer, last, i); - last = i; - last_syllable = info[last].syllable(); - } - reorder_syllable (plan, font->face, buffer, last, count); + + foreach_syllable (buffer, start, end) + reorder_syllable (buffer, start, end); /* Zero syllables now... */ + unsigned int count = buffer->len; for (unsigned int i = 0; i < count; i++) info[i].syllable() = 0; From 56f71ff98890fc4fd13e8d9743dc34c4b9407309 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 22 Jul 2015 11:58:11 +0100 Subject: [PATCH 37/43] Use foreach_syllable in Myanmar shaper --- src/hb-ot-shape-complex-myanmar.cc | 62 ++++++------------------------ 1 file changed, 12 insertions(+), 50 deletions(-) diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc index 29c1ae827..7e3ab01d5 100644 --- a/src/hb-ot-shape-complex-myanmar.cc +++ b/src/hb-ot-shape-complex-myanmar.cc @@ -304,9 +304,7 @@ compare_myanmar_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb) * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm */ static void -initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, +initial_reordering_consonant_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) { hb_glyph_info_t *info = buffer->info; @@ -398,37 +396,6 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_bubble_sort (info + start, end - start, compare_myanmar_order); } -static void -initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) -{ - /* We already inserted dotted-circles, so just call the consonant_syllable. */ - initial_reordering_consonant_syllable (plan, face, buffer, start, end); -} - -static void -initial_reordering_punctuation_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_face_t *face HB_UNUSED, - hb_buffer_t *buffer 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 - * buffer in the reordering process, we'd need to next_glyph() here. */ -} - -static void -initial_reordering_non_myanmar_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_face_t *face HB_UNUSED, - hb_buffer_t *buffer 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 - * buffer in the reordering process, we'd need to next_glyph() here. */ -} - - static void initial_reordering_syllable (const hb_ot_shape_plan_t *plan, hb_face_t *face, @@ -437,10 +404,15 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan, { syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F); switch (syllable_type) { - case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return; - case punctuation_cluster: initial_reordering_punctuation_cluster (plan, face, buffer, start, end); return; - case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return; - case non_myanmar_cluster: initial_reordering_non_myanmar_cluster (plan, face, buffer, start, end); return; + + case broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */ + case consonant_syllable: + initial_reordering_consonant_syllable (buffer, start, end); + break; + + case punctuation_cluster: + case non_myanmar_cluster: + break; } } @@ -505,18 +477,8 @@ initial_reordering (const hb_ot_shape_plan_t *plan, { insert_dotted_circles (plan, font, buffer); - hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; - if (unlikely (!count)) return; - unsigned int last = 0; - unsigned int last_syllable = info[0].syllable(); - for (unsigned int i = 1; i < count; i++) - if (last_syllable != info[i].syllable()) { - initial_reordering_syllable (plan, font->face, buffer, last, i); - last = i; - last_syllable = info[last].syllable(); - } - initial_reordering_syllable (plan, font->face, buffer, last, count); + foreach_syllable (buffer, start, end) + initial_reordering_syllable (plan, font->face, buffer, start, end); } static void From ecb0b24ef3f8177e7c789f45a2e858bd67e31be3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 22 Jul 2015 12:02:09 +0100 Subject: [PATCH 38/43] Use foreach_cluster in Indic shaper --- src/hb-ot-shape-complex-indic.cc | 90 +++++++------------------------- 1 file changed, 19 insertions(+), 71 deletions(-) diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index 1dc84be2e..b7f3d5c66 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -1161,17 +1161,6 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, } } - -static void -initial_reordering_vowel_syllable (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) -{ - /* We made the vowels look like consonants. So let's call the consonant logic! */ - initial_reordering_consonant_syllable (plan, face, buffer, start, end); -} - static void initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan, hb_face_t *face, @@ -1193,37 +1182,6 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan, initial_reordering_consonant_syllable (plan, face, buffer, start, end); } -static void -initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) -{ - /* We already inserted dotted-circles, so just call the standalone_cluster. */ - initial_reordering_standalone_cluster (plan, face, buffer, start, end); -} - -static void -initial_reordering_symbol_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_face_t *face HB_UNUSED, - hb_buffer_t *buffer 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 - * buffer in the reordering process, we'd need to next_glyph() here. */ -} - -static void -initial_reordering_non_indic_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_face_t *face HB_UNUSED, - hb_buffer_t *buffer 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 - * buffer in the reordering process, we'd need to next_glyph() here. */ -} - - static void initial_reordering_syllable (const hb_ot_shape_plan_t *plan, hb_face_t *face, @@ -1231,13 +1189,21 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan, unsigned int start, unsigned int end) { syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F); - switch (syllable_type) { - 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 standalone_cluster: initial_reordering_standalone_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 non_indic_cluster: initial_reordering_non_indic_cluster (plan, face, buffer, start, end); return; + switch (syllable_type) + { + case vowel_syllable: /* We made the vowels look like consonants. So let's call the consonant logic! */ + case consonant_syllable: + initial_reordering_consonant_syllable (plan, face, buffer, start, end); + break; + + case broken_cluster: /* We already inserted dotted-circles, so just call the standalone_cluster. */ + case standalone_cluster: + initial_reordering_standalone_cluster (plan, face, buffer, start, end); + break; + + case symbol_cluster: + case non_indic_cluster: + break; } } @@ -1310,18 +1276,8 @@ initial_reordering (const hb_ot_shape_plan_t *plan, update_consonant_positions (plan, font, buffer); insert_dotted_circles (plan, font, buffer); - hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; - if (unlikely (!count)) return; - unsigned int last = 0; - unsigned int last_syllable = info[0].syllable(); - for (unsigned int i = 1; i < count; i++) - if (last_syllable != info[i].syllable()) { - initial_reordering_syllable (plan, font->face, buffer, last, i); - last = i; - last_syllable = info[last].syllable(); - } - initial_reordering_syllable (plan, font->face, buffer, last, count); + foreach_syllable (buffer, start, end) + initial_reordering_syllable (plan, font->face, buffer, start, end); } static void @@ -1737,16 +1693,8 @@ final_reordering (const hb_ot_shape_plan_t *plan, unsigned int count = buffer->len; if (unlikely (!count)) return; - hb_glyph_info_t *info = buffer->info; - unsigned int last = 0; - unsigned int last_syllable = info[0].syllable(); - for (unsigned int i = 1; i < count; i++) - if (last_syllable != info[i].syllable()) { - final_reordering_syllable (plan, buffer, last, i); - last = i; - last_syllable = info[last].syllable(); - } - final_reordering_syllable (plan, buffer, last, count); + foreach_syllable (buffer, start, end) + final_reordering_syllable (plan, buffer, start, end); HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category); HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position); From 9cd59db1af47ff511edf251949d58b82673cf704 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 22 Jul 2015 13:27:06 +0100 Subject: [PATCH 39/43] [USE] Implement topographical features for non-Arabic-joining scripts This works per-syllable as per the spec, but we think it should be per spacing/base/??? glyph instead. --- src/hb-ot-shape-complex-use.cc | 87 +++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 7 deletions(-) diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index ba4c04cb3..4b84bd750 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -66,6 +66,14 @@ arabic_features[] = HB_TAG('f','i','n','2'), HB_TAG('f','i','n','3'), }; +/* Same order as arabic_features. Don't need Syriac stuff.*/ +enum joining_form_t { + ISOL, + INIT, + MEDI, + FINA, + _NONE +}; static const hb_tag_t other_features[] = { @@ -136,7 +144,6 @@ collect_features_use (hb_ot_shape_planner_t *plan) /* "Topographical features" */ for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++) map->add_feature (arabic_features[i], 1, F_NONE); - map->add_gsub_pause (NULL); /* "Standard typographic presentation" and "Positional feature application" */ @@ -264,14 +271,9 @@ setup_masks_use (const hb_ot_shape_plan_t *plan, } static void -setup_syllables (const hb_ot_shape_plan_t *plan, - hb_font_t *font HB_UNUSED, +setup_rphf_mask (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer) { - find_syllables (buffer); - - /* Setup 'rphf' mask. */ - const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; hb_mask_t mask = use_plan->rphf_mask; @@ -287,6 +289,77 @@ setup_syllables (const hb_ot_shape_plan_t *plan, } } +static void +setup_topographical_masks (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer) +{ + + ASSERT_STATIC (INIT < 4 && ISOL < 4 && MEDI < 4 && FINA < 4); + hb_mask_t masks[4], all_masks = 0; + for (unsigned int i = 0; i < 4; i++) + { + masks[i] = plan->map.get_1_mask (arabic_features[i]); + if (masks[i] == plan->map.get_global_mask ()) + masks[i] = 0; + all_masks |= masks[i]; + } + if (!all_masks) + return; + hb_mask_t other_masks = ~all_masks; + + unsigned int last_start = 0; + joining_form_t last_form = _NONE; + hb_glyph_info_t *info = buffer->info; + foreach_syllable (buffer, start, end) + { + syllable_type_t syllable_type = (syllable_type_t) (info[start].syllable() & 0x0F); + switch (syllable_type) + { + case independent_cluster: + case symbol_cluster: + /* These don't join. Nothing to do. */ + last_form = _NONE; + break; + + case virama_terminated_cluster: + case consonant_cluster: + case vowel_cluster: + case number_joiner_terminated_cluster: + case numeral_cluster: + case broken_cluster: + + bool join = last_form == FINA || last_form == ISOL; + + if (join) + { + /* Fixup previous syllable's form. */ + last_form = last_form == FINA ? MEDI : INIT; + for (unsigned int i = last_start; i < start; i++) + info[i].mask = (info[i].mask & other_masks) | masks[last_form]; + } + + /* Form for this syllable. */ + last_form = join ? FINA : ISOL; + for (unsigned int i = start; i < end; i++) + info[i].mask = (info[i].mask & other_masks) | masks[last_form]; + + break; + } + + last_start = start; + } +} + +static void +setup_syllables (const hb_ot_shape_plan_t *plan, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) +{ + find_syllables (buffer); + setup_rphf_mask (plan, buffer); + setup_topographical_masks (plan, buffer); +} + static void clear_substitution_flags (const hb_ot_shape_plan_t *plan, hb_font_t *font HB_UNUSED, From 67ba7320cc5545baeacfcff64cea338223b9bd6d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 23 Jul 2015 12:58:21 +0100 Subject: [PATCH 40/43] [test] Remove New Tai Lue texts New Tai Lue changed encoding to visual, boring, model. --- test/shaping/texts/in-tree/shaper-sea/MANIFEST | 1 - .../shaping/texts/in-tree/shaper-sea/script-new-tai-lue/MANIFEST | 1 - .../texts/in-tree/shaper-sea/script-new-tai-lue/misc/MANIFEST | 1 - .../texts/in-tree/shaper-sea/script-new-tai-lue/misc/misc.txt | 1 - 4 files changed, 4 deletions(-) delete mode 100644 test/shaping/texts/in-tree/shaper-sea/script-new-tai-lue/MANIFEST delete mode 100644 test/shaping/texts/in-tree/shaper-sea/script-new-tai-lue/misc/MANIFEST delete mode 100644 test/shaping/texts/in-tree/shaper-sea/script-new-tai-lue/misc/misc.txt diff --git a/test/shaping/texts/in-tree/shaper-sea/MANIFEST b/test/shaping/texts/in-tree/shaper-sea/MANIFEST index ba95488bd..359b7785b 100644 --- a/test/shaping/texts/in-tree/shaper-sea/MANIFEST +++ b/test/shaping/texts/in-tree/shaper-sea/MANIFEST @@ -1,3 +1,2 @@ script-cham -script-new-tai-lue script-tai-tham diff --git a/test/shaping/texts/in-tree/shaper-sea/script-new-tai-lue/MANIFEST b/test/shaping/texts/in-tree/shaper-sea/script-new-tai-lue/MANIFEST deleted file mode 100644 index b8752e7b9..000000000 --- a/test/shaping/texts/in-tree/shaper-sea/script-new-tai-lue/MANIFEST +++ /dev/null @@ -1 +0,0 @@ -misc diff --git a/test/shaping/texts/in-tree/shaper-sea/script-new-tai-lue/misc/MANIFEST b/test/shaping/texts/in-tree/shaper-sea/script-new-tai-lue/misc/MANIFEST deleted file mode 100644 index 29cfb2f28..000000000 --- a/test/shaping/texts/in-tree/shaper-sea/script-new-tai-lue/misc/MANIFEST +++ /dev/null @@ -1 +0,0 @@ -misc.txt diff --git a/test/shaping/texts/in-tree/shaper-sea/script-new-tai-lue/misc/misc.txt b/test/shaping/texts/in-tree/shaper-sea/script-new-tai-lue/misc/misc.txt deleted file mode 100644 index 11224a10b..000000000 --- a/test/shaping/texts/in-tree/shaper-sea/script-new-tai-lue/misc/misc.txt +++ /dev/null @@ -1 +0,0 @@ -ᦀᦷᧃᧈ From b8c159ffccad090974a2b97be0a0140fa09af132 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 23 Jul 2015 12:59:17 +0100 Subject: [PATCH 41/43] [test] Remove shaper-sea texts under shaper-use --- test/shaping/texts/in-tree/MANIFEST | 1 - test/shaping/texts/in-tree/shaper-sea/MANIFEST | 2 -- test/shaping/texts/in-tree/shaper-sea/script-cham/MANIFEST | 1 - test/shaping/texts/in-tree/shaper-sea/script-tai-tham/MANIFEST | 1 - test/shaping/texts/in-tree/shaper-use/MANIFEST | 2 ++ .../script-cham/misc => shaper-use/script-cham}/MANIFEST | 0 .../script-cham/misc => shaper-use/script-cham}/misc.txt | 0 .../misc => shaper-use/script-tai-tham}/MANIFEST | 0 .../misc => shaper-use/script-tai-tham}/misc.txt | 0 .../misc => shaper-use/script-tai-tham}/torture.txt | 0 10 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 test/shaping/texts/in-tree/shaper-sea/MANIFEST delete mode 100644 test/shaping/texts/in-tree/shaper-sea/script-cham/MANIFEST delete mode 100644 test/shaping/texts/in-tree/shaper-sea/script-tai-tham/MANIFEST rename test/shaping/texts/in-tree/{shaper-sea/script-cham/misc => shaper-use/script-cham}/MANIFEST (100%) rename test/shaping/texts/in-tree/{shaper-sea/script-cham/misc => shaper-use/script-cham}/misc.txt (100%) rename test/shaping/texts/in-tree/{shaper-sea/script-tai-tham/misc => shaper-use/script-tai-tham}/MANIFEST (100%) rename test/shaping/texts/in-tree/{shaper-sea/script-tai-tham/misc => shaper-use/script-tai-tham}/misc.txt (100%) rename test/shaping/texts/in-tree/{shaper-sea/script-tai-tham/misc => shaper-use/script-tai-tham}/torture.txt (100%) diff --git a/test/shaping/texts/in-tree/MANIFEST b/test/shaping/texts/in-tree/MANIFEST index 5733ddfdd..5739730d6 100644 --- a/test/shaping/texts/in-tree/MANIFEST +++ b/test/shaping/texts/in-tree/MANIFEST @@ -4,7 +4,6 @@ shaper-hangul shaper-hebrew shaper-indic shaper-myanmar -shaper-sea shaper-thai shaper-tibetan shaper-use diff --git a/test/shaping/texts/in-tree/shaper-sea/MANIFEST b/test/shaping/texts/in-tree/shaper-sea/MANIFEST deleted file mode 100644 index 359b7785b..000000000 --- a/test/shaping/texts/in-tree/shaper-sea/MANIFEST +++ /dev/null @@ -1,2 +0,0 @@ -script-cham -script-tai-tham diff --git a/test/shaping/texts/in-tree/shaper-sea/script-cham/MANIFEST b/test/shaping/texts/in-tree/shaper-sea/script-cham/MANIFEST deleted file mode 100644 index b8752e7b9..000000000 --- a/test/shaping/texts/in-tree/shaper-sea/script-cham/MANIFEST +++ /dev/null @@ -1 +0,0 @@ -misc diff --git a/test/shaping/texts/in-tree/shaper-sea/script-tai-tham/MANIFEST b/test/shaping/texts/in-tree/shaper-sea/script-tai-tham/MANIFEST deleted file mode 100644 index b8752e7b9..000000000 --- a/test/shaping/texts/in-tree/shaper-sea/script-tai-tham/MANIFEST +++ /dev/null @@ -1 +0,0 @@ -misc diff --git a/test/shaping/texts/in-tree/shaper-use/MANIFEST b/test/shaping/texts/in-tree/shaper-use/MANIFEST index 88e14954f..d4a310e70 100644 --- a/test/shaping/texts/in-tree/shaper-use/MANIFEST +++ b/test/shaping/texts/in-tree/shaper-use/MANIFEST @@ -1 +1,3 @@ +script-cham script-kharoshti +script-tai-tham diff --git a/test/shaping/texts/in-tree/shaper-sea/script-cham/misc/MANIFEST b/test/shaping/texts/in-tree/shaper-use/script-cham/MANIFEST similarity index 100% rename from test/shaping/texts/in-tree/shaper-sea/script-cham/misc/MANIFEST rename to test/shaping/texts/in-tree/shaper-use/script-cham/MANIFEST diff --git a/test/shaping/texts/in-tree/shaper-sea/script-cham/misc/misc.txt b/test/shaping/texts/in-tree/shaper-use/script-cham/misc.txt similarity index 100% rename from test/shaping/texts/in-tree/shaper-sea/script-cham/misc/misc.txt rename to test/shaping/texts/in-tree/shaper-use/script-cham/misc.txt diff --git a/test/shaping/texts/in-tree/shaper-sea/script-tai-tham/misc/MANIFEST b/test/shaping/texts/in-tree/shaper-use/script-tai-tham/MANIFEST similarity index 100% rename from test/shaping/texts/in-tree/shaper-sea/script-tai-tham/misc/MANIFEST rename to test/shaping/texts/in-tree/shaper-use/script-tai-tham/MANIFEST diff --git a/test/shaping/texts/in-tree/shaper-sea/script-tai-tham/misc/misc.txt b/test/shaping/texts/in-tree/shaper-use/script-tai-tham/misc.txt similarity index 100% rename from test/shaping/texts/in-tree/shaper-sea/script-tai-tham/misc/misc.txt rename to test/shaping/texts/in-tree/shaper-use/script-tai-tham/misc.txt diff --git a/test/shaping/texts/in-tree/shaper-sea/script-tai-tham/misc/torture.txt b/test/shaping/texts/in-tree/shaper-use/script-tai-tham/torture.txt similarity index 100% rename from test/shaping/texts/in-tree/shaper-sea/script-tai-tham/misc/torture.txt rename to test/shaping/texts/in-tree/shaper-use/script-tai-tham/torture.txt From b4231255032e243153a6f32cf8c93c158cb0bf6a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 23 Jul 2015 13:01:55 +0100 Subject: [PATCH 42/43] [test] Add Batak and Buginese test texts --- .../shaping/texts/in-tree/shaper-use/MANIFEST | 2 + .../in-tree/shaper-use/script-batak/MANIFEST | 1 + .../in-tree/shaper-use/script-batak/misc.txt | 9 +++ .../shaper-use/script-buginese/MANIFEST | 1 + .../shaper-use/script-buginese/misc.txt | 70 +++++++++++++++++++ 5 files changed, 83 insertions(+) create mode 100644 test/shaping/texts/in-tree/shaper-use/script-batak/MANIFEST create mode 100644 test/shaping/texts/in-tree/shaper-use/script-batak/misc.txt create mode 100644 test/shaping/texts/in-tree/shaper-use/script-buginese/MANIFEST create mode 100644 test/shaping/texts/in-tree/shaper-use/script-buginese/misc.txt diff --git a/test/shaping/texts/in-tree/shaper-use/MANIFEST b/test/shaping/texts/in-tree/shaper-use/MANIFEST index d4a310e70..51903a765 100644 --- a/test/shaping/texts/in-tree/shaper-use/MANIFEST +++ b/test/shaping/texts/in-tree/shaper-use/MANIFEST @@ -1,3 +1,5 @@ +script-batak +script-buginese script-cham script-kharoshti script-tai-tham diff --git a/test/shaping/texts/in-tree/shaper-use/script-batak/MANIFEST b/test/shaping/texts/in-tree/shaper-use/script-batak/MANIFEST new file mode 100644 index 000000000..29cfb2f28 --- /dev/null +++ b/test/shaping/texts/in-tree/shaper-use/script-batak/MANIFEST @@ -0,0 +1 @@ +misc.txt diff --git a/test/shaping/texts/in-tree/shaper-use/script-batak/misc.txt b/test/shaping/texts/in-tree/shaper-use/script-batak/misc.txt new file mode 100644 index 000000000..c8ae04bc9 --- /dev/null +++ b/test/shaping/texts/in-tree/shaper-use/script-batak/misc.txt @@ -0,0 +1,9 @@ +ᯂᯩ +ᯄ᯦ᯩ +ᯇᯪᯰ +ᯓᯩᯰ +ᯄᯮ +ᯃᯮ +ᯎᯮ +ᯞᯮ +ᯖᯪᯇ᯲ diff --git a/test/shaping/texts/in-tree/shaper-use/script-buginese/MANIFEST b/test/shaping/texts/in-tree/shaper-use/script-buginese/MANIFEST new file mode 100644 index 000000000..29cfb2f28 --- /dev/null +++ b/test/shaping/texts/in-tree/shaper-use/script-buginese/MANIFEST @@ -0,0 +1 @@ +misc.txt diff --git a/test/shaping/texts/in-tree/shaper-use/script-buginese/misc.txt b/test/shaping/texts/in-tree/shaper-use/script-buginese/misc.txt new file mode 100644 index 000000000..fe1b76dd4 --- /dev/null +++ b/test/shaping/texts/in-tree/shaper-use/script-buginese/misc.txt @@ -0,0 +1,70 @@ +ᨒᨚᨈᨑ +ᨔᨑ +ᨅᨔ ᨈᨚ ᨅᨙᨀ +ᨕᨒᨚ ᨆᨒᨗᨕᨘ ᨅᨛᨈᨘᨕᨊ +ᨕᨗᨉᨚ ᨔᨘᨑᨛ +ᨕᨗᨊ ᨔᨘᨑᨛ +ᨕᨊ ᨔᨘᨑᨛ + +ᨊᨀᨚ ᨕᨛᨃ ᨈᨕᨘᨄᨔᨒ᨞ ᨕᨍ ᨆᨘᨄᨈᨒᨒᨚᨓᨗ ᨄᨌᨒᨆᨘ ᨑᨗᨈᨚᨄᨔᨒᨕᨙ᨞ +ᨄᨔᨗᨈᨘᨍᨘᨓᨗᨆᨘᨈᨚᨓᨗᨔ ᨕᨔᨒᨊ ᨄᨌᨒᨆᨘ᨞ ᨕᨄ ᨕᨗᨀᨚᨊᨈᨘ ᨊᨁᨗᨒᨗ ᨉᨙᨓᨈᨕᨙ᨞ +ᨊᨀᨚ ᨅᨕᨗᨌᨘᨆᨘᨄᨗ ᨕᨔᨒᨊ ᨈᨕᨘᨓᨙ᨞ ᨆᨘᨄᨙᨑᨍᨕᨗᨔ ᨄᨉᨈᨚᨓᨗ᨞ +ᨊᨀᨚ ᨄᨔᨒᨕᨗ ᨈᨕᨘᨓᨙ᨞ ᨕᨍ ᨈᨗᨆᨘᨌᨒᨕᨗ ᨑᨗᨔᨗᨈᨗᨊᨍᨊᨕᨙᨈᨚᨔ ᨕᨔᨒᨊ᨞ + +ᨕᨛᨛᨃ ᨕᨛᨃ ᨄ ᨙᨑ᨞ ᨕᨛᨃ ᨙᨔᨕᨘᨓ ᨓᨛᨈᨘ᨞ +ᨕᨛᨃ ᨙᨔᨕᨘᨓ ᨕᨑᨘ ᨆᨀᨘᨋᨕᨗ ᨑᨗ ᨒᨘᨓᨘ᨞ ᨆᨔᨒ ᨕᨘᨒᨗ᨞ + +ᨄᨘᨑᨊᨗᨀᨚ ᨆᨙᨋ? +ᨉᨙᨄ + +ᨆᨙᨒᨚ ᨀ ᨌᨛᨙᨆ +ᨔᨙᨉᨗ +ᨉᨘᨓ +ᨈᨛᨒᨘ +ᨕᨛᨄ +ᨒᨗᨆ +ᨕᨛᨊᨛ +ᨄᨗᨈᨘ +ᨕᨑᨘᨓ +ᨕᨙᨔᨑ +ᨔᨄᨘᨒᨚ +ᨉᨘᨓᨄᨘᨒᨚ +ᨈᨛᨒᨘᨄᨘᨒᨚ +ᨄᨈᨄᨘᨒᨚ +ᨒᨗᨆᨄᨘᨒᨚ +ᨕᨛᨊᨛᨄᨘᨒᨚᨊ +ᨄᨗᨈᨘᨄᨘᨒᨚ +ᨕᨑᨘᨓᨄᨘᨒᨚᨊ +ᨕᨙᨔᨑᨄᨘᨒᨚᨊ +ᨔᨗᨑᨈᨘ +ᨔᨗᨔᨛᨅᨘ +ᨔᨗᨒᨔ +ᨔᨗᨀᨚᨈᨗ + +ᨅᨔ ᨕᨘᨁᨗ + +ᨅᨔ ᨆᨀᨔᨑ +ᨅᨒ +ᨅᨚᨒᨚ +ᨅᨅ +ᨌᨗᨄᨘᨑᨘ +ᨉᨚᨕᨙ +ᨕᨗᨐᨚ +ᨒᨚᨄᨚ +ᨔᨒᨚ +ᨈ ᨅᨙᨙ +ᨈᨙᨊ +ᨀᨑᨕᨙ +ᨕᨄ ᨀᨑᨙᨅ? +ᨒᨀᨙᨀᨚ ᨆᨕᨙ? +ᨅᨒ +ᨅᨚᨈᨚ +ᨑᨈᨔ +ᨅᨈᨒ +ᨅᨗᨒ +ᨁᨙᨒᨙ ᨁᨙᨒᨙ +ᨀᨚᨀᨚ +ᨍᨑ +ᨅᨙᨅᨙ +ᨆᨚᨈᨙᨑᨙ +ᨂᨑᨙ From 786ba45847127b9cd4d9c0c01ae0e6c61f3a8e06 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 23 Jul 2015 13:04:34 +0100 Subject: [PATCH 43/43] [test] Encode Kharoshti text Ouch! --- .../shaper-use/script-kharoshti/misc.txt | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/test/shaping/texts/in-tree/shaper-use/script-kharoshti/misc.txt b/test/shaping/texts/in-tree/shaper-use/script-kharoshti/misc.txt index 0a8d5229e..5a563c170 100644 --- a/test/shaping/texts/in-tree/shaper-use/script-kharoshti/misc.txt +++ b/test/shaping/texts/in-tree/shaper-use/script-kharoshti/misc.txt @@ -1,36 +1,36 @@ -10a24 10a2a 10a0c 10a2a 10a3f 10a17 10a38 10a05 10a0c 10a0f -10a00 10a01 -10a10 10a01 -10a20 10a01 -10a00 10a02 -10a31 10a02 -10a28 10a02 -10a00 10a03 -10a28 10a03 -10a00 10a05 -10a10 10a05 -10a20 10a05 -10a21 10a05 -10a00 10a06 -10a24 10a06 -10a28 10a0c -10a2f 10a0d -10a00 10a0e -10a10 10a0f -10a17 10a38 -10a12 10a39 -10a28 10a3a -10a22 10a01 10a10 10a3f -10a10 10a3f 10a2e -10a28 10a3f 10a2a -10a2c 10a3f 10a31 -10a2f 10a3f 10a1f -10a2f 10a3f 10a29 -10a2a 10a3f 10a1f -10a1f 10a3f 10a2a -10a2b 10a3f 10a24 -10a24 10a3f 10a2b -10a10 10a3f 10a2b -10a1f 10a3f 10a2c -10a10 10a3f 10a1f -10a11 10a3f 10a10 10a3f 10a2e +𐨤𐨪𐨌𐨪𐨿𐨗𐨸𐨅𐨌𐨏 +𐨀𐨁 +𐨐𐨁 +𐨠𐨁 +𐨀𐨂 +𐨱𐨂 +𐨨𐨂 +𐨀𐨃 +𐨨𐨃 +𐨀𐨅 +𐨐𐨅 +𐨠𐨅 +𐨡𐨅 +𐨀𐨆 +𐨤𐨆 +𐨨𐨌 +𐨯𐨍 +𐨀𐨎 +𐨐𐨏 +𐨗𐨸 +𐨒𐨹 +𐨨𐨺 +𐨢𐨁𐨐𐨿 +𐨐𐨿𐨮 +𐨨𐨿𐨪 +𐨬𐨿𐨱 +𐨯𐨿𐨟 +𐨯𐨿𐨩 +𐨪𐨿𐨟 +𐨟𐨿𐨪 +𐨫𐨿𐨤 +𐨤𐨿𐨫 +𐨐𐨿𐨫 +𐨟𐨿𐨬 +𐨐𐨿𐨟 +𐨑𐨿𐨐𐨿𐨮