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