[subset] draw charstrings with NullPen to set the width before dropping hints

This is the same patch as PR #606

Quoting myself:
```
It seems that the horizontal advance of hinted charstrings gets lost when the CFF hinting is stripped with '--no-hinting' option...

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:

c63fea0f8f/Lib/fontTools/subset/__init__.py (L1928)

Hence, we must 'draw' the charstring (with a NullPen) before stripping the hints.
```

Now this method fixes the issue (advances are kept) when doing _both_ --no-hinting and --desubroutinize (the test_no_hinting_desubroutinize should now pass, while it was failing before).

However, when one only does does --no-hinting, this method raises an error:

AttributeError: 'NoneType' object has no attribute 'nominalWidthX'
Lib/fontTools/misc/psCharStrings.py:282: AttributeError

(this is reflected in the failing `test_no_hinting_CFF`)
This commit is contained in:
Cosimo Lupo 2017-01-14 14:45:35 +00:00
parent 99303de5c5
commit 3b7124757c
No known key found for this signature in database
GPG Key ID: B61AAAD0B53A6419

View File

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