Fix conversion of cubic Bézier "curveto" commands into "shorthand/smooth curveto" commands. (#110)

When the preceeding path segment is a Bézier curve, too, the first control point of the shorthand defaults to the mirrored version of the second control point of this preceeding path segment. Scour always assumed (0,0) as the control point in this case which could result in modified path data (e.g. #91).
This commit is contained in:
Eduard Braun 2016-09-06 01:43:36 +02:00 committed by GitHub
parent 0fac95ee09
commit 1aa5722c6a
3 changed files with 16 additions and 4 deletions

View file

@ -2193,7 +2193,13 @@ def cleanPath(element, options) :
newPath.append( (cmd, lineTuples) )
# convert Bézier curve segments into s where possible
elif cmd == 'c':
bez_ctl_pt = (0,0)
# set up the assumed bezier control point as the current point, i.e. (0,0) since we're using relative coords
bez_ctl_pt = (0, 0)
# however if the previous command was 's' the assumed control point is a reflection of the previous control point at the current point
if len(newPath):
(prevCmd, prevData) = newPath[-1]
if prevCmd == 's':
bez_ctl_pt = (prevData[-2]-prevData[-4], prevData[-1]-prevData[-3])
i = 0
curveTuples = []
while i < len(data):

View file

@ -675,9 +675,13 @@ class ChangeLineToVerticalLineSegmentInPath(unittest.TestCase):
class ChangeBezierToShorthandInPath(unittest.TestCase):
def runTest(self):
path = scour.scourXmlFile('unittests/path-bez-optimize.svg').getElementsByTagNameNS(SVGNS, 'path')[0]
self.assertEqual(path.getAttribute('d'), 'm10 100c50-50 50 50 100 0s50 50 100 0',
doc = scour.scourXmlFile('unittests/path-bez-optimize.svg')
self.assertEqual(doc.getElementById('path1').getAttribute('d'), 'm10 100c50-50 50 50 100 0s50 50 100 0',
'Did not change bezier curves into shorthand curve segments in path')
self.assertEqual(doc.getElementById('path2a').getAttribute('d'), 'm200 200s200 100 200 0',
'Did not change bezier curve into shorthand curve segment when first control point is the current point and previous command was not a bezier curve')
self.assertEqual(doc.getElementById('path2b').getAttribute('d'), 'm0 300s200-100 200 0c0 0 200 100 200 0',
'Did change bezier curve into shorthand curve segment when first control point is the current point but previous command was a bezier curve with a different control point')
class ChangeQuadToShorthandInPath(unittest.TestCase):
def runTest(self):

View file

@ -1,4 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg version="1.1" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
<path d="m10,100c50-50,50,50,100,0,50-50,50,50,100,0" fill="none" stroke="blue" stroke-width="5"/>
<path id="path1" d="m10,100c50-50,50,50,100,0,50-50,50,50,100,0" fill="none" stroke="blue" stroke-width="5"/>
<path id="path2a" d="m200,200c0,0 200,100 200,0" fill="none" stroke="red" stroke-width="5"/>
<path id="path2b" d="m0,300s200-100 200,0c0,0 200,100 200,0" fill="none" stroke="green" stroke-width="5"/>
</svg>

Before

Width:  |  Height:  |  Size: 240 B

After

Width:  |  Height:  |  Size: 455 B

Before After
Before After