Optimize/simplify code for last commit and fix a longstanding indexing bug when collapsing subpaths

(the first command of a path and all of its parameters were never optimized and as many paths consist only of one moveto command with many parameters the functionality might have been broken in many cases)
This commit is contained in:
Eduard Braun 2017-05-16 22:59:50 +02:00
parent 3c3f60f4c0
commit d4efcaa983

View file

@ -404,6 +404,8 @@ default_properties = { # excluded all properties with 'auto' as default
def is_same_sign(a, b): return (a <= 0 and b <= 0) or (a >= 0 and b >= 0) def is_same_sign(a, b): return (a <= 0 and b <= 0) or (a >= 0 and b >= 0)
def is_same_slope(x1, y1, x2, y2): return y1/x1 - y2/x2 == 0 def is_same_slope(x1, y1, x2, y2): return y1/x1 - y2/x2 == 0
@ -2407,25 +2409,30 @@ def cleanPath(element, options):
# Reuse the data structure 'path', since we're not adding or removing subcommands. # Reuse the data structure 'path', since we're not adding or removing subcommands.
# Also reuse the coordinate lists, even if we're deleting items, because these # Also reuse the coordinate lists, even if we're deleting items, because these
# deletions are relatively cheap. # deletions are relatively cheap.
for pathIndex in range(1, len(path)): if not has_markers:
for pathIndex in range(len(path)):
cmd, data = path[pathIndex] cmd, data = path[pathIndex]
if cmd in ['h', 'v'] and len(data) > 1 and not has_markers:
coordIndex = 1 # the first (moveto) command in a path is always absolute, so we have to skip it
while coordIndex < len(data): startIndex = (pathIndex == 0)
if is_same_sign(data[coordIndex - 1], data[coordIndex]):
data[coordIndex - 1] += data[coordIndex] if cmd in ['h', 'v'] and len(data) > startIndex+1: # h,v expect only one parameter
del data[coordIndex] coordIndex = startIndex
while coordIndex+1 < len(data):
if is_same_sign(data[coordIndex], data[coordIndex+1]):
data[coordIndex] += data[coordIndex+1]
del data[coordIndex+1]
_num_path_segments_removed += 1 _num_path_segments_removed += 1
else: else:
coordIndex += 1 coordIndex += 1
if cmd in ['m', 'l'] and len(data) > 3 and not has_markers: elif cmd in ['m', 'l'] and len(data) > (startIndex+1)*2: # m,l expect two parameters
coordIndex = 2 coordIndex = startIndex * 2
while coordIndex < len(data): while coordIndex+2 < len(data):
if is_same_slope(data[coordIndex-2], data[coordIndex-1], data[coordIndex], data[coordIndex+1]): if is_same_slope(*data[coordIndex:coordIndex+4]):
data[coordIndex - 2] += data[coordIndex] data[coordIndex] += data[coordIndex+2]
data[coordIndex - 1] += data[coordIndex+1] data[coordIndex+1] += data[coordIndex+3]
del data[coordIndex] del data[coordIndex+2] # delete the next two elements
del data[coordIndex] del data[coordIndex+2]
_num_path_segments_removed += 1 _num_path_segments_removed += 1
else: else:
coordIndex += 2 coordIndex += 2