Merge pull request #940 from fonttools/t2CharStringPen

[t2CharStringPen] Add support for more path operators
This commit is contained in:
Cosimo Lupo 2017-04-28 15:34:50 +01:00 committed by GitHub
commit 386b528aaf
2 changed files with 113 additions and 24 deletions

View File

@ -112,8 +112,13 @@ class T2CharStringPen(RelativeCoordinatePen):
def _relativeMoveTo(self, pt):
pt = self.roundPoint(pt)
x, y = pt
self._heldMove = [x, y, "rmoveto"]
dx, dy = pt
if dx == 0:
self._heldMove = [dy, "vmoveto"]
elif dy == 0:
self._heldMove = [dx, "hmoveto"]
else:
self._heldMove = [dx, dy, "rmoveto"]
def _storeHeldMove(self):
if self._heldMove is not None:
@ -126,8 +131,13 @@ class T2CharStringPen(RelativeCoordinatePen):
def _relativeLineTo(self, pt):
self._storeHeldMove()
pt = self.roundPoint(pt)
x, y = pt
self._program.extend([x, y, "rlineto"])
dx, dy = pt
if dx == 0:
self._program.extend([dy, "vlineto"])
elif dy == 0:
self._program.extend([dx, "hlineto"])
else:
self._program.extend([dx, dy, "rlineto"])
def _curveToOne(self, pt1, pt2, pt3):
RelativeCoordinatePen._curveToOne(self,
@ -140,10 +150,29 @@ class T2CharStringPen(RelativeCoordinatePen):
pt1 = self.roundPoint(pt1)
pt2 = self.roundPoint(pt2)
pt3 = self.roundPoint(pt3)
x1, y1 = pt1
x2, y2 = pt2
x3, y3 = pt3
self._program.extend([x1, y1, x2, y2, x3, y3, "rrcurveto"])
dx1, dy1 = pt1
dx2, dy2 = pt2
dx3, dy3 = pt3
if dx1 == 0:
if dx3 == 0:
self._program.extend([dy1, dx2, dy2, dy3, "vvcurveto"])
elif dy3 == 0:
self._program.extend([dy1, dx2, dy2, dx3, "vhcurveto"])
else:
self._program.extend([dy1, dx2, dy2, dx3, dy3, "vhcurveto"])
elif dy1 == 0:
if dy3 == 0:
self._program.extend([dx1, dx2, dy2, dx3, "hhcurveto"])
elif dx3 == 0:
self._program.extend([dx1, dx2, dy2, dy3, "hvcurveto"])
else:
self._program.extend([dx1, dx2, dy2, dy3, dx3, "hvcurveto"])
elif dx3 == 0:
self._program.extend([dx1, dy1, dx2, dy2, dy3, "vvcurveto"])
elif dy3 == 0:
self._program.extend([dy1, dx1, dx2, dy2, dx3, "hhcurveto"])
else:
self._program.extend([dx1, dy1, dx2, dy2, dx3, dy3, "rrcurveto"])
def _closePath(self):
pass

View File

@ -22,7 +22,7 @@ class T2CharStringPenTest(unittest.TestCase):
else:
self.assertAlmostEqual(i1, i2)
def test_draw_lines(self):
def test_draw_h_v_lines(self):
pen = T2CharStringPen(100, {})
pen.moveTo((0, 0))
pen.lineTo((10, 0))
@ -33,14 +33,32 @@ class T2CharStringPenTest(unittest.TestCase):
self.assertEqual(
[100,
0, 0, 'rmoveto',
10, 0, 'rlineto',
0, 10, 'rlineto',
-10, 0, 'rlineto',
0, 'vmoveto',
10, 'hlineto',
10, 'vlineto',
-10, 'hlineto',
'endchar'],
charstring.program)
def test_draw_curves(self):
def test_draw_lines(self):
pen = T2CharStringPen(100, {})
pen.moveTo((5, 5))
pen.lineTo((25, 15))
pen.lineTo((35, 35))
pen.lineTo((15, 25))
pen.closePath() # no-op
charstring = pen.getCharString(None, None)
self.assertEqual(
[100,
5, 5, 'rmoveto',
20, 10, 'rlineto',
10, 20, 'rlineto',
-20, -10, 'rlineto',
'endchar'],
charstring.program)
def test_draw_h_v_curves(self):
pen = T2CharStringPen(100, {})
pen.moveTo((0, 0))
pen.curveTo((10, 0), (20, 10), (20, 20))
@ -50,9 +68,51 @@ class T2CharStringPenTest(unittest.TestCase):
self.assertEqual(
[100,
0, 0, 'rmoveto',
10, 0, 10, 10, 0, 10, 'rrcurveto',
0, 10, -10, 10, -10, 0, 'rrcurveto',
0, 'vmoveto',
10, 10, 10, 10, 'hvcurveto',
10, -10, 10, -10, 'vhcurveto',
'endchar'],
charstring.program)
def test_draw_curves(self):
pen = T2CharStringPen(100, {})
pen.moveTo((95, 25))
pen.curveTo((115, 44), (115, 76), (95, 95))
pen.curveTo((76, 114), (44, 115), (25, 95))
pen.endPath() # no-op
charstring = pen.getCharString(None, None)
self.assertEqual(
[100,
95, 25, 'rmoveto',
20, 19, 0, 32, -20, 19, 'rrcurveto',
-19, 19, -32, 1, -19, -20, 'rrcurveto',
'endchar'],
charstring.program)
def test_draw_more_curves(self):
pen = T2CharStringPen(100, {})
pen.moveTo((10, 10))
pen.curveTo((20, 10), (50, 10), (60, 10))
pen.curveTo((60, 20), (60, 50), (60, 60))
pen.curveTo((50, 50), (40, 60), (30, 60))
pen.curveTo((40, 50), (30, 40), (30, 30))
pen.curveTo((30, 25), (25, 19), (20, 20))
pen.curveTo((15, 20), (9, 25), (10, 30))
pen.curveTo((7, 25), (6, 15), (10, 10))
pen.endPath() # no-op
charstring = pen.getCharString(None, None)
self.assertEqual(
[100,
10, 10, 'rmoveto',
10, 30, 0, 10, 'hhcurveto',
10, 0, 30, 10, 'vvcurveto',
-10, -10, -10, 10, -10, 'hhcurveto',
10, -10, -10, -10, -10, 'vvcurveto',
-5, -5, -6, -5, 1, 'vhcurveto',
-5, -6, 5, 5, 1, 'hvcurveto',
-3, -5, -1, -10, 4, -5, 'rrcurveto',
'endchar'],
charstring.program)
@ -71,9 +131,9 @@ class T2CharStringPenTest(unittest.TestCase):
self.assertAlmostEqualProgram(
[100, # we always round the advance width
0, 0, 'rmoveto',
0, 'vmoveto',
10.1, 0.1, 9.8, 9.8, 0.59, 10.59, 'rrcurveto',
0, 10, -10.59, 9.41, -9.8, 0.2, 'rrcurveto',
10, -10.59, 9.41, -9.8, 0.2, 'vhcurveto',
'endchar'],
charstring.program)
@ -87,9 +147,9 @@ class T2CharStringPenTest(unittest.TestCase):
self.assertEqual(
[100,
0, 0, 'rmoveto',
10, 0, 10, 10, 0, 10, 'rrcurveto',
0, 10, -10, 10, -10, 0, 'rrcurveto',
0, 'vmoveto',
10, 10, 10, 10, 'hvcurveto',
10, -10, 10, -10, 'vhcurveto',
'endchar'],
charstring.program)
@ -106,8 +166,8 @@ class T2CharStringPenTest(unittest.TestCase):
self.assertAlmostEqualProgram(
[100,
0, 0, 'rmoveto',
10, 0, 'rlineto',
0, 'vmoveto',
10, 'hlineto',
10, 10, 'rlineto',
0.49, 10.49, 'rlineto',
'endchar'],