#!/usr/bin/env python3

"""Extend a ttx file with additional data.

Takes a ttx file and one or more directories containing image files named
after sequences of codepoints, extends the cmap, hmtx, GSUB, and GlyphOrder
tables in the source ttx file based on these sequences, and writes out a new
ttx file.

This can also apply aliases from an alias file."""

import argparse
import collections
import os
from os import path
import re
import sys

from fontTools import ttx
from fontTools.ttLib.tables import otTables

import add_emoji_gsub
import add_aliases

sys.path.append(
    path.join(os.path.dirname(__file__), 'third_party', 'color_emoji'))
from png import PNG


def get_seq_to_file(image_dir, prefix, suffix):
  """Return a mapping from codepoint sequences to files in the given directory,
  for files that match the prefix and suffix.  File names with this prefix and
  suffix should consist of codepoints in hex separated by underscore.  'fe0f'
  (the codepoint of the emoji presentation variation selector) is stripped from
  the sequence.
  """
  start = len(prefix)
  limit = -len(suffix)
  seq_to_file = {}
  for name in os.listdir(image_dir):
    if not (name.startswith(prefix) and name.endswith(suffix)):
      continue
    try:
      cps = [int(s, 16) for s in name[start:limit].split('_')]
      seq = tuple(cp for cp in cps if cp != 0xfe0f)
    except:
      raise Exception('could not parse "%s"' % name)
    for cp in cps:
      if not (0 <= cp <= 0x10ffff):
        raise Exception('bad codepoint(s) in "%s"' % name)
    if seq in seq_to_file:
      raise Exception('duplicate sequence for "%s" in %s' % (name, image_dir))
    seq_to_file[seq] = path.join(image_dir, name)
  return seq_to_file


def collect_seq_to_file(image_dirs, prefix, suffix):
  """Return a sequence to file mapping by calling get_seq_to_file on a list
  of directories.  When sequences for files in later directories match those
  from earlier directories, the later file replaces the earlier one.
  """
  seq_to_file = {}
  for image_dir in image_dirs:
    seq_to_file.update(get_seq_to_file(image_dir, prefix, suffix))
  return seq_to_file


def remap_values(seq_to_file, map_fn):
  return {k: map_fn(v) for k, v in seq_to_file.items()}


def get_png_file_to_advance_mapper(lineheight):
  def map_fn(filename):
    wid, ht = PNG(filename).get_size()
    return int(round(float(lineheight) * wid / ht))
  return map_fn


def cp_name(cp):
  """return uniXXXX or uXXXXX(X) as a name for the glyph mapped to this cp."""
  return '%s%04X' % ('u' if cp > 0xffff else 'uni', cp)


def seq_name(seq):
  """Sequences of length one get the cp_name.  Others start with 'u' followed by
  two or more 4-to-6-digit hex strings separated by underscore."""
  if len(seq) == 1:
    return cp_name(seq[0])
  return 'u' + '_'.join('%04X' % cp for cp in seq)


def collect_cps(seqs):
  cps = set()
  for seq in seqs:
    cps.update(seq)
  return cps


def get_glyphorder_cps_and_truncate(glyphOrder):
  """This scans glyphOrder for names that correspond to a single codepoint
  using the 'u(ni)XXXXXX' syntax.  All names that don't match are moved
  to the front the glyphOrder list in their original order, and the
  list is truncated.  The ones that do match are returned as a set of
  codepoints."""
  glyph_name_re = re.compile(r'^u(?:ni)?([0-9a-fA-F]{4,6})$')
  cps = set()
  write_ix = 0
  for ix, name in enumerate(glyphOrder):
    m = glyph_name_re.match(name)
    if m:
      cps.add(int(m.group(1), 16))
    else:
      glyphOrder[write_ix] = name
      write_ix += 1
  del glyphOrder[write_ix:]
  return cps


def get_all_seqs(font, seq_to_advance):
  """Copies the sequences from seq_to_advance and extends it with single-
  codepoint sequences from the GlyphOrder table as well as those internal
  to sequences in seq_to_advance.  Reduces the GlyphOrder table. """

  all_seqs = set(seq_to_advance.keys())
  # using collect_cps includes cps internal to a seq
  cps = collect_cps(all_seqs)
  glyphOrder = font.getGlyphOrder()
  # extract cps in glyphOrder and reduce glyphOrder to only those that remain
  glyphOrder_cps = get_glyphorder_cps_and_truncate(glyphOrder)
  cps.update(glyphOrder_cps)
  # add new single codepoint sequences from glyphOrder and sequences
  all_seqs.update((cp,) for cp in cps)
  return all_seqs


def get_font_cmap(font):
  """Return the first cmap in the font, we assume it exists and is a unicode
  cmap."""
  return font['cmap'].tables[0].cmap


