Merge remote-tracking branch 'refs/remotes/scour-project/master'
This commit is contained in:
commit
3bcff5e9c4
7 changed files with 116 additions and 30 deletions
28
.travis.yml
28
.travis.yml
|
|
@ -1,31 +1,27 @@
|
||||||
|
sudo: false
|
||||||
|
|
||||||
language: python
|
language: python
|
||||||
|
|
||||||
|
python:
|
||||||
|
- pypy
|
||||||
|
- 2.7
|
||||||
|
- 3.3
|
||||||
|
- 3.4
|
||||||
|
- 3.5
|
||||||
|
- 3.6
|
||||||
install:
|
install:
|
||||||
- pip install tox codecov
|
- pip install tox-travis codecov
|
||||||
|
|
||||||
env:
|
|
||||||
- TOX_ENV=pypy
|
|
||||||
- TOX_ENV=py27
|
|
||||||
- TOX_ENV=py33
|
|
||||||
- TOX_ENV=py34
|
|
||||||
# - TOX_ENV=py35
|
|
||||||
# - TOX_ENV=flake8
|
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- tox -e $TOX_ENV
|
- tox
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
|
||||||
include:
|
include:
|
||||||
# https://github.com/travis-ci/travis-ci/issues/4794#issuecomment-143758799
|
|
||||||
- python: 3.5
|
- python: 3.5
|
||||||
env:
|
env:
|
||||||
- TOX_ENV=py35
|
- TOXENV=flake8
|
||||||
|
|
||||||
- python: 3.5
|
|
||||||
env:
|
|
||||||
- TOX_ENV=flake8
|
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- coverage combine && codecov
|
- coverage combine && codecov
|
||||||
|
|
@ -2625,6 +2625,7 @@ def scourUnitlessLength(length, needsRendererWorkaround=False, isControlPoint=Fa
|
||||||
"""
|
"""
|
||||||
if not isinstance(length, Decimal):
|
if not isinstance(length, Decimal):
|
||||||
length = getcontext().create_decimal(str(length))
|
length = getcontext().create_decimal(str(length))
|
||||||
|
initial_length = length
|
||||||
|
|
||||||
# reduce numeric precision
|
# reduce numeric precision
|
||||||
# plus() corresponds to the unary prefix plus operator and applies context precision and rounding
|
# plus() corresponds to the unary prefix plus operator and applies context precision and rounding
|
||||||
|
|
@ -2655,15 +2656,17 @@ def scourUnitlessLength(length, needsRendererWorkaround=False, isControlPoint=Fa
|
||||||
else:
|
else:
|
||||||
length = length.normalize()
|
length = length.normalize()
|
||||||
|
|
||||||
# gather the non-scientific notation version of the coordinate.
|
# Gather the non-scientific notation version of the coordinate.
|
||||||
# this may actually be in scientific notation if the value is
|
# Re-quantize from the initial value to prevent unnecessary loss of precision
|
||||||
# sufficiently large or small, so this is a misnomer.
|
# (e.g. 123.4 should become 123, not 120 or even 100)
|
||||||
nonsci = six.text_type(length).lower().replace("e+", "e")
|
nonsci = '{0:f}'.format(length)
|
||||||
|
nonsci = '{0:f}'.format(initial_length.quantize(Decimal(nonsci)))
|
||||||
if not needsRendererWorkaround:
|
if not needsRendererWorkaround:
|
||||||
if len(nonsci) > 2 and nonsci[:2] == '0.':
|
if len(nonsci) > 2 and nonsci[:2] == '0.':
|
||||||
nonsci = nonsci[1:] # remove the 0, leave the dot
|
nonsci = nonsci[1:] # remove the 0, leave the dot
|
||||||
elif len(nonsci) > 3 and nonsci[:3] == '-0.':
|
elif len(nonsci) > 3 and nonsci[:3] == '-0.':
|
||||||
nonsci = '-' + nonsci[2:] # remove the 0, leave the minus and dot
|
nonsci = '-' + nonsci[2:] # remove the 0, leave the minus and dot
|
||||||
|
return_value = nonsci
|
||||||
|
|
||||||
# Gather the scientific notation version of the coordinate which
|
# Gather the scientific notation version of the coordinate which
|
||||||
# can only be shorter if the length of the number is at least 4 characters (e.g. 1000 = 1e3).
|
# can only be shorter if the length of the number is at least 4 characters (e.g. 1000 = 1e3).
|
||||||
|
|
@ -2676,11 +2679,9 @@ def scourUnitlessLength(length, needsRendererWorkaround=False, isControlPoint=Fa
|
||||||
sci = six.text_type(length) + 'e' + six.text_type(exponent)
|
sci = six.text_type(length) + 'e' + six.text_type(exponent)
|
||||||
|
|
||||||
if len(sci) < len(nonsci):
|
if len(sci) < len(nonsci):
|
||||||
return sci
|
return_value = sci
|
||||||
else:
|
|
||||||
return nonsci
|
return return_value
|
||||||
else:
|
|
||||||
return nonsci
|
|
||||||
|
|
||||||
|
|
||||||
def reducePrecision(element):
|
def reducePrecision(element):
|
||||||
|
|
@ -3057,7 +3058,7 @@ def properlySizeDoc(docElement, options):
|
||||||
# else we have a statically sized image and we should try to remedy that
|
# else we have a statically sized image and we should try to remedy that
|
||||||
|
|
||||||
# parse viewBox attribute
|
# parse viewBox attribute
|
||||||
vbSep = re.split("\\s*\\,?\\s*", docElement.getAttribute('viewBox'), 3)
|
vbSep = re.split('[, ]+', docElement.getAttribute('viewBox'))
|
||||||
# if we have a valid viewBox we need to check it
|
# if we have a valid viewBox we need to check it
|
||||||
vbWidth, vbHeight = 0, 0
|
vbWidth, vbHeight = 0, 0
|
||||||
if len(vbSep) == 4:
|
if len(vbSep) == 4:
|
||||||
|
|
@ -3516,6 +3517,11 @@ def scourString(in_string, options=None):
|
||||||
'x1', 'y1', 'x2', 'y2', 'fx', 'fy', 'offset']:
|
'x1', 'y1', 'x2', 'y2', 'fx', 'fy', 'offset']:
|
||||||
if elem.getAttribute(attr) != '':
|
if elem.getAttribute(attr) != '':
|
||||||
elem.setAttribute(attr, scourLength(elem.getAttribute(attr)))
|
elem.setAttribute(attr, scourLength(elem.getAttribute(attr)))
|
||||||
|
viewBox = doc.documentElement.getAttribute('viewBox')
|
||||||
|
if viewBox:
|
||||||
|
lengths = re.split('[, ]+', viewBox)
|
||||||
|
lengths = [scourUnitlessLength(lenght) for lenght in lengths]
|
||||||
|
doc.documentElement.setAttribute('viewBox', ' '.join(lengths))
|
||||||
|
|
||||||
# more length scouring in this function
|
# more length scouring in this function
|
||||||
_num_bytes_saved_in_lengths = reducePrecision(doc.documentElement)
|
_num_bytes_saved_in_lengths = reducePrecision(doc.documentElement)
|
||||||
|
|
|
||||||
72
testscour.py
72
testscour.py
|
|
@ -956,6 +956,62 @@ class LimitPrecisionInPathData(unittest.TestCase):
|
||||||
'Not correctly limiting precision on path data')
|
'Not correctly limiting precision on path data')
|
||||||
|
|
||||||
|
|
||||||
|
class KeepPrecisionInPathDataIfSameLength(unittest.TestCase):
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
doc = scourXmlFile('unittests/path-precision.svg', parse_args(['--set-precision=1']))
|
||||||
|
paths = doc.getElementsByTagNameNS(SVGNS, 'path')
|
||||||
|
for path in paths[1:3]:
|
||||||
|
self.assertEqual(path.getAttribute('d'), "m1 12 123 1e3 1e4 1e5",
|
||||||
|
'Precision not correctly reduced with "--set-precision=1" '
|
||||||
|
'for path with ID ' + path.getAttribute('id'))
|
||||||
|
self.assertEqual(paths[4].getAttribute('d'), "m-1-12-123-1e3 -1e4 -1e5",
|
||||||
|
'Precision not correctly reduced with "--set-precision=1" '
|
||||||
|
'for path with ID ' + paths[4].getAttribute('id'))
|
||||||
|
self.assertEqual(paths[5].getAttribute('d'), "m123 101-123-101",
|
||||||
|
'Precision not correctly reduced with "--set-precision=1" '
|
||||||
|
'for path with ID ' + paths[5].getAttribute('id'))
|
||||||
|
|
||||||
|
doc = scourXmlFile('unittests/path-precision.svg', parse_args(['--set-precision=2']))
|
||||||
|
paths = doc.getElementsByTagNameNS(SVGNS, 'path')
|
||||||
|
for path in paths[1:3]:
|
||||||
|
self.assertEqual(path.getAttribute('d'), "m1 12 123 1234 12345 1.2e5",
|
||||||
|
'Precision not correctly reduced with "--set-precision=2" '
|
||||||
|
'for path with ID ' + path.getAttribute('id'))
|
||||||
|
self.assertEqual(paths[4].getAttribute('d'), "m-1-12-123-1234-12345-1.2e5",
|
||||||
|
'Precision not correctly reduced with "--set-precision=2" '
|
||||||
|
'for path with ID ' + paths[4].getAttribute('id'))
|
||||||
|
self.assertEqual(paths[5].getAttribute('d'), "m123 101-123-101",
|
||||||
|
'Precision not correctly reduced with "--set-precision=2" '
|
||||||
|
'for path with ID ' + paths[5].getAttribute('id'))
|
||||||
|
|
||||||
|
doc = scourXmlFile('unittests/path-precision.svg', parse_args(['--set-precision=3']))
|
||||||
|
paths = doc.getElementsByTagNameNS(SVGNS, 'path')
|
||||||
|
for path in paths[1:3]:
|
||||||
|
self.assertEqual(path.getAttribute('d'), "m1 12 123 1234 12345 123456",
|
||||||
|
'Precision not correctly reduced with "--set-precision=3" '
|
||||||
|
'for path with ID ' + path.getAttribute('id'))
|
||||||
|
self.assertEqual(paths[4].getAttribute('d'), "m-1-12-123-1234-12345-123456",
|
||||||
|
'Precision not correctly reduced with "--set-precision=3" '
|
||||||
|
'for path with ID ' + paths[4].getAttribute('id'))
|
||||||
|
self.assertEqual(paths[5].getAttribute('d'), "m123 101-123-101",
|
||||||
|
'Precision not correctly reduced with "--set-precision=3" '
|
||||||
|
'for path with ID ' + paths[5].getAttribute('id'))
|
||||||
|
|
||||||
|
doc = scourXmlFile('unittests/path-precision.svg', parse_args(['--set-precision=4']))
|
||||||
|
paths = doc.getElementsByTagNameNS(SVGNS, 'path')
|
||||||
|
for path in paths[1:3]:
|
||||||
|
self.assertEqual(path.getAttribute('d'), "m1 12 123 1234 12345 123456",
|
||||||
|
'Precision not correctly reduced with "--set-precision=4" '
|
||||||
|
'for path with ID ' + path.getAttribute('id'))
|
||||||
|
self.assertEqual(paths[4].getAttribute('d'), "m-1-12-123-1234-12345-123456",
|
||||||
|
'Precision not correctly reduced with "--set-precision=4" '
|
||||||
|
'for path with ID ' + paths[4].getAttribute('id'))
|
||||||
|
self.assertEqual(paths[5].getAttribute('d'), "m123.5 101-123.5-101",
|
||||||
|
'Precision not correctly reduced with "--set-precision=4" '
|
||||||
|
'for path with ID ' + paths[5].getAttribute('id'))
|
||||||
|
|
||||||
|
|
||||||
class RemoveEmptyLineSegmentsFromPath(unittest.TestCase):
|
class RemoveEmptyLineSegmentsFromPath(unittest.TestCase):
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
|
|
@ -2449,7 +2505,21 @@ class EmbedRasters(unittest.TestCase):
|
||||||
"Raster image from remote path '" + href + "' not embedded.")
|
"Raster image from remote path '" + href + "' not embedded.")
|
||||||
|
|
||||||
|
|
||||||
# TODO: write tests for --enable-viewboxing
|
class ViewBox(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_viewbox_create(self):
|
||||||
|
doc = scourXmlFile('unittests/viewbox-create.svg', parse_args(['--enable-viewboxing']))
|
||||||
|
viewBox = doc.documentElement.getAttribute('viewBox')
|
||||||
|
self.assertEqual(viewBox, '0 0 123.46 654.32', "viewBox not properly created with '--enable-viewboxing'.")
|
||||||
|
|
||||||
|
def test_viewbox_remove_width_and_height(self):
|
||||||
|
doc = scourXmlFile('unittests/viewbox-remove.svg', parse_args(['--enable-viewboxing']))
|
||||||
|
width = doc.documentElement.getAttribute('width')
|
||||||
|
height = doc.documentElement.getAttribute('height')
|
||||||
|
self.assertEqual(width, '', "width not removed with '--enable-viewboxing'.")
|
||||||
|
self.assertEqual(height, '', "height not removed with '--enable-viewboxing'.")
|
||||||
|
|
||||||
|
|
||||||
# TODO: write tests for --keep-editor-data
|
# TODO: write tests for --keep-editor-data
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
||||||
1
tox.ini
1
tox.ini
|
|
@ -5,6 +5,7 @@ envlist =
|
||||||
py33
|
py33
|
||||||
py34
|
py34
|
||||||
py35
|
py35
|
||||||
|
py36
|
||||||
flake8
|
flake8
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,11 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" version="1.1">
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M 100.0000001 99.9999999 h100.01 v123456789.123456789 h-100 z" fill="red" />
|
<path id="p0" d="M 100.0000001 99.9999999 h100.01 v123456789.123456789 h-100 z" />
|
||||||
|
|
||||||
|
<path id="p1" d="m 1 12 123 1234 12345 123456 " />
|
||||||
|
<path id="p2" d="m 1.0 12.0 123.0 1234.0 12345.0 123456.0" />
|
||||||
|
<path id="p3" d="m 01 012 0123 01234 012345 0123456 " />
|
||||||
|
<path id="p4" d="m -1 -12 -123 -1234 -12345 -123456 " />
|
||||||
|
|
||||||
|
<path id="p6" d="m 123.456 101.001 -123.456 -101.001" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 227 B After Width: | Height: | Size: 517 B |
3
unittests/viewbox-create.svg
Normal file
3
unittests/viewbox-create.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="123.456" height="654.321">
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 120 B |
3
unittests/viewbox-remove.svg
Normal file
3
unittests/viewbox-remove.svg
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="123.456" height="654.321" viewBox="0 0 123.456 654.321">
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 150 B |
Loading…
Add table
Add a link
Reference in a new issue