From 9ae156b76820d9079bae062e7e38c34a386d9bd2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 5 Jul 2015 22:43:17 +0100 Subject: [PATCH 01/77] Fix pragma usage https://bugs.freedesktop.org/show_bug.cgi?id=91228 Commit cdcdfe61b97a0a48ccf834b6d924d187da9609be changed two `#pragma message` to `#pragma error` in hb-unicode.cc, however MSVC uses #error, just like the #else branch. `#pragma error` is an unknown pragma so MSVC does not fail the build because of it, which I believe was the intention of that commit. If it's meant to be an #error, then the #ifdef for _MSC_VER can be removed entirely. --- src/hb-unicode.cc | 5 ----- src/hb-warning.cc | 10 ---------- 2 files changed, 15 deletions(-) diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc index cf2032fd6..6b32faf66 100644 --- a/src/hb-unicode.cc +++ b/src/hb-unicode.cc @@ -146,14 +146,9 @@ hb_unicode_funcs_get_default (void) } #if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL) -#ifdef _MSC_VER -#pragma error("Could not find any Unicode functions implementation, you have to provide your own.") -#pragma error("Consider building hb-ucdn.c. If you absolutely want to build without any, check the code.") -#else #error "Could not find any Unicode functions implementation, you have to provide your own" #error "Consider building hb-ucdn.c. If you absolutely want to build without any, check the code." #endif -#endif /** * hb_unicode_funcs_create: (Xconstructor) diff --git a/src/hb-warning.cc b/src/hb-warning.cc index e69fff234..8f322bcb1 100644 --- a/src/hb-warning.cc +++ b/src/hb-warning.cc @@ -29,21 +29,11 @@ #if defined(HB_ATOMIC_INT_NIL) -#ifdef _MSC_VER -#pragma error("Could not find any system to define atomic_int macros, library WILL NOT be thread-safe") -#pragma error("Check hb-atomic-private.hh for possible resolutions.") -#else #error "Could not find any system to define atomic_int macros, library WILL NOT be thread-safe" #error "Check hb-atomic-private.hh for possible resolutions." #endif -#endif #if defined(HB_MUTEX_IMPL_NIL) -#ifdef _MSC_VER -#pragma error("Could not find any system to define mutex macros, library WILL NOT be thread-safe") -#pragma error("Check hb-mutex-private.hh for possible resolutions.") -#else #error "Could not find any system to define mutex macros, library WILL NOT be thread-safe" #error "Check hb-mutex-private.hh for possible resolutions." #endif -#endif From 64a2726e2c6efce4379a7609024ec21eb4b5e4dc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 15 Jul 2015 01:36:39 +0100 Subject: [PATCH 02/77] Add Unicode 8.0 scripts Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1183209 --- src/hb-common.cc | 3 +++ src/hb-common.h | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/src/hb-common.cc b/src/hb-common.cc index 21d3b4117..d510c9be4 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -493,6 +493,9 @@ hb_script_get_horizontal_direction (hb_script_t script) case HB_SCRIPT_PALMYRENE: case HB_SCRIPT_PSALTER_PAHLAVI: + /* Unicode-8.0 additions */ + case HB_SCRIPT_OLD_HUNGARIAN: + return HB_DIRECTION_RTL; } diff --git a/src/hb-common.h b/src/hb-common.h index b6ce3f724..d160be5ca 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -296,6 +296,13 @@ typedef enum /*7.0*/ HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'), /*7.0*/ HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'), + /*8.0*/ HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'), + /*8.0*/ HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'), + /*8.0*/ HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'), + /*8.0*/ HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'), + /*8.0*/ HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'), + /*8.0*/ HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'), + /* No script set. */ HB_SCRIPT_INVALID = HB_TAG_NONE, From 41a29af8053782e3a9c6a96a394bd76ef6d42099 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 15 Jul 2015 01:39:57 +0100 Subject: [PATCH 03/77] Update Arabic shaping table for Unicode 8.0 --- src/hb-ot-shape-complex-arabic-table.hh | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/hb-ot-shape-complex-arabic-table.hh b/src/hb-ot-shape-complex-arabic-table.hh index 17100497e..80d504435 100644 --- a/src/hb-ot-shape-complex-arabic-table.hh +++ b/src/hb-ot-shape-complex-arabic-table.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-7.0.0.txt - * # Date: 2014-02-14, 21:00:00 GMT [RP, KW, LI] - * # Blocks-7.0.0.txt - * # Date: 2014-04-03, 23:23:00 GMT [RP, KW] + * # ArabicShaping-8.0.0.txt + * # Date: 2015-02-17, 23:33:00 GMT [RP] + * # Blocks-8.0.0.txt + * # Date: 2014-11-10, 23:04:00 GMT [KW] * UnicodeData.txt does not have a header. */ @@ -76,9 +76,9 @@ static const uint8_t joining_table[] = /* Arabic Extended-A */ - /* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R, + /* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R,D,D, -#define joining_offset_0x1806u 691 +#define joining_offset_0x1806u 693 /* Mongolian */ @@ -89,40 +89,40 @@ static const uint8_t joining_table[] = /* 1880 */ U,U,U,U,U,U,U,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, /* 18A0 */ D,D,D,D,D,D,D,D,D,X,D, -#define joining_offset_0x200cu 856 +#define joining_offset_0x200cu 858 /* General Punctuation */ /* 2000 */ U,C, -#define joining_offset_0x2066u 858 +#define joining_offset_0x2066u 860 /* General Punctuation */ /* 2060 */ U,U,U,U, -#define joining_offset_0xa840u 862 +#define joining_offset_0xa840u 864 /* Phags-pa */ /* A840 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, /* A860 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,L,U, -#define joining_offset_0x10ac0u 914 +#define joining_offset_0x10ac0u 916 /* Manichaean */ /* 10AC0 */ D,D,D,D,D,R,U,R,U,R,R,U,U,L,R,R,R,R,R,D,D,D,D,L,D,D,D,D,D,R,D,D, /* 10AE0 */ D,R,U,U,R,X,X,X,X,X,X,D,D,D,D,R, -#define joining_offset_0x10b80u 962 +#define joining_offset_0x10b80u 964 /* Psalter Pahlavi */ /* 10B80 */ D,R,D,R,R,R,D,D,D,R,D,D,R,D,R,R,D,R,X,X,X,X,X,X,X,X,X,X,X,X,X,X, /* 10BA0 */ X,X,X,X,X,X,X,X,X,R,R,R,R,D,D,U, -}; /* Table items: 1010; occupancy: 57% */ +}; /* Table items: 1012; occupancy: 57% */ static unsigned int @@ -131,7 +131,7 @@ joining_type (hb_codepoint_t u) switch (u >> 12) { case 0x0u: - if (hb_in_range (u, 0x0600u, 0x08B2u)) return joining_table[u - 0x0600u + joining_offset_0x0600u]; + if (hb_in_range (u, 0x0600u, 0x08B4u)) return joining_table[u - 0x0600u + joining_offset_0x0600u]; break; case 0x1u: From e2c95116e1423f83a692d6170553d0cc95733d24 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 20 Jul 2015 11:32:48 +0100 Subject: [PATCH 04/77] [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 05/77] [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 06/77] [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 07/77] [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 08/77] 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 09/77] [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 10/77] [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 11/77] [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 12/77] [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 13/77] [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 14/77] [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 15/77] [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 16/77] [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 17/77] [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 18/77] [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 19/77] [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 20/77] [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 21/77] 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 22/77] 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 23/77] 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 24/77] 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 25/77] 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 26/77] [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 27/77] [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 28/77] [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 29/77] [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 30/77] [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 31/77] 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 32/77] [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 33/77] 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 34/77] 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 35/77] [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 36/77] [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 37/77] 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 38/77] [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 39/77] 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 40/77] 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 41/77] 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 42/77] [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 ea7f8414e34d4b5efc7b98974637c08f75440f0e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 22 Jul 2015 13:53:45 +0100 Subject: [PATCH 43/77] [graphite2] Enlarge buffer for output glyphs! --- src/hb-graphite2.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc index 807c33087..26619e1ce 100644 --- a/src/hb-graphite2.cc +++ b/src/hb-graphite2.cc @@ -269,6 +269,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, gr_seg_destroy (seg); return false; } + buffer->ensure (glyph_count); scratch = buffer->get_scratch_buffer (&scratch_size); while ((DIV_CEIL (sizeof (hb_graphite2_cluster_t) * buffer->len, sizeof (*scratch)) + From 97d7c3a100e2673279f066540229d229aaf0df78 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 22 Jul 2015 14:28:25 +0100 Subject: [PATCH 44/77] [graphite2] Fix bunch of stuff Based on patch from Martin Hosken, with review from Jonathan and I. --- src/hb-graphite2.cc | 82 +++++++++++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 28 deletions(-) diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc index 26619e1ce..626b84f4e 100644 --- a/src/hb-graphite2.cc +++ b/src/hb-graphite2.cc @@ -228,12 +228,11 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, int lang_len = lang_end ? lang_end - lang : -1; gr_feature_val *feats = gr_face_featureval_for_lang (grface, lang ? hb_tag_from_string (lang, lang_len) : 0); - while (num_features--) + for (unsigned int i = 0; i < num_features; i++) { - const gr_feature_ref *fref = gr_face_find_fref (grface, features->tag); + const gr_feature_ref *fref = gr_face_find_fref (grface, features[i].tag); if (fref) - gr_fref_set_feature_value (fref, features->value, feats); - features++; + gr_fref_set_feature_value (fref, features[i].value, feats); } gr_segment *seg = NULL; @@ -249,6 +248,8 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, for (unsigned int i = 0; i < buffer->len; ++i) chars[i] = buffer->info[i].codepoint; + /* TODO ensure_native_direction. */ + hb_tag_t script_tag[2]; hb_ot_tags_from_script (hb_buffer_get_script (buffer), &script_tag[0], &script_tag[1]); @@ -267,10 +268,11 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, if (unlikely (!glyph_count)) { if (feats) gr_featureval_destroy (feats); gr_seg_destroy (seg); - return false; + buffer->len = 0; + return true; } - buffer->ensure (glyph_count); + buffer->ensure (glyph_count); scratch = buffer->get_scratch_buffer (&scratch_size); while ((DIV_CEIL (sizeof (hb_graphite2_cluster_t) * buffer->len, sizeof (*scratch)) + DIV_CEIL (sizeof (hb_codepoint_t) * glyph_count, sizeof (*scratch))) > scratch_size) @@ -332,7 +334,6 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, } ci++; - //buffer->clear_output (); for (unsigned int i = 0; i < ci; ++i) { for (unsigned int j = 0; j < clusters[i].num_glyphs; ++j) @@ -343,32 +344,57 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan, } } buffer->len = glyph_count; - //buffer->swap_buffers (); - if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction)) - curradvx = gr_seg_advance_X(seg); - - hb_glyph_position_t *pPos; - for (pPos = hb_buffer_get_glyph_positions (buffer, NULL), is = gr_seg_first_slot (seg); - is; pPos++, is = gr_slot_next_in_segment (is)) + /* Positioning. */ + if (!HB_DIRECTION_IS_BACKWARD(buffer->props.direction)) { - pPos->x_offset = gr_slot_origin_X (is) - curradvx; - pPos->y_offset = gr_slot_origin_Y (is) - curradvy; - pPos->x_advance = gr_slot_advance_X (is, grface, grfont); - pPos->y_advance = gr_slot_advance_Y (is, grface, grfont); - if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) - curradvx -= pPos->x_advance; - pPos->x_offset = gr_slot_origin_X (is) - curradvx; - if (!HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) + hb_glyph_position_t *pPos; + for (pPos = hb_buffer_get_glyph_positions (buffer, NULL), is = gr_seg_first_slot (seg); + is; pPos++, is = gr_slot_next_in_segment (is)) + { + pPos->x_offset = gr_slot_origin_X (is) - curradvx; + pPos->y_offset = gr_slot_origin_Y (is) - curradvy; + pPos->x_advance = gr_slot_advance_X (is, grface, grfont); + pPos->y_advance = gr_slot_advance_Y (is, grface, grfont); curradvx += pPos->x_advance; - pPos->y_offset = gr_slot_origin_Y (is) - curradvy; - curradvy += pPos->y_advance; - } - if (!HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) + curradvy += pPos->y_advance; + } pPos[-1].x_advance += gr_seg_advance_X(seg) - curradvx; - - if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) + } + else + { + hb_glyph_position_t *pPos = hb_buffer_get_glyph_positions (buffer, NULL) + buffer->len - 1; + const hb_glyph_info_t *info = buffer->info + buffer->len - 1; + const hb_glyph_info_t *tinfo; + const gr_slot *tis; + int currclus = -1; + float clusx = 0., clusy = 0.; + for (is = gr_seg_last_slot (seg); is; pPos--, info--, is = gr_slot_prev_in_segment (is)) + { + if (info->cluster != currclus) + { + curradvx += clusx; + curradvy += clusy; + currclus = info->cluster; + clusx = 0.; + clusy = 0.; + for (tis = is, tinfo = info; tis && tinfo->cluster == currclus; tis = gr_slot_prev_in_segment (tis), tinfo--) + { + clusx += gr_slot_advance_X (tis, grface, grfont); + clusy += gr_slot_advance_Y (tis, grface, grfont); + } + curradvx += clusx; + curradvy += clusy; + } + pPos->x_advance = gr_slot_advance_X (is, grface, grfont); + pPos->y_advance = gr_slot_advance_Y (is, grface, grfont); + curradvx -= pPos->x_advance; + curradvy -= pPos->y_advance; + pPos->x_offset = gr_slot_origin_X (is) - curradvx; + pPos->y_offset = gr_slot_origin_Y (is) - curradvy; + } hb_buffer_reverse_clusters (buffer); + } if (feats) gr_featureval_destroy (feats); gr_seg_destroy (seg); From 7b8b63adc5e0389fc4cf2720ef7e5804ab6c29cc Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 22 Jul 2015 15:24:26 +0100 Subject: [PATCH 45/77] [ot] Don't mirror character if font doesn't support mirrored character! --- src/hb-ot-shape.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index a531d7706..8d6bb3d53 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -305,7 +305,7 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c) hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) { hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint); - if (likely (codepoint == info[i].codepoint)) + if (likely (codepoint == info[i].codepoint || !c->font->has_glyph (codepoint))) info[i].mask |= rtlm_mask; else info[i].codepoint = codepoint; From 701112dad9f6e690b253f1e64f4e7e549f5ae65f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 22 Jul 2015 15:42:20 +0100 Subject: [PATCH 46/77] [ot] Simplify form_clusters() --- src/hb-buffer-private.hh | 9 ++++++++- src/hb-buffer.cc | 7 ++----- src/hb-ot-shape.cc | 11 +++++++++-- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh index ced748fdd..32d5a5f93 100644 --- a/src/hb-buffer-private.hh +++ b/src/hb-buffer-private.hh @@ -189,7 +189,14 @@ struct hb_buffer_t { unsigned int cluster_end); HB_INTERNAL void merge_clusters (unsigned int start, - unsigned int end); + unsigned int end) + { + if (end - start < 2) + return; + merge_clusters_impl (start, end); + } + HB_INTERNAL void merge_clusters_impl (unsigned int start, + unsigned int end); HB_INTERNAL void merge_out_clusters (unsigned int start, unsigned int end); /* Merge clusters for deleting current glyph, and skip it. */ diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index 4f953f0a7..0a11fec77 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -504,16 +504,13 @@ hb_buffer_t::reverse_clusters (void) } void -hb_buffer_t::merge_clusters (unsigned int start, - unsigned int end) +hb_buffer_t::merge_clusters_impl (unsigned int start, + unsigned int end) { #ifdef HB_NO_MERGE_CLUSTERS return; #endif - if (unlikely (end - start < 2)) - return; - unsigned int cluster = info[start].cluster; for (unsigned int i = start + 1; i < end; i++) diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 8d6bb3d53..bbd044fe4 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -264,11 +264,18 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) static void hb_form_clusters (hb_buffer_t *buffer) { + unsigned int base = 0; unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 1; i < count; i++) - if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i]))) - buffer->merge_clusters (i - 1, i + 1); + { + if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))) + { + buffer->merge_clusters (base, i); + base = i; + } + } + buffer->merge_clusters (base, count); } static void From a60e2cfa395718cde48eb81f43adc27b4a92e117 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 22 Jul 2015 15:49:08 +0100 Subject: [PATCH 47/77] [ot] Don't rely on cluster numbers for ensure_native_direction() --- src/hb-ot-shape.cc | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index bbd044fe4..5ead0b75c 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -264,6 +264,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) static void hb_form_clusters (hb_buffer_t *buffer) { + /* Loop duplicated in hb_ensure_native_direction(). */ unsigned int base = 0; unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; @@ -290,7 +291,23 @@ hb_ensure_native_direction (hb_buffer_t *buffer) if ((HB_DIRECTION_IS_HORIZONTAL (direction) && direction != hb_script_get_horizontal_direction (buffer->props.script)) || (HB_DIRECTION_IS_VERTICAL (direction) && direction != HB_DIRECTION_TTB)) { - hb_buffer_reverse_clusters (buffer); + /* Same loop as hb_form_clusters(). + * Since form_clusters() merged clusters already, we don't merge. */ + unsigned int base = 0; + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 1; i < count; i++) + { + if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))) + { + buffer->reverse_range (base, i); + base = i; + } + } + buffer->reverse_range (base, count); + + buffer->reverse (); + buffer->props.direction = HB_DIRECTION_REVERSE (buffer->props.direction); } } From 376d587f36b4ff10342ee6ca3bacd73532ea44c8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 22 Jul 2015 16:51:12 +0100 Subject: [PATCH 48/77] Implement more granular cluster-merging TODO: Documentation. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=71445 --- NEWS | 8 ++++++ src/hb-buffer-private.hh | 1 + src/hb-buffer.cc | 46 +++++++++++++++++++++++++++---- src/hb-buffer.h | 12 ++++++++ src/hb-ot-shape-complex-hangul.cc | 13 ++++----- src/hb-ot-shape.cc | 7 +++++ util/options.cc | 1 + util/options.hh | 3 ++ 8 files changed, 77 insertions(+), 14 deletions(-) diff --git a/NEWS b/NEWS index d985427dd..a5ac9067b 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,11 @@ + +- Removed HB_NO_MERGE_CLUSTERS hack. +- New API: + hb_buffer_cluster_level_t enum + hb_buffer_get_cluster_level() + hb_buffer_set_cluster_level() + hb-shape / hb-view --cluster-level + Overview of changes leading to 0.9.41 Thursday, June 18, 2015 ===================================== diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh index 32d5a5f93..3a2db481c 100644 --- a/src/hb-buffer-private.hh +++ b/src/hb-buffer-private.hh @@ -50,6 +50,7 @@ struct hb_buffer_t { /* Information about how the text in the buffer should be treated */ hb_unicode_funcs_t *unicode; /* Unicode functions */ hb_buffer_flags_t flags; /* BOT / EOT / etc. */ + hb_buffer_cluster_level_t cluster_level; hb_codepoint_t replacement; /* U+FFFD or something else. */ /* Buffer contents */ diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index 0a11fec77..03fe8e134 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -507,9 +507,8 @@ void hb_buffer_t::merge_clusters_impl (unsigned int start, unsigned int end) { -#ifdef HB_NO_MERGE_CLUSTERS - return; -#endif + if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) + return; unsigned int cluster = info[start].cluster; @@ -536,9 +535,8 @@ void hb_buffer_t::merge_out_clusters (unsigned int start, unsigned int end) { -#ifdef HB_NO_MERGE_CLUSTERS - return; -#endif + if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) + return; if (unlikely (end - start < 2)) return; @@ -738,6 +736,7 @@ hb_buffer_get_empty (void) const_cast (&_hb_unicode_funcs_nil), HB_BUFFER_FLAG_DEFAULT, + HB_BUFFER_CLUSTER_LEVEL_DEFAULT, HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, HB_BUFFER_CONTENT_TYPE_INVALID, @@ -1083,6 +1082,41 @@ hb_buffer_get_flags (hb_buffer_t *buffer) return buffer->flags; } +/** + * hb_buffer_set_cluster_level: + * @buffer: a buffer. + * @cluster_level: + * + * + * + * Since: 0.9.42 + **/ +void +hb_buffer_set_cluster_level (hb_buffer_t *buffer, + hb_buffer_cluster_level_t cluster_level) +{ + if (unlikely (hb_object_is_inert (buffer))) + return; + + buffer->cluster_level = cluster_level; +} + +/** + * hb_buffer_get_cluster_level: + * @buffer: a buffer. + * + * + * + * Return value: + * + * Since: 0.9.42 + **/ +hb_buffer_cluster_level_t +hb_buffer_get_cluster_level (hb_buffer_t *buffer) +{ + return buffer->cluster_level; +} + /** * hb_buffer_set_replacement_codepoint: diff --git a/src/hb-buffer.h b/src/hb-buffer.h index 520141b8a..4b285bbb3 100644 --- a/src/hb-buffer.h +++ b/src/hb-buffer.h @@ -185,7 +185,19 @@ hb_buffer_set_flags (hb_buffer_t *buffer, hb_buffer_flags_t hb_buffer_get_flags (hb_buffer_t *buffer); +typedef enum { + HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES = 0, + HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS = 1, + HB_BUFFER_CLUSTER_LEVEL_CHARACTERS = 2, + HB_BUFFER_CLUSTER_LEVEL_DEFAULT = HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES +} hb_buffer_cluster_level_t; +void +hb_buffer_set_cluster_level (hb_buffer_t *buffer, + hb_buffer_cluster_level_t cluster_level); + +hb_buffer_cluster_level_t +hb_buffer_get_cluster_level (hb_buffer_t *buffer); #define HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT 0xFFFDu diff --git a/src/hb-ot-shape-complex-hangul.cc b/src/hb-ot-shape-complex-hangul.cc index 6ac18b08b..763dbf00d 100644 --- a/src/hb-ot-shape-complex-hangul.cc +++ b/src/hb-ot-shape-complex-hangul.cc @@ -209,13 +209,8 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, hb_glyph_info_t tone = info[end]; memmove (&info[start + 1], &info[start], (end - start) * sizeof (hb_glyph_info_t)); info[start] = tone; + buffer->merge_out_clusters (start, end + 1); } - /* Merge clusters across the (possibly reordered) syllable+tone. - * We want to merge even in the zero-width tone mark case here, - * so that clustering behavior isn't dependent on how the tone mark - * is handled by the font. - */ - buffer->merge_out_clusters (start, end + 1); } else { @@ -296,7 +291,8 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, } else end = start + 2; - buffer->merge_out_clusters (start, end); + if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) + buffer->merge_out_clusters (start, end); continue; } } @@ -368,7 +364,8 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, info[i++].hangul_shaping_feature() = VJMO; if (i < end) info[i++].hangul_shaping_feature() = TJMO; - buffer->merge_out_clusters (start, end); + if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) + buffer->merge_out_clusters (start, end); continue; } } diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 5ead0b75c..d290cadc9 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -264,6 +264,9 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) static void hb_form_clusters (hb_buffer_t *buffer) { + if (buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) + return; + /* Loop duplicated in hb_ensure_native_direction(). */ unsigned int base = 0; unsigned int count = buffer->len; @@ -301,10 +304,14 @@ hb_ensure_native_direction (hb_buffer_t *buffer) if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))) { buffer->reverse_range (base, i); + if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) + buffer->merge_clusters (base, i); base = i; } } buffer->reverse_range (base, count); + if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) + buffer->merge_clusters (base, count); buffer->reverse (); diff --git a/util/options.cc b/util/options.cc index 0f92aec0e..0821a17bc 100644 --- a/util/options.cc +++ b/util/options.cc @@ -291,6 +291,7 @@ shape_options_t::add_options (option_parser_t *parser) {"eot", 0, 0, G_OPTION_ARG_NONE, &this->eot, "Treat text as end-of-paragraph", NULL}, {"preserve-default-ignorables",0, 0, G_OPTION_ARG_NONE, &this->preserve_default_ignorables, "Preserve Default-Ignorable characters", NULL}, {"utf8-clusters", 0, 0, G_OPTION_ARG_NONE, &this->utf8_clusters, "Use UTF8 byte indices, not char indices", NULL}, + {"cluster-level", 0, 0, G_OPTION_ARG_INT, &this->cluster_level, "Cluster merging level (default: 0)", "0/1/2"}, {"normalize-glyphs",0, 0, G_OPTION_ARG_NONE, &this->normalize_glyphs, "Rearrange glyph clusters in nominal order", NULL}, {"num-iterations", 0, 0, G_OPTION_ARG_INT, &this->num_iterations, "Run shaper N times (default: 1)", "N"}, {NULL} diff --git a/util/options.hh b/util/options.hh index 8b9b10ef0..6eb6c04c4 100644 --- a/util/options.hh +++ b/util/options.hh @@ -180,6 +180,7 @@ struct shape_options_t : option_group_t num_features = 0; shapers = NULL; utf8_clusters = false; + cluster_level = HB_BUFFER_CLUSTER_LEVEL_DEFAULT; normalize_glyphs = false; num_iterations = 1; @@ -202,6 +203,7 @@ struct shape_options_t : option_group_t (bot ? HB_BUFFER_FLAG_BOT : 0) | (eot ? HB_BUFFER_FLAG_EOT : 0) | (preserve_default_ignorables ? HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES : 0))); + hb_buffer_set_cluster_level (buffer, cluster_level); hb_buffer_guess_segment_properties (buffer); } @@ -265,6 +267,7 @@ struct shape_options_t : option_group_t unsigned int num_features; char **shapers; hb_bool_t utf8_clusters; + hb_buffer_cluster_level_t cluster_level; hb_bool_t normalize_glyphs; unsigned int num_iterations; }; From f0010dfd01ef4a927b0bdc175dd4e343a8637174 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 22 Jul 2015 17:36:23 +0100 Subject: [PATCH 49/77] [ot] Hide default-ignorables before finishing off positioning For example, fixes the following sequence with Arial XP: 628 25cc 651 25cc 64e 3a 20 628 651 34f 64e 628 25cc 64e 25cc 651 3a 20 628 64e 34f 651 Discovered as part of: https://bugs.freedesktop.org/show_bug.cgi?id=85873 --- src/hb-ot-shape.cc | 125 +++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 62 deletions(-) diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index d290cadc9..59c58fdaf 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -411,6 +411,65 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) } } + +static void +hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) +{ + hb_buffer_t *buffer = c->buffer; + + if (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) + return; + + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + unsigned int i = 0; + for (i = 0; i < count; i++) + { + if (unlikely (!_hb_glyph_info_ligated (&info[i]) && + _hb_glyph_info_is_default_ignorable (&info[i]))) + break; + } + + /* No default-ignorables found; return. */ + if (i == count) + return; + + hb_codepoint_t space; + if (c->font->get_glyph (' ', 0, &space)) + { + /* Replace default-ignorables with a zero-advance space glyph. */ + for (/*continue*/; i < count; i++) + { + if (!_hb_glyph_info_ligated (&info[i]) && + _hb_glyph_info_is_default_ignorable (&info[i])) + { + info[i].codepoint = space; + pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; + } + } + } + else + { + /* Merge clusters and delete default-ignorables. */ + buffer->clear_output (); + buffer->idx = 0; + buffer->next_glyphs (i); + while (buffer->idx < buffer->len) + { + if (!_hb_glyph_info_ligated (&info[buffer->idx]) && + _hb_glyph_info_is_default_ignorable (&info[buffer->idx])) + { + buffer->delete_glyph (); + continue; + } + buffer->next_glyph (); + } + buffer->swap_buffers (); + } +} + + static inline void hb_ot_map_glyphs_fast (hb_buffer_t *buffer) { @@ -656,6 +715,10 @@ hb_ot_position (hb_ot_shape_context_t *c) hb_bool_t fallback = !hb_ot_position_complex (c); + /* Need to do this here, since position_finish and fallback positioning + * might be affected by width of default_ignorables. */ + hb_ot_hide_default_ignorables (c); + hb_ot_layout_position_finish (c->font, c->buffer); if (fallback && c->plan->shaper->fallback_position) @@ -673,66 +736,6 @@ hb_ot_position (hb_ot_shape_context_t *c) } -/* Post-process */ - -static void -hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) -{ - hb_buffer_t *buffer = c->buffer; - - if (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) - return; - - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - hb_glyph_position_t *pos = buffer->pos; - unsigned int i = 0; - for (i = 0; i < count; i++) - { - if (unlikely (!_hb_glyph_info_ligated (&info[i]) && - _hb_glyph_info_is_default_ignorable (&info[i]))) - break; - } - - /* No default-ignorables found; return. */ - if (i == count) - return; - - hb_codepoint_t space; - if (c->font->get_glyph (' ', 0, &space)) - { - /* Replace default-ignorables with a zero-advance space glyph. */ - for (/*continue*/; i < count; i++) - { - if (!_hb_glyph_info_ligated (&info[i]) && - _hb_glyph_info_is_default_ignorable (&info[i])) - { - info[i].codepoint = space; - pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; - } - } - } - else - { - /* Merge clusters and delete default-ignorables. */ - buffer->clear_output (); - buffer->idx = 0; - buffer->next_glyphs (i); - while (buffer->idx < buffer->len) - { - if (!_hb_glyph_info_ligated (&info[buffer->idx]) && - _hb_glyph_info_is_default_ignorable (&info[buffer->idx])) - { - buffer->delete_glyph (); - continue; - } - buffer->next_glyph (); - } - buffer->swap_buffers (); - } -} - - /* Pull it all together! */ static void @@ -756,8 +759,6 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) hb_ot_substitute (c); hb_ot_position (c); - hb_ot_hide_default_ignorables (c); - _hb_buffer_deallocate_unicode_vars (c->buffer); c->buffer->props.direction = c->target_direction; From 4ba796b26ee62de0d2830a550f3aa3b4aecf6f59 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 22 Jul 2015 17:41:31 +0100 Subject: [PATCH 50/77] Refactor _hb_glyph_info_is_default_ignorable() --- src/hb-ot-layout-gsubgpos-private.hh | 3 +-- src/hb-ot-layout-private.hh | 4 +++- src/hb-ot-shape.cc | 9 +++------ 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index 842be880d..99c4c8385 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -328,8 +328,7 @@ struct hb_apply_context_t if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && - (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) && - !_hb_glyph_info_ligated (&info))) + (ignore_zwj || !_hb_glyph_info_is_zwj (&info)))) return SKIP_MAYBE; return SKIP_NO; diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index 47fecd216..d85456375 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -225,10 +225,12 @@ _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info) return info->unicode_props1(); } +static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info); + static inline hb_bool_t _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) { - return !!(info->unicode_props0() & MASK0_IGNORABLE); + return (info->unicode_props0() & MASK0_IGNORABLE) && !_hb_glyph_info_ligated (info); } static inline hb_bool_t diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 59c58fdaf..33b13b52b 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -426,8 +426,7 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) unsigned int i = 0; for (i = 0; i < count; i++) { - if (unlikely (!_hb_glyph_info_ligated (&info[i]) && - _hb_glyph_info_is_default_ignorable (&info[i]))) + if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i]))) break; } @@ -441,8 +440,7 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) /* Replace default-ignorables with a zero-advance space glyph. */ for (/*continue*/; i < count; i++) { - if (!_hb_glyph_info_ligated (&info[i]) && - _hb_glyph_info_is_default_ignorable (&info[i])) + if (_hb_glyph_info_is_default_ignorable (&info[i])) { info[i].codepoint = space; pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; @@ -457,8 +455,7 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) buffer->next_glyphs (i); while (buffer->idx < buffer->len) { - if (!_hb_glyph_info_ligated (&info[buffer->idx]) && - _hb_glyph_info_is_default_ignorable (&info[buffer->idx])) + if (_hb_glyph_info_is_default_ignorable (&info[buffer->idx])) { buffer->delete_glyph (); continue; From 2dbd3d29d6548bd96fd976606ed689fac8ad8817 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 22 Jul 2015 18:28:39 +0100 Subject: [PATCH 51/77] Fix hide-ignorables if font doesn't have space glyph Was broken by 82b521aeb7cc73879b44ca4278d6fa8b4347527f, as we have positioning data by then and can't use the output buffer. Ouch! --- src/hb-buffer-private.hh | 18 ---------------- src/hb-ot-shape.cc | 44 ++++++++++++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh index 3a2db481c..9aa5e7d7e 100644 --- a/src/hb-buffer-private.hh +++ b/src/hb-buffer-private.hh @@ -152,24 +152,6 @@ struct hb_buffer_t { idx++; } - inline void - next_glyphs (unsigned int count) - { - if (have_output) - { - if (unlikely (out_info != info || out_len != idx)) { - if (unlikely (!make_room_for (count, count))) return; - { - while (count--) - out_info[out_len++] = info[idx++]; - return; - } - } - out_len += count; - } - - idx += count; - } /* Advance idx without copying to output. */ inline void skip_glyph (void) { idx++; } diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 33b13b52b..cf5ae8799 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -449,20 +449,46 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) } else { - /* Merge clusters and delete default-ignorables. */ - buffer->clear_output (); - buffer->idx = 0; - buffer->next_glyphs (i); - while (buffer->idx < buffer->len) + /* Merge clusters and delete default-ignorables. + * NOTE! We can't use out-buffer as we have positioning data. */ + unsigned int j = i; + for (; i < count; i++) { - if (_hb_glyph_info_is_default_ignorable (&info[buffer->idx])) + if (_hb_glyph_info_is_default_ignorable (&info[i])) { - buffer->delete_glyph (); + /* Merge clusters. + * Same logic as buffer->delete_glyph(), but for in-place removal. */ + + unsigned int cluster = info[i].cluster; + if (i + 1 < count && cluster == info[i + 1].cluster) + continue; /* Cluster survives; do nothing. */ + + if (j) + { + /* Merge cluster backward. */ + if (cluster < info[j - 1].cluster) + { + unsigned int old_cluster = info[j - 1].cluster; + for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--) + info[k - 1].cluster = cluster; + } + continue; + } + + if (i + 1 < count) + buffer->merge_clusters (i, i + 2); /* Merge cluster forward. */ + continue; } - buffer->next_glyph (); + + if (j != i) + { + info[j] = info[i]; + pos[j] = pos[i]; + } + j++; } - buffer->swap_buffers (); + buffer->len = j; } } From 8cfbc304ee563ec96e402beed34b10b6c0950a6a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 22 Jul 2015 18:41:10 +0100 Subject: [PATCH 52/77] Fix hide-default-ignorables after f0010dfd01ef4a927b0bdc175dd4e343a8637174 We can't delete things before hb_ot_layout_position_finish(). So, just zero the advance before it, and remove later. --- src/hb-ot-shape.cc | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index cf5ae8799..993497a46 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -411,6 +411,22 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) } } +static void +hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c) +{ + hb_buffer_t *buffer = c->buffer; + + if (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) + return; + + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + unsigned int i = 0; + for (i = 0; i < count; i++) + if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i]))) + pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; +} static void hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) @@ -441,10 +457,7 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) for (/*continue*/; i < count; i++) { if (_hb_glyph_info_is_default_ignorable (&info[i])) - { info[i].codepoint = space; - pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; - } } } else @@ -738,9 +751,7 @@ hb_ot_position (hb_ot_shape_context_t *c) hb_bool_t fallback = !hb_ot_position_complex (c); - /* Need to do this here, since position_finish and fallback positioning - * might be affected by width of default_ignorables. */ - hb_ot_hide_default_ignorables (c); + hb_ot_zero_width_default_ignorables (c); hb_ot_layout_position_finish (c->font, c->buffer); @@ -782,6 +793,8 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) hb_ot_substitute (c); hb_ot_position (c); + hb_ot_hide_default_ignorables (c); + _hb_buffer_deallocate_unicode_vars (c->buffer); c->buffer->props.direction = c->target_direction; From 582069172c39326c7f94373793c656439a4c2b59 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 22 Jul 2015 18:44:59 +0100 Subject: [PATCH 53/77] Add test case for deleting default ignorables with positioning --- .../051d92f8bc6ff724511b296c27623f824de256e9.ttf | Bin 0 -> 2028 bytes test/shaping/fonts/sha1sum/MANIFEST | 1 + test/shaping/tests/MANIFEST | 1 + test/shaping/tests/default-ignorables.tests | 1 + 4 files changed, 3 insertions(+) create mode 100644 test/shaping/fonts/sha1sum/051d92f8bc6ff724511b296c27623f824de256e9.ttf create mode 100644 test/shaping/tests/default-ignorables.tests diff --git a/test/shaping/fonts/sha1sum/051d92f8bc6ff724511b296c27623f824de256e9.ttf b/test/shaping/fonts/sha1sum/051d92f8bc6ff724511b296c27623f824de256e9.ttf new file mode 100644 index 0000000000000000000000000000000000000000..419f8f3db0b504de0723b11667472546499c91c7 GIT binary patch literal 2028 zcmZuyeQZ-z6#w1(ZeP1Gw{^C-Nu}$`28@rv-r84n*g28mVyLpA#Au|O`+&9G+y>iB z2$BiW=mdcn#V>*%L1PrnoCF9uOfYJQHj6QnKO`m+{~-Rc#4py@dhUCjTL!P$x#xH8 zIluGq-n|0@kdLRKU|YlbdpBSSDgoP1J4#M|$MEiQ+fSvFt;k=I6Q2U|>y@R9^pHkS_ z7JcIH&L4MC{2H~P3c;&g7P&JzN@FZuRpUL?SzlWeQ+G3KKg9GQMUzv&+pWfnxIy_(Ct$F zWfiPtboBhXRh8jz<*Id}ku9$c25avOg}`t;b5*Ptjc`%C)3s2m4hEc>)4$ZO%D{k= zZ5`PC{?X5l+?um?bl}1_qS08lZ|~V8ubm!yDe};{B>$cQ*|3;Yys8g51cE_bbE~S| z&xR{@E}L9=Iy@kz)_k(bU3Y#hZQ~;nEtFBQ>XfyK#!SYri^=rcs;|%vWm-aq#= zYKv%bNy*~$u~}UVBom25Y9Fg--z8c2T4VRbzpOqr+}+LUC&UWLc7_D|Lf2)e3}gek z?(ukxH_U~@JTG`P1s4>IJrAr^1wo63s}?IVkf=X2cMw&r|PRS1-q6$tH4Wr--5~ozqQQgiYv1 zKmC=`$&4a_K5RxCozR_#5$-j;Nl?Y@^6t99!>BH*jp~`HSUQ!NRX9k>pVg0IddPPx z--EQ~VgqGYT8DaLaCP*yb)hsC?N4B}IRg-<^p*3Fx{OlhAV#_^9_^*5tn7++VOe~R zq==bZl1ZUTi?K}JdBiNMlic(1Bgmm3YhR`P{iNs7tQb7xEBlc>$ZlnAvJVx^cwU?| z`Sa;sX3U|k1mnBNM!J;q80^Fw>Q0uhvZIV Date: Thu, 23 Jul 2015 10:07:21 +0100 Subject: [PATCH 54/77] [ot] Add missing return! --- src/hb-ot-layout-gsubgpos-private.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index 99c4c8385..e14b5b699 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -719,7 +719,7 @@ static inline bool match_input (hb_apply_context_t *c, { TRACE_APPLY (NULL); - if (unlikely (count > MAX_CONTEXT_LENGTH)) TRACE_RETURN (false); + if (unlikely (count > MAX_CONTEXT_LENGTH)) return TRACE_RETURN (false); hb_buffer_t *buffer = c->buffer; From d99f50bde0e8be0866385ca6886938d2023dbd4f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 23 Jul 2015 10:08:48 +0100 Subject: [PATCH 55/77] Add missing TRACE_RETURN --- src/hb-ot-layout-gsubgpos-private.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index e14b5b699..5033a223d 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -2164,7 +2164,7 @@ struct ExtensionFormat1 { TRACE_DISPATCH (this, format); if (unlikely (!c->may_dispatch (this, this))) TRACE_RETURN (c->default_return_value ()); - return get_subtable ().dispatch (c, get_type ()); + return TRACE_RETURN (get_subtable ().dispatch (c, get_type ())); } /* This is called from may_dispatch() above with hb_sanitize_context_t. */ From d78463c8016ff1852233479a1ebde30c3bb6de6e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 23 Jul 2015 10:11:35 +0100 Subject: [PATCH 56/77] Minor debug output fix --- src/hb-ot-layout.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 05ea0603c..5570a819c 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -905,7 +905,7 @@ apply_backward (OT::hb_apply_context_t *c, struct hb_apply_forward_context_t { - inline const char *get_name (void) { return "APPLY_FORWARD"; } + inline const char *get_name (void) { return "APPLY_FWD"; } static const unsigned int max_debug_depth = HB_DEBUG_APPLY; typedef bool return_t; template From f327aacfa107bbef0c823ef9c3b7dfc91316040c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 23 Jul 2015 11:32:59 +0100 Subject: [PATCH 57/77] [ot] Minor --- src/hb-ot-shape.cc | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 993497a46..00a212192 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -59,10 +59,6 @@ static hb_tag_t horizontal_features[] = { HB_TAG('r','c','l','t'), }; -static hb_tag_t vertical_features[] = { - HB_TAG('v','e','r','t'), -}; - static void @@ -105,10 +101,9 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, (horizontal_features[i] == HB_TAG('k','e','r','n') ? F_HAS_FALLBACK : F_NONE)); else - for (unsigned int i = 0; i < ARRAY_LENGTH (vertical_features); i++) - map->add_feature (vertical_features[i], 1, F_GLOBAL | - (vertical_features[i] == HB_TAG('v','k','r','n') ? - F_HAS_FALLBACK : F_NONE)); + { + map->add_global_bool_feature (HB_TAG('v','e','r','t')); + } if (planner->shaper->override_features) planner->shaper->override_features (planner); From 0f98fe88f42471eb8fb28d08d45eca9cd8303f7a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 23 Jul 2015 11:52:11 +0100 Subject: [PATCH 58/77] [ot] Search globally for 'vert' feature if not found in specified script/lang Fixes https://github.com/behdad/harfbuzz/issues/63 --- src/hb-ot-layout-private.hh | 9 +++++++++ src/hb-ot-layout.cc | 22 ++++++++++++++++++++++ src/hb-ot-map-private.hh | 7 ++++--- src/hb-ot-map.cc | 10 ++++++++++ src/hb-ot-shape.cc | 6 +++++- 5 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index d85456375..a98734a06 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -36,6 +36,15 @@ #include "hb-set-private.hh" +/* Private API corresponding to hb-ot-layout.h: */ + +HB_INTERNAL hb_bool_t +hb_ot_layout_table_find_feature (hb_face_t *face, + hb_tag_t table_tag, + hb_tag_t feature_tag, + unsigned int *feature_index); + + /* * GDEF */ diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 5570a819c..6fe7b6ca0 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -291,6 +291,28 @@ hb_ot_layout_table_get_feature_tags (hb_face_t *face, return g.get_feature_tags (start_offset, feature_count, feature_tags); } +hb_bool_t +hb_ot_layout_table_find_feature (hb_face_t *face, + hb_tag_t table_tag, + hb_tag_t feature_tag, + unsigned int *feature_index) +{ + ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX); + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + + unsigned int num_features = g.get_feature_count (); + for (unsigned int i = 0; i < num_features; i++) + { + if (feature_tag == g.get_feature_tag (i)) { + if (feature_index) *feature_index = i; + return true; + } + } + + if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX; + return false; +} + unsigned int hb_ot_layout_script_get_language_tags (hb_face_t *face, diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh index 86b7e9faf..f9538af18 100644 --- a/src/hb-ot-map-private.hh +++ b/src/hb-ot-map-private.hh @@ -154,9 +154,10 @@ struct hb_ot_map_t enum hb_ot_map_feature_flags_t { F_NONE = 0x0000u, - F_GLOBAL = 0x0001u, - F_HAS_FALLBACK = 0x0002u, - F_MANUAL_ZWJ = 0x0004u + F_GLOBAL = 0x0001u, /* Feature applies to all characters; results in no mask allocated for it. */ + F_HAS_FALLBACK = 0x0002u, /* Has fallback implementation, so include mask bit even if feature not found. */ + F_MANUAL_ZWJ = 0x0004u, /* Don't skip over ZWJ when matching. */ + F_GLOBAL_SEARCH = 0x0008u /* If feature not found in LangSys, look for it in global feature list and pick one. */ }; /* Macro version for where const is desired. */ #define F_COMBINE(l,r) (hb_ot_map_feature_flags_t ((unsigned int) (l) | (unsigned int) (r))) diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index 4985eb22b..95bd04ee8 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc @@ -216,6 +216,16 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) info->tag, &feature_index[table_index]); } + if (!found && (info->flags & F_GLOBAL_SEARCH)) + { + for (unsigned int table_index = 0; table_index < 2; table_index++) + { + found |= hb_ot_layout_table_find_feature (face, + table_tags[table_index], + info->tag, + &feature_index[table_index]); + } + } if (!found && !(info->flags & F_HAS_FALLBACK)) continue; diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 00a212192..f20be2aac 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -102,7 +102,11 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, F_HAS_FALLBACK : F_NONE)); else { - map->add_global_bool_feature (HB_TAG('v','e','r','t')); + /* We really want to find a 'vert' feature if there's any in the font, no + * matter which script/langsys it is listed (or not) under. + * See various bugs referenced from: + * https://github.com/behdad/harfbuzz/issues/63 */ + map->add_feature (HB_TAG ('v','e','r','t'), 1, F_GLOBAL | F_GLOBAL_SEARCH); } if (planner->shaper->override_features) From 895fb31c7f0201f13df5a6866b367476bc4aab2e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 23 Jul 2015 12:14:03 +0100 Subject: [PATCH 59/77] [test] Support additional options to hb-shape in micro-test suite --- test/shaping/record-test.sh | 47 +++++++++++++++---- test/shaping/run-tests.sh | 9 +++- .../tests/arabic-fallback-shaping.tests | 2 +- test/shaping/tests/arabic-feature-order.tests | 6 +-- test/shaping/tests/context-matching.tests | 6 +-- test/shaping/tests/default-ignorables.tests | 2 +- test/shaping/tests/hangul-jamo.tests | 4 +- .../tests/indic-joiner-candrabindu.tests | 4 +- test/shaping/tests/indic-old-spec.tests | 4 +- test/shaping/tests/indic-pref-blocking.tests | 4 +- .../tests/mongolian-variation-selector.tests | 6 +-- test/shaping/tests/zero-width-marks.tests | 4 +- 12 files changed, 67 insertions(+), 31 deletions(-) diff --git a/test/shaping/record-test.sh b/test/shaping/record-test.sh index a69157f73..691f78d14 100755 --- a/test/shaping/record-test.sh +++ b/test/shaping/record-test.sh @@ -5,11 +5,42 @@ dir=`mktemp --directory` hb_shape=$1 shift fontfile=$1 +if test "x${fontfile:0:1}" == 'x-'; then + echo "Specify font file before other options." >&2 + exit 1 +fi shift -hb_shape="$hb_shape $@" -unicodes=`./hb-unicode-decode` -text=`./hb-unicode-encode "$unicodes"` -glyphs=`echo "$text" | $hb_shape "$fontfile"` +if ! echo "$hb_shape" | grep -q 'hb-shape'; then + echo "Specify hb-shape (not hb-view, etc)." >&2 + exit 1 +fi +options= +have_text=false +for arg in "$@"; do + if test "x${arg:0:1}" == 'x-'; then + if echo "$arg" | grep -q ' '; then + echo "Space in argument is not supported: '$arg'." >&2 + exit 1 + fi + options="$options${options:+ }$arg" + continue + fi + if $have_text; then + echo "Too many arguments found... Use '=' notation for options: '$arg'" >&2 + exit 1; + fi + text="$arg" + have_text=true +done +if ! $have_text; then + text=`cat` +fi +unicodes=`./hb-unicode-decode "$text"` +glyphs=`echo "$text" | $hb_shape $options "$fontfile"` +if test $? != 0; then + echo "hb-shape failed." >&2 + exit 2 +fi cp "$fontfile" "$dir/font.ttf" pyftsubset \ @@ -22,14 +53,14 @@ if ! test -s "$dir/font.ttf.subset"; then fi # Verify that subset font produces same glyphs! -glyphs_subset=`echo "$text" | $hb_shape "$dir/font.ttf.subset"` +glyphs_subset=`echo "$text" | $hb_shape $options "$dir/font.ttf.subset"` if ! test "x$glyphs" = "x$glyphs_subset"; then echo "Subset font produced different glyphs!" >&2 echo "Perhaps font doesn't have glyph names; checking visually..." >&2 hb_view=${hb_shape/shape/view} - echo "$text" | $hb_view "$dir/font.ttf" --output-format=png --output-file="$dir/orig.png" - echo "$text" | $hb_view "$dir/font.ttf.subset" --output-format=png --output-file="$dir/subset.png" + echo "$text" | $hb_view $options "$dir/font.ttf" --output-format=png --output-file="$dir/orig.png" + echo "$text" | $hb_view $options "$dir/font.ttf.subset" --output-format=png --output-file="$dir/subset.png" if ! cmp "$dir/orig.png" "$dir/subset.png"; then echo "Images differ. Please inspect $dir/*.png." >&2 echo "$glyphs" @@ -46,7 +77,7 @@ sha1sum=`sha1sum "$dir/font.ttf.subset" | cut -d' ' -f1` subset="fonts/sha1sum/$sha1sum.ttf" mv "$dir/font.ttf.subset" "$subset" -echo "$subset:$unicodes:$glyphs" +echo "$subset:$options:$unicodes:$glyphs" rm -f "$dir/font.ttf" rmdir "$dir" diff --git a/test/shaping/run-tests.sh b/test/shaping/run-tests.sh index a2cdf32ac..1e2e34d1b 100755 --- a/test/shaping/run-tests.sh +++ b/test/shaping/run-tests.sh @@ -15,9 +15,14 @@ fi IFS=: for f in "$@"; do echo "Running tests in $f" - while read fontfile unicodes glyphs_expected; do + while read fontfile options unicodes glyphs_expected; do echo "Testing $fontfile:$unicodes" - glyphs=`$srcdir/hb-unicode-encode "$unicodes" | $hb_shape "$srcdir/$fontfile"` + glyphs=`$srcdir/hb-unicode-encode "$unicodes" | $hb_shape $options "$srcdir/$fontfile"` + if test $? != 0; then + echo "hb-shape failed." >&2 + fails=$((fails+1)) + continue + fi if ! test "x$glyphs" = "x$glyphs_expected"; then echo "Actual: $glyphs" >&2 echo "Expected: $glyphs_expected" >&2 diff --git a/test/shaping/tests/arabic-fallback-shaping.tests b/test/shaping/tests/arabic-fallback-shaping.tests index e3eaf3feb..6f1cb8b93 100644 --- a/test/shaping/tests/arabic-fallback-shaping.tests +++ b/test/shaping/tests/arabic-fallback-shaping.tests @@ -1 +1 @@ -fonts/sha1sum/df768b9c257e0c9c35786c47cae15c46571d56be.ttf:U+0633,U+064F,U+0644,U+064E,U+0651,U+0627,U+0651,U+0650,U+0645,U+062A,U+06CC:[uni06CC.fina=10+1655|uni062A.medi=9+868|uni0645.init=8+1098|uni0650=2@221,0+0|uni0651=2@260,736+0|uni064E=2@935,1259+0|uni0651=2@974,736+0|uni06440627.fina=2+1470|uni064F=0@558,-10+0|uni0633.init=0+1585] +fonts/sha1sum/df768b9c257e0c9c35786c47cae15c46571d56be.ttf::U+0633,U+064F,U+0644,U+064E,U+0651,U+0627,U+0651,U+0650,U+0645,U+062A,U+06CC:[uni06CC.fina=10+1655|uni062A.medi=9+868|uni0645.init=8+1098|uni0650=2@221,0+0|uni0651=2@260,736+0|uni064E=2@935,1259+0|uni0651=2@974,736+0|uni06440627.fina=2+1470|uni064F=0@558,-10+0|uni0633.init=0+1585] diff --git a/test/shaping/tests/arabic-feature-order.tests b/test/shaping/tests/arabic-feature-order.tests index 3e3cf6a97..e60ab1a22 100644 --- a/test/shaping/tests/arabic-feature-order.tests +++ b/test/shaping/tests/arabic-feature-order.tests @@ -1,3 +1,3 @@ -fonts/sha1sum/813c2f8e5512187fd982417a7fb4286728e6f4a8.ttf:U+1820,U+180B:[uni2048.E81A=0+1550] -fonts/sha1sum/8a9fea2a7384f2116e5b84a9b31f83be7850ce21.ttf:U+1820,U+180B:[uni2048.E81A=0+1550] -fonts/sha1sum/a919b33197965846f21074b24e30250d67277bce.ttf:U+0644,U+0644,U+0647:[Lellah=0+1503] +fonts/sha1sum/813c2f8e5512187fd982417a7fb4286728e6f4a8.ttf::U+1820,U+180B:[uni2048.E81A=0+1550] +fonts/sha1sum/8a9fea2a7384f2116e5b84a9b31f83be7850ce21.ttf::U+1820,U+180B:[uni2048.E81A=0+1550] +fonts/sha1sum/a919b33197965846f21074b24e30250d67277bce.ttf::U+0644,U+0644,U+0647:[Lellah=0+1503] diff --git a/test/shaping/tests/context-matching.tests b/test/shaping/tests/context-matching.tests index 4c7d25f2c..4af186d88 100644 --- a/test/shaping/tests/context-matching.tests +++ b/test/shaping/tests/context-matching.tests @@ -1,3 +1,3 @@ -fonts/sha1sum/4cce528e99f600ed9c25a2b69e32eb94a03b4ae8.ttf:U+1A48,U+1A58,U+1A25,U+1A48,U+1A58,U+1A25,U+1A6E,U+1A63:[uni1A48=0+1212|uni1A25=0+1912|uni1A58=0+0|uni1A48=3+1212|uni1A6E=3+1212|uni1A25=3+1912|uni1A58=3+0|uni1A63=3+1212] -fonts/sha1sum/d629e7fedc0b350222d7987345fe61613fa3929a.ttf:U+0915,U+093F,U+0915,U+093F:[ivowelsign03deva=0+530|kadeva=0+1561|ivowelsign03deva=2+530|kadeva=2+1561] -fonts/sha1sum/f499fbc23865022234775c43503bba2e63978fe1.ttf:U+09B0,U+09CD,U+09A5,U+09CD,U+09AF,U+09C0:[gid1=0+1320|gid13=0+523|gid18=0+545] +fonts/sha1sum/4cce528e99f600ed9c25a2b69e32eb94a03b4ae8.ttf::U+1A48,U+1A58,U+1A25,U+1A48,U+1A58,U+1A25,U+1A6E,U+1A63:[uni1A48=0+1212|uni1A25=0+1912|uni1A58=0+0|uni1A48=3+1212|uni1A6E=3+1212|uni1A25=3+1912|uni1A58=3+0|uni1A63=3+1212] +fonts/sha1sum/d629e7fedc0b350222d7987345fe61613fa3929a.ttf::U+0915,U+093F,U+0915,U+093F:[ivowelsign03deva=0+530|kadeva=0+1561|ivowelsign03deva=2+530|kadeva=2+1561] +fonts/sha1sum/f499fbc23865022234775c43503bba2e63978fe1.ttf::U+09B0,U+09CD,U+09A5,U+09CD,U+09AF,U+09C0:[gid1=0+1320|gid13=0+523|gid18=0+545] diff --git a/test/shaping/tests/default-ignorables.tests b/test/shaping/tests/default-ignorables.tests index 317873128..2d3ce9759 100644 --- a/test/shaping/tests/default-ignorables.tests +++ b/test/shaping/tests/default-ignorables.tests @@ -1 +1 @@ -fonts/sha1sum/051d92f8bc6ff724511b296c27623f824de256e9.ttf:U+0075,U+0361,U+034F,U+0301,U+0069:[gid2=0+1266|gid7=0@-617,442+0|gid5=0@-7,0+0|gid1=4+528] +fonts/sha1sum/051d92f8bc6ff724511b296c27623f824de256e9.ttf::U+0075,U+0361,U+034F,U+0301,U+0069:[gid2=0+1266|gid7=0@-617,442+0|gid5=0@-7,0+0|gid1=4+528] diff --git a/test/shaping/tests/hangul-jamo.tests b/test/shaping/tests/hangul-jamo.tests index 667a1ccc7..fe9973f4c 100644 --- a/test/shaping/tests/hangul-jamo.tests +++ b/test/shaping/tests/hangul-jamo.tests @@ -1,2 +1,2 @@ -fonts/sha1sum/757ebd573617a24aa9dfbf0b885c54875c6fe06b.ttf:U+115F,U+11A2:[gid3=0+920|gid4=0+0] -fonts/sha1sum/7e14e7883ed152baa158b80e207b66114c823a8b.ttf:U+11A2:[gid1=0+920] +fonts/sha1sum/757ebd573617a24aa9dfbf0b885c54875c6fe06b.ttf::U+115F,U+11A2:[gid3=0+920|gid4=0+0] +fonts/sha1sum/7e14e7883ed152baa158b80e207b66114c823a8b.ttf::U+11A2:[gid1=0+920] diff --git a/test/shaping/tests/indic-joiner-candrabindu.tests b/test/shaping/tests/indic-joiner-candrabindu.tests index 351e927fd..2ef3304b1 100644 --- a/test/shaping/tests/indic-joiner-candrabindu.tests +++ b/test/shaping/tests/indic-joiner-candrabindu.tests @@ -1,2 +1,2 @@ -fonts/sha1sum/5028afb650b1bb718ed2131e872fbcce57828fff.ttf:U+0B13,U+200D,U+0B01:[omorya=0+1450] -fonts/sha1sum/5028afb650b1bb718ed2131e872fbcce57828fff.ttf:U+0B13,U+200C,U+0B01:[oorya=0+1309|space=1+0|candrabinduorya=1+0] +fonts/sha1sum/5028afb650b1bb718ed2131e872fbcce57828fff.ttf::U+0B13,U+200D,U+0B01:[omorya=0+1450] +fonts/sha1sum/5028afb650b1bb718ed2131e872fbcce57828fff.ttf::U+0B13,U+200C,U+0B01:[oorya=0+1309|space=1+0|candrabinduorya=1+0] diff --git a/test/shaping/tests/indic-old-spec.tests b/test/shaping/tests/indic-old-spec.tests index 96e8cdd3e..5410a6abf 100644 --- a/test/shaping/tests/indic-old-spec.tests +++ b/test/shaping/tests/indic-old-spec.tests @@ -1,2 +1,2 @@ -fonts/sha1sum/57a9d9f83020155cbb1d2be1f43d82388cbecc88.ttf:U+0C9A,U+0CCD,U+0C9A,U+0CCD:[U0C9A_U0CCD.haln=0+1066|U0C9A_0CCD.blwf=0+0] -fonts/sha1sum/270b89df543a7e48e206a2d830c0e10e5265c630.ttf:U+0D38,U+0D4D,U+0D31,U+0D4D,U+0D31,U+0D4D:[glyph201=0+1183|U0D4D=0+0] +fonts/sha1sum/57a9d9f83020155cbb1d2be1f43d82388cbecc88.ttf::U+0C9A,U+0CCD,U+0C9A,U+0CCD:[U0C9A_U0CCD.haln=0+1066|U0C9A_0CCD.blwf=0+0] +fonts/sha1sum/270b89df543a7e48e206a2d830c0e10e5265c630.ttf::U+0D38,U+0D4D,U+0D31,U+0D4D,U+0D31,U+0D4D:[glyph201=0+1183|U0D4D=0+0] diff --git a/test/shaping/tests/indic-pref-blocking.tests b/test/shaping/tests/indic-pref-blocking.tests index 260980a15..204b92a43 100644 --- a/test/shaping/tests/indic-pref-blocking.tests +++ b/test/shaping/tests/indic-pref-blocking.tests @@ -1,2 +1,2 @@ -fonts/sha1sum/226bc2deab3846f1a682085f70c67d0421014144.ttf:U+0D2F,U+0D4D,U+0D30,U+0D46:[evowelsignmlym=0+1465|rapostmlym=0+499|yamlym=0+2120] -fonts/sha1sum/e207635780b42f898d58654b65098763e340f5c7.ttf:U+0D2F,U+0D4D,U+0D30,U+0D46:[yamlym=0+2120|viramamlym=0+0|evowelsignmlym=0+1465|ramlym=0+1507] +fonts/sha1sum/226bc2deab3846f1a682085f70c67d0421014144.ttf::U+0D2F,U+0D4D,U+0D30,U+0D46:[evowelsignmlym=0+1465|rapostmlym=0+499|yamlym=0+2120] +fonts/sha1sum/e207635780b42f898d58654b65098763e340f5c7.ttf::U+0D2F,U+0D4D,U+0D30,U+0D46:[yamlym=0+2120|viramamlym=0+0|evowelsignmlym=0+1465|ramlym=0+1507] diff --git a/test/shaping/tests/mongolian-variation-selector.tests b/test/shaping/tests/mongolian-variation-selector.tests index 6b7e94a92..29d11f4cd 100644 --- a/test/shaping/tests/mongolian-variation-selector.tests +++ b/test/shaping/tests/mongolian-variation-selector.tests @@ -1,3 +1,3 @@ -fonts/sha1sum/37033cc5cf37bb223d7355153016b6ccece93b28.ttf:U+1826,U+180B,U+1826:[uni1826.E85E_ue.init1=0+599|uni1826.E856_ue.fina=2+750] -fonts/sha1sum/ef86fe710cfea877bbe0dbb6946a1f88d0661031.ttf:U+1820,U+180B:[uni1820.E821_a.isol1=0+1199] -fonts/sha1sum/bb29ce50df2bdba2d10726427c6b7609bf460e04.ttf:U+183A,U+1823,U+182E,U+182B,U+1822,U+1826,U+180B,U+1832,U+180B,U+1827,U+1837,U+0020,U+182D,U+182D,U+180B,U+0020,U+182D,U+180C,U+0020,U+182D,U+180D,U+200D,U+0020,U+182D,U+200D,U+182D,U+180B,U+200D,U+0020,U+182D,U+180C,U+200D,U+0020,U+182D,U+180D,U+200D,U+0020,U+200D,U+182D,U+200D,U+200D,U+182D,U+180B,U+200D,U+0020,U+200D,U+182D,U+180C,U+200D,U+0020,U+200D,U+182D,U+180D,U+200D,U+0020,U+200D,U+182D,U+200D,U+182D,U+180B,U+0020,U+200D,U+182D,U+180C,U+0020,U+1820,U+200C,U+182D,U+1820,U+1837,U+0020,U+1830,U+1824,U+1837,U+200D,U+200D,U+182D,U+1820,U+200D,U+0020,U+200D,U+182D,U+1824,U+182F,U+1822,U+0020,U+182A,U+1820,U+1822,U+182D,U+180E,U+1820,U+202F,U+1836,U+1822,U+1828:[uni183A1823.E971_ko.init=0+950|uni182E.E904_m.medi=2+400|uni182B1822.E8A6_pi.medi=3+1150|uni1826.E854_ue.medi1=5+1100|uni1832.E916_t.medi1=7+1000|uni1827.E85C_ee.medi=9+750|uni1837.E931_r.fina=10+750|space=11+500|uni182D.E8E2_g.init=12+1000|uni182D.E8E8_g.fina1=13+1250|space=15+500|uni182D.EA1B_g.isol2=16+1000|space=18+500|uni182D.EA1E_g.init3=19+650|space=21+0|space=22+500|uni182D.E8E2_g.init=23+1000|space=24+0|uni182D.E8E5_g.medi1=25+800|space=27+0|space=28+500|uni182D.EA1D_g.init2=29+950|space=31+0|space=32+500|uni182D.EA1E_g.init3=33+650|space=35+0|space=36+500|space=37+0|uni182D.E8E4_g.medi=38+800|space=39+0|space=40+0|uni182D.E8E5_g.medi1=41+800|space=43+0|space=44+500|space=45+0|uni182D.E8E6_g.medi2=46+650|space=48+0|space=49+500|space=50+0|uni182D.E8E6_g.medi2=51+650|space=53+0|space=54+500|space=55+0|uni182D.E8E4_g.medi=56+800|space=57+0|uni182D.E8E8_g.fina1=58+1250|space=60+500|space=61+0|uni182D.E8E9_g.fina2=62+1050|space=64+500|uni1820.E820_a.isol=65+1550|space=66+0|uni182D.E8E2_g.init=67+1000|uni1820.E823_a.medi=68+400|uni1837.E931_r.fina=69+750|space=70+500|uni1830.E90B_s.init=71+850|uni1824.E844_u.medi=72+600|uni1837.E930_r.medi=73+600|space=74+0|space=75+0|uni182D.E8E5_g.medi1=76+800|uni1820.E823_a.medi=77+400|space=78+0|space=79+500|space=80+0|uni182D.E8E5_g.medi1=81+800|uni1824.E844_u.medi=82+600|uni182F.E908_l.medi=83+400|uni1822.E837_i.fina=84+600|space=85+500|uni182A1820.E875_ba.init=86+1000|uni1822.E836_i.medi2=88+1000|uni182D.E8E8_g.fina1=89+1250|space=90+0|uni1820.E827_a.fina2=91+600|uni202F.nobreak=92+500|uni1836.E92B_y.init1=93+500|uni1822.E834_i.medi=94+500|uni1828.E866_n.fina=95+850] +fonts/sha1sum/37033cc5cf37bb223d7355153016b6ccece93b28.ttf::U+1826,U+180B,U+1826:[uni1826.E85E_ue.init1=0+599|uni1826.E856_ue.fina=2+750] +fonts/sha1sum/ef86fe710cfea877bbe0dbb6946a1f88d0661031.ttf::U+1820,U+180B:[uni1820.E821_a.isol1=0+1199] +fonts/sha1sum/bb29ce50df2bdba2d10726427c6b7609bf460e04.ttf::U+183A,U+1823,U+182E,U+182B,U+1822,U+1826,U+180B,U+1832,U+180B,U+1827,U+1837,U+0020,U+182D,U+182D,U+180B,U+0020,U+182D,U+180C,U+0020,U+182D,U+180D,U+200D,U+0020,U+182D,U+200D,U+182D,U+180B,U+200D,U+0020,U+182D,U+180C,U+200D,U+0020,U+182D,U+180D,U+200D,U+0020,U+200D,U+182D,U+200D,U+200D,U+182D,U+180B,U+200D,U+0020,U+200D,U+182D,U+180C,U+200D,U+0020,U+200D,U+182D,U+180D,U+200D,U+0020,U+200D,U+182D,U+200D,U+182D,U+180B,U+0020,U+200D,U+182D,U+180C,U+0020,U+1820,U+200C,U+182D,U+1820,U+1837,U+0020,U+1830,U+1824,U+1837,U+200D,U+200D,U+182D,U+1820,U+200D,U+0020,U+200D,U+182D,U+1824,U+182F,U+1822,U+0020,U+182A,U+1820,U+1822,U+182D,U+180E,U+1820,U+202F,U+1836,U+1822,U+1828:[uni183A1823.E971_ko.init=0+950|uni182E.E904_m.medi=2+400|uni182B1822.E8A6_pi.medi=3+1150|uni1826.E854_ue.medi1=5+1100|uni1832.E916_t.medi1=7+1000|uni1827.E85C_ee.medi=9+750|uni1837.E931_r.fina=10+750|space=11+500|uni182D.E8E2_g.init=12+1000|uni182D.E8E8_g.fina1=13+1250|space=15+500|uni182D.EA1B_g.isol2=16+1000|space=18+500|uni182D.EA1E_g.init3=19+650|space=21+0|space=22+500|uni182D.E8E2_g.init=23+1000|space=24+0|uni182D.E8E5_g.medi1=25+800|space=27+0|space=28+500|uni182D.EA1D_g.init2=29+950|space=31+0|space=32+500|uni182D.EA1E_g.init3=33+650|space=35+0|space=36+500|space=37+0|uni182D.E8E4_g.medi=38+800|space=39+0|space=40+0|uni182D.E8E5_g.medi1=41+800|space=43+0|space=44+500|space=45+0|uni182D.E8E6_g.medi2=46+650|space=48+0|space=49+500|space=50+0|uni182D.E8E6_g.medi2=51+650|space=53+0|space=54+500|space=55+0|uni182D.E8E4_g.medi=56+800|space=57+0|uni182D.E8E8_g.fina1=58+1250|space=60+500|space=61+0|uni182D.E8E9_g.fina2=62+1050|space=64+500|uni1820.E820_a.isol=65+1550|space=66+0|uni182D.E8E2_g.init=67+1000|uni1820.E823_a.medi=68+400|uni1837.E931_r.fina=69+750|space=70+500|uni1830.E90B_s.init=71+850|uni1824.E844_u.medi=72+600|uni1837.E930_r.medi=73+600|space=74+0|space=75+0|uni182D.E8E5_g.medi1=76+800|uni1820.E823_a.medi=77+400|space=78+0|space=79+500|space=80+0|uni182D.E8E5_g.medi1=81+800|uni1824.E844_u.medi=82+600|uni182F.E908_l.medi=83+400|uni1822.E837_i.fina=84+600|space=85+500|uni182A1820.E875_ba.init=86+1000|uni1822.E836_i.medi2=88+1000|uni182D.E8E8_g.fina1=89+1250|space=90+0|uni1820.E827_a.fina2=91+600|uni202F.nobreak=92+500|uni1836.E92B_y.init1=93+500|uni1822.E834_i.medi=94+500|uni1828.E866_n.fina=95+850] diff --git a/test/shaping/tests/zero-width-marks.tests b/test/shaping/tests/zero-width-marks.tests index be7ec96ee..ead3ff4d7 100644 --- a/test/shaping/tests/zero-width-marks.tests +++ b/test/shaping/tests/zero-width-marks.tests @@ -1,2 +1,2 @@ -fonts/sha1sum/bb9473d2403488714043bcfb946c9f78b86ad627.ttf:U+1030:[circledash=0+636|u1030.med=0@-162,0+0] -fonts/sha1sum/8454d22037f892e76614e1645d066689a0200e61.ttf:U+05E0,U+05B8,U+0591,U+05DA,U+05B0:[uni05DA05B0=3+991|uni2009=0+200|uni0591=0@75,0+0|uni05B8=0@495,0+0|uni05E0=0+683] +fonts/sha1sum/bb9473d2403488714043bcfb946c9f78b86ad627.ttf::U+1030:[circledash=0+636|u1030.med=0@-162,0+0] +fonts/sha1sum/8454d22037f892e76614e1645d066689a0200e61.ttf::U+05E0,U+05B8,U+0591,U+05DA,U+05B0:[uni05DA05B0=3+991|uni2009=0+200|uni0591=0@75,0+0|uni05B8=0@495,0+0|uni05E0=0+683] From 8a6a16dbcb1808c7ed50f9ba320384565bbf405a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 23 Jul 2015 12:49:09 +0100 Subject: [PATCH 60/77] [test] Add recently added test Ouch. --- test/shaping/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/test/shaping/Makefile.am b/test/shaping/Makefile.am index 70bcdd525..c7434a645 100644 --- a/test/shaping/Makefile.am +++ b/test/shaping/Makefile.am @@ -39,6 +39,7 @@ TESTS = \ tests/arabic-fallback-shaping.tests \ tests/arabic-feature-order.tests \ tests/context-matching.tests \ + tests/default-ignorables.tests \ tests/hangul-jamo.tests \ tests/indic-joiner-candrabindu.tests \ tests/indic-old-spec.tests \ From c81d957a264539dfe3252f9a94ee066c4a44edf4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 23 Jul 2015 12:50:48 +0100 Subject: [PATCH 61/77] [test] Add tests for improved 'vert' feature --- test/shaping/Makefile.am | 1 + .../191826b9643e3f124d865d617ae609db6a2ce203.ttf | Bin 0 -> 2140 bytes test/shaping/fonts/sha1sum/MANIFEST | 1 + test/shaping/tests/MANIFEST | 1 + test/shaping/tests/vertical.tests | 1 + 5 files changed, 4 insertions(+) create mode 100644 test/shaping/fonts/sha1sum/191826b9643e3f124d865d617ae609db6a2ce203.ttf create mode 100644 test/shaping/tests/vertical.tests diff --git a/test/shaping/Makefile.am b/test/shaping/Makefile.am index c7434a645..22e326e38 100644 --- a/test/shaping/Makefile.am +++ b/test/shaping/Makefile.am @@ -45,6 +45,7 @@ TESTS = \ tests/indic-old-spec.tests \ tests/indic-pref-blocking.tests \ tests/mongolian-variation-selector.tests \ + tests/vertical.tests \ tests/zero-width-marks.tests \ $(NULL) diff --git a/test/shaping/fonts/sha1sum/191826b9643e3f124d865d617ae609db6a2ce203.ttf b/test/shaping/fonts/sha1sum/191826b9643e3f124d865d617ae609db6a2ce203.ttf new file mode 100644 index 0000000000000000000000000000000000000000..dbc6e268117efd6f9e84e9813f57b7750bfa2901 GIT binary patch literal 2140 zcmeIz_j?po6vpv)W;YE&Dxn7gA=LB`YUl~Qhu*@Hglr&X2_bY)6tRGypjc3mqNt$3 zSb~V4fJ6mBMMO{$?21?uMaue}-SC@#g0s(l?m2hP%-orIo-;Be1?d*qG-F`qxPBMI zF9b>cjhIaznVFD0cWY*iWSk@)pIzv1DKIfhGTV`N$}TI73O*P@=(CYI&2r@x8e=wd ztT~m*ioAkFvj(0$UrBt4|3qi5Bj;R=^DyTtAn)vC!f%_cFZnL=*3QDxg}znhZu0Hq z{sqO^4mD6Ld5)DAIu^PbrH0KRPbZHmaunv;b_Rw@eq3MauHt#6k(gxdp+fex^xWXsNP)AkR<4tu;Op1vPO^Jv$uOw9;-e6Y7%P=C{ zM{TFI-&1SG+pSv9A=IX}jEGJ(BF(+=Ym#b?$a;ph(A8?j$l^TKmv|5t$-KFBAD+lu zmvg9jv#j8>YSU)-l+HHRJS%F475V4te!VuDyTLh489o>hr~i?Y(jZR2g<`( z2vJ;lxOc{iRcW|al^bjK7`JAm?=e?`?KZIA4nC{E_YUw|4gPmRz+F)1Zm4??1g?R4 zYa!@f2wn#v>ml?$2)iG`H$eT35b*#scn}(Hf<_NP#Za2g~4+$?oVmT!3f#eq< zr2;y=1gS4W=U1T1tI)L)y6uJTuR)J}koG$C+z-9pfZhk7&q3(>CiHs?`X7Sy!;oP_5#|4;q5wgF6oUbAG8<_Pi|IMKD*yt-h@|7Q*FhF%wSAnX>wDQt`)p~ll!2{+5_mMd`4 Date: Thu, 23 Jul 2015 12:58:21 +0100 Subject: [PATCH 62/77] [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 63/77] [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 64/77] [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 65/77] [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 +𐨤𐨪𐨌𐨪𐨿𐨗𐨸𐨅𐨌𐨏 +𐨀𐨁 +𐨐𐨁 +𐨠𐨁 +𐨀𐨂 +𐨱𐨂 +𐨨𐨂 +𐨀𐨃 +𐨨𐨃 +𐨀𐨅 +𐨐𐨅 +𐨠𐨅 +𐨡𐨅 +𐨀𐨆 +𐨤𐨆 +𐨨𐨌 +𐨯𐨍 +𐨀𐨎 +𐨐𐨏 +𐨗𐨸 +𐨒𐨹 +𐨨𐨺 +𐨢𐨁𐨐𐨿 +𐨐𐨿𐨮 +𐨨𐨿𐨪 +𐨬𐨿𐨱 +𐨯𐨿𐨟 +𐨯𐨿𐨩 +𐨪𐨿𐨟 +𐨟𐨿𐨪 +𐨫𐨿𐨤 +𐨤𐨿𐨫 +𐨐𐨿𐨫 +𐨟𐨿𐨬 +𐨐𐨿𐨟 +𐨑𐨿𐨐𐨿𐨮 From 91a2e5d2878a8c0b4d4500e3d52d4fbaaf1ac0d7 Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Wed, 8 Jul 2015 23:28:11 +0200 Subject: [PATCH 66/77] Update UCDN to upstream commit 8af93f30 This adds support for Unicode 8.0 and fixes a bug with wrong properties for ranges of codepoints. --- src/hb-ucdn.cc | 6 + src/hb-ucdn/ucdn.h | 6 + src/hb-ucdn/unicodedata_db.h | 2175 +++++++++++++++++----------------- 3 files changed, 1122 insertions(+), 1065 deletions(-) diff --git a/src/hb-ucdn.cc b/src/hb-ucdn.cc index 5b53821f9..b4a583324 100644 --- a/src/hb-ucdn.cc +++ b/src/hb-ucdn.cc @@ -148,6 +148,12 @@ static const hb_script_t ucdn_script_translate[] = HB_SCRIPT_SIDDHAM, HB_SCRIPT_TIRHUTA, HB_SCRIPT_WARANG_CITI, + HB_SCRIPT_AHOM, + HB_SCRIPT_ANATOLIAN_HIEROGLYPHS, + HB_SCRIPT_HATRAN, + HB_SCRIPT_MULTANI, + HB_SCRIPT_OLD_HUNGARIAN, + HB_SCRIPT_SIGNWRITING, }; static hb_unicode_combining_class_t diff --git a/src/hb-ucdn/ucdn.h b/src/hb-ucdn/ucdn.h index ec8085b14..8354ae533 100644 --- a/src/hb-ucdn/ucdn.h +++ b/src/hb-ucdn/ucdn.h @@ -191,6 +191,12 @@ typedef unsigned __int64 uint64_t; #define UCDN_SCRIPT_SIDDHAM 123 #define UCDN_SCRIPT_TIRHUTA 124 #define UCDN_SCRIPT_WARANG_CITI 125 +#define UCDN_SCRIPT_AHOM 126 +#define UCDN_SCRIPT_ANATOLIAN_HIEROGLYPHS 127 +#define UCDN_SCRIPT_HATRAN 128 +#define UCDN_SCRIPT_MULTANI 129 +#define UCDN_SCRIPT_OLD_HUNGARIAN 130 +#define UCDN_SCRIPT_SIGNWRITING 131 #define UCDN_GENERAL_CATEGORY_CC 0 #define UCDN_GENERAL_CATEGORY_CF 1 diff --git a/src/hb-ucdn/unicodedata_db.h b/src/hb-ucdn/unicodedata_db.h index a78d2e667..f458be14a 100644 --- a/src/hb-ucdn/unicodedata_db.h +++ b/src/hb-ucdn/unicodedata_db.h @@ -1,6 +1,6 @@ /* this file was generated by makeunicodedata.py 3.2 */ -#define UNIDATA_VERSION "7.0.0" +#define UNIDATA_VERSION "8.0.0" /* a list of unique database records */ static const UCDRecord ucd_records[] = { {2, 0, 18, 0, 5, 0, 102}, @@ -141,7 +141,7 @@ static const UCDRecord ucd_records[] = { {12, 34, 13, 0, 5, 0, 40}, {12, 220, 13, 0, 5, 0, 40}, {12, 220, 13, 0, 5, 0, 6}, - {13, 0, 11, 0, 5, 0, 0}, + {13, 0, 11, 0, 5, 0, 6}, {21, 0, 11, 0, 5, 0, 6}, {12, 35, 13, 0, 5, 0, 40}, {6, 0, 4, 0, 5, 0, 6}, @@ -300,7 +300,8 @@ static const UCDRecord ucd_records[] = { {21, 0, 0, 0, 5, 0, 25}, {15, 0, 0, 0, 5, 0, 25}, {26, 0, 18, 0, 5, 0, 25}, - {7, 0, 0, 0, 5, 0, 26}, + {9, 0, 0, 0, 5, 0, 26}, + {5, 0, 0, 0, 5, 0, 26}, {17, 0, 18, 0, 5, 0, 27}, {7, 0, 0, 0, 5, 0, 27}, {21, 0, 0, 0, 5, 0, 27}, @@ -349,7 +350,6 @@ static const UCDRecord ucd_records[] = { {13, 0, 0, 0, 5, 0, 45}, {7, 0, 0, 0, 5, 0, 46}, {7, 0, 0, 0, 5, 0, 55}, - {10, 0, 0, 0, 5, 0, 55}, {13, 0, 0, 0, 5, 0, 55}, {15, 0, 0, 0, 5, 0, 55}, {26, 0, 18, 0, 5, 0, 55}, @@ -500,7 +500,6 @@ static const UCDRecord ucd_records[] = { {15, 0, 18, 0, 2, 0, 0}, {26, 0, 0, 0, 2, 0, 33}, {7, 0, 0, 0, 2, 0, 35}, - {2, 0, 18, 0, 2, 0, 35}, {2, 0, 18, 0, 2, 0, 102}, {7, 0, 0, 0, 2, 0, 36}, {6, 0, 0, 0, 2, 0, 36}, @@ -568,10 +567,8 @@ static const UCDRecord ucd_records[] = { {6, 0, 0, 0, 5, 0, 85}, {12, 9, 13, 0, 5, 0, 85}, {13, 0, 0, 0, 5, 0, 85}, - {2, 0, 18, 0, 2, 0, 24}, {4, 0, 0, 0, 5, 0, 102}, {3, 0, 0, 0, 4, 0, 102}, - {2, 0, 18, 0, 4, 0, 102}, {12, 26, 13, 0, 5, 0, 5}, {25, 0, 9, 0, 5, 0, 5}, {24, 0, 4, 0, 5, 0, 6}, @@ -644,6 +641,8 @@ static const UCDRecord ucd_records[] = { {15, 0, 3, 0, 5, 0, 120}, {7, 0, 3, 0, 5, 0, 116}, {15, 0, 3, 0, 5, 0, 116}, + {7, 0, 3, 0, 5, 0, 128}, + {15, 0, 3, 0, 5, 0, 128}, {7, 0, 3, 0, 5, 0, 63}, {15, 0, 3, 0, 5, 0, 63}, {21, 0, 18, 0, 5, 0, 63}, @@ -651,6 +650,7 @@ static const UCDRecord ucd_records[] = { {21, 0, 3, 0, 5, 0, 75}, {7, 0, 3, 0, 5, 0, 97}, {7, 0, 3, 0, 5, 0, 96}, + {15, 0, 3, 0, 5, 0, 96}, {7, 0, 3, 0, 5, 0, 60}, {12, 0, 13, 0, 5, 0, 60}, {12, 220, 13, 0, 5, 0, 60}, @@ -680,6 +680,9 @@ static const UCDRecord ucd_records[] = { {21, 0, 3, 0, 5, 0, 122}, {15, 0, 3, 0, 5, 0, 122}, {7, 0, 3, 0, 5, 0, 90}, + {9, 0, 3, 0, 5, 0, 130}, + {5, 0, 3, 0, 5, 0, 130}, + {15, 0, 3, 0, 5, 0, 130}, {15, 0, 11, 0, 5, 0, 6}, {10, 0, 0, 0, 5, 0, 93}, {12, 0, 13, 0, 5, 0, 93}, @@ -712,6 +715,7 @@ static const UCDRecord ucd_records[] = { {7, 0, 0, 0, 5, 0, 99}, {10, 9, 0, 0, 5, 0, 99}, {21, 0, 0, 0, 5, 0, 99}, + {12, 7, 13, 0, 5, 0, 99}, {13, 0, 0, 0, 5, 0, 99}, {15, 0, 0, 0, 5, 0, 18}, {7, 0, 0, 0, 5, 0, 108}, @@ -720,6 +724,8 @@ static const UCDRecord ucd_records[] = { {10, 9, 0, 0, 5, 0, 108}, {12, 7, 13, 0, 5, 0, 108}, {21, 0, 0, 0, 5, 0, 108}, + {7, 0, 0, 0, 5, 0, 129}, + {21, 0, 0, 0, 5, 0, 129}, {7, 0, 0, 0, 5, 0, 109}, {12, 0, 13, 0, 5, 0, 109}, {10, 0, 0, 0, 5, 0, 109}, @@ -757,6 +763,14 @@ static const UCDRecord ucd_records[] = { {10, 9, 0, 0, 5, 0, 101}, {12, 7, 13, 0, 5, 0, 101}, {13, 0, 0, 0, 5, 0, 101}, + {7, 0, 0, 0, 5, 0, 126}, + {12, 0, 13, 0, 5, 0, 126}, + {10, 0, 0, 0, 5, 0, 126}, + {12, 9, 13, 0, 5, 0, 126}, + {13, 0, 0, 0, 5, 0, 126}, + {15, 0, 0, 0, 5, 0, 126}, + {21, 0, 0, 0, 5, 0, 126}, + {26, 0, 0, 0, 5, 0, 126}, {9, 0, 0, 0, 5, 0, 125}, {5, 0, 0, 0, 5, 0, 125}, {13, 0, 0, 0, 5, 0, 125}, @@ -767,6 +781,7 @@ static const UCDRecord ucd_records[] = { {14, 0, 0, 0, 5, 0, 62}, {21, 0, 0, 0, 5, 0, 62}, {7, 0, 0, 0, 5, 0, 80}, + {7, 0, 0, 0, 5, 0, 127}, {7, 0, 0, 0, 5, 0, 115}, {13, 0, 0, 0, 5, 0, 115}, {21, 0, 0, 0, 5, 0, 115}, @@ -794,6 +809,9 @@ static const UCDRecord ucd_records[] = { {12, 230, 13, 0, 5, 0, 2}, {25, 0, 0, 0, 5, 0, 0}, {13, 0, 8, 0, 5, 0, 0}, + {26, 0, 0, 0, 5, 0, 131}, + {12, 0, 13, 0, 5, 0, 131}, + {21, 0, 0, 0, 5, 0, 131}, {7, 0, 3, 0, 5, 0, 113}, {15, 0, 3, 0, 5, 0, 113}, {12, 220, 13, 0, 5, 0, 113}, @@ -1561,6 +1579,12 @@ static const Reindex nfc_last[] = { #define UCDN_SCRIPT_SIDDHAM 123 #define UCDN_SCRIPT_TIRHUTA 124 #define UCDN_SCRIPT_WARANG_CITI 125 +#define UCDN_SCRIPT_AHOM 126 +#define UCDN_SCRIPT_ANATOLIAN_HIEROGLYPHS 127 +#define UCDN_SCRIPT_HATRAN 128 +#define UCDN_SCRIPT_MULTANI 129 +#define UCDN_SCRIPT_OLD_HUNGARIAN 130 +#define UCDN_SCRIPT_SIGNWRITING 131 #define UCDN_GENERAL_CATEGORY_CC 0 #define UCDN_GENERAL_CATEGORY_CF 1 @@ -1623,252 +1647,251 @@ static const Reindex nfc_last[] = { static const unsigned char index0[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 54, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 55, 56, 57, 57, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 68, 69, 70, 70, - 71, 69, 70, 70, 72, 73, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 70, 96, 70, 97, - 98, 99, 100, 101, 102, 103, 70, 104, 70, 105, 70, 70, 70, 70, 70, 106, - 106, 106, 107, 108, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 109, 109, - 109, 109, 110, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 111, 111, 112, 113, 70, 70, 70, 114, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 115, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 116, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 117, 118, - 119, 120, 121, 122, 123, 124, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 125, 70, 70, 70, 70, 70, 126, 70, 127, 128, 129, 130, - 131, 132, 133, 134, 135, 70, 70, 70, 70, 70, 70, 70, 52, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 136, - 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 137, 138, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 76, 76, 140, 139, 139, 139, 139, 141, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 141, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 142, 143, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 73, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 144, 73, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 144, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 53, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 54, 55, 56, 56, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 66, 67, 67, 67, + 67, 67, 67, 67, 67, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 52, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 88, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 88, 99, 88, 88, 88, 88, 88, 100, 100, + 100, 101, 102, 103, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 104, 104, + 104, 104, 105, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 106, 106, 107, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 108, 108, 109, 110, 88, 88, 88, 111, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 112, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 113, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 122, 123, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 124, 88, 88, 88, 88, 88, 125, 88, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 88, 88, 88, 88, 88, 88, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 136, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 137, 138, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 139, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 52, 52, 141, 140, 140, 140, 140, 142, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 142, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 143, 144, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, 88, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 145, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 145, }; static const unsigned short index1[] = { @@ -1894,319 +1917,323 @@ static const unsigned short index1[] = { 180, 181, 182, 175, 183, 184, 185, 186, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 120, 212, 213, 214, 215, 215, 216, - 217, 218, 219, 220, 221, 120, 222, 223, 224, 120, 225, 226, 227, 228, - 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 120, 239, 240, - 241, 242, 243, 240, 244, 245, 246, 247, 248, 120, 249, 250, 251, 252, - 253, 254, 255, 256, 256, 255, 256, 257, 258, 259, 260, 261, 262, 263, - 120, 264, 265, 266, 267, 268, 268, 267, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 120, 278, 279, 280, 281, 281, 281, 281, 282, 283, 284, - 285, 120, 286, 287, 288, 289, 290, 291, 292, 293, 291, 291, 294, 295, - 292, 296, 297, 298, 299, 300, 301, 120, 302, 303, 303, 303, 303, 303, - 304, 305, 306, 307, 308, 309, 120, 120, 120, 120, 310, 311, 312, 313, - 314, 315, 316, 317, 318, 319, 320, 321, 120, 120, 120, 120, 322, 323, - 324, 325, 326, 327, 328, 329, 330, 331, 330, 330, 330, 332, 333, 334, - 335, 336, 337, 338, 337, 337, 337, 339, 340, 341, 342, 343, 120, 120, - 120, 120, 344, 344, 344, 344, 344, 345, 346, 347, 348, 349, 350, 351, - 352, 353, 354, 344, 355, 356, 348, 357, 358, 358, 358, 358, 359, 360, - 361, 361, 361, 361, 361, 362, 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, 365, 365, 365, 365, - 365, 365, 365, 365, 365, 366, 367, 366, 365, 365, 365, 365, 365, 366, - 365, 365, 365, 365, 366, 367, 366, 365, 367, 365, 365, 365, 365, 365, - 365, 365, 366, 365, 365, 365, 365, 365, 365, 365, 365, 368, 369, 370, - 371, 372, 365, 365, 373, 374, 375, 375, 375, 375, 375, 375, 375, 375, - 375, 375, 376, 120, 377, 378, 378, 378, 378, 378, 378, 378, 378, 378, - 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, - 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, - 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, - 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, - 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, 379, 378, 378, - 380, 381, 381, 382, 383, 383, 383, 383, 383, 383, 383, 383, 383, 384, - 385, 386, 387, 388, 389, 120, 390, 390, 391, 120, 392, 392, 393, 120, - 394, 395, 396, 120, 397, 397, 397, 397, 397, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 412, 412, 412, - 413, 412, 412, 412, 412, 412, 412, 120, 412, 412, 412, 412, 412, 414, - 378, 378, 378, 378, 378, 378, 378, 378, 415, 120, 416, 416, 416, 417, - 418, 419, 420, 421, 422, 423, 424, 424, 424, 425, 426, 120, 427, 427, - 427, 427, 427, 428, 429, 429, 430, 431, 432, 433, 434, 434, 434, 434, - 435, 435, 436, 437, 438, 438, 438, 438, 438, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 445, 446, 447, 448, 449, 450, 120, 120, 120, 120, - 120, 120, 120, 120, 451, 452, 452, 452, 452, 452, 453, 454, 455, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 464, 464, 465, 466, 467, 468, - 469, 469, 469, 469, 470, 471, 472, 473, 474, 474, 474, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 483, 483, 483, 484, 120, 120, 120, 120, - 120, 120, 120, 120, 485, 120, 486, 487, 488, 489, 490, 491, 54, 54, 54, - 54, 492, 493, 56, 56, 56, 56, 56, 494, 495, 496, 54, 497, 54, 54, 54, - 498, 56, 56, 56, 499, 500, 501, 502, 503, 503, 503, 504, 505, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 506, 507, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 508, 509, 510, 511, 508, 509, - 508, 509, 510, 511, 508, 512, 508, 509, 508, 510, 508, 513, 508, 513, - 508, 513, 514, 515, 516, 517, 518, 519, 508, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, - 539, 540, 56, 541, 542, 543, 542, 544, 120, 120, 545, 546, 547, 548, 549, - 120, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, - 563, 562, 564, 565, 566, 567, 568, 569, 570, 571, 572, 571, 573, 574, - 571, 575, 571, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, - 587, 588, 589, 590, 591, 586, 586, 592, 593, 594, 595, 596, 586, 586, - 597, 577, 598, 599, 586, 586, 600, 586, 586, 571, 601, 602, 571, 603, - 604, 605, 606, 606, 606, 606, 606, 606, 606, 606, 607, 571, 571, 608, - 609, 577, 577, 610, 571, 571, 571, 571, 576, 611, 571, 571, 612, 571, - 571, 571, 571, 613, 120, 120, 120, 571, 612, 120, 120, 614, 614, 614, - 614, 614, 615, 615, 616, 617, 617, 617, 617, 617, 617, 617, 617, 617, - 618, 614, 614, 619, 619, 619, 619, 619, 619, 619, 619, 619, 620, 619, - 619, 619, 619, 620, 571, 619, 619, 621, 571, 622, 572, 623, 624, 625, - 626, 572, 571, 621, 575, 571, 577, 627, 628, 624, 629, 571, 571, 571, - 571, 630, 571, 571, 571, 631, 632, 571, 571, 571, 571, 571, 633, 571, - 634, 571, 633, 635, 636, 619, 619, 637, 619, 619, 619, 571, 571, 571, - 571, 571, 571, 571, 638, 571, 571, 575, 571, 571, 639, 640, 614, 641, - 641, 642, 571, 571, 571, 571, 571, 643, 644, 645, 646, 647, 648, 577, - 577, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, - 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, - 649, 649, 649, 649, 649, 577, 577, 577, 577, 577, 577, 577, 577, 577, - 577, 577, 577, 577, 577, 577, 577, 650, 651, 651, 652, 586, 586, 577, - 653, 600, 654, 655, 656, 657, 658, 659, 660, 577, 661, 586, 662, 663, - 664, 665, 646, 577, 577, 589, 653, 665, 666, 667, 668, 586, 586, 586, - 586, 669, 670, 586, 586, 586, 586, 671, 672, 673, 646, 674, 675, 571, - 571, 571, 571, 571, 571, 577, 577, 676, 677, 678, 572, 571, 571, 679, - 571, 571, 571, 680, 571, 571, 571, 571, 681, 571, 682, 683, 120, 120, - 120, 120, 120, 684, 684, 684, 684, 684, 685, 686, 686, 686, 686, 686, - 687, 688, 689, 690, 691, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 692, 693, 694, 695, 696, 696, 696, 696, 697, 698, 699, 699, 699, 699, - 699, 699, 699, 700, 701, 702, 365, 365, 367, 120, 367, 367, 367, 367, - 367, 367, 367, 367, 703, 703, 703, 703, 704, 705, 706, 707, 708, 709, - 532, 710, 711, 120, 120, 120, 120, 120, 120, 120, 712, 712, 712, 713, - 712, 712, 712, 712, 712, 712, 712, 712, 712, 712, 714, 120, 712, 712, - 712, 712, 712, 712, 712, 712, 712, 712, 712, 712, 712, 712, 712, 712, - 712, 712, 712, 712, 712, 712, 712, 712, 712, 712, 715, 120, 120, 120, - 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 727, 727, - 727, 727, 727, 727, 727, 727, 728, 729, 730, 731, 731, 731, 731, 731, - 731, 731, 731, 731, 731, 732, 733, 734, 734, 734, 734, 735, 736, 363, - 363, 363, 363, 363, 363, 363, 363, 363, 363, 737, 738, 739, 734, 734, - 734, 740, 716, 716, 716, 716, 717, 120, 731, 731, 741, 741, 741, 742, - 743, 744, 739, 739, 739, 745, 746, 747, 741, 741, 741, 748, 743, 744, - 739, 739, 739, 739, 749, 747, 739, 750, 751, 751, 751, 751, 751, 752, - 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 739, 739, 739, - 753, 754, 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, 755, - 739, 739, 739, 753, 756, 757, 757, 757, 757, 757, 757, 757, 757, 757, - 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, - 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, - 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, - 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, - 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, - 757, 757, 757, 757, 757, 757, 758, 759, 571, 571, 571, 571, 571, 571, - 571, 571, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, - 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 760, - 759, 759, 759, 759, 759, 759, 761, 761, 762, 761, 761, 761, 761, 761, + 217, 218, 219, 220, 221, 120, 222, 223, 224, 225, 226, 227, 228, 229, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 120, 240, 241, + 242, 243, 244, 241, 245, 246, 247, 248, 249, 120, 250, 251, 252, 253, + 254, 255, 256, 257, 257, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 120, 265, 266, 267, 268, 269, 269, 268, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 120, 279, 280, 281, 282, 282, 282, 282, 283, 284, 285, + 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 293, 293, 296, 297, + 294, 298, 299, 300, 301, 302, 303, 120, 304, 305, 305, 305, 305, 305, + 306, 307, 308, 309, 310, 311, 120, 120, 120, 120, 312, 313, 314, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 120, 120, 120, 120, 324, 325, + 326, 327, 328, 329, 330, 331, 332, 333, 332, 332, 332, 334, 335, 336, + 337, 338, 339, 340, 339, 339, 339, 341, 342, 343, 344, 345, 120, 120, + 120, 120, 346, 346, 346, 346, 346, 347, 348, 349, 350, 351, 352, 353, + 354, 355, 356, 346, 357, 358, 350, 359, 360, 360, 360, 360, 361, 362, + 363, 363, 363, 363, 363, 364, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, + 366, 366, 366, 366, 366, 366, 366, 366, 366, 366, 367, 367, 367, 367, + 367, 367, 367, 367, 367, 368, 369, 368, 367, 367, 367, 367, 367, 368, + 367, 367, 367, 367, 368, 369, 368, 367, 369, 367, 367, 367, 367, 367, + 367, 367, 368, 367, 367, 367, 367, 367, 367, 367, 367, 370, 371, 372, + 373, 374, 367, 367, 375, 376, 377, 377, 377, 377, 377, 377, 377, 377, + 377, 377, 378, 379, 380, 381, 381, 381, 381, 381, 381, 381, 381, 381, + 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, + 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, + 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, + 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, + 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, 382, 381, 381, + 383, 384, 384, 385, 386, 386, 386, 386, 386, 386, 386, 386, 386, 387, + 388, 389, 390, 391, 392, 120, 393, 393, 394, 120, 395, 395, 396, 120, + 397, 398, 399, 120, 400, 400, 400, 400, 400, 400, 401, 402, 403, 404, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 415, 415, 415, + 416, 415, 415, 415, 415, 415, 415, 120, 415, 415, 415, 415, 415, 417, + 381, 381, 381, 381, 381, 381, 381, 381, 418, 120, 419, 419, 419, 420, + 421, 422, 423, 424, 425, 426, 427, 427, 427, 428, 429, 120, 430, 430, + 430, 430, 430, 431, 430, 430, 430, 432, 433, 434, 435, 435, 435, 435, + 436, 436, 437, 438, 439, 439, 439, 439, 439, 439, 440, 441, 442, 443, + 444, 445, 446, 447, 446, 447, 448, 449, 450, 451, 120, 120, 120, 120, + 120, 120, 120, 120, 452, 453, 453, 453, 453, 453, 454, 455, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 465, 465, 466, 467, 468, 469, + 470, 470, 470, 470, 471, 472, 473, 474, 475, 475, 475, 475, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 484, 484, 485, 120, 120, 120, 120, + 120, 120, 120, 120, 486, 120, 487, 488, 489, 490, 491, 492, 54, 54, 54, + 54, 493, 494, 56, 56, 56, 56, 56, 495, 496, 497, 54, 498, 54, 54, 54, + 499, 56, 56, 56, 500, 501, 502, 503, 504, 504, 504, 505, 506, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 507, 508, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 509, 510, 511, 512, 509, 510, + 509, 510, 511, 512, 509, 513, 509, 510, 509, 511, 509, 514, 509, 514, + 509, 514, 515, 516, 517, 518, 519, 520, 509, 521, 522, 523, 524, 525, + 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, + 540, 541, 56, 542, 543, 544, 543, 545, 120, 120, 546, 547, 548, 549, 550, + 120, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, + 564, 563, 565, 566, 567, 568, 569, 570, 571, 572, 573, 572, 574, 575, + 572, 576, 572, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, + 588, 589, 590, 591, 592, 587, 587, 593, 594, 595, 596, 597, 587, 587, + 598, 578, 599, 600, 587, 587, 601, 587, 587, 572, 602, 603, 572, 604, + 605, 606, 607, 607, 607, 607, 607, 607, 607, 607, 608, 572, 572, 609, + 610, 578, 578, 611, 572, 572, 572, 572, 577, 612, 572, 572, 613, 572, + 572, 572, 572, 614, 120, 120, 120, 572, 613, 120, 120, 615, 615, 615, + 615, 615, 616, 616, 617, 618, 618, 618, 618, 618, 618, 618, 618, 618, + 619, 615, 615, 620, 620, 620, 620, 620, 620, 620, 620, 620, 621, 620, + 620, 620, 620, 621, 572, 620, 620, 622, 572, 623, 573, 624, 625, 626, + 627, 573, 572, 622, 576, 572, 578, 628, 629, 625, 630, 572, 572, 572, + 572, 631, 572, 572, 572, 632, 633, 572, 572, 572, 572, 572, 634, 572, + 635, 572, 634, 636, 637, 620, 620, 638, 620, 620, 620, 572, 572, 572, + 572, 572, 572, 572, 639, 572, 572, 576, 572, 572, 640, 641, 615, 642, + 642, 643, 572, 572, 572, 572, 572, 644, 645, 646, 647, 648, 649, 578, + 578, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + 650, 650, 650, 650, 650, 578, 578, 578, 578, 578, 578, 578, 578, 578, + 578, 578, 578, 578, 578, 578, 578, 651, 652, 652, 653, 587, 587, 578, + 654, 601, 655, 656, 657, 658, 659, 660, 661, 578, 662, 587, 663, 664, + 665, 666, 647, 578, 578, 590, 654, 666, 667, 668, 669, 587, 587, 587, + 587, 670, 671, 587, 587, 587, 587, 672, 673, 674, 647, 675, 676, 572, + 572, 572, 572, 572, 572, 578, 578, 677, 678, 679, 573, 572, 572, 680, + 572, 572, 572, 681, 572, 572, 572, 572, 682, 572, 683, 684, 120, 120, + 685, 120, 120, 686, 686, 686, 686, 686, 687, 688, 688, 688, 688, 688, + 689, 690, 691, 692, 693, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 694, 695, 696, 697, 698, 698, 698, 698, 699, 700, 701, 701, 701, 701, + 701, 701, 701, 702, 703, 704, 367, 367, 369, 120, 369, 369, 369, 369, + 369, 369, 369, 369, 705, 705, 705, 705, 706, 707, 708, 709, 710, 711, + 533, 712, 713, 120, 120, 120, 120, 120, 120, 120, 714, 714, 714, 715, + 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 716, 120, 714, 714, + 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, + 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 717, 120, 120, 120, + 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 729, 729, + 729, 729, 729, 729, 729, 729, 730, 731, 732, 733, 733, 733, 733, 733, + 733, 733, 733, 733, 733, 734, 735, 736, 736, 736, 736, 737, 738, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 739, 740, 741, 736, 736, + 736, 742, 718, 718, 718, 718, 719, 120, 733, 733, 743, 743, 743, 744, + 745, 746, 741, 741, 741, 747, 748, 749, 743, 743, 743, 750, 745, 746, + 741, 741, 741, 741, 751, 749, 741, 752, 753, 753, 753, 753, 753, 754, + 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 741, 741, 741, + 755, 756, 741, 741, 741, 741, 741, 741, 741, 741, 741, 741, 741, 757, + 741, 741, 741, 755, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 759, 760, 572, 572, 572, 572, 572, 572, 572, 572, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 759, 760, 760, 760, + 760, 760, 761, 761, 762, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, - 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, - 761, 761, 761, 763, 764, 764, 764, 764, 764, 764, 765, 120, 766, 766, - 766, 766, 766, 767, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 763, + 764, 764, 764, 764, 764, 764, 765, 120, 766, 766, 766, 766, 766, 767, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, - 768, 768, 768, 768, 768, 768, 768, 768, 768, 769, 768, 768, 770, 771, - 120, 120, 101, 101, 101, 101, 101, 772, 773, 774, 101, 101, 101, 775, - 776, 776, 776, 776, 776, 776, 776, 776, 777, 778, 779, 120, 64, 64, 780, - 781, 782, 27, 783, 27, 27, 27, 27, 27, 27, 27, 784, 785, 27, 786, 787, - 27, 27, 788, 789, 120, 120, 120, 120, 120, 120, 120, 790, 791, 792, 793, - 794, 794, 795, 796, 797, 798, 799, 799, 799, 799, 799, 799, 800, 120, - 801, 802, 802, 802, 802, 802, 803, 804, 805, 806, 807, 808, 809, 809, - 810, 811, 812, 813, 814, 814, 815, 816, 817, 817, 818, 819, 820, 821, - 363, 363, 363, 822, 823, 824, 824, 824, 824, 824, 825, 826, 827, 828, - 829, 830, 831, 344, 348, 832, 833, 833, 833, 833, 833, 834, 835, 120, - 836, 837, 838, 839, 344, 344, 840, 841, 842, 842, 842, 842, 842, 842, - 843, 844, 845, 120, 120, 846, 847, 848, 849, 120, 850, 850, 850, 120, - 367, 367, 54, 54, 54, 54, 54, 851, 852, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 847, 847, 847, 847, 853, 854, 855, 856, 857, - 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, - 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, - 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, - 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, - 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, - 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 858, 859, - 120, 364, 364, 860, 861, 364, 364, 364, 364, 364, 862, 863, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 864, 863, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 864, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 864, 865, - 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, - 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, - 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, - 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, - 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, - 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, - 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 867, 868, 868, 868, - 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, - 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, - 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, - 869, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, 868, - 870, 759, 759, 759, 759, 871, 120, 872, 873, 121, 874, 875, 876, 877, - 121, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 878, - 879, 880, 120, 881, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, 768, 768, 768, 768, 769, 768, 768, 770, 771, 120, 120, 101, 101, + 101, 101, 101, 772, 773, 774, 101, 101, 101, 775, 776, 776, 776, 776, + 776, 776, 776, 776, 777, 778, 779, 120, 64, 64, 780, 781, 782, 27, 783, + 27, 27, 27, 27, 27, 27, 27, 784, 785, 27, 786, 787, 27, 27, 788, 789, + 120, 120, 120, 120, 120, 120, 120, 790, 791, 792, 793, 794, 794, 795, + 796, 797, 798, 799, 799, 799, 799, 799, 799, 800, 120, 801, 802, 802, + 802, 802, 802, 803, 804, 805, 806, 807, 808, 809, 809, 810, 811, 812, + 813, 814, 814, 815, 816, 817, 817, 818, 819, 820, 821, 365, 365, 365, + 822, 823, 824, 824, 824, 824, 824, 825, 826, 827, 828, 829, 830, 831, + 346, 350, 832, 833, 833, 833, 833, 833, 834, 835, 120, 836, 837, 838, + 839, 346, 346, 840, 841, 842, 842, 842, 842, 842, 842, 843, 844, 845, + 120, 120, 846, 847, 848, 849, 120, 850, 850, 850, 120, 369, 369, 54, 54, + 54, 54, 54, 851, 852, 120, 853, 853, 853, 853, 853, 853, 853, 853, 853, + 853, 847, 847, 847, 847, 854, 855, 856, 857, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 365, 858, 120, 366, 366, 859, 860, 366, 366, 366, + 366, 366, 861, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, + 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, + 862, 862, 862, 862, 862, 862, 862, 863, 863, 863, 863, 863, 863, 863, + 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, + 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 759, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 864, 760, 760, 760, + 760, 865, 120, 866, 867, 121, 868, 869, 870, 871, 121, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 872, 873, 874, 120, 875, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 882, 120, 120, 128, 128, 128, 128, 128, - 128, 128, 128, 883, 128, 128, 128, 128, 128, 128, 120, 120, 120, 120, - 120, 128, 884, 885, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, - 895, 896, 897, 898, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 899, 900, 901, 902, 903, 904, 905, 905, - 906, 907, 908, 908, 909, 910, 911, 912, 911, 911, 911, 911, 913, 914, - 914, 914, 915, 916, 916, 916, 917, 918, 919, 120, 920, 921, 922, 921, - 921, 923, 921, 921, 924, 921, 925, 921, 925, 120, 120, 120, 120, 921, - 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, - 926, 927, 928, 928, 928, 928, 928, 929, 606, 930, 930, 930, 930, 930, - 930, 931, 932, 933, 934, 571, 935, 936, 120, 120, 120, 120, 120, 606, - 606, 606, 606, 606, 937, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 938, 938, 938, 939, 940, 940, 940, - 940, 940, 940, 941, 120, 942, 943, 943, 944, 945, 945, 945, 945, 946, - 120, 947, 947, 948, 949, 950, 950, 950, 950, 951, 952, 953, 953, 953, - 954, 955, 955, 955, 955, 956, 955, 957, 120, 120, 120, 120, 120, 958, - 958, 958, 958, 958, 959, 959, 959, 959, 959, 960, 960, 960, 960, 960, - 960, 961, 961, 961, 962, 963, 964, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 965, 965, 965, 965, 965, 120, 966, 966, 966, 966, 966, - 966, 967, 968, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 969, 969, 969, 969, 969, 969, 969, - 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, - 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, - 969, 969, 969, 970, 120, 969, 969, 971, 120, 969, 120, 120, 120, 120, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 876, 120, 120, 128, 128, 128, 128, 128, 128, 128, 128, 877, + 128, 128, 128, 128, 128, 128, 120, 120, 120, 120, 120, 128, 878, 879, + 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 893, 894, 895, 896, 897, 898, 899, 899, 900, 901, 902, 902, + 903, 904, 905, 906, 905, 905, 905, 905, 907, 908, 908, 908, 909, 910, + 910, 910, 911, 912, 913, 120, 914, 915, 916, 915, 915, 917, 915, 915, + 918, 915, 919, 915, 919, 120, 120, 120, 120, 915, 915, 915, 915, 915, + 915, 915, 915, 915, 915, 915, 915, 915, 915, 915, 920, 921, 922, 922, + 922, 922, 922, 923, 607, 924, 924, 924, 924, 924, 924, 925, 926, 927, + 928, 572, 929, 930, 120, 120, 120, 120, 120, 607, 607, 607, 607, 607, + 931, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 932, 932, 932, 933, 934, 934, 934, 934, 934, 934, 935, + 120, 936, 937, 937, 938, 939, 939, 939, 939, 940, 120, 941, 941, 942, + 943, 944, 944, 944, 944, 945, 946, 947, 947, 947, 948, 949, 949, 949, + 949, 950, 949, 951, 120, 120, 120, 120, 120, 952, 952, 952, 952, 952, + 953, 953, 953, 953, 953, 954, 954, 954, 954, 954, 954, 955, 955, 955, + 956, 957, 958, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 959, + 959, 959, 959, 959, 120, 960, 960, 960, 960, 960, 960, 961, 962, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 972, 973, 974, 974, 974, 974, 975, 976, 977, 977, 978, 979, 980, - 980, 981, 982, 983, 983, 983, 984, 985, 986, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 987, 987, 988, 989, 990, 990, 990, 991, 120, - 120, 120, 120, 120, 120, 120, 120, 992, 992, 992, 992, 993, 993, 993, - 994, 120, 120, 120, 120, 120, 120, 120, 120, 995, 996, 997, 998, 999, - 999, 1000, 1001, 1002, 120, 1003, 1004, 1005, 1005, 1005, 1006, 1007, - 1007, 1007, 1008, 120, 120, 120, 120, 1009, 1010, 1009, 1009, 1011, 1012, - 1013, 120, 1014, 1014, 1014, 1014, 1014, 1014, 1015, 1016, 1017, 1017, - 1018, 1019, 1020, 1020, 1021, 1022, 1023, 1023, 1024, 1025, 120, 1026, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1027, 1027, 1027, 1027, - 1027, 1027, 1027, 1027, 1027, 1028, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, + 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, + 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 964, + 120, 963, 963, 965, 120, 963, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 966, 967, 968, + 968, 968, 968, 969, 970, 971, 971, 972, 973, 974, 974, 975, 976, 977, + 977, 977, 978, 979, 980, 120, 120, 120, 120, 120, 120, 981, 981, 982, + 983, 984, 984, 985, 986, 987, 987, 987, 988, 120, 120, 120, 120, 120, + 120, 120, 120, 989, 989, 989, 989, 990, 990, 990, 991, 992, 992, 993, + 992, 992, 992, 992, 992, 994, 995, 996, 997, 998, 998, 999, 1000, 1001, + 120, 1002, 1003, 1004, 1004, 1004, 1005, 1006, 1006, 1006, 1007, 120, + 120, 120, 120, 1008, 1009, 1008, 1008, 1010, 1011, 1012, 120, 1013, 1013, + 1013, 1013, 1013, 1013, 1014, 1015, 1016, 1016, 1017, 1018, 1019, 1019, + 1020, 1021, 1022, 1022, 1023, 1024, 120, 1025, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, + 1026, 1027, 120, 120, 120, 120, 120, 120, 1028, 1028, 1028, 1028, 1028, + 1028, 1029, 120, 1030, 1030, 1030, 1030, 1030, 1030, 1031, 1032, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1029, - 1029, 1029, 1030, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 1031, 1032, 1032, 1032, 1032, 1032, 1032, 1033, - 1034, 1035, 1036, 1037, 1038, 1039, 120, 1040, 1041, 1042, 1042, 1042, - 1042, 1042, 1043, 1044, 1045, 120, 1046, 1046, 1046, 1047, 1048, 1049, - 1050, 1051, 1051, 1051, 1052, 1053, 1054, 1055, 1056, 120, 1057, 1057, - 1057, 1057, 1058, 120, 1059, 1060, 1060, 1060, 1060, 1060, 1061, 1062, - 1063, 1064, 1065, 1066, 1067, 1068, 1069, 120, 1070, 1070, 1071, 1070, - 1070, 1072, 1073, 1074, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 1075, 1075, 1075, 1075, 1075, 1076, 1077, 1078, 1079, - 1080, 1081, 1082, 1083, 1084, 1084, 1085, 1086, 1087, 1088, 1089, 1090, - 1091, 1092, 1093, 1093, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 1094, 1094, 1094, 1094, - 1094, 1094, 1095, 1096, 1097, 120, 1098, 1099, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 1100, 1100, 1100, 1100, 1100, 1101, 1102, 1103, 1104, 1105, 120, - 120, 120, 120, 120, 120, 1106, 1106, 1106, 1106, 1106, 1106, 1107, 1108, - 1109, 120, 1110, 1111, 120, 120, 120, 120, 1112, 1112, 1112, 1112, 1112, - 1113, 1114, 120, 1115, 1116, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 1033, 1033, 1033, 1034, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 1035, 1036, 1036, 1036, 1036, 1036, + 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 120, 1044, 1045, 1046, + 1046, 1046, 1046, 1046, 1047, 1048, 1049, 120, 1050, 1050, 1050, 1051, + 1052, 1053, 1054, 1055, 1055, 1055, 1056, 1057, 1058, 1059, 1060, 120, + 1061, 1061, 1061, 1061, 1062, 120, 1063, 1064, 1064, 1064, 1064, 1064, + 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 120, 1074, 1074, + 1075, 1074, 1074, 1076, 1077, 1078, 120, 120, 120, 120, 120, 120, 120, + 120, 1079, 1080, 1081, 1082, 1081, 1083, 1084, 1084, 1084, 1084, 1084, + 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1093, 1094, 1095, + 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1102, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 1117, 1117, 1117, 1117, 1118, 1118, 1118, 1118, 1119, - 1120, 1121, 1122, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1123, - 1123, 1123, 1123, 1123, 1123, 1123, 1124, 1125, 1125, 1125, 1125, 1125, - 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, - 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, - 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, - 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1126, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1127, 1127, 1127, - 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1128, 1129, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, - 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, - 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, 1130, - 1130, 1130, 1130, 1130, 1131, 120, 120, 120, 120, 120, 120, 120, 120, + 1103, 1103, 1103, 1103, 1103, 1103, 1104, 1105, 1106, 120, 1107, 1108, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 120, 120, 120, 120, 120, 120, 1109, 1109, 1109, 1109, 1109, 1110, 1111, + 1112, 1113, 1114, 1114, 1115, 120, 120, 120, 120, 1116, 1116, 1116, 1116, + 1116, 1116, 1117, 1118, 1119, 120, 1120, 1121, 120, 120, 120, 120, 1122, + 1122, 1122, 1122, 1122, 1123, 1124, 120, 1125, 1126, 120, 120, 120, 120, + 120, 120, 1127, 1127, 1127, 1128, 1129, 1130, 1131, 1132, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1133, + 1133, 1133, 1133, 1134, 1134, 1134, 1134, 1135, 1136, 1137, 1138, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 1139, 1139, 1139, 1139, + 1139, 1139, 1139, 1140, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, + 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, + 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, + 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, + 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1142, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 1143, 1143, 1143, 1143, 1143, 1143, + 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1144, 1145, 120, 1141, 1141, + 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, + 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1146, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 1147, 1147, 1147, 1147, 1147, + 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, + 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, + 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1148, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 1149, 1149, 1149, 1149, 1149, + 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, + 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, + 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1149, 1150, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, - 776, 1132, 1133, 1133, 1133, 1134, 1135, 1136, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 1137, 1137, 1137, 1138, 1139, 120, - 1140, 1140, 1140, 1140, 1140, 1140, 1141, 1142, 1143, 120, 1144, 1145, - 1146, 1140, 1140, 1147, 1140, 1140, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 1148, 1148, 1148, 1148, 1148, 1148, - 1148, 1148, 1149, 120, 1150, 1151, 1151, 1151, 1151, 1152, 120, 1153, - 1154, 1155, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 1156, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 776, 776, 776, 776, 776, 776, 1151, 1152, 1152, 1152, 1153, 1154, 1155, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1156, 1156, + 1156, 1157, 1158, 120, 1159, 1159, 1159, 1159, 1159, 1159, 1160, 1161, + 1162, 120, 1163, 1164, 1165, 1159, 1159, 1166, 1159, 1159, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1167, 1167, 1167, + 1167, 1167, 1167, 1167, 1167, 1168, 120, 1169, 1170, 1170, 1170, 1170, + 1171, 120, 1172, 1173, 1174, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 1175, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, - 1157, 1157, 1157, 1157, 1158, 1157, 1159, 1157, 1160, 1157, 1161, 1162, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 606, 606, 606, - 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, - 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 1163, - 120, 606, 606, 606, 606, 1164, 1165, 606, 606, 606, 606, 606, 606, 1166, - 1167, 1168, 1169, 1170, 1171, 606, 606, 606, 1172, 606, 606, 606, 606, - 606, 1163, 120, 120, 120, 120, 933, 933, 933, 933, 933, 933, 933, 933, - 1173, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 571, 571, 571, 571, - 571, 571, 571, 571, 571, 571, 613, 120, 928, 928, 1174, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 1176, 1176, 1176, 1176, 1176, 1176, + 1176, 1176, 1176, 1176, 1176, 1176, 1176, 1177, 1176, 1178, 1176, 1179, + 1176, 1180, 1181, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, + 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, + 607, 607, 1182, 120, 607, 607, 607, 607, 1183, 1184, 607, 607, 607, 607, + 607, 607, 1185, 1186, 1187, 1188, 1189, 1190, 607, 607, 607, 1191, 607, + 607, 607, 607, 607, 607, 607, 1192, 120, 120, 927, 927, 927, 927, 927, + 927, 927, 927, 1193, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 572, + 572, 572, 572, 572, 572, 572, 572, 572, 572, 614, 120, 922, 922, 1194, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 1175, 1175, 1175, 1176, 1177, 1177, 1178, 1175, 1175, 1179, 1180, 1177, - 1177, 1175, 1175, 1175, 1176, 1177, 1177, 1181, 1182, 1183, 1179, 1184, - 1185, 1177, 1175, 1175, 1175, 1176, 1177, 1177, 1186, 1187, 1188, 1189, - 1177, 1177, 1177, 1190, 1191, 1192, 1193, 1177, 1177, 1178, 1175, 1175, - 1179, 1177, 1177, 1177, 1175, 1175, 1175, 1176, 1177, 1177, 1178, 1175, - 1175, 1179, 1177, 1177, 1177, 1175, 1175, 1175, 1176, 1177, 1177, 1178, - 1175, 1175, 1179, 1177, 1177, 1177, 1175, 1175, 1175, 1176, 1177, 1177, - 1194, 1175, 1175, 1175, 1195, 1177, 1177, 1196, 1197, 1175, 1175, 1198, - 1177, 1177, 1199, 1178, 1175, 1175, 1200, 1177, 1177, 1201, 1202, 1175, - 1175, 1203, 1177, 1177, 1177, 1204, 1175, 1175, 1175, 1195, 1177, 1177, - 1196, 1205, 1206, 1206, 1206, 1206, 1206, 1206, 1207, 1207, 1207, 1207, - 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, - 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1207, 1208, 1209, 1210, 120, - 120, 120, 120, 120, 1211, 128, 128, 128, 1212, 1213, 1214, 1215, 1216, - 1217, 1212, 1218, 1212, 1214, 1214, 1219, 128, 1220, 128, 1221, 1222, - 1220, 128, 1221, 120, 120, 120, 120, 120, 120, 1223, 120, 571, 571, 571, - 571, 571, 935, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, - 571, 935, 120, 571, 613, 1224, 571, 1224, 571, 1224, 571, 571, 571, 680, - 120, 615, 1225, 617, 617, 617, 1226, 617, 617, 617, 617, 617, 617, 617, - 1227, 617, 617, 617, 617, 617, 1228, 120, 120, 120, 120, 120, 120, 120, - 120, 1229, 606, 606, 606, 1230, 120, 739, 739, 739, 739, 739, 1231, 739, - 1232, 1233, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 571, 571, 571, 571, 571, - 1234, 571, 571, 571, 571, 571, 571, 571, 571, 571, 680, 571, 571, 571, - 571, 571, 571, 571, 571, 571, 613, 1235, 571, 571, 571, 571, 120, 571, - 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, - 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, - 571, 571, 613, 571, 571, 571, 571, 571, 571, 571, 571, 571, 612, 571, - 571, 571, 571, 571, 1236, 571, 571, 571, 571, 1237, 571, 571, 571, 571, - 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, - 571, 1238, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, - 571, 571, 571, 571, 571, 120, 120, 571, 1234, 935, 120, 571, 571, 571, - 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 935, 120, 571, - 571, 571, 571, 571, 571, 571, 571, 571, 571, 1234, 120, 120, 120, 120, - 120, 571, 935, 571, 571, 571, 571, 571, 571, 571, 120, 571, 683, 571, - 571, 571, 571, 571, 120, 571, 571, 571, 680, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 757, 757, 757, 757, 757, 757, 757, 757, 757, - 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, - 757, 757, 757, 1239, 759, 759, 759, 759, 759, 757, 757, 757, 757, 757, - 757, 760, 759, 756, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, - 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, 757, - 757, 757, 758, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, - 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, - 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, - 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, - 759, 759, 759, 759, 759, 759, 759, 868, 868, 868, 869, 759, 759, 759, - 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, - 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, - 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, - 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, - 1240, 1241, 120, 120, 120, 1242, 1242, 1242, 1242, 1242, 1242, 1242, - 1242, 1242, 1242, 1242, 1242, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 885, 885, 885, 885, 885, 885, - 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, - 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 120, 120, 866, 866, - 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, - 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, - 866, 1243, + 120, 120, 120, 1195, 1195, 1195, 1196, 1197, 1197, 1198, 1195, 1195, + 1199, 1200, 1197, 1197, 1195, 1195, 1195, 1196, 1197, 1197, 1201, 1202, + 1203, 1199, 1204, 1205, 1197, 1195, 1195, 1195, 1196, 1197, 1197, 1206, + 1207, 1208, 1209, 1197, 1197, 1197, 1210, 1211, 1212, 1213, 1197, 1197, + 1198, 1195, 1195, 1199, 1197, 1197, 1197, 1195, 1195, 1195, 1196, 1197, + 1197, 1198, 1195, 1195, 1199, 1197, 1197, 1197, 1195, 1195, 1195, 1196, + 1197, 1197, 1198, 1195, 1195, 1199, 1197, 1197, 1197, 1195, 1195, 1195, + 1196, 1197, 1197, 1214, 1195, 1195, 1195, 1215, 1197, 1197, 1216, 1217, + 1195, 1195, 1218, 1197, 1197, 1219, 1198, 1195, 1195, 1220, 1197, 1197, + 1221, 1222, 1195, 1195, 1223, 1197, 1197, 1197, 1224, 1195, 1195, 1195, + 1215, 1197, 1197, 1216, 1225, 1226, 1226, 1226, 1226, 1226, 1226, 1227, + 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, + 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1227, + 1227, 1227, 1227, 1227, 1227, 1227, 1227, 1228, 1228, 1228, 1228, 1228, + 1228, 1229, 1230, 1228, 1228, 1228, 1228, 1228, 1231, 1232, 1227, 1233, + 1234, 120, 1235, 1236, 1228, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, + 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, + 1237, 1238, 1239, 1240, 120, 120, 120, 120, 120, 1241, 128, 128, 128, + 1242, 1243, 1244, 1245, 1246, 1247, 1242, 1248, 1242, 1244, 1244, 1249, + 128, 1250, 128, 1251, 1252, 1250, 128, 1251, 120, 120, 120, 120, 120, + 120, 1253, 120, 572, 572, 572, 572, 572, 929, 572, 572, 572, 572, 572, + 572, 572, 572, 572, 572, 572, 572, 929, 120, 572, 614, 1254, 572, 1254, + 572, 1254, 572, 572, 572, 681, 120, 616, 1255, 618, 618, 618, 1256, 618, + 618, 618, 618, 618, 618, 618, 1257, 618, 618, 618, 618, 618, 1258, 120, + 120, 120, 120, 120, 120, 120, 120, 1259, 607, 607, 607, 1260, 120, 741, + 741, 741, 741, 741, 1261, 741, 1262, 1263, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, + 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, + 572, 572, 572, 572, 1264, 572, 572, 572, 572, 572, 572, 572, 572, 572, + 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, + 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, + 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 1265, 572, 572, 572, + 572, 1266, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, + 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, + 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 1267, 120, 572, + 1268, 929, 120, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, + 572, 572, 572, 929, 120, 572, 572, 572, 572, 572, 572, 572, 572, 572, + 572, 1268, 120, 120, 120, 120, 120, 572, 929, 572, 572, 572, 572, 572, + 572, 572, 120, 572, 684, 572, 572, 572, 572, 572, 120, 572, 572, 572, + 681, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 572, + 1267, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1268, + 120, 120, 120, 120, 120, 120, 120, 1267, 120, 120, 120, 120, 120, 120, + 120, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 1269, + 760, 760, 760, 760, 760, 758, 758, 758, 758, 758, 758, 1270, 760, 758, + 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 759, 758, + 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 864, 760, 760, 760, 760, 760, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 760, 758, 758, 758, 759, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, + 1271, 1272, 120, 120, 120, 1273, 1273, 1273, 1273, 1273, 1273, 1273, + 1273, 1273, 1273, 1273, 1273, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 879, 879, 879, 879, 879, 879, + 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, + 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 120, 120, 863, 863, + 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, + 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, + 863, 1274, }; static const unsigned short index2[] = { @@ -2289,109 +2316,110 @@ static const unsigned short index2[] = { 161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 161, 160, 160, 160, 161, 160, 160, 160, 160, 160, 64, 64, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 64, 163, 163, 163, 163, 163, 163, - 163, 163, 163, 164, 164, 164, 64, 64, 165, 64, 126, 126, 126, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 120, 120, 137, 120, 120, 137, 120, 120, 120, 137, - 137, 137, 166, 167, 168, 120, 120, 120, 137, 120, 120, 137, 137, 120, - 120, 120, 120, 120, 169, 169, 169, 170, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, 169, 170, 172, 171, 170, 170, - 170, 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 173, - 170, 170, 171, 78, 136, 174, 174, 169, 169, 169, 171, 171, 169, 169, 84, - 84, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 176, 177, 171, 171, - 171, 171, 171, 171, 178, 179, 180, 180, 64, 178, 178, 178, 178, 178, 178, - 178, 178, 64, 64, 178, 178, 64, 64, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 64, 178, 178, 178, 178, 178, 178, 178, - 64, 178, 64, 64, 64, 178, 178, 178, 178, 64, 64, 181, 178, 180, 180, 180, - 179, 179, 179, 179, 64, 64, 180, 180, 64, 64, 180, 180, 182, 178, 64, 64, - 64, 64, 64, 64, 64, 64, 180, 64, 64, 64, 64, 178, 178, 64, 178, 178, 178, - 179, 179, 64, 64, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 178, - 178, 184, 184, 185, 185, 185, 185, 185, 185, 186, 184, 64, 64, 64, 64, - 64, 187, 187, 188, 64, 189, 189, 189, 189, 189, 189, 64, 64, 64, 64, 189, - 189, 64, 64, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 64, 189, 189, 189, 189, 189, 189, 189, 64, 189, 189, 64, 189, - 189, 64, 189, 189, 64, 64, 190, 64, 188, 188, 188, 187, 187, 64, 64, 64, - 64, 187, 187, 64, 64, 187, 187, 191, 64, 64, 64, 187, 64, 64, 64, 64, 64, - 64, 64, 189, 189, 189, 189, 64, 189, 64, 64, 64, 64, 64, 64, 64, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 187, 187, 189, 189, 189, - 187, 64, 64, 64, 193, 193, 194, 64, 195, 195, 195, 195, 195, 195, 195, - 195, 195, 64, 195, 195, 195, 64, 195, 195, 195, 195, 195, 195, 195, 195, - 195, 195, 195, 195, 195, 195, 64, 195, 195, 195, 195, 195, 195, 195, 64, - 195, 195, 64, 195, 195, 195, 195, 195, 64, 64, 196, 195, 194, 194, 194, - 193, 193, 193, 193, 193, 64, 193, 193, 194, 64, 194, 194, 197, 64, 64, - 195, 64, 64, 64, 64, 64, 64, 64, 195, 195, 193, 193, 64, 64, 198, 198, - 198, 198, 198, 198, 198, 198, 198, 198, 199, 200, 64, 64, 64, 64, 64, 64, - 64, 201, 202, 202, 64, 203, 203, 203, 203, 203, 203, 203, 203, 64, 64, - 203, 203, 64, 64, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 64, 203, 203, 203, 203, 203, 203, 203, 64, 203, 203, 64, - 203, 203, 203, 203, 203, 64, 64, 204, 203, 202, 201, 202, 201, 201, 201, - 201, 64, 64, 202, 202, 64, 64, 202, 202, 205, 64, 64, 64, 64, 64, 64, 64, - 64, 201, 202, 64, 64, 64, 64, 203, 203, 64, 203, 203, 203, 201, 201, 64, - 64, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 207, 203, 208, 208, - 208, 208, 208, 208, 64, 64, 209, 210, 64, 210, 210, 210, 210, 210, 210, - 64, 64, 64, 210, 210, 210, 64, 210, 210, 210, 210, 64, 64, 64, 210, 210, - 64, 210, 64, 210, 210, 64, 64, 64, 210, 210, 64, 64, 64, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 64, 64, 64, 64, 211, 211, 209, 211, - 211, 64, 64, 64, 211, 211, 211, 64, 211, 211, 211, 212, 64, 64, 210, 64, - 64, 64, 64, 64, 64, 211, 64, 64, 64, 64, 64, 64, 213, 213, 213, 213, 213, - 213, 213, 213, 213, 213, 214, 214, 214, 215, 215, 215, 215, 215, 215, - 216, 215, 64, 64, 64, 64, 64, 217, 218, 218, 218, 64, 219, 219, 219, 219, - 219, 219, 219, 219, 64, 219, 219, 219, 64, 219, 219, 219, 219, 219, 219, - 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 64, 64, 64, 219, 217, - 217, 217, 218, 218, 218, 218, 64, 217, 217, 217, 64, 217, 217, 217, 220, - 64, 64, 64, 64, 64, 64, 64, 221, 222, 64, 219, 219, 64, 64, 64, 64, 64, - 64, 219, 219, 217, 217, 64, 64, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 224, 224, 224, 224, 224, 224, 224, 225, 64, 226, 227, 227, 64, - 228, 228, 228, 228, 228, 228, 228, 228, 64, 228, 228, 228, 64, 228, 228, - 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, - 228, 228, 64, 228, 228, 228, 228, 228, 64, 64, 229, 228, 227, 230, 227, - 227, 227, 227, 227, 64, 230, 227, 227, 64, 227, 227, 226, 231, 64, 64, - 64, 64, 64, 64, 64, 227, 227, 64, 64, 64, 64, 64, 64, 64, 228, 64, 228, - 228, 226, 226, 64, 64, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, - 64, 228, 228, 64, 64, 64, 64, 64, 64, 233, 234, 234, 64, 235, 235, 235, - 235, 235, 235, 235, 235, 64, 235, 235, 235, 64, 235, 235, 235, 235, 235, - 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 64, 64, 235, - 234, 234, 234, 233, 233, 233, 233, 64, 234, 234, 234, 64, 234, 234, 234, - 236, 235, 64, 64, 64, 64, 64, 64, 64, 64, 234, 235, 235, 233, 233, 64, - 64, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 238, 238, 238, 238, - 238, 238, 64, 64, 64, 239, 235, 235, 235, 235, 235, 235, 64, 64, 240, - 240, 64, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 64, 64, 64, 241, 241, 241, 241, 241, 241, 241, - 241, 64, 241, 241, 241, 241, 241, 241, 241, 241, 241, 64, 241, 64, 64, - 64, 64, 242, 64, 64, 64, 64, 240, 240, 240, 243, 243, 243, 64, 243, 64, - 240, 240, 240, 240, 240, 240, 240, 240, 64, 64, 64, 64, 64, 64, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 64, 64, 240, 240, 245, 64, 64, - 64, 64, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, - 246, 246, 246, 247, 246, 246, 247, 247, 247, 247, 248, 248, 249, 64, 64, - 64, 64, 250, 246, 246, 246, 246, 246, 246, 251, 247, 252, 252, 252, 252, - 247, 247, 247, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, - 253, 253, 64, 64, 64, 64, 64, 255, 255, 64, 255, 64, 64, 255, 255, 64, - 255, 64, 64, 255, 64, 64, 64, 64, 64, 64, 255, 255, 255, 255, 64, 255, - 255, 255, 255, 255, 255, 255, 64, 255, 255, 255, 64, 255, 64, 255, 64, - 64, 255, 255, 64, 255, 255, 255, 255, 256, 255, 255, 256, 256, 256, 256, - 257, 257, 64, 256, 256, 255, 64, 64, 255, 255, 255, 255, 255, 64, 258, - 64, 259, 259, 259, 259, 256, 256, 64, 64, 260, 260, 260, 260, 260, 260, - 260, 260, 260, 260, 64, 64, 255, 255, 255, 255, 261, 262, 262, 262, 263, + 163, 163, 163, 164, 164, 164, 64, 64, 165, 64, 126, 126, 126, 126, 126, + 64, 64, 64, 64, 64, 64, 137, 120, 120, 137, 120, 120, 137, 120, 120, 120, + 137, 137, 137, 166, 167, 168, 120, 120, 120, 137, 120, 120, 137, 137, + 120, 120, 120, 120, 120, 169, 169, 169, 170, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 169, 170, 172, 171, 170, + 170, 170, 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, + 173, 170, 170, 171, 78, 136, 174, 174, 169, 169, 169, 171, 171, 169, 169, + 84, 84, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 176, 177, 171, + 171, 171, 171, 171, 171, 178, 179, 180, 180, 64, 178, 178, 178, 178, 178, + 178, 178, 178, 64, 64, 178, 178, 64, 64, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 64, 178, 178, 178, 178, 178, 178, + 178, 64, 178, 64, 64, 64, 178, 178, 178, 178, 64, 64, 181, 178, 180, 180, + 180, 179, 179, 179, 179, 64, 64, 180, 180, 64, 64, 180, 180, 182, 178, + 64, 64, 64, 64, 64, 64, 64, 64, 180, 64, 64, 64, 64, 178, 178, 64, 178, + 178, 178, 179, 179, 64, 64, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 178, 178, 184, 184, 185, 185, 185, 185, 185, 185, 186, 184, 64, 64, + 64, 64, 64, 187, 187, 188, 64, 189, 189, 189, 189, 189, 189, 64, 64, 64, + 64, 189, 189, 64, 64, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 64, 189, 189, 189, 189, 189, 189, 189, 64, 189, 189, + 64, 189, 189, 64, 189, 189, 64, 64, 190, 64, 188, 188, 188, 187, 187, 64, + 64, 64, 64, 187, 187, 64, 64, 187, 187, 191, 64, 64, 64, 187, 64, 64, 64, + 64, 64, 64, 64, 189, 189, 189, 189, 64, 189, 64, 64, 64, 64, 64, 64, 64, + 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 187, 187, 189, 189, + 189, 187, 64, 64, 64, 193, 193, 194, 64, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 64, 195, 195, 195, 64, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 64, 195, 195, 195, 195, 195, 195, 195, + 64, 195, 195, 64, 195, 195, 195, 195, 195, 64, 64, 196, 195, 194, 194, + 194, 193, 193, 193, 193, 193, 64, 193, 193, 194, 64, 194, 194, 197, 64, + 64, 195, 64, 64, 64, 64, 64, 64, 64, 195, 195, 193, 193, 64, 64, 198, + 198, 198, 198, 198, 198, 198, 198, 198, 198, 199, 200, 64, 64, 64, 64, + 64, 64, 64, 195, 64, 64, 64, 64, 64, 64, 64, 201, 202, 202, 64, 203, 203, + 203, 203, 203, 203, 203, 203, 64, 64, 203, 203, 64, 64, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 64, 203, 203, 203, + 203, 203, 203, 203, 64, 203, 203, 64, 203, 203, 203, 203, 203, 64, 64, + 204, 203, 202, 201, 202, 201, 201, 201, 201, 64, 64, 202, 202, 64, 64, + 202, 202, 205, 64, 64, 64, 64, 64, 64, 64, 64, 201, 202, 64, 64, 64, 64, + 203, 203, 64, 203, 203, 203, 201, 201, 64, 64, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 207, 203, 208, 208, 208, 208, 208, 208, 64, 64, + 209, 210, 64, 210, 210, 210, 210, 210, 210, 64, 64, 64, 210, 210, 210, + 64, 210, 210, 210, 210, 64, 64, 64, 210, 210, 64, 210, 64, 210, 210, 64, + 64, 64, 210, 210, 64, 64, 64, 210, 210, 210, 210, 210, 210, 210, 210, + 210, 210, 64, 64, 64, 64, 211, 211, 209, 211, 211, 64, 64, 64, 211, 211, + 211, 64, 211, 211, 211, 212, 64, 64, 210, 64, 64, 64, 64, 64, 64, 211, + 64, 64, 64, 64, 64, 64, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, + 214, 214, 214, 215, 215, 215, 215, 215, 215, 216, 215, 64, 64, 64, 64, + 64, 217, 218, 218, 218, 64, 219, 219, 219, 219, 219, 219, 219, 219, 64, + 219, 219, 219, 64, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 64, 64, 64, 219, 217, 217, 217, 218, 218, 218, + 218, 64, 217, 217, 217, 64, 217, 217, 217, 220, 64, 64, 64, 64, 64, 64, + 64, 221, 222, 64, 219, 219, 219, 64, 64, 64, 64, 64, 219, 219, 217, 217, + 64, 64, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 224, 224, 224, + 224, 224, 224, 224, 225, 64, 226, 227, 227, 64, 228, 228, 228, 228, 228, + 228, 228, 228, 64, 228, 228, 228, 64, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 64, 228, 228, 228, + 228, 228, 64, 64, 229, 228, 227, 230, 227, 227, 227, 227, 227, 64, 230, + 227, 227, 64, 227, 227, 226, 231, 64, 64, 64, 64, 64, 64, 64, 227, 227, + 64, 64, 64, 64, 64, 64, 64, 228, 64, 228, 228, 226, 226, 64, 64, 232, + 232, 232, 232, 232, 232, 232, 232, 232, 232, 64, 228, 228, 64, 64, 64, + 64, 64, 64, 233, 234, 234, 64, 235, 235, 235, 235, 235, 235, 235, 235, + 64, 235, 235, 235, 64, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 64, 64, 235, 234, 234, 234, 233, 233, + 233, 233, 64, 234, 234, 234, 64, 234, 234, 234, 236, 235, 64, 64, 64, 64, + 64, 64, 64, 64, 234, 64, 64, 64, 64, 64, 64, 64, 235, 235, 235, 233, 233, + 64, 64, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 238, 238, 238, + 238, 238, 238, 64, 64, 64, 239, 235, 235, 235, 235, 235, 235, 64, 64, + 240, 240, 64, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 64, 64, 64, 241, 241, 241, 241, 241, 241, + 241, 241, 64, 241, 241, 241, 241, 241, 241, 241, 241, 241, 64, 241, 64, + 64, 64, 64, 242, 64, 64, 64, 64, 240, 240, 240, 243, 243, 243, 64, 243, + 64, 240, 240, 240, 240, 240, 240, 240, 240, 64, 64, 64, 64, 64, 64, 244, + 244, 244, 244, 244, 244, 244, 244, 244, 244, 64, 64, 240, 240, 245, 64, + 64, 64, 64, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 247, 246, 246, 247, 247, 247, 247, 248, 248, 249, 64, + 64, 64, 64, 250, 246, 246, 246, 246, 246, 246, 251, 247, 252, 252, 252, + 252, 247, 247, 247, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, + 254, 253, 253, 64, 64, 64, 64, 64, 255, 255, 64, 255, 64, 64, 255, 255, + 64, 255, 64, 64, 255, 64, 64, 64, 64, 64, 64, 255, 255, 255, 255, 64, + 255, 255, 255, 255, 255, 255, 255, 64, 255, 255, 255, 64, 255, 64, 255, + 64, 64, 255, 255, 64, 255, 255, 255, 255, 256, 255, 255, 256, 256, 256, + 256, 257, 257, 64, 256, 256, 255, 64, 64, 255, 255, 255, 255, 255, 64, + 258, 64, 259, 259, 259, 259, 256, 256, 64, 64, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 64, 64, 255, 255, 255, 255, 261, 262, 262, 262, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, - 262, 263, 262, 262, 262, 264, 264, 262, 262, 262, 262, 262, 262, 265, - 265, 265, 265, 265, 265, 265, 265, 265, 265, 266, 266, 266, 266, 266, - 266, 266, 266, 266, 266, 262, 264, 262, 264, 262, 267, 268, 269, 268, - 269, 270, 270, 261, 261, 261, 261, 261, 261, 261, 261, 64, 261, 261, 261, - 261, 261, 261, 261, 261, 261, 261, 261, 261, 64, 64, 64, 64, 271, 272, - 273, 274, 273, 273, 273, 273, 273, 272, 272, 272, 272, 273, 270, 272, - 273, 275, 275, 276, 263, 275, 275, 261, 261, 261, 261, 261, 273, 273, - 273, 273, 273, 273, 273, 273, 273, 273, 273, 64, 273, 273, 273, 273, 273, - 273, 273, 273, 273, 273, 273, 273, 64, 262, 262, 262, 262, 262, 262, 262, - 262, 264, 262, 262, 262, 262, 262, 262, 64, 262, 262, 263, 263, 263, 263, - 263, 277, 277, 277, 277, 263, 263, 64, 64, 64, 64, 64, 278, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 279, 279, 280, 280, 280, 280, - 279, 280, 280, 280, 280, 280, 281, 279, 282, 282, 279, 279, 280, 280, - 278, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 284, 284, 284, - 284, 284, 284, 278, 278, 278, 278, 278, 278, 279, 279, 280, 280, 278, - 278, 278, 278, 280, 280, 280, 278, 279, 279, 279, 278, 278, 279, 279, - 279, 279, 279, 279, 279, 278, 278, 278, 280, 280, 280, 280, 278, 278, - 278, 278, 278, 280, 279, 279, 280, 280, 279, 279, 279, 279, 279, 279, - 285, 278, 279, 283, 283, 279, 279, 279, 280, 286, 286, 287, 287, 287, - 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 64, 287, 64, 64, - 64, 64, 64, 287, 64, 64, 288, 288, 288, 288, 288, 288, 288, 288, 288, + 263, 262, 263, 262, 262, 262, 264, 264, 262, 262, 262, 262, 262, 262, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 266, 266, 266, 266, + 266, 266, 266, 266, 266, 266, 262, 264, 262, 264, 262, 267, 268, 269, + 268, 269, 270, 270, 261, 261, 261, 261, 261, 261, 261, 261, 64, 261, 261, + 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 64, 64, 64, 64, 271, + 272, 273, 274, 273, 273, 273, 273, 273, 272, 272, 272, 272, 273, 270, + 272, 273, 275, 275, 276, 263, 275, 275, 261, 261, 261, 261, 261, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 64, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 64, 262, 262, 262, 262, 262, 262, + 262, 262, 264, 262, 262, 262, 262, 262, 262, 64, 262, 262, 263, 263, 263, + 263, 263, 277, 277, 277, 277, 263, 263, 64, 64, 64, 64, 64, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 279, 279, 280, 280, 280, + 280, 279, 280, 280, 280, 280, 280, 281, 279, 282, 282, 279, 279, 280, + 280, 278, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 284, 284, + 284, 284, 284, 284, 278, 278, 278, 278, 278, 278, 279, 279, 280, 280, + 278, 278, 278, 278, 280, 280, 280, 278, 279, 279, 279, 278, 278, 279, + 279, 279, 279, 279, 279, 279, 278, 278, 278, 280, 280, 280, 280, 278, + 278, 278, 278, 278, 280, 279, 279, 280, 280, 279, 279, 279, 279, 279, + 279, 285, 278, 279, 283, 283, 279, 279, 279, 280, 286, 286, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 64, 287, 64, + 64, 64, 64, 64, 287, 64, 64, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 84, 289, 288, 288, 288, 290, 290, 290, 290, 290, 290, 290, 290, 291, 291, 291, 291, 291, 291, 291, 291, 292, 292, 292, 292, 292, 292, 292, 292, 292, 64, 292, 292, 292, 292, 64, 64, 292, 292, 292, 292, 292, @@ -2399,166 +2427,166 @@ static const unsigned short index2[] = { 294, 294, 294, 294, 294, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 64, 64, 64, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 64, 64, 64, 64, 64, 64, 297, - 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 64, 64, 64, - 298, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, - 299, 299, 299, 299, 299, 299, 299, 300, 300, 299, 301, 302, 302, 302, - 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, - 302, 303, 304, 64, 64, 64, 305, 305, 305, 305, 305, 305, 305, 305, 305, - 305, 305, 84, 84, 84, 306, 306, 306, 305, 305, 305, 305, 305, 305, 305, - 305, 64, 64, 64, 64, 64, 64, 64, 307, 307, 307, 307, 307, 307, 307, 307, - 307, 307, 307, 307, 307, 64, 307, 307, 307, 307, 308, 308, 309, 64, 64, - 64, 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, 311, 311, 312, 84, - 84, 64, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 314, 314, 64, - 64, 64, 64, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, - 315, 64, 315, 315, 315, 64, 316, 316, 64, 64, 64, 64, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 318, 318, 319, 318, 318, 318, - 318, 318, 318, 318, 319, 319, 319, 319, 319, 319, 319, 319, 318, 319, - 319, 318, 318, 318, 318, 318, 318, 318, 318, 318, 320, 318, 321, 321, - 321, 322, 321, 321, 321, 323, 317, 324, 64, 64, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 64, 64, 64, 64, 64, 64, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 64, 64, 64, 64, 64, 64, 327, 327, 66, 66, 327, - 66, 328, 327, 327, 327, 327, 329, 329, 329, 330, 64, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 64, 64, 64, 64, 64, 64, 332, 332, 332, 332, - 332, 332, 332, 332, 332, 332, 332, 333, 332, 332, 332, 332, 332, 334, - 332, 64, 64, 64, 64, 64, 299, 299, 299, 299, 299, 299, 64, 64, 335, 335, - 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 64, 336, - 336, 336, 337, 337, 337, 337, 336, 336, 337, 337, 337, 64, 64, 64, 64, - 337, 337, 336, 337, 337, 337, 337, 337, 337, 338, 339, 340, 64, 64, 64, - 64, 341, 64, 64, 64, 342, 342, 343, 343, 343, 343, 343, 343, 343, 343, - 343, 343, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, - 344, 344, 64, 64, 344, 344, 344, 344, 344, 64, 64, 64, 345, 345, 345, - 345, 345, 345, 345, 345, 345, 345, 345, 345, 64, 64, 64, 64, 346, 346, - 346, 346, 346, 346, 346, 346, 346, 345, 345, 345, 345, 345, 345, 345, - 346, 346, 64, 64, 64, 64, 64, 64, 347, 347, 347, 347, 347, 347, 347, 347, - 347, 347, 348, 64, 64, 64, 349, 349, 350, 350, 350, 350, 350, 350, 350, - 350, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, - 351, 351, 352, 353, 354, 354, 355, 64, 64, 356, 356, 357, 357, 357, 357, - 357, 357, 357, 357, 357, 357, 357, 357, 357, 358, 359, 358, 359, 359, - 359, 359, 359, 359, 359, 64, 360, 358, 359, 358, 358, 359, 359, 359, 359, - 359, 359, 359, 359, 358, 358, 358, 358, 358, 358, 359, 359, 361, 361, - 361, 361, 361, 361, 361, 361, 64, 64, 362, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 64, 64, 64, 64, 64, 64, 364, 364, 364, 364, 364, 364, - 364, 365, 364, 364, 364, 364, 364, 364, 64, 64, 78, 78, 78, 78, 78, 136, - 136, 136, 136, 136, 136, 78, 78, 136, 366, 64, 367, 367, 367, 367, 368, - 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 370, 368, 367, 367, 367, 367, 367, 368, 367, 368, 368, 368, 368, - 368, 367, 368, 371, 369, 369, 369, 369, 369, 369, 369, 64, 64, 64, 64, - 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 373, 373, 373, 373, - 373, 373, 373, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 375, - 376, 375, 375, 375, 375, 375, 375, 375, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 64, 64, 64, 377, 377, 378, 379, 379, 379, 379, 379, 379, - 379, 379, 379, 379, 379, 379, 379, 379, 378, 377, 377, 377, 377, 378, - 378, 377, 377, 380, 381, 377, 377, 379, 379, 382, 382, 382, 382, 382, - 382, 382, 382, 382, 382, 379, 379, 379, 379, 379, 379, 383, 383, 383, - 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 384, 385, 386, - 386, 385, 385, 385, 386, 385, 386, 386, 386, 387, 387, 64, 64, 64, 64, - 64, 64, 64, 64, 388, 388, 388, 388, 389, 389, 389, 389, 389, 389, 389, - 389, 389, 389, 389, 389, 390, 390, 390, 390, 390, 390, 390, 390, 391, - 391, 391, 391, 391, 391, 391, 391, 390, 390, 391, 392, 64, 64, 64, 393, - 393, 393, 393, 393, 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 64, - 64, 64, 389, 389, 389, 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, - 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, - 397, 397, 397, 397, 397, 397, 398, 398, 399, 399, 399, 399, 399, 399, - 399, 399, 78, 78, 78, 84, 400, 136, 136, 136, 136, 136, 78, 78, 136, 136, - 136, 136, 78, 401, 400, 400, 400, 400, 400, 400, 400, 402, 402, 402, 402, - 136, 402, 402, 402, 402, 401, 401, 78, 402, 402, 64, 78, 78, 64, 64, 64, - 64, 64, 64, 41, 41, 41, 41, 41, 41, 62, 62, 62, 62, 62, 75, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 65, 65, 65, 65, 65, 44, 44, 44, 44, 65, 65, 65, - 65, 65, 41, 41, 41, 41, 41, 403, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 65, 78, 78, 136, 78, 78, - 78, 78, 78, 78, 78, 136, 78, 78, 404, 405, 136, 406, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 64, 64, - 64, 64, 64, 64, 407, 136, 78, 136, 37, 41, 37, 41, 37, 41, 41, 41, 41, - 41, 41, 41, 41, 41, 37, 41, 62, 62, 62, 62, 62, 62, 62, 62, 61, 61, 61, - 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62, 64, 64, 61, 61, 61, 61, 61, - 61, 64, 64, 64, 61, 64, 61, 64, 61, 64, 61, 408, 408, 408, 408, 408, 408, - 408, 408, 62, 62, 62, 62, 62, 64, 62, 62, 61, 61, 61, 61, 408, 63, 62, - 63, 63, 63, 62, 62, 62, 64, 62, 62, 61, 61, 61, 61, 408, 63, 63, 63, 62, - 62, 62, 62, 64, 64, 62, 62, 61, 61, 61, 61, 64, 63, 63, 63, 61, 61, 61, - 61, 61, 63, 63, 63, 64, 64, 62, 62, 62, 64, 62, 62, 61, 61, 61, 61, 408, - 63, 63, 64, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, 410, - 411, 411, 412, 413, 414, 415, 415, 414, 414, 414, 22, 66, 416, 417, 418, - 419, 416, 417, 418, 419, 22, 22, 22, 66, 22, 22, 22, 22, 420, 421, 422, - 423, 424, 425, 426, 21, 427, 428, 427, 427, 428, 22, 66, 66, 66, 28, 35, - 22, 66, 66, 22, 429, 429, 66, 66, 66, 430, 431, 432, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 433, 66, 429, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 409, 410, 410, 410, 410, 410, 64, 434, 435, 436, 437, 410, 410, 410, - 410, 410, 410, 438, 44, 64, 64, 33, 438, 438, 438, 438, 438, 439, 439, - 433, 431, 432, 440, 438, 33, 33, 33, 33, 438, 438, 438, 438, 438, 439, - 439, 433, 431, 432, 64, 44, 44, 44, 44, 44, 64, 64, 64, 250, 250, 250, - 250, 250, 250, 250, 250, 250, 441, 250, 250, 23, 250, 250, 250, 250, 250, - 250, 250, 250, 250, 64, 64, 78, 78, 400, 400, 78, 78, 78, 78, 400, 400, - 400, 78, 78, 366, 366, 366, 366, 78, 366, 366, 366, 400, 400, 78, 136, - 78, 400, 400, 136, 136, 136, 136, 78, 64, 64, 64, 64, 64, 64, 64, 26, 26, - 442, 30, 26, 30, 26, 442, 26, 30, 34, 442, 442, 442, 34, 34, 442, 442, - 442, 443, 26, 442, 30, 26, 433, 442, 442, 442, 442, 442, 26, 26, 26, 30, - 30, 26, 442, 26, 67, 26, 442, 26, 37, 38, 442, 442, 444, 34, 442, 442, - 37, 442, 34, 402, 402, 402, 402, 34, 26, 26, 34, 34, 442, 442, 445, 433, - 433, 433, 433, 442, 34, 34, 34, 34, 26, 433, 26, 26, 41, 277, 446, 446, - 446, 36, 36, 446, 446, 446, 446, 446, 446, 36, 36, 36, 36, 446, 447, 447, - 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 448, 448, 448, 448, - 447, 447, 448, 448, 448, 448, 448, 448, 448, 448, 448, 37, 41, 448, 448, - 448, 448, 36, 64, 64, 64, 64, 64, 64, 39, 39, 39, 39, 39, 30, 30, 30, 30, - 30, 433, 433, 26, 26, 26, 26, 433, 26, 26, 433, 26, 26, 433, 26, 26, 26, - 26, 26, 26, 26, 433, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 433, 433, 26, 26, 39, 26, 39, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 433, 433, 433, - 433, 433, 433, 433, 433, 433, 433, 433, 433, 39, 445, 449, 449, 445, 433, - 433, 39, 449, 445, 445, 449, 445, 445, 433, 39, 433, 449, 439, 450, 433, - 449, 445, 433, 433, 433, 449, 445, 445, 449, 39, 449, 449, 445, 445, 39, - 445, 39, 445, 39, 39, 39, 39, 449, 449, 445, 449, 445, 445, 445, 445, - 445, 39, 39, 39, 39, 433, 445, 433, 445, 449, 449, 445, 445, 445, 445, - 445, 445, 445, 445, 445, 445, 449, 445, 445, 445, 449, 433, 433, 433, - 433, 433, 449, 445, 445, 445, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 445, 449, 39, 445, 433, 449, 449, 449, 449, 445, 445, 449, 449, 433, - 433, 449, 449, 445, 445, 449, 449, 445, 445, 449, 449, 445, 445, 445, - 445, 445, 433, 433, 445, 445, 445, 445, 433, 433, 39, 433, 433, 445, 39, - 433, 433, 433, 433, 433, 433, 433, 433, 445, 445, 433, 39, 445, 445, 445, - 433, 433, 433, 433, 433, 445, 449, 433, 445, 445, 445, 445, 445, 433, + 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, 64, 64, + 298, 298, 298, 298, 298, 298, 64, 64, 299, 300, 300, 300, 300, 300, 300, + 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 301, 301, 300, 302, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, 304, 305, 64, 64, 64, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 84, 84, 84, 307, 307, 307, + 306, 306, 306, 306, 306, 306, 306, 306, 64, 64, 64, 64, 64, 64, 64, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 64, 308, 308, + 308, 308, 309, 309, 310, 64, 64, 64, 311, 311, 311, 311, 311, 311, 311, + 311, 311, 311, 312, 312, 313, 84, 84, 64, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 315, 315, 64, 64, 64, 64, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 64, 316, 316, 316, 64, 317, 317, + 64, 64, 64, 64, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 319, 319, 320, 319, 319, 319, 319, 319, 319, 319, 320, 320, 320, + 320, 320, 320, 320, 320, 319, 320, 320, 319, 319, 319, 319, 319, 319, + 319, 319, 319, 321, 319, 322, 322, 322, 323, 322, 322, 322, 324, 318, + 325, 64, 64, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 64, 64, + 64, 64, 64, 64, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 64, 64, + 64, 64, 64, 64, 328, 328, 66, 66, 328, 66, 329, 328, 328, 328, 328, 330, + 330, 330, 331, 64, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 64, + 64, 64, 64, 64, 64, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, + 333, 334, 333, 333, 333, 333, 333, 335, 333, 64, 64, 64, 64, 64, 300, + 300, 300, 300, 300, 300, 64, 64, 336, 336, 336, 336, 336, 336, 336, 336, + 336, 336, 336, 336, 336, 336, 336, 64, 337, 337, 337, 338, 338, 338, 338, + 337, 337, 338, 338, 338, 64, 64, 64, 64, 338, 338, 337, 338, 338, 338, + 338, 338, 338, 339, 340, 341, 64, 64, 64, 64, 342, 64, 64, 64, 343, 343, + 344, 344, 344, 344, 344, 344, 344, 344, 344, 344, 345, 345, 345, 345, + 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 64, 64, 345, 345, 345, + 345, 345, 64, 64, 64, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 64, 64, 64, 64, 346, 346, 64, 64, 64, 64, 64, 64, 347, 347, + 347, 347, 347, 347, 347, 347, 347, 347, 348, 64, 64, 64, 349, 349, 350, + 350, 350, 350, 350, 350, 350, 350, 351, 351, 351, 351, 351, 351, 351, + 351, 351, 351, 351, 351, 351, 351, 351, 352, 353, 354, 354, 355, 64, 64, + 356, 356, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, + 357, 358, 359, 358, 359, 359, 359, 359, 359, 359, 359, 64, 360, 358, 359, + 358, 358, 359, 359, 359, 359, 359, 359, 359, 359, 358, 358, 358, 358, + 358, 358, 359, 359, 361, 361, 361, 361, 361, 361, 361, 361, 64, 64, 362, + 363, 363, 363, 363, 363, 363, 363, 363, 363, 363, 64, 64, 64, 64, 64, 64, + 364, 364, 364, 364, 364, 364, 364, 365, 364, 364, 364, 364, 364, 364, 64, + 64, 78, 78, 78, 78, 78, 136, 136, 136, 136, 136, 136, 78, 78, 136, 366, + 64, 367, 367, 367, 367, 368, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 370, 368, 367, 367, 367, 367, 367, 368, + 367, 368, 368, 368, 368, 368, 367, 368, 371, 369, 369, 369, 369, 369, + 369, 369, 64, 64, 64, 64, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 372, 373, 373, 373, 373, 373, 373, 373, 374, 374, 374, 374, 374, 374, + 374, 374, 374, 374, 375, 376, 375, 375, 375, 375, 375, 375, 375, 374, + 374, 374, 374, 374, 374, 374, 374, 374, 64, 64, 64, 377, 377, 378, 379, + 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, 378, + 377, 377, 377, 377, 378, 378, 377, 377, 380, 381, 377, 377, 379, 379, + 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 379, 379, 379, 379, + 379, 379, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 384, 385, 386, 386, 385, 385, 385, 386, 385, 386, 386, 386, + 387, 387, 64, 64, 64, 64, 64, 64, 64, 64, 388, 388, 388, 388, 389, 389, + 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 390, 390, 390, 390, + 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, 391, 390, 390, + 391, 392, 64, 64, 64, 393, 393, 393, 393, 393, 394, 394, 394, 394, 394, + 394, 394, 394, 394, 394, 64, 64, 64, 389, 389, 389, 395, 395, 395, 395, + 395, 395, 395, 395, 395, 395, 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 397, 397, 397, 397, 397, 397, 398, 398, + 399, 399, 399, 399, 399, 399, 399, 399, 78, 78, 78, 84, 400, 136, 136, + 136, 136, 136, 78, 78, 136, 136, 136, 136, 78, 401, 400, 400, 400, 400, + 400, 400, 400, 402, 402, 402, 402, 136, 402, 402, 402, 402, 401, 401, 78, + 402, 402, 64, 78, 78, 64, 64, 64, 64, 64, 64, 41, 41, 41, 41, 41, 41, 62, + 62, 62, 62, 62, 75, 44, 44, 44, 44, 44, 44, 44, 44, 44, 65, 65, 65, 65, + 65, 44, 44, 44, 44, 65, 65, 65, 65, 65, 41, 41, 41, 41, 41, 403, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 65, 78, 78, 136, 78, 78, 78, 78, 78, 78, 78, 136, 78, 78, 404, + 405, 136, 406, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 64, 64, 64, 64, 64, 64, 407, 136, 78, 136, + 37, 41, 37, 41, 37, 41, 41, 41, 41, 41, 41, 41, 41, 41, 37, 41, 62, 62, + 62, 62, 62, 62, 62, 62, 61, 61, 61, 61, 61, 61, 61, 61, 62, 62, 62, 62, + 62, 62, 64, 64, 61, 61, 61, 61, 61, 61, 64, 64, 64, 61, 64, 61, 64, 61, + 64, 61, 408, 408, 408, 408, 408, 408, 408, 408, 62, 62, 62, 62, 62, 64, + 62, 62, 61, 61, 61, 61, 408, 63, 62, 63, 63, 63, 62, 62, 62, 64, 62, 62, + 61, 61, 61, 61, 408, 63, 63, 63, 62, 62, 62, 62, 64, 64, 62, 62, 61, 61, + 61, 61, 64, 63, 63, 63, 61, 61, 61, 61, 61, 63, 63, 63, 64, 64, 62, 62, + 62, 64, 62, 62, 61, 61, 61, 61, 408, 63, 63, 64, 409, 409, 409, 409, 409, + 409, 409, 409, 409, 409, 409, 410, 411, 411, 412, 413, 414, 415, 415, + 414, 414, 414, 22, 66, 416, 417, 418, 419, 416, 417, 418, 419, 22, 22, + 22, 66, 22, 22, 22, 22, 420, 421, 422, 423, 424, 425, 426, 21, 427, 428, + 427, 427, 428, 22, 66, 66, 66, 28, 35, 22, 66, 66, 22, 429, 429, 66, 66, + 66, 430, 431, 432, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 433, 66, + 429, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 409, 410, 410, 410, 410, + 410, 64, 434, 435, 436, 437, 410, 410, 410, 410, 410, 410, 438, 44, 64, + 64, 33, 438, 438, 438, 438, 438, 439, 439, 433, 431, 432, 440, 438, 33, + 33, 33, 33, 438, 438, 438, 438, 438, 439, 439, 433, 431, 432, 64, 44, 44, + 44, 44, 44, 64, 64, 64, 250, 250, 250, 250, 250, 250, 250, 250, 250, 441, + 250, 250, 23, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 64, 78, + 78, 400, 400, 78, 78, 78, 78, 400, 400, 400, 78, 78, 366, 366, 366, 366, + 78, 366, 366, 366, 400, 400, 78, 136, 78, 400, 400, 136, 136, 136, 136, + 78, 64, 64, 64, 64, 64, 64, 64, 26, 26, 442, 30, 26, 30, 26, 442, 26, 30, + 34, 442, 442, 442, 34, 34, 442, 442, 442, 443, 26, 442, 30, 26, 433, 442, + 442, 442, 442, 442, 26, 26, 26, 30, 30, 26, 442, 26, 67, 26, 442, 26, 37, + 38, 442, 442, 444, 34, 442, 442, 37, 442, 34, 402, 402, 402, 402, 34, 26, + 26, 34, 34, 442, 442, 445, 433, 433, 433, 433, 442, 34, 34, 34, 34, 26, + 433, 26, 26, 41, 277, 446, 446, 446, 36, 36, 446, 446, 446, 446, 446, + 446, 36, 36, 36, 36, 446, 447, 447, 447, 447, 447, 447, 447, 447, 447, + 447, 447, 447, 448, 448, 448, 448, 447, 447, 448, 448, 448, 448, 448, + 448, 448, 448, 448, 37, 41, 448, 448, 448, 448, 36, 26, 26, 64, 64, 64, + 64, 39, 39, 39, 39, 39, 30, 30, 30, 30, 30, 433, 433, 26, 26, 26, 26, + 433, 26, 26, 433, 26, 26, 433, 26, 26, 26, 26, 26, 26, 26, 433, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 433, 433, 26, 26, 39, 26, 39, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 30, 26, 26, 26, 26, 433, 433, 433, 433, 433, 433, 433, 433, 433, + 433, 433, 433, 39, 445, 449, 449, 445, 433, 433, 39, 449, 445, 445, 449, + 445, 445, 433, 39, 433, 449, 439, 450, 433, 449, 445, 433, 433, 433, 449, + 445, 445, 449, 39, 449, 449, 445, 445, 39, 445, 39, 445, 39, 39, 39, 39, + 449, 449, 445, 449, 445, 445, 445, 445, 445, 39, 39, 39, 39, 433, 445, + 433, 445, 449, 449, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, + 449, 445, 445, 445, 449, 433, 433, 433, 433, 433, 449, 445, 445, 445, + 433, 433, 433, 433, 433, 433, 433, 433, 433, 445, 449, 39, 445, 433, 449, + 449, 449, 449, 445, 445, 449, 449, 433, 433, 449, 449, 445, 445, 449, + 449, 445, 445, 449, 449, 445, 445, 445, 445, 445, 433, 433, 445, 445, + 445, 445, 433, 433, 39, 433, 433, 445, 39, 433, 433, 433, 433, 433, 433, + 433, 433, 445, 445, 433, 39, 445, 445, 445, 433, 433, 433, 433, 433, 445, + 449, 433, 445, 445, 445, 445, 445, 433, 433, 445, 445, 433, 433, 433, + 433, 445, 445, 445, 445, 445, 445, 445, 445, 433, 433, 431, 432, 431, + 432, 26, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 26, 445, 445, 26, 26, + 26, 26, 26, 26, 26, 451, 452, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 26, 433, + 26, 26, 26, 26, 26, 26, 26, 26, 277, 26, 26, 26, 26, 26, 433, 433, 433, + 433, 433, 433, 433, 433, 433, 26, 26, 26, 26, 433, 433, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 64, 64, 64, 64, 64, 26, 26, 26, 26, 26, 26, 26, 64, + 36, 36, 36, 36, 36, 36, 36, 36, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, + 453, 446, 36, 36, 36, 36, 36, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 26, 26, 26, 26, 26, 26, 30, 30, 30, 30, 26, 26, 30, 30, 26, 30, 30, + 30, 30, 30, 26, 26, 30, 30, 26, 26, 30, 39, 26, 26, 26, 26, 30, 30, 26, + 26, 30, 39, 26, 26, 26, 26, 30, 30, 30, 26, 26, 30, 26, 26, 30, 30, 26, + 26, 26, 26, 26, 30, 30, 26, 26, 30, 26, 26, 26, 26, 30, 30, 26, 26, 26, + 26, 30, 26, 30, 26, 30, 26, 30, 26, 26, 26, 26, 26, 30, 30, 26, 30, 30, + 30, 26, 30, 30, 30, 30, 26, 30, 30, 26, 39, 26, 26, 26, 26, 26, 26, 30, + 30, 26, 26, 26, 26, 277, 26, 26, 26, 26, 26, 26, 26, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 26, 30, 30, 30, 26, 30, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 30, 26, 26, 431, 432, 431, 432, 431, 432, 431, 432, 431, 432, + 431, 432, 431, 432, 36, 36, 446, 446, 446, 446, 446, 446, 446, 446, 446, + 446, 446, 446, 26, 26, 26, 26, 445, 433, 433, 445, 445, 431, 432, 433, + 445, 445, 433, 445, 445, 445, 433, 433, 433, 433, 433, 445, 445, 445, + 445, 433, 433, 433, 433, 433, 445, 445, 445, 433, 433, 433, 445, 445, + 445, 445, 9, 10, 9, 10, 9, 10, 9, 10, 431, 432, 454, 454, 454, 454, 454, + 454, 454, 454, 433, 433, 433, 431, 432, 9, 10, 431, 432, 431, 432, 431, + 432, 431, 432, 431, 432, 433, 433, 445, 445, 445, 445, 445, 445, 433, + 433, 433, 433, 433, 433, 433, 433, 445, 433, 433, 433, 433, 445, 445, + 445, 445, 445, 433, 445, 445, 433, 433, 431, 432, 431, 432, 445, 433, + 433, 433, 433, 445, 433, 445, 445, 445, 433, 433, 445, 445, 433, 433, + 433, 433, 433, 433, 433, 433, 433, 433, 445, 445, 445, 445, 445, 445, + 433, 433, 431, 432, 433, 433, 433, 433, 445, 445, 445, 445, 445, 445, + 445, 445, 445, 445, 445, 433, 445, 445, 445, 445, 433, 433, 445, 433, + 445, 433, 433, 445, 433, 445, 445, 445, 445, 433, 433, 433, 433, 433, + 445, 445, 433, 433, 433, 433, 445, 445, 445, 445, 433, 445, 445, 433, 433, 445, 445, 433, 433, 433, 433, 445, 445, 445, 445, 445, 445, 445, - 445, 433, 433, 431, 432, 431, 432, 26, 26, 26, 26, 26, 26, 30, 26, 26, - 26, 26, 26, 445, 445, 26, 26, 26, 26, 26, 26, 26, 451, 452, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 26, 433, 26, 26, 26, 26, 26, 26, 26, 26, 277, - 26, 26, 26, 26, 26, 433, 433, 433, 433, 433, 433, 433, 433, 433, 26, 26, - 26, 26, 433, 433, 26, 26, 26, 26, 26, 26, 26, 26, 26, 64, 64, 64, 64, 64, - 26, 26, 26, 26, 26, 26, 26, 64, 36, 36, 36, 36, 36, 36, 36, 36, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 453, 453, 453, 453, 453, 453, - 453, 453, 453, 453, 453, 453, 453, 453, 446, 36, 36, 36, 36, 36, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 26, 26, 26, 26, 26, 30, 30, - 30, 30, 26, 26, 30, 30, 26, 30, 30, 30, 30, 30, 26, 26, 30, 30, 26, 26, - 30, 39, 26, 26, 26, 26, 30, 30, 26, 26, 30, 39, 26, 26, 26, 26, 30, 30, - 30, 26, 26, 30, 26, 26, 30, 30, 26, 26, 26, 26, 26, 30, 30, 26, 26, 30, - 26, 26, 26, 26, 30, 30, 26, 26, 26, 26, 30, 26, 30, 26, 30, 26, 30, 26, - 26, 26, 26, 26, 30, 30, 26, 30, 30, 30, 26, 30, 30, 30, 30, 26, 30, 30, - 26, 39, 26, 26, 26, 26, 26, 26, 30, 30, 26, 26, 26, 26, 277, 26, 26, 26, - 26, 26, 26, 26, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 30, 30, 30, - 26, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 26, 26, 431, 432, 431, - 432, 431, 432, 431, 432, 431, 432, 431, 432, 431, 432, 36, 36, 446, 446, - 446, 446, 446, 446, 446, 446, 446, 446, 446, 446, 26, 26, 26, 26, 445, - 433, 433, 445, 445, 431, 432, 433, 445, 445, 433, 445, 445, 445, 433, - 433, 433, 433, 433, 445, 445, 445, 445, 433, 433, 433, 433, 433, 445, - 445, 445, 433, 433, 433, 445, 445, 445, 445, 9, 10, 9, 10, 9, 10, 9, 10, - 431, 432, 454, 454, 454, 454, 454, 454, 454, 454, 433, 433, 433, 431, - 432, 9, 10, 431, 432, 431, 432, 431, 432, 431, 432, 431, 432, 433, 433, - 445, 445, 445, 445, 445, 445, 433, 433, 433, 433, 433, 433, 433, 433, - 445, 433, 433, 433, 433, 445, 445, 445, 445, 445, 433, 445, 445, 433, - 433, 431, 432, 431, 432, 445, 433, 433, 433, 433, 445, 433, 445, 445, - 445, 433, 433, 445, 445, 433, 433, 433, 433, 433, 433, 433, 433, 433, - 433, 445, 445, 445, 445, 445, 445, 433, 433, 431, 432, 433, 433, 433, - 433, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 433, 445, - 445, 445, 445, 433, 433, 445, 433, 445, 433, 433, 445, 433, 445, 445, - 445, 445, 433, 433, 433, 433, 433, 445, 445, 433, 433, 433, 433, 445, - 445, 445, 445, 433, 445, 445, 433, 433, 445, 445, 433, 433, 433, 433, - 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 445, 433, 433, 445, - 445, 445, 445, 445, 445, 445, 445, 433, 445, 445, 445, 445, 445, 445, - 445, 445, 433, 433, 433, 433, 433, 445, 433, 445, 433, 433, 433, 445, - 445, 445, 445, 445, 433, 433, 433, 433, 445, 433, 433, 433, 445, 445, - 445, 445, 445, 433, 445, 433, 433, 433, 433, 433, 433, 433, 26, 26, 433, - 433, 433, 433, 433, 433, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 30, 26, - 26, 26, 26, 64, 64, 26, 26, 26, 26, 26, 26, 26, 26, 64, 64, 26, 26, 64, - 64, 64, 26, 26, 26, 26, 64, 26, 26, 26, 26, 26, 26, 26, 26, 64, 64, 64, - 64, 64, 64, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, + 445, 445, 445, 445, 433, 433, 445, 445, 445, 445, 445, 445, 445, 445, + 433, 445, 445, 445, 445, 445, 445, 445, 445, 433, 433, 433, 433, 433, + 445, 433, 445, 433, 433, 433, 445, 445, 445, 445, 445, 433, 433, 433, + 433, 445, 433, 433, 433, 445, 445, 445, 445, 445, 433, 445, 433, 433, + 433, 433, 433, 433, 433, 26, 26, 433, 433, 433, 433, 433, 433, 26, 26, + 26, 26, 26, 26, 26, 26, 30, 30, 30, 26, 26, 26, 26, 64, 64, 26, 26, 26, + 26, 26, 26, 26, 26, 64, 64, 26, 26, 64, 64, 64, 26, 26, 26, 26, 64, 26, + 26, 26, 26, 26, 26, 26, 26, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 26, + 26, 26, 26, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, 64, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 64, 37, 41, 37, 37, 37, 41, 41, 37, 41, 37, 41, 37, 41, 37, 37, 37, 37, 41, 37, 41, 41, 37, 41, 41, 41, 41, 41, 41, 44, 44, @@ -2596,263 +2624,280 @@ static const unsigned short index2[] = { 467, 467, 467, 467, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, 495, 64, 489, 489, 489, 489, 489, 489, 489, 467, 467, 467, 467, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 467, - 467, 496, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 497, 497, 497, 496, 498, 498, 498, 498, 498, - 498, 498, 498, 498, 498, 497, 497, 497, 497, 496, 498, 498, 498, 499, - 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 500, 499, - 499, 499, 499, 499, 499, 499, 64, 64, 64, 501, 501, 501, 501, 501, 501, - 501, 501, 501, 501, 501, 501, 501, 501, 501, 64, 502, 502, 502, 502, 502, - 502, 502, 502, 503, 503, 503, 503, 503, 503, 504, 504, 505, 505, 505, - 505, 505, 505, 505, 505, 505, 505, 505, 505, 506, 507, 507, 507, 508, - 508, 508, 508, 508, 508, 508, 508, 508, 508, 505, 505, 64, 64, 64, 64, - 72, 75, 72, 75, 72, 75, 509, 77, 79, 79, 79, 510, 77, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 510, 511, 72, 75, 72, 75, 403, 403, 64, 77, 512, 512, - 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 513, 513, - 513, 513, 513, 513, 513, 513, 513, 513, 514, 514, 515, 515, 515, 515, - 515, 515, 47, 47, 47, 47, 47, 47, 47, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 47, 47, 37, 41, 37, 41, 37, 41, 41, 41, 37, 41, 37, 41, 37, 41, 44, 41, - 41, 41, 41, 41, 41, 41, 41, 37, 41, 37, 41, 37, 37, 41, 45, 516, 516, 37, - 41, 37, 41, 64, 37, 41, 37, 41, 41, 41, 37, 41, 37, 41, 37, 37, 37, 37, - 64, 64, 37, 37, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 42, - 44, 44, 41, 42, 42, 42, 42, 42, 517, 517, 518, 517, 517, 517, 519, 517, - 517, 517, 517, 518, 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, - 517, 517, 517, 517, 517, 520, 520, 518, 518, 520, 521, 521, 521, 521, 64, - 64, 64, 64, 522, 522, 522, 522, 522, 522, 277, 277, 250, 444, 64, 64, 64, - 64, 64, 64, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, 523, - 524, 524, 524, 524, 525, 525, 526, 526, 526, 526, 526, 526, 526, 526, - 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 525, 525, 525, 525, - 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 527, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 528, 528, 529, 529, 529, 529, 529, 529, 529, - 529, 529, 529, 64, 64, 64, 64, 64, 64, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 171, 171, 171, 171, 171, 171, 176, 176, 176, 171, 64, 64, - 64, 64, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 531, 531, 531, - 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, - 531, 531, 531, 532, 532, 532, 532, 532, 533, 533, 533, 84, 534, 535, 535, - 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, 536, - 536, 536, 536, 536, 536, 536, 536, 536, 536, 536, 537, 538, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 539, 290, 290, 290, 290, 290, 64, 64, 64, - 540, 540, 540, 541, 542, 542, 542, 542, 542, 542, 542, 542, 542, 542, - 542, 542, 542, 542, 542, 543, 541, 541, 540, 540, 540, 540, 541, 541, - 540, 541, 541, 541, 544, 545, 545, 545, 545, 545, 545, 545, 545, 545, - 545, 545, 545, 545, 64, 46, 546, 546, 546, 546, 546, 546, 546, 546, 546, - 546, 64, 64, 64, 64, 545, 545, 278, 278, 278, 278, 278, 280, 547, 278, - 283, 283, 278, 278, 278, 278, 278, 64, 548, 548, 548, 548, 548, 548, 548, - 548, 548, 549, 549, 549, 549, 549, 549, 550, 550, 549, 549, 550, 550, - 549, 549, 64, 548, 548, 548, 549, 548, 548, 548, 548, 548, 548, 548, 548, - 549, 550, 64, 64, 551, 551, 551, 551, 551, 551, 551, 551, 551, 551, 64, - 64, 552, 552, 552, 552, 547, 278, 278, 278, 278, 278, 278, 286, 286, 286, - 278, 279, 280, 279, 278, 278, 553, 553, 553, 553, 553, 553, 553, 553, - 554, 553, 554, 554, 555, 553, 553, 554, 554, 553, 553, 553, 553, 553, - 554, 554, 553, 554, 553, 64, 64, 64, 64, 64, 64, 64, 64, 553, 553, 556, - 557, 557, 558, 558, 558, 558, 558, 558, 558, 558, 558, 558, 558, 559, - 560, 560, 559, 559, 561, 561, 558, 562, 562, 559, 563, 64, 64, 292, 292, - 292, 292, 292, 292, 64, 41, 41, 41, 516, 44, 44, 44, 44, 64, 64, 64, 64, - 41, 62, 64, 64, 558, 558, 558, 559, 559, 560, 559, 559, 560, 559, 559, - 561, 559, 563, 64, 64, 564, 564, 564, 564, 564, 564, 564, 564, 564, 564, - 64, 64, 64, 64, 64, 64, 290, 565, 565, 565, 565, 565, 565, 565, 565, 565, - 565, 565, 565, 565, 565, 565, 565, 565, 565, 290, 64, 64, 64, 64, 291, - 291, 291, 291, 291, 291, 291, 64, 64, 64, 64, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 64, 64, 64, 64, 566, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 566, 567, 568, 568, 568, 568, 568, 568, 568, 568, - 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, - 567, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, - 496, 498, 498, 496, 496, 498, 498, 498, 498, 498, 498, 41, 41, 41, 41, - 41, 41, 41, 64, 64, 64, 64, 83, 83, 83, 83, 83, 64, 64, 64, 64, 64, 110, - 569, 110, 110, 570, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 64, 110, 110, 110, 110, 110, 64, 110, 64, 110, 110, 64, - 110, 110, 64, 110, 110, 126, 126, 571, 571, 571, 571, 571, 571, 571, 571, - 571, 571, 571, 571, 571, 571, 571, 571, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 572, 418, 64, - 64, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 116, 119, 64, 64, - 58, 58, 58, 58, 58, 58, 58, 58, 469, 469, 469, 469, 469, 469, 469, 474, - 475, 469, 64, 64, 64, 64, 64, 64, 78, 78, 78, 78, 78, 78, 78, 136, 136, - 136, 136, 136, 136, 136, 64, 64, 469, 473, 473, 573, 573, 474, 475, 474, - 475, 474, 475, 474, 475, 474, 475, 474, 475, 474, 475, 474, 475, 469, - 469, 474, 475, 469, 469, 469, 469, 573, 573, 573, 574, 469, 574, 64, 469, - 574, 469, 469, 473, 451, 452, 451, 452, 451, 452, 575, 469, 469, 576, - 577, 578, 578, 579, 64, 469, 580, 575, 469, 64, 64, 64, 64, 126, 126, - 126, 126, 126, 64, 126, 126, 126, 126, 126, 126, 126, 64, 64, 410, 64, - 581, 581, 582, 583, 582, 581, 581, 584, 585, 581, 586, 587, 588, 587, - 587, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 587, 581, 590, - 591, 590, 581, 581, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, - 592, 592, 592, 592, 592, 592, 592, 592, 584, 581, 585, 593, 594, 593, - 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, - 595, 595, 595, 595, 584, 591, 585, 591, 584, 585, 596, 597, 598, 596, - 596, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 600, 599, 599, - 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 600, 600, 601, - 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 64, - 64, 64, 601, 601, 601, 601, 601, 601, 64, 64, 601, 601, 601, 64, 64, 64, - 583, 583, 591, 593, 602, 583, 583, 64, 603, 604, 604, 604, 604, 603, 603, - 64, 64, 605, 605, 605, 26, 30, 64, 64, 606, 606, 606, 606, 606, 606, 606, - 606, 606, 606, 606, 606, 64, 606, 606, 606, 606, 606, 606, 606, 606, 606, - 606, 64, 606, 606, 606, 64, 606, 606, 64, 606, 606, 606, 606, 606, 606, - 606, 64, 64, 606, 606, 606, 64, 64, 64, 64, 64, 84, 66, 84, 64, 64, 64, - 64, 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 64, - 64, 64, 277, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, 607, - 607, 608, 608, 608, 608, 609, 609, 609, 609, 609, 609, 609, 609, 609, - 609, 609, 609, 609, 609, 609, 609, 609, 608, 608, 609, 64, 64, 64, 26, - 26, 26, 26, 64, 64, 64, 64, 609, 64, 64, 64, 64, 64, 64, 64, 277, 277, - 277, 277, 277, 136, 64, 64, 610, 610, 610, 610, 610, 610, 610, 610, 610, - 610, 610, 610, 610, 64, 64, 64, 611, 611, 611, 611, 611, 611, 611, 611, - 611, 64, 64, 64, 64, 64, 64, 64, 136, 438, 438, 438, 438, 438, 438, 438, + 467, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, 496, + 496, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 498, 498, 498, + 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 499, 498, 498, 498, + 498, 498, 498, 498, 64, 64, 64, 500, 500, 500, 500, 500, 500, 500, 500, + 500, 500, 500, 500, 500, 500, 500, 64, 501, 501, 501, 501, 501, 501, 501, + 501, 502, 502, 502, 502, 502, 502, 503, 503, 504, 504, 504, 504, 504, + 504, 504, 504, 504, 504, 504, 504, 505, 506, 506, 506, 507, 507, 507, + 507, 507, 507, 507, 507, 507, 507, 504, 504, 64, 64, 64, 64, 72, 75, 72, + 75, 72, 75, 508, 77, 79, 79, 79, 509, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 509, 510, 72, 75, 72, 75, 403, 403, 77, 77, 511, 511, 511, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 512, 512, 512, 512, 512, + 512, 512, 512, 512, 512, 513, 513, 514, 514, 514, 514, 514, 514, 47, 47, + 47, 47, 47, 47, 47, 45, 45, 45, 45, 45, 45, 45, 45, 45, 47, 47, 37, 41, + 37, 41, 37, 41, 41, 41, 37, 41, 37, 41, 37, 41, 44, 41, 41, 41, 41, 41, + 41, 41, 41, 37, 41, 37, 41, 37, 37, 41, 45, 515, 515, 37, 41, 37, 41, 42, + 37, 41, 37, 41, 41, 41, 37, 41, 37, 41, 37, 37, 37, 37, 64, 64, 37, 37, + 37, 37, 37, 41, 37, 41, 64, 64, 64, 64, 64, 64, 64, 42, 44, 44, 41, 42, + 42, 42, 42, 42, 516, 516, 517, 516, 516, 516, 518, 516, 516, 516, 516, + 517, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 519, 519, 517, 517, 519, 520, 520, 520, 520, 64, 64, 64, 64, + 521, 521, 521, 521, 521, 521, 277, 277, 250, 444, 64, 64, 64, 64, 64, 64, + 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, 523, 523, + 523, 523, 524, 524, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, + 525, 525, 525, 525, 525, 525, 525, 525, 524, 524, 524, 524, 524, 524, + 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, 526, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 527, 527, 528, 528, 528, 528, 528, 528, 528, 528, + 528, 528, 64, 64, 64, 64, 64, 64, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 171, 171, 171, 171, 171, 171, 176, 176, 176, 171, 176, 171, 64, + 64, 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, 530, 530, 530, 530, + 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, + 530, 530, 531, 531, 531, 531, 531, 532, 532, 532, 84, 533, 534, 534, 534, + 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 535, 535, + 535, 535, 535, 535, 535, 535, 535, 535, 535, 536, 537, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 538, 290, 290, 290, 290, 290, 64, 64, 64, + 539, 539, 539, 540, 541, 541, 541, 541, 541, 541, 541, 541, 541, 541, + 541, 541, 541, 541, 541, 542, 540, 540, 539, 539, 539, 539, 540, 540, + 539, 540, 540, 540, 543, 544, 544, 544, 544, 544, 544, 544, 544, 544, + 544, 544, 544, 544, 64, 46, 545, 545, 545, 545, 545, 545, 545, 545, 545, + 545, 64, 64, 64, 64, 544, 544, 278, 278, 278, 278, 278, 280, 546, 278, + 283, 283, 278, 278, 278, 278, 278, 64, 547, 547, 547, 547, 547, 547, 547, + 547, 547, 548, 548, 548, 548, 548, 548, 549, 549, 548, 548, 549, 549, + 548, 548, 64, 547, 547, 547, 548, 547, 547, 547, 547, 547, 547, 547, 547, + 548, 549, 64, 64, 550, 550, 550, 550, 550, 550, 550, 550, 550, 550, 64, + 64, 551, 551, 551, 551, 546, 278, 278, 278, 278, 278, 278, 286, 286, 286, + 278, 279, 280, 279, 278, 278, 552, 552, 552, 552, 552, 552, 552, 552, + 553, 552, 553, 553, 554, 552, 552, 553, 553, 552, 552, 552, 552, 552, + 553, 553, 552, 553, 552, 64, 64, 64, 64, 64, 64, 64, 64, 552, 552, 555, + 556, 556, 557, 557, 557, 557, 557, 557, 557, 557, 557, 557, 557, 558, + 559, 559, 558, 558, 560, 560, 557, 561, 561, 558, 562, 64, 64, 292, 292, + 292, 292, 292, 292, 64, 41, 41, 41, 515, 44, 44, 44, 44, 41, 41, 41, 41, + 41, 62, 64, 64, 298, 298, 298, 298, 298, 298, 298, 298, 557, 557, 557, + 558, 558, 559, 558, 558, 559, 558, 558, 560, 558, 562, 64, 64, 563, 563, + 563, 563, 563, 563, 563, 563, 563, 563, 64, 64, 64, 64, 64, 64, 290, 290, + 290, 290, 64, 64, 64, 64, 291, 291, 291, 291, 291, 291, 291, 64, 64, 64, + 64, 291, 291, 291, 291, 291, 291, 291, 291, 291, 64, 64, 64, 64, 564, + 564, 564, 564, 564, 564, 564, 564, 565, 565, 565, 565, 565, 565, 565, + 565, 496, 496, 497, 497, 497, 497, 497, 497, 41, 41, 41, 41, 41, 41, 41, + 64, 64, 64, 64, 83, 83, 83, 83, 83, 64, 64, 64, 64, 64, 110, 566, 110, + 110, 567, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 64, 110, 110, 110, 110, 110, 64, 110, 64, 110, 110, 64, 110, 110, + 64, 110, 110, 126, 126, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, 64, 64, 64, 64, 64, 64, 64, 64, 64, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 569, 418, 64, 64, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 116, 119, 64, 64, 58, 58, + 58, 58, 58, 58, 58, 58, 469, 469, 469, 469, 469, 469, 469, 474, 475, 469, + 64, 64, 64, 64, 64, 64, 78, 78, 78, 78, 78, 78, 78, 136, 136, 136, 136, + 136, 136, 136, 77, 77, 469, 473, 473, 570, 570, 474, 475, 474, 475, 474, + 475, 474, 475, 474, 475, 474, 475, 474, 475, 474, 475, 469, 469, 474, + 475, 469, 469, 469, 469, 570, 570, 570, 571, 469, 571, 64, 469, 571, 469, + 469, 473, 451, 452, 451, 452, 451, 452, 572, 469, 469, 573, 574, 575, + 575, 576, 64, 469, 577, 572, 469, 64, 64, 64, 64, 126, 126, 126, 126, + 126, 64, 126, 126, 126, 126, 126, 126, 126, 64, 64, 410, 64, 578, 578, + 579, 580, 579, 578, 578, 581, 582, 578, 583, 584, 585, 584, 584, 586, + 586, 586, 586, 586, 586, 586, 586, 586, 586, 584, 578, 587, 588, 587, + 578, 578, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, + 589, 589, 589, 589, 589, 589, 581, 578, 582, 590, 591, 590, 592, 592, + 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, + 592, 592, 581, 588, 582, 588, 581, 582, 593, 594, 595, 593, 593, 596, + 596, 596, 596, 596, 596, 596, 596, 596, 596, 597, 596, 596, 596, 596, + 596, 596, 596, 596, 596, 596, 596, 596, 596, 597, 597, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 64, 64, 64, + 598, 598, 598, 598, 598, 598, 64, 64, 598, 598, 598, 64, 64, 64, 580, + 580, 588, 590, 599, 580, 580, 64, 600, 601, 601, 601, 601, 600, 600, 64, + 64, 602, 602, 602, 26, 30, 64, 64, 603, 603, 603, 603, 603, 603, 603, + 603, 603, 603, 603, 603, 64, 603, 603, 603, 603, 603, 603, 603, 603, 603, + 603, 64, 603, 603, 603, 64, 603, 603, 64, 603, 603, 603, 603, 603, 603, + 603, 64, 64, 603, 603, 603, 64, 64, 64, 64, 64, 84, 66, 84, 64, 64, 64, + 64, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 64, + 64, 64, 277, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, + 604, 605, 605, 605, 605, 606, 606, 606, 606, 606, 606, 606, 606, 606, + 606, 606, 606, 606, 606, 606, 606, 606, 605, 605, 606, 64, 64, 64, 26, + 26, 26, 26, 64, 64, 64, 64, 606, 64, 64, 64, 64, 64, 64, 64, 277, 277, + 277, 277, 277, 136, 64, 64, 607, 607, 607, 607, 607, 607, 607, 607, 607, + 607, 607, 607, 607, 64, 64, 64, 608, 608, 608, 608, 608, 608, 608, 608, + 608, 64, 64, 64, 64, 64, 64, 64, 136, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, 64, 64, 64, - 64, 612, 612, 612, 612, 612, 612, 612, 612, 613, 613, 613, 613, 64, 64, - 64, 64, 614, 614, 614, 614, 614, 614, 614, 614, 614, 615, 614, 614, 614, - 614, 614, 614, 614, 614, 615, 64, 64, 64, 64, 64, 616, 616, 616, 616, - 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 617, 617, 617, 617, - 617, 64, 64, 64, 64, 64, 618, 618, 618, 618, 618, 618, 618, 618, 618, - 618, 618, 618, 618, 618, 64, 619, 620, 620, 620, 620, 620, 620, 620, 620, - 620, 620, 620, 620, 64, 64, 64, 64, 621, 622, 622, 622, 622, 622, 64, 64, - 623, 623, 623, 623, 623, 623, 623, 623, 624, 624, 624, 624, 624, 624, - 624, 624, 625, 625, 625, 625, 625, 625, 625, 625, 626, 626, 626, 626, - 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 64, 64, 627, 627, 627, - 627, 627, 627, 627, 627, 627, 627, 64, 64, 64, 64, 64, 64, 628, 628, 628, - 628, 628, 628, 628, 628, 629, 629, 629, 629, 629, 629, 629, 629, 629, - 629, 629, 629, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 630, 631, 631, - 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 64, 631, - 631, 631, 631, 631, 631, 64, 64, 632, 632, 632, 632, 632, 632, 64, 64, - 632, 64, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, - 632, 632, 632, 632, 632, 632, 632, 64, 632, 632, 64, 64, 64, 632, 64, 64, - 632, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, - 633, 64, 634, 635, 635, 635, 635, 635, 635, 635, 635, 636, 636, 636, 636, - 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 637, 637, 638, - 638, 638, 638, 638, 638, 638, 639, 639, 639, 639, 639, 639, 639, 639, - 639, 639, 639, 639, 639, 639, 639, 64, 64, 64, 64, 64, 64, 64, 64, 640, - 640, 640, 640, 640, 640, 640, 640, 640, 641, 641, 641, 641, 641, 641, - 641, 641, 641, 641, 641, 641, 641, 641, 642, 642, 642, 642, 642, 642, 64, - 64, 64, 643, 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, 64, 64, - 64, 64, 64, 645, 646, 646, 646, 646, 646, 646, 646, 646, 647, 647, 647, - 647, 647, 647, 647, 647, 64, 64, 64, 64, 64, 64, 647, 647, 648, 649, 649, - 649, 64, 649, 649, 64, 64, 64, 64, 64, 649, 650, 649, 651, 648, 648, 648, - 648, 64, 648, 648, 648, 64, 648, 648, 648, 648, 648, 648, 648, 648, 648, - 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 64, 64, 64, 64, 651, - 652, 650, 64, 64, 64, 64, 653, 654, 654, 654, 654, 654, 654, 654, 654, - 655, 655, 655, 655, 655, 655, 655, 655, 655, 64, 64, 64, 64, 64, 64, 64, - 656, 656, 656, 656, 656, 656, 656, 656, 656, 656, 656, 656, 656, 657, - 657, 658, 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, - 659, 660, 660, 660, 661, 661, 661, 661, 661, 661, 661, 661, 662, 661, - 661, 661, 661, 661, 661, 661, 661, 661, 661, 661, 661, 663, 664, 64, 64, - 64, 64, 665, 665, 665, 665, 665, 666, 666, 666, 666, 666, 666, 666, 64, - 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, 64, - 64, 64, 668, 668, 668, 668, 668, 668, 668, 669, 669, 669, 669, 669, 669, - 669, 669, 669, 669, 669, 669, 669, 669, 64, 64, 670, 670, 670, 670, 670, - 670, 670, 670, 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, 64, - 64, 64, 64, 64, 672, 672, 672, 672, 672, 672, 672, 672, 673, 673, 673, - 673, 673, 673, 673, 673, 673, 673, 64, 64, 64, 64, 64, 64, 64, 674, 674, - 674, 674, 64, 64, 64, 64, 675, 675, 675, 675, 675, 675, 675, 676, 676, - 676, 676, 676, 676, 676, 676, 676, 64, 64, 64, 64, 64, 64, 64, 677, 677, - 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 677, 64, 678, - 679, 678, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, - 680, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, - 679, 681, 682, 682, 682, 682, 682, 682, 682, 64, 64, 64, 64, 683, 683, - 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, - 683, 683, 683, 683, 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, 64, - 64, 64, 64, 64, 64, 64, 681, 685, 685, 686, 687, 687, 687, 687, 687, 687, - 687, 687, 687, 687, 687, 687, 687, 686, 686, 686, 685, 685, 685, 685, - 686, 686, 688, 689, 690, 690, 691, 690, 690, 690, 690, 64, 64, 64, 64, - 64, 64, 692, 692, 692, 692, 692, 692, 692, 692, 692, 64, 64, 64, 64, 64, - 64, 64, 693, 693, 693, 693, 693, 693, 693, 693, 693, 693, 64, 64, 64, 64, - 64, 64, 694, 694, 694, 695, 695, 695, 695, 695, 695, 695, 695, 695, 695, - 695, 695, 695, 695, 695, 695, 695, 695, 695, 695, 696, 696, 696, 696, - 696, 697, 696, 696, 696, 696, 696, 696, 698, 698, 64, 699, 699, 699, 699, - 699, 699, 699, 699, 699, 699, 700, 700, 700, 700, 64, 64, 64, 64, 701, - 701, 701, 701, 701, 701, 701, 701, 701, 701, 701, 702, 703, 703, 701, 64, - 704, 704, 705, 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, - 706, 706, 706, 706, 706, 705, 705, 705, 704, 704, 704, 704, 704, 704, - 704, 704, 704, 705, 707, 706, 706, 706, 706, 708, 708, 708, 708, 64, 64, - 64, 64, 708, 64, 64, 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, - 706, 64, 64, 64, 64, 64, 64, 710, 710, 710, 710, 710, 710, 710, 710, 710, - 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, 64, 64, 64, 711, - 711, 711, 711, 711, 711, 711, 711, 711, 711, 64, 711, 711, 711, 711, 711, - 711, 711, 711, 711, 712, 712, 712, 713, 713, 713, 712, 712, 713, 714, - 715, 713, 716, 716, 716, 716, 716, 716, 64, 64, 717, 717, 717, 717, 717, - 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 718, 719, 719, 719, - 718, 718, 718, 718, 718, 718, 720, 721, 64, 64, 64, 64, 64, 722, 722, - 722, 722, 722, 722, 722, 722, 722, 722, 64, 64, 64, 64, 64, 64, 64, 723, - 724, 724, 64, 725, 725, 725, 725, 725, 725, 725, 725, 64, 64, 725, 725, - 64, 64, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, - 725, 64, 725, 725, 725, 725, 725, 725, 725, 64, 725, 725, 64, 725, 725, - 725, 725, 725, 64, 64, 726, 725, 724, 724, 723, 724, 724, 724, 724, 64, - 64, 724, 724, 64, 64, 724, 724, 727, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 724, 64, 64, 64, 64, 64, 725, 725, 725, 725, 725, 724, 724, 64, 64, 728, - 728, 728, 728, 728, 728, 728, 64, 64, 64, 729, 729, 729, 729, 729, 729, - 729, 729, 730, 730, 730, 731, 731, 731, 731, 731, 731, 730, 731, 730, - 730, 730, 730, 731, 731, 730, 732, 733, 729, 729, 734, 729, 735, 735, - 735, 735, 735, 735, 735, 735, 735, 735, 64, 64, 64, 64, 64, 64, 736, 736, - 736, 736, 736, 736, 736, 736, 736, 736, 736, 736, 736, 736, 736, 737, - 737, 737, 738, 738, 738, 738, 64, 64, 737, 737, 737, 737, 738, 738, 737, - 739, 740, 741, 741, 741, 741, 741, 741, 741, 741, 741, 64, 64, 64, 64, - 64, 64, 742, 742, 742, 742, 742, 742, 742, 742, 743, 743, 743, 744, 744, - 744, 744, 744, 744, 744, 744, 743, 743, 744, 743, 745, 744, 746, 746, - 746, 742, 64, 64, 64, 747, 747, 747, 747, 747, 747, 747, 747, 747, 747, - 64, 64, 64, 64, 64, 64, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, - 748, 749, 750, 749, 750, 750, 749, 749, 749, 749, 749, 749, 751, 752, - 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 64, 64, 64, 64, 64, 64, - 754, 754, 754, 754, 754, 754, 754, 754, 755, 755, 755, 755, 755, 755, - 755, 755, 756, 756, 756, 756, 756, 756, 756, 756, 756, 756, 757, 757, - 757, 757, 757, 757, 757, 757, 757, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 758, 759, 759, 759, 759, 759, 759, 759, 759, 759, 64, 64, 64, - 64, 64, 64, 64, 760, 760, 760, 760, 760, 760, 760, 760, 760, 64, 64, 64, - 64, 64, 64, 64, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, - 761, 761, 761, 761, 64, 762, 762, 762, 762, 762, 64, 64, 64, 763, 763, - 763, 763, 763, 763, 763, 763, 763, 763, 763, 763, 763, 763, 763, 64, 512, - 64, 64, 64, 64, 64, 64, 64, 764, 764, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 764, 764, 64, 765, 765, 765, 765, 765, 765, 765, 765, - 765, 765, 64, 64, 64, 64, 766, 766, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 64, 64, 768, 768, 768, 768, 768, 769, - 64, 64, 770, 770, 770, 770, 770, 770, 770, 770, 771, 771, 771, 771, 771, - 771, 771, 772, 772, 772, 772, 772, 773, 773, 773, 773, 774, 774, 774, - 774, 772, 773, 64, 64, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, - 64, 776, 776, 776, 776, 776, 776, 776, 64, 770, 770, 770, 770, 770, 64, - 64, 64, 64, 64, 770, 770, 770, 777, 777, 777, 777, 777, 777, 777, 777, - 777, 777, 777, 777, 777, 64, 64, 64, 777, 778, 778, 778, 778, 778, 778, - 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, - 778, 778, 64, 64, 64, 64, 64, 64, 64, 64, 779, 779, 779, 779, 780, 780, - 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 486, 482, 64, 64, - 64, 64, 64, 64, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, - 64, 64, 64, 64, 64, 781, 781, 781, 781, 781, 64, 64, 64, 781, 64, 64, 64, - 64, 64, 64, 64, 781, 781, 64, 64, 782, 783, 784, 785, 410, 410, 410, 410, - 64, 64, 64, 64, 277, 277, 277, 277, 277, 277, 64, 64, 277, 277, 277, 277, - 277, 277, 277, 64, 64, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 786, 786, 400, 400, 400, 277, 277, 277, 787, 786, 786, 786, - 786, 786, 410, 410, 410, 410, 410, 410, 410, 410, 136, 136, 136, 136, - 136, 136, 136, 136, 277, 277, 78, 78, 78, 78, 78, 136, 136, 277, 277, - 277, 277, 277, 277, 78, 78, 78, 78, 277, 277, 609, 609, 788, 788, 788, - 609, 64, 64, 522, 522, 64, 64, 64, 64, 64, 64, 442, 442, 442, 442, 442, - 442, 442, 442, 442, 442, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, - 34, 34, 34, 34, 34, 34, 34, 64, 34, 34, 34, 34, 34, 34, 442, 64, 442, - 442, 64, 64, 442, 64, 64, 442, 442, 64, 64, 442, 442, 442, 442, 64, 442, - 442, 34, 34, 64, 34, 64, 34, 34, 34, 34, 34, 34, 34, 64, 34, 34, 34, 34, - 34, 34, 34, 442, 442, 64, 442, 442, 442, 442, 64, 64, 442, 442, 442, 442, - 442, 442, 442, 442, 64, 442, 442, 442, 442, 442, 442, 442, 64, 34, 34, - 442, 442, 64, 442, 442, 442, 442, 64, 442, 442, 442, 442, 442, 64, 442, - 64, 64, 64, 442, 442, 442, 442, 442, 442, 442, 64, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 64, 64, 442, 789, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 445, 34, 34, 34, 34, 34, 34, 442, 442, 442, 442, 442, 442, 442, - 442, 442, 789, 34, 34, 34, 34, 34, 34, 34, 34, 34, 445, 34, 34, 442, 442, - 442, 442, 442, 789, 34, 34, 34, 34, 34, 34, 34, 34, 34, 445, 34, 34, 34, - 34, 34, 34, 442, 442, 442, 442, 442, 442, 442, 442, 442, 789, 34, 445, - 34, 34, 34, 34, 34, 34, 34, 34, 442, 34, 64, 64, 790, 790, 790, 790, 790, - 790, 790, 790, 790, 790, 791, 791, 791, 791, 791, 791, 791, 791, 791, - 791, 791, 791, 791, 64, 64, 792, 792, 792, 792, 792, 792, 792, 792, 792, - 793, 793, 793, 793, 793, 793, 793, 64, 126, 126, 126, 126, 64, 126, 126, - 126, 64, 126, 126, 64, 126, 64, 64, 126, 64, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 64, 126, 126, 126, 126, 64, 126, 64, 126, 64, - 64, 64, 64, 64, 64, 126, 64, 64, 64, 64, 126, 64, 126, 64, 126, 64, 126, - 126, 126, 64, 126, 64, 126, 64, 126, 64, 126, 64, 126, 126, 126, 126, 64, - 126, 64, 126, 126, 64, 126, 126, 126, 126, 126, 126, 126, 126, 126, 64, - 64, 64, 64, 64, 126, 126, 126, 64, 126, 126, 126, 113, 113, 64, 64, 64, - 64, 64, 64, 64, 26, 26, 26, 26, 26, 26, 26, 33, 33, 33, 446, 446, 64, 64, - 64, 453, 453, 453, 453, 453, 453, 277, 64, 453, 453, 26, 26, 64, 64, 64, - 64, 453, 453, 453, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 277, 277, - 794, 489, 489, 64, 64, 64, 64, 64, 489, 489, 489, 64, 64, 64, 64, 64, - 489, 64, 64, 64, 64, 64, 64, 64, 489, 489, 64, 64, 64, 64, 64, 64, 26, - 26, 26, 26, 26, 64, 64, 64, 64, 64, 64, 64, 26, 26, 26, 26, 26, 26, 64, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 64, 26, 26, 26, 26, 26, 26, 64, 64, - 26, 26, 26, 497, 497, 497, 497, 497, 497, 496, 498, 498, 498, 498, 498, - 498, 498, 64, 64, 64, 410, 64, 64, 64, 64, 64, 64, 410, 410, 410, 410, - 410, 410, 410, 410, 568, 568, 568, 568, 568, 567, 64, 64, + 64, 609, 609, 609, 609, 609, 609, 609, 609, 610, 610, 610, 610, 64, 64, + 64, 64, 611, 611, 611, 611, 611, 611, 611, 611, 611, 612, 611, 611, 611, + 611, 611, 611, 611, 611, 612, 64, 64, 64, 64, 64, 613, 613, 613, 613, + 613, 613, 613, 613, 613, 613, 613, 613, 613, 613, 614, 614, 614, 614, + 614, 64, 64, 64, 64, 64, 615, 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 64, 616, 617, 617, 617, 617, 617, 617, 617, 617, + 617, 617, 617, 617, 64, 64, 64, 64, 618, 619, 619, 619, 619, 619, 64, 64, + 620, 620, 620, 620, 620, 620, 620, 620, 621, 621, 621, 621, 621, 621, + 621, 621, 622, 622, 622, 622, 622, 622, 622, 622, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 64, 64, 624, 624, 624, + 624, 624, 624, 624, 624, 624, 624, 64, 64, 64, 64, 64, 64, 625, 625, 625, + 625, 625, 625, 625, 625, 626, 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 626, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 627, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 64, 628, + 628, 628, 628, 628, 628, 64, 64, 629, 629, 629, 629, 629, 629, 64, 64, + 629, 64, 629, 629, 629, 629, 629, 629, 629, 629, 629, 629, 629, 629, 629, + 629, 629, 629, 629, 629, 629, 629, 64, 629, 629, 64, 64, 64, 629, 64, 64, + 629, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, + 630, 64, 631, 632, 632, 632, 632, 632, 632, 632, 632, 633, 633, 633, 633, + 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 634, 634, 635, + 635, 635, 635, 635, 635, 635, 636, 636, 636, 636, 636, 636, 636, 636, + 636, 636, 636, 636, 636, 636, 636, 64, 64, 64, 64, 64, 64, 64, 64, 637, + 637, 637, 637, 637, 637, 637, 637, 637, 638, 638, 638, 638, 638, 638, + 638, 638, 638, 638, 638, 64, 638, 638, 64, 64, 64, 64, 64, 639, 639, 639, + 639, 639, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 641, 641, 641, 641, 641, 641, 64, 64, 64, 642, 643, 643, 643, + 643, 643, 643, 643, 643, 643, 643, 64, 64, 64, 64, 64, 644, 645, 645, + 645, 645, 645, 645, 645, 645, 646, 646, 646, 646, 646, 646, 646, 646, 64, + 64, 64, 64, 647, 647, 646, 646, 647, 647, 647, 647, 647, 647, 647, 647, + 64, 64, 647, 647, 647, 647, 647, 647, 648, 649, 649, 649, 64, 649, 649, + 64, 64, 64, 64, 64, 649, 650, 649, 651, 648, 648, 648, 648, 64, 648, 648, + 648, 64, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, + 648, 648, 648, 648, 648, 648, 64, 64, 64, 64, 651, 652, 650, 64, 64, 64, + 64, 653, 654, 654, 654, 654, 654, 654, 654, 654, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 64, 64, 64, 64, 64, 64, 64, 656, 656, 656, 656, 656, + 656, 656, 656, 656, 656, 656, 656, 656, 657, 657, 658, 659, 659, 659, + 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, 660, 660, 660, 661, + 661, 661, 661, 661, 661, 661, 661, 662, 661, 661, 661, 661, 661, 661, + 661, 661, 661, 661, 661, 661, 663, 664, 64, 64, 64, 64, 665, 665, 665, + 665, 665, 666, 666, 666, 666, 666, 666, 666, 64, 667, 667, 667, 667, 667, + 667, 667, 667, 667, 667, 667, 667, 667, 667, 64, 64, 64, 668, 668, 668, + 668, 668, 668, 668, 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, + 669, 669, 669, 669, 64, 64, 670, 670, 670, 670, 670, 670, 670, 670, 671, + 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, 64, 64, 64, 64, 64, + 672, 672, 672, 672, 672, 672, 672, 672, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 64, 64, 64, 64, 64, 64, 64, 674, 674, 674, 674, 64, + 64, 64, 64, 675, 675, 675, 675, 675, 675, 675, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 64, 64, 64, 64, 64, 64, 64, 677, 677, 677, 677, 677, + 677, 677, 677, 677, 677, 677, 64, 64, 64, 64, 64, 678, 678, 678, 678, + 678, 678, 678, 678, 678, 678, 678, 64, 64, 64, 64, 64, 64, 64, 679, 679, + 679, 679, 679, 679, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, + 680, 680, 680, 680, 680, 64, 681, 682, 681, 683, 683, 683, 683, 683, 683, + 683, 683, 683, 683, 683, 683, 683, 682, 682, 682, 682, 682, 682, 682, + 682, 682, 682, 682, 682, 682, 682, 684, 685, 685, 685, 685, 685, 685, + 685, 64, 64, 64, 64, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, + 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 687, 687, 687, 687, + 687, 687, 687, 687, 687, 687, 64, 64, 64, 64, 64, 64, 64, 684, 688, 688, + 689, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, + 689, 689, 689, 688, 688, 688, 688, 689, 689, 691, 692, 693, 693, 694, + 693, 693, 693, 693, 64, 64, 64, 64, 64, 64, 695, 695, 695, 695, 695, 695, + 695, 695, 695, 64, 64, 64, 64, 64, 64, 64, 696, 696, 696, 696, 696, 696, + 696, 696, 696, 696, 64, 64, 64, 64, 64, 64, 697, 697, 697, 698, 698, 698, + 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698, + 698, 698, 698, 699, 699, 699, 699, 699, 700, 699, 699, 699, 699, 699, + 699, 701, 701, 64, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 703, + 703, 703, 703, 64, 64, 64, 64, 704, 704, 704, 704, 704, 704, 704, 704, + 704, 704, 704, 705, 706, 706, 704, 64, 707, 707, 708, 709, 709, 709, 709, + 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, 709, 708, 708, + 708, 707, 707, 707, 707, 707, 707, 707, 707, 707, 708, 710, 709, 709, + 709, 709, 711, 711, 711, 711, 711, 712, 707, 707, 711, 64, 64, 713, 713, + 713, 713, 713, 713, 713, 713, 713, 713, 709, 711, 709, 711, 711, 711, 64, + 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, + 714, 714, 714, 714, 714, 714, 64, 64, 64, 715, 715, 715, 715, 715, 715, + 715, 715, 715, 715, 64, 715, 715, 715, 715, 715, 715, 715, 715, 715, 716, + 716, 716, 717, 717, 717, 716, 716, 717, 718, 719, 717, 720, 720, 720, + 720, 720, 720, 64, 64, 721, 721, 721, 721, 721, 721, 721, 64, 721, 64, + 721, 721, 721, 721, 64, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, + 721, 721, 721, 721, 721, 64, 721, 721, 722, 64, 64, 64, 64, 64, 64, 723, + 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, + 724, 725, 725, 725, 724, 724, 724, 724, 724, 724, 726, 727, 64, 64, 64, + 64, 64, 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, 64, 64, 64, 64, + 64, 64, 729, 729, 730, 730, 64, 731, 731, 731, 731, 731, 731, 731, 731, + 64, 64, 731, 731, 64, 64, 731, 731, 731, 731, 731, 731, 731, 731, 731, + 731, 731, 731, 731, 731, 64, 731, 731, 731, 731, 731, 731, 731, 64, 731, + 731, 64, 731, 731, 731, 731, 731, 64, 64, 732, 731, 730, 730, 729, 730, + 730, 730, 730, 64, 64, 730, 730, 64, 64, 730, 730, 733, 64, 64, 731, 64, + 64, 64, 64, 64, 64, 730, 64, 64, 64, 64, 64, 731, 731, 731, 731, 731, + 730, 730, 64, 64, 734, 734, 734, 734, 734, 734, 734, 64, 64, 64, 735, + 735, 735, 735, 735, 735, 735, 735, 736, 736, 736, 737, 737, 737, 737, + 737, 737, 736, 737, 736, 736, 736, 736, 737, 737, 736, 738, 739, 735, + 735, 740, 735, 741, 741, 741, 741, 741, 741, 741, 741, 741, 741, 64, 64, + 64, 64, 64, 64, 742, 742, 742, 742, 742, 742, 742, 742, 742, 742, 742, + 742, 742, 742, 742, 743, 743, 743, 744, 744, 744, 744, 64, 64, 743, 743, + 743, 743, 744, 744, 743, 745, 746, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 747, 747, 747, 747, 747, 747, 742, 742, 742, 742, 744, 744, 64, + 64, 748, 748, 748, 748, 748, 748, 748, 748, 749, 749, 749, 750, 750, 750, + 750, 750, 750, 750, 750, 749, 749, 750, 749, 751, 750, 752, 752, 752, + 748, 64, 64, 64, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 64, + 64, 64, 64, 64, 64, 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, + 754, 755, 756, 755, 756, 756, 755, 755, 755, 755, 755, 755, 757, 758, + 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 64, 64, 64, 64, 64, 64, + 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 64, 64, 64, 761, 761, + 761, 762, 762, 761, 761, 761, 761, 762, 761, 761, 761, 761, 763, 64, 64, + 64, 64, 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, 765, 765, 766, + 766, 766, 767, 768, 768, 768, 768, 768, 768, 768, 768, 769, 769, 769, + 769, 769, 769, 769, 769, 770, 770, 770, 770, 770, 770, 770, 770, 770, + 770, 771, 771, 771, 771, 771, 771, 771, 771, 771, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 772, 773, 773, 773, 773, 773, 773, 773, 773, 773, + 64, 64, 64, 64, 64, 64, 64, 774, 774, 774, 774, 774, 774, 774, 774, 774, + 774, 64, 64, 64, 64, 64, 64, 775, 775, 775, 775, 775, 775, 775, 775, 775, + 775, 775, 775, 775, 775, 775, 64, 776, 776, 776, 776, 776, 64, 64, 64, + 774, 774, 774, 774, 64, 64, 64, 64, 777, 777, 777, 777, 777, 777, 777, + 777, 777, 777, 777, 777, 777, 777, 777, 64, 778, 778, 778, 778, 778, 778, + 778, 778, 778, 778, 778, 778, 778, 778, 778, 64, 511, 64, 64, 64, 64, 64, + 64, 64, 779, 779, 779, 779, 779, 779, 779, 779, 779, 779, 779, 779, 779, + 779, 779, 64, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 64, 64, + 64, 64, 781, 781, 782, 782, 782, 782, 782, 782, 782, 782, 782, 782, 782, + 782, 782, 782, 64, 64, 783, 783, 783, 783, 783, 784, 64, 64, 785, 785, + 785, 785, 785, 785, 785, 785, 786, 786, 786, 786, 786, 786, 786, 787, + 787, 787, 787, 787, 788, 788, 788, 788, 789, 789, 789, 789, 787, 788, 64, + 64, 790, 790, 790, 790, 790, 790, 790, 790, 790, 790, 64, 791, 791, 791, + 791, 791, 791, 791, 64, 785, 785, 785, 785, 785, 64, 64, 64, 64, 64, 785, + 785, 785, 792, 792, 792, 792, 792, 792, 792, 792, 792, 792, 792, 792, + 792, 64, 64, 64, 792, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, + 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 64, 64, 64, + 64, 64, 64, 64, 64, 794, 794, 794, 794, 795, 795, 795, 795, 795, 795, + 795, 795, 795, 795, 795, 795, 795, 486, 482, 64, 64, 64, 64, 64, 64, 796, + 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, 64, 64, 64, 64, 64, + 796, 796, 796, 796, 796, 64, 64, 64, 796, 64, 64, 64, 64, 64, 64, 64, + 796, 796, 64, 64, 797, 798, 799, 800, 410, 410, 410, 410, 64, 64, 64, 64, + 277, 277, 277, 277, 277, 277, 64, 64, 277, 277, 277, 277, 277, 277, 277, + 64, 64, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 801, + 801, 400, 400, 400, 277, 277, 277, 802, 801, 801, 801, 801, 801, 410, + 410, 410, 410, 410, 410, 410, 410, 136, 136, 136, 136, 136, 136, 136, + 136, 277, 277, 78, 78, 78, 78, 78, 136, 136, 277, 277, 277, 277, 277, + 277, 78, 78, 78, 78, 277, 277, 277, 64, 64, 64, 64, 64, 64, 64, 606, 606, + 803, 803, 803, 606, 64, 64, 521, 521, 64, 64, 64, 64, 64, 64, 442, 442, + 442, 442, 442, 442, 442, 442, 442, 442, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 442, 442, 442, 442, 442, 442, + 442, 442, 442, 442, 34, 34, 34, 34, 34, 34, 34, 64, 34, 34, 34, 34, 34, + 34, 442, 64, 442, 442, 64, 64, 442, 64, 64, 442, 442, 64, 64, 442, 442, + 442, 442, 64, 442, 442, 34, 34, 64, 34, 64, 34, 34, 34, 34, 34, 34, 34, + 64, 34, 34, 34, 34, 34, 34, 34, 442, 442, 64, 442, 442, 442, 442, 64, 64, + 442, 442, 442, 442, 442, 442, 442, 442, 64, 442, 442, 442, 442, 442, 442, + 442, 64, 34, 34, 442, 442, 64, 442, 442, 442, 442, 64, 442, 442, 442, + 442, 442, 64, 442, 64, 64, 64, 442, 442, 442, 442, 442, 442, 442, 64, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 64, 64, 442, 804, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 445, 34, 34, 34, 34, 34, 34, 442, 442, 442, 442, + 442, 442, 442, 442, 442, 804, 34, 34, 34, 34, 34, 34, 34, 34, 34, 445, + 34, 34, 442, 442, 442, 442, 442, 804, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 445, 34, 34, 34, 34, 34, 34, 442, 442, 442, 442, 442, 442, 442, 442, 442, + 804, 34, 445, 34, 34, 34, 34, 34, 34, 34, 34, 442, 34, 64, 64, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, 806, 806, 806, 806, 806, 806, + 806, 806, 807, 807, 807, 807, 807, 807, 807, 807, 807, 807, 807, 807, + 807, 807, 807, 806, 806, 806, 806, 807, 807, 807, 807, 807, 807, 807, + 807, 807, 807, 806, 806, 806, 806, 806, 806, 806, 806, 807, 806, 806, + 806, 806, 806, 806, 807, 806, 806, 808, 808, 808, 808, 808, 64, 64, 64, + 64, 64, 64, 64, 807, 807, 807, 807, 807, 64, 807, 807, 807, 807, 807, + 807, 807, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, + 809, 64, 64, 810, 810, 810, 810, 810, 810, 810, 810, 810, 811, 811, 811, + 811, 811, 811, 811, 64, 126, 126, 126, 126, 64, 126, 126, 126, 64, 126, + 126, 64, 126, 64, 64, 126, 64, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 64, 126, 126, 126, 126, 64, 126, 64, 126, 64, 64, 64, 64, 64, + 64, 126, 64, 64, 64, 64, 126, 64, 126, 64, 126, 64, 126, 126, 126, 64, + 126, 64, 126, 64, 126, 64, 126, 64, 126, 126, 126, 126, 64, 126, 64, 126, + 126, 64, 126, 126, 126, 126, 126, 126, 126, 126, 126, 64, 64, 64, 64, 64, + 126, 126, 126, 64, 126, 126, 126, 113, 113, 64, 64, 64, 64, 64, 64, 64, + 26, 26, 26, 26, 26, 26, 26, 33, 33, 33, 446, 446, 64, 64, 64, 453, 453, + 453, 453, 453, 453, 277, 64, 453, 453, 26, 26, 64, 64, 64, 64, 453, 453, + 453, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 277, 277, 812, 489, 489, + 64, 64, 64, 64, 64, 489, 489, 489, 64, 64, 64, 64, 64, 489, 64, 64, 64, + 64, 64, 64, 64, 489, 489, 64, 64, 64, 64, 64, 64, 26, 26, 26, 47, 47, 47, + 47, 47, 26, 26, 64, 26, 26, 26, 26, 26, 26, 26, 26, 26, 64, 26, 26, 26, + 26, 64, 64, 64, 64, 64, 64, 64, 26, 26, 26, 26, 26, 64, 64, 64, 496, 496, + 496, 496, 496, 496, 496, 497, 496, 496, 496, 496, 496, 497, 497, 497, + 497, 497, 497, 497, 497, 497, 64, 64, 64, 410, 64, 64, 64, 64, 64, 64, + 410, 410, 410, 410, 410, 410, 410, 410, 565, 565, 565, 565, 565, 565, 64, + 64, }; /* decomposition data */ From 23e56e088a721863cfdef4f027fb66eecbd77457 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 25 Jul 2015 17:36:46 +0200 Subject: [PATCH 67/77] Fix broken sentence --- src/hb-set-private.hh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh index bba401517..3c302b1da 100644 --- a/src/hb-set-private.hh +++ b/src/hb-set-private.hh @@ -36,7 +36,15 @@ * "approximate member query". Conceptually these are like Bloom * Filter and Quotient Filter, however, much smaller, faster, and * designed to fit the requirements of our uses for glyph coverage - * queries. As a result, our filters have much higher. + * queries. + * + * Our filters are highly accurate if the lookup covers fairly local + * set of glyphs, but fully flooded and ineffective if coverage is + * all over the place. + * + * The frozen-set can be used instead of a digest, to trade more + * memory for 100% accuracy, but in practice, that doesn't look like + * an attractive trade-off. */ template From 2ed6be66703e6cc67f3a3746e197001dad3d9b74 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 26 Jul 2015 19:29:53 +0200 Subject: [PATCH 68/77] 0.9.42 --- NEWS | 12 ++++++++++++ configure.ac | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index a5ac9067b..d0798773d 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,14 @@ +Overview of changes leading to 0.9.42 +Thursday, July 26, 2015 +===================================== +- New API to allow for retrieving finer-grained cluster + mappings if the client desires to handle them. Default + behavior is unchanged. +- Fix cluster merging when removing default-ignorables. +- Update to Unicode 8.0 +- hb-graphite2 fixes. +- Misc fixes. - Removed HB_NO_MERGE_CLUSTERS hack. - New API: hb_buffer_cluster_level_t enum @@ -6,6 +16,7 @@ hb_buffer_set_cluster_level() hb-shape / hb-view --cluster-level + Overview of changes leading to 0.9.41 Thursday, June 18, 2015 ===================================== @@ -16,6 +27,7 @@ Thursday, June 18, 2015 - Fix hb_language_t in language bindings. - Misc fixes. + Overview of changes leading to 0.9.40 Friday, March 20, 2015 ===================================== diff --git a/configure.ac b/configure.ac index 4d2bbf81e..ff61c9521 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.64]) AC_INIT([HarfBuzz], - [0.9.41], + [0.9.42], [http://bugs.freedesktop.org/enter_bug.cgi?product=harfbuzz], [harfbuzz], [http://harfbuzz.org/]) From 260442346a5756c3538ee8fcbf157d1cddcf6f36 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 26 Jul 2015 23:39:10 +0200 Subject: [PATCH 69/77] 1.0.0 --- NEWS | 10 ++++++++++ configure.ac | 4 ++-- src/Makefile.am | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index d0798773d..70e108850 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,13 @@ +Overview of changes leading to 1.0.0 +Thursday, July 26, 2015 +==================================== + +- Implement Universal Shaping Engine: + https://www.microsoft.com/typography/OpenTypeDev/USE/intro.htm + http://blogs.windows.com/bloggingwindows/2015/02/23/windows-shapes-the-worlds-languages/ +- Bump version to 1.0.0. The soname was NOT bumped. + + Overview of changes leading to 0.9.42 Thursday, July 26, 2015 ===================================== diff --git a/configure.ac b/configure.ac index ff61c9521..c6aa7eed2 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.64]) AC_INIT([HarfBuzz], - [0.9.42], + [1.0.0], [http://bugs.freedesktop.org/enter_bug.cgi?product=harfbuzz], [harfbuzz], [http://harfbuzz.org/]) @@ -51,7 +51,7 @@ m4_if(m4_eval(hb_version_minor % 2), [1], m4_define([hb_libtool_age], m4_eval(hb_version_int - hb_libtool_revision)) m4_define([hb_libtool_current], - m4_eval(hb_version_major + hb_libtool_age)) + m4_eval(hb_libtool_age)) HB_LIBTOOL_VERSION_INFO=hb_libtool_current:hb_libtool_revision:hb_libtool_age AC_SUBST(HB_LIBTOOL_VERSION_INFO) diff --git a/src/Makefile.am b/src/Makefile.am index a528c9d63..753b9308f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -371,7 +371,7 @@ TESTS_ENVIRONMENT = \ if HAVE_INTROSPECTION -include $(INTROSPECTION_MAKEFILE) -INTROSPECTION_GIRS = HarfBuzz-$(HB_VERSION_MAJOR).0.gir # What does the 0 mean anyway?! +INTROSPECTION_GIRS = HarfBuzz-0.0.gir # What does the 0 mean anyway?! INTROSPECTION_SCANNER_ARGS = -I$(srcdir) -n hb --identifier-prefix=hb_ --warn-all INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) INTROSPECTION_SCANNER_ENV = CC="$(CC)" From f1c20e1ba5bf218df7dc3e198bdcf1f449fc9387 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 27 Jul 2015 12:16:02 +0200 Subject: [PATCH 70/77] [USE] Fix out-of-bounds static array access --- src/hb-ot-shape-complex-use.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index 4b84bd750..1d44d2200 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -142,7 +142,7 @@ collect_features_use (hb_ot_shape_planner_t *plan) map->add_gsub_pause (reorder); /* "Topographical features" */ - for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++) + for (unsigned int i = 0; i < ARRAY_LENGTH (arabic_features); i++) map->add_feature (arabic_features[i], 1, F_NONE); map->add_gsub_pause (NULL); From 9002c27b2f54bb5135db92045c0d770b47317577 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 27 Jul 2015 12:17:54 +0200 Subject: [PATCH 71/77] 1.0.1 --- NEWS | 9 ++++++++- configure.ac | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 70e108850..ed67abf12 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,12 @@ +Overview of changes leading to 1.0.1 +Monday, July 27, 2015 +==================================== + +- Fix out-of-bounds access in USE shaper. + + Overview of changes leading to 1.0.0 -Thursday, July 26, 2015 +Sunday, July 26, 2015 ==================================== - Implement Universal Shaping Engine: diff --git a/configure.ac b/configure.ac index c6aa7eed2..4d64586b5 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.64]) AC_INIT([HarfBuzz], - [1.0.0], + [1.0.1], [http://bugs.freedesktop.org/enter_bug.cgi?product=harfbuzz], [harfbuzz], [http://harfbuzz.org/]) From 160f635523d596f61e292776f638d4eb09673463 Mon Sep 17 00:00:00 2001 From: Romain Naour Date: Wed, 22 Jul 2015 23:26:23 +0200 Subject: [PATCH 72/77] fix static linking with icu-uc When linking test-unicode statically it needs $(ICU_LIBS) which contains all required flags. Especially -lstdc++. Fixes: http://autobuild.buildroot.net/results/210/2107f9dfb39eeb6559fb4271c7af8b39aef521ca/ Signed-off-by: Romain Naour --- test/api/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/api/Makefile.am b/test/api/Makefile.am index 4ff14fa20..314a09fd9 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -34,7 +34,7 @@ test_unicode_CPPFLAGS += $(GLIB_CFLAGS) endif if HAVE_ICU test_unicode_CPPFLAGS += $(ICU_CFLAGS) -test_unicode_LDADD += $(top_builddir)/src/libharfbuzz-icu.la +test_unicode_LDADD += $(top_builddir)/src/libharfbuzz-icu.la $(ICU_LIBS) endif From bd22a5cfae24b3b9253bccaeb139e698e74cd0c3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 7 Aug 2015 11:13:27 +0200 Subject: [PATCH 73/77] Bug 91559 - HarfBuzz 1.0.1: Inconsistent DLL files specified/created... Fixes https://bugs.freedesktop.org/show_bug.cgi?id=91559 --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 753b9308f..9d88c24e3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -270,7 +270,7 @@ harfbuzz.def: $(HBHEADERS) $(HBNODISTHEADERS) $(EGREP) '^hb_.* \(' | \ sed -e 's/ (.*//' | \ LANG=C sort; \ - echo LIBRARY libharfbuzz-$(HB_VERSION_MAJOR).dll; \ + echo LIBRARY libharfbuzz-0.dll; \ ) >"$@" @ ! grep -q hb_ERROR "$@" \ || ($(RM) "$@"; false) From f3792342f670978cdc3f8512fb5e80314ca0678d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 8 Aug 2015 18:02:18 +0200 Subject: [PATCH 74/77] [tests] Add test for fallback positioning with cluster_level > 0 For https://github.com/behdad/harfbuzz/pull/123 Currently fails. Fix coming. --- test/shaping/Makefile.am | 1 + .../6466d38c62e73a39202435a4f73bf5d6acbb73c0.ttf | Bin 0 -> 824 bytes test/shaping/fonts/sha1sum/MANIFEST | 1 + test/shaping/tests/MANIFEST | 1 + test/shaping/tests/cluster.tests | 1 + 5 files changed, 4 insertions(+) create mode 100644 test/shaping/fonts/sha1sum/6466d38c62e73a39202435a4f73bf5d6acbb73c0.ttf create mode 100644 test/shaping/tests/cluster.tests diff --git a/test/shaping/Makefile.am b/test/shaping/Makefile.am index 22e326e38..bab3b4779 100644 --- a/test/shaping/Makefile.am +++ b/test/shaping/Makefile.am @@ -38,6 +38,7 @@ CLEANFILES += \ TESTS = \ tests/arabic-fallback-shaping.tests \ tests/arabic-feature-order.tests \ + tests/cluster.tests \ tests/context-matching.tests \ tests/default-ignorables.tests \ tests/hangul-jamo.tests \ diff --git a/test/shaping/fonts/sha1sum/6466d38c62e73a39202435a4f73bf5d6acbb73c0.ttf b/test/shaping/fonts/sha1sum/6466d38c62e73a39202435a4f73bf5d6acbb73c0.ttf new file mode 100644 index 0000000000000000000000000000000000000000..33c4229cb1c324ac04f98f158bd645a8b1686a66 GIT binary patch literal 824 zcmZvaO-NKx7>3_-?!7wB3>M-~5!mFU5C!Ut4TVlAEexRq4RV)vbY_$so${v%F>)bc zG$7VW!nO)Qe`FXy3-t&FmIR^rO2REUi zuD!E1u=V=x89>(2+TD{dlSpe1$us1pxH+6eAuF_FWN&=ndaUfptxue z9Ji)qPOeyMGHjitwwl@sy-jKJGNt#6r}k7v91#1~?I|&nvESR-by+X>+YvEueYf6< zWxEYhB=ilfwqTm-3hGM>{8cr_8$!WAd0|71zp9|Dv^*FHX|)rvcq$c--ni0IA82Vj z5j<@yMaM>aBco$xC>##4IgaDgH}JJ!dT${#>lrgscVdVRTtGLB9iky$v^-ZLj2;Z^ zknmZ2508Xpb*|y38nZv%-QP}IS@*0fLM(z*R%V{Ts{R-*y%E*=yhs3! zI#0OL)&k&O-cIKx-LwDrW>nDi=VFEV__*{sq!$M#`bH zBg$iIdwVOI>Brjj;Y!Ocx_t2Y1EXo<9fCKivlo1e>IA$b^$uOED(WtzG`FMn%g>xe z=l1X1UolElDz#ojYYA8G&LxUT=P`s4HXk}+Vi3dVKooI|@)S*6-C50!5ysRT`)^^2 IOv{1x2THxLKmY&$ literal 0 HcmV?d00001 diff --git a/test/shaping/fonts/sha1sum/MANIFEST b/test/shaping/fonts/sha1sum/MANIFEST index 2881f0a8a..072911f63 100644 --- a/test/shaping/fonts/sha1sum/MANIFEST +++ b/test/shaping/fonts/sha1sum/MANIFEST @@ -6,6 +6,7 @@ 4cce528e99f600ed9c25a2b69e32eb94a03b4ae8.ttf 5028afb650b1bb718ed2131e872fbcce57828fff.ttf 57a9d9f83020155cbb1d2be1f43d82388cbecc88.ttf +6466d38c62e73a39202435a4f73bf5d6acbb73c0.ttf 757ebd573617a24aa9dfbf0b885c54875c6fe06b.ttf 7e14e7883ed152baa158b80e207b66114c823a8b.ttf 813c2f8e5512187fd982417a7fb4286728e6f4a8.ttf diff --git a/test/shaping/tests/MANIFEST b/test/shaping/tests/MANIFEST index 323ad4601..0d97806e3 100644 --- a/test/shaping/tests/MANIFEST +++ b/test/shaping/tests/MANIFEST @@ -1,5 +1,6 @@ arabic-fallback-shaping.tests arabic-feature-order.tests +cluster.tests context-matching.tests default-ignorables.tests hangul-jamo.tests diff --git a/test/shaping/tests/cluster.tests b/test/shaping/tests/cluster.tests new file mode 100644 index 000000000..3a3a3971e --- /dev/null +++ b/test/shaping/tests/cluster.tests @@ -0,0 +1 @@ +fonts/sha1sum/6466d38c62e73a39202435a4f73bf5d6acbb73c0.ttf:--cluster-level=2:U+0078,U+030A,U+0058,U+030A:[gid2=0+1083|gid4=1@-555,-8+0|gid1=2+1200|gid4=3@-614,349+0] From 9099e48e29fe5cfdf8566c8f1ba6ddc8c0799e7e Mon Sep 17 00:00:00 2001 From: jfkthame Date: Fri, 7 Aug 2015 17:51:28 +0100 Subject: [PATCH 75/77] Don't rely on .cluster field in fallback_position Fixes tests/cluster. Fixes https://github.com/behdad/harfbuzz/pull/123 --- src/hb-ot-shape-fallback.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc index 53274b502..748372d01 100644 --- a/src/hb-ot-shape-fallback.cc +++ b/src/hb-ot-shape-fallback.cc @@ -418,13 +418,12 @@ _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan, _hb_buffer_assert_gsubgpos_vars (buffer); unsigned int start = 0; - unsigned int last_cluster = buffer->info[0].cluster; unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; for (unsigned int i = 1; i < count; i++) - if (buffer->info[i].cluster != last_cluster) { + if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))) { position_cluster (plan, font, buffer, start, i); start = i; - last_cluster = buffer->info[i].cluster; } position_cluster (plan, font, buffer, start, count); } From c7dfe316f8c0fc04b7976fca5e58eb46d91b4821 Mon Sep 17 00:00:00 2001 From: jfkthame Date: Fri, 7 Aug 2015 17:55:03 +0100 Subject: [PATCH 76/77] Don't rely on .cluster in _hb_ot_shape_normalize() Fixes https://github.com/behdad/harfbuzz/pull/124 --- src/hb-ot-shape-normalize.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-shape-normalize.cc b/src/hb-ot-shape-normalize.cc index 8cc64af01..111b5908f 100644 --- a/src/hb-ot-shape-normalize.cc +++ b/src/hb-ot-shape-normalize.cc @@ -323,7 +323,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, { unsigned int end; for (end = buffer->idx + 1; end < count; end++) - if (buffer->cur().cluster != buffer->info[end].cluster) + if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end])))) break; decompose_cluster (&c, end, might_short_circuit, always_short_circuit); From 539a610e2e72375e598ab29fd390ed9ec93816d5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 11 Aug 2015 12:58:49 +0200 Subject: [PATCH 77/77] Add Libs.private and Requires.private to harfbuzz.pc Fixes https://bugs.freedesktop.org/show_bug.cgi?id=64501 --- configure.ac | 12 +++++++++--- src/Makefile.am | 15 ++++++++++++--- src/harfbuzz.pc.in | 2 ++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 4d64586b5..7d200760b 100644 --- a/configure.ac +++ b/configure.ac @@ -145,8 +145,10 @@ AC_ARG_WITH(glib, [Use glib @<:@default=auto@:>@])],, [with_glib=auto]) have_glib=false +GLIB_DEPS="glib-2.0 >= 2.16" +AC_SUBST(GLIB_DEPS) if test "x$with_glib" = "xyes" -o "x$with_glib" = "xauto"; then - PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, have_glib=true, :) + PKG_CHECK_MODULES(GLIB, $GLIB_DEPS, have_glib=true, :) fi if test "x$with_glib" = "xyes" -a "x$have_glib" != "xtrue"; then AC_MSG_ERROR([glib support requested but glib-2.0 not found]) @@ -296,8 +298,10 @@ AC_ARG_WITH(graphite2, [Use the graphite2 library @<:@default=no@:>@])],, [with_graphite2=no]) have_graphite2=false +GRAPHITE2_DEPS="graphite2" +AC_SUBST(GRAPHITE2_DEPS) if test "x$with_graphite2" = "xyes" -o "x$with_graphite2" = "xauto"; then - PKG_CHECK_MODULES(GRAPHITE2, graphite2, have_graphite2=true, :) + PKG_CHECK_MODULES(GRAPHITE2, $GRAPHITE2_DEPS, have_graphite2=true, :) fi if test "x$with_graphite2" = "xyes" -a "x$have_graphite2" != "xtrue"; then AC_MSG_ERROR([graphite2 support requested but libgraphite2 not found]) @@ -314,9 +318,11 @@ AC_ARG_WITH(freetype, [Use the FreeType library @<:@default=auto@:>@])],, [with_freetype=auto]) have_freetype=false +FREETYPE_DEPS="freetype2 >= 12.0.6" +AC_SUBST(FREETYPE_DEPS) if test "x$with_freetype" = "xyes" -o "x$with_freetype" = "xauto"; then # See freetype/docs/VERSION.DLL; 12.0.6 means freetype-2.4.2 - PKG_CHECK_MODULES(FREETYPE, freetype2 >= 12.0.6, have_freetype=true, :) + PKG_CHECK_MODULES(FREETYPE, $FREETYPE_DEPS, have_freetype=true, :) fi if test "x$with_freetype" = "xyes" -a "x$have_freetype" != "xtrue"; then AC_MSG_ERROR([FreeType support requested but libfreetype2 not found]) diff --git a/src/Makefile.am b/src/Makefile.am index 9d88c24e3..132683ab3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,6 +20,8 @@ lib_LTLIBRARIES = libharfbuzz.la HBCFLAGS = HBLIBS = +HBNONPCLIBS = +HBDEPS = HBSOURCES = \ hb-atomic-private.hh \ hb-blob.cc \ @@ -133,12 +135,13 @@ endif if HAVE_PTHREAD HBCFLAGS += $(PTHREAD_CFLAGS) -HBLIBS += $(PTHREAD_LIBS) +HBNONPCLIBS += $(PTHREAD_LIBS) endif if HAVE_GLIB HBCFLAGS += $(GLIB_CFLAGS) HBLIBS += $(GLIB_LIBS) +HBDEPS += $(GLIB_DEPS) HBSOURCES += hb-glib.cc HBHEADERS += hb-glib.h endif @@ -146,6 +149,7 @@ endif if HAVE_FREETYPE HBCFLAGS += $(FREETYPE_CFLAGS) HBLIBS += $(FREETYPE_LIBS) +HBDEPS += $(FREETYPE_DEPS) HBSOURCES += hb-ft.cc HBHEADERS += hb-ft.h endif @@ -153,20 +157,21 @@ endif if HAVE_GRAPHITE2 HBCFLAGS += $(GRAPHITE2_CFLAGS) HBLIBS += $(GRAPHITE2_LIBS) +HBDEPS += $(GRAPHITE2_DEPS) HBSOURCES += hb-graphite2.cc HBHEADERS += hb-graphite2.h endif if HAVE_UNISCRIBE HBCFLAGS += $(UNISCRIBE_CFLAGS) -HBLIBS += $(UNISCRIBE_LIBS) +HBNONPCLIBS += $(UNISCRIBE_LIBS) HBSOURCES += hb-uniscribe.cc HBHEADERS += hb-uniscribe.h endif if HAVE_CORETEXT HBCFLAGS += $(CORETEXT_CFLAGS) -HBLIBS += $(CORETEXT_LIBS) +HBNONPCLIBS += $(CORETEXT_LIBS) HBSOURCES += hb-coretext.cc HBHEADERS += hb-coretext.h endif @@ -182,6 +187,8 @@ DIST_SUBDIRS += hb-ucdn # Put the library together +HBLIBS += $(HBNONPCLIBS) + if OS_WIN32 export_symbols = -export-symbols harfbuzz.def harfbuzz_def_dependency = harfbuzz.def @@ -256,6 +263,8 @@ EXTRA_DIST += \ -e 's@%exec_prefix%@$(exec_prefix)@g' \ -e 's@%libdir%@$(libdir)@g' \ -e 's@%includedir%@$(includedir)@g' \ + -e 's@%libs_private%@$(HBNONPCLIBS)@g' \ + -e 's@%requires_private%@$(HBDEPS)@g' \ -e 's@%VERSION%@$(VERSION)@g' \ "$<" > "$@" \ || ($(RM) "$@"; false) diff --git a/src/harfbuzz.pc.in b/src/harfbuzz.pc.in index 7f27bbbde..b3e124aa8 100644 --- a/src/harfbuzz.pc.in +++ b/src/harfbuzz.pc.in @@ -8,4 +8,6 @@ Description: HarfBuzz text shaping library Version: %VERSION% Libs: -L${libdir} -lharfbuzz +Libs.private: %libs_private% +Requires.private: %requires_private% Cflags: -I${includedir}/harfbuzz