Merge pull request #34 from googlei18n/update-tests
Add travis config file
This commit is contained in:
commit
0479616451
15
.travis.yml
Normal file
15
.travis.yml
Normal 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
|
@ -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]
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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>
|
||||
</glyph>
|
||||
|
@ -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,26 +39,27 @@
|
||||
<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"/>
|
||||
</outline>
|
||||
</glyph>
|
||||
</glyph>
|
||||
|
@ -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"/>
|
||||
@ -90,4 +90,4 @@
|
||||
<point name="top0315" x="1118" y="1290" type="move"/>
|
||||
</contour>
|
||||
</outline>
|
||||
</glyph>
|
||||
</glyph>
|
||||
|
@ -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'
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user