def add_glyph_data(font, seqs, seq_to_advance, vadvance):
  """Add hmtx and GlyphOrder data for all sequences in seqs, and ensures there's
  a cmap entry for each single-codepoint sequence.  Seqs not in seq_to_advance
  will get a zero advance."""

  # We allow the template cmap to omit mappings for single-codepoint glyphs
  # defined in the template's GlyphOrder table.  Similarly, the hmtx table can
  # omit advances.  We assume glyphs named 'uniXXXX' or 'uXXXXX(X)' in the
  # GlyphOrder table correspond to codepoints based on the name; we don't
  # attempt to handle other types of names and these must occur in the cmap and
  # hmtx tables in the template.
  #
  # seq_to_advance maps sequences (including single codepoints) to advances.
  # All codepoints in these sequences will be added to the cmap.  Some cps
  # in these sequences have no corresponding single-codepoint sequence, they
  # will also get added.
  #
  # The added codepoints have no advance information, so will get a zero
  # advance.

  cmap = get_font_cmap(font)
  hmtx = font['hmtx'].metrics
  vmtx = font['vmtx'].metrics

  # We don't expect sequences to be in the glyphOrder, since we removed all the
  # single-cp sequences from it and don't expect it to already contain names
  # corresponding to multiple-cp sequencess.  But just in case, we use
  # reverseGlyphMap to avoid duplicating names accidentally.

  updatedGlyphOrder = False
  reverseGlyphMap = font.getReverseGlyphMap()

  # Order the glyphs by grouping all the single-codepoint sequences first,
  # then order by sequence so that related sequences are together.  We group
  # by single-codepoint sequence first in order to keep these glyphs together--
  # they're used in the coverage tables for some of the substitutions, and
  # those tables can be more compact this way.
  for seq in sorted(seqs, key=lambda s: (0 if len(s) == 1 else 1, s)):
    name = seq_name(seq)
    if len(seq) == 1:
      cmap[seq[0]] = name
    advance = seq_to_advance.get(seq, 0)
    hmtx[name] = [advance, 0]
    vmtx[name] = [vadvance, 0]
    if name not in reverseGlyphMap:
      font.glyphOrder.append(name)
      updatedGlyphOrder=True

  if updatedGlyphOrder:
    delattr(font, '_reverseGlyphOrderDict')


def add_aliases_to_cmap(font, aliases):
  """Some aliases might map a single codepoint to some other sequence.  These
  should map directly to the glyph for that sequence in the cmap.  (Others will
  map via GSUB).
  """
  if not aliases:
    return

  cp_aliases = [seq for seq in aliases if len(seq) == 1]
  if not cp_aliases:
    return

  cmap = get_font_cmap(font)
  for src_seq in cp_aliases:
    cp = src_seq[0]
    name = seq_name(aliases[src_seq])
    cmap[cp] = name


