From 9626ea9734928d0a9342b4a3759f15ce5c0aedd6 Mon Sep 17 00:00:00 2001 From: James Godfrey-Kittle Date: Wed, 27 Jul 2016 13:09:58 -0700 Subject: [PATCH 1/7] Add travis config file --- .travis.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..51dcae198 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +sudo: false +language: python +python: + - "2.7" + - "3.5" +branches: + only: + - master + +install: + - python setup.py install + +script: + - python setup.py test From 7318a62e80b48a0c1efab9e7f6c62d2803aaae5c Mon Sep 17 00:00:00 2001 From: James Godfrey-Kittle Date: Wed, 27 Jul 2016 13:13:23 -0700 Subject: [PATCH 2/7] Trying to get travis working --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 51dcae198..9ae50011c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ sudo: false language: python python: - - "2.7" - "3.5" branches: only: @@ -9,6 +8,7 @@ branches: install: - python setup.py install + - pip install git+https://github.com/unified-font-object/ufoLib script: - python setup.py test From 1988c265959377143456705a3c846dacdf4eb3ae Mon Sep 17 00:00:00 2001 From: James Godfrey-Kittle Date: Wed, 27 Jul 2016 13:17:55 -0700 Subject: [PATCH 3/7] Trying to get travis working --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 9ae50011c..e2bd5ccf8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ branches: install: - python setup.py install + - pip install git+https://github.com/behdad/fonttools - pip install git+https://github.com/unified-font-object/ufoLib script: From 039e35b212948ea97ca3626a4640cc91802b2675 Mon Sep 17 00:00:00 2001 From: James Godfrey-Kittle Date: Wed, 27 Jul 2016 13:21:47 -0700 Subject: [PATCH 4/7] No error returned from API, update tests --- Lib/cu2qu/__init__.py | 2 +- Lib/cu2qu/pens.py | 4 +- Lib/cu2qu/test/cu2qu_test.py | 71 +++++++++++++++++++++++++++++++++--- Lib/cu2qu/ufo.py | 2 +- 4 files changed, 70 insertions(+), 9 deletions(-) diff --git a/Lib/cu2qu/__init__.py b/Lib/cu2qu/__init__.py index 77d92dd8d..9c4de981e 100644 --- a/Lib/cu2qu/__init__.py +++ b/Lib/cu2qu/__init__.py @@ -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] diff --git a/Lib/cu2qu/pens.py b/Lib/cu2qu/pens.py index 63a49c7de..625630378 100644 --- a/Lib/cu2qu/pens.py +++ b/Lib/cu2qu/pens.py @@ -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 diff --git a/Lib/cu2qu/test/cu2qu_test.py b/Lib/cu2qu/test/cu2qu_test.py index 3ef96c308..c31a7d018 100644 --- a/Lib/cu2qu/test/cu2qu_test.py +++ b/Lib/cu2qu/test/cu2qu_test.py @@ -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 = [] @@ -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() diff --git a/Lib/cu2qu/ufo.py b/Lib/cu2qu/ufo.py index a671db826..2d3543ecd 100644 --- a/Lib/cu2qu/ufo.py +++ b/Lib/cu2qu/ufo.py @@ -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' From d556e8a4226f55aeb55844501a9b56acb68a16b3 Mon Sep 17 00:00:00 2001 From: James Godfrey-Kittle Date: Wed, 27 Jul 2016 13:24:34 -0700 Subject: [PATCH 5/7] Update expected test results These have changed with the new conversion method from https://github.com/googlei18n/cu2qu/pull/33 --- Lib/cu2qu/test/cu2qu_test.py | 22 +++++----- Lib/cu2qu/test/data/quadratic/A_.glif | 50 +++++++--------------- Lib/cu2qu/test/data/quadratic/E_acute.glif | 29 +++++++------ Lib/cu2qu/test/data/quadratic/a.glif | 32 +++++++------- 4 files changed, 58 insertions(+), 75 deletions(-) diff --git a/Lib/cu2qu/test/cu2qu_test.py b/Lib/cu2qu/test/cu2qu_test.py index c31a7d018..a9a51465c 100644 --- a/Lib/cu2qu/test/cu2qu_test.py +++ b/Lib/cu2qu/test/cu2qu_test.py @@ -67,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: @@ -86,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: diff --git a/Lib/cu2qu/test/data/quadratic/A_.glif b/Lib/cu2qu/test/data/quadratic/A_.glif index f70bfa6c3..673eb514e 100644 --- a/Lib/cu2qu/test/data/quadratic/A_.glif +++ b/Lib/cu2qu/test/data/quadratic/A_.glif @@ -6,8 +6,8 @@ - - + + @@ -22,12 +22,12 @@ - + - - + + @@ -37,27 +37,27 @@ - - - - - - + + + + + + - + - + - - + + @@ -71,22 +71,4 @@ - - - org.robofab.fontlab.guides - - hguides - - - angle - 0 - position - -180 - - - - org.robofab.fontlab.mark - 80 - - - \ No newline at end of file + diff --git a/Lib/cu2qu/test/data/quadratic/E_acute.glif b/Lib/cu2qu/test/data/quadratic/E_acute.glif index b0a5ec486..89b4a5afa 100644 --- a/Lib/cu2qu/test/data/quadratic/E_acute.glif +++ b/Lib/cu2qu/test/data/quadratic/E_acute.glif @@ -6,15 +6,15 @@ - - + + - - + + @@ -38,26 +38,27 @@ - - - + + + + - - + + - - + + - - + + - \ No newline at end of file + diff --git a/Lib/cu2qu/test/data/quadratic/a.glif b/Lib/cu2qu/test/data/quadratic/a.glif index 141bc75fb..dc776e117 100644 --- a/Lib/cu2qu/test/data/quadratic/a.glif +++ b/Lib/cu2qu/test/data/quadratic/a.glif @@ -6,8 +6,8 @@ - - + + @@ -17,17 +17,17 @@ - + - - + + - - + + @@ -37,17 +37,17 @@ - - + + - - + + - - + + @@ -57,8 +57,8 @@ - - + + @@ -90,4 +90,4 @@ - \ No newline at end of file + From ac58a7699a5ae588ba8a29e64bdf7572d3b7e1b7 Mon Sep 17 00:00:00 2001 From: James Godfrey-Kittle Date: Wed, 27 Jul 2016 13:43:29 -0700 Subject: [PATCH 6/7] Trying to get travis working --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e2bd5ccf8..2d4cce0ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ sudo: false language: python python: - - "3.5" + - "3.4" branches: only: - master From 79beda96a4e26d5d1778f24de673cf14c6bda1ac Mon Sep 17 00:00:00 2001 From: James Godfrey-Kittle Date: Wed, 27 Jul 2016 13:48:19 -0700 Subject: [PATCH 7/7] Change expected test results for travis This is kind of annoying, because I don't get these results running the test locally. Hoping it's a user error of some sort on my part. --- Lib/cu2qu/test/data/quadratic/E_acute.glif | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/cu2qu/test/data/quadratic/E_acute.glif b/Lib/cu2qu/test/data/quadratic/E_acute.glif index 89b4a5afa..e5bb4fd5b 100644 --- a/Lib/cu2qu/test/data/quadratic/E_acute.glif +++ b/Lib/cu2qu/test/data/quadratic/E_acute.glif @@ -30,7 +30,8 @@ - + +