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 def __init__(self, glyphset=None): 11 BasePen.__init__(self, glyphset) 12 self.value = 0 13 14 def _moveTo(self, p0): 15 self._p0 = self._startPoint = p0 16 17 def _lineTo(self, p1): 18 x0, y0 = self._p0 19 x1, y1 = p1 20 self.value -= (x1 - x0) * (y1 + y0) * 0.5 21 self._p0 = p1 22 23 def _qCurveToOne(self, p1, p2): 24 # https://github.com/Pomax/bezierinfo/issues/44 25 p0 = self._p0 26 x0, y0 = p0[0], p0[1] 27 x1, y1 = p1[0] - x0, p1[1] - y0 28 x2, y2 = p2[0] - x0, p2[1] - y0 29 self.value -= (x2 * y1 - x1 * y2) / 3 30 self._lineTo(p2) 31 self._p0 = p2 32 33 def _curveToOne(self, p1, p2, p3): 34 # https://github.com/Pomax/bezierinfo/issues/44 35 p0 = self._p0 36 x0, y0 = p0[0], p0[1] 37 x1, y1 = p1[0] - x0, p1[1] - y0 38 x2, y2 = p2[0] - x0, p2[1] - y0 39 x3, y3 = p3[0] - x0, p3[1] - y0 40 self.value -= (x1 * (-y2 - y3) + x2 * (y1 - 2 * y3) + x3 * (y1 + 2 * y2)) * 0.15 41 self._lineTo(p3) 42 self._p0 = p3 43 44 def _closePath(self): 45 self._lineTo(self._startPoint) 46 del self._p0, self._startPoint 47 48 def _endPath(self): 49 if self._p0 != self._startPoint: 50 # Area is not defined for open contours. 51 raise NotImplementedError 52 del self._p0, self._startPoint 53