[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.py23 import *
from fontTools.misc import sstruct from fontTools.misc import sstruct
from fontTools.misc import psCharStrings from fontTools.misc import psCharStrings
from fontTools.misc.arrayTools import unionRect
from fontTools.misc.textTools import safeEval from fontTools.misc.textTools import safeEval
from fontTools.ttLib import TTFont from fontTools.ttLib import TTFont
from fontTools.ttLib.tables.otBase import OTTableWriter from fontTools.ttLib.tables.otBase import OTTableWriter
@ -101,6 +102,11 @@ class CFFFontSet(object):
# use current 'major' value to determine output format # use current 'major' value to determine output format
assert self.major in (1, 2), "Unknown CFF format" assert self.major in (1, 2), "Unknown CFF format"
isCFF2 = self.major == 2 isCFF2 = self.major == 2
if otFont.recalcBBoxes and not isCFF2:
for topDict in self.topDictIndex:
topDict.recalcFontBBox()
if not isCFF2: if not isCFF2:
strings = IndexedStrings() strings = IndexedStrings()
else: else:
@ -2313,6 +2319,20 @@ class TopDict(BaseDict):
progress.increment(0) # update progress.increment(0) # update
i = i + 1 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): 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())