Speed up perimeterPen
It's still too slow, but an improvement. Also, remove duplicate copy from symfont.
This commit is contained in:
parent
71fb49962a
commit
56c27f45c9
@ -3,7 +3,7 @@
|
||||
from __future__ import print_function, division, absolute_import
|
||||
from fontTools.misc.py23 import *
|
||||
from fontTools.pens.basePen import BasePen
|
||||
from fontTools.misc.bezierTools import splitCubicAtT
|
||||
from fontTools.misc.bezierTools import splitQuadraticAtT, splitCubicAtT
|
||||
import math
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ class PerimeterPen(BasePen):
|
||||
def __init__(self, glyphset=None, tolerance=0.005):
|
||||
BasePen.__init__(self, glyphset)
|
||||
self.value = 0
|
||||
self._mult = 1. + tolerance
|
||||
self._mult = 1.+1.5*tolerance # The 1.5 is a empirical hack; no math
|
||||
|
||||
def _moveTo(self, p0):
|
||||
self.__startPoint = p0
|
||||
@ -25,15 +25,26 @@ class PerimeterPen(BasePen):
|
||||
p0 = self._getCurrentPoint()
|
||||
self.value += distance(p0, p1)
|
||||
|
||||
def _addQuadratic(self, p0, p1, p2):
|
||||
arch = distance(p0, p2)
|
||||
box = distance(p0, p1) + distance(p1, p2)
|
||||
if arch * self._mult >= box:
|
||||
self.value += (arch + box) * .5
|
||||
else:
|
||||
for c in splitQuadraticAtT(p0,p1,p2,.25,.5,.75):
|
||||
self._addQuadratic(*c)
|
||||
def _addCubic(self, p0, p1, p2, p3):
|
||||
arch = distance(p0, p3)
|
||||
box = distance(p0, p1) + distance(p1, p2) + distance(p2, p3)
|
||||
if arch * self._mult >= box:
|
||||
self.value += (arch + box) * .5
|
||||
else:
|
||||
for c in splitCubicAtT(p0, p1, p2, p3, .5):
|
||||
for c in splitCubicAtT(p0,p1,p2,p3,.2,.4,.6,.8):
|
||||
self._addCubic(*c)
|
||||
|
||||
def _qCurveToOne(self, p1, p2):
|
||||
p0 = self._getCurrentPoint()
|
||||
self._addQuadratic(p0, p1, p2)
|
||||
def _curveToOne(self, p1, p2, p3):
|
||||
p0 = self._getCurrentPoint()
|
||||
self._addCubic(p0, p1, p2, p3)
|
||||
|
@ -14,8 +14,9 @@ import sympy as sp
|
||||
import math
|
||||
from fontTools.pens.basePen import BasePen
|
||||
from fontTools.pens.transformPen import TransformPen
|
||||
from fontTools.pens.perimeterPen import PerimeterPen
|
||||
from fontTools.misc.transform import Scale
|
||||
from fontTools.misc.bezierTools import splitCubicAtT
|
||||
from fontTools.misc.bezierTools import splitQuadraticAtT, splitCubicAtT
|
||||
from functools import partial
|
||||
|
||||
n = 3 # Max Bezier degree; 3 for cubic, 2 for quadratic
|
||||
@ -109,33 +110,6 @@ Moment2XYPen = partial(GreenPen, func=x*y)
|
||||
def distance(p0, p1):
|
||||
return math.hypot(p0[0] - p1[0], p0[1] - p1[1])
|
||||
|
||||
class PerimeterPen(BasePen):
|
||||
|
||||
def __init__(self, tolerance=0.005, glyphset=None):
|
||||
BasePen.__init__(self, glyphset)
|
||||
self.value = 0
|
||||
self._mult = 1.+tolerance
|
||||
|
||||
def _moveTo(self, p0):
|
||||
pass
|
||||
|
||||
def _lineTo(self, p1):
|
||||
p0 = self._getCurrentPoint()
|
||||
self.value += distance(p0, p1)
|
||||
|
||||
def _addCubic(self, p0, p1, p2, p3):
|
||||
arch = distance(p0, p3)
|
||||
box = distance(p0, p1) + distance(p1, p2) + distance(p2, p3)
|
||||
if arch * self._mult >= box:
|
||||
self.value += (arch + box) * .5
|
||||
else:
|
||||
for c in splitCubicAtT(p0,p1,p2,p3,.5):
|
||||
self._addCubic(*c)
|
||||
|
||||
def _curveToOne(self, p1, p2, p3):
|
||||
p0 = self._getCurrentPoint()
|
||||
self._addCubic(p0, p1, p2, p3)
|
||||
|
||||
class GlyphStatistics(object):
|
||||
|
||||
def __init__(self, glyph, transform=None, glyphset=None):
|
||||
|
Loading…
x
Reference in New Issue
Block a user