From a2c94c96fb75a8b62b99b2af81d8f5d291fd2bb3 Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Sun, 11 Mar 2018 07:18:27 +0000 Subject: [PATCH] Disable the "m0 0"-optimization as it is wrong in some cases The "m0 0" rewrite gets some cases wrong, like: m150 240h200m0 0 150 150v-300z Scour rewrote that into the following m150 240h200l150 150v-300z However, these two paths do not produce an identical figure at all. The first is a line followed by a triangle while the second is a quadrilateral. While there are some instances we can rewrite (that scour will no longer rewrite), these will require an analysis over multiple commands to determine whether the rewrite is safe. This will reappear in the next commit. Closes: #163 Signed-off-by: Niels Thykier --- scour/scour.py | 17 +++++++++-------- testscour.py | 5 +++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/scour/scour.py b/scour/scour.py index 1e990c4..806747e 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -2190,14 +2190,15 @@ def cleanPath(element, options): i = 0 if cmd in ['m', 'l', 't']: if cmd == 'm': - # remove m0,0 segments - if pathIndex > 0 and data[0] == data[i + 1] == 0: - # 'm0,0 x,y' can be replaces with 'lx,y', - # except the first m which is a required absolute moveto - path[pathIndex] = ('l', data[2:]) - _num_path_segments_removed += 1 - else: # else skip move coordinate - i = 2 + # It might be tempting to rewrite "m0 0 ..." into + # "l..." here. However, this is an unsound + # optimization in general as "m0 0 ... z" is + # different from "l...z". + # + # To do such a rewrite, we need to understand the + # full subpath, so for now just leave the first + # two coordinates of "m" alone. + i = 2 while i < len(data): if data[i] == data[i + 1] == 0: del data[i:i + 2] diff --git a/testscour.py b/testscour.py index 060b095..b6abfd5 100755 --- a/testscour.py +++ b/testscour.py @@ -2058,8 +2058,9 @@ class PathEmptyMove(unittest.TestCase): def runTest(self): doc = scourXmlFile('unittests/path-empty-move.svg') - self.assertEqual(doc.getElementsByTagName('path')[0].getAttribute('d'), 'm100 100 200 100z') - self.assertEqual(doc.getElementsByTagName('path')[1].getAttribute('d'), 'm100 100v200l100 100z') + # This path can actually be optimized to avoid the "m0 0z". + self.assertEqual(doc.getElementsByTagName('path')[0].getAttribute('d'), 'm100 100 200 100m0 0z') + self.assertEqual(doc.getElementsByTagName('path')[1].getAttribute('d'), 'm100 100v200m0 0 100 100z') class DefaultsRemovalToplevel(unittest.TestCase):