コード例 #1
0
  def _load_font(data, codelist_map):
    if len(data) < 4:
      data = data + tuple([None] * (4 - len(data)))
    key, fname, name, codelistfile = data

    if not fname:
      if not name:
        raise Exception('must have name if no font provided')
      if not codelistfile:
        raise Exception('must have codelist file if no font provided')
      fontpath = None
    else:
      fontpath = path.join(data_dir, fname)
      if not path.isfile(fontpath):
        raise Exception('font "%s" not found' % fontpath)

    if codelistfile:
      codelist = _load_codelist(codelistfile, data_dir, codelist_map)

    if fname and (not codelistfile or not name):
      font = ttLib.TTFont(fontpath)
      if not name:
        names = font_data.get_name_records(font)
        name = names[16] if 16 in names else names[1] if 1 in names else None
        if not name:
          raise Exception('cannot read name from font "%s"' % fontpath)
      if not codelistfile:
        codelist = CodeList.fromset(font_data.get_cmap(font))

    return key, fontpath, name, codelist
コード例 #2
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:
        ### This line is added for emoji_builder ###
        try:
            ### Thes following lines are indented for emoji_builder ###
            ligatures = lookup.SubTable[0].ligatures
            try:
                for ligature in ligatures[first_glyph]:
                    if ligature.Component == rest_of_glyphs:
                        return ligature.LigGlyph
            except KeyError:
                continue
        ### This line is added for emoji_builder ###
        except AttributeError:  # If there are no ligatures at all, it's fine as well.
            ### This line is added for emoji_builder ###
            pass
    return None
コード例 #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
ファイル: add_emoji_gsub.py プロジェクト: C1710/emoji_builder
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 subset_font_cmap(srcname,
                     dstname,
                     exclude=None,
                     include=None,
                     bump_version=True):

    opt = _DEFAULT_OPTIONS

    font = subset.load_font(srcname, opt)
    target_charset = set(font_data.get_cmap(font).keys())

    if include is not None:
        target_charset &= include
    if exclude is not None:
        target_charset -= exclude

    subsetter = subset.Subsetter(options=opt)
    subsetter.populate(unicodes=target_charset)
    subsetter.subset(font)

    if bump_version:
        # assume version string has 'uh' if unhinted, else hinted.
        revision, version_string = swat_license.get_bumped_version(font)
        font['head'].fontRevision = revision
        font_data.set_name_record(font, _VERSION_ID, version_string)

    subset.save_font(font, dstname, opt)
コード例 #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
ファイル: map_pua_emoji.py プロジェクト: arunlodhi/noto-emoji
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)
コード例 #8
0
ファイル: add_vs_cmap.py プロジェクト: anthrotype/nototools
def modify_font(font_name, font, presentation, emoji_variants):
  cmap_table = font_data.get_cmap(font)
  emoji = set(cmap_table.keys()) & emoji_variants
  if not emoji:
    print 'no emoji match those in %s' % font_name
    return
  uvs = VS_EMOJI if presentation == 'emoji' else VS_TEXT
  cmap14 = _c_m_a_p.CmapSubtable.newSubtable(14)
  cmap14.cmap = {}
  cmap14.uvsDict = {uvs: [[c, None] for c in sorted(emoji)]}
  cmap14.platformID = 0
  cmap14.platEncID = 5
  cmap14.language = 0xFF # what fontTools would have used
  font['cmap'].tables.append(cmap14)
コード例 #9
0
def modify_font(font_name, font, presentation, emoji_variants):
    cmap_table = font_data.get_cmap(font)
    emoji = set(cmap_table.keys()) & emoji_variants
    if not emoji:
        print('no emoji match those in %s' % font_name)
        return
    uvs = VS_EMOJI if presentation == 'emoji' else VS_TEXT
    cmap14 = _c_m_a_p.CmapSubtable.newSubtable(14)
    cmap14.cmap = {}
    cmap14.uvsDict = {uvs: [[c, None] for c in sorted(emoji)]}
    cmap14.platformID = 0
    cmap14.platEncID = 5
    cmap14.language = 0xFF  # what fontTools would have used
    font['cmap'].tables.append(cmap14)
コード例 #10
0
def _get_cp_metrics(font, cp):
    # returns metrics for nominal glyph for cp, or None if cp not in font
    cmap = font_data.get_cmap(font)
    if cp not in cmap:
      return None
    glyphs = font.getGlyphSet()
    g = glyphs[cmap[cp]]
    pen = BoundsPen(glyphs)
    g.draw(pen)
    if not pen.bounds:
      return None
    xmin, ymin, xmax, ymax = pen.bounds
    return GMetrics(
        xmin, g.width - xmax, xmax - xmin, g.width, (ymin + ymax) / 2)
コード例 #11
0
ファイル: glyph_image_compare.py プロジェクト: hmr/nototools
    def create_glyph_data(font, collection):
        glyphorder = font.getGlyphOrder()
        data = [None] * len(glyphorder)
        name_to_index = {g: i for i, g in enumerate(glyphorder)}
        cmap = font_data.get_cmap(font)
        # if different cps map to the same glyph, this uses the last one
        index_to_cp = {name_to_index[cmap[cp]]: cp for cp in cmap}

        for i, g in enumerate(glyphorder):
            cp = index_to_cp.get(i, -1)
            name = "" if (i == 0 or cp >= 0 or g == "glyph%05d" % i) else g
            adv = collection.image_dict[i].adv.int
            data[i] = (adv, cp, name)
        return data
コード例 #12
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
コード例 #13
0
ファイル: add_emoji_gsub.py プロジェクト: C1710/emoji_builder
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
コード例 #14
0
ファイル: map_pua_emoji.py プロジェクト: arunlodhi/noto-emoji
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
コード例 #15
0
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)
コード例 #16
0
ファイル: map_pua_emoji.py プロジェクト: C1710/emoji_builder
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
コード例 #17
0
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)
コード例 #18
0
def subset_font_cmap(
  srcname, dstname, exclude=None, include=None, bump_version=True):

  opt = _DEFAULT_OPTIONS

  font = subset.load_font(srcname, opt)
  target_charset = set(font_data.get_cmap(font).keys())

  if include is not None:
    target_charset &= include
  if exclude is not None:
    target_charset -= exclude

  subsetter = subset.Subsetter(options=opt)
  subsetter.populate(unicodes=target_charset)
  subsetter.subset(font)

  if bump_version:
    # assume version string has 'uh' if unhinted, else hinted.
    revision, version_string = swat_license.get_bumped_version(font)
    font['head'].fontRevision = revision
    font_data.set_name_record(font, _VERSION_ID, version_string)

  subset.save_font(font, dstname, opt)
コード例 #19
0
def _get_cp_to_glyphix(font):
    # so, i should use glyph names, then the cmap is exactly what I want, no?
    cmap = font_data.get_cmap(font)  # cp to glyph name
    name_to_index = {g: i for i, g in enumerate(font.getGlyphOrder())}
    return {cp: name_to_index[cmap[cp]] for cp in cmap}
コード例 #20
0
ファイル: glyph_image_compare.py プロジェクト: hmr/nototools
 def create_font_data(font, collection):
     cps = len(font_data.get_cmap(font))
     version = font_data.font_version(font)
     return GlyphImageFontData._make(collection.file_header +
                                     (cps, version))
コード例 #21
0
 def fromfontcmap(fontname):
   font = ttLib.TTFont(fontname)
   return CodeList.fromset(font_data.get_cmap(font))