1 """Calculate the area of a glyph.""" 2 3 from __future__ import print_function, division, absolute_import 4 from fontTools.misc.py23 import * 5 from fontTools.pens.basePen import BasePen 6 7 8 __all__ = ["AreaPen"] 9 10 11 class AreaPen(BasePen): 12 13 def __init__(self, glyphset=None): 14 BasePen.__init__(self, glyphset) 15 self.value = 0 16 17 def _moveTo(self, p0): 18 self._p0 = self._startPoint = p0 19 20 def _lineTo(self, p1): 21 x0, y0 = self._p0 22 x1, y1 = p1 23 self.value -= (x1 - x0) * (y1 + y0) * .5 24 self._p0 = p1 25 26 def _qCurveToOne(self, p1, p2): 27 # https://github.com/Pomax/bezierinfo/issues/44 28 p0 = self._p0 29 x0, y0 = p0[0], p0[1] 30 x1, y1 = p1[0] - x0, p1[1] - y0 31 x2, y2 = p2[0] - x0, p2[1] - y0 32 self.value -= (x2 * y1 - x1 * y2) / 3 33 self._lineTo(p2) 34 self._p0 = p2 35 36 def _curveToOne(self, p1, p2, p3): 37 # https://github.com/Pomax/bezierinfo/issues/44 38 p0 = self._p0 39 x0, y0 = p0[0], p0[1] 40 x1, y1 = p1[0] - x0, p1[1] - y0 41 x2, y2 = p2[0] - x0, p2[1] - y0 42 x3, y3 = p3[0] - x0, p3[1] - y0 43 self.value -= ( 44 x1 * ( - y2 - y3) + 45 x2 * (y1 - 2*y3) + 46 x3 * (y1 + 2*y2 ) 47 ) * 0.15 48 self._lineTo(p3) 49 self._p0 = p3 50 51 def _closePath(self): 52 self._lineTo(self._startPoint) 53 del self._p0, self._startPoint 54 55 def _endPath(self): 56 if self._p0 != self._startPoint: 57 # Area is not defined for open contours. 58 raise NotImplementedError 59 del self._p0, self._startPoint 60