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:
parent
3c3f60f4c0
commit
d4efcaa983
1 changed files with 29 additions and 22 deletions
|
|
@ -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,28 +2409,33 @@ 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:
|
||||||
cmd, data = path[pathIndex]
|
for pathIndex in range(len(path)):
|
||||||
if cmd in ['h', 'v'] and len(data) > 1 and not has_markers:
|
cmd, data = path[pathIndex]
|
||||||
coordIndex = 1
|
|
||||||
while coordIndex < len(data):
|
# the first (moveto) command in a path is always absolute, so we have to skip it
|
||||||
if is_same_sign(data[coordIndex - 1], data[coordIndex]):
|
startIndex = (pathIndex == 0)
|
||||||
data[coordIndex - 1] += data[coordIndex]
|
|
||||||
del data[coordIndex]
|
if cmd in ['h', 'v'] and len(data) > startIndex+1: # h,v expect only one parameter
|
||||||
_num_path_segments_removed += 1
|
coordIndex = startIndex
|
||||||
else:
|
while coordIndex+1 < len(data):
|
||||||
coordIndex += 1
|
if is_same_sign(data[coordIndex], data[coordIndex+1]):
|
||||||
if cmd in ['m', 'l'] and len(data) > 3 and not has_markers:
|
data[coordIndex] += data[coordIndex+1]
|
||||||
coordIndex = 2
|
del data[coordIndex+1]
|
||||||
while coordIndex < len(data):
|
_num_path_segments_removed += 1
|
||||||
if is_same_slope(data[coordIndex-2], data[coordIndex-1], data[coordIndex], data[coordIndex+1]):
|
else:
|
||||||
data[coordIndex - 2] += data[coordIndex]
|
coordIndex += 1
|
||||||
data[coordIndex - 1] += data[coordIndex+1]
|
elif cmd in ['m', 'l'] and len(data) > (startIndex+1)*2: # m,l expect two parameters
|
||||||
del data[coordIndex]
|
coordIndex = startIndex * 2
|
||||||
del data[coordIndex]
|
while coordIndex+2 < len(data):
|
||||||
_num_path_segments_removed += 1
|
if is_same_slope(*data[coordIndex:coordIndex+4]):
|
||||||
else:
|
data[coordIndex] += data[coordIndex+2]
|
||||||
coordIndex += 2
|
data[coordIndex+1] += data[coordIndex+3]
|
||||||
|
del data[coordIndex+2] # delete the next two elements
|
||||||
|
del data[coordIndex+2]
|
||||||
|
_num_path_segments_removed += 1
|
||||||
|
else:
|
||||||
|
coordIndex += 2
|
||||||
|
|
||||||
# it is possible that we have consecutive h, v, c, t commands now
|
# it is possible that we have consecutive h, v, c, t commands now
|
||||||
# so again collapse all consecutive commands of the same type into one command
|
# so again collapse all consecutive commands of the same type into one command
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue