Merge pull request #34 from googlei18n/update-tests

Add travis config file
This commit is contained in:
James Godfrey-Kittle 2016-07-27 13:50:59 -07:00 committed by GitHub
commit 0479616451
8 changed files with 145 additions and 85 deletions

15
.travis.yml Normal file
View File

@ -0,0 +1,15 @@
sudo: false
language: python
python:
- "3.4"
branches:
only:
- master
install:
- python setup.py install
- pip install git+https://github.com/behdad/fonttools
- pip install git+https://github.com/unified-font-object/ufoLib
script:
- python setup.py test

View File

@ -234,4 +234,4 @@ def curves_to_quadratic(curves, max_errors):
for c, s, max_err in zip(curves, splines, max_errors):
if s is None:
raise ApproxNotFoundError(c)
return [[(s.real,s.imag) for s in spline] for spline in splines], None
return [[(s.real,s.imag) for s in spline] for spline in splines]

View File

@ -72,7 +72,7 @@ class Cu2QuPen(AbstractPen):
def _curve_to_quadratic(self, pt1, pt2, pt3):
curve = (self.current_pt, pt1, pt2, pt3)
quadratic, _ = curve_to_quadratic(curve, self.max_err)
quadratic = curve_to_quadratic(curve, self.max_err)
if self.stats is not None:
n = str(len(quadratic))
self.stats[n] = self.stats.get(n, 0) + 1
@ -144,7 +144,7 @@ class Cu2QuPointPen(BasePointToSegmentPen):
on_curve, smooth, name, kwargs = sub_points[-1]
bcp1, bcp2 = sub_points[0][0], sub_points[1][0]
cubic = [prev_on_curve, bcp1, bcp2, on_curve]
quad, _ = curve_to_quadratic(cubic, self.max_err)
quad = curve_to_quadratic(cubic, self.max_err)
if self.stats is not None:
n = str(len(quad))
self.stats[n] = self.stats.get(n, 0) + 1

View File

