예제 #1
0
    def __init__(self, target, test, incremental, emit_config, ignored_cp,
                 only_cp, enabled_tests):
        self.target = target
        self.test = test
        self.incremental = incremental  # target is different version of same file
        self.emit_config = emit_config  # generate config lines
        self.enabled_tests = enabled_tests or FontCompare.test_names

        self.target_cmap = font_data.get_cmap(target)
        self.test_cmap = font_data.get_cmap(test)

        target_chars = set(self.target_cmap.keys()) - _get_excluded_chars()
        if ignored_cp:
            target_chars -= ignored_cp
        if only_cp:
            target_chars &= only_cp
        self.target_chars = target_chars

        # Assume version has two decimal places, which MTI fonts do but Adobe's do not.
        target_version = font_data.printable_font_revision(target)
        test_version = font_data.printable_font_revision(test)

        target_names = font_data.get_name_records(target)
        test_names = font_data.get_name_records(test)
        self._log('target name: %s %s, version: %s' %
                  (target_names[1], target_names[2], target_version))
        self._log('test name: %s %s, version %s' %
                  (test_names[1], test_names[2], test_version))

        if emit_config:
            font_family = test_names[1]
            font_subfamily = test_names[2].replace(' ', '')
            self._config('name like %s; weight like %s; version == %s' %
                         (font_family, font_subfamily, test_version))
예제 #2
0
  def __init__(self, target, test, incremental, emit_config, ignored_cp, only_cp,
               enabled_tests):
    self.target = target
    self.test = test
    self.incremental = incremental # target is different version of same file
    self.emit_config = emit_config # generate config lines
    self.enabled_tests = enabled_tests or FontCompare.test_names

    self.target_cmap = font_data.get_cmap(target)
    self.test_cmap = font_data.get_cmap(test)

    target_chars = set(self.target_cmap.keys()) - _get_excluded_chars()
    if ignored_cp:
      target_chars -= ignored_cp
    if only_cp:
      target_chars &= only_cp
    self.target_chars = target_chars

    # Assume version has two decimal places, which MTI fonts do but Adobe's do not.
    target_version = font_data.printable_font_revision(target)
    test_version = font_data.printable_font_revision(test)

    target_names = font_data.get_name_records(target)
    test_names = font_data.get_name_records(test)
    self._log('target name: %s %s, version: %s' % (target_names[1], target_names[2], target_version))
    self._log('test name: %s %s, version %s' % (test_names[1], test_names[2], test_version))

    if emit_config:
      font_family = test_names[1]
      font_subfamily = test_names[2].replace(' ', '')
      self._config('name like %s; weight like %s; version == %s' %
                   (font_family, font_subfamily, test_version))
예제 #3
0
def create_lookup(table, font, flag=0):
    """Create a Lookup based on mapping table."""
    cmap = font_data.get_cmap(font)

    ligatures = {}
    for output, (ch1, ch2) in table.iteritems():
        output = cmap[output]
        ch1 = get_glyph_name_or_create(ch1, font)
        ch2 = get_glyph_name_or_create(ch2, font)

        ligature = otTables.Ligature()
        ligature.CompCount = 2
        ligature.Component = [ch2]
        ligature.LigGlyph = output

        try:
            ligatures[ch1].append(ligature)
        except KeyError:
            ligatures[ch1] = [ligature]

    ligature_subst = otTables.LigatureSubst()
    ligature_subst.ligatures = ligatures

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

    return lookup
예제 #4
0
def create_lookup(table, font, flag=0):
    """Create a Lookup based on mapping table."""
    cmap = font_data.get_cmap(font)

    ligatures = {}
    for output, (ch1, ch2) in table.iteritems():
        output = cmap[output]
        ch1 = get_glyph_name_or_create(ch1, font)
        ch2 = get_glyph_name_or_create(ch2, font)

        ligature = otTables.Ligature()
        ligature.CompCount = 2
        ligature.Component = [ch2]
        ligature.LigGlyph = output

        try:
            ligatures[ch1].append(ligature)
        except KeyError:
            ligatures[ch1] = [ligature]

    ligature_subst = otTables.LigatureSubst()
    ligature_subst.ligatures = ligatures

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

    return lookup
예제 #5
0
def add_pua_cmap(source_file, target_file):
    """Add PUA characters to the cmap of the first font and save as second."""
    font = ttLib.TTFont(source_file)
    cmap = font_data.get_cmap(font)
    for pua, (ch1, ch2) in (add_emoji_gsub.EMOJI_KEYCAPS.items()
                            + add_emoji_gsub.EMOJI_FLAGS.items()):
        if pua not in cmap:
            glyph_name = get_glyph_name_from_gsub([ch1, ch2], font)
            if glyph_name is not None:
                cmap[pua] = glyph_name
    font.save(target_file)