def get_rtl_seq(seq):
  """Return the rtl variant of the sequence, if it has one, else the empty
  sequence.
  """
  # Sequences with ZWJ in them will reflect.  Fitzpatrick modifiers
  # however do not, so if we reflect we make a pass to swap them back into their
  # logical order.
  # Used to check for TAG_END 0xe007f as well but Android fontchain_lint
  # dislikes the resulting mangling of flags for England, Scotland, Wales.

  ZWJ = 0x200d
  def is_fitzpatrick(cp):
    return 0x1f3fb <= cp <= 0x1f3ff

  if ZWJ not in seq:
    return ()

  rev_seq = list(seq)
  rev_seq.reverse()
  for i in range(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
  return tuple(rev_seq)


def get_gsub_ligature_lookup(font):
  """If the font does not have a GSUB table, create one with a ligature
  substitution lookup.  If it does, ensure the first lookup is a properly
  initialized ligature substitution lookup.  Return the lookup."""

  # The template might include more lookups after lookup 0, if it has a
  # GSUB table.
  if 'GSUB' not in font:
    ligature_subst = otTables.LigatureSubst()
    ligature_subst.ligatures = {}

    lookup = otTables.Lookup()
    lookup.LookupType = 4
    lookup.LookupFlag = 0
    lookup.SubTableCount = 1
    lookup.SubTable = [ligature_subst]

    font['GSUB'] = add_emoji_gsub.create_simple_gsub([lookup])
  else:
    lookup = font['GSUB'].table.LookupList.Lookup[0]
    assert lookup.LookupFlag == 0

    # importXML doesn't fully init GSUB structures, so help it out
    st = lookup.SubTable[0]
    if not hasattr(lookup, 'LookupType'):
      assert st.LookupType == 4
      setattr(lookup, 'LookupType', 4)

    if not hasattr(st, 'ligatures'):
      setattr(st, 'ligatures', {})

  return lookup


def add_ligature_sequences(font, seqs, aliases):
  """Add ligature sequences."""

  seq_to_target_name = {
      seq: seq_name(seq) for seq in seqs if len(seq) > 1}
  if aliases:
    seq_to_target_name.update({
        seq: seq_name(aliases[seq]) for seq in aliases if len(seq) > 1})
  if not seq_to_target_name:
    return

  rtl_seq_to_target_name = {
      get_rtl_seq(seq): name for seq, name in seq_to_target_name.items()}
  seq_to_target_name.update(rtl_seq_to_target_name)
  # sequences that don't have rtl variants get mapped to the empty sequence,
  # delete it.
  if () in seq_to_target_name:
    del seq_to_target_name[()]

  # organize by first codepoint in sequence
  keyed_ligatures = collections.defaultdict(list)
  for t in seq_to_target_name.items():
    first_cp = t[0][0]
    keyed_ligatures[first_cp].append(t)

  def add_ligature(lookup, cmap, seq, name):
    # The sequences consist of codepoints, but the entries in the ligature table
    # are glyph names.  Aliasing can give single codepoints names based on
    # sequences (e.g. 'guardsman' with 'male guardsman') so we map the
    # codepoints through the cmap to get the glyph names.
    glyph_names = [cmap[cp] for cp in seq]

    lig = otTables.Ligature()
    lig.CompCount = len(seq)
    lig.Component = glyph_names[1:]
    lig.LigGlyph = name

    ligatures = lookup.SubTable[0].ligatures
    first_name = glyph_names[0]
    try:
      ligatures[first_name].append(lig)
    except KeyError:
      ligatures[first_name] = [lig]

  lookup = get_gsub_ligature_lookup(font)
  cmap = get_font_cmap(font)
  for first_cp in sorted(keyed_ligatures):
    pairs = keyed_ligatures[first_cp]

    # Sort longest first, this ensures longer sequences with common prefixes
    # are handled before shorter ones.  The secondary sort is a standard
    # sort on the codepoints in the sequence.
    pairs.sort(key = lambda pair: (-len(pair[0]), pair[0]))
    for seq, name in pairs:
      add_ligature(lookup, cmap, seq, name)


def update_font_data(font, seq_to_advance, vadvance, aliases):
  """Update the font's cmap, hmtx, GSUB, and GlyphOrder tables."""
  seqs = get_all_seqs(font, seq_to_advance)
  add_glyph_data(font, seqs, seq_to_advance, vadvance)
  add_aliases_to_cmap(font, aliases)
  add_ligature_sequences(font, seqs, aliases)


def apply_aliases(seq_dict, aliases):
  """Aliases is a mapping from sequence to replacement sequence.  We can use
  an alias if the target is a key in the dictionary.  Furthermore, if the
  source is a key in the dictionary, we can delete it.  This updates the
  dictionary and returns the usable aliases."""
  usable_aliases = {}
  for k, v in aliases.items():
    if v in seq_dict:
      usable_aliases[k] = v
      if k in seq_dict:
        del seq_dict[k]
  return usable_aliases


def update_ttx(in_file, out_file, image_dirs, prefix, ext, aliases_file):
  if ext != '.png':
    raise Exception('extension "%s" not supported' % ext)

  seq_to_file = collect_seq_to_file(image_dirs, prefix, ext)
  if not seq_to_file:
    raise ValueError(
        'no sequences with prefix "%s" and extension "%s" in %s' % (
            prefix, ext, ', '.join(image_dirs)))

  aliases = None
  if aliases_file:
    aliases = add_aliases.read_emoji_aliases(aliases_file)
    aliases = apply_aliases(seq_to_file, aliases)

  font = ttx.TTFont()
  font.importXML(in_file)

  lineheight = font['hhea'].ascent - font['hhea'].descent
  map_fn = get_png_file_to_advance_mapper(lineheight)
  seq_to_advance = remap_values(seq_to_file, map_fn)

  vadvance = font['vhea'].advanceHeightMax if 'vhea' in font else lineheight

  update_font_data(font, seq_to_advance, vadvance, aliases)

  font.saveXML(out_file)


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument(
      '-f', '--in_file', help='ttx input file', metavar='file', required=True)
  parser.add_argument(
      '-o', '--out_file', help='ttx output file', metavar='file', required=True)
  parser.add_argument(
      '-d', '--image_dirs', help='directories containing image files',
      nargs='+', metavar='dir', required=True)
  parser.add_argument(
      '-p', '--prefix', help='file prefix (default "emoji_u")',
      metavar='pfx', default='emoji_u')
  parser.add_argument(
      '-e', '--ext', help='file extension (default ".png", currently only '
      '".png" is supported',  metavar='ext', default='.png')
  parser.add_argument(
      '-a', '--aliases', help='process alias table', const='emoji_aliases.txt',
      nargs='?', metavar='file')
  args = parser.parse_args()

  update_ttx(
      args.in_file, args.out_file, args.image_dirs, args.prefix, args.ext,
      args.aliases)


if __name__ == '__main__':
  main()