@ -16,6 +16,7 @@
from __future__ import print_function, division, absolute_import
import collections
import math
import unittest
import random
@ -34,12 +35,18 @@ class CurveToQuadraticTest(unittest.TestCase):
random.seed(1)
curves = [generate_curve() for i in range(1000)]
cls.single_splines, cls.single_errors = zip(*[
curve_to_quadratic(c, MAX_ERR) for c in curves])
cls.single_splines = [
curve_to_quadratic(c, MAX_ERR) for c in curves]
cls.single_errors = [
cls.curve_spline_dist(c, s)
for c, s in zip(curves, cls.single_splines)]
cls.compat_splines, cls.compat_errors = zip(*[
curves_to_quadratic(curves[i:i + 3], [MAX_ERR] * 3)
for i in range(0, 300, 3)])
curve_groups = [curves[i:i + 3] for i in range(0, 300, 3)]
cls.compat_splines = [
curves_to_quadratic(c, [MAX_ERR] * 3) for c in curve_groups]
cls.compat_errors = [
[cls.curve_spline_dist(c, s) for c, s in zip(curve_group, splines)]
for curve_group, splines in zip(curve_groups, cls.compat_splines)]
cls.results = []
@ -60,13 +67,13 @@ class CurveToQuadraticTest(unittest.TestCase):
"""
expected = {
3: 5,
4: 31,
5: 74,
6: 228,
7: 416,
8: 242,
9: 4}
3: 6,
4: 26,
5: 82,
6: 232,
7: 360,
8: 266,
9: 28}
results = collections.defaultdict(int)
for spline in self.single_splines:
@ -79,10 +86,10 @@ class CurveToQuadraticTest(unittest.TestCase):
"""Test that conversion results are unchanged for multiple curves."""
expected = {
6: 3,
7: 34,
8: 62,
9: 1}
6: 11,
7: 35,
8: 49,
9: 5}
results = collections.defaultdict(int)
for splines in self.compat_splines:
@ -113,6 +120,60 @@ class CurveToQuadraticTest(unittest.TestCase):
self.assertLessEqual(error, MAX_ERR)
self.results.append(('compatible errors', results))
@classmethod
def curve_spline_dist(cls, bezier, spline, total_steps=20):
"""Max distance between a bezier and quadratic spline at sampled points."""
error = 0
n = len(spline) - 2
steps = total_steps // n
for i in range(0, n - 1):
p1 = spline[0] if i == 0 else p3
p2 = spline[i + 1]
if i < n - 1:
p3 = cls.lerp(spline[i + 1], spline[i + 2], 0.5)
else:
p3 = spline[n + 2]
segment = p1, p2, p3
for j in range(steps):
error = max(error, cls.dist(
cls.cubic_bezier_at(bezier, (j / steps + i) / n),
cls.quadratic_bezier_at(segment, j / steps)))
return error
@classmethod
def lerp(cls, p1, p2, t):
(x1, y1), (x2, y2) = p1, p2
return x1 + (x2 - x1) * t, y1 + (y2 - y1) * t
@classmethod
def dist(cls, p1, p2):
(x1, y1), (x2, y2) = p1, p2
return math.hypot(x1 - x2, y1 - y2)
@classmethod
def quadratic_bezier_at(cls, b, t):
(x1, y1), (x2, y2), (x3, y3) = b
_t = 1 - t
t2 = t * t
_t2 = _t * _t
_2_t_t = 2 * t * _t
return (_t2 * x1 + _2_t_t * x2 + t2 * x3,
_t2 * y1 + _2_t_t * y2 + t2 * y3)
@classmethod
def cubic_bezier_at(cls, b, t):
(x1, y1), (x2, y2), (x3, y3), (x4, y4) = b
_t = 1 - t
t2 = t * t
_t2 = _t * _t
t3 = t * t2
_t3 = _t * _t2
_3_t2_t = 3 * t2 * _t
_3_t_t2 = 3 * t * _t2
return (_t3 * x1 + _3_t_t2 * x2 + _3_t2_t * x3 + t3 * x4,
_t3 * y1 + _3_t_t2 * y2 + _3_t2_t * y3 + t3 * y4)
if __name__ == '__main__':
unittest.main()

View File

@ -6,8 +6,8 @@
<contour>
<point x="501" y="347" type="line"/>
<point x="456.5" y="370"/>
<point x="386.50000000000006" y="393.16666666666674"/>
<point x="320.5" y="401.0000000000001"/>
<point x="386.5" y="393.16666666666663"/>
<point x="320.5" y="401"/>
<point x="282" y="401" type="qcurve" smooth="yes"/>
<point x="214.5" y="401"/>
<point x="126.75" y="379.25"/>
@ -22,12 +22,12 @@
<point x="9" y="305.75"/>
<point x="9" y="335" type="qcurve" smooth="yes"/>
<point x="9" y="369"/>
<point x="61.83333333333333" y="424.8333333333333"/>
<point x="61.83333333333332" y="424.8333333333333"/>
<point x="154" y="458"/>
<point x="213" y="458" type="qcurve" smooth="yes"/>
<point x="237.375" y="458"/>
<point x="313.00520833333337" y="450.2916666666667"/>
<point x="401.2447916666667" y="433.20833333333337"/>
<point x="313.0052083333333" y="450.2916666666667"/>
<point x="401.2447916666667" y="433.2083333333333"/>
<point x="489.25" y="405.25"/>
<point x="526" y="385" type="qcurve"/>
</contour>
@ -37,27 +37,27 @@
<point x="591.5" y="692"/>
<point x="578" y="692" type="qcurve" smooth="yes"/>
<point x="544.3571428571429" y="692"/>
<point x="471.67614188532553" y="631.7033527696793"/>
<point x="398.9164237123422" y="527.9810495626823"/>
<point x="330.9234693877552" y="396.2091836734695"/>
<point x="272.54275996112733" y="251.76384839650146"/>
<point x="228.6197764820214" y="110.02113702623913"/>
<point x="204.00000000000009" y="-13.642857142857068"/>
<point x="471.67614188532553" y="631.7033527696792"/>
<point x="398.9164237123421" y="527.9810495626824"/>
<point x="330.9234693877551" y="396.2091836734695"/>
<point x="272.54275996112733" y="251.76384839650154"/>
<point x="228.6197764820214" y="110.0211370262391"/>
<point x="204.00000000000006" y="-13.64285714285704"/>
<point x="204" y="-58" type="qcurve" smooth="yes"/>
<point x="204" y="-82"/>
<point x="213.5" y="-107.25"/>
<point x="218" y="-114" type="qcurve"/>
<point x="197.75" y="-114"/>
<point x="151.36458333333334" y="-109.60416666666667"/>
<point x="110.13541666666666" y="-90.39583333333334"/>
<point x="110.13541666666667" y="-90.39583333333333"/>
<point x="84" y="-47"/>
<point x="84" y="-8" type="qcurve" smooth="yes"/>
<point x="84" y="34.64285714285714"/>
<point x="117.10762876579204" y="157.5352283770651"/>
<point x="176.77793974732754" y="300.39552964042764"/>
<point x="176.7779397473275" y="300.3955296404276"/>
<point x="257.04591836734687" y="447.1479591836734"/>
<point x="351.94655004859084" y="581.7167152575316"/>
<point x="455.5148202137997" y="688.0259961127306"/>
<point x="351.94655004859084" y="581.7167152575314"/>
<point x="455.5148202137998" y="688.0259961127308"/>
<point x="561.7857142857142" y="749.9999999999998"/>
<point x="613" y="750" type="qcurve" smooth="yes"/>
<point x="630.25" y="750"/>
@ -71,22 +71,4 @@
<point x="535" y="0" type="line"/>
</contour>
</outline>
<lib>
<dict>
<key>org.robofab.fontlab.guides</key>
<dict>
<key>hguides</key>
<array>
<dict>
<key>angle</key>
<integer>0</integer>
<key>position</key>
<integer>-180</integer>
</dict>
</array>
</dict>
<key>org.robofab.fontlab.mark</key>
<integer>80</integer>
</dict>
</lib>
</glyph>

View File

@ -6,15 +6,15 @@
<contour>
<point x="461" y="180" type="line"/>
<point x="443" y="147"/>
<point x="378.9166666666667" y="101.5"/>
<point x="306.50000000000006" y="78"/>
<point x="378.91666666666663" y="101.49999999999999"/>
<point x="306.5" y="78"/>
<point x="276" y="78" type="qcurve" smooth="yes"/>
<point x="225" y="78"/>
<point x="181" y="137"/>
<point x="181" y="179" type="qcurve" smooth="yes"/>
<point x="181" y="213.5"/>
<point x="206.65104166666669" y="289.3854166666667"/>
<point x="254.09895833333331" y="358.6145833333333"/>
<point x="206.65104166666666" y="289.3854166666667"/>
<point x="254.09895833333334" y="358.6145833333333"/>
<point x="319.875" y="409"/>
<point x="360" y="418" type="qcurve"/>
<point x="306" y="432.25"/>
@ -30,7 +30,8 @@
<point x="416" y="611.5"/>
<point x="390.75" y="556"/>
<point x="372" y="550" type="qcurve"/>
<point x="391.89473684210526" y="523"/>
<point x="385.2631578947368" y="532"/>
<point x="400.9298245614035" y="523"/>
<point x="419" y="523" type="qcurve" smooth="yes"/>
<point x="449" y="523"/>
<point x="493" y="582"/>
@ -38,24 +39,25 @@
<point x="493" y="688.5"/>
<point x="409.25" y="752"/>
<point x="350" y="752" type="qcurve" smooth="yes"/>
<point x="286" y="752"/>
<point x="187.16666666666657" y="687.4166666666667"/>
<point x="130.99999999999994" y="588.4999999999999"/>
<point x="302" y="752"/>
<point x="221.84375" y="714.4114583333334"/>
<point x="163.15625" y="651.8385416666666"/>
<point x="131" y="575.625"/>
<point x="131" y="537" type="qcurve" smooth="yes"/>
<point x="131" y="503.25"/>
<point x="159.75" y="440.25"/>
<point x="192" y="417" type="qcurve"/>
<point x="134.5" y="403"/>
<point x="51.58333333333333" y="319.58333333333337"/>
<point x="6.999999999999977" y="210.5"/>
<point x="51.58333333333333" y="319.58333333333326"/>
<point x="7" y="210.5"/>
<point x="7" y="158" type="qcurve" smooth="yes"/>
<point x="7" y="111"/>
<point x="45.66666666666666" y="30.83333333333333"/>
<point x="126.99999999999997" y="-18.000000000000014"/>
<point x="45.66666666666667" y="30.83333333333333"/>
<point x="127.00000000000001" y="-18"/>
<point x="191" y="-18" type="qcurve" smooth="yes"/>
<point x="250.5" y="-18"/>
<point x="365.41666666666663" y="26.833333333333336"/>
<point x="458" y="111"/>
<point x="365.4166666666667" y="26.833333333333336"/>
<point x="458" y="110.99999999999999"/>
<point x="484" y="170" type="qcurve"/>
</contour>
<component base="acute" xOffset="210" yOffset="250"/>

View File

@ -6,8 +6,8 @@
<contour>
<point x="771" y="183" type="line"/>
<point x="771" y="153"/>
<point x="778.1666666666665" y="83.58333333333334"/>
<point x="792" y="20.49999999999998"/>
<point x="778.1666666666665" y="83.58333333333333"/>
<point x="792" y="20.5"/>
<point x="802" y="0" type="qcurve"/>
<point x="1010" y="0" type="line"/>
<point x="1010" y="17" type="line"/>
@ -17,17 +17,17 @@
<point x="971" y="738" type="line"/>
<point x="971" y="859.5"/>
<point x="867.25" y="1021.25"/>
<point x="684.4999999999998" y="1101.9999999999995"/>
<point x="684.5" y="1102"/>
<point x="566" y="1102" type="qcurve" smooth="yes"/>
<point x="466.625" y="1102"/>
<point x="306.8385416666667" y="1045.9739583333335"/>
<point x="193.41145833333331" y="952.7760416666667"/>
<point x="306.8385416666667" y="1045.9739583333333"/>
<point x="193.41145833333334" y="952.7760416666666"/>
<point x="133" y="839.375"/>
<point x="133" y="782" type="qcurve"/>
<point x="333" y="782" type="line"/>
<point x="333" y="824.5"/>
<point x="388.08333333333337" y="898.9166666666667"/>
<point x="487.50000000000006" y="945"/>
<point x="388.0833333333333" y="898.9166666666665"/>
<point x="487.5" y="945"/>
<point x="554" y="945" type="qcurve" smooth="yes"/>
<point x="661.25" y="945"/>
<point x="771" y="833"/>
@ -37,17 +37,17 @@
<point x="804" y="661" type="line"/>
<point x="596" y="661" type="line"/>
<point x="448.5" y="661"/>
<point x="230.58333333333334" y="580.3333333333335"/>
<point x="111.00000000000004" y="421"/>
<point x="230.58333333333331" y="580.3333333333334"/>
<point x="111" y="421"/>
<point x="111" y="303" type="qcurve" smooth="yes"/>
<point x="111" y="213"/>
<point x="202.58333333333331" y="66.50000000000003"/>
<point x="368.49999999999994" y="-19.99999999999999"/>
<point x="202.58333333333334" y="66.5"/>
<point x="368.5" y="-20"/>
<point x="480" y="-20" type="qcurve" smooth="yes"/>
<point x="549.3000000000001" y="-20"/>
<point x="666.664" y="20.413000000000004"/>
<point x="760.4599999999999" y="86.76999999999998"/>
<point x="828.5760000000001" y="165.96700000000004"/>
<point x="760.4599999999999" y="86.77000000000001"/>
<point x="828.576" y="165.967"/>
<point x="868.8999999999999" y="244.90000000000003"/>
<point x="874" y="277" type="qcurve"/>
<point x="789" y="370" type="line"/>
@ -57,8 +57,8 @@
<point x="571.125" y="151"/>
<point x="510" y="151" type="qcurve" smooth="yes"/>
<point x="443.5" y="151"/>
<point x="355.0833333333333" y="198.91666666666669"/>
<point x="311.0000000000001" y="280.5"/>
<point x="355.08333333333326" y="198.916666666666666"/>
<point x="311" y="280.5"/>
<point x="311" y="331" type="qcurve" smooth="yes"/>
<point x="311" y="429.25"/>
<point x="476" y="524"/>

View File

@ -126,7 +126,7 @@ def _segments_to_quadratic(segments, max_err, stats):
assert all(s[0] == 'curve' for s in segments), 'Non-cubic given to convert'
new_points, _ = curves_to_quadratic([s[1] for s in segments], max_err)
new_points = curves_to_quadratic([s[1] for s in segments], max_err)
n = len(new_points[0])
assert all(len(s) == n for s in new_points[1:]), 'Converted incompatibly'