Remove duplicate gradient stops and update unit tests
This commit is contained in:
parent
238d0d5402
commit
f6387b1f22
3 changed files with 53 additions and 11 deletions
37
scour.py
37
scour.py
|
|
@ -29,7 +29,6 @@
|
||||||
#
|
#
|
||||||
# * Specify a limit to the precision of all positional elements.
|
# * Specify a limit to the precision of all positional elements.
|
||||||
# * Clean up Definitions
|
# * Clean up Definitions
|
||||||
# * Remove duplicate gradient stops
|
|
||||||
# * Collapse duplicate gradient definitions
|
# * Collapse duplicate gradient definitions
|
||||||
# * Remove gradients that are only referenced by one other gradient
|
# * Remove gradients that are only referenced by one other gradient
|
||||||
# * Clean up CSS
|
# * Clean up CSS
|
||||||
|
|
@ -47,11 +46,11 @@
|
||||||
|
|
||||||
# Next Up:
|
# Next Up:
|
||||||
# + Remove unnecessary nested <g> elements
|
# + Remove unnecessary nested <g> elements
|
||||||
# - Remove duplicate gradient stops (same offset, stop-color, stop-opacity)
|
# + Remove duplicate gradient stops (same offset, stop-color, stop-opacity)
|
||||||
# - Convert all colors to #RRGGBB format
|
# - Convert all colors to #RRGGBB format
|
||||||
# - Reduce #RRGGBB format to #RGB format when possible
|
# - Reduce #RRGGBB format to #RGB format when possible
|
||||||
# - rework command-line argument processing so that options are configurable
|
# - rework command-line argument processing so that options are configurable
|
||||||
# - remove unreferenced patterns? https://bugs.edge.launchpad.net/ubuntu/+source/human-icon-theme/+bug/361667/
|
https://bugs.edge.launchpad.net/ubuntu/+source/human-icon-theme/+bug/361667/
|
||||||
|
|
||||||
# Some notes to not forget:
|
# Some notes to not forget:
|
||||||
# - removing unreferenced IDs loses some semantic information
|
# - removing unreferenced IDs loses some semantic information
|
||||||
|
|
@ -309,8 +308,33 @@ def removeNestedGroups(node):
|
||||||
# now recurse for children
|
# now recurse for children
|
||||||
for child in node.childNodes:
|
for child in node.childNodes:
|
||||||
if child.nodeType == 1:
|
if child.nodeType == 1:
|
||||||
num += removeNestedGroups(child)
|
num += removeNestedGroups(child)
|
||||||
|
return num
|
||||||
|
|
||||||
|
def removeDuplicateGradientStops(doc):
|
||||||
|
global numElemsRemoved
|
||||||
|
num = 0
|
||||||
|
|
||||||
|
for gradType in ['linearGradient', 'radialGradient']:
|
||||||
|
for grad in doc.getElementsByTagNameNS(NS['SVG'], gradType):
|
||||||
|
stops = {}
|
||||||
|
stopsToRemove = []
|
||||||
|
for stop in grad.getElementsByTagNameNS(NS['SVG'], 'stop'):
|
||||||
|
offset = string.atof(stop.getAttribute('offset'))
|
||||||
|
color = stop.getAttribute('stop-color')
|
||||||
|
opacity = stop.getAttribute('stop-opacity')
|
||||||
|
if stops.has_key(offset) :
|
||||||
|
oldStop = stops[offset]
|
||||||
|
if oldStop[0] == color and oldStop[1] == opacity:
|
||||||
|
stopsToRemove.append(stop)
|
||||||
|
stops[offset] = [color, opacity]
|
||||||
|
|
||||||
|
for stop in stopsToRemove:
|
||||||
|
stop.parentNode.removeChild(stop)
|
||||||
|
num += 1
|
||||||
|
numElemsRemoved += 1
|
||||||
|
|
||||||
|
# linear gradients
|
||||||
return num
|
return num
|
||||||
|
|
||||||
coord = re.compile("\\-?\\d+\\.?\\d*")
|
coord = re.compile("\\-?\\d+\\.?\\d*")
|
||||||
|
|
@ -668,6 +692,9 @@ def scourString(in_string):
|
||||||
while removeNestedGroups(doc.documentElement) > 0:
|
while removeNestedGroups(doc.documentElement) > 0:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
while removeDuplicateGradientStops(doc) > 0:
|
||||||
|
pass
|
||||||
|
|
||||||
# clean path data
|
# clean path data
|
||||||
for elem in doc.documentElement.getElementsByTagNameNS(NS['SVG'], 'path') :
|
for elem in doc.documentElement.getElementsByTagNameNS(NS['SVG'], 'path') :
|
||||||
cleanPath(elem)
|
cleanPath(elem)
|
||||||
|
|
|
||||||
16
testscour.py
16
testscour.py
|
|
@ -139,13 +139,21 @@ class RemoveUselessNestedGroups(unittest.TestCase):
|
||||||
self.assertEquals(len(doc.getElementsByTagNameNS(SVGNS, 'g')), 1,
|
self.assertEquals(len(doc.getElementsByTagNameNS(SVGNS, 'g')), 1,
|
||||||
'Useless nested groups not removed' )
|
'Useless nested groups not removed' )
|
||||||
|
|
||||||
# These tests will fail at present
|
class RemoveDuplicateLinearGradientStops(unittest.TestCase):
|
||||||
class RemoveDuplicateGradientStops(unittest.TestCase):
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
doc = scour.scourXmlFile('unittests/duplicate-gradient-stops.svg')
|
doc = scour.scourXmlFile('unittests/duplicate-gradient-stops.svg')
|
||||||
self.assertEquals(len(doc.getElementsByTagNameNS(SVGNS, 'stop')), 3,
|
grad = doc.getElementsByTagNameNS(SVGNS, 'linearGradient')
|
||||||
'Duplicate gradient stops not removed' )
|
self.assertEquals(len(grad[0].getElementsByTagNameNS(SVGNS, 'stop')), 3,
|
||||||
|
'Duplicate linear gradient stops not removed' )
|
||||||
|
|
||||||
|
class RemoveDuplicateRadialGradientStops(unittest.TestCase):
|
||||||
|
def runTest(self):
|
||||||
|
doc = scour.scourXmlFile('unittests/duplicate-gradient-stops.svg')
|
||||||
|
grad = doc.getElementsByTagNameNS(SVGNS, 'radialGradient')
|
||||||
|
self.assertEquals(len(grad[0].getElementsByTagNameNS(SVGNS, 'stop')), 3,
|
||||||
|
'Duplicate radial gradient stops not removed' )
|
||||||
|
|
||||||
|
# These tests will fail at present
|
||||||
#class NoInkscapeAttributes(unittest.TestCase):
|
#class NoInkscapeAttributes(unittest.TestCase):
|
||||||
# def runTest(self):
|
# def runTest(self):
|
||||||
# self.assertNotEquals(walkTree(scour.scourXmlFile('unittests/inkscape.svg').documentElement,
|
# self.assertNotEquals(walkTree(scour.scourXmlFile('unittests/inkscape.svg').documentElement,
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,18 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient id="grad" x1="0" y1="0" x2="0" y2="1">
|
<linearGradient id="lingrad" x1="0" y1="0" x2="0" y2="1">
|
||||||
<stop offset="0" stop-color="red" />
|
<stop offset="0" stop-color="red" />
|
||||||
<stop offset="0.5" stop-color="blue" />
|
<stop offset="0.5" stop-color="blue" />
|
||||||
<stop offset="0.5" stop-color="blue" />
|
<stop offset="0.5" stop-color="blue" />
|
||||||
<stop offset="1.0" stop-color="green" />
|
<stop offset="1.0" stop-color="green" />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
|
<radialGradient id="radgrad">
|
||||||
|
<stop offset="0" stop-color="red" />
|
||||||
|
<stop offset="0.5" stop-color="blue" />
|
||||||
|
<stop offset="0.5" stop-color="blue" />
|
||||||
|
<stop offset="1.0" stop-color="green" />
|
||||||
|
</radialGradient>
|
||||||
</defs>
|
</defs>
|
||||||
<rect width="300" height="300" fill="url(#grad)" />
|
<rect width="300" height="300" fill="url(#lingrad)" />
|
||||||
|
<rect width="300" height="300" fill="url(#radgrad)" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 384 B After Width: | Height: | Size: 685 B |
Loading…
Add table
Add a link
Reference in a new issue