Exemplo n.º 1
0
def subset_truetype(sfnt, character_map, extra_glyphs):
    loca = sfnt[b'loca']
    glyf = sfnt[b'glyf']

    try:
        head, maxp = sfnt[b'head'], sfnt[b'maxp']
    except KeyError:
        raise UnsupportedFont(
            'This font does not contain head and/or maxp tables')
    loca.load_offsets(head, maxp)

    resolved_glyphs = resolve_glyphs(loca, glyf, character_map, extra_glyphs)
    if not resolved_glyphs or set(resolved_glyphs) == {0}:
        raise NoGlyphs('This font has no glyphs for the specified character '
                       'set, subsetting it is pointless')

    # Keep only character codes that have resolved glyphs
    for code, glyph_id in tuple(character_map.iteritems()):
        if glyph_id not in resolved_glyphs:
            del character_map[code]

    # Update the glyf table
    glyph_offset_map = glyf.update(resolved_glyphs)

    # Update the loca table
    loca.subset(glyph_offset_map)
Exemplo n.º 2
0
    def subset(self, character_map, extra_glyphs):
        from calibre.utils.fonts.sfnt.cff.writer import Subset
        # Map codes from the cmap table to glyph names, this will be used to
        # reconstruct character_map for the subset font
        charset_map = {
            code: self.cff.charset.safe_lookup(glyph_id)
            for code, glyph_id in character_map.iteritems()
        }
        charset = set(charset_map.itervalues())
        charset.discard(None)
        if not charset and character_map:
            raise NoGlyphs(
                'This font has no glyphs for the specified characters')
        charset |= {
            self.cff.charset.safe_lookup(glyph_id)
            for glyph_id in extra_glyphs
        }
        charset.discard(None)
        s = Subset(self.cff, charset)

        # Rebuild character_map with the glyph ids from the subset font
        character_map.clear()
        for code, charname in charset_map.iteritems():
            glyph_id = s.charname_map.get(charname, None)
            if glyph_id:
                character_map[code] = glyph_id

        # Check that raw is parseable
        CFF(s.raw)

        self.raw = s.raw