Imported Upstream version 8.2.2
[platform/upstream/harfbuzz.git] / src / gen-arabic-table.py
index 621d5b6..8278d7d 100755 (executable)
@@ -153,12 +153,29 @@ def print_joining_table(f):
                print ("#undef %s" % (short))
        print ()
 
+LIGATURES = (
+       0xF2EE, 0xFC08, 0xFC0E, 0xFC12, 0xFC32, 0xFC3F, 0xFC40, 0xFC41, 0xFC42,
+       0xFC44, 0xFC4E, 0xFC5E, 0xFC60, 0xFC61, 0xFC62, 0xFC6A, 0xFC6D, 0xFC6F,
+       0xFC70, 0xFC73, 0xFC75, 0xFC86, 0xFC8F, 0xFC91, 0xFC94, 0xFC9C, 0xFC9D,
+       0xFC9E, 0xFC9F, 0xFCA1, 0xFCA2, 0xFCA3, 0xFCA4, 0xFCA8, 0xFCAA, 0xFCAC,
+       0xFCB0, 0xFCC9, 0xFCCA, 0xFCCB, 0xFCCC, 0xFCCD, 0xFCCE, 0xFCCF, 0xFCD0,
+       0xFCD1, 0xFCD2, 0xFCD3, 0xFCD5, 0xFCDA, 0xFCDB, 0xFCDC, 0xFCDD, 0xFD30,
+       0xFD88, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8, 0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC,
+       0xF201, 0xF211, 0xF2EE,
+)
+
 def print_shaping_table(f):
 
        shapes = {}
        ligatures = {}
        names = {}
-       for line in f:
+       lines = f.readlines()
+       lines += [
+               "F201;PUA ARABIC LIGATURE LELLAH ISOLATED FORM;Lo;0;AL;<isolated> 0644 0644 0647;;;;N;;;;;",
+               "F211;PUA ARABIC LIGATURE LAM WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0644 0645 062C;;;;N;;;;;",
+               "F2EE;PUA ARABIC LIGATURE SHADDA WITH FATHATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064B 0651;;;;N;;;;;",
+       ]
+       for line in lines:
 
                fields = [x.strip () for x in line.split (';')]
                if fields[5][0:1] != '<':
@@ -166,14 +183,19 @@ def print_shaping_table(f):
 
                items = fields[5].split (' ')
                shape, items = items[0][1:-1], tuple (int (x, 16) for x in items[1:])
+               c = int (fields[0], 16)
 
                if not shape in ['initial', 'medial', 'isolated', 'final']:
                        continue
 
-               c = int (fields[0], 16)
                if len (items) != 1:
-                       # We only care about lam-alef ligatures
-                       if len (items) != 2 or items[0] != 0x0644 or items[1] not in [0x0622, 0x0623, 0x0625, 0x0627]:
+                       # Mark ligatures start with space and are in visual order, so we
+                       # remove the space and reverse the items.
+                       if items[0] == 0x0020:
+                               items = items[:0:-1]
+                               shape = None
+                       # We only care about a subset of ligatures
+                       if c not in LIGATURES:
                                continue
 
                        # Save ligature
@@ -209,34 +231,99 @@ def print_shaping_table(f):
        print ("#define SHAPING_TABLE_LAST      0x%04Xu" % max_u)
        print ()
 
-       ligas = {}
-       for pair in ligatures.keys ():
-               for shape in ligatures[pair]:
-                       c = ligatures[pair][shape]
-                       if shape == 'isolated':
-                               liga = (shapes[pair[0]]['initial'], shapes[pair[1]]['final'])
-                       elif shape == 'final':
-                               liga = (shapes[pair[0]]['medial'], shapes[pair[1]]['final'])
+       ligas_2 = {}
+       ligas_3 = {}
+       ligas_mark_2 = {}
+       for key in ligatures.keys ():
+               for shape in ligatures[key]:
+                       c = ligatures[key][shape]
+                       if len(key) == 3:
+                               if shape == 'isolated':
+                                       liga = (shapes[key[0]]['initial'], shapes[key[1]]['medial'], shapes[key[2]]['final'])
+                               elif shape == 'final':
+                                       liga = (shapes[key[0]]['medial'], shapes[key[1]]['medial'], shapes[key[2]]['final'])
+                               elif shape == 'initial':
+                                       liga = (shapes[key[0]]['initial'], shapes[key[1]]['medial'], shapes[key[2]]['medial'])
+                               else:
+                                       raise Exception ("Unexpected shape", shape)
+                               if liga[0] not in ligas_3:
+                                       ligas_3[liga[0]] = []
+                               ligas_3[liga[0]].append ((liga[1], liga[2], c))
+                       elif len(key) == 2:
+                               if shape is None:
+                                       liga = key
+                                       if liga[0] not in ligas_mark_2:
+                                               ligas_mark_2[liga[0]] = []
+                                       ligas_mark_2[liga[0]].append ((liga[1], c))
+                                       continue
+                               elif shape == 'isolated':
+                                       liga = (shapes[key[0]]['initial'], shapes[key[1]]['final'])
+                               elif shape == 'final':
+                                       liga = (shapes[key[0]]['medial'], shapes[key[1]]['final'])
+                               elif shape == 'initial':
+                                       liga = (shapes[key[0]]['initial'], shapes[key[1]]['medial'])
+                               else:
+                                       raise Exception ("Unexpected shape", shape)
+                               if liga[0] not in ligas_2:
+                                       ligas_2[liga[0]] = []
+                               ligas_2[liga[0]].append ((liga[1], c))
                        else:
