Remove duplicate gradient stops and update unit tests

This commit is contained in:
JSCHILL1 2009-04-17 08:18:36 -05:00
parent 238d0d5402
commit f6387b1f22
3 changed files with 53 additions and 11 deletions

View file

@ -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
@ -310,7 +309,32 @@ def removeNestedGroups(node):
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)

View file

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

View file

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

Before After
Before After