This repository has been archived on 2025-10-02. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
inter-font/misc/pylib/robofab/misc/test.py
Rasmus Andersson 8234b62ab7 Speeds up font compilation by around 200%
Cython is used to compile some hot paths into native Python extensions.
These hot paths were identified through running ufocompile with the hotshot
profiler and then converting file by file to Cython, starting with the "hottest"
paths and continuing until returns were deminishing. This means that only a few
Python files were converted to Cython.

Closes #23
Closes #20 (really this time)
2017-09-04 11:12:34 -04:00

119 lines
No EOL
3.4 KiB
Python

"""
doc test requires fontTools to compare and defon to make the test font.
"""
import random
from fontTools.pens.basePen import BasePen
from fontTools.misc import arrayTools
from fontTools.misc import bezierTools
import robofab.misc.arrayTools as noNumpyArrayTools
import robofab.misc.bezierTools as noNumpyBezierTools
def drawMoveTo(pen, maxBox):
pen.moveTo((maxBox*random.random(), maxBox*random.random()))
def drawLineTo(pen, maxBox):
pen.lineTo((maxBox*random.random(), maxBox*random.random()))
def drawCurveTo(pen, maxBox):
pen.curveTo((maxBox*random.random(), maxBox*random.random()),
(maxBox*random.random(), maxBox*random.random()),
(maxBox*random.random(), maxBox*random.random()))
def drawClosePath(pen):
pen.closePath()
def createRandomFont():
from defcon import Font
maxGlyphs = 1000
maxContours = 10
maxSegments = 10
maxBox = 700
drawCallbacks = [drawLineTo, drawCurveTo]
f = Font()
for i in range(maxGlyphs):
name = "%s" %i
f.newGlyph(name)
g = f[name]
g.width = maxBox
pen = g.getPen()
for c in range(maxContours):
drawMoveTo(pen, maxBox)
for s in range(maxSegments):
random.choice(drawCallbacks)(pen, maxBox)
drawClosePath(pen)
return f
class BoundsPen(BasePen):
def __init__(self, glyphSet, at, bt):
BasePen.__init__(self, glyphSet)
self.bounds = None
self._start = None
self._arrayTools = at
self._bezierTools = bt
def _moveTo(self, pt):
self._start = pt
def _addMoveTo(self):
if self._start is None:
return
bounds = self.bounds
if bounds:
self.bounds = self._arrayTools.updateBounds(bounds, self._start)
else:
x, y = self._start
self.bounds = (x, y, x, y)
self._start = None
def _lineTo(self, pt):
self._addMoveTo()
self.bounds = self._arrayTools.updateBounds(self.bounds, pt)
def _curveToOne(self, bcp1, bcp2, pt):
self._addMoveTo()
bounds = self.bounds
bounds = self._arrayTools.updateBounds(bounds, pt)
if not self._arrayTools.pointInRect(bcp1, bounds) or not self._arrayTools.pointInRect(bcp2, bounds):
bounds = self._arrayTools.unionRect(bounds, self._bezierTools.calcCubicBounds(
self._getCurrentPoint(), bcp1, bcp2, pt))
self.bounds = bounds
def _qCurveToOne(self, bcp, pt):
self._addMoveTo()
bounds = self.bounds
bounds = self._arrayTools.updateBounds(bounds, pt)
if not self._arrayTools.pointInRect(bcp, bounds):
bounds = self._arrayToolsunionRect(bounds, self._bezierTools.calcQuadraticBounds(
self._getCurrentPoint(), bcp, pt))
self.bounds = bounds
def _testFont(font):
succes = True
for glyph in font:
fontToolsBoundsPen = BoundsPen(font, arrayTools, bezierTools)
glyph.draw(fontToolsBoundsPen)
noNumpyBoundsPen = BoundsPen(font, noNumpyArrayTools, noNumpyBezierTools)
glyph.draw(noNumpyBoundsPen)
if fontToolsBoundsPen.bounds != noNumpyBoundsPen.bounds:
succes = False
return succes
def testCompareAgainstFontTools():
"""
>>> font = createRandomFont()
>>> _testFont(font)
True
"""
if __name__ == "__main__":
import doctest
doctest.testmod()