[cffLib] Recalc CFF's FontBBox when compiling

This commit is contained in:
Masaya Nakamura 2017-05-18 17:58:39 +09:00
parent a68bfc2458
commit b84ee6744d
2 changed files with 68 additions and 0 deletions

View File

@ -4,6 +4,7 @@ from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
from fontTools.misc import sstruct
from fontTools.misc import psCharStrings
from fontTools.misc.arrayTools import unionRect
from fontTools.misc.textTools import safeEval
from fontTools.ttLib import TTFont
from fontTools.ttLib.tables.otBase import OTTableWriter
@ -101,6 +102,11 @@ class CFFFontSet(object):
# use current 'major' value to determine output format
assert self.major in (1, 2), "Unknown CFF format"
isCFF2 = self.major == 2
if otFont.recalcBBoxes and not isCFF2:
for topDict in self.topDictIndex:
topDict.recalcFontBBox()
if not isCFF2:
strings = IndexedStrings()
else:
@ -2313,6 +2319,20 @@ class TopDict(BaseDict):
progress.increment(0) # update
i = i + 1
def recalcFontBBox(self):
initialBounds = (float('inf'), float('inf'), float('-inf'), float('-inf'))
bounds = initialBounds
for charString in self.CharStrings.values():
if not hasattr(charString, 'bounds'):
charString.recalcBounds()
if charString.bounds is not None:
bounds = unionRect(bounds, charString.bounds)
if bounds == initialBounds:
self.FontBBox = self.defaults['FontBBox'][:]
else:
self.FontBBox = [round(v) for v in bounds]
class FontDict(BaseDict):
#

View File

@ -0,0 +1,48 @@
from __future__ import print_function, division, absolute_import
from fontTools.cffLib import TopDict, PrivateDict, CharStrings
from fontTools.misc.testTools import parseXML
import unittest
class TopDictTest(unittest.TestCase):
def test_recalcFontBBox(self):
topDict = TopDict()
topDict.CharStrings = CharStrings(None, None, None, PrivateDict(), None, None)
topDict.CharStrings.fromXML(None, None, parseXML("""
<CharString name=".notdef">
endchar
</CharString>
<CharString name="foo"><!-- [100, -100, 300, 100] -->
100 -100 rmoveto 200 hlineto 200 vlineto -200 hlineto endchar
</CharString>
<CharString name="bar"><!-- [0, 0, 200, 200] -->
0 0 rmoveto 200 hlineto 200 vlineto -200 hlineto endchar
</CharString>
<CharString name="baz"><!-- [-55.5, -55.5, 55.5, 55.5] -->
-55.5 -55.5 rmoveto 111 hlineto 111 vlineto -111 hlineto endchar
</CharString>
"""))
topDict.recalcFontBBox()
self.assertEqual(topDict.FontBBox, [-56, -100, 300, 200])
def test_recalcFontBBox_empty(self):
topDict = TopDict()
topDict.CharStrings = CharStrings(None, None, None, PrivateDict(), None, None)
topDict.CharStrings.fromXML(None, None, parseXML("""
<CharString name=".notdef">
endchar
</CharString>
<CharString name="space">
123 endchar
</CharString>
"""))
topDict.recalcFontBBox()
self.assertEqual(topDict.FontBBox, [0, 0, 0, 0])
if __name__ == "__main__":
import sys
sys.exit(unittest.main())