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