[Indic] Start an Indic shaper
authorBehdad Esfahbod <behdad@behdad.org>
Thu, 2 Jun 2011 21:43:12 +0000 (17:43 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Thu, 2 Jun 2011 21:43:12 +0000 (17:43 -0400)
Nothing functional in there yet.

So far, we're parsing IndicSyllabicCategory.txt and IndicMatraCategory.txt
fils from Unicode Character Database and store them in an array to be used
by the shaper.  Also hooked up the shaper, but it does not do anything
right now.

src/Makefile.am
src/gen-indic-table.py [new file with mode: 0755]
src/hb-ot-shape-complex-arabic.cc
src/hb-ot-shape-complex-indic-table.hh [new file with mode: 0644]
src/hb-ot-shape-complex-indic.cc [new file with mode: 0644]
src/hb-ot-shape-complex-private.hh
src/hb-ot-shape-private.hh

index 87d0b02..8701d94 100644 (file)
@@ -55,6 +55,8 @@ HBSOURCES += \
        hb-ot-shape.cc \
        hb-ot-shape-complex-arabic.cc \
        hb-ot-shape-complex-arabic-table.hh \
+       hb-ot-shape-complex-indic.cc \
+       hb-ot-shape-complex-indic-table.hh \
        hb-ot-shape-complex-private.hh \
        hb-ot-shape-private.hh \
        hb-ot-tag.cc \
@@ -114,6 +116,7 @@ nodist_pkginclude_HEADERS = hb-version.h
 
 GENERATORS = \
        gen-arabic-table.py \
+       gen-indic-table.py \
        $(NULL)
 
 EXTRA_DIST += $(GENERATORS)
diff --git a/src/gen-indic-table.py b/src/gen-indic-table.py
new file mode 100755 (executable)
index 0000000..92ec8fe
--- /dev/null
@@ -0,0 +1,201 @@
+#!/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)
+
+files = [file (sys.argv[i+1]) for i in range (3)]
+
+headers = [[f.readline () for i in range (2)] for f in files]
+
+blocks = {}
+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) + 1
+
+               if i == 2:
+                       blocks[t] = (start, end)
+
+# 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
+data = combined
+del combined
+num = len (data)
+
+# 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 " */"
+
+# Shorten values
+print
+short = [{
+       "Bindu":                'Bi',
+       "Visarga":              'Vs',
+       "Vowel":                'Vo',
+       "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].append (s)
+
+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, s)
+                       all_shorts[i].append (s)
+                       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
+
+def print_block (block, start, end, data):
+       print
+       print
+       print "  /* %s  (%04X..%04X) */" % (block, start, end)
+       num = 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)
+               print "%10s" % ("_(%s,%s)," % (short[0][d[0]], short[1][d[1]])),
+
+       if num == 0:
+               # Filler block, don't check occupancy
+               return
+       total = end - start + 1
+       occupancy = num * 100. / total
+       # Maintain at least 30% occupancy in the table */
+       if occupancy < 30:
+               raise Exception ("Table too sparse, please investigate: ", occupancy, block)
+
+uu = data.keys ()
+uu.sort ()
+
+last = -1
+num = 0
+total = 0
+tables = []
+for u in uu:
+       if u <= last:
+               continue
+       block = data[u][2]
+       (start, end) = blocks[block]
+
+       if start != last + 1:
+               if start - last <= 33:
+                       print_block ("FILLER", last+1, start-1, data)
+                       last = start-1
+               else:
+                       if last >= 0:
+                               print
+                               print "};"
+                               print
+                       print "static const INDIC_TABLE_ELEMENT_TYPE indic_table_0x%04x[] =" % start
+                       print "{",
+                       tables.append (start)
+
+       print_block (block, start, end, data)
+       last = end
+print
+print "};"
+print
+
+print
+print "static INDIC_TABLE_ELEMENT_TYPE"
+print "get_indic_categories (hb_codepoint_t u)"
+print "{"
+for u in tables:
+       t = "indic_table_0x%04x" % u
+       print "  if (0x%04X <= u && u <= 0x%04X + ARRAY_LENGTH (%s)) return %s[u - 0x%04X];" % (u, u, t, t, u)
+for u,d in singles.items ():
+       print "  if (unlikely (u == 0x%04X)) return _(%s,%s);" % (u, short[0][d[0]], short[1][d[1]])
+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
+print "/* == End of generated table == */"
index 1b5b231..4e7170c 100644 (file)
@@ -152,7 +152,7 @@ static const struct arabic_state_table_entry {
 
 
 void
-_hb_ot_shape_complex_collect_features_arabic   (hb_ot_shape_planner_t *planner, const hb_segment_properties_t  *props)
+_hb_ot_shape_complex_collect_features_arabic (hb_ot_shape_planner_t *planner, const hb_segment_properties_t  *props)
 {
   /* ArabicOT spec enables 'cswh' for Arabic where as for basic shaper it's disabled by default. */
   planner->map.add_bool_feature (HB_TAG('c','s','w','h'));
@@ -163,7 +163,7 @@ _hb_ot_shape_complex_collect_features_arabic        (hb_ot_shape_planner_t *planner, co
 }
 
 void
-_hb_ot_shape_complex_setup_masks_arabic        (hb_ot_shape_context_t *c)
+_hb_ot_shape_complex_setup_masks_arabic (hb_ot_shape_context_t *c)
 {
   unsigned int count = c->buffer->len;
   unsigned int prev = 0, state = 0;
diff --git a/src/hb-ot-shape-complex-indic-table.hh b/src/hb-ot-shape-complex-indic-table.hh
new file mode 100644 (file)
index 0000000..2d0d32b
--- /dev/null
@@ -0,0 +1,834 @@
+/*
+ * Copyright © 2011  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_INDIC_TABLE_HH
+#define HB_OT_SHAPE_COMPLEX_INDIC_TABLE_HH
+
+#include "hb-private.hh"
+
+HB_BEGIN_DECLS
+
+/* == Start of generated table == */
+/*
+ * The following table is generated by running:
+ *
+ *   ./gen-indic-table.py IndicSyllabicCategory.txt IndicMatraCategory.txt Blocks.txt
+ *
+ * on files with these headers:
+ *
+ * # IndicSyllabicCategory-6.0.0.txt
+ * # Date: 2010-05-25, 11:45:00 PDT [KW]
+ * # IndicMatraCategory-6.0.0.txt
+ * # Date: 2010-07-14, 15:03:00 PDT [KW]
+ * # Blocks-6.0.0.txt
+ * # Date: 2010-06-04, 11:12:00 PDT [KW]
+ */
+
+
+#define ISC_A  INDIC_SYLLABIC_CATEGORY_AVAGRAHA                /*   9 chars; Avagraha */
+#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU                   /*  31 chars; Bindu */
+#define ISC_C  INDIC_SYLLABIC_CATEGORY_CONSONANT               /* 116 chars; Consonant */
+#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD          /*   2 chars; Consonant_Dead */
+#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL         /*  16 chars; Consonant_Final */
+#define ISC_CHL        INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER   /*   1 chars; Consonant_Head_Letter */
+#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL        /*  12 chars; Consonant_Medial */
+#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER   /*   4 chars; Consonant_Placeholder */
+#define ISC_CR INDIC_SYLLABIC_CATEGORY_CONSONANT_REPHA         /*   5 chars; Consonant_Repha */
+#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED     /*   9 chars; Consonant_Subjoined */
+#define ISC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER        /*   1 chars; Modifying_Letter */
+#define ISC_N  INDIC_SYLLABIC_CATEGORY_NUKTA                   /*  11 chars; Nukta */
+#define ISC_X  INDIC_SYLLABIC_CATEGORY_OTHER                   /*   1 chars; Other */
+#define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER        /*   1 chars; Register_Shifter */
+#define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER             /*   3 chars; Tone_Letter */
+#define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK               /*  16 chars; Tone_Mark */
+#define ISC_V  INDIC_SYLLABIC_CATEGORY_VIRAMA                  /*  29 chars; Virama */
+#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA                 /*  19 chars; Visarga */
+#define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL                   /*   5 chars; Vowel */
+#define ISC_VD INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT         /* 161 chars; Vowel_Dependent */
+#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT       /*  53 chars; Vowel_Independent */
+
+#define IMC_B  INDIC_MATRA_CATEGORY_BOTTOM                     /*  60 chars; Bottom */
+#define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT           /*   2 chars; Bottom_And_Right */
+#define IMC_I  INDIC_MATRA_CATEGORY_INVISIBLE                  /*   4 chars; Invisible */
+#define IMC_L  INDIC_MATRA_CATEGORY_LEFT                       /*  25 chars; Left */
+#define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT             /*   8 chars; Left_And_Right */
+#define IMC_X  INDIC_MATRA_CATEGORY_NOT_APPLICABLE             /*   1 chars; Not_Applicable */
+#define IMC_O  INDIC_MATRA_CATEGORY_OVERSTRUCK                 /*   2 chars; Overstruck */
+#define IMC_R  INDIC_MATRA_CATEGORY_RIGHT                      /*  70 chars; Right */
+#define IMC_T  INDIC_MATRA_CATEGORY_TOP                        /*  74 chars; Top */
+#define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM             /*   5 chars; Top_And_Bottom */
+#define IMC_TBR        INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT   /*   1 chars; Top_And_Bottom_And_Right */
+#define IMC_TL INDIC_MATRA_CATEGORY_TOP_AND_LEFT               /*   4 chars; Top_And_Left */
+#define IMC_TLR        INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT     /*   2 chars; Top_And_Left_And_Right */
+#define IMC_TR INDIC_MATRA_CATEGORY_TOP_AND_RIGHT              /*   7 chars; Top_And_Right */
+#define IMC_VOL        INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT          /*   5 chars; Visual_Order_Left */
+
+#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)
+
+
+static const INDIC_TABLE_ELEMENT_TYPE indic_table_0x0900[] =
+{
+
+  /* Devanagari  (0900..097F) */
+
+  /* 0900 */   _(Bi,X),   _(Bi,X),   _(Bi,X),   _(Vs,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 0908 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 0910 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0918 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0920 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0928 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0930 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0938 */    _(C,X),    _(C,X),   _(VD,T),   _(VD,R),    _(N,X),    _(A,X),   _(VD,R),   _(VD,L),
+  /* 0940 */   _(VD,R),   _(VD,B),   _(VD,B),   _(VD,B),   _(VD,B),   _(VD,T),   _(VD,T),   _(VD,T),
+  /* 0948 */   _(VD,T),   _(VD,R),   _(VD,R),   _(VD,R),   _(VD,R),    _(V,B),   _(VD,L),   _(VD,R),
+  /* 0950 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),   _(VD,T),   _(VD,B),   _(VD,B),
+  /* 0958 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0960 */   _(VI,X),   _(VI,X),   _(VD,B),   _(VD,B),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0968 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0970 */    _(X,X),    _(X,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 0978 */    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+
+  /* Bengali  (0980..09FF) */
+
+  /* 0980 */    _(X,X),   _(Bi,X),   _(Bi,X),   _(Vs,X),    _(X,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 0988 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),    _(X,X),    _(X,X),   _(VI,X),
+  /* 0990 */   _(VI,X),    _(X,X),    _(X,X),   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0998 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 09A0 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 09A8 */    _(C,X),    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 09B0 */    _(C,X),    _(X,X),    _(C,X),    _(X,X),    _(X,X),    _(X,X),    _(C,X),    _(C,X),
+  /* 09B8 */    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(N,X),    _(A,X),   _(VD,R),   _(VD,L),
+  /* 09C0 */   _(VD,R),   _(VD,B),   _(VD,B),   _(VD,B),   _(VD,B),    _(X,X),    _(X,X),   _(VD,L),
+  /* 09C8 */   _(VD,L),    _(X,X),    _(X,X),  _(VD,LR),  _(VD,LR),    _(V,B),   _(CD,X),    _(X,X),
+  /* 09D0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),   _(VD,R),
+  /* 09D8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(C,X),    _(C,X),    _(X,X),    _(C,X),
+  /* 09E0 */   _(VI,X),   _(VI,X),   _(VD,B),   _(VD,B),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 09E8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 09F0 */    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 09F8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Gurmukhi  (0A00..0A7F) */
+
+  /* 0A00 */    _(X,X),   _(Bi,X),   _(Bi,X),   _(Vs,X),    _(X,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 0A08 */   _(VI,X),   _(VI,X),   _(VI,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),   _(VI,X),
+  /* 0A10 */   _(VI,X),    _(X,X),    _(X,X),   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0A18 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0A20 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0A28 */    _(C,X),    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0A30 */    _(C,X),    _(X,X),    _(C,X),    _(C,X),    _(X,X),    _(C,X),    _(C,X),    _(X,X),
+  /* 0A38 */    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(N,X),    _(X,X),   _(VD,R),   _(VD,L),
+  /* 0A40 */   _(VD,R),   _(VD,B),   _(VD,B),    _(X,X),    _(X,X),    _(X,X),    _(X,X),   _(VD,T),
+  /* 0A48 */   _(VD,T),    _(X,X),    _(X,X),   _(VD,T),   _(VD,T),    _(V,B),    _(X,X),    _(X,X),
+  /* 0A50 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0A58 */    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(X,X),    _(C,X),    _(X,X),
+  /* 0A60 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0A68 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0A70 */   _(Bi,X),    _(X,X),   _(CP,X),   _(CP,X),    _(X,X),   _(CM,X),    _(X,X),    _(X,X),
+  /* 0A78 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Gujarati  (0A80..0AFF) */
+
+  /* 0A80 */    _(X,X),   _(Bi,X),   _(Bi,X),   _(Vs,X),    _(X,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 0A88 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),    _(X,X),   _(VI,X),
+  /* 0A90 */   _(VI,X),   _(VI,X),    _(X,X),   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0A98 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0AA0 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0AA8 */    _(C,X),    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0AB0 */    _(C,X),    _(X,X),    _(C,X),    _(C,X),    _(X,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0AB8 */    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(N,X),    _(A,X),   _(VD,R),   _(VD,L),
+  /* 0AC0 */   _(VD,R),   _(VD,B),   _(VD,B),   _(VD,B),   _(VD,B),   _(VD,T),    _(X,X),   _(VD,T),
+  /* 0AC8 */   _(VD,T),  _(VD,TR),    _(X,X),   _(VD,R),   _(VD,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),   _(VD,B),   _(VD,B),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0AE8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0AF0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0AF8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Oriya  (0B00..0B7F) */
+
+  /* 0B00 */    _(X,X),   _(Bi,X),   _(Bi,X),   _(Vs,X),    _(X,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 0B08 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),    _(X,X),    _(X,X),   _(VI,X),
+  /* 0B10 */   _(VI,X),    _(X,X),    _(X,X),   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0B18 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0B20 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0B28 */    _(C,X),    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0B30 */    _(C,X),    _(X,X),    _(C,X),    _(C,X),    _(X,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0B38 */    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(N,X),    _(A,X),   _(VD,R),   _(VD,T),
+  /* 0B40 */   _(VD,R),   _(VD,B),   _(VD,B),   _(VD,B),   _(VD,B),    _(X,X),    _(X,X),   _(VD,L),
+  /* 0B48 */  _(VD,TL),    _(X,X),    _(X,X),  _(VD,LR), _(VD,TLR),    _(V,B),    _(X,X),    _(X,X),
+  /* 0B50 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),   _(VD,T),  _(VD,TR),
+  /* 0B58 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(C,X),    _(C,X),    _(X,X),    _(C,X),
+  /* 0B60 */   _(VI,X),   _(VI,X),   _(VD,B),   _(VD,B),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0B68 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0B70 */    _(X,X),    _(C,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0B78 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Tamil  (0B80..0BFF) */
+
+  /* 0B80 */    _(X,X),    _(X,X),   _(Bi,X),   _(ML,X),    _(X,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 0B88 */   _(VI,X),   _(VI,X),   _(VI,X),    _(X,X),    _(X,X),    _(X,X),   _(VI,X),   _(VI,X),
+  /* 0B90 */   _(VI,X),    _(X,X),   _(VI,X),   _(VI,X),   _(VI,X),    _(C,X),    _(X,X),    _(X,X),
+  /* 0B98 */    _(X,X),    _(C,X),    _(C,X),    _(X,X),    _(C,X),    _(X,X),    _(C,X),    _(C,X),
+  /* 0BA0 */    _(X,X),    _(X,X),    _(X,X),    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0BA8 */    _(C,X),    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(X,X),    _(C,X),    _(C,X),
+  /* 0BB0 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0BB8 */    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),   _(VD,R),   _(VD,R),
+  /* 0BC0 */   _(VD,T),   _(VD,B),   _(VD,B),    _(X,X),    _(X,X),    _(X,X),   _(VD,L),   _(VD,L),
+  /* 0BC8 */   _(VD,L),    _(X,X),  _(VD,LR),  _(VD,LR),  _(VD,LR),    _(V,T),    _(X,X),    _(X,X),
+  /* 0BD0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),   _(VD,R),
+  /* 0BD8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0BE0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0BE8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0BF0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0BF8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Telugu  (0C00..0C7F) */
+
+  /* 0C00 */    _(X,X),   _(Bi,X),   _(Bi,X),   _(Vs,X),    _(X,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 0C08 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),    _(X,X),   _(VI,X),   _(VI,X),
+  /* 0C10 */   _(VI,X),    _(X,X),   _(VI,X),   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0C18 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0C20 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0C28 */    _(C,X),    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0C30 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(X,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0C38 */    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(X,X),    _(A,X),   _(VD,T),   _(VD,T),
+  /* 0C40 */   _(VD,T),   _(VD,R),   _(VD,R),   _(VD,R),   _(VD,R),    _(X,X),   _(VD,T),   _(VD,T),
+  /* 0C48 */  _(VD,TB),    _(X,X),   _(VD,T),   _(VD,T),   _(VD,T),    _(V,T),    _(X,X),    _(X,X),
+  /* 0C50 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),   _(VD,T),   _(VD,B),    _(X,X),
+  /* 0C58 */    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0C60 */   _(VI,X),   _(VI,X),   _(VD,B),   _(VD,B),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0C68 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0C70 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0C78 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Kannada  (0C80..0CFF) */
+
+  /* 0C80 */    _(X,X),    _(X,X),   _(Bi,X),   _(Vs,X),    _(X,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 0C88 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),    _(X,X),   _(VI,X),   _(VI,X),
+  /* 0C90 */   _(VI,X),    _(X,X),   _(VI,X),   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0C98 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0CA0 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0CA8 */    _(C,X),    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0CB0 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(X,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0CB8 */    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(N,X),    _(A,X),   _(VD,R),   _(VD,T),
+  /* 0CC0 */  _(VD,TR),   _(VD,R),   _(VD,R),   _(VD,R),   _(VD,R),    _(X,X),   _(VD,T),  _(VD,TR),
+  /* 0CC8 */  _(VD,TR),    _(X,X),  _(VD,TR),  _(VD,TR),   _(VD,T),    _(V,T),    _(X,X),    _(X,X),
+  /* 0CD0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),   _(VD,R),   _(VD,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),   _(VD,B),   _(VD,B),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0CE8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0CF0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0CF8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Malayalam  (0D00..0D7F) */
+
+  /* 0D00 */    _(X,X),    _(X,X),   _(Bi,X),   _(Vs,X),    _(X,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 0D08 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),    _(X,X),   _(VI,X),   _(VI,X),
+  /* 0D10 */   _(VI,X),    _(X,X),   _(VI,X),   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0D18 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0D20 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0D28 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0D30 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0D38 */    _(C,X),    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(A,X),   _(VD,R),   _(VD,R),
+  /* 0D40 */   _(VD,R),   _(VD,R),   _(VD,R),   _(VD,B),   _(VD,B),    _(X,X),   _(VD,L),   _(VD,L),
+  /* 0D48 */   _(VD,L),    _(X,X),  _(VD,LR),  _(VD,LR),  _(VD,LR),    _(V,T),   _(CR,X),    _(X,X),
+  /* 0D50 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),   _(VD,R),
+  /* 0D58 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0D60 */   _(VI,X),   _(VI,X),   _(VD,B),   _(VD,B),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0D68 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0D70 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0D78 */    _(X,X),    _(X,X),   _(CD,X),   _(CD,X),   _(CD,X),   _(CD,X),   _(CD,X),   _(CD,X),
+
+  /* Sinhala  (0D80..0DFF) */
+
+  /* 0D80 */    _(X,X),    _(X,X),   _(Bi,X),   _(Vs,X),    _(X,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 0D88 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 0D90 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),    _(X,X),
+  /* 0D98 */    _(X,X),    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0DA0 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0DA8 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0DB0 */    _(C,X),    _(C,X),    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0DB8 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(X,X),    _(C,X),    _(X,X),    _(X,X),
+  /* 0DC0 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(X,X),
+  /* 0DC8 */    _(X,X),    _(X,X),    _(V,T),    _(X,X),    _(X,X),    _(X,X),    _(X,X),   _(VD,R),
+  /* 0DD0 */   _(VD,R),   _(VD,R),   _(VD,T),   _(VD,T),   _(VD,B),    _(X,X),   _(VD,B),    _(X,X),
+  /* 0DD8 */   _(VD,R),   _(VD,L),  _(VD,TL),   _(VD,L),  _(VD,LR),  _(VD,LR),  _(VD,LR),   _(VD,R),
+  /* 0DE0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0DE8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0DF0 */    _(X,X),    _(X,X),   _(VD,R),   _(VD,R),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0DF8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Thai  (0E00..0E7F) */
+
+  /* 0E00 */    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0E08 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0E10 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0E18 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0E20 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0E28 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(X,X),
+  /* 0E30 */   _(VD,R),   _(VD,T),   _(VD,R),   _(VD,R),   _(VD,T),   _(VD,T),   _(VD,T),   _(VD,T),
+  /* 0E38 */   _(VD,B),   _(VD,B),    _(V,B),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0E40 */ _(VD,VOL), _(VD,VOL), _(VD,VOL), _(VD,VOL), _(VD,VOL),   _(VD,R),    _(X,X),   _(VD,T),
+  /* 0E48 */   _(TM,X),   _(TM,X),   _(TM,X),   _(TM,X),    _(X,X),   _(Bi,X),    _(V,T),    _(X,X),
+  /* 0E50 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0E58 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0E60 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0E68 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0E70 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0E78 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Lao  (0E80..0EFF) */
+
+  /* 0E80 */    _(X,X),    _(C,X),    _(C,X),    _(X,X),    _(C,X),    _(X,X),    _(X,X),    _(C,X),
+  /* 0E88 */    _(C,X),    _(X,X),    _(C,X),    _(X,X),    _(X,X),    _(C,X),    _(X,X),    _(X,X),
+  /* 0E90 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0E98 */    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0EA0 */    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(X,X),    _(C,X),    _(X,X),    _(C,X),
+  /* 0EA8 */    _(X,X),    _(X,X),    _(C,X),    _(C,X),    _(X,X),    _(C,X),    _(C,X),    _(X,X),
+  /* 0EB0 */   _(VD,R),   _(VD,T),   _(VD,R),   _(VD,R),   _(VD,T),   _(VD,T),   _(VD,T),   _(VD,T),
+  /* 0EB8 */   _(VD,B),   _(VD,B),    _(X,X),   _(VD,T),   _(CM,X),   _(CM,X),    _(X,X),    _(X,X),
+  /* 0EC0 */ _(VD,VOL), _(VD,VOL), _(VD,VOL), _(VD,VOL), _(VD,VOL),    _(X,X),    _(X,X),    _(X,X),
+  /* 0EC8 */   _(TM,X),   _(TM,X),   _(TM,X),   _(TM,X),    _(X,X),   _(Bi,X),    _(X,X),    _(X,X),
+  /* 0ED0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0ED8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(C,X),    _(C,X),    _(X,X),    _(X,X),
+  /* 0EE0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0EE8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0EF0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0EF8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Tibetan  (0F00..0FFF) */
+
+  /* 0F00 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0F08 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0F10 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0F18 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0F20 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0F28 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0F30 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0F38 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0F40 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0F48 */    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0F50 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0F58 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0F60 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 0F68 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0F70 */    _(X,X),   _(VD,B),   _(VD,T),  _(VD,TB),   _(VD,B),   _(VD,B),  _(VD,TB),  _(VD,TB),
+  /* 0F78 */  _(VD,TB),  _(VD,TB),   _(VD,T),   _(VD,T),   _(VD,T),   _(VD,T),   _(Bi,X),   _(Vs,X),
+  /* 0F80 */   _(VD,T),  _(VD,TB),   _(Bi,X),   _(Bi,X),    _(V,B),    _(A,X),    _(X,X),    _(X,X),
+  /* 0F88 */  _(CHL,X),  _(CHL,X),  _(CHL,X),  _(CHL,X),  _(CHL,X),   _(CS,X),   _(CS,X),   _(CS,X),
+  /* 0F90 */   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),
+  /* 0F98 */    _(X,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),
+  /* 0FA0 */   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),
+  /* 0FA8 */   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),
+  /* 0FB0 */   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),
+  /* 0FB8 */   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(CS,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0FC0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0FC8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0FD0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0FD8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0FE0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0FE8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0FF0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 0FF8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Myanmar  (1000..109F) */
+
+  /* 1000 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1008 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1010 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1018 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1020 */    _(C,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 1028 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VD,R),   _(VD,R),   _(VD,T),   _(VD,T),   _(VD,B),
+  /* 1030 */   _(VD,B),   _(VD,L),   _(VD,T),   _(VD,T),   _(VD,T),   _(VD,T),   _(Bi,X),   _(TM,X),
+  /* 1038 */   _(Vs,X),    _(V,I),    _(V,T),   _(CM,X),   _(CM,X),   _(CM,X),   _(CM,X),    _(C,X),
+  /* 1040 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1048 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1050 */    _(C,X),    _(C,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VD,R),   _(VD,R),
+  /* 1058 */   _(VD,B),   _(VD,B),    _(C,X),    _(C,X),    _(C,X),    _(C,X),   _(CM,X),   _(CM,X),
+  /* 1060 */   _(CM,X),    _(C,X),   _(VD,R),   _(TM,X),   _(TM,X),    _(C,X),    _(C,X),   _(VD,R),
+  /* 1068 */   _(VD,R),   _(TM,X),   _(TM,X),   _(TM,X),   _(TM,X),   _(TM,X),    _(C,X),    _(C,X),
+  /* 1070 */    _(C,X),   _(VD,T),   _(VD,T),   _(VD,T),   _(VD,T),    _(C,X),    _(C,X),    _(C,X),
+  /* 1078 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1080 */    _(C,X),    _(C,X),   _(CM,X),   _(VD,R),   _(VD,L),   _(VD,T),   _(VD,T),   _(TM,X),
+  /* 1088 */   _(TM,X),   _(TM,X),   _(TM,X),   _(TM,X),   _(TM,X),   _(TM,X),    _(C,X),   _(TM,X),
+  /* 1090 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1098 */    _(X,X),    _(X,X),   _(TM,X),   _(TM,X),   _(VD,R),   _(VD,T),    _(X,X),    _(X,X),
+};
+
+static const INDIC_TABLE_ELEMENT_TYPE indic_table_0x1700[] =
+{
+
+  /* Tagalog  (1700..171F) */
+
+  /* 1700 */   _(VI,X),   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1708 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(X,X),    _(C,X),    _(C,X),
+  /* 1710 */    _(C,X),    _(C,X),   _(VD,T),   _(VD,B),    _(V,B),    _(X,X),    _(X,X),    _(X,X),
+  /* 1718 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Hanunoo  (1720..173F) */
+
+  /* 1720 */   _(VI,X),   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1728 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1730 */    _(C,X),    _(C,X),   _(VD,T),   _(VD,B),    _(V,B),    _(X,X),    _(X,X),    _(X,X),
+  /* 1738 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Buhid  (1740..175F) */
+
+  /* 1740 */   _(VI,X),   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1748 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1750 */    _(C,X),    _(C,X),   _(VD,T),   _(VD,B),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1758 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Tagbanwa  (1760..177F) */
+
+  /* 1760 */   _(VI,X),   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1768 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(X,X),    _(C,X),    _(C,X),
+  /* 1770 */    _(C,X),    _(X,X),   _(VD,T),   _(VD,B),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1778 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Khmer  (1780..17FF) */
+
+  /* 1780 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1788 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1790 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1798 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 17A0 */    _(C,X),    _(C,X),    _(C,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 17A8 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 17B0 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),    _(X,X),    _(X,X),   _(VD,R),   _(VD,T),
+  /* 17B8 */   _(VD,T),   _(VD,T),   _(VD,T),   _(VD,B),   _(VD,B),   _(VD,B),  _(VD,TL), _(VD,TLR),
+  /* 17C0 */  _(VD,LR),   _(VD,L),   _(VD,L),   _(VD,L),  _(VD,LR),  _(VD,LR),   _(Bi,X),   _(Vs,X),
+  /* 17C8 */   _(VD,R),   _(RS,X),   _(RS,X),    _(X,X),   _(CR,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 17D0 */    _(X,X),    _(V,T),    _(V,I),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 17D8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(A,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 17E0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 17E8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 17F0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 17F8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+};
+
+static const INDIC_TABLE_ELEMENT_TYPE indic_table_0x1900[] =
+{
+
+  /* Limbu  (1900..194F) */
+
+  /* 1900 */   _(CP,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1908 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1910 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1918 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1920 */   _(VD,T),   _(VD,T),   _(VD,B),   _(VD,R),   _(VD,R),  _(VD,TR),  _(VD,TR),   _(VD,T),
+  /* 1928 */   _(VD,T),   _(CS,X),   _(CS,X),   _(CS,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1930 */   _(CF,X),   _(CF,X),   _(Bi,X),   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),
+  /* 1938 */   _(CF,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1940 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1948 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Tai Le  (1950..197F) */
+
+  /* 1950 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1958 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1960 */    _(C,X),    _(C,X),    _(C,X),   _(Vo,X),   _(Vo,X),   _(Vo,X),   _(Vo,X),   _(Vo,X),
+  /* 1968 */   _(Vo,X),   _(Vo,X),   _(Vo,X),   _(Vo,X),   _(Vo,X),   _(Vo,X),    _(X,X),    _(X,X),
+  /* 1970 */   _(TL,X),   _(TL,X),   _(TL,X),   _(TL,X),   _(TL,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1978 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* New Tai Lue  (1980..19DF) */
+
+  /* 1980 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1988 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1990 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1998 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 19A0 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 19A8 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 19B0 */   _(VD,R),   _(VD,R),   _(VD,R),   _(VD,R),   _(VD,R),   _(VD,L),   _(VD,L),   _(VD,L),
+  /* 19B8 */   _(VD,R),   _(VD,R),   _(VD,L),   _(VD,R),   _(VD,R),   _(VD,R),   _(VD,R),   _(VD,R),
+  /* 19C0 */   _(VD,R),   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),
+  /* 19C8 */   _(TM,X),   _(TM,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 19D0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 19D8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* FILLER  (19E0..19FF) */
+
+  /* 19E0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 19E8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 19F0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 19F8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Buginese  (1A00..1A1F) */
+
+  /* 1A00 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1A08 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1A10 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),   _(VD,T),
+  /* 1A18 */   _(VD,B),   _(VD,L),   _(VD,R),   _(VD,L),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Tai Tham  (1A20..1AAF) */
+
+  /* 1A20 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1A28 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1A30 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1A38 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1A40 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1A48 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 1A50 */   _(VI,X),   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),   _(CM,X),   _(CM,X),   _(CF,X),
+  /* 1A58 */   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),    _(X,X),
+  /* 1A60 */    _(V,I),   _(VD,R),   _(VD,T),   _(VD,R),   _(VD,R),   _(VD,T),   _(VD,T),   _(VD,T),
+  /* 1A68 */   _(VD,T),   _(VD,B),   _(VD,B),   _(VD,T),   _(VD,B),   _(VD,R),   _(VD,L),   _(VD,L),
+  /* 1A70 */   _(VD,L),   _(VD,L),   _(VD,L),   _(VD,T),   _(VD,T),   _(TM,X),   _(TM,X),   _(TM,X),
+  /* 1A78 */   _(TM,X),   _(TM,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1A80 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1A88 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1A90 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1A98 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1AA0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1AA8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+};
+
+static const INDIC_TABLE_ELEMENT_TYPE indic_table_0x1b00[] =
+{
+
+  /* Balinese  (1B00..1B7F) */
+
+  /* 1B00 */   _(Bi,X),   _(Bi,X),   _(Bi,X),   _(CR,X),   _(Vs,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 1B08 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 1B10 */   _(VI,X),   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1B18 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1B20 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1B28 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1B30 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(N,X),   _(VD,R),   _(VD,T),   _(VD,T),
+  /* 1B38 */   _(VD,B),   _(VD,B),   _(VD,B),  _(VD,BR),  _(VD,TB), _(VD,TBR),   _(VD,L),   _(VD,L),
+  /* 1B40 */  _(VD,LR),  _(VD,LR),   _(VD,T),  _(VD,TR),    _(V,R),    _(C,X),    _(C,X),    _(C,X),
+  /* 1B48 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1B50 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1B58 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1B60 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1B68 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1B70 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1B78 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Sundanese  (1B80..1BBF) */
+
+  /* 1B80 */   _(Bi,X),   _(CR,X),   _(Vs,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 1B88 */   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1B90 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1B98 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1BA0 */    _(C,X),   _(CS,X),   _(CS,X),   _(CS,X),   _(VD,T),   _(VD,B),   _(VD,L),   _(VD,R),
+  /* 1BA8 */   _(VD,T),   _(VD,T),    _(V,R),    _(X,X),    _(X,X),    _(X,X),    _(C,X),    _(C,X),
+  /* 1BB0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1BB8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Batak  (1BC0..1BFF) */
+
+  /* 1BC0 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1BC8 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1BD0 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1BD8 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1BE0 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),   _(VI,X),   _(VI,X),    _(N,X),   _(VD,X),
+  /* 1BE8 */   _(VD,X),   _(VD,X),   _(VD,X),   _(VD,X),   _(VD,X),   _(VD,X),   _(VD,X),   _(VD,X),
+  /* 1BF0 */   _(CF,X),   _(CF,X),    _(V,R),    _(V,R),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1BF8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Lepcha  (1C00..1C4F) */
+
+  /* 1C00 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1C08 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1C10 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1C18 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 1C20 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),   _(CS,X),   _(CS,X),   _(VD,R),   _(VD,L),
+  /* 1C28 */   _(VD,L),  _(VD,TL),   _(VD,R),   _(VD,R),   _(VD,B),   _(CF,X),   _(CF,X),   _(CF,X),
+  /* 1C30 */   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),   _(Bi,X),   _(Bi,X),    _(X,X),    _(N,X),
+  /* 1C38 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1C40 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 1C48 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(C,X),    _(C,X),    _(C,X),
+};
+
+static const INDIC_TABLE_ELEMENT_TYPE indic_table_0xa800[] =
+{
+
+  /* Syloti Nagri  (A800..A82F) */
+
+  /* A800 */   _(VI,X),   _(VI,X),    _(X,X),   _(VI,X),   _(VI,X),   _(VI,X),    _(V,T),    _(C,X),
+  /* A808 */    _(C,X),    _(C,X),    _(C,X),   _(Bi,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A810 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A818 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A820 */    _(C,X),    _(C,X),    _(C,X),   _(VD,R),   _(VD,R),   _(VD,B),   _(VD,T),   _(VD,R),
+  /* A828 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* FILLER  (A830..A83F) */
+
+  /* A830 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A838 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Phags-pa  (A840..A87F) */
+
+  /* A840 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A848 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A850 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A858 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),   _(Vo,X),   _(Vo,X),
+  /* A860 */   _(Vo,X),   _(Vo,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),   _(Vo,X),   _(CS,X),
+  /* A868 */   _(CS,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A870 */    _(C,X),   _(CS,X),    _(C,X),   _(Bi,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A878 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Saurashtra  (A880..A8DF) */
+
+  /* A880 */   _(Bi,X),   _(Vs,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* A888 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* A890 */   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A898 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A8A0 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A8A8 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A8B0 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),   _(CF,X),   _(VD,R),   _(VD,R),   _(VD,R),
+  /* A8B8 */   _(VD,R),   _(VD,R),   _(VD,R),   _(VD,R),   _(VD,R),   _(VD,R),   _(VD,R),   _(VD,R),
+  /* A8C0 */   _(VD,R),   _(VD,R),   _(VD,R),   _(VD,R),    _(V,B),    _(X,X),    _(X,X),    _(X,X),
+  /* A8C8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A8D0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A8D8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* FILLER  (A8E0..A8FF) */
+
+  /* A8E0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A8E8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A8F0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A8F8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Kayah Li  (A900..A92F) */
+
+  /* A900 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A908 */    _(X,X),    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A910 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A918 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A920 */    _(C,X),    _(C,X),   _(Vo,X),   _(Vo,X),   _(Vo,X),   _(Vo,X),   _(Vo,X),   _(Vo,X),
+  /* A928 */   _(Vo,X),   _(Vo,X),   _(Vo,X),   _(TM,X),   _(TM,X),   _(TM,X),    _(X,X),    _(X,X),
+
+  /* Rejang  (A930..A95F) */
+
+  /* A930 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A938 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A940 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),   _(VD,B),
+  /* A948 */   _(VD,B),   _(VD,B),   _(VD,T),   _(VD,B),   _(VD,B),   _(VD,B),   _(VD,B),   _(CF,X),
+  /* A950 */   _(CF,X),   _(CF,X),   _(CF,X),    _(V,R),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A958 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* FILLER  (A960..A97F) */
+
+  /* A960 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A968 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A970 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A978 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Javanese  (A980..A9DF) */
+
+  /* A980 */   _(Bi,X),   _(Bi,X),   _(CR,X),   _(Vs,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* A988 */   _(VI,X),    _(C,X),    _(C,X),    _(C,X),   _(VI,X),   _(VI,X),   _(VI,X),    _(C,X),
+  /* A990 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A998 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A9A0 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A9A8 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* A9B0 */    _(C,X),    _(C,X),    _(C,X),    _(N,X),   _(VD,R),   _(VD,R),   _(VD,T),   _(VD,T),
+  /* A9B8 */   _(VD,B),   _(VD,B),   _(VD,L),   _(VD,L),   _(VD,T),   _(CS,X),   _(CM,X),   _(CM,X),
+  /* A9C0 */   _(V,BR),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A9C8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A9D0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A9D8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* FILLER  (A9E0..A9FF) */
+
+  /* A9E0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A9E8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A9F0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* A9F8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Cham  (AA00..AA5F) */
+
+  /* AA00 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),
+  /* AA08 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* AA10 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* AA18 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* AA20 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* AA28 */    _(C,X),   _(VD,T),   _(VD,T),   _(VD,T),   _(VD,T),   _(VD,B),   _(VD,T),   _(VD,L),
+  /* AA30 */   _(VD,L),   _(VD,T),   _(VD,B),   _(CM,X),   _(CM,X),   _(CM,X),   _(CM,X),    _(X,X),
+  /* AA38 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* AA40 */   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),
+  /* AA48 */   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),   _(CF,X),    _(X,X),    _(X,X),
+  /* AA50 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* AA58 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Myanmar Extended-A  (AA60..AA7F) */
+
+  /* AA60 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* AA68 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* AA70 */    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* AA78 */    _(X,X),    _(X,X),    _(C,X),   _(TM,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Tai Viet  (AA80..AADF) */
+
+  /* AA80 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* AA88 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* AA90 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* AA98 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* AAA0 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* AAA8 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* AAB0 */   _(VD,T),   _(VD,R),   _(VD,T),   _(VD,T),   _(VD,B), _(VD,VOL), _(VD,VOL),   _(VD,T),
+  /* AAB8 */   _(VD,T), _(VD,VOL),   _(VD,R), _(VD,VOL), _(VD,VOL),   _(VD,R),   _(VD,T),   _(TM,X),
+  /* AAC0 */   _(TL,X),   _(TM,X),   _(TL,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* AAC8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* AAD0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* AAD8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+};
+
+static const INDIC_TABLE_ELEMENT_TYPE indic_table_0xabc0[] =
+{
+
+  /* Meetei Mayek  (ABC0..ABFF) */
+
+  /* ABC0 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* ABC8 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* ABD0 */    _(C,X),    _(C,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),   _(VD,R),   _(VD,R),   _(VD,T),   _(VD,R),   _(VD,R),
+  /* ABE8 */   _(VD,B),   _(VD,R),   _(VD,R),    _(X,X),   _(TM,X),    _(V,B),    _(X,X),    _(X,X),
+  /* ABF0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* ABF8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+};
+
+static const INDIC_TABLE_ELEMENT_TYPE indic_table_0x10a00[] =
+{
+
+  /* Kharoshthi  (10A00..10A5F) */
+
+  /* 10A00 */    _(C,X),   _(VD,O),   _(VD,B),   _(VD,B),    _(X,X),   _(VD,T),   _(VD,O),    _(X,X),
+  /* 10A08 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),   _(VD,B),    _(X,X),   _(Bi,X),   _(Vs,X),
+  /* 10A10 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(X,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 10A18 */    _(X,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 10A20 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 10A28 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 10A30 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 10A38 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(V,I),
+  /* 10A40 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 10A48 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 10A50 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 10A58 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+};
+
+static const INDIC_TABLE_ELEMENT_TYPE indic_table_0x11000[] =
+{
+
+  /* Brahmi  (11000..1107F) */
+
+  /* 11000 */   _(Bi,X),   _(Bi,X),   _(Vs,X),    _(X,X),    _(X,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 11008 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 11010 */   _(VI,X),   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 11018 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 11020 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 11028 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 11030 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 11038 */   _(VD,T),   _(VD,T),   _(VD,T),   _(VD,T),   _(VD,B),   _(VD,B),   _(VD,B),   _(VD,B),
+  /* 11040 */   _(VD,B),   _(VD,B),   _(VD,T),   _(VD,T),   _(VD,T),   _(VD,T),    _(V,T),    _(X,X),
+  /* 11048 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 11050 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 11058 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 11060 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 11068 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 11070 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 11078 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+
+  /* Kaithi  (11080..110CF) */
+
+  /* 11080 */   _(Bi,X),   _(Bi,X),   _(Vs,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),
+  /* 11088 */   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),   _(VI,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 11090 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 11098 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 110A0 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 110A8 */    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),    _(C,X),
+  /* 110B0 */   _(VD,R),   _(VD,L),   _(VD,R),   _(VD,B),   _(VD,B),   _(VD,T),   _(VD,T),   _(VD,R),
+  /* 110B8 */   _(VD,R),    _(V,B),    _(N,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 110C0 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+  /* 110C8 */    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),    _(X,X),
+};
+
+
+static INDIC_TABLE_ELEMENT_TYPE
+get_indic_categories (hb_codepoint_t u)
+{
+  if (0x0900 <= u && u <= 0x0900 + ARRAY_LENGTH (indic_table_0x0900)) return indic_table_0x0900[u - 0x0900];
+  if (0x1700 <= u && u <= 0x1700 + ARRAY_LENGTH (indic_table_0x1700)) return indic_table_0x1700[u - 0x1700];
+  if (0x1900 <= u && u <= 0x1900 + ARRAY_LENGTH (indic_table_0x1900)) return indic_table_0x1900[u - 0x1900];
+  if (0x1B00 <= u && u <= 0x1B00 + ARRAY_LENGTH (indic_table_0x1b00)) return indic_table_0x1b00[u - 0x1B00];
+  if (0xA800 <= u && u <= 0xA800 + ARRAY_LENGTH (indic_table_0xa800)) return indic_table_0xa800[u - 0xA800];
+  if (0xABC0 <= u && u <= 0xABC0 + ARRAY_LENGTH (indic_table_0xabc0)) return indic_table_0xabc0[u - 0xABC0];
+  if (0x10A00 <= u && u <= 0x10A00 + ARRAY_LENGTH (indic_table_0x10a00)) return indic_table_0x10a00[u - 0x10A00];
+  if (0x11000 <= u && u <= 0x11000 + ARRAY_LENGTH (indic_table_0x11000)) return indic_table_0x11000[u - 0x11000];
+  if (unlikely (u == 0x00A0)) return _(CP,X);
+  if (unlikely (u == 0x25CC)) return _(CP,X);
+  return _(X,X);
+}
+
+#undef _
+
+#undef ISC_A
+#undef ISC_Bi
+#undef ISC_C
+#undef ISC_CD
+#undef ISC_CF
+#undef ISC_CHL
+#undef ISC_CM
+#undef ISC_CP
+#undef ISC_CR
+#undef ISC_CS
+#undef ISC_ML
+#undef ISC_N
+#undef ISC_X
+#undef ISC_RS
+#undef ISC_TL
+#undef ISC_TM
+#undef ISC_V
+#undef ISC_Vs
+#undef ISC_Vo
+#undef ISC_VD
+#undef ISC_VI
+
+#undef IMC_B
+#undef IMC_BR
+#undef IMC_I
+#undef IMC_L
+#undef IMC_LR
+#undef IMC_X
+#undef IMC_O
+#undef IMC_R
+#undef IMC_T
+#undef IMC_TB
+#undef IMC_TBR
+#undef IMC_TL
+#undef IMC_TLR
+#undef IMC_TR
+#undef IMC_VOL
+
+
+/* == End of generated table == */
+
+HB_END_DECLS
+
+#endif /* HB_OT_SHAPE_COMPLEX_INDIC_TABLE_HH */
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
new file mode 100644 (file)
index 0000000..901c0e5
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright © 2010  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-private.hh"
+
+HB_BEGIN_DECLS
+
+
+/* buffer var allocations */
+#define indic_categories() var2.u32 /* indic shaping action */
+
+#define INDIC_TABLE_ELEMENT_TYPE uint8_t
+
+enum indic_syllabic_category_t {
+  INDIC_SYLLABIC_CATEGORY_AVAGRAHA,
+  INDIC_SYLLABIC_CATEGORY_BINDU,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT_REPHA,
+  INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED,
+  INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER,
+  INDIC_SYLLABIC_CATEGORY_NUKTA,
+  INDIC_SYLLABIC_CATEGORY_OTHER,
+  INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER,
+  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,
+};
+
+enum indic_matra_category_t {
+  INDIC_MATRA_CATEGORY_BOTTOM,
+  INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT,
+  INDIC_MATRA_CATEGORY_INVISIBLE,
+  INDIC_MATRA_CATEGORY_LEFT,
+  INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT,
+  INDIC_MATRA_CATEGORY_NOT_APPLICABLE,
+  INDIC_MATRA_CATEGORY_OVERSTRUCK,
+  INDIC_MATRA_CATEGORY_RIGHT,
+  INDIC_MATRA_CATEGORY_TOP,
+  INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM,
+  INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT,
+  INDIC_MATRA_CATEGORY_TOP_AND_LEFT,
+  INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT,
+  INDIC_MATRA_CATEGORY_TOP_AND_RIGHT,
+  INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT,
+};
+
+#define INDIC_COMBINE_CATEGORIES(S,M) (S)
+
+#include "hb-ot-shape-complex-indic-table.hh"
+
+static const hb_tag_t indic_basic_features[] =
+{
+  HB_TAG('n','u','k','t'),
+  HB_TAG('a','k','h','n'),
+  HB_TAG('r','p','h','f'),
+  HB_TAG('r','k','r','f'),
+  HB_TAG('p','r','e','f'),
+  HB_TAG('b','l','w','f'),
+  HB_TAG('h','a','l','f'),
+  HB_TAG('v','a','t','u'),
+  HB_TAG('p','s','t','f'),
+  HB_TAG('c','j','c','t'),
+};
+
+static const hb_tag_t indic_other_features[] =
+{
+  HB_TAG('p','r','e','s'),
+  HB_TAG('a','b','v','s'),
+  HB_TAG('b','l','w','s'),
+  HB_TAG('p','s','t','s'),
+  HB_TAG('h','a','l','n'),
+
+  HB_TAG('d','i','s','t'),
+  HB_TAG('a','b','v','m'),
+  HB_TAG('b','l','w','m'),
+};
+
+
+
+void
+_hb_ot_shape_complex_collect_features_indic    (hb_ot_shape_planner_t *planner, const hb_segment_properties_t  *props)
+{
+  for (unsigned int i = 0; i < ARRAY_LENGTH (indic_basic_features); i++)
+    planner->map.add_bool_feature (indic_basic_features[i], false);
+
+  for (unsigned int i = 0; i < ARRAY_LENGTH (indic_other_features); i++)
+    planner->map.add_bool_feature (indic_other_features[i], true);
+}
+
+void
+_hb_ot_shape_complex_setup_masks_indic (hb_ot_shape_context_t *c)
+{
+  unsigned int count = c->buffer->len;
+
+  for (unsigned int i = 0; i < count; i++)
+  {
+    unsigned int this_type = get_indic_categories (c->buffer->info[i].codepoint);
+
+    c->buffer->info[i].indic_categories() = this_type;
+  }
+
+  hb_mask_t mask_array[ARRAY_LENGTH (indic_basic_features)] = {0};
+  unsigned int num_masks = ARRAY_LENGTH (indic_basic_features);
+  for (unsigned int i = 0; i < num_masks; i++)
+    mask_array[i] = c->plan->map.get_1_mask (indic_basic_features[i]);
+}
+
+
+HB_END_DECLS
index f58e5da..a7a1afb 100644 (file)
@@ -40,12 +40,58 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
   switch ((int) props->script)
   {
     case HB_SCRIPT_ARABIC:
-    case HB_SCRIPT_NKO:
-    case HB_SCRIPT_SYRIAC:
     case HB_SCRIPT_MANDAIC:
     case HB_SCRIPT_MONGOLIAN:
+    case HB_SCRIPT_NKO:
+    case HB_SCRIPT_SYRIAC:
       return hb_ot_complex_shaper_arabic;
 
+    /* TODO: These are all the scripts that the ucd/IndicSyllabicCategory.txt covers.
+     * Quite possibly many of these need no shaping, and some other are encoded visually.
+     * Needs to be refined.
+     */
+    case HB_SCRIPT_BALINESE:
+    case HB_SCRIPT_BATAK:
+    case HB_SCRIPT_BENGALI:
+    case HB_SCRIPT_BRAHMI:
+    case HB_SCRIPT_BUGINESE:
+    case HB_SCRIPT_BUHID:
+    case HB_SCRIPT_CHAM:
+    case HB_SCRIPT_DEVANAGARI:
+    case HB_SCRIPT_GUJARATI:
+    case HB_SCRIPT_GURMUKHI:
+    case HB_SCRIPT_HANUNOO:
+    case HB_SCRIPT_JAVANESE:
+    case HB_SCRIPT_KAITHI:
+    case HB_SCRIPT_KANNADA:
+    case HB_SCRIPT_KAYAH_LI:
+    case HB_SCRIPT_KHAROSHTHI:
+    case HB_SCRIPT_KHMER:
+    case HB_SCRIPT_LAO:
+    case HB_SCRIPT_LEPCHA:
+    case HB_SCRIPT_LIMBU:
+    case HB_SCRIPT_MALAYALAM:
+    case HB_SCRIPT_MEETEI_MAYEK:
+    case HB_SCRIPT_MYANMAR:
+    case HB_SCRIPT_NEW_TAI_LUE:
+    case HB_SCRIPT_ORIYA:
+    case HB_SCRIPT_PHAGS_PA:
+    case HB_SCRIPT_REJANG:
+    case HB_SCRIPT_SAURASHTRA:
+    case HB_SCRIPT_SINHALA:
+    case HB_SCRIPT_SUNDANESE:
+    case HB_SCRIPT_SYLOTI_NAGRI:
+    case HB_SCRIPT_TAGALOG:
+    case HB_SCRIPT_TAGBANWA:
+    case HB_SCRIPT_TAI_LE:
+    case HB_SCRIPT_TAI_THAM:
+    case HB_SCRIPT_TAI_VIET:
+    case HB_SCRIPT_TAMIL:
+    case HB_SCRIPT_TELUGU:
+    case HB_SCRIPT_THAI:
+    case HB_SCRIPT_TIBETAN:
+      return hb_ot_complex_shaper_indic;
+
     default:
       return hb_ot_complex_shaper_none;
   }
@@ -62,14 +108,16 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
  */
 
 HB_INTERNAL void _hb_ot_shape_complex_collect_features_arabic  (hb_ot_shape_planner_t *plan, const hb_segment_properties_t  *props);
+HB_INTERNAL void _hb_ot_shape_complex_collect_features_indic   (hb_ot_shape_planner_t *plan, const hb_segment_properties_t  *props);
 
 static inline void
 hb_ot_shape_complex_collect_features (hb_ot_shape_planner_t *planner,
                                      const hb_segment_properties_t  *props)
 {
   switch (planner->shaper) {
-    case hb_ot_complex_shaper_arabic:  _hb_ot_shape_complex_collect_features_arabic (planner, props);  return;
-    case hb_ot_complex_shaper_none:    default:                                                        return;
+    case hb_ot_complex_shaper_arabic:  _hb_ot_shape_complex_collect_features_arabic    (planner, props);       return;
+    case hb_ot_complex_shaper_indic:   _hb_ot_shape_complex_collect_features_indic     (planner, props);       return;
+    case hb_ot_complex_shaper_none:    default:                                                                return;
   }
 }
 
@@ -82,12 +130,14 @@ hb_ot_shape_complex_collect_features (hb_ot_shape_planner_t *planner,
  */
 
 HB_INTERNAL void _hb_ot_shape_complex_setup_masks_arabic       (hb_ot_shape_context_t *c);
+HB_INTERNAL void _hb_ot_shape_complex_setup_masks_indic                (hb_ot_shape_context_t *c);
 
 static inline void
 hb_ot_shape_complex_setup_masks (hb_ot_shape_context_t *c)
 {
   switch (c->plan->shaper) {
     case hb_ot_complex_shaper_arabic:  _hb_ot_shape_complex_setup_masks_arabic (c);    return;
+    case hb_ot_complex_shaper_indic:   _hb_ot_shape_complex_setup_masks_indic (c);     return;
     case hb_ot_complex_shaper_none:    default:                                        return;
   }
 }
index 60269ce..bce27f5 100644 (file)
@@ -43,7 +43,8 @@ HB_BEGIN_DECLS
 
 enum hb_ot_complex_shaper_t {
   hb_ot_complex_shaper_none,
-  hb_ot_complex_shaper_arabic
+  hb_ot_complex_shaper_arabic,
+  hb_ot_complex_shaper_indic,
 };