From b7e8f69ece40b13d8442556ec40c4ed4c649fc7b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 8 Nov 2012 15:54:59 +0530 Subject: [PATCH] Start work on subsetting CFF tables --- src/calibre/utils/fonts/sfnt/cff/table.py | 23 ++++++++++++++++++++++ src/calibre/utils/fonts/sfnt/cff/writer.py | 16 +++++++++++++++ src/calibre/utils/fonts/sfnt/subset.py | 1 + 3 files changed, 40 insertions(+) create mode 100644 src/calibre/utils/fonts/sfnt/cff/writer.py diff --git a/src/calibre/utils/fonts/sfnt/cff/table.py b/src/calibre/utils/fonts/sfnt/cff/table.py index 11f24aa98d..accb5f91f3 100644 --- a/src/calibre/utils/fonts/sfnt/cff/table.py +++ b/src/calibre/utils/fonts/sfnt/cff/table.py @@ -268,6 +268,12 @@ class Charset(list): return self[glyph_id] return self.STANDARD_CHARSETS[self.standard_charset][glyph_id].encode('ascii') + def safe_lookup(self, glyph_id): + try: + return self.lookup(glyph_id) + except (KeyError, IndexError, ValueError): + return None + class Subrs(Index): pass @@ -279,6 +285,23 @@ class CFFTable(UnknownTable): def decompile(self): self.cff = CFF(self.raw) + def subset(self, character_map): + 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) + 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: + glyph_id = s.charname_map.get(charname, None) + if glyph_id: + character_map[code] = glyph_id + # cff_standard_strings {{{ # The 391 Standard Strings as used in the CFF format. # from Adobe Technical None #5176, version 1.0, 18 March 1998 diff --git a/src/calibre/utils/fonts/sfnt/cff/writer.py b/src/calibre/utils/fonts/sfnt/cff/writer.py new file mode 100644 index 0000000000..cab5707fa0 --- /dev/null +++ b/src/calibre/utils/fonts/sfnt/cff/writer.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:fdm=marker:ai +from __future__ import (unicode_literals, division, absolute_import, + print_function) + +__license__ = 'GPL v3' +__copyright__ = '2012, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +class Subset(object): + + def __init__(self, cff, character_map): + self.cff = cff + self.character_map = character_map + self.charname_map = {} + diff --git a/src/calibre/utils/fonts/sfnt/subset.py b/src/calibre/utils/fonts/sfnt/subset.py index c7e3ec8c34..4c4fbfa7c1 100644 --- a/src/calibre/utils/fonts/sfnt/subset.py +++ b/src/calibre/utils/fonts/sfnt/subset.py @@ -69,6 +69,7 @@ def subset_truetype(sfnt, character_map): def subset_postscript(sfnt, character_map): cff = sfnt[b'CFF '] cff.decompile() + cff.subset(character_map) raise Exception('TODO: Implement CFF subsetting') def subset(raw, individual_chars, ranges=()):