Fix Bug 541889: Properly parse polygon/polyline points missing whitespace/comma for negative attributes
39
scour.py
|
|
@ -1786,12 +1786,43 @@ def parseListOfPoints(s):
|
||||||
|
|
||||||
Returns a list of containing an even number of coordinate strings
|
Returns a list of containing an even number of coordinate strings
|
||||||
"""
|
"""
|
||||||
|
i = 0
|
||||||
|
points = []
|
||||||
|
|
||||||
# (wsp)? comma-or-wsp-separated coordinate pairs (wsp)?
|
# (wsp)? comma-or-wsp-separated coordinate pairs (wsp)?
|
||||||
# coordinate-pair = coordinate comma-or-wsp coordinate
|
# coordinate-pair = coordinate comma-or-wsp coordinate
|
||||||
# coordinate = sign? integer
|
# coordinate = sign? integer
|
||||||
nums = re.split("\\s*\\,?\\s*", s.strip())
|
# comma-wsp: (wsp+ comma? wsp*) | (comma wsp*)
|
||||||
|
ws_nums = re.split("\\s*\\,?\\s*", s.strip())
|
||||||
|
nums = []
|
||||||
|
|
||||||
|
# also, if 100-100 is found, split it into two also
|
||||||
|
# <polygon points="100,-100,100-100,100-100-100,-100-100" />
|
||||||
|
for i in range(len(ws_nums)):
|
||||||
|
negcoords = re.split("\\-", ws_nums[i]);
|
||||||
|
|
||||||
|
# this string didn't have any negative coordinates
|
||||||
|
if len(negcoords) == 1:
|
||||||
|
nums.append(negcoords[0])
|
||||||
|
# we got negative coords
|
||||||
|
else:
|
||||||
|
for j in range(len(negcoords)):
|
||||||
|
# first number could be positive
|
||||||
|
if j == 0:
|
||||||
|
if negcoords[0] != '':
|
||||||
|
nums.append(negcoords[0])
|
||||||
|
# otherwise all other strings will be negative
|
||||||
|
else:
|
||||||
|
# unless we accidentally split a number that was in scientific notation
|
||||||
|
# and had a negative exponent (500.00e-1)
|
||||||
|
prev = nums[len(nums)-1]
|
||||||
|
if prev[len(prev)-1] == 'e' or prev[len(prev)-1] == 'E':
|
||||||
|
nums[len(nums)-1] = prev + '-' + negcoords[j]
|
||||||
|
else:
|
||||||
|
nums.append( '-'+negcoords[j] )
|
||||||
|
|
||||||
|
# now resolve into SVGLength values
|
||||||
i = 0
|
i = 0
|
||||||
points = []
|
|
||||||
while i < len(nums):
|
while i < len(nums):
|
||||||
x = SVGLength(nums[i])
|
x = SVGLength(nums[i])
|
||||||
# if we had an odd number of points, return empty
|
# if we had an odd number of points, return empty
|
||||||
|
|
@ -1820,14 +1851,14 @@ def cleanPolygon(elem):
|
||||||
if startx == endx and starty == endy:
|
if startx == endx and starty == endy:
|
||||||
pts = pts[:-2]
|
pts = pts[:-2]
|
||||||
numPointsRemovedFromPolygon += 1
|
numPointsRemovedFromPolygon += 1
|
||||||
elem.setAttribute('points', scourCoordinates(pts))
|
elem.setAttribute('points', scourCoordinates(pts,True))
|
||||||
|
|
||||||
def cleanPolyline(elem):
|
def cleanPolyline(elem):
|
||||||
"""
|
"""
|
||||||
Scour the polyline points attribute
|
Scour the polyline points attribute
|
||||||
"""
|
"""
|
||||||
pts = parseListOfPoints(elem.getAttribute('points'))
|
pts = parseListOfPoints(elem.getAttribute('points'))
|
||||||
elem.setAttribute('points', scourCoordinates(pts))
|
elem.setAttribute('points', scourCoordinates(pts,True))
|
||||||
|
|
||||||
def serializePath(pathObj):
|
def serializePath(pathObj):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,6 @@ class ElementSelector(unittest.TestCase):
|
||||||
class ElementSelectorWithProperty(unittest.TestCase):
|
class ElementSelectorWithProperty(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
r = parseCssString('foo { bar: baz}')
|
r = parseCssString('foo { bar: baz}')
|
||||||
print r
|
|
||||||
self.assertEquals( len(r), 1, 'Element selector not returned')
|
self.assertEquals( len(r), 1, 'Element selector not returned')
|
||||||
self.assertEquals( r[0]['selector'], 'foo', 'Selector for foo not returned')
|
self.assertEquals( r[0]['selector'], 'foo', 'Selector for foo not returned')
|
||||||
self.assertEquals( len(r[0]['properties']), 1, 'Property list for foo did not have 1')
|
self.assertEquals( len(r[0]['properties']), 1, 'Property list for foo did not have 1')
|
||||||
|
|
|
||||||
23
testscour.py
|
|
@ -654,7 +654,7 @@ class ConvertStraightCurvesToLines(unittest.TestCase):
|
||||||
self.assertEquals(p.getAttribute('d'), 'M10,10l40,40,40-40z',
|
self.assertEquals(p.getAttribute('d'), 'M10,10l40,40,40-40z',
|
||||||
'Did not convert straight curves into lines')
|
'Did not convert straight curves into lines')
|
||||||
|
|
||||||
class RemoveUnnecessaryPolgonEndPoint(unittest.TestCase):
|
class RemoveUnnecessaryPolygonEndPoint(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
p = scour.scourXmlFile('unittests/polygon.svg').getElementsByTagNameNS(SVGNS, 'polygon')[0]
|
p = scour.scourXmlFile('unittests/polygon.svg').getElementsByTagNameNS(SVGNS, 'polygon')[0]
|
||||||
self.assertEquals(p.getAttribute('points'), '50,50,150,50,150,150,50,150',
|
self.assertEquals(p.getAttribute('points'), '50,50,150,50,150,150,50,150',
|
||||||
|
|
@ -666,18 +666,31 @@ class DoNotRemovePolgonLastPoint(unittest.TestCase):
|
||||||
self.assertEquals(p.getAttribute('points'), '200,50,300,50,300,150,200,150',
|
self.assertEquals(p.getAttribute('points'), '200,50,300,50,300,150,200,150',
|
||||||
'Last point of polygon removed' )
|
'Last point of polygon removed' )
|
||||||
|
|
||||||
class ScourPolygonCoordinates(unittest.TestCase):
|
class ScourPolygonCoordsSciNo(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
p = scour.scourXmlFile('unittests/polygon-coord.svg').getElementsByTagNameNS(SVGNS, 'polygon')[0]
|
p = scour.scourXmlFile('unittests/polygon-coord.svg').getElementsByTagNameNS(SVGNS, 'polygon')[0]
|
||||||
self.assertEquals(p.getAttribute('points'), '1E+4-50',
|
self.assertEquals(p.getAttribute('points'), '1E+4,50',
|
||||||
'Polygon coordinates not scoured')
|
'Polygon coordinates not scoured')
|
||||||
|
|
||||||
class ScourPolylineCoordinates(unittest.TestCase):
|
class ScourPolylineCoordsSciNo(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
p = scour.scourXmlFile('unittests/polyline-coord.svg').getElementsByTagNameNS(SVGNS, 'polyline')[0]
|
p = scour.scourXmlFile('unittests/polyline-coord.svg').getElementsByTagNameNS(SVGNS, 'polyline')[0]
|
||||||
self.assertEquals(p.getAttribute('points'), '1E+4-50',
|
self.assertEquals(p.getAttribute('points'), '1E+4,50',
|
||||||
'Polyline coordinates not scoured')
|
'Polyline coordinates not scoured')
|
||||||
|
|
||||||
|
class ScourPolygonNegativeCoords(unittest.TestCase):
|
||||||
|
def runTest(self):
|
||||||
|
p = scour.scourXmlFile('unittests/polygon-coord-neg.svg').getElementsByTagNameNS(SVGNS, 'polygon')[0]
|
||||||
|
# points="100,-100,100-100,100-100-100,-100-100,200" />
|
||||||
|
self.assertEquals(p.getAttribute('points'), '100,-100,100,-100,100,-100,-100,-100,-100,200',
|
||||||
|
'Negative polygon coordinates not properly parsed')
|
||||||
|
|
||||||
|
class ScourPolylineNegativeCoords(unittest.TestCase):
|
||||||
|
def runTest(self):
|
||||||
|
p = scour.scourXmlFile('unittests/polyline-coord-neg.svg').getElementsByTagNameNS(SVGNS, 'polyline')[0]
|
||||||
|
self.assertEquals(p.getAttribute('points'), '100,-100,100,-100,100,-100,-100,-100,-100,200',
|
||||||
|
'Negative polyline coordinates not properly parsed')
|
||||||
|
|
||||||
class DoNotRemoveGroupsWithIDsInDefs(unittest.TestCase):
|
class DoNotRemoveGroupsWithIDsInDefs(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
f = scour.scourXmlFile('unittests/important-groups-in-defs.svg')
|
f = scour.scourXmlFile('unittests/important-groups-in-defs.svg')
|
||||||
|
|
|
||||||
4
unittests/polygon-coord-neg.svg
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<polygon points="100,-100,100-100,100-100-100,-100-100,200" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 155 B |
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
<polygon fill="blue" points="10000,-50" />
|
<polygon fill="blue" points="10000,50" />
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 146 B After Width: | Height: | Size: 145 B |
4
unittests/polyline-coord-neg.svg
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<polyline points="100,-100,100-100,100-100-100,-100-100,200" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 156 B |
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg">
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
<polyline fill="blue" points="10000,-50" />
|
<polyline fill="blue" points="10000,50" />
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 147 B After Width: | Height: | Size: 146 B |
8
unittests/refs-in-defs.svg
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<defs>
|
||||||
|
<path id="L" stroke="#000000" d="M0,0 100,100"/>
|
||||||
|
<g id="G"><use xlink:href="#L"/> <path stroke="#000000" d="M0,100 100,0"/></g>
|
||||||
|
</defs>
|
||||||
|
<use xlink:href="#G"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 345 B |