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))
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
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)
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 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