Ensure all consecutive commands are collapsed where possible
This commit is contained in:
parent
9f47a59a30
commit
04487ed1ec
1 changed files with 38 additions and 7 deletions
45
scour.py
45
scour.py
|
|
@ -25,7 +25,6 @@
|
||||||
# (and implemented here: http://intertwingly.net/code/svgtidy/svgtidy.rb )
|
# (and implemented here: http://intertwingly.net/code/svgtidy/svgtidy.rb )
|
||||||
|
|
||||||
# Yet more ideas here: http://wiki.inkscape.org/wiki/index.php/Save_Cleaned_SVG
|
# Yet more ideas here: http://wiki.inkscape.org/wiki/index.php/Save_Cleaned_SVG
|
||||||
# TODO: Adapt this script into an Inkscape python plugin
|
|
||||||
#
|
#
|
||||||
# * Process Transformations
|
# * Process Transformations
|
||||||
# * Collapse all group based transformations
|
# * Collapse all group based transformations
|
||||||
|
|
@ -59,12 +58,13 @@
|
||||||
# Next Up:
|
# Next Up:
|
||||||
# + Remove some attributes that have default values
|
# + Remove some attributes that have default values
|
||||||
# + Convert c/q path segments into shorthand equivalents where possible:
|
# + Convert c/q path segments into shorthand equivalents where possible:
|
||||||
# - add an option for svgweb compatible markup (no self-closing tags)?
|
# - parse transform attribute
|
||||||
# - if a <g> has only one element in it, collapse the <g> (ensure transform, etc are carried down)
|
# - if a <g> has only one element in it, collapse the <g> (ensure transform, etc are carried down)
|
||||||
# - remove id if it matches the Inkscape-style of IDs (also provide a switch to disable this)
|
# - remove id if it matches the Inkscape-style of IDs (also provide a switch to disable this)
|
||||||
# - prevent elements from being stripped if they are referenced in a <style> element
|
# - prevent elements from being stripped if they are referenced in a <style> element
|
||||||
# (for instance, filter, marker, pattern) - need a crude CSS parser
|
# (for instance, filter, marker, pattern) - need a crude CSS parser
|
||||||
# - Remove any unused glyphs from font elements?
|
# - Remove any unused glyphs from font elements?
|
||||||
|
# - add an option for svgweb compatible markup (no self-closing tags)?
|
||||||
|
|
||||||
# necessary to get true division
|
# necessary to get true division
|
||||||
from __future__ import division
|
from __future__ import division
|
||||||
|
|
@ -1129,6 +1129,9 @@ def convertColors(element) :
|
||||||
|
|
||||||
return numBytes
|
return numBytes
|
||||||
|
|
||||||
|
# TODO: go over what this method does and see if there is a way to optimize it
|
||||||
|
# TODO: go over the performance of this method and see if I can save memory/speed by
|
||||||
|
# reusing data structures, etc
|
||||||
def cleanPath(element) :
|
def cleanPath(element) :
|
||||||
"""
|
"""
|
||||||
Cleans the path string (d attribute) of the element
|
Cleans the path string (d attribute) of the element
|
||||||
|
|
@ -1479,15 +1482,14 @@ def cleanPath(element) :
|
||||||
newPath = [path[0]]
|
newPath = [path[0]]
|
||||||
for (cmd,data) in path[1:]:
|
for (cmd,data) in path[1:]:
|
||||||
# flush the previous command if it is not the same type as the current command
|
# flush the previous command if it is not the same type as the current command
|
||||||
# or it is not an h or v line
|
|
||||||
if prevCmd != '':
|
if prevCmd != '':
|
||||||
if cmd != prevCmd:# or not prevCmd in ['h','v']:
|
if cmd != prevCmd:
|
||||||
newPath.append( (prevCmd, prevData) )
|
newPath.append( (prevCmd, prevData) )
|
||||||
prevCmd = ''
|
prevCmd = ''
|
||||||
prevData = []
|
prevData = []
|
||||||
|
|
||||||
# if the previous and current commands are the same type and a h/v line, collapse
|
# if the previous and current commands are the same type, collapse
|
||||||
if cmd == prevCmd: # and cmd in ['h','v','l']:
|
if cmd == prevCmd:
|
||||||
for coord in data:
|
for coord in data:
|
||||||
prevData.append(coord)
|
prevData.append(coord)
|
||||||
|
|
||||||
|
|
@ -1545,6 +1547,7 @@ def cleanPath(element) :
|
||||||
curveTuples = []
|
curveTuples = []
|
||||||
# append the s command
|
# append the s command
|
||||||
newPath.append( ('s', [data[i+2], data[i+3], data[i+4], data[i+5]]) )
|
newPath.append( ('s', [data[i+2], data[i+3], data[i+4], data[i+5]]) )
|
||||||
|
numPathSegmentsReduced += 1
|
||||||
else:
|
else:
|
||||||
j = 0
|
j = 0
|
||||||
while j <= 5:
|
while j <= 5:
|
||||||
|
|
@ -1569,6 +1572,7 @@ def cleanPath(element) :
|
||||||
curveTuples = []
|
curveTuples = []
|
||||||
# append the t command
|
# append the t command
|
||||||
newPath.append( ('t', [data[i+2], data[i+3]]) )
|
newPath.append( ('t', [data[i+2], data[i+3]]) )
|
||||||
|
numPathSegmentsReduced += 1
|
||||||
else:
|
else:
|
||||||
j = 0;
|
j = 0;
|
||||||
while j <= 3:
|
while j <= 3:
|
||||||
|
|
@ -1583,7 +1587,7 @@ def cleanPath(element) :
|
||||||
else:
|
else:
|
||||||
newPath.append( (cmd, data) )
|
newPath.append( (cmd, data) )
|
||||||
path = newPath
|
path = newPath
|
||||||
|
|
||||||
# for each h or v, collapse unnecessary coordinates that run in the same direction
|
# for each h or v, collapse unnecessary coordinates that run in the same direction
|
||||||
# i.e. "h-100-100" becomes "h-200" but "h300-100" does not change
|
# i.e. "h-100-100" becomes "h-200" but "h300-100" does not change
|
||||||
newPath = [path[0]]
|
newPath = [path[0]]
|
||||||
|
|
@ -1604,6 +1608,33 @@ def cleanPath(element) :
|
||||||
newPath.append( (cmd, data) )
|
newPath.append( (cmd, data) )
|
||||||
path = newPath
|
path = newPath
|
||||||
|
|
||||||
|
# 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
|
||||||
|
prevCmd = ''
|
||||||
|
prevData = []
|
||||||
|
newPath = [path[0]]
|
||||||
|
for (cmd,data) in path[1:]:
|
||||||
|
# flush the previous command if it is not the same type as the current command
|
||||||
|
if prevCmd != '':
|
||||||
|
if cmd != prevCmd:
|
||||||
|
newPath.append( (prevCmd, prevData) )
|
||||||
|
prevCmd = ''
|
||||||
|
prevData = []
|
||||||
|
|
||||||
|
# if the previous and current commands are the same type, collapse
|
||||||
|
if cmd == prevCmd:
|
||||||
|
for coord in data:
|
||||||
|
prevData.append(coord)
|
||||||
|
|
||||||
|
# save last command and data
|
||||||
|
else:
|
||||||
|
prevCmd = cmd
|
||||||
|
prevData = data
|
||||||
|
# flush last command and data
|
||||||
|
if prevCmd != '':
|
||||||
|
newPath.append( (prevCmd, prevData) )
|
||||||
|
path = newPath
|
||||||
|
|
||||||
newPathStr = serializePath(path)
|
newPathStr = serializePath(path)
|
||||||
numBytesSavedInPathData += ( len(oldPathStr) - len(newPathStr) )
|
numBytesSavedInPathData += ( len(oldPathStr) - len(newPathStr) )
|
||||||
element.setAttribute('d', newPathStr)
|
element.setAttribute('d', newPathStr)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue