Merge pull request #53 from codedread/detect_flowtext
add option to check and warn or bail out on flowtext
This commit is contained in:
commit
1a8ece216d
5 changed files with 230 additions and 51 deletions
6
Makefile
6
Makefile
|
|
@ -17,3 +17,9 @@ test_version:
|
||||||
|
|
||||||
test_help:
|
test_help:
|
||||||
PYTHONPATH=. python -m scour.scour --help
|
PYTHONPATH=. python -m scour.scour --help
|
||||||
|
|
||||||
|
test_error_on_flowtext:
|
||||||
|
# this is fine ..
|
||||||
|
PYTHONPATH=. scour --error-on-flowtext unittests/flowtext-less.svg /dev/null
|
||||||
|
# .. and this should bail out!
|
||||||
|
PYTHONPATH=. scour --error-on-flowtext unittests/flowtext.svg /dev/null
|
||||||
|
|
|
||||||
|
|
@ -2880,6 +2880,16 @@ def scourString(in_string, options=None):
|
||||||
global numBytesSavedInTransforms
|
global numBytesSavedInTransforms
|
||||||
doc = xml.dom.minidom.parseString(in_string)
|
doc = xml.dom.minidom.parseString(in_string)
|
||||||
|
|
||||||
|
# determine number of flowRoot elements in input document
|
||||||
|
# flowRoot elements don't render at all on current browsers (04/2016)
|
||||||
|
cnt_flowText_el = len(doc.getElementsByTagName('flowRoot'))
|
||||||
|
if cnt_flowText_el:
|
||||||
|
errmsg = "SVG input document uses {} flow text elements, which won't render on browsers!".format(cnt_flowText_el)
|
||||||
|
if options.error_on_flowtext:
|
||||||
|
raise Exception(errmsg)
|
||||||
|
else:
|
||||||
|
print("WARNING: {}".format(errmsg))
|
||||||
|
|
||||||
# remove <metadata> if the user wants to
|
# remove <metadata> if the user wants to
|
||||||
if options.remove_metadata:
|
if options.remove_metadata:
|
||||||
removeMetadataElements(doc)
|
removeMetadataElements(doc)
|
||||||
|
|
@ -3225,6 +3235,11 @@ _option_group_ids.add_option("--protect-ids-prefix",
|
||||||
help="don't remove IDs starting with the given prefix")
|
help="don't remove IDs starting with the given prefix")
|
||||||
_options_parser.add_option_group(_option_group_ids)
|
_options_parser.add_option_group(_option_group_ids)
|
||||||
|
|
||||||
|
_option_group_compatibility = optparse.OptionGroup(_options_parser, "SVG compatibility checks")
|
||||||
|
_option_group_compatibility.add_option("--error-on-flowtext",
|
||||||
|
action="store_true", dest="error_on_flowtext", default=False,
|
||||||
|
help="In case the input SVG uses flow text, bail out with error. Otherwise only warn. (default: False)")
|
||||||
|
_options_parser.add_option_group(_option_group_compatibility)
|
||||||
|
|
||||||
|
|
||||||
def maybe_gziped_file(filename, mode="r"):
|
def maybe_gziped_file(filename, mode="r"):
|
||||||
|
|
|
||||||
116
testscour.py
116
testscour.py
|
|
@ -34,9 +34,9 @@ from scour.scour import scourXmlFile, scourString, parse_args, makeWellFormed
|
||||||
|
|
||||||
SVGNS = 'http://www.w3.org/2000/svg'
|
SVGNS = 'http://www.w3.org/2000/svg'
|
||||||
|
|
||||||
# I couldn't figure out how to get ElementTree to work with the following XPath
|
# I couldn't figure out how to get ElementTree to work with the following XPath
|
||||||
# "//*[namespace-uri()='http://example.com']"
|
# "//*[namespace-uri()='http://example.com']"
|
||||||
# so I decided to use minidom and this helper function that performs a test on a given node
|
# so I decided to use minidom and this helper function that performs a test on a given node
|
||||||
# and all its children
|
# and all its children
|
||||||
# func must return either True (if pass) or False (if fail)
|
# func must return either True (if pass) or False (if fail)
|
||||||
def walkTree(elem, func):
|
def walkTree(elem, func):
|
||||||
|
|
@ -73,64 +73,64 @@ class InvalidOptions(unittest.TestCase):
|
||||||
|
|
||||||
class NoInkscapeElements(unittest.TestCase):
|
class NoInkscapeElements(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/sodipodi.svg').documentElement,
|
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/sodipodi.svg').documentElement,
|
||||||
lambda e: e.namespaceURI != 'http://www.inkscape.org/namespaces/inkscape'), False,
|
lambda e: e.namespaceURI != 'http://www.inkscape.org/namespaces/inkscape'), False,
|
||||||
'Found Inkscape elements' )
|
'Found Inkscape elements' )
|
||||||
|
|
||||||
class NoSodipodiElements(unittest.TestCase):
|
class NoSodipodiElements(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/sodipodi.svg').documentElement,
|
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/sodipodi.svg').documentElement,
|
||||||
lambda e: e.namespaceURI != 'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd'), False,
|
lambda e: e.namespaceURI != 'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd'), False,
|
||||||
'Found Sodipodi elements' )
|
'Found Sodipodi elements' )
|
||||||
|
|
||||||
class NoAdobeIllustratorElements(unittest.TestCase):
|
class NoAdobeIllustratorElements(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
||||||
lambda e: e.namespaceURI != 'http://ns.adobe.com/AdobeIllustrator/10.0/'), False,
|
lambda e: e.namespaceURI != 'http://ns.adobe.com/AdobeIllustrator/10.0/'), False,
|
||||||
'Found Adobe Illustrator elements' )
|
'Found Adobe Illustrator elements' )
|
||||||
class NoAdobeGraphsElements(unittest.TestCase):
|
class NoAdobeGraphsElements(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
||||||
lambda e: e.namespaceURI != 'http://ns.adobe.com/Graphs/1.0/'), False,
|
lambda e: e.namespaceURI != 'http://ns.adobe.com/Graphs/1.0/'), False,
|
||||||
'Found Adobe Graphs elements' )
|
'Found Adobe Graphs elements' )
|
||||||
class NoAdobeSVGViewerElements(unittest.TestCase):
|
class NoAdobeSVGViewerElements(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
||||||
lambda e: e.namespaceURI != 'http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/'), False,
|
lambda e: e.namespaceURI != 'http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/'), False,
|
||||||
'Found Adobe SVG Viewer elements' )
|
'Found Adobe SVG Viewer elements' )
|
||||||
class NoAdobeVariablesElements(unittest.TestCase):
|
class NoAdobeVariablesElements(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
||||||
lambda e: e.namespaceURI != 'http://ns.adobe.com/Variables/1.0/'), False,
|
lambda e: e.namespaceURI != 'http://ns.adobe.com/Variables/1.0/'), False,
|
||||||
'Found Adobe Variables elements' )
|
'Found Adobe Variables elements' )
|
||||||
class NoAdobeSaveForWebElements(unittest.TestCase):
|
class NoAdobeSaveForWebElements(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
||||||
lambda e: e.namespaceURI != 'http://ns.adobe.com/SaveForWeb/1.0/'), False,
|
lambda e: e.namespaceURI != 'http://ns.adobe.com/SaveForWeb/1.0/'), False,
|
||||||
'Found Adobe Save For Web elements' )
|
'Found Adobe Save For Web elements' )
|
||||||
class NoAdobeExtensibilityElements(unittest.TestCase):
|
class NoAdobeExtensibilityElements(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
||||||
lambda e: e.namespaceURI != 'http://ns.adobe.com/Extensibility/1.0/'), False,
|
lambda e: e.namespaceURI != 'http://ns.adobe.com/Extensibility/1.0/'), False,
|
||||||
'Found Adobe Extensibility elements' )
|
'Found Adobe Extensibility elements' )
|
||||||
class NoAdobeFlowsElements(unittest.TestCase):
|
class NoAdobeFlowsElements(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
||||||
lambda e: e.namespaceURI != 'http://ns.adobe.com/Flows/1.0/'), False,
|
lambda e: e.namespaceURI != 'http://ns.adobe.com/Flows/1.0/'), False,
|
||||||
'Found Adobe Flows elements' )
|
'Found Adobe Flows elements' )
|
||||||
class NoAdobeImageReplacementElements(unittest.TestCase):
|
class NoAdobeImageReplacementElements(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
||||||
lambda e: e.namespaceURI != 'http://ns.adobe.com/ImageReplacement/1.0/'), False,
|
lambda e: e.namespaceURI != 'http://ns.adobe.com/ImageReplacement/1.0/'), False,
|
||||||
'Found Adobe Image Replacement elements' )
|
'Found Adobe Image Replacement elements' )
|
||||||
class NoAdobeCustomElements(unittest.TestCase):
|
class NoAdobeCustomElements(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
||||||
lambda e: e.namespaceURI != 'http://ns.adobe.com/GenericCustomNamespace/1.0/'), False,
|
lambda e: e.namespaceURI != 'http://ns.adobe.com/GenericCustomNamespace/1.0/'), False,
|
||||||
'Found Adobe Custom elements' )
|
'Found Adobe Custom elements' )
|
||||||
class NoAdobeXPathElements(unittest.TestCase):
|
class NoAdobeXPathElements(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/adobe.svg').documentElement,
|
||||||
lambda e: e.namespaceURI != 'http://ns.adobe.com/XPath/1.0/'), False,
|
lambda e: e.namespaceURI != 'http://ns.adobe.com/XPath/1.0/'), False,
|
||||||
'Found Adobe XPath elements' )
|
'Found Adobe XPath elements' )
|
||||||
|
|
||||||
|
|
@ -200,7 +200,7 @@ class KeepUnreferencedIDsWhenEnabled(unittest.TestCase):
|
||||||
doc = scour.scourXmlFile('unittests/ids-to-strip.svg')
|
doc = scour.scourXmlFile('unittests/ids-to-strip.svg')
|
||||||
self.assertEqual(doc.getElementsByTagNameNS(SVGNS, 'svg')[0].getAttribute('id'), 'boo',
|
self.assertEqual(doc.getElementsByTagNameNS(SVGNS, 'svg')[0].getAttribute('id'), 'boo',
|
||||||
'<svg> ID stripped when it should be disabled' )
|
'<svg> ID stripped when it should be disabled' )
|
||||||
|
|
||||||
class RemoveUnreferencedIDsWhenEnabled(unittest.TestCase):
|
class RemoveUnreferencedIDsWhenEnabled(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
doc = scour.scourXmlFile('unittests/ids-to-strip.svg',
|
doc = scour.scourXmlFile('unittests/ids-to-strip.svg',
|
||||||
|
|
@ -269,9 +269,9 @@ class NoInkscapeNamespaceDecl(unittest.TestCase):
|
||||||
self.assertNotEqual(attrs.item(i).nodeValue,
|
self.assertNotEqual(attrs.item(i).nodeValue,
|
||||||
'http://www.inkscape.org/namespaces/inkscape',
|
'http://www.inkscape.org/namespaces/inkscape',
|
||||||
'Inkscape namespace declaration found' )
|
'Inkscape namespace declaration found' )
|
||||||
|
|
||||||
class NoSodipodiAttributes(unittest.TestCase):
|
class NoSodipodiAttributes(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
def findSodipodiAttr(elem):
|
def findSodipodiAttr(elem):
|
||||||
attrs = elem.attributes
|
attrs = elem.attributes
|
||||||
if attrs == None: return True
|
if attrs == None: return True
|
||||||
|
|
@ -279,12 +279,12 @@ class NoSodipodiAttributes(unittest.TestCase):
|
||||||
if attrs.item(i).namespaceURI == 'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd':
|
if attrs.item(i).namespaceURI == 'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd':
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/sodipodi.svg').documentElement,
|
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/sodipodi.svg').documentElement,
|
||||||
findSodipodiAttr), False,
|
findSodipodiAttr), False,
|
||||||
'Found Sodipodi attributes' )
|
'Found Sodipodi attributes' )
|
||||||
|
|
||||||
class NoInkscapeAttributes(unittest.TestCase):
|
class NoInkscapeAttributes(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
def findInkscapeAttr(elem):
|
def findInkscapeAttr(elem):
|
||||||
attrs = elem.attributes
|
attrs = elem.attributes
|
||||||
if attrs == None: return True
|
if attrs == None: return True
|
||||||
|
|
@ -292,7 +292,7 @@ class NoInkscapeAttributes(unittest.TestCase):
|
||||||
if attrs.item(i).namespaceURI == 'http://www.inkscape.org/namespaces/inkscape':
|
if attrs.item(i).namespaceURI == 'http://www.inkscape.org/namespaces/inkscape':
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/inkscape.svg').documentElement,
|
self.assertNotEqual(walkTree(scour.scourXmlFile('unittests/inkscape.svg').documentElement,
|
||||||
findInkscapeAttr), False,
|
findInkscapeAttr), False,
|
||||||
'Found Inkscape attributes' )
|
'Found Inkscape attributes' )
|
||||||
|
|
||||||
|
|
@ -305,7 +305,7 @@ class KeepInkscapeNamespaceDeclarationsWhenKeepEditorData(unittest.TestCase):
|
||||||
for i in range(len(attrs)):
|
for i in range(len(attrs)):
|
||||||
if attrs.item(i).nodeValue == 'http://www.inkscape.org/namespaces/inkscape':
|
if attrs.item(i).nodeValue == 'http://www.inkscape.org/namespaces/inkscape':
|
||||||
FoundNamespace = True
|
FoundNamespace = True
|
||||||
break
|
break
|
||||||
self.assertEqual(True, FoundNamespace,
|
self.assertEqual(True, FoundNamespace,
|
||||||
"Did not find Inkscape namespace declaration when using --keep-editor-data")
|
"Did not find Inkscape namespace declaration when using --keep-editor-data")
|
||||||
return False
|
return False
|
||||||
|
|
@ -319,7 +319,7 @@ class KeepSodipodiNamespaceDeclarationsWhenKeepEditorData(unittest.TestCase):
|
||||||
for i in range(len(attrs)):
|
for i in range(len(attrs)):
|
||||||
if attrs.item(i).nodeValue == 'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd':
|
if attrs.item(i).nodeValue == 'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd':
|
||||||
FoundNamespace = True
|
FoundNamespace = True
|
||||||
break
|
break
|
||||||
self.assertEqual(True, FoundNamespace,
|
self.assertEqual(True, FoundNamespace,
|
||||||
"Did not find Sodipodi namespace declaration when using --keep-editor-data")
|
"Did not find Sodipodi namespace declaration when using --keep-editor-data")
|
||||||
return False
|
return False
|
||||||
|
|
@ -330,13 +330,13 @@ class KeepReferencedFonts(unittest.TestCase):
|
||||||
fonts = doc.documentElement.getElementsByTagNameNS(SVGNS,'font')
|
fonts = doc.documentElement.getElementsByTagNameNS(SVGNS,'font')
|
||||||
self.assertEqual(len(fonts), 1,
|
self.assertEqual(len(fonts), 1,
|
||||||
'Font wrongly removed from <defs>' )
|
'Font wrongly removed from <defs>' )
|
||||||
|
|
||||||
class ConvertStyleToAttrs(unittest.TestCase):
|
class ConvertStyleToAttrs(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
doc = scour.scourXmlFile('unittests/stroke-transparent.svg')
|
doc = scour.scourXmlFile('unittests/stroke-transparent.svg')
|
||||||
self.assertEqual(doc.getElementsByTagNameNS(SVGNS, 'path')[0].getAttribute('style'), '',
|
self.assertEqual(doc.getElementsByTagNameNS(SVGNS, 'path')[0].getAttribute('style'), '',
|
||||||
'style attribute not emptied' )
|
'style attribute not emptied' )
|
||||||
|
|
||||||
class RemoveStrokeWhenStrokeTransparent(unittest.TestCase):
|
class RemoveStrokeWhenStrokeTransparent(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
doc = scour.scourXmlFile('unittests/stroke-transparent.svg')
|
doc = scour.scourXmlFile('unittests/stroke-transparent.svg')
|
||||||
|
|
@ -414,7 +414,7 @@ class RemoveStrokeWhenStrokeNone(unittest.TestCase):
|
||||||
doc = scour.scourXmlFile('unittests/stroke-none.svg')
|
doc = scour.scourXmlFile('unittests/stroke-none.svg')
|
||||||
self.assertEqual(doc.getElementsByTagNameNS(SVGNS, 'path')[0].getAttribute('stroke'), '',
|
self.assertEqual(doc.getElementsByTagNameNS(SVGNS, 'path')[0].getAttribute('stroke'), '',
|
||||||
'stroke attribute not emptied when no stroke' )
|
'stroke attribute not emptied when no stroke' )
|
||||||
|
|
||||||
class RemoveStrokeWidthWhenStrokeNone(unittest.TestCase):
|
class RemoveStrokeWidthWhenStrokeNone(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
doc = scour.scourXmlFile('unittests/stroke-none.svg')
|
doc = scour.scourXmlFile('unittests/stroke-none.svg')
|
||||||
|
|
@ -456,7 +456,7 @@ class RemoveFillRuleWhenFillNone(unittest.TestCase):
|
||||||
doc = scour.scourXmlFile('unittests/fill-none.svg')
|
doc = scour.scourXmlFile('unittests/fill-none.svg')
|
||||||
self.assertEqual(doc.getElementsByTagNameNS(SVGNS, 'path')[0].getAttribute('fill-rule'), '',
|
self.assertEqual(doc.getElementsByTagNameNS(SVGNS, 'path')[0].getAttribute('fill-rule'), '',
|
||||||
'fill-rule attribute not emptied when no fill' )
|
'fill-rule attribute not emptied when no fill' )
|
||||||
|
|
||||||
class RemoveFillOpacityWhenFillNone(unittest.TestCase):
|
class RemoveFillOpacityWhenFillNone(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
doc = scour.scourXmlFile('unittests/fill-none.svg')
|
doc = scour.scourXmlFile('unittests/fill-none.svg')
|
||||||
|
|
@ -481,7 +481,7 @@ class ConvertFillRuleOpacityPropertyToAttr(unittest.TestCase):
|
||||||
doc = scour.scourXmlFile('unittests/fill-none.svg')
|
doc = scour.scourXmlFile('unittests/fill-none.svg')
|
||||||
self.assertEqual(doc.getElementsByTagNameNS(SVGNS, 'path')[1].getAttribute('fill-rule'), 'evenodd',
|
self.assertEqual(doc.getElementsByTagNameNS(SVGNS, 'path')[1].getAttribute('fill-rule'), 'evenodd',
|
||||||
'fill-rule property not converted to XML attribute' )
|
'fill-rule property not converted to XML attribute' )
|
||||||
|
|
||||||
class CollapseSinglyReferencedGradients(unittest.TestCase):
|
class CollapseSinglyReferencedGradients(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
doc = scour.scourXmlFile('unittests/collapse-gradients.svg')
|
doc = scour.scourXmlFile('unittests/collapse-gradients.svg')
|
||||||
|
|
@ -491,7 +491,7 @@ class CollapseSinglyReferencedGradients(unittest.TestCase):
|
||||||
class InheritGradientUnitsUponCollapsing(unittest.TestCase):
|
class InheritGradientUnitsUponCollapsing(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
doc = scour.scourXmlFile('unittests/collapse-gradients.svg')
|
doc = scour.scourXmlFile('unittests/collapse-gradients.svg')
|
||||||
self.assertEqual(doc.getElementsByTagNameNS(SVGNS, 'radialGradient')[0].getAttribute('gradientUnits'),
|
self.assertEqual(doc.getElementsByTagNameNS(SVGNS, 'radialGradient')[0].getAttribute('gradientUnits'),
|
||||||
'userSpaceOnUse',
|
'userSpaceOnUse',
|
||||||
'gradientUnits not properly inherited when collapsing gradients' )
|
'gradientUnits not properly inherited when collapsing gradients' )
|
||||||
|
|
||||||
|
|
@ -525,9 +525,9 @@ class RemoveDelimiterBeforeNegativeCoordsInPath(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
doc = scour.scourXmlFile('unittests/path-truncate-zeros.svg')
|
doc = scour.scourXmlFile('unittests/path-truncate-zeros.svg')
|
||||||
path = doc.getElementsByTagNameNS(SVGNS, 'path')[0].getAttribute('d')
|
path = doc.getElementsByTagNameNS(SVGNS, 'path')[0].getAttribute('d')
|
||||||
self.assertEqual(path[4], '-',
|
self.assertEqual(path[4], '-',
|
||||||
'Delimiters not removed before negative coordinates in path data' )
|
'Delimiters not removed before negative coordinates in path data' )
|
||||||
|
|
||||||
class UseScientificNotationToShortenCoordsInPath(unittest.TestCase):
|
class UseScientificNotationToShortenCoordsInPath(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
doc = scour.scourXmlFile('unittests/path-use-scientific-notation.svg')
|
doc = scour.scourXmlFile('unittests/path-use-scientific-notation.svg')
|
||||||
|
|
@ -552,7 +552,7 @@ class RoundPathData(unittest.TestCase):
|
||||||
'Not rounding down' )
|
'Not rounding down' )
|
||||||
self.assertEqual(float(path[0][1][1]), 100.0,
|
self.assertEqual(float(path[0][1][1]), 100.0,
|
||||||
'Not rounding up' )
|
'Not rounding up' )
|
||||||
|
|
||||||
class LimitPrecisionInPathData(unittest.TestCase):
|
class LimitPrecisionInPathData(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
doc = scour.scourXmlFile('unittests/path-precision.svg')
|
doc = scour.scourXmlFile('unittests/path-precision.svg')
|
||||||
|
|
@ -629,7 +629,7 @@ class HandleSciNoInPathData(unittest.TestCase):
|
||||||
doc = scour.scourXmlFile('unittests/path-sn.svg')
|
doc = scour.scourXmlFile('unittests/path-sn.svg')
|
||||||
self.assertEqual( len(doc.getElementsByTagNameNS(SVGNS, 'path')), 1,
|
self.assertEqual( len(doc.getElementsByTagNameNS(SVGNS, 'path')), 1,
|
||||||
'Did not handle scientific notation in path data' )
|
'Did not handle scientific notation in path data' )
|
||||||
|
|
||||||
class TranslateRGBIntoHex(unittest.TestCase):
|
class TranslateRGBIntoHex(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
elem = scour.scourXmlFile('unittests/color-formats.svg').getElementsByTagNameNS(SVGNS, 'rect')[0]
|
elem = scour.scourXmlFile('unittests/color-formats.svg').getElementsByTagNameNS(SVGNS, 'rect')[0]
|
||||||
|
|
@ -671,13 +671,13 @@ class AllowQuotEntitiesInUrl(unittest.TestCase):
|
||||||
grads = scour.scourXmlFile('unittests/quot-in-url.svg').getElementsByTagNameNS(SVGNS, 'linearGradient')
|
grads = scour.scourXmlFile('unittests/quot-in-url.svg').getElementsByTagNameNS(SVGNS, 'linearGradient')
|
||||||
self.assertEqual( len(grads), 1,
|
self.assertEqual( len(grads), 1,
|
||||||
'Removed referenced gradient when " was in the url')
|
'Removed referenced gradient when " was in the url')
|
||||||
|
|
||||||
class RemoveFontStylesFromNonTextShapes(unittest.TestCase):
|
class RemoveFontStylesFromNonTextShapes(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
r = scour.scourXmlFile('unittests/font-styles.svg').getElementsByTagNameNS(SVGNS, 'rect')[0]
|
r = scour.scourXmlFile('unittests/font-styles.svg').getElementsByTagNameNS(SVGNS, 'rect')[0]
|
||||||
self.assertEqual( r.getAttribute('font-size'), '',
|
self.assertEqual( r.getAttribute('font-size'), '',
|
||||||
'font-size not removed from rect' )
|
'font-size not removed from rect' )
|
||||||
|
|
||||||
class CollapseConsecutiveHLinesSegments(unittest.TestCase):
|
class CollapseConsecutiveHLinesSegments(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
p = scour.scourXmlFile('unittests/consecutive-hlines.svg').getElementsByTagNameNS(SVGNS, 'path')[0]
|
p = scour.scourXmlFile('unittests/consecutive-hlines.svg').getElementsByTagNameNS(SVGNS, 'path')[0]
|
||||||
|
|
@ -689,7 +689,7 @@ class CollapseConsecutiveHLinesCoords(unittest.TestCase):
|
||||||
p = scour.scourXmlFile('unittests/consecutive-hlines.svg').getElementsByTagNameNS(SVGNS, 'path')[1]
|
p = scour.scourXmlFile('unittests/consecutive-hlines.svg').getElementsByTagNameNS(SVGNS, 'path')[1]
|
||||||
self.assertEqual( p.getAttribute('d'), 'm100 300h200v100h-200z',
|
self.assertEqual( p.getAttribute('d'), 'm100 300h200v100h-200z',
|
||||||
'Did not collapse consecutive hlines coordinates')
|
'Did not collapse consecutive hlines coordinates')
|
||||||
|
|
||||||
class DoNotCollapseConsecutiveHLinesSegsWithDifferingSigns(unittest.TestCase):
|
class DoNotCollapseConsecutiveHLinesSegsWithDifferingSigns(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
p = scour.scourXmlFile('unittests/consecutive-hlines.svg').getElementsByTagNameNS(SVGNS, 'path')[2]
|
p = scour.scourXmlFile('unittests/consecutive-hlines.svg').getElementsByTagNameNS(SVGNS, 'path')[2]
|
||||||
|
|
@ -699,9 +699,9 @@ class DoNotCollapseConsecutiveHLinesSegsWithDifferingSigns(unittest.TestCase):
|
||||||
class ConvertStraightCurvesToLines(unittest.TestCase):
|
class ConvertStraightCurvesToLines(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
p = scour.scourXmlFile('unittests/straight-curve.svg').getElementsByTagNameNS(SVGNS, 'path')[0]
|
p = scour.scourXmlFile('unittests/straight-curve.svg').getElementsByTagNameNS(SVGNS, 'path')[0]
|
||||||
self.assertEqual(p.getAttribute('d'), 'm10 10l40 40 40-40z',
|
self.assertEqual(p.getAttribute('d'), 'm10 10l40 40 40-40z',
|
||||||
'Did not convert straight curves into lines')
|
'Did not convert straight curves into lines')
|
||||||
|
|
||||||
class RemoveUnnecessaryPolygonEndPoint(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]
|
||||||
|
|
@ -713,7 +713,7 @@ class DoNotRemovePolgonLastPoint(unittest.TestCase):
|
||||||
p = scour.scourXmlFile('unittests/polygon.svg').getElementsByTagNameNS(SVGNS, 'polygon')[1]
|
p = scour.scourXmlFile('unittests/polygon.svg').getElementsByTagNameNS(SVGNS, 'polygon')[1]
|
||||||
self.assertEqual(p.getAttribute('points'), '200 50 300 50 300 150 200 150',
|
self.assertEqual(p.getAttribute('points'), '200 50 300 50 300 150 200 150',
|
||||||
'Last point of polygon removed' )
|
'Last point of polygon removed' )
|
||||||
|
|
||||||
class ScourPolygonCoordsSciNo(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]
|
||||||
|
|
@ -770,7 +770,7 @@ class RemoveDuplicateLinearGradients(unittest.TestCase):
|
||||||
lingrads = svgdoc.getElementsByTagNameNS(SVGNS, 'linearGradient')
|
lingrads = svgdoc.getElementsByTagNameNS(SVGNS, 'linearGradient')
|
||||||
self.assertEqual(1, lingrads.length,
|
self.assertEqual(1, lingrads.length,
|
||||||
'Duplicate linear gradient not removed')
|
'Duplicate linear gradient not removed')
|
||||||
|
|
||||||
class RereferenceForLinearGradient(unittest.TestCase):
|
class RereferenceForLinearGradient(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
svgdoc = scour.scourXmlFile('unittests/remove-duplicate-gradients.svg')
|
svgdoc = scour.scourXmlFile('unittests/remove-duplicate-gradients.svg')
|
||||||
|
|
@ -779,14 +779,14 @@ class RereferenceForLinearGradient(unittest.TestCase):
|
||||||
'Rect not changed after removing duplicate linear gradient')
|
'Rect not changed after removing duplicate linear gradient')
|
||||||
self.assertEqual(rects[0].getAttribute('fill'), rects[4].getAttribute('fill'),
|
self.assertEqual(rects[0].getAttribute('fill'), rects[4].getAttribute('fill'),
|
||||||
'Rect not changed after removing duplicate linear gradient')
|
'Rect not changed after removing duplicate linear gradient')
|
||||||
|
|
||||||
class RemoveDuplicateRadialGradients(unittest.TestCase):
|
class RemoveDuplicateRadialGradients(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
svgdoc = scour.scourXmlFile('unittests/remove-duplicate-gradients.svg')
|
svgdoc = scour.scourXmlFile('unittests/remove-duplicate-gradients.svg')
|
||||||
radgrads = svgdoc.getElementsByTagNameNS(SVGNS, 'radialGradient')
|
radgrads = svgdoc.getElementsByTagNameNS(SVGNS, 'radialGradient')
|
||||||
self.assertEqual(1, radgrads.length,
|
self.assertEqual(1, radgrads.length,
|
||||||
'Duplicate radial gradient not removed')
|
'Duplicate radial gradient not removed')
|
||||||
|
|
||||||
class RereferenceForRadialGradient(unittest.TestCase):
|
class RereferenceForRadialGradient(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
svgdoc = scour.scourXmlFile('unittests/remove-duplicate-gradients.svg')
|
svgdoc = scour.scourXmlFile('unittests/remove-duplicate-gradients.svg')
|
||||||
|
|
@ -912,7 +912,7 @@ class CDATAInXml(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
with open('unittests/cdata.svg') as f:
|
with open('unittests/cdata.svg') as f:
|
||||||
lines = scour.scourString(f.read()).splitlines()
|
lines = scour.scourString(f.read()).splitlines()
|
||||||
self.assertEqual( lines[3],
|
self.assertEqual( lines[3],
|
||||||
" alert('pb&j');",
|
" alert('pb&j');",
|
||||||
'CDATA did not come out correctly')
|
'CDATA did not come out correctly')
|
||||||
|
|
||||||
|
|
@ -990,7 +990,7 @@ class RemoveCommonAttributesFromChild(unittest.TestCase):
|
||||||
r = scour.scourXmlFile('unittests/move-common-attributes-to-parent.svg').getElementsByTagNameNS(SVGNS, 'rect')[0]
|
r = scour.scourXmlFile('unittests/move-common-attributes-to-parent.svg').getElementsByTagNameNS(SVGNS, 'rect')[0]
|
||||||
self.assertNotEqual( r.getAttribute('fill'), '#0F0',
|
self.assertNotEqual( r.getAttribute('fill'), '#0F0',
|
||||||
'Did not remove common fill attribute from child')
|
'Did not remove common fill attribute from child')
|
||||||
|
|
||||||
class DontRemoveCommonAttributesIfParentHasTextNodes(unittest.TestCase):
|
class DontRemoveCommonAttributesIfParentHasTextNodes(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
text = scour.scourXmlFile('unittests/move-common-attributes-to-parent.svg').getElementsByTagNameNS(SVGNS, 'text')[0]
|
text = scour.scourXmlFile('unittests/move-common-attributes-to-parent.svg').getElementsByTagNameNS(SVGNS, 'text')[0]
|
||||||
|
|
@ -1002,7 +1002,7 @@ class PropagateCommonAttributesUp(unittest.TestCase):
|
||||||
g = scour.scourXmlFile('unittests/move-common-attributes-to-grandparent.svg').getElementsByTagNameNS(SVGNS, 'g')[0]
|
g = scour.scourXmlFile('unittests/move-common-attributes-to-grandparent.svg').getElementsByTagNameNS(SVGNS, 'g')[0]
|
||||||
self.assertEqual( g.getAttribute('fill'), '#0F0',
|
self.assertEqual( g.getAttribute('fill'), '#0F0',
|
||||||
'Did not move common fill attribute to grandparent')
|
'Did not move common fill attribute to grandparent')
|
||||||
|
|
||||||
class PathEllipticalArcParsingCommaWsp(unittest.TestCase):
|
class PathEllipticalArcParsingCommaWsp(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
p = scour.scourXmlFile('unittests/path-elliptical-arc-parsing.svg').getElementsByTagNameNS(SVGNS, 'path')[0]
|
p = scour.scourXmlFile('unittests/path-elliptical-arc-parsing.svg').getElementsByTagNameNS(SVGNS, 'path')[0]
|
||||||
|
|
@ -1050,9 +1050,9 @@ class DoNotPrettyPrintWhenNestedWhitespacePreserved(unittest.TestCase):
|
||||||
</svg>
|
</svg>
|
||||||
'''.splitlines()
|
'''.splitlines()
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
self.assertEqual( s[i], c[i],
|
self.assertEqual( s[i], c[i],
|
||||||
'Whitespace not preserved when nested for line ' + str(i))
|
'Whitespace not preserved when nested for line ' + str(i))
|
||||||
|
|
||||||
class GetAttrPrefixRight(unittest.TestCase):
|
class GetAttrPrefixRight(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
grad = scour.scourXmlFile('unittests/xml-namespace-attrs.svg').getElementsByTagNameNS(SVGNS, 'linearGradient')[1]
|
grad = scour.scourXmlFile('unittests/xml-namespace-attrs.svg').getElementsByTagNameNS(SVGNS, 'linearGradient')[1]
|
||||||
|
|
@ -1080,7 +1080,7 @@ class EnsureLineEndings(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
with open('unittests/whitespace-important.svg') as f:
|
with open('unittests/whitespace-important.svg') as f:
|
||||||
s = scour.scourString(f.read())
|
s = scour.scourString(f.read())
|
||||||
self.assertEqual( len(s.splitlines()), 4,
|
self.assertEqual( len(s.splitlines()), 4,
|
||||||
'Did not output line ending character correctly')
|
'Did not output line ending character correctly')
|
||||||
|
|
||||||
class XmlEntities(unittest.TestCase):
|
class XmlEntities(unittest.TestCase):
|
||||||
|
|
@ -1091,7 +1091,7 @@ class XmlEntities(unittest.TestCase):
|
||||||
class DoNotStripCommentsOutsideOfRoot(unittest.TestCase):
|
class DoNotStripCommentsOutsideOfRoot(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
doc = scour.scourXmlFile('unittests/comments.svg')
|
doc = scour.scourXmlFile('unittests/comments.svg')
|
||||||
self.assertEqual( doc.childNodes.length, 4,
|
self.assertEqual( doc.childNodes.length, 4,
|
||||||
'Did not include all comment children outside of root')
|
'Did not include all comment children outside of root')
|
||||||
self.assertEqual( doc.childNodes[0].nodeType, 8, 'First node not a comment')
|
self.assertEqual( doc.childNodes[0].nodeType, 8, 'First node not a comment')
|
||||||
self.assertEqual( doc.childNodes[1].nodeType, 8, 'Second node not a comment')
|
self.assertEqual( doc.childNodes[1].nodeType, 8, 'Second node not a comment')
|
||||||
|
|
@ -1100,7 +1100,7 @@ class DoNotStripCommentsOutsideOfRoot(unittest.TestCase):
|
||||||
class DoNotStripDoctype(unittest.TestCase):
|
class DoNotStripDoctype(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
doc = scour.scourXmlFile('unittests/doctype.svg')
|
doc = scour.scourXmlFile('unittests/doctype.svg')
|
||||||
self.assertEqual( doc.childNodes.length, 3,
|
self.assertEqual( doc.childNodes.length, 3,
|
||||||
'Did not include the DOCROOT')
|
'Did not include the DOCROOT')
|
||||||
self.assertEqual( doc.childNodes[0].nodeType, 8, 'First node not a comment')
|
self.assertEqual( doc.childNodes[0].nodeType, 8, 'First node not a comment')
|
||||||
self.assertEqual( doc.childNodes[1].nodeType, 10, 'Second node not a doctype')
|
self.assertEqual( doc.childNodes[1].nodeType, 10, 'Second node not a doctype')
|
||||||
|
|
@ -1229,7 +1229,7 @@ class StyleToAttr(unittest.TestCase):
|
||||||
self.assertEqual(line.getAttribute('marker-start'), 'url(#m)')
|
self.assertEqual(line.getAttribute('marker-start'), 'url(#m)')
|
||||||
self.assertEqual(line.getAttribute('marker-mid'), 'url(#m)')
|
self.assertEqual(line.getAttribute('marker-mid'), 'url(#m)')
|
||||||
self.assertEqual(line.getAttribute('marker-end'), 'url(#m)')
|
self.assertEqual(line.getAttribute('marker-end'), 'url(#m)')
|
||||||
|
|
||||||
class PathEmptyMove(unittest.TestCase):
|
class PathEmptyMove(unittest.TestCase):
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
doc = scour.scourXmlFile('unittests/path-empty-move.svg')
|
doc = scour.scourXmlFile('unittests/path-empty-move.svg')
|
||||||
|
|
@ -1416,6 +1416,20 @@ class DuplicateGradientsUpdateStyle(unittest.TestCase):
|
||||||
self.assertEqual('fill:url(#' + gradientTag.getAttribute('id') + ')', rectTag1.getAttribute('style'),
|
self.assertEqual('fill:url(#' + gradientTag.getAttribute('id') + ')', rectTag1.getAttribute('style'),
|
||||||
'Either of #duplicate-one or #duplicate-two was removed, but style="fill:" was not updated to reflect this')
|
'Either of #duplicate-one or #duplicate-two was removed, but style="fill:" was not updated to reflect this')
|
||||||
|
|
||||||
|
class DocWithFlowtext(unittest.TestCase):
|
||||||
|
def runTest(self):
|
||||||
|
with self.assertRaises(Exception):
|
||||||
|
scour.scourXmlFile('unittests/flowtext.svg',
|
||||||
|
scour.parse_args(['--error-on-flowtext'])[0])
|
||||||
|
|
||||||
|
class DocWithNoFlowtext(unittest.TestCase):
|
||||||
|
def runTest(self):
|
||||||
|
try:
|
||||||
|
scour.scourXmlFile('unittests/flowtext-less.svg',
|
||||||
|
scour.parse_args(['--error-on-flowtext'])[0])
|
||||||
|
except Exception as e:
|
||||||
|
self.fail("exception '{}' was raised, and we didn't expect that!".format(e))
|
||||||
|
|
||||||
# TODO: write tests for --enable-viewboxing
|
# TODO: write tests for --enable-viewboxing
|
||||||
# TODO; write a test for embedding rasters
|
# TODO; write a test for embedding rasters
|
||||||
# TODO: write a test for --disable-embed-rasters
|
# TODO: write a test for --disable-embed-rasters
|
||||||
|
|
|
||||||
66
unittests/flowtext-less.svg
Normal file
66
unittests/flowtext-less.svg
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="210mm"
|
||||||
|
height="297mm"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="flowtext-less.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="0.35"
|
||||||
|
inkscape:cx="350"
|
||||||
|
inkscape:cy="520"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1559"
|
||||||
|
inkscape:window-height="876"
|
||||||
|
inkscape:window-x="41"
|
||||||
|
inkscape:window-y="24"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Ebene 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||||
|
x="142.85715"
|
||||||
|
y="638.07648"
|
||||||
|
id="text2997"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan2999"
|
||||||
|
x="142.85715"
|
||||||
|
y="638.07648">abcd</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.9 KiB |
78
unittests/flowtext.svg
Normal file
78
unittests/flowtext.svg
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="210mm"
|
||||||
|
height="297mm"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.4 r9939"
|
||||||
|
sodipodi:docname="Neues Dokument 1">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="0.35"
|
||||||
|
inkscape:cx="350"
|
||||||
|
inkscape:cy="520"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="936"
|
||||||
|
inkscape:window-height="631"
|
||||||
|
inkscape:window-x="41"
|
||||||
|
inkscape:window-y="24"
|
||||||
|
inkscape:window-maximized="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Ebene 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<flowRoot
|
||||||
|
xml:space="preserve"
|
||||||
|
id="flowRoot2985"
|
||||||
|
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><flowRegion
|
||||||
|
id="flowRegion2987"><rect
|
||||||
|
id="rect2989"
|
||||||
|
width="480"
|
||||||
|
height="262.85715"
|
||||||
|
x="45.714287"
|
||||||
|
y="218.07646" /></flowRegion><flowPara
|
||||||
|
id="flowPara2991">sfdadasd</flowPara><flowPara
|
||||||
|
id="flowPara2993">asdasd</flowPara><flowPara
|
||||||
|
id="flowPara2995">adsa</flowPara></flowRoot> <text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||||
|
x="142.85715"
|
||||||
|
y="638.07648"
|
||||||
|
id="text2997"
|
||||||
|
sodipodi:linespacing="125%"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan2999"
|
||||||
|
x="142.85715"
|
||||||
|
y="638.07648">abcd</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.5 KiB |
Loading…
Add table
Add a link
Reference in a new issue