-                               raise Exception ("Unexpected shape", shape)
-                       if liga[0] not in ligas:
-                               ligas[liga[0]] = []
-                       ligas[liga[0]].append ((liga[1], c))
-       max_i = max (len (ligas[l]) for l in ligas)
+                               raise Exception ("Unexpected number of ligature components", key)
+       max_i = max (len (ligas_2[l]) for l in ligas_2)
        print ()
        print ("static const struct ligature_set_t {")
        print (" uint16_t first;")
        print (" struct ligature_pairs_t {")
-       print ("   uint16_t second;")
+       print ("   uint16_t components[1];")
        print ("   uint16_t ligature;")
        print (" } ligatures[%d];" % max_i)
        print ("} ligature_table[] =")
        print ("{")
-       for first in sorted (ligas.keys ()):
+       for first in sorted (ligas_2.keys ()):
+
+               print ("  { 0x%04Xu, {" % (first))
+               for liga in ligas_2[first]:
+                       print ("    { {0x%04Xu}, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]]))
+               print ("  }},")
+
+       print ("};")
+       print ()
+
+       max_i = max (len (ligas_mark_2[l]) for l in ligas_mark_2)
+       print ()
+       print ("static const struct ligature_mark_set_t {")
+       print (" uint16_t first;")
+       print (" struct ligature_pairs_t {")
+       print ("   uint16_t components[1];")
+       print ("   uint16_t ligature;")
+       print (" } ligatures[%d];" % max_i)
+       print ("} ligature_mark_table[] =")
+       print ("{")
+       for first in sorted (ligas_mark_2.keys ()):
+
+               print ("  { 0x%04Xu, {" % (first))
+               for liga in ligas_mark_2[first]:
+                       print ("    { {0x%04Xu}, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]]))
+               print ("  }},")
+
+       print ("};")
+       print ()
+
+       max_i = max (len (ligas_3[l]) for l in ligas_3)
+       print ()
+       print ("static const struct ligature_3_set_t {")
+       print (" uint16_t first;")
+       print (" struct ligature_triplets_t {")
+       print ("   uint16_t components[2];")
+       print ("   uint16_t ligature;")
+       print (" } ligatures[%d];" % max_i)
+       print ("} ligature_3_table[] =")
+       print ("{")
+       for first in sorted (ligas_3.keys ()):
 
                print ("  { 0x%04Xu, {" % (first))
-               for liga in ligas[first]:
-                       print ("    { 0x%04Xu, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]]))
+               for liga in ligas_3[first]:
+                       print ("    { {0x%04Xu, 0x%04Xu}, 0x%04Xu}, /* %s */" % (liga[0], liga[1], liga[2], names[liga[2]]))
                print ("  }},")
 
        print ("};")
@@ -257,8 +344,8 @@ for h in headers:
                print (" * %s" % (l.strip()))
 print (" */")
 print ()
-print ("#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH")
-print ("#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH")
+print ("#ifndef HB_OT_SHAPER_ARABIC_TABLE_HH")
+print ("#define HB_OT_SHAPER_ARABIC_TABLE_HH")
 print ()
 
 read_blocks (files[2])
@@ -266,6 +353,6 @@ print_joining_table (files[0])
 print_shaping_table (files[1])
 
 print ()
-print ("#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */")
+print ("#endif /* HB_OT_SHAPER_ARABIC_TABLE_HH */")
 print ()
 print ("/* == End of generated table == */")