Merge e0e3f81632 into 0609c59676
This commit is contained in:
commit
ff4a85bdd6
3 changed files with 71 additions and 12 deletions
|
|
@ -1931,6 +1931,37 @@ def mayContainTextNodes(node):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def _gradient_units_is_not_user_space(node):
|
||||||
|
current_node = node
|
||||||
|
doc = None
|
||||||
|
while True:
|
||||||
|
gradient_unit = current_node.getAttribute('gradientUnits')
|
||||||
|
if gradient_unit != '':
|
||||||
|
# The current node has a value, then it decides
|
||||||
|
break
|
||||||
|
|
||||||
|
# The current node did not have value - check if we reference
|
||||||
|
# another node that might have it.
|
||||||
|
href = current_node.getAttributeNS(NS['XLINK'], 'href')
|
||||||
|
if href == '' or not href.startswith('#'):
|
||||||
|
return True
|
||||||
|
if doc is None:
|
||||||
|
doc = current_node.ownerDocument
|
||||||
|
# Should not happen in practise as our nodes should
|
||||||
|
# always be attached to a document. However, if it
|
||||||
|
# does, then we assume we can strip the attribute.
|
||||||
|
if doc is None:
|
||||||
|
return True
|
||||||
|
node_id = href[1:]
|
||||||
|
current_node = doc.getElementById(node_id)
|
||||||
|
if current_node is None:
|
||||||
|
# Assume we can strip the attribute when we cannot find
|
||||||
|
# the other node
|
||||||
|
return True
|
||||||
|
|
||||||
|
return gradient_unit != 'userSpaceOnUse'
|
||||||
|
|
||||||
|
|
||||||
# A list of default attributes that are safe to remove if all conditions are fulfilled
|
# A list of default attributes that are safe to remove if all conditions are fulfilled
|
||||||
#
|
#
|
||||||
# Each default attribute is an object of type 'DefaultAttribute' with the following fields:
|
# Each default attribute is an object of type 'DefaultAttribute' with the following fields:
|
||||||
|
|
@ -2006,16 +2037,16 @@ default_attributes = [
|
||||||
# filters and masks
|
# filters and masks
|
||||||
DefaultAttribute('x', -10, Unit.PCT, ['filter', 'mask']),
|
DefaultAttribute('x', -10, Unit.PCT, ['filter', 'mask']),
|
||||||
DefaultAttribute('x', -0.1, Unit.NONE, ['filter', 'mask'],
|
DefaultAttribute('x', -0.1, Unit.NONE, ['filter', 'mask'],
|
||||||
conditions=lambda node: node.getAttribute('gradientUnits') != 'userSpaceOnUse'),
|
conditions=_gradient_units_is_not_user_space),
|
||||||
DefaultAttribute('y', -10, Unit.PCT, ['filter', 'mask']),
|
DefaultAttribute('y', -10, Unit.PCT, ['filter', 'mask']),
|
||||||
DefaultAttribute('y', -0.1, Unit.NONE, ['filter', 'mask'],
|
DefaultAttribute('y', -0.1, Unit.NONE, ['filter', 'mask'],
|
||||||
conditions=lambda node: node.getAttribute('gradientUnits') != 'userSpaceOnUse'),
|
conditions=_gradient_units_is_not_user_space),
|
||||||
DefaultAttribute('width', 120, Unit.PCT, ['filter', 'mask']),
|
DefaultAttribute('width', 120, Unit.PCT, ['filter', 'mask']),
|
||||||
DefaultAttribute('width', 1.2, Unit.NONE, ['filter', 'mask'],
|
DefaultAttribute('width', 1.2, Unit.NONE, ['filter', 'mask'],
|
||||||
conditions=lambda node: node.getAttribute('gradientUnits') != 'userSpaceOnUse'),
|
conditions=_gradient_units_is_not_user_space),
|
||||||
DefaultAttribute('height', 120, Unit.PCT, ['filter', 'mask']),
|
DefaultAttribute('height', 120, Unit.PCT, ['filter', 'mask']),
|
||||||
DefaultAttribute('height', 1.2, Unit.NONE, ['filter', 'mask'],
|
DefaultAttribute('height', 1.2, Unit.NONE, ['filter', 'mask'],
|
||||||
conditions=lambda node: node.getAttribute('gradientUnits') != 'userSpaceOnUse'),
|
conditions=_gradient_units_is_not_user_space),
|
||||||
|
|
||||||
# gradients
|
# gradients
|
||||||
DefaultAttribute('x1', 0, elements=['linearGradient']),
|
DefaultAttribute('x1', 0, elements=['linearGradient']),
|
||||||
|
|
@ -2023,7 +2054,7 @@ default_attributes = [
|
||||||
DefaultAttribute('y2', 0, elements=['linearGradient']),
|
DefaultAttribute('y2', 0, elements=['linearGradient']),
|
||||||
DefaultAttribute('x2', 100, Unit.PCT, elements=['linearGradient']),
|
DefaultAttribute('x2', 100, Unit.PCT, elements=['linearGradient']),
|
||||||
DefaultAttribute('x2', 1, Unit.NONE, elements=['linearGradient'],
|
DefaultAttribute('x2', 1, Unit.NONE, elements=['linearGradient'],
|
||||||
conditions=lambda node: node.getAttribute('gradientUnits') != 'userSpaceOnUse'),
|
conditions=_gradient_units_is_not_user_space),
|
||||||
# remove fx/fy before cx/cy to catch the case where fx = cx = 50% or fy = cy = 50% respectively
|
# remove fx/fy before cx/cy to catch the case where fx = cx = 50% or fy = cy = 50% respectively
|
||||||
DefaultAttribute('fx', elements=['radialGradient'],
|
DefaultAttribute('fx', elements=['radialGradient'],
|
||||||
conditions=lambda node: node.getAttribute('fx') == node.getAttribute('cx')),
|
conditions=lambda node: node.getAttribute('fx') == node.getAttribute('cx')),
|
||||||
|
|
@ -2031,13 +2062,13 @@ default_attributes = [
|
||||||
conditions=lambda node: node.getAttribute('fy') == node.getAttribute('cy')),
|
conditions=lambda node: node.getAttribute('fy') == node.getAttribute('cy')),
|
||||||
DefaultAttribute('r', 50, Unit.PCT, elements=['radialGradient']),
|
DefaultAttribute('r', 50, Unit.PCT, elements=['radialGradient']),
|
||||||
DefaultAttribute('r', 0.5, Unit.NONE, elements=['radialGradient'],
|
DefaultAttribute('r', 0.5, Unit.NONE, elements=['radialGradient'],
|
||||||
conditions=lambda node: node.getAttribute('gradientUnits') != 'userSpaceOnUse'),
|
conditions=_gradient_units_is_not_user_space),
|
||||||
DefaultAttribute('cx', 50, Unit.PCT, elements=['radialGradient']),
|
DefaultAttribute('cx', 50, Unit.PCT, elements=['radialGradient']),
|
||||||
DefaultAttribute('cx', 0.5, Unit.NONE, elements=['radialGradient'],
|
DefaultAttribute('cx', 0.5, Unit.NONE, elements=['radialGradient'],
|
||||||
conditions=lambda node: node.getAttribute('gradientUnits') != 'userSpaceOnUse'),
|
conditions=_gradient_units_is_not_user_space),
|
||||||
DefaultAttribute('cy', 50, Unit.PCT, elements=['radialGradient']),
|
DefaultAttribute('cy', 50, Unit.PCT, elements=['radialGradient']),
|
||||||
DefaultAttribute('cy', 0.5, Unit.NONE, elements=['radialGradient'],
|
DefaultAttribute('cy', 0.5, Unit.NONE, elements=['radialGradient'],
|
||||||
conditions=lambda node: node.getAttribute('gradientUnits') != 'userSpaceOnUse'),
|
conditions=_gradient_units_is_not_user_space),
|
||||||
DefaultAttribute('spreadMethod', 'pad', elements=['linearGradient', 'radialGradient']),
|
DefaultAttribute('spreadMethod', 'pad', elements=['linearGradient', 'radialGradient']),
|
||||||
|
|
||||||
# filter effects
|
# filter effects
|
||||||
|
|
@ -3641,6 +3672,7 @@ def scourString(in_string, options=None, stats=None):
|
||||||
scouringContextC = Context(prec=options.cdigits)
|
scouringContextC = Context(prec=options.cdigits)
|
||||||
|
|
||||||
doc = xml.dom.minidom.parseString(in_string)
|
doc = xml.dom.minidom.parseString(in_string)
|
||||||
|
_mark_id_attributes(doc)
|
||||||
|
|
||||||
# determine number of flowRoot elements in input document
|
# determine number of flowRoot elements in input document
|
||||||
# flowRoot elements don't render at all on current browsers (04/2016)
|
# flowRoot elements don't render at all on current browsers (04/2016)
|
||||||
|
|
@ -3882,6 +3914,12 @@ def scourXmlFile(filename, options=None, stats=None):
|
||||||
# prepare the output xml.dom.minidom object
|
# prepare the output xml.dom.minidom object
|
||||||
doc = xml.dom.minidom.parseString(out_string.encode('utf-8'))
|
doc = xml.dom.minidom.parseString(out_string.encode('utf-8'))
|
||||||
|
|
||||||
|
_mark_id_attributes(doc)
|
||||||
|
|
||||||
|
return doc
|
||||||
|
|
||||||
|
|
||||||
|
def _mark_id_attributes(doc):
|
||||||
# since minidom does not seem to parse DTDs properly
|
# since minidom does not seem to parse DTDs properly
|
||||||
# manually declare all attributes with name "id" to be of type ID
|
# manually declare all attributes with name "id" to be of type ID
|
||||||
# (otherwise things like doc.getElementById() won't work)
|
# (otherwise things like doc.getElementById() won't work)
|
||||||
|
|
@ -3892,8 +3930,6 @@ def scourXmlFile(filename, options=None, stats=None):
|
||||||
except NotFoundErr:
|
except NotFoundErr:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return doc
|
|
||||||
|
|
||||||
|
|
||||||
# GZ: Seems most other commandline tools don't do this, is it really wanted?
|
# GZ: Seems most other commandline tools don't do this, is it really wanted?
|
||||||
class HeaderedFormatter(optparse.IndentedHelpFormatter):
|
class HeaderedFormatter(optparse.IndentedHelpFormatter):
|
||||||
|
|
|
||||||
|
|
@ -1517,8 +1517,21 @@ class RemoveRedundantSvgNamespacePrefix(unittest.TestCase):
|
||||||
class RemoveDefaultGradX1Value(unittest.TestCase):
|
class RemoveDefaultGradX1Value(unittest.TestCase):
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
g = scourXmlFile('unittests/gradient-default-attrs.svg').getElementById('grad1')
|
doc = scourXmlFile('unittests/gradient-default-attrs.svg')
|
||||||
self.assertEqual(g.getAttribute('x1'), '',
|
g1 = doc.getElementById('grad1')
|
||||||
|
g1b = doc.getElementById('grad1b')
|
||||||
|
g1c = doc.getElementById('grad1c')
|
||||||
|
g1d = doc.getElementById('grad1d')
|
||||||
|
g1e = doc.getElementById('grad1e')
|
||||||
|
self.assertEqual(g1.getAttribute('x1'), '',
|
||||||
|
'x1="0" not removed')
|
||||||
|
self.assertEqual(g1b.getAttribute('x1'), '',
|
||||||
|
'x1="0" not removed')
|
||||||
|
self.assertEqual(g1c.getAttribute('x1'), '',
|
||||||
|
'x1="0" removed (but should not be due to gradientUnits)')
|
||||||
|
self.assertEqual(g1d.getAttribute('x1'), '',
|
||||||
|
'x1="0" removed (but should not be due to href)')
|
||||||
|
self.assertEqual(g1e.getAttribute('x1'), '',
|
||||||
'x1="0" not removed')
|
'x1="0" not removed')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,20 @@
|
||||||
<stop offset="0" stop-color="black"/>
|
<stop offset="0" stop-color="black"/>
|
||||||
<stop offset="1" stop-color="white"/>
|
<stop offset="1" stop-color="white"/>
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
|
<linearGradient id="grad1d" x2='1' xlink:href="#grad1c">
|
||||||
|
<stop offset="0" stop-color="black"/>
|
||||||
|
<stop offset="1" stop-color="white"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad1e" x2='1' xlink:href="#grad1b">
|
||||||
|
<stop offset="0" stop-color="black"/>
|
||||||
|
<stop offset="1" stop-color="white"/>
|
||||||
|
</linearGradient>
|
||||||
<radialGradient id="grad2" xlink:href="#grad1" cx="50%" cy="0.5" r="50%" fx="50%" fy="0.5"/>
|
<radialGradient id="grad2" xlink:href="#grad1" cx="50%" cy="0.5" r="50%" fx="50%" fy="0.5"/>
|
||||||
|
|
||||||
<rect width="100" height="100" fill="url(#grad1)"/>
|
<rect width="100" height="100" fill="url(#grad1)"/>
|
||||||
<rect width="100" height="100" fill="url(#grad1b)"/>
|
<rect width="100" height="100" fill="url(#grad1b)"/>
|
||||||
<rect width="100" height="100" fill="url(#grad1c)"/>
|
<rect width="100" height="100" fill="url(#grad1c)"/>
|
||||||
|
<rect width="100" height="100" fill="url(#grad1d)"/>
|
||||||
|
<rect width="100" height="100" fill="url(#grad1e)"/>
|
||||||
<rect width="50" height="50" fill="url(#grad2)"/>
|
<rect width="50" height="50" fill="url(#grad2)"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1.4 KiB |
Loading…
Add table
Add a link
Reference in a new issue