[USE] Finish converting Unicode positional categories to USE Even compiles.
diff --git a/src/gen-use-table.py b/src/gen-use-table.py index f1484fd..7293b73 100755 --- a/src/gen-use-table.py +++ b/src/gen-use-table.py
@@ -99,7 +99,7 @@ 'Number', 'Brahmi_Joining_Number', # Indic_Positional_Category - 'Not_Applicable' + 'Not_Applicable', 'Right', 'Left', 'Visual_Order_Left', @@ -121,8 +121,7 @@ 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 @@ '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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 == */"