Update handling of fitzpatrick modifiers.

To handle forming emoji 'ligatures' in RTL contexts we generate
reversed ligature sequences for the GSUB table.  Formerly we only did
this when there was a ZWJ in the sequence, and full reversal worked
because we had no sequences with both fitzpatrick modifiers and ZWJ.
However, now we do.  Harfbuzz treats fitzpatrick modifiers as though
they were combining marks and so we need to as well so that GSUB data
is in the order Harfbuzz expects.  So we 'unreverse' these pairs.
This commit is contained in:
Doug Felt 2016-07-11 11:31:51 -07:00
parent 1da485d2be
commit be1ec4f152

View file

@ -17,6 +17,10 @@ import add_emoji_gsub
def is_vs(cp): def is_vs(cp):
return cp >= 0xfe00 and cp <= 0xfe0f return cp >= 0xfe00 and cp <= 0xfe0f
def is_fitzpatrick(gname):
cp = int(gname[1:], 16)
return 0x1f3fb <= cp <= 0x1f3ff
def codes_to_string(codes): def codes_to_string(codes):
if "_" in codes: if "_" in codes:
pieces = codes.split ("_") pieces = codes.split ("_")
@ -147,10 +151,19 @@ glyph_names = set()
ligatures = {} ligatures = {}
def add_lig_sequence(ligatures, seq, n): def add_lig_sequence(ligatures, seq, n):
# Assume sequences with ZWJ are emoji 'ligatures' and rtl order # We have emoji sequences using regional indicator symbols,
# is also valid. Internal permutations, though, no. # ZWJ, fitzpatrick modifiers, and combinations of ZWJ and fitzpatrick
# We associate a sequence with a filename. We can overwrite the # modifiers. Currently, Harfbuzz special-cases the fitzpatrick
# sequence with a different filename later. # modifiers to treat them as combining marks instead of as Other
# Neutral, which unicode says they are, and processes them
# in visual order (at least in some circumstances). So to handle
# emoji sequences in an RTL context we need GSUB sequences that match
# this order.
# Regional indicator symbols are LTR, and emoji+fitzpatrick are
# effectively LTR, so we only reorder sequences with ZWJ. If however
# the ZWJ sequence has fitzpatrick modifiers, those need to still follow
# the emoji they logically follow, so simply reversing the sequence
# doesn't work. This code assumes the lig sequence is valid.
tseq = tuple(seq) tseq = tuple(seq)
if tseq in ligatures: if tseq in ligatures:
print 'lig sequence %s, replace %s with %s' % ( print 'lig sequence %s, replace %s with %s' % (
@ -159,6 +172,12 @@ def add_lig_sequence(ligatures, seq, n):
if 'u200D' in seq: if 'u200D' in seq:
rev_seq = seq[:] rev_seq = seq[:]
rev_seq.reverse() rev_seq.reverse()
for i in xrange(1, len(rev_seq)):
if is_fitzpatrick(rev_seq[i - 1]):
tmp = rev_seq[i]
rev_seq[i] = rev_seq[i-1]
rev_seq[i-1] = tmp
trseq = tuple(rev_seq) trseq = tuple(rev_seq)
# if trseq in ligatures: # if trseq in ligatures:
# print 'rev lig sequence %s, replace %s with %s' % ( # print 'rev lig sequence %s, replace %s with %s' % (