diff options
Diffstat (limited to 'Lib/fontTools/subset/cff.py')
-rw-r--r-- | Lib/fontTools/subset/cff.py | 66 |
1 files changed, 48 insertions, 18 deletions
diff --git a/Lib/fontTools/subset/cff.py b/Lib/fontTools/subset/cff.py index 96dc3210..f01dfe67 100644 --- a/Lib/fontTools/subset/cff.py +++ b/Lib/fontTools/subset/cff.py @@ -352,28 +352,44 @@ class _DehintingT2Decompiler(psCharStrings.T2WidthExtractor): if subr_hints.status == 0: hints.last_hint = index else: - hints.last_hint = index - 2 # Leave the subr call in + hints.last_hint = index - 2 # Leave the subr call in elif subr_hints.status == 0: hints.deletions.append(index) hints.status = max(hints.status, subr_hints.status) +class StopHintCountEvent(Exception): + pass + + + + class _DesubroutinizingT2Decompiler(psCharStrings.SimpleT2Decompiler): + stop_hintcount_ops = ("op_hstem", "op_vstem", "op_rmoveto", "op_hmoveto", + "op_vmoveto") def __init__(self, localSubrs, globalSubrs, private=None): - psCharStrings.SimpleT2Decompiler.__init__(self, - localSubrs, - globalSubrs, private) + psCharStrings.SimpleT2Decompiler.__init__(self, localSubrs, globalSubrs, + private) def execute(self, charString): + self.need_hintcount = True # until proven otherwise + for op_name in self.stop_hintcount_ops: + setattr(self, op_name, self.stop_hint_count) + if hasattr(charString, '_desubroutinized'): + if self.need_hintcount and self.callingStack: + try: + psCharStrings.SimpleT2Decompiler.execute(self, charString) + except StopHintCountEvent: + del self.callingStack[-1] return charString._patches = [] psCharStrings.SimpleT2Decompiler.execute(self, charString) desubroutinized = charString.program[:] - for idx,expansion in reversed (charString._patches): + for idx, expansion in reversed(charString._patches): assert idx >= 2 assert desubroutinized[idx - 1] in ['callsubr', 'callgsubr'], desubroutinized[idx - 1] assert type(desubroutinized[idx - 2]) == int @@ -401,9 +417,23 @@ class _DesubroutinizingT2Decompiler(psCharStrings.SimpleT2Decompiler): psCharStrings.SimpleT2Decompiler.op_callgsubr(self, index) self.processSubr(index, subr) + def stop_hint_count(self, *args): + self.need_hintcount = False + for op_name in self.stop_hintcount_ops: + setattr(self, op_name, None) + cs = self.callingStack[-1] + if hasattr(cs, '_desubroutinized'): + raise StopHintCountEvent() + + def op_hintmask(self, index): + psCharStrings.SimpleT2Decompiler.op_hintmask(self, index) + if self.need_hintcount: + self.stop_hint_count() + def processSubr(self, index, subr): cs = self.callingStack[-1] - cs._patches.append((index, subr._desubroutinized)) + if not hasattr(cs, '_desubroutinized'): + cs._patches.append((index, subr._desubroutinized)) @_add_method(ttLib.getTableClass('CFF ')) @@ -425,16 +455,12 @@ def prune_post_subset(self, ttfFont, options): # Desubroutinize if asked for if options.desubroutinize: self.desubroutinize() - else: - for fontname in cff.keys(): - font = cff[fontname] - self.remove_unused_subroutines() # Drop hints if not needed if not options.hinting: self.remove_hints() - - + elif not options.desubroutinize: + self.remove_unused_subroutines() return True @@ -458,9 +484,7 @@ def desubroutinize(self): decompiler.execute(c) c.program = c._desubroutinized del c._desubroutinized - # Delete All the Subrs!!! - if font.GlobalSubrs: - del font.GlobalSubrs + # Delete all the local subrs if hasattr(font, 'FDArray'): for fd in font.FDArray: pd = fd.Private @@ -468,7 +492,14 @@ def desubroutinize(self): del pd.Subrs if 'Subrs' in pd.rawDict: del pd.rawDict['Subrs'] - self.remove_unused_subroutines() + else: + pd = font.Private + if hasattr(pd, 'Subrs'): + del pd.Subrs + if 'Subrs' in pd.rawDict: + del pd.rawDict['Subrs'] + # as well as the global subrs + cff.GlobalSubrs.clear() @_add_method(ttLib.getTableClass('CFF ')) @@ -506,7 +537,7 @@ def remove_hints(self): for charstring in css: charstring.drop_hints() del css - + # Drop font-wide hinting values all_privs = [] if hasattr(font, 'FDArray'): @@ -590,4 +621,3 @@ def remove_unused_subroutines(self): # Cleanup for subrs in all_subrs: del subrs._used, subrs._old_bias, subrs._new_bias - |