예제 #6
0
def add_pua_cmap(source_file, target_file):
    """Add PUA characters to the cmap of the first font and save as second."""
    font = ttLib.TTFont(source_file)
    cmap = font_data.get_cmap(font)
    for pua, (ch1, ch2) in (add_emoji_gsub.EMOJI_KEYCAPS.items() +
                            add_emoji_gsub.EMOJI_FLAGS.items()):
        if pua not in cmap:
            glyph_name = get_glyph_name_from_gsub([ch1, ch2], font)
            if glyph_name is not None:
                cmap[pua] = glyph_name
    font.save(target_file)
예제 #7
0
def get_glyph_name_or_create(char, font):
    """Return the glyph name for a character, creating if it doesn't exist."""
    cmap = font_data.get_cmap(font)
    if char in cmap:
        return cmap[char]

    glyph_name = agl.UV2AGL[char]
    assert glyph_name not in font.glyphOrder

    font['hmtx'].metrics[glyph_name] = [0, 0]
    cmap[char] = glyph_name

    if 'glyf' in font:
        from fontTools.ttLib.tables import _g_l_y_f
        empty_glyph = _g_l_y_f.Glyph()
        font['glyf'].glyphs[glyph_name] = empty_glyph

    font.glyphOrder.append(glyph_name)
    return glyph_name
예제 #8
0
def get_glyph_name_or_create(char, font):
    """Return the glyph name for a character, creating if it doesn't exist."""
    cmap = font_data.get_cmap(font)
    if char in cmap:
        return cmap[char]

    glyph_name = agl.UV2AGL[char]
    assert glyph_name not in font.glyphOrder

    font['hmtx'].metrics[glyph_name] = [0, 0]
    cmap[char] = glyph_name

    if 'glyf' in font:
        from fontTools.ttLib.tables import _g_l_y_f
        empty_glyph = _g_l_y_f.Glyph()
        font['glyf'].glyphs[glyph_name] = empty_glyph

    font.glyphOrder.append(glyph_name)
    return glyph_name
def merge_chars_from_bank(orig_font, bank_font, target_font, chars):
    """Merge glyphs from a bank font to another font.
    
    Only the glyphs themselves, the horizontal metrics, and the cmaps will be
    copied.
    """
    bank_font = ttLib.TTFont(bank_font)
    orig_font = ttLib.TTFont(orig_font)

    bank_cmap = font_data.get_cmap(bank_font)
    extra_cmap = {}
    for char in sorted(chars):
        assert char in bank_cmap
        bank_glyph_name = bank_cmap[char]
        assert bank_glyph_name not in orig_font['glyf'].glyphs
        orig_font['glyf'][bank_glyph_name] = bank_font['glyf'][bank_glyph_name]
        orig_font['hmtx'][bank_glyph_name] = bank_font['hmtx'][bank_glyph_name]
        extra_cmap[char] = bank_glyph_name
    font_data.add_to_cmap(orig_font, extra_cmap)
    orig_font.save(target_font)
def merge_chars_from_bank(orig_font, bank_font, target_font, chars):
    """Merge glyphs from a bank font to another font.
    
    Only the glyphs themselves, the horizontal metrics, and the cmaps will be
    copied.
    """
    bank_font = ttLib.TTFont(bank_font)
    orig_font = ttLib.TTFont(orig_font)

    bank_cmap = font_data.get_cmap(bank_font)
    extra_cmap = {}
    for char in sorted(chars):
        assert char in bank_cmap
        bank_glyph_name = bank_cmap[char]
        assert bank_glyph_name not in orig_font['glyf'].glyphs
        orig_font['glyf'][bank_glyph_name] = bank_font['glyf'][bank_glyph_name]
        orig_font['hmtx'][bank_glyph_name] = bank_font['hmtx'][bank_glyph_name]
        extra_cmap[char] = bank_glyph_name
    font_data.add_to_cmap(orig_font, extra_cmap)
    orig_font.save(target_font)
예제 #11
0
def get_glyph_name_from_gsub(char_seq, font):
    """Find the glyph name for ligature of a given character sequence from GSUB.
    """
    cmap = font_data.get_cmap(font)
    # FIXME: So many assumptions are made here.
    try:
        first_glyph = cmap[char_seq[0]]
        rest_of_glyphs = [cmap[ch] for ch in char_seq[1:]]
    except KeyError:
        return None

    for lookup in font['GSUB'].table.LookupList.Lookup:
        ligatures = lookup.SubTable[0].ligatures
        try:
            for ligature in ligatures[first_glyph]:
                if ligature.Component == rest_of_glyphs:
                    return ligature.LigGlyph
        except KeyError:
            continue
    return None
예제 #12
0
def get_glyph_name_from_gsub(char_seq, font):
    """Find the glyph name for ligature of a given character sequence from GSUB.
    """
    cmap = font_data.get_cmap(font)
    # FIXME: So many assumptions are made here.
    try:
        first_glyph = cmap[char_seq[0]]
        rest_of_glyphs = [cmap[ch] for ch in char_seq[1:]]
    except KeyError:
        return None

    for lookup in font['GSUB'].table.LookupList.Lookup:
        ligatures = lookup.SubTable[0].ligatures
        try:
            for ligature in ligatures[first_glyph]:
                if ligature.Component == rest_of_glyphs:
                    return ligature.LigGlyph
        except KeyError:
            continue
    return None