subset: 'draw' charstrings to set 'width' before calling 'drop_hints'

the horizontal advance of hinted charstrings gets lost when the CFF hinting
is stripped with '--no-hinting' option, as noted by @miguelsousa here:

https://github.com/behdad/fonttools/issues/343#issuecomment-156234918

The reason is T2CharString objects only get assigned a 'witdh' attribute
after their 'draw' method is called.

The subsetter's 'drop_hints' function attempts to insert the width back
at the beginning of the de-hinted charstring's program, but can do that
only if the charstring does have a 'width' attribute:

https://github.com/behdad/fonttools/blob/master/Lib/fontTools/subset/__init__.py#L1908
This commit is contained in:
Cosimo Lupo 2016-05-15 22:53:42 +01:00
parent c719da5bca
commit ddfa48ea7c

View File

@ -7,7 +7,7 @@ from fontTools.misc.py23 import *
from fontTools import ttLib from fontTools import ttLib
from fontTools.ttLib.tables import otTables from fontTools.ttLib.tables import otTables
from fontTools.misc import psCharStrings from fontTools.misc import psCharStrings
from fontTools.pens.boundsPen import BoundsPen from fontTools.pens.basePen import NullPen
from fontTools.misc.loggingTools import Timer from fontTools.misc.loggingTools import Timer
import sys import sys
import struct import struct
@ -1847,8 +1847,8 @@ def prune_pre_subset(self, font, options):
private = font.Private private = font.Private
dfltWdX = private.defaultWidthX dfltWdX = private.defaultWidthX
nmnlWdX = private.nominalWidthX nmnlWdX = private.nominalWidthX
pen = BoundsPen(None) pen = NullPen()
c.draw(pen) # this will set the charstring's width c.draw(pen) # this will set the charstring's width
if c.width != dfltWdX: if c.width != dfltWdX:
c.program = [c.width - nmnlWdX, 'endchar'] c.program = [c.width - nmnlWdX, 'endchar']
else: else:
@ -2207,7 +2207,9 @@ def prune_post_subset(self, options):
subrs = getattr(c.private, "Subrs", []) subrs = getattr(c.private, "Subrs", [])
decompiler = _DehintingT2Decompiler(css, subrs, c.globalSubrs) decompiler = _DehintingT2Decompiler(css, subrs, c.globalSubrs)
decompiler.execute(c) decompiler.execute(c)
pen = NullPen()
for charstring in css: for charstring in css:
charstring.draw(pen) # this will set the charstring's width
charstring.drop_hints() charstring.drop_hints()
del css del css