Don't cache charString bounds

https://github.com/fonttools/fonttools/pull/970#discussion_r117903692
This commit is contained in:
Masaya Nakamura 2017-08-01 10:35:39 +09:00
parent 22dfcd94a1
commit 3708f2c8d3
5 changed files with 25 additions and 30 deletions

View File

@ -2320,20 +2320,19 @@ class TopDict(BaseDict):
i = i + 1 i = i + 1
def recalcFontBBox(self): def recalcFontBBox(self):
bounds = None fontBBox = None
for charString in self.CharStrings.values(): for charString in self.CharStrings.values():
if not hasattr(charString, 'bounds'): bounds = charString.calcBounds()
charString.recalcBounds() if bounds is not None:
if charString.bounds is not None: if fontBBox is not None:
if bounds is not None: fontBBox = unionRect(fontBBox, bounds)
bounds = unionRect(bounds, charString.bounds)
else: else:
bounds = charString.bounds fontBBox = bounds
if bounds is None: if fontBBox is None:
self.FontBBox = self.defaults['FontBBox'][:] self.FontBBox = self.defaults['FontBBox'][:]
else: else:
self.FontBBox = list(intRect(bounds)) self.FontBBox = list(intRect(fontBBox))
class FontDict(BaseDict): class FontDict(BaseDict):

View File

@ -978,10 +978,10 @@ class T2CharString(object):
extractor.execute(self) extractor.execute(self)
self.width = extractor.width self.width = extractor.width
def recalcBounds(self): def calcBounds(self):
boundsPen = BoundsPen(None) boundsPen = BoundsPen(None)
self.draw(boundsPen) self.draw(boundsPen)
self.bounds = boundsPen.bounds return boundsPen.bounds
def check_program(self, program, isCFF2=False): def check_program(self, program, isCFF2=False):
if isCFF2: if isCFF2:

View File

@ -65,11 +65,9 @@ class table__h_h_e_a(DefaultTable.DefaultTable):
topDict = ttFont['CFF '].cff.topDictIndex[0] topDict = ttFont['CFF '].cff.topDictIndex[0]
for name in ttFont.getGlyphOrder(): for name in ttFont.getGlyphOrder():
cs = topDict.CharStrings[name] cs = topDict.CharStrings[name]
if not hasattr(cs, 'bounds'): bounds = cs.calcBounds()
cs.recalcBounds() if bounds is not None:
if cs.bounds is None: boundsWidthDict[name] = math.ceil(bounds[2]) - math.floor(bounds[0])
continue
boundsWidthDict[name] = math.ceil(cs.bounds[2]) - math.floor(cs.bounds[0])
if boundsWidthDict: if boundsWidthDict:
minLeftSideBearing = float('inf') minLeftSideBearing = float('inf')

View File

@ -64,11 +64,9 @@ class table__v_h_e_a(DefaultTable.DefaultTable):
topDict = ttFont['CFF '].cff.topDictIndex[0] topDict = ttFont['CFF '].cff.topDictIndex[0]
for name in ttFont.getGlyphOrder(): for name in ttFont.getGlyphOrder():
cs = topDict.CharStrings[name] cs = topDict.CharStrings[name]
if not hasattr(cs, 'bounds'): bounds = cs.calcBounds()
cs.recalcBounds() if bounds is not None:
if cs.bounds is None: boundsHeightDict[name] = math.ceil(bounds[3]) - math.floor(bounds[1])
continue
boundsHeightDict[name] = math.ceil(cs.bounds[3]) - math.floor(cs.bounds[1])
if boundsHeightDict: if boundsHeightDict:
minTopSideBearing = float('inf') minTopSideBearing = float('inf')

View File

@ -11,20 +11,20 @@ class T2CharStringTest(unittest.TestCase):
def stringToT2CharString(cls, string): def stringToT2CharString(cls, string):
return T2CharString(program=stringToProgram(string), private=PrivateDict()) return T2CharString(program=stringToProgram(string), private=PrivateDict())
def test_recalcBounds_empty(self): def test_calcBounds_empty(self):
cs = self.stringToT2CharString("endchar") cs = self.stringToT2CharString("endchar")
cs.recalcBounds() bounds = cs.calcBounds()
self.assertEqual(cs.bounds, None) self.assertEqual(bounds, None)
def test_recalcBounds_line(self): def test_calcBounds_line(self):
cs = self.stringToT2CharString("100 100 rmoveto 40 10 rlineto -20 50 rlineto endchar") cs = self.stringToT2CharString("100 100 rmoveto 40 10 rlineto -20 50 rlineto endchar")
cs.recalcBounds() bounds = cs.calcBounds()
self.assertEqual(cs.bounds, (100, 100, 140, 160)) self.assertEqual(bounds, (100, 100, 140, 160))
def test_recalcBounds_curve(self): def test_calcBounds_curve(self):
cs = self.stringToT2CharString("100 100 rmoveto -50 -150 200 0 -50 150 rrcurveto endchar") cs = self.stringToT2CharString("100 100 rmoveto -50 -150 200 0 -50 150 rrcurveto endchar")
cs.recalcBounds() bounds = cs.calcBounds()
self.assertEqual(cs.bounds, (91.90524980688875, -12.5, 208.09475019311125, 100)) self.assertEqual(bounds, (91.90524980688875, -12.5, 208.09475019311125, 100))
if __name__ == "__main__": if __name__ == "__main__":