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 <niels@thykier.net>
This commit is contained in:
Niels Thykier 2018-03-11 07:18:27 +00:00
parent 6ea126d290
commit a2c94c96fb
2 changed files with 12 additions and 10 deletions

View file

@ -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]

View file

@ -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):