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