diff options
Diffstat (limited to 'Lib/fontTools/pens/perimeterPen.py')
-rw-r--r-- | Lib/fontTools/pens/perimeterPen.py | 101 |
1 files changed, 56 insertions, 45 deletions
diff --git a/Lib/fontTools/pens/perimeterPen.py b/Lib/fontTools/pens/perimeterPen.py index 9a09cb8f..efb2b2d1 100644 --- a/Lib/fontTools/pens/perimeterPen.py +++ b/Lib/fontTools/pens/perimeterPen.py @@ -2,7 +2,12 @@ """Calculate the perimeter of a glyph.""" from fontTools.pens.basePen import BasePen -from fontTools.misc.bezierTools import approximateQuadraticArcLengthC, calcQuadraticArcLengthC, approximateCubicArcLengthC, calcCubicArcLengthC +from fontTools.misc.bezierTools import ( + approximateQuadraticArcLengthC, + calcQuadraticArcLengthC, + approximateCubicArcLengthC, + calcCubicArcLengthC, +) import math @@ -10,49 +15,55 @@ __all__ = ["PerimeterPen"] def _distance(p0, p1): - return math.hypot(p0[0] - p1[0], p0[1] - p1[1]) + return math.hypot(p0[0] - p1[0], p0[1] - p1[1]) -class PerimeterPen(BasePen): - - def __init__(self, glyphset=None, tolerance=0.005): - BasePen.__init__(self, glyphset) - self.value = 0 - self.tolerance = tolerance - - # Choose which algorithm to use for quadratic and for cubic. - # Quadrature is faster but has fixed error characteristic with no strong - # error bound. The cutoff points are derived empirically. - self._addCubic = self._addCubicQuadrature if tolerance >= 0.0015 else self._addCubicRecursive - self._addQuadratic = self._addQuadraticQuadrature if tolerance >= 0.00075 else self._addQuadraticExact - - def _moveTo(self, p0): - self.__startPoint = p0 - - def _closePath(self): - p0 = self._getCurrentPoint() - if p0 != self.__startPoint: - self._lineTo(self.__startPoint) - - def _lineTo(self, p1): - p0 = self._getCurrentPoint() - self.value += _distance(p0, p1) - def _addQuadraticExact(self, c0, c1, c2): - self.value += calcQuadraticArcLengthC(c0, c1, c2) - - def _addQuadraticQuadrature(self, c0, c1, c2): - self.value += approximateQuadraticArcLengthC(c0, c1, c2) - - def _qCurveToOne(self, p1, p2): - p0 = self._getCurrentPoint() - self._addQuadratic(complex(*p0), complex(*p1), complex(*p2)) - - def _addCubicRecursive(self, c0, c1, c2, c3): - self.value += calcCubicArcLengthC(c0, c1, c2, c3, self.tolerance) - - def _addCubicQuadrature(self, c0, c1, c2, c3): - self.value += approximateCubicArcLengthC(c0, c1, c2, c3) - - def _curveToOne(self, p1, p2, p3): - p0 = self._getCurrentPoint() - self._addCubic(complex(*p0), complex(*p1), complex(*p2), complex(*p3)) +class PerimeterPen(BasePen): + def __init__(self, glyphset=None, tolerance=0.005): + BasePen.__init__(self, glyphset) + self.value = 0 + self.tolerance = tolerance + + # Choose which algorithm to use for quadratic and for cubic. + # Quadrature is faster but has fixed error characteristic with no strong + # error bound. The cutoff points are derived empirically. + self._addCubic = ( + self._addCubicQuadrature if tolerance >= 0.0015 else self._addCubicRecursive + ) + self._addQuadratic = ( + self._addQuadraticQuadrature + if tolerance >= 0.00075 + else self._addQuadraticExact + ) + + def _moveTo(self, p0): + self.__startPoint = p0 + + def _closePath(self): + p0 = self._getCurrentPoint() + if p0 != self.__startPoint: + self._lineTo(self.__startPoint) + + def _lineTo(self, p1): + p0 = self._getCurrentPoint() + self.value += _distance(p0, p1) + + def _addQuadraticExact(self, c0, c1, c2): + self.value += calcQuadraticArcLengthC(c0, c1, c2) + + def _addQuadraticQuadrature(self, c0, c1, c2): + self.value += approximateQuadraticArcLengthC(c0, c1, c2) + + def _qCurveToOne(self, p1, p2): + p0 = self._getCurrentPoint() + self._addQuadratic(complex(*p0), complex(*p1), complex(*p2)) + + def _addCubicRecursive(self, c0, c1, c2, c3): + self.value += calcCubicArcLengthC(c0, c1, c2, c3, self.tolerance) + + def _addCubicQuadrature(self, c0, c1, c2, c3): + self.value += approximateCubicArcLengthC(c0, c1, c2, c3) + + def _curveToOne(self, p1, p2, p3): + p0 = self._getCurrentPoint() + self._addCubic(complex(*p0), complex(*p1), complex(*p2), complex(*p3)) |