summaryrefslogtreecommitdiffstats
path: root/svgio/qa/cppunit
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /svgio/qa/cppunit
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'svgio/qa/cppunit')
-rw-r--r--svgio/qa/cppunit/SvgImportTest.cxx1103
-rw-r--r--svgio/qa/cppunit/SvgNumberTest.cxx95
-rw-r--r--svgio/qa/cppunit/SvgRead.cxx127
-rw-r--r--svgio/qa/cppunit/data/47446.svg19
-rw-r--r--svgio/qa/cppunit/data/47446b.svg18
-rw-r--r--svgio/qa/cppunit/data/ClipPathAndParentStyle.svg10
-rw-r--r--svgio/qa/cppunit/data/ClipPathAndStyle.svg13
-rw-r--r--svgio/qa/cppunit/data/ClipPathUsingClipPath.svg24
-rw-r--r--svgio/qa/cppunit/data/ClipRule.svg18
-rw-r--r--svgio/qa/cppunit/data/CssClassRedefinition.svg13
-rw-r--r--svgio/qa/cppunit/data/Drawing_NoWidthHeight.svg12
-rw-r--r--svgio/qa/cppunit/data/Drawing_WithWidthHeight.svg14
-rw-r--r--svgio/qa/cppunit/data/FontsizeKeywords.svg14
-rw-r--r--svgio/qa/cppunit/data/FontsizePercentage.svg3
-rw-r--r--svgio/qa/cppunit/data/FontsizeRelative.svg6
-rw-r--r--svgio/qa/cppunit/data/MarkerOrient.svg22
-rw-r--r--svgio/qa/cppunit/data/RGBAColor.svg4
-rw-r--r--svgio/qa/cppunit/data/RGBColor.svg4
-rw-r--r--svgio/qa/cppunit/data/Rect.svg4
-rw-r--r--svgio/qa/cppunit/data/RectWithParentStyles.svg13
-rw-r--r--svgio/qa/cppunit/data/RectWithStyles.svg4
-rw-r--r--svgio/qa/cppunit/data/RectWithStylesByGroup.svg18
-rw-r--r--svgio/qa/cppunit/data/ShapeWithClipPathAndCssStyle.svg13
-rw-r--r--svgio/qa/cppunit/data/VisiotorTest-Rect.svg4
-rw-r--r--svgio/qa/cppunit/data/em_units.svg14
-rw-r--r--svgio/qa/cppunit/data/i125329.svg12
-rw-r--r--svgio/qa/cppunit/data/markerInCssStyle.svg14
-rw-r--r--svgio/qa/cppunit/data/maskText.svg26
-rw-r--r--svgio/qa/cppunit/data/masking-path-07-b.svg147
-rw-r--r--svgio/qa/cppunit/data/noneColor.svg3
-rw-r--r--svgio/qa/cppunit/data/path.svg3
-rw-r--r--svgio/qa/cppunit/data/symbol.svg11
-rw-r--r--svgio/qa/cppunit/data/tdf101237.svg11
-rw-r--r--svgio/qa/cppunit/data/tdf103888.svg11
-rw-r--r--svgio/qa/cppunit/data/tdf104339.svg65
-rw-r--r--svgio/qa/cppunit/data/tdf123926.svg14
-rw-r--r--svgio/qa/cppunit/data/tdf149880.svg11
-rw-r--r--svgio/qa/cppunit/data/tdf149893.svg3
-rw-r--r--svgio/qa/cppunit/data/tdf45771.svg5
-rw-r--r--svgio/qa/cppunit/data/tdf79163.svg8
-rw-r--r--svgio/qa/cppunit/data/tdf85770.svg7
-rw-r--r--svgio/qa/cppunit/data/tdf87309.svg4
-rw-r--r--svgio/qa/cppunit/data/tdf94765.svg14
-rw-r--r--svgio/qa/cppunit/data/tdf97542_1.svg15
-rw-r--r--svgio/qa/cppunit/data/tdf97542_2.svg15
-rw-r--r--svgio/qa/cppunit/data/tdf97543.svg4
-rw-r--r--svgio/qa/cppunit/data/tdf97936.svg5
-rw-r--r--svgio/qa/cppunit/data/tdf97941.svg6
-rw-r--r--svgio/qa/cppunit/data/tdf99115.svg40
-rw-r--r--svgio/qa/cppunit/data/tdf99994.svg8
-rw-r--r--svgio/qa/cppunit/data/textXmlSpace.svg16
-rw-r--r--svgio/qa/cppunit/data/tspan-fill-opacity.svg15
52 files changed, 2082 insertions, 0 deletions
diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx
new file mode 100644
index 000000000..ed178ffb6
--- /dev/null
+++ b/svgio/qa/cppunit/SvgImportTest.cxx
@@ -0,0 +1,1103 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+#include <test/bootstrapfixture.hxx>
+#include <test/xmltesttools.hxx>
+
+#include <comphelper/seqstream.hxx>
+
+#include <com/sun/star/graphic/SvgTools.hpp>
+#include <com/sun/star/graphic/XPrimitive2D.hpp>
+
+#include <drawinglayer/primitive2d/Tools.hxx>
+#include <drawinglayer/tools/primitive2dxmldump.hxx>
+#include <drawinglayer/primitive2d/Primitive2DContainer.hxx>
+
+#include <memory>
+#include <string_view>
+
+namespace
+{
+
+using namespace css;
+using namespace css::uno;
+using namespace css::io;
+using namespace css::graphic;
+using drawinglayer::primitive2d::Primitive2DSequence;
+using drawinglayer::primitive2d::Primitive2DContainer;
+using drawinglayer::primitive2d::Primitive2DReference;
+
+class Test : public test::BootstrapFixture, public XmlTestTools
+{
+ void checkRectPrimitive(Primitive2DSequence const & rPrimitive);
+
+ void testStyles();
+ void testSymbol();
+ void testTdf87309();
+ void testFontsizeKeywords();
+ void testFontsizePercentage();
+ void testFontsizeRelative();
+ void testMarkerOrient();
+ void testMarkerInCssStyle();
+ void testTextXmlSpace();
+ void testTdf45771();
+ void testTdf97941();
+ void testTdf104339();
+ void testTdf85770();
+ void testTdf79163();
+ void testTdf97542_1();
+ void testTdf97542_2();
+ void testTdf97543();
+ void testRGBColor();
+ void testRGBAColor();
+ void testNoneColor();
+ void testTdf97936();
+ void testTdf149893();
+ void testShapeWithClipPathAndCssStyle();
+ void testClipPathAndParentStyle();
+ void testClipPathAndStyle();
+ void testClipPathUsingClipPath();
+ void testClipRule();
+ void testi125329();
+ void testMaskingPath07b();
+ void test123926();
+ void test47446();
+ void test47446b();
+ void testTdf103888();
+ void testMaskText();
+ void testTdf99994();
+ void testTdf99115();
+ void testTdf101237();
+ void testTdf94765();
+ void testBehaviourWhenWidthAndHeightIsOrIsNotSet();
+ void testTdf97663();
+ void testTdf149880();
+ void testCssClassRedefinition();
+ void testTspanFillOpacity();
+
+ Primitive2DSequence parseSvg(std::u16string_view aSource);
+
+public:
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(testStyles);
+ CPPUNIT_TEST(testSymbol);
+ CPPUNIT_TEST(testTdf87309);
+ CPPUNIT_TEST(testFontsizeKeywords);
+ CPPUNIT_TEST(testFontsizePercentage);
+ CPPUNIT_TEST(testFontsizeRelative);
+ CPPUNIT_TEST(testMarkerOrient);
+ CPPUNIT_TEST(testMarkerInCssStyle);
+ CPPUNIT_TEST(testTextXmlSpace);
+ CPPUNIT_TEST(testTdf45771);
+ CPPUNIT_TEST(testTdf97941);
+ CPPUNIT_TEST(testTdf104339);
+ CPPUNIT_TEST(testTdf85770);
+ CPPUNIT_TEST(testTdf79163);
+ CPPUNIT_TEST(testTdf97542_1);
+ CPPUNIT_TEST(testTdf97542_2);
+ CPPUNIT_TEST(testTdf97543);
+ CPPUNIT_TEST(testRGBColor);
+ CPPUNIT_TEST(testRGBAColor);
+ CPPUNIT_TEST(testNoneColor);
+ CPPUNIT_TEST(testTdf97936);
+ CPPUNIT_TEST(testTdf149893);
+ CPPUNIT_TEST(testShapeWithClipPathAndCssStyle);
+ CPPUNIT_TEST(testClipPathAndParentStyle);
+ CPPUNIT_TEST(testClipPathAndStyle);
+ CPPUNIT_TEST(testClipPathUsingClipPath);
+ CPPUNIT_TEST(testClipRule);
+ CPPUNIT_TEST(testi125329);
+ CPPUNIT_TEST(testMaskingPath07b);
+ CPPUNIT_TEST(test123926);
+ CPPUNIT_TEST(test47446);
+ CPPUNIT_TEST(test47446b);
+ CPPUNIT_TEST(testTdf103888);
+ CPPUNIT_TEST(testMaskText);
+ CPPUNIT_TEST(testTdf99994);
+ CPPUNIT_TEST(testTdf99115);
+ CPPUNIT_TEST(testTdf101237);
+ CPPUNIT_TEST(testTdf94765);
+ CPPUNIT_TEST(testBehaviourWhenWidthAndHeightIsOrIsNotSet);
+ CPPUNIT_TEST(testTdf97663);
+ CPPUNIT_TEST(testTdf149880);
+ CPPUNIT_TEST(testCssClassRedefinition);
+ CPPUNIT_TEST(testTspanFillOpacity);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+Primitive2DSequence Test::parseSvg(std::u16string_view aSource)
+{
+ const Reference<XSvgParser> xSvgParser = SvgTools::create(m_xContext);
+
+ OUString aUrl = m_directories.getURLFromSrc(aSource);
+ OUString aPath = m_directories.getPathFromSrc(aSource);
+
+ SvFileStream aFileStream(aUrl, StreamMode::READ);
+ std::size_t nSize = aFileStream.remainingSize();
+ std::unique_ptr<sal_Int8[]> pBuffer(new sal_Int8[nSize + 1]);
+ aFileStream.ReadBytes(pBuffer.get(), nSize);
+ pBuffer[nSize] = 0;
+
+ Sequence<sal_Int8> aData(pBuffer.get(), nSize + 1);
+ Reference<XInputStream> aInputStream(new comphelper::SequenceInputStream(aData));
+
+ return xSvgParser->getDecomposition(aInputStream, aPath);
+}
+
+void Test::checkRectPrimitive(Primitive2DSequence const & rPrimitive)
+{
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(rPrimitive));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "color", "#00cc00"); // rect background color
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "height", "100"); // rect background height
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "width", "100"); // rect background width
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "minx", "10");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "miny", "10");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "maxx", "110");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "maxy", "110");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygonstroke/line", "color", "#ff0000"); // rect stroke color
+ assertXPath(pDocument, "/primitive2D/transform/polypolygonstroke/line", "width", "3"); // rect stroke width
+
+
+}
+
+bool arePrimitive2DSequencesEqual(const Primitive2DSequence& rA, const Primitive2DSequence& rB)
+{
+ return std::equal(rA.begin(), rA.end(), rB.begin(), rB.end(),
+ [](const css::uno::Reference<css::graphic::XPrimitive2D>& a,
+ const css::uno::Reference<css::graphic::XPrimitive2D>& b)
+ {
+ return drawinglayer::primitive2d::arePrimitive2DReferencesEqual(a, b);
+ });
+}
+
+// Attributes for an object (like rect as in this case) can be defined
+// in different ways (directly with xml attributes, or with CSS styles),
+// however the end result should be the same.
+void Test::testStyles()
+{
+ Primitive2DSequence aSequenceRect = parseSvg(u"/svgio/qa/cppunit/data/Rect.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceRect.getLength()));
+ checkRectPrimitive(aSequenceRect);
+
+ Primitive2DSequence aSequenceRectWithStyle = parseSvg(u"/svgio/qa/cppunit/data/RectWithStyles.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceRectWithStyle.getLength()));
+ checkRectPrimitive(aSequenceRectWithStyle);
+
+ Primitive2DSequence aSequenceRectWithParentStyle = parseSvg(u"/svgio/qa/cppunit/data/RectWithParentStyles.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceRectWithParentStyle.getLength()));
+ checkRectPrimitive(aSequenceRectWithParentStyle);
+
+ Primitive2DSequence aSequenceRectWithStylesByGroup = parseSvg(u"/svgio/qa/cppunit/data/RectWithStylesByGroup.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceRectWithStylesByGroup.getLength()));
+ checkRectPrimitive(aSequenceRectWithStylesByGroup);
+
+ CPPUNIT_ASSERT(arePrimitive2DSequencesEqual(aSequenceRect, aSequenceRectWithStyle));
+ CPPUNIT_ASSERT(arePrimitive2DSequencesEqual(aSequenceRect, aSequenceRectWithParentStyle));
+ CPPUNIT_ASSERT(arePrimitive2DSequencesEqual(aSequenceRect, aSequenceRectWithStylesByGroup));
+}
+
+void Test::testSymbol()
+{
+ Primitive2DSequence aSequenceTdf87309 = parseSvg(u"/svgio/qa/cppunit/data/symbol.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf87309.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequenceTdf87309);
+
+ CPPUNIT_ASSERT (pDocument);
+
+ // tdf#126330: Without the fix in place, this test would have failed with
+ // - Expected: 1
+ // - Actual : 2
+ // number of nodes is incorrect
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "color", "#00d000");
+}
+
+void Test::testTdf87309()
+{
+ Primitive2DSequence aSequenceTdf87309 = parseSvg(u"/svgio/qa/cppunit/data/tdf87309.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf87309.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequenceTdf87309);
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "color", "#000000");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "height", "100");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "width", "100");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "minx", "10");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "miny", "10");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "maxx", "110");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "maxy", "110");
+}
+
+void Test::testFontsizeKeywords()
+{
+ Primitive2DSequence aSequenceFontsizeKeywords = parseSvg(u"/svgio/qa/cppunit/data/FontsizeKeywords.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceFontsizeKeywords.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequenceFontsizeKeywords);
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "fontcolor", "#000000");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "text", "Sample");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "height", "9");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "familyname", "Times New Roman");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "fontcolor", "#ffffff");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "text", "Sample");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "height", "11");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "familyname", "Times New Roman");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[3]", "fontcolor", "#ffd700");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[3]", "text", "Sample");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[3]", "height", "13");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[3]", "familyname", "Times New Roman");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[4]", "fontcolor", "#ff0000");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[4]", "text", "Sample");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[4]", "height", "16");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[4]", "familyname", "Times New Roman");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[5]", "fontcolor", "#ffff00");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[5]", "text", "Sample");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[5]", "height", "19");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[5]", "familyname", "Times New Roman");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[6]", "fontcolor", "#0000ff");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[6]", "text", "Sample");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[6]", "height", "23");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[6]", "familyname", "Times New Roman");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[7]", "fontcolor", "#008000");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[7]", "text", "Sample");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[7]", "height", "27");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[7]", "familyname", "Times New Roman");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[8]", "fontcolor", "#ff7f50");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[8]", "text", "Sample");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[8]", "height", "13");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[8]", "familyname", "Times New Roman");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[9]", "fontcolor", "#ffc0cb");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[9]", "text", "Sample");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[9]", "height", "19");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[9]", "familyname", "Times New Roman");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[10]", "fontcolor", "#fffff0");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[10]", "text", "Sample");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[10]", "height", "16");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[9]", "familyname", "Times New Roman");
+}
+
+
+void Test::testFontsizePercentage()
+{
+ //Check when font-size uses percentage and defined globally
+ Primitive2DSequence aSequenceFontsizePercentage = parseSvg(u"/svgio/qa/cppunit/data/FontsizePercentage.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceFontsizePercentage.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequenceFontsizePercentage);
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "fontcolor", "#000000");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "text", "Sample");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "height", "16");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "familyname", "Times New Roman");
+}
+
+void Test::testFontsizeRelative()
+{
+ //Check when font-size uses relative units (em,ex) and it's based on its parent's font-size
+ Primitive2DSequence aSequenceFontsizeRelative = parseSvg(u"/svgio/qa/cppunit/data/FontsizeRelative.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceFontsizeRelative.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequenceFontsizeRelative);
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "fontcolor", "#000000");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "text", "Sample");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "height", "50");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "familyname", "serif");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "fontcolor", "#000000");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "text", "Sample");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "height", "50");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "familyname", "serif");
+}
+
+void Test::testMarkerOrient()
+{
+ Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/MarkerOrient.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequence);
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/transform[1]", "xy11", "0");
+ assertXPath(pDocument, "/primitive2D/transform/transform[1]", "xy12", "0");
+ assertXPath(pDocument, "/primitive2D/transform/transform[1]", "xy13", "7");
+ assertXPath(pDocument, "/primitive2D/transform/transform[1]", "xy21", "0");
+ assertXPath(pDocument, "/primitive2D/transform/transform[1]", "xy22", "0");
+ assertXPath(pDocument, "/primitive2D/transform/transform[1]", "xy23", "13");
+ assertXPath(pDocument, "/primitive2D/transform/transform[1]", "xy31", "0");
+ assertXPath(pDocument, "/primitive2D/transform/transform[1]", "xy32", "0");
+ assertXPath(pDocument, "/primitive2D/transform/transform[1]", "xy33", "1");
+
+ assertXPath(pDocument, "/primitive2D/transform/transform[2]", "xy11", "0");
+ assertXPath(pDocument, "/primitive2D/transform/transform[2]", "xy12", "0");
+ assertXPath(pDocument, "/primitive2D/transform/transform[2]", "xy13", "87");
+ assertXPath(pDocument, "/primitive2D/transform/transform[2]", "xy21", "0");
+ assertXPath(pDocument, "/primitive2D/transform/transform[2]", "xy22", "0");
+ assertXPath(pDocument, "/primitive2D/transform/transform[2]", "xy23", "87");
+ assertXPath(pDocument, "/primitive2D/transform/transform[2]", "xy31", "0");
+ assertXPath(pDocument, "/primitive2D/transform/transform[2]", "xy32", "0");
+ assertXPath(pDocument, "/primitive2D/transform/transform[2]", "xy33", "1");
+}
+
+void Test::testMarkerInCssStyle()
+{
+ Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/markerInCssStyle.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequence);
+
+ CPPUNIT_ASSERT (pDocument);
+
+ // Without the fix in place, this test would have failed with
+ // - Expected: 20
+ // - Actual : 0
+ assertXPath(pDocument, "/primitive2D/transform/transform/polypolygonstroke/line", 20);
+
+ assertXPath(pDocument, "/primitive2D/transform/transform[1]/polypolygonstroke/line", "color", "#008000");
+ assertXPath(pDocument, "/primitive2D/transform/transform[1]/polypolygonstroke/line", "width", "1");
+ assertXPath(pDocument, "/primitive2D/transform/transform[1]/polypolygonstroke/line", "linejoin", "Miter");
+ assertXPath(pDocument, "/primitive2D/transform/transform[1]/polypolygonstroke/line", "miterangle", "28");
+ assertXPath(pDocument, "/primitive2D/transform/transform[1]/polypolygonstroke/line", "linecap", "BUTT");
+}
+
+void Test::testTextXmlSpace()
+{
+ //Check tspan fontsize when using relative units
+ Primitive2DSequence aSequenceTdf97941 = parseSvg(u"/svgio/qa/cppunit/data/textXmlSpace.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf97941.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequenceTdf97941);
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/mask/textsimpleportion[1]", "text", "a b");
+ assertXPath(pDocument, "/primitive2D/transform/mask/textsimpleportion[2]", "text", "a b");
+ assertXPath(pDocument, "/primitive2D/transform/mask/textsimpleportion[3]", "text", "a b");
+ assertXPath(pDocument, "/primitive2D/transform/mask/textsimpleportion[4]", "text", "ab");
+ assertXPath(pDocument, "/primitive2D/transform/mask/textsimpleportion[5]", "text", " a b ");
+ assertXPath(pDocument, "/primitive2D/transform/mask/textsimpleportion[6]", "text", "a b");
+ assertXPath(pDocument, "/primitive2D/transform/mask/textsimpleportion[7]", "text", "a b");
+ assertXPath(pDocument, "/primitive2D/transform/mask/textsimpleportion[8]", "text", "a b");
+}
+
+void Test::testTdf45771()
+{
+ //Check text fontsize when using relative units
+ Primitive2DSequence aSequenceTdf45771 = parseSvg(u"/svgio/qa/cppunit/data/tdf45771.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf45771.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequenceTdf45771);
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "fontcolor", "#000000");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "text", "Sample");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "height", "32");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "familyname", "Times New Roman");
+}
+
+void Test::testTdf97941()
+{
+ //Check tspan fontsize when using relative units
+ Primitive2DSequence aSequenceTdf97941 = parseSvg(u"/svgio/qa/cppunit/data/tdf97941.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf97941.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequenceTdf97941);
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "fontcolor", "#000000");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "text", "Sample");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "height", "48");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "familyname", "Times New Roman");
+}
+
+void Test::testTdf104339()
+{
+ Primitive2DSequence aSequenceTdf104339 = parseSvg(u"/svgio/qa/cppunit/data/tdf104339.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf104339.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequenceTdf104339);
+
+ CPPUNIT_ASSERT (pDocument);
+ assertXPath(pDocument, "/primitive2D/transform/transform/transform/transform/transform/polypolygoncolor", "color", "#000000");
+}
+
+void Test::testTdf85770()
+{
+ Primitive2DSequence aSequenceTdf85770 = parseSvg(u"/svgio/qa/cppunit/data/tdf85770.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf85770.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceTdf85770));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "fontcolor", "#000000");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "text", "Start Middle End");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "height", "11");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "familyname", "Times New Roman");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "fontcolor", "#000000");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "text", "Start");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "height", "11");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "familyname", "Times New Roman");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[3]", "fontcolor", "#000000");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[3]", "text", "End");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[3]", "height", "11");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[3]", "familyname", "Times New Roman");
+
+}
+
+void Test::testTdf79163()
+{
+ //Check Opacity
+ Primitive2DSequence aSequenceTdf79163 = parseSvg(u"/svgio/qa/cppunit/data/tdf79163.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf79163.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceTdf79163));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/unifiedtransparence", "transparence", "50");
+}
+
+void Test::testTdf97542_1()
+{
+ Primitive2DSequence aSequenceTdf97542_1 = parseSvg(u"/svgio/qa/cppunit/data/tdf97542_1.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf97542_1.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceTdf97542_1));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/objectinfo/textsimpleportion", "fontcolor", "#ffff00");
+ assertXPath(pDocument, "/primitive2D/transform/objectinfo/textsimpleportion", "text", "Text");
+ assertXPath(pDocument, "/primitive2D/transform/objectinfo/textsimpleportion", "height", "48");
+ assertXPath(pDocument, "/primitive2D/transform/objectinfo/textsimpleportion", "familyname", "serif");
+}
+
+void Test::testTdf97542_2()
+{
+ Primitive2DSequence aSequenceTdf97542_2 = parseSvg(u"/svgio/qa/cppunit/data/tdf97542_2.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf97542_2.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceTdf97542_2));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/objectinfo/svgradialgradient", "startx", "1");
+ assertXPath(pDocument, "/primitive2D/transform/objectinfo/svgradialgradient", "starty", "1");
+ assertXPath(pDocument, "/primitive2D/transform/objectinfo/svgradialgradient/focalx", 0);
+ assertXPath(pDocument, "/primitive2D/transform/objectinfo/svgradialgradient/focaly", 0);
+ assertXPath(pDocument, "/primitive2D/transform/objectinfo/svgradialgradient", "radius", "3");
+ assertXPath(pDocument, "/primitive2D/transform/objectinfo/svgradialgradient", "spreadmethod", "pad");
+ assertXPath(pDocument, "/primitive2D/transform/objectinfo/svgradialgradient", "opacity", "1");
+}
+
+void Test::testTdf97543()
+{
+ // check visibility="inherit"
+ Primitive2DSequence aSequenceTdf97543 = parseSvg(u"/svgio/qa/cppunit/data/tdf97543.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf97543.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceTdf97543));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "color", "#00cc00");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "height", "100");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "width", "100");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "minx", "10");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "miny", "10");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "maxx", "110");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "maxy", "110");
+}
+
+void Test::testRGBColor()
+{
+ Primitive2DSequence aSequenceRGBColor = parseSvg(u"/svgio/qa/cppunit/data/RGBColor.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceRGBColor.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceRGBColor));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "color", "#646464");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "height", "100");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "width", "100");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "minx", "10");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "miny", "10");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "maxx", "110");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor/polypolygon", "maxy", "110");
+}
+
+void Test::testRGBAColor()
+{
+ Primitive2DSequence aSequenceRGBAColor = parseSvg(u"/svgio/qa/cppunit/data/RGBAColor.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceRGBAColor.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceRGBAColor));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/unifiedtransparence", "transparence", "50");
+}
+
+void Test::testNoneColor()
+{
+ Primitive2DSequence aSequenceRGBAColor = parseSvg(u"/svgio/qa/cppunit/data/noneColor.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceRGBAColor.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceRGBAColor));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ //No polypolygoncolor exists
+ assertXPath(pDocument, "/primitive2D/transform/mask/polypolygoncolor", 0);
+ assertXPath(pDocument, "/primitive2D/transform/mask/polypolygonstroke/line", "color", "#000000");
+ assertXPath(pDocument, "/primitive2D/transform/mask/polypolygonstroke/line", "width", "3");
+}
+
+void Test::testTdf97936()
+{
+ // check that both rectangles are rendered in the viewBox
+ Primitive2DSequence aSequenceTdf97936 = parseSvg(u"/svgio/qa/cppunit/data/tdf97936.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf97936.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceTdf97936));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[1]");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[1]/polypolygon", "height", "50");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[1]/polypolygon", "width", "50");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[1]/polypolygon", "minx", "70");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[1]/polypolygon", "miny", "50");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[1]/polypolygon", "maxx", "120");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[1]/polypolygon", "maxy", "100");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[2]");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[2]/polypolygon", "height", "50");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[2]/polypolygon", "width", "50");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[2]/polypolygon", "minx", "10");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[2]/polypolygon", "miny", "50");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[2]/polypolygon", "maxx", "60");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[2]/polypolygon", "maxy", "100");
+}
+
+void Test::testTdf149893()
+{
+ Primitive2DSequence aSequenceClipPathAndParentStyle = parseSvg(u"/svgio/qa/cppunit/data/tdf149893.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceClipPathAndParentStyle.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceClipPathAndParentStyle));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ // Without the fix in place, this test would have failed with
+ // - Expected: #008000
+ // - Actual : #000000
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "color", "#008000");
+}
+
+void Test::testShapeWithClipPathAndCssStyle()
+{
+ // tdf#97539: Check there is a mask and 3 polygons
+ Primitive2DSequence aSequenceClipPathAndStyle = parseSvg(u"/svgio/qa/cppunit/data/ShapeWithClipPathAndCssStyle.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceClipPathAndStyle.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceClipPathAndStyle));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/mask/polypolygon/polygon", 2);
+ assertXPath(pDocument, "/primitive2D/transform/mask/polypolygoncolor/polypolygon/polygon", 1);
+}
+
+void Test::testClipPathAndParentStyle()
+{
+ //Check that fill color, stroke color and stroke-width are inherited from use element
+ //when the element is within a clipPath element
+ Primitive2DSequence aSequenceClipPathAndParentStyle = parseSvg(u"/svgio/qa/cppunit/data/ClipPathAndParentStyle.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceClipPathAndParentStyle.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceClipPathAndParentStyle));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "color", "#ff0000");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygonstroke/line", "color", "#000000");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygonstroke/line", "width", "5");
+
+}
+
+void Test::testClipPathAndStyle()
+{
+ //Check that fill color, stroke color and stroke-width are inherited from use element
+ //when the element is within a clipPath element
+ Primitive2DSequence aSequenceClipPathAndStyle = parseSvg(u"/svgio/qa/cppunit/data/ClipPathAndStyle.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceClipPathAndStyle.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceClipPathAndStyle));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "color", "#ccccff");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygonstroke/line", "color", "#0000cc");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygonstroke/line", "width", "2");
+
+}
+
+void Test::testClipPathUsingClipPath()
+{
+ Primitive2DSequence aSequenceClipPathAndStyle = parseSvg(u"/svgio/qa/cppunit/data/ClipPathUsingClipPath.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceClipPathAndStyle.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceClipPathAndStyle));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/mask/polypolygon/polygon/point", 20);
+ assertXPath(pDocument, "/primitive2D/transform/mask/mask/polypolygon/polygon/point", 13);
+}
+
+void Test::testClipRule()
+{
+ Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/ClipRule.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ // Without the place in place, this test would have failed with
+ // - Expected: 5
+ // - Actual : 10
+ assertXPath(pDocument, "/primitive2D/transform/mask[1]/polypolygon/polygon/point", 5);
+ assertXPath(pDocument, "/primitive2D/transform/mask[1]/polypolygoncolor", "color", "#0000ff");
+ assertXPath(pDocument, "/primitive2D/transform/mask[1]/polypolygoncolor/polypolygon/polygon/point", 5);
+
+ assertXPath(pDocument, "/primitive2D/transform/mask[2]/polypolygon/polygon/point", 5);
+ assertXPath(pDocument, "/primitive2D/transform/mask[2]/polypolygoncolor", "color", "#ff0000");
+ assertXPath(pDocument, "/primitive2D/transform/mask[2]/polypolygoncolor/polypolygon/polygon/point", 5);
+}
+
+void Test::testi125329()
+{
+ //Check style inherit from * css element
+ Primitive2DSequence aSequencei125329 = parseSvg(u"/svgio/qa/cppunit/data/i125329.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequencei125329.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequencei125329));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/transform/objectinfo/polypolygoncolor", "color", "#c0c0c0"); // rect background color
+ assertXPath(pDocument, "/primitive2D/transform/transform/objectinfo/polypolygoncolor/polypolygon", "height", "30"); // rect background height
+ assertXPath(pDocument, "/primitive2D/transform/transform/objectinfo/polypolygoncolor/polypolygon", "width", "50"); // rect background width
+ assertXPath(pDocument, "/primitive2D/transform/transform/objectinfo/polypolygoncolor/polypolygon", "minx", "15");
+ assertXPath(pDocument, "/primitive2D/transform/transform/objectinfo/polypolygoncolor/polypolygon", "miny", "15");
+ assertXPath(pDocument, "/primitive2D/transform/transform/objectinfo/polypolygoncolor/polypolygon", "maxx", "65");
+ assertXPath(pDocument, "/primitive2D/transform/transform/objectinfo/polypolygoncolor/polypolygon", "maxy", "45");
+ assertXPath(pDocument, "/primitive2D/transform/transform/objectinfo/polypolygonstroke/line", "color", "#008000"); // rect stroke color
+ assertXPath(pDocument, "/primitive2D/transform/transform/objectinfo/polypolygonstroke/line", "width", "1"); // rect stroke width
+}
+
+void Test::testMaskingPath07b()
+{
+ //For the time being, check that masking-path-07-b.svg can be imported and it doesn't hang on loading
+ //it used to hang after d5649ae7b76278cb3155f951d6327157c7c92b65
+ Primitive2DSequence aSequenceMaskingPath07b = parseSvg(u"/svgio/qa/cppunit/data/masking-path-07-b.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceMaskingPath07b.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceMaskingPath07b));
+
+ CPPUNIT_ASSERT (pDocument);
+
+}
+
+void Test::test123926()
+{
+ Primitive2DSequence aSequence123926 = parseSvg(u"/svgio/qa/cppunit/data/tdf123926.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence123926.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence123926));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/transform/transform/unifiedtransparence/polypolygoncolor", "color", "#7cb5ec");
+}
+
+void Test::test47446()
+{
+ //Check that marker's fill attribute is black is not set
+ Primitive2DSequence aSequence47446 = parseSvg(u"/svgio/qa/cppunit/data/47446.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence47446.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence47446));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/transform/transform/polypolygoncolor", "color", "#000000");
+
+}
+
+void Test::test47446b()
+{
+ //Check that marker's fill attribute is inherit from def
+ Primitive2DSequence aSequence47446b = parseSvg(u"/svgio/qa/cppunit/data/47446b.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence47446b.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence47446b));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/transform/transform/polypolygoncolor", "color", "#ffff00");
+
+}
+
+void Test::testTdf103888()
+{
+ Primitive2DSequence aSequenceMaskText = parseSvg(u"/svgio/qa/cppunit/data/tdf103888.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceMaskText.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceMaskText));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ // Without the fix in place, this test would have failed here with number of nodes is incorrect
+ assertXPath(pDocument, "/primitive2D/transform/transform/textsimpleportion[1]", "text", "Her");
+ assertXPath(pDocument, "/primitive2D/transform/transform/textsimpleportion[2]", "text", "vor");
+ assertXPath(pDocument, "/primitive2D/transform/transform/textsimpleportion[3]", "text", "hebung");
+}
+
+void Test::testMaskText()
+{
+ //Check that mask is applied on text
+ Primitive2DSequence aSequenceMaskText = parseSvg(u"/svgio/qa/cppunit/data/maskText.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceMaskText.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceMaskText));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/transform/polypolygoncolor", "color", "#000000");
+ assertXPath(pDocument, "/primitive2D/transform/transform/textsimpleportion", "fontcolor", "#ffffff");
+ assertXPath(pDocument, "/primitive2D/transform/transform/textsimpleportion", "text", "Black White");
+ assertXPath(pDocument, "/primitive2D/transform/transform/textsimpleportion", "height", "26");
+ assertXPath(pDocument, "/primitive2D/transform/transform/textsimpleportion", "familyname", "Times New Roman");
+}
+
+void Test::testTdf99994()
+{
+ //Check text fontsize when using relative units
+ Primitive2DSequence aSequenceTdf99994 = parseSvg(u"/svgio/qa/cppunit/data/tdf99994.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf99994.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceTdf99994));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "fontcolor", "#0000ff");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "height", "16");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "text", "test");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "familyname", "Sans");
+}
+
+void Test::testTdf99115()
+{
+ //Check that styles are resolved correctly where there is a * css selector
+ Primitive2DSequence aSequenceTdf99115 = parseSvg(u"/svgio/qa/cppunit/data/tdf99115.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf99115.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceTdf99115) );
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "text", "red 1");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "fontcolor", "#ff0000");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "height", "18");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "text", "red 2");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "fontcolor", "#ff0000");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "height", "18");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[3]", "text", "red 3");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[3]", "fontcolor", "#ff0000");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[3]", "height", "18");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[4]", "text", "blue 4");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[4]", "fontcolor", "#0000ff");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[4]", "height", "18");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[5]", "text", "blue 5");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[5]", "fontcolor", "#0000ff");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[5]", "height", "18");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[6]", "text", "blue 6");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[6]", "fontcolor", "#0000ff");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[6]", "height", "18");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[7]", "text", "green 7");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[7]", "fontcolor", "#008000");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[7]", "height", "18");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[8]", "text", "green 8");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[8]", "fontcolor", "#008000");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[8]", "height", "18");
+
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[9]", "text", "green 9");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[9]", "fontcolor", "#008000");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[9]", "height", "18");
+}
+
+void Test::testTdf101237()
+{
+ //Check that fill color, stroke color and stroke-width are inherited from use element
+ //when the element is within a clipPath element
+ Primitive2DSequence aSequenceTdf101237 = parseSvg(u"/svgio/qa/cppunit/data/tdf101237.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf101237.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceTdf101237));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "color", "#ff0000");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygonstroke/line", "color", "#000000");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygonstroke/line", "width", "5");
+}
+
+void Test::testTdf94765()
+{
+ Primitive2DSequence aSequenceTdf94765 = parseSvg(u"/svgio/qa/cppunit/data/tdf94765.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequenceTdf94765.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequenceTdf94765));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ //Check that both rectangles use the gradient as fill
+ assertXPath(pDocument, "/primitive2D/transform/transform/svglineargradient[1]", "startx", "1");
+ assertXPath(pDocument, "/primitive2D/transform/transform/svglineargradient[1]", "starty", "1");
+ assertXPath(pDocument, "/primitive2D/transform/transform/svglineargradient[1]", "endx", "2");
+ assertXPath(pDocument, "/primitive2D/transform/transform/svglineargradient[1]", "endy", "1");
+ assertXPath(pDocument, "/primitive2D/transform/transform/svglineargradient[2]", "startx", "0");
+ assertXPath(pDocument, "/primitive2D/transform/transform/svglineargradient[2]", "starty", "0");
+ assertXPath(pDocument, "/primitive2D/transform/transform/svglineargradient[2]", "endx", "0");
+ assertXPath(pDocument, "/primitive2D/transform/transform/svglineargradient[2]", "endy", "0");
+}
+
+void Test::testBehaviourWhenWidthAndHeightIsOrIsNotSet()
+{
+ // This test checks the behaviour when width and height attributes
+ // are and are not set. In both cases the result must be the same,
+ // however if the width / height are set, then the size of the image
+ // is enforced, but this isn't really possible in LibreOffice (or
+ // maybe we could lock the size in this case).
+ // The behaviour in browsers is that when a SVG image has width / height
+ // attributes set, then the image is shown with that size, but if it
+ // isn't set then it is shown as scalable image which is the size of
+ // the container.
+
+ {
+ const Primitive2DSequence aSequence = parseSvg(u"svgio/qa/cppunit/data/Drawing_WithWidthHeight.svg");
+ CPPUNIT_ASSERT(aSequence.hasElements());
+
+ geometry::RealRectangle2D aRealRect;
+ basegfx::B2DRange aRange;
+ uno::Sequence<beans::PropertyValue> aViewParameters;
+
+ for (css::uno::Reference<css::graphic::XPrimitive2D> const & xReference : aSequence)
+ {
+ if (xReference.is())
+ {
+ aRealRect = xReference->getRange(aViewParameters);
+ aRange.expand(basegfx::B2DRange(aRealRect.X1, aRealRect.Y1, aRealRect.X2, aRealRect.Y2));
+ }
+ }
+
+ double fWidth = (aRange.getWidth() / 2540.0) * 96.0;
+ double fHeight = (aRange.getHeight() / 2540.0) * 96.0;
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(11.0, fWidth, 1E-12);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(11.0, fHeight, 1E-12);
+ }
+
+ {
+ const Primitive2DSequence aSequence = parseSvg(u"svgio/qa/cppunit/data/Drawing_NoWidthHeight.svg");
+ CPPUNIT_ASSERT(aSequence.hasElements());
+
+
+ geometry::RealRectangle2D aRealRect;
+ basegfx::B2DRange aRange;
+ uno::Sequence<beans::PropertyValue> aViewParameters;
+
+ for (css::uno::Reference<css::graphic::XPrimitive2D> const & xReference : aSequence)
+ {
+ if (xReference.is())
+ {
+ aRealRect = xReference->getRange(aViewParameters);
+ aRange.expand(basegfx::B2DRange(aRealRect.X1, aRealRect.Y1, aRealRect.X2, aRealRect.Y2));
+ }
+ }
+
+ double fWidth = (aRange.getWidth() / 2540.0) * 96.0;
+ double fHeight = (aRange.getHeight() / 2540.0) * 96.0;
+
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(11.0, fWidth, 1E-12);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(11.0, fHeight, 1E-12);
+ }
+}
+
+void Test::testTdf97663()
+{
+ Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/em_units.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ // tdf#97663: Without the fix in place, this test would have failed with
+ // - Expected: 236
+ // - Actual : 204
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "y", "236");
+}
+
+void Test::testTdf149880()
+{
+ Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/tdf149880.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence));
+
+ CPPUNIT_ASSERT (pDocument);
+
+ // Without the fix in place, this test would have failed with
+ // - Expected: 1
+ // - Actual : 0
+ // - In <>, XPath '/primitive2D/transform/mask/unhandled' number of nodes is incorrect
+ assertXPath(pDocument,
+ "/primitive2D/transform/mask/unhandled", "id", "PATTERNFILL");
+ assertXPath(pDocument,
+ "/primitive2D/transform/mask/unhandled/mask/transform/transform/bitmap", 28);
+}
+
+void Test::testCssClassRedefinition()
+{
+ // Tests for svg css class redefinition behavior
+ // Example:
+ // .c1 {fill:#00ff00}
+ // .c1 {font-family:Sans}
+ // .c1 {fill:#ff0000}
+ // Expected result is .c1 {font-family:Sans; fill:#ff0000} because
+ // the second redefinition appends attributes to the class and the
+ // third redefinition replaces the already existing
+ // attribute in the original definition
+ Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/CssClassRedefinition.svg");
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence));
+ CPPUNIT_ASSERT (pDocument);
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "text", "test");
+ assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "fontcolor", "#ff0000");
+ assertXPath(
+ pDocument, "/primitive2D/transform/textsimpleportion[1]", "familyname", "Open Symbol");
+}
+
+void Test::testTspanFillOpacity()
+{
+ // Given an SVG file with <tspan fill-opacity="0.30">:
+ std::u16string_view aPath = u"/svgio/qa/cppunit/data/tspan-fill-opacity.svg";
+
+ // When rendering that SVG:
+ Primitive2DSequence aSequence = parseSvg(aPath);
+
+ // Then make sure that the text portion is wrapped in a transparency primitive with the correct
+ // transparency value:
+ drawinglayer::Primitive2dXmlDump aDumper;
+ xmlDocUniquePtr pDocument = aDumper.dumpAndParse(Primitive2DContainer(aSequence));
+ sal_Int32 nTransparence = getXPath(pDocument, "//textsimpleportion[@text='hello']/parent::unifiedtransparence", "transparence").toInt32();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1
+ // - Actual : 0
+ // - XPath '//textsimpleportion[@text='hello']/parent::unifiedtransparence' number of nodes is incorrect
+ // i.e. the relevant <textsimpleportion> had no <unifiedtransparence> parent, the text was not
+ // semi-transparent.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(70), nTransparence);
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svgio/qa/cppunit/SvgNumberTest.cxx b/svgio/qa/cppunit/SvgNumberTest.cxx
new file mode 100644
index 000000000..f420a44b4
--- /dev/null
+++ b/svgio/qa/cppunit/SvgNumberTest.cxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <SvgNumber.hxx>
+
+namespace
+{
+class TestNumber : public CppUnit::TestFixture
+{
+ void testSetting();
+ void testSolve();
+
+public:
+ CPPUNIT_TEST_SUITE(TestNumber);
+ CPPUNIT_TEST(testSetting);
+ CPPUNIT_TEST(testSolve);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+class TestInfoProvider : public svgio::svgreader::InfoProvider
+{
+public:
+ basegfx::B2DRange getCurrentViewPort() const override
+ {
+ return basegfx::B2DRange(0.0, 0.0, 0.0, 0.0);
+ }
+
+ double getCurrentFontSizeInherited() const override { return 12.0; }
+
+ double getCurrentXHeightInherited() const override { return 5.0; }
+};
+
+void TestNumber::testSetting()
+{
+ {
+ svgio::svgreader::SvgNumber aNumber;
+ CPPUNIT_ASSERT_EQUAL(svgio::svgreader::SvgUnit::px, aNumber.getUnit());
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, aNumber.getNumber(), 1e-8);
+ CPPUNIT_ASSERT_EQUAL(false, aNumber.isSet());
+ }
+ {
+ svgio::svgreader::SvgNumber aNumber(0.01);
+ CPPUNIT_ASSERT_EQUAL(svgio::svgreader::SvgUnit::px, aNumber.getUnit());
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(0.01, aNumber.getNumber(), 1e-8);
+ CPPUNIT_ASSERT_EQUAL(true, aNumber.isSet());
+ }
+ {
+ svgio::svgreader::SvgNumber aNumber(1.01, svgio::svgreader::SvgUnit::cm);
+ CPPUNIT_ASSERT_EQUAL(svgio::svgreader::SvgUnit::cm, aNumber.getUnit());
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(1.01, aNumber.getNumber(), 1e-8);
+ CPPUNIT_ASSERT_EQUAL(true, aNumber.isSet());
+ }
+}
+
+void TestNumber::testSolve()
+{
+ {
+ svgio::svgreader::SvgNumber aNumber(1.01);
+ TestInfoProvider aInfoProvider;
+ double aSolvedNumber = aNumber.solve(aInfoProvider);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(1.01, aSolvedNumber, 1e-8);
+ }
+ {
+ svgio::svgreader::SvgNumber aNumber(1.0, svgio::svgreader::SvgUnit::pt);
+ TestInfoProvider aInfoProvider;
+ double aSolvedNumber = aNumber.solve(aInfoProvider);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(1.333, aSolvedNumber, 1e-3);
+ }
+ {
+ svgio::svgreader::SvgNumber aNumber(2.54, svgio::svgreader::SvgUnit::cm);
+ TestInfoProvider aInfoProvider;
+ double aSolvedNumber = aNumber.solve(aInfoProvider);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(96.0, aSolvedNumber, 1e-3);
+ }
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(TestNumber);
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svgio/qa/cppunit/SvgRead.cxx b/svgio/qa/cppunit/SvgRead.cxx
new file mode 100644
index 000000000..127de19a7
--- /dev/null
+++ b/svgio/qa/cppunit/SvgRead.cxx
@@ -0,0 +1,127 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+#include <test/bootstrapfixture.hxx>
+
+#include <memory>
+
+#include <comphelper/seqstream.hxx>
+#include <comphelper/processfactory.hxx>
+#include <tools/stream.hxx>
+
+#include <com/sun/star/graphic/SvgTools.hpp>
+#include <com/sun/star/graphic/XSvgParser.hpp>
+
+#include <basegfx/DrawCommands.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+
+namespace
+{
+using namespace css;
+
+class TestParsing : public test::BootstrapFixture
+{
+ void testSimpleRectangle();
+ void testPath();
+ uno::Reference<io::XInputStream> parseSvg(const OUString& aSource);
+
+public:
+ CPPUNIT_TEST_SUITE(TestParsing);
+ CPPUNIT_TEST(testSimpleRectangle);
+ CPPUNIT_TEST(testPath);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+uno::Reference<io::XInputStream> TestParsing::parseSvg(const OUString& aSource)
+{
+ SvFileStream aFileStream(aSource, StreamMode::READ);
+ std::size_t nSize = aFileStream.remainingSize();
+ std::unique_ptr<sal_Int8[]> pBuffer(new sal_Int8[nSize + 1]);
+ aFileStream.ReadBytes(pBuffer.get(), nSize);
+ pBuffer[nSize] = 0;
+
+ uno::Sequence<sal_Int8> aData(pBuffer.get(), nSize + 1);
+ uno::Reference<io::XInputStream> aInputStream(new comphelper::SequenceInputStream(aData));
+
+ return aInputStream;
+}
+
+void TestParsing::testSimpleRectangle()
+{
+ OUString aSvgFile = "/svgio/qa/cppunit/data/VisiotorTest-Rect.svg";
+ OUString aUrl = m_directories.getURLFromSrc(aSvgFile);
+ OUString aPath = m_directories.getPathFromSrc(aSvgFile);
+
+ uno::Reference<io::XInputStream> xStream = parseSvg(aUrl);
+ CPPUNIT_ASSERT(xStream.is());
+
+ uno::Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext());
+ const uno::Reference<graphic::XSvgParser> xSvgParser = graphic::SvgTools::create(xContext);
+
+ uno::Any aAny = xSvgParser->getDrawCommands(xStream, aPath);
+ CPPUNIT_ASSERT(aAny.has<sal_uInt64>());
+ auto* pDrawRoot = reinterpret_cast<gfx::DrawRoot*>(aAny.get<sal_uInt64>());
+
+ basegfx::B2DRange aSurfaceRectangle(0, 0, 120, 120);
+
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pDrawRoot->maChildren.size());
+ CPPUNIT_ASSERT_EQUAL(aSurfaceRectangle, pDrawRoot->maRectangle);
+
+ auto* pDrawBase = pDrawRoot->maChildren[0].get();
+ CPPUNIT_ASSERT_EQUAL(gfx::DrawCommandType::Rectangle, pDrawRoot->maChildren[0]->getType());
+ auto* pDrawRect = static_cast<gfx::DrawRectangle*>(pDrawBase);
+ CPPUNIT_ASSERT_EQUAL(basegfx::B2DRange(10, 10, 110, 110), pDrawRect->maRectangle);
+ CPPUNIT_ASSERT_EQUAL(3.0, pDrawRect->mnStrokeWidth);
+ CPPUNIT_ASSERT(bool(pDrawRect->mpStrokeColor));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0xff0000), sal_Int32(Color(*pDrawRect->mpStrokeColor)));
+ CPPUNIT_ASSERT(bool(pDrawRect->mpFillColor));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0x00cc00), sal_Int32(Color(*pDrawRect->mpFillColor)));
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(0.1, pDrawRect->mnOpacity, 1E-12);
+}
+
+void TestParsing::testPath()
+{
+ OUString aSvgFile = "/svgio/qa/cppunit/data/path.svg";
+ OUString aUrl = m_directories.getURLFromSrc(aSvgFile);
+ OUString aPath = m_directories.getPathFromSrc(aSvgFile);
+
+ uno::Reference<io::XInputStream> xStream = parseSvg(aUrl);
+ CPPUNIT_ASSERT(xStream.is());
+
+ uno::Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext());
+ const uno::Reference<graphic::XSvgParser> xSvgParser = graphic::SvgTools::create(xContext);
+
+ uno::Any aAny = xSvgParser->getDrawCommands(xStream, aPath);
+ CPPUNIT_ASSERT(aAny.has<sal_uInt64>());
+ auto* pDrawRoot = reinterpret_cast<gfx::DrawRoot*>(aAny.get<sal_uInt64>());
+
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pDrawRoot->maChildren.size());
+
+ auto* pDrawBase = pDrawRoot->maChildren[0].get();
+ CPPUNIT_ASSERT_EQUAL(gfx::DrawCommandType::Path, pDrawBase->getType());
+ auto* pDrawPath = static_cast<gfx::DrawPath*>(pDrawBase);
+
+ CPPUNIT_ASSERT_EQUAL(OUString("m1 1h42v24h-42v-24z"),
+ basegfx::utils::exportToSvgD(pDrawPath->maPolyPolygon, true, true, false));
+ CPPUNIT_ASSERT_EQUAL(0.0, pDrawPath->mnStrokeWidth);
+ CPPUNIT_ASSERT(bool(pDrawPath->mpStrokeColor));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0xffffff), sal_Int32(Color(*pDrawPath->mpStrokeColor)));
+ CPPUNIT_ASSERT(bool(pDrawPath->mpFillColor));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0x007aff), sal_Int32(Color(*pDrawPath->mpFillColor)));
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(0.1, pDrawPath->mnOpacity, 1E-12);
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(TestParsing);
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svgio/qa/cppunit/data/47446.svg b/svgio/qa/cppunit/data/47446.svg
new file mode 100644
index 000000000..aec66b9bd
--- /dev/null
+++ b/svgio/qa/cppunit/data/47446.svg
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="no" ?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="12cm" height="4cm" viewBox="0 0 1200 400"
+ xmlns="http://www.w3.org/2000/svg" version="1.1">
+<defs>
+ <marker id="Triangle"
+ markerUnits="strokeWidth" refY="3"
+ markerWidth="6" markerHeight="6"
+ orient="auto">
+ <path d="M 0 0 L 6 3 L 0 6 z"
+ stroke-width="0.5" stroke="black"/>
+ </marker>
+</defs>
+
+<polyline fill="none" stroke="red" stroke-width="10"
+ points="450,50 550,50 650,150"
+ marker-end="url(#Triangle)" />
+</svg>
diff --git a/svgio/qa/cppunit/data/47446b.svg b/svgio/qa/cppunit/data/47446b.svg
new file mode 100644
index 000000000..29cfce5d8
--- /dev/null
+++ b/svgio/qa/cppunit/data/47446b.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="no" ?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="12cm" height="4cm" viewBox="0 0 1200 400"
+ xmlns="http://www.w3.org/2000/svg" version="1.1">
+<defs fill="yellow">
+ <marker id="Triangle"
+ markerUnits="strokeWidth" refY="3"
+ markerWidth="6" markerHeight="6"
+ orient="auto">
+ <path d="M 0 0 L 6 3 L 0 6 z"
+ stroke-width="0.5" stroke="black"/>
+ </marker>
+</defs>
+<polyline fill="none" stroke="red" stroke-width="10"
+ points="450,50 550,50 650,150"
+ marker-end="url(#Triangle)" />
+</svg>
diff --git a/svgio/qa/cppunit/data/ClipPathAndParentStyle.svg b/svgio/qa/cppunit/data/ClipPathAndParentStyle.svg
new file mode 100644
index 000000000..d85a95995
--- /dev/null
+++ b/svgio/qa/cppunit/data/ClipPathAndParentStyle.svg
@@ -0,0 +1,10 @@
+<svg version="1.1" baseProfile="basic" id="svg-root"
+ width="100%" height="100%" viewBox="0 0 480 360"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <clipPath>
+ <circle id="c1" cx="100" cy="100" r="50"/>
+ </clipPath>
+
+ <use xlink:href="#c1" style="fill:red" stroke-width="5px" stroke="black"/>
+
+</svg>
diff --git a/svgio/qa/cppunit/data/ClipPathAndStyle.svg b/svgio/qa/cppunit/data/ClipPathAndStyle.svg
new file mode 100644
index 000000000..f3b1777fa
--- /dev/null
+++ b/svgio/qa/cppunit/data/ClipPathAndStyle.svg
@@ -0,0 +1,13 @@
+<svg version="1.1" baseProfile="basic" id="svg-root"
+ width="100%" height="100%" viewBox="0 0 480 360"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <clipPath>
+ <circle id="c1" cx="100" cy="100" r="50"
+ style="stroke: #0000cc;
+ stroke-width: 2px;
+ fill : #ccccff;"/>
+ </clipPath>
+
+ <use href="#c1" style="fill:red" stroke-width="5px" stroke="black"/>
+
+</svg>
diff --git a/svgio/qa/cppunit/data/ClipPathUsingClipPath.svg b/svgio/qa/cppunit/data/ClipPathUsingClipPath.svg
new file mode 100644
index 000000000..5eaa7928c
--- /dev/null
+++ b/svgio/qa/cppunit/data/ClipPathUsingClipPath.svg
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<defs>
+
+<clipPath id="clip1">
+ <polygon id="clip1Shape" points="100,10 40,180 190,60 10,60 160,180 100,10" stroke="blue" />
+</clipPath>
+
+<clipPath id="clip2">
+ <circle id="clip2Shape" cx="100" cy="100" r="65" />
+</clipPath>
+
+
+<clipPath id="clipIntersection" clip-path="url(#clip1)">
+ <use x="0" y="0" width="200" height="200" xlink:href="#clip2Shape" />
+</clipPath>
+
+</defs>
+
+<rect x="10" y="10" width="180" height="180" fill="red"
+ clip-path="url(#clipIntersection)" transform="translate(200)" />
+
+</svg>
diff --git a/svgio/qa/cppunit/data/ClipRule.svg b/svgio/qa/cppunit/data/ClipRule.svg
new file mode 100644
index 000000000..55f0cb9ee
--- /dev/null
+++ b/svgio/qa/cppunit/data/ClipRule.svg
@@ -0,0 +1,18 @@
+<svg version="1.1" baseProfile="basic" id="svg-root"
+ width="100%" height="100%" viewBox="0 0 480 360"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Define star path -->
+ <defs>
+ <path d="M50,0 21,90 98,35 2,35 79,90z" id="star" />
+ </defs>
+ <clipPath id="emptyStar">
+ <use xlink:href="#star" clip-rule="evenodd" />
+ </clipPath>
+ <rect clip-path="url(#emptyStar)" width="50" height="90" fill="blue" />
+
+ <clipPath id="filledStar">
+ <use xlink:href="#star" clip-rule="evenodd" />
+ </clipPath>
+ <rect clip-path="url(#filledStar)" width="50" height="90" x="50" fill="red" />
+</svg>
+
diff --git a/svgio/qa/cppunit/data/CssClassRedefinition.svg b/svgio/qa/cppunit/data/CssClassRedefinition.svg
new file mode 100644
index 000000000..384cf8848
--- /dev/null
+++ b/svgio/qa/cppunit/data/CssClassRedefinition.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="50 px" height="100 px">
+ <style type="text/css">
+ .c1 {fill:#00ff00}
+ <!-- this redefinition should be appended -->
+ .c1 {font-family:Open Symbol}
+ <!-- this redefinition should change the color to red, replacing the first definition -->
+ .c1 {fill:#ff0000}
+ <!-- finally c1 should be equal to fill:#ff0000 and font-family:Sans -->
+ </style>
+ <text x="20" y="20" >
+ <tspan class="c1">test</tspan>
+ </text>
+</svg>
diff --git a/svgio/qa/cppunit/data/Drawing_NoWidthHeight.svg b/svgio/qa/cppunit/data/Drawing_NoWidthHeight.svg
new file mode 100644
index 000000000..59520d6ab
--- /dev/null
+++ b/svgio/qa/cppunit/data/Drawing_NoWidthHeight.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ viewBox="0 0 10 10">
+ <rect
+ width="3"
+ height="3"
+ x="6"
+ y="6"
+ style="fill:#008000;stroke-width:0.15288568" />
+</svg>
diff --git a/svgio/qa/cppunit/data/Drawing_WithWidthHeight.svg b/svgio/qa/cppunit/data/Drawing_WithWidthHeight.svg
new file mode 100644
index 000000000..bc5afb553
--- /dev/null
+++ b/svgio/qa/cppunit/data/Drawing_WithWidthHeight.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ viewBox="0 0 10 10"
+ height="10"
+ width="10">
+ <rect
+ width="3"
+ height="3"
+ x="6"
+ y="6"
+ style="fill:#008000;stroke-width:0.15288568" />
+</svg>
diff --git a/svgio/qa/cppunit/data/FontsizeKeywords.svg b/svgio/qa/cppunit/data/FontsizeKeywords.svg
new file mode 100644
index 000000000..9a97983c0
--- /dev/null
+++ b/svgio/qa/cppunit/data/FontsizeKeywords.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg height="600" width="400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+
+<text x="5" y="15" font-size="xx-small" fill="black">Sample</text>
+<text x="5" y="50" font-size="x-small" fill="white">Sample</text>
+<text x="5" y="100" font-size="small" fill="gold">Sample</text>
+<text x="5" y="150" font-size="medium" fill="red">Sample</text>
+<text x="5" y="200" font-size="large" fill="yellow">Sample</text>
+<text x="5" y="250" font-size="x-large" fill="blue">Sample</text>
+<text x="5" y="300" font-size="xx-large" fill="green">Sample</text>
+<text x="5" y="350" font-size="smaller" fill="coral">Sample</text>
+<text x="5" y="400" font-size="larger" fill="pink">Sample</text>
+<text x="5" y="450" font-size="initial" fill="ivory">Sample</text>
+</svg>
diff --git a/svgio/qa/cppunit/data/FontsizePercentage.svg b/svgio/qa/cppunit/data/FontsizePercentage.svg
new file mode 100644
index 000000000..fc7c9fa61
--- /dev/null
+++ b/svgio/qa/cppunit/data/FontsizePercentage.svg
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?> <svg height="600" width="400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" font-size="100%">
+ <text x="5" y="15">Sample</text>
+</svg>
diff --git a/svgio/qa/cppunit/data/FontsizeRelative.svg b/svgio/qa/cppunit/data/FontsizeRelative.svg
new file mode 100644
index 000000000..b957b90a3
--- /dev/null
+++ b/svgio/qa/cppunit/data/FontsizeRelative.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?> <svg height="600" width="400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g font-size="5px" font-family="serif">
+ <text x="10" y="150" font-size="10em" font-family="inherit">Sample</text>
+ <text x="200" y="150" font-size="10em" font-family="serif">Sample</text>
+</g>
+</svg>
diff --git a/svgio/qa/cppunit/data/MarkerOrient.svg b/svgio/qa/cppunit/data/MarkerOrient.svg
new file mode 100644
index 000000000..7997e1cce
--- /dev/null
+++ b/svgio/qa/cppunit/data/MarkerOrient.svg
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <!-- arrowhead marker definition -->
+ <marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5"
+ markerWidth="6" markerHeight="6"
+ orient="auto-start-reverse">
+ <path d="M 0 0 L 10 5 L 0 10 z" />
+ </marker>
+
+ <marker id="arrow2" viewBox="0 0 10 10" refX="5" refY="5"
+ markerWidth="6" markerHeight="6"
+ orient="auto-start-reverse">
+ <path d="M 0 0 L 10 5 L 0 10 z" />
+ </marker>
+
+ </defs>
+
+ <!-- Coordinate axes with a arrowhead in both direction -->
+ <polyline points="10,10 10,90 90,90" fill="none" stroke="black"
+ marker-start="url(#arrow)" marker-end="url(#arrow2)" />
+</svg>
diff --git a/svgio/qa/cppunit/data/RGBAColor.svg b/svgio/qa/cppunit/data/RGBAColor.svg
new file mode 100644
index 000000000..ddd7a3cc0
--- /dev/null
+++ b/svgio/qa/cppunit/data/RGBAColor.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<svg width="120" height="120" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <rect x="10" y="10" width="100" height="100" rx="10" ry="10" fill="rgba(20,10,100,0.5)" visibility="inherit" />
+</svg>
diff --git a/svgio/qa/cppunit/data/RGBColor.svg b/svgio/qa/cppunit/data/RGBColor.svg
new file mode 100644
index 000000000..ad60d5b55
--- /dev/null
+++ b/svgio/qa/cppunit/data/RGBColor.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<svg width="120" height="120" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <rect x="10" y="10" width="100" height="100" rx="10" ry="10" fill="rgb(100,100,100)" visibility="inherit" />
+</svg>
diff --git a/svgio/qa/cppunit/data/Rect.svg b/svgio/qa/cppunit/data/Rect.svg
new file mode 100644
index 000000000..7567cdfb5
--- /dev/null
+++ b/svgio/qa/cppunit/data/Rect.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<svg width="120" height="120" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <rect x="10" y="10" width="100" height="100" rx="10" ry="10" stroke="#ff0000" fill="#00cc00" stroke-width="3" />
+</svg>
diff --git a/svgio/qa/cppunit/data/RectWithParentStyles.svg b/svgio/qa/cppunit/data/RectWithParentStyles.svg
new file mode 100644
index 000000000..a01ba3ff5
--- /dev/null
+++ b/svgio/qa/cppunit/data/RectWithParentStyles.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<svg width="120" height="120" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <style type="text/css" >
+ <![CDATA[
+ svg
+ {
+ stroke: #ff0000;
+ fill: #00cc00;
+ }
+ ]]>
+ </style>
+ <rect x="10" y="10" width="100" height="100" rx="10" ry="10" style="stroke-width: 3;" />
+</svg>
diff --git a/svgio/qa/cppunit/data/RectWithStyles.svg b/svgio/qa/cppunit/data/RectWithStyles.svg
new file mode 100644
index 000000000..b7068499b
--- /dev/null
+++ b/svgio/qa/cppunit/data/RectWithStyles.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<svg width="120" height="120" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <rect x="10" y="10" width="100" height="100" rx="10" ry="10" style="stroke: #ff0000; fill: #00cc00; stroke-width: 3" />
+</svg>
diff --git a/svgio/qa/cppunit/data/RectWithStylesByGroup.svg b/svgio/qa/cppunit/data/RectWithStylesByGroup.svg
new file mode 100644
index 000000000..0a3b1e3cd
--- /dev/null
+++ b/svgio/qa/cppunit/data/RectWithStylesByGroup.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<svg width="120" height="120" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <style type="text/css">
+ <![CDATA[
+ g
+ {
+ stroke: #ff0000;
+ fill: #00cc00;
+ }
+ ]]>
+ </style>
+ </defs>
+ <g>
+ <rect x="10" y="10" width="100" height="100" rx="10" ry="10" style="stroke-width: 3;" />
+ </g>
+</svg>
diff --git a/svgio/qa/cppunit/data/ShapeWithClipPathAndCssStyle.svg b/svgio/qa/cppunit/data/ShapeWithClipPathAndCssStyle.svg
new file mode 100644
index 000000000..4b6455c64
--- /dev/null
+++ b/svgio/qa/cppunit/data/ShapeWithClipPathAndCssStyle.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<svg width="120" height="120"
+ viewPort="0 0 120 120" version="1.1"
+ xmlns="http://www.w3.org/2000/svg">
+
+ <clipPath id="myClip">
+ <rect x="30" y="30" width="20" height="20"/>
+ <rect x="70" y="70" width="20" height="20"/>
+ </clipPath>
+
+ <rect x="10" y="10" width="100" height="100" style="fill:#00D000"
+ clip-path="url(#myClip)"/>
+</svg>
diff --git a/svgio/qa/cppunit/data/VisiotorTest-Rect.svg b/svgio/qa/cppunit/data/VisiotorTest-Rect.svg
new file mode 100644
index 000000000..4cd2d3602
--- /dev/null
+++ b/svgio/qa/cppunit/data/VisiotorTest-Rect.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<svg width="120" height="120" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <rect x="10" y="10" width="100" height="100" rx="10" ry="10" stroke="#ff0000" opacity="0.1" fill="#00cc00" stroke-width="3" />
+</svg>
diff --git a/svgio/qa/cppunit/data/em_units.svg b/svgio/qa/cppunit/data/em_units.svg
new file mode 100644
index 000000000..1ad4d3e3a
--- /dev/null
+++ b/svgio/qa/cppunit/data/em_units.svg
@@ -0,0 +1,14 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="10cm" height="10cm">
+
+ <style>
+ text {font-family: sans-serif; font-size: 36pt;}
+ new {font-family: sans-serif; font-size: 1em;}
+ </style>
+
+ <line x1="5cm" y1="5cm" x2="8cm" y2="5cm" stroke="black" />
+ <!-- 0.5in = 1.27cm = 36pt !-->
+ <line x1="5cm" y1="6.27cm" x2="8cm" y2="6.27cm" stroke="black" />
+ <text x="5cm" y="5cm" class="new">AWlll<tspan x="5cm" dy="1em">AWlll</tspan>
+ </text>
+</svg>
+
diff --git a/svgio/qa/cppunit/data/i125329.svg b/svgio/qa/cppunit/data/i125329.svg
new file mode 100644
index 000000000..86e3bd839
--- /dev/null
+++ b/svgio/qa/cppunit/data/i125329.svg
@@ -0,0 +1,12 @@
+<svg version="1.1" baseProfile="full" id="svg-root"
+ width="12cm" height="6cm" viewBox="0 0 120 60"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <title id="test-title">all selector</title>
+ <style type="text/css">
+ * {fill:silver; stroke-width:1;stroke-miterlimit:100000;}
+ rect {stroke:green;}
+ #test-frame {stroke:blue; fill:none;}
+ </style>
+ <rect x="15" y="15" width="50" height="30" stroke-width="10"/>
+</svg>
diff --git a/svgio/qa/cppunit/data/markerInCssStyle.svg b/svgio/qa/cppunit/data/markerInCssStyle.svg
new file mode 100644
index 000000000..a7a8374f6
--- /dev/null
+++ b/svgio/qa/cppunit/data/markerInCssStyle.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<svg width="500" height="500" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<defs>
+<marker style="overflow:visible;" id="bip" refX="0" refY="0" orient="auto">
+ <path style="stroke: green" d="M 0,-3 v 6" />
+</marker>
+</defs>
+
+<style>
+path.boundary {stroke: red; fill: #ccc; stroke-width: 3; marker-mid: url(#bip); marker-end: url(#bip)}
+</style>
+
+<path class="boundary" d="m 20,20 v 90 90 90 90 90 h 90 90 90 90 90 v -90 -90 -90 -90 -90 h -90 -90 -90 -90 z" />
+</svg>
diff --git a/svgio/qa/cppunit/data/maskText.svg b/svgio/qa/cppunit/data/maskText.svg
new file mode 100644
index 000000000..7405f6a56
--- /dev/null
+++ b/svgio/qa/cppunit/data/maskText.svg
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<svg width="200" height="80"
+ viewBox="0 0 200 80" version="1.1"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <defs>
+ <mask id="myMask"
+ x="0" y="0" width="200" height="80">
+ <rect x="0" y="0" width="100" height="80" fill="white"/>
+ </mask>
+
+ <text id="Text" x="100" y="48"
+ font-size="26" font-weight="bold" text-anchor="middle">
+ Black White
+ </text>
+ </defs>
+
+ <!-- Draw black rectangle in the background -->
+ <rect x="100" y="10" width="95" height="60" />
+
+ <!-- Draw the text string twice. First, the white text without mask.
+ Second, the black text with the mask applied-->
+ <use xlink:href="#Text" fill="white"/>
+ <use xlink:href="#Text" fill="black" mask="url(#myMask)"/>
+</svg>
diff --git a/svgio/qa/cppunit/data/masking-path-07-b.svg b/svgio/qa/cppunit/data/masking-path-07-b.svg
new file mode 100644
index 000000000..63f73d821
--- /dev/null
+++ b/svgio/qa/cppunit/data/masking-path-07-b.svg
@@ -0,0 +1,147 @@
+<svg version="1.1" baseProfile="basic" id="svg-root"
+ width="100%" height="100%" viewBox="0 0 480 360"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!--======================================================================-->
+ <!--= SVG 1.1 2nd Edition Test Case =-->
+ <!--======================================================================-->
+ <!--= Copyright 2009 World Wide Web Consortium, (Massachusetts =-->
+ <!--= Institute of Technology, European Research Consortium for =-->
+ <!--= Informatics and Mathematics (ERCIM), Keio University). =-->
+ <!--= All Rights Reserved. =-->
+ <!--= See http://www.w3.org/Consortium/Legal/. =-->
+ <!--======================================================================-->
+ <d:SVGTestCase xmlns:d="http://www.w3.org/2000/02/svg/testsuite/description/"
+ template-version="1.3" reviewer="CM" author="ED" status="accepted"
+ version="$Revision: 1.11 $" testname="$RCSfile: masking-path-07-b.svg,v $">
+ <d:testDescription xmlns="http://www.w3.org/1999/xhtml" href="http://www.w3.org/TR/SVG11/masking.html#ClippingPaths">
+ <p>
+ This tests that 'clipPath' elements can be used together and how the clipping paths are intersected.
+ </p>
+ <p>
+ There is a gray-white pattern as a background for the two subtest rectangles. This is to show that the holes that are cut out using clip-paths are transparent.
+ The first subtest verifies that when you use the 'clip-path' property on a child element inside a 'clipPath' element the child element is clipped correctly.
+ The second subtest verifies that when a 'clipPath' element has a 'clip-path' property the result is the intersection of the two clip paths.
+ </p>
+ </d:testDescription>
+ <d:operatorScript xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ Run the test. No interaction required.
+ </p>
+ </d:operatorScript>
+ <d:passCriteria xmlns="http://www.w3.org/1999/xhtml">
+ <p>
+ The test has passed if the following conditions are met:
+ </p>
+ <ul>
+ <li>There is no red visible.</li>
+ <li>No shapes extend outside of the rects that have a thick black border.</li>
+ <li>For the left subtest:
+ <ul>
+ <li>There must be a large blue rect with a transparent smaller rect in it, and the intersection of two circles.</li>
+ <li>The borders of the clipregions are shown with black stroke.</li>
+ <li>The blue shapes must be visible only inside of these stroked regions.</li>
+ </ul>
+ </li>
+ <li>For the right subtest:
+ <ul>
+ <li>The test on the right must show part of the large blue rect shape with a transparent rect in it, and part of a circle.</li>
+ <li>The blue shapes must only be visible inside of the circle that has black stroke.</li>
+ </ul>
+ </li>
+ </ul>
+ </d:passCriteria>
+ </d:SVGTestCase>
+ <title id="test-title">$RCSfile: masking-path-07-b.svg,v $</title>
+ <defs>
+ <font-face font-family="SVGFreeSansASCII" unicode-range="U+0-7F">
+ <font-face-src>
+ <font-face-uri xlink:href="../resources/SVGFreeSans.svg#ascii"/>
+ </font-face-src>
+ </font-face>
+ </defs>
+ <g id="test-body-content" font-family="SVGFreeSansASCII,sans-serif" font-size="18">
+
+ <defs>
+ <clipPath id="clipCircle1">
+ <circle id="c1" cx="100" cy="100" r="50"/>
+ </clipPath>
+
+ <clipPath id="clipCircle2">
+ <circle id="c2" cx="150" cy="150" r="50"/>
+ </clipPath>
+
+ <clipPath id="clipPath1">
+ <path id="p1" d="M10 10l100 0 0 100 -100 0ZM50 50l40 0 0 40 -40 0Z" clip-rule="evenodd"/>
+ </clipPath>
+
+ <!-- "If a valid 'clip-path' reference is placed on one of the children of a 'clipPath' element,
+ then the given child element is clipped by the referenced clipping path before OR'ing the
+ silhouette of the child element with the silhouettes of the other child elements." -->
+ <clipPath id="clipRects1">
+ <rect x="50" y="30" width="25" height="100"/>
+ <rect x="25" y="50" width="10" height="10" clip-path="url(#clipTwoCircles)"/>
+ </clipPath>
+
+ <!-- Test use in a clipPath -->
+ <clipPath id="clipTwoCircles">
+ <use xlink:href="#c1"/>
+ <use xlink:href="#c2"/>
+ </clipPath>
+
+ <clipPath id="clipInClip1">
+ <use xlink:href="#c2" clip-path="url(#clipCircle1)"/>
+ <use xlink:href="#p1"/>
+ </clipPath>
+
+ <clipPath id="clipOnClip1" clip-path="url(#clipCircle1)">
+ <use xlink:href="#c2"/>
+ <use xlink:href="#p1"/>
+ </clipPath>
+
+ <pattern patternUnits="userSpaceOnUse" id="pattern" x="0" y="0" width="20" height="20">
+ <rect x="0" y="0" width="10" height="10" fill="gray"/>
+ <rect x="10" y="10" width="10" height="10" fill="gray"/>
+ </pattern>
+ </defs>
+
+ <rect x="20" y="70" width="210" height="210" fill="url(#pattern)" stroke="black" stroke-width="4"/>
+ <rect x="250" y="70" width="210" height="210" fill="url(#pattern)" stroke="black" stroke-width="4"/>
+
+ <text x="240" y="2em" text-anchor="middle">Test clip unions and intersections</text>
+
+ <g transform="translate(20, 70)">
+ <g id="subtest1">
+ <use xlink:href="#p1" fill="red" fill-rule="evenodd"/>
+ <use xlink:href="#c2" fill="red" clip-path="url(#clipCircle1)"/>
+ <use xlink:href="#c1" fill="red" clip-path="url(#clipCircle2)"/>
+
+ <rect width="200" height="200" fill="blue" clip-path="url(#clipInClip1)"/>
+
+ <use xlink:href="#c2" fill="none" clip-path="url(#clipCircle1)" stroke="black"/>
+ <use xlink:href="#c1" fill="none" clip-path="url(#clipCircle2)" stroke="black"/>
+ <use xlink:href="#p1" fill="none" stroke="black"/>
+ </g>
+
+ <g id="subtest2" transform="translate(230,0)">
+ <g clip-path="url(#clipCircle1)">
+ <use xlink:href="#c2" fill="red"/>
+ <use xlink:href="#p1" fill="red" fill-rule="evenodd"/>
+ </g>
+
+ <rect width="300" height="300" fill="blue" clip-path="url(#clipOnClip1)"/>
+
+ <use xlink:href="#c1" fill="none" stroke="black"/>
+ </g>
+ </g>
+ </g>
+ <g font-family="SVGFreeSansASCII,sans-serif" font-size="32">
+ <text id="revision" x="10" y="340" stroke="none" fill="black">$Revision: 1.11 $</text>
+ </g>
+ <rect id="test-frame" x="1" y="1" width="478" height="358" fill="none" stroke="#000000"/>
+ <!-- comment out this watermark once the test is approved --><!--
+ <g id="draft-watermark">
+ <rect x="1" y="1" width="478" height="20" fill="red" stroke="black" stroke-width="1"/>
+ <text font-family="SVGFreeSansASCII,sans-serif" font-weight="bold" font-size="20" x="240"
+ text-anchor="middle" y="18" stroke-width="0.5" stroke="black" fill="white">DRAFT</text>
+ </g>-->
+</svg>
diff --git a/svgio/qa/cppunit/data/noneColor.svg b/svgio/qa/cppunit/data/noneColor.svg
new file mode 100644
index 000000000..552a1cf5a
--- /dev/null
+++ b/svgio/qa/cppunit/data/noneColor.svg
@@ -0,0 +1,3 @@
+<svg width="400" height="110">
+ <rect width="300" height="100" style="fill:none;stroke-width:3;stroke:rgb(0,0,0)" />
+</svg>
diff --git a/svgio/qa/cppunit/data/path.svg b/svgio/qa/cppunit/data/path.svg
new file mode 100644
index 000000000..559ceec6d
--- /dev/null
+++ b/svgio/qa/cppunit/data/path.svg
@@ -0,0 +1,3 @@
+<svg width="44" height="26" xmlns="http://www.w3.org/2000/svg">
+ <path d="M1 1 H 43 V 25 H 1 L 1 1 Z" fill="#007aff" stroke="#fff" opacity="0.1" stroke-width="0"/>
+</svg>
diff --git a/svgio/qa/cppunit/data/symbol.svg b/svgio/qa/cppunit/data/symbol.svg
new file mode 100644
index 000000000..55110f374
--- /dev/null
+++ b/svgio/qa/cppunit/data/symbol.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<svg width="120" height="120"
+ viewPort="0 0 120 120" version="1.1"
+ xmlns="http://www.w3.org/2000/svg">
+
+ <symbol>
+ <rect x="10" y="10" width="100" height="100" fill="red"/>
+ </symbol>
+
+ <rect x="10" y="10" width="10" height="10" fill="#00D000"/>
+</svg>
diff --git a/svgio/qa/cppunit/data/tdf101237.svg b/svgio/qa/cppunit/data/tdf101237.svg
new file mode 100644
index 000000000..e5afa3738
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf101237.svg
@@ -0,0 +1,11 @@
+<svg version="1.1" baseProfile="basic" id="svg-root"
+ width="100%" height="100%" viewBox="0 0 480 360"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none">
+
+ <clipPath id="p.0">
+ <path
+ d="m0 0l437.0 0l0 487.0l-437.0 0l0 -487.0z"
+ clip-rule="nonzero"/>
+ </clipPath>
+ <circle clip-path="url(#p.0)" id="c1" cx="100" cy="100" r="50" style="fill:red" stroke-width="5px" stroke="black"/>
+</svg>
diff --git a/svgio/qa/cppunit/data/tdf103888.svg b/svgio/qa/cppunit/data/tdf103888.svg
new file mode 100644
index 000000000..1663fa395
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf103888.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
+ width="75mm"
+ height="15mm"
+ viewBox="0 0 250 50">
+ <text
+ style="font-size:30px;font-family:sans-serif;fill:#000000;stroke:none"
+ x="20"
+ y="30">Her<tspan style="font-weight:bold">vor</tspan>hebung</text>
+</svg>
diff --git a/svgio/qa/cppunit/data/tdf104339.svg b/svgio/qa/cppunit/data/tdf104339.svg
new file mode 100644
index 000000000..d06ff695c
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf104339.svg
@@ -0,0 +1,65 @@
+<?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"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92pre2 r"
+ xml:space="preserve"
+ width="565.10504"
+ height="132.81749"
+ viewBox="0 0 565.10504 132.8175"
+ sodipodi:docname="aaFINAL_bot_05px.svg"><metadata
+ id="metadata8"><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><defs
+ id="defs6"><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath16"><path
+ d="M 0,612 792,612 792,0 0,0 0,612 Z"
+ id="path18"
+ inkscape:connector-curvature="0" /></clipPath></defs><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="2013"
+ inkscape:window-height="1245"
+ id="namedview4"
+ showgrid="false"
+ fit-margin-top="5"
+ fit-margin-left="5"
+ fit-margin-right="5"
+ fit-margin-bottom="5"
+ inkscape:zoom="0.87256051"
+ inkscape:cx="191.22352"
+ inkscape:cy="-230.18873"
+ inkscape:window-x="616"
+ inkscape:window-y="79"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="g14" /><g
+ id="g10"
+ inkscape:groupmode="layer"
+ inkscape:label="FINAL1"
+ transform="matrix(1.25,0,0,-1.25,-221.64057,456.20243)"><g
+ id="g12"
+ transform="translate(16.855932,5.8347458)"><g
+ id="g14"
+ clip-path="url(#clipPath16)"><g
+ id="g118"
+ transform="translate(403.16803,288.82005)"><path
+ d="m 0,0 v -7.675 h -34.756 v 51.656 h 8.19 V 0 Z"
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ id="path120"
+ inkscape:connector-curvature="0" /></g></g></g></g></svg> \ No newline at end of file
diff --git a/svgio/qa/cppunit/data/tdf123926.svg b/svgio/qa/cppunit/data/tdf123926.svg
new file mode 100644
index 000000000..1a5c2758a
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf123926.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1" class="highcharts-root" style="font-family:&quot;Lucida Grande&quot;, &quot;Lucida Sans Unicode&quot;, Arial, Helvetica, sans-serif;font-size:12px;" width="600" height="400" viewBox="0 0 600 400">
+ <defs>
+ <clipPath id="highcharts-qkip48v-39">
+ <rect x="0" y="0" width="505" height="283" fill="none"/>
+ </clipPath>
+ </defs>
+ <g class="highcharts-series-group" data-z-index="3">
+ <g data-z-index="0.1" class="highcharts-series highcharts-series-0 highcharts-bubble-series highcharts-color-0 " transform="translate(85,61) scale(1 1)" clip-path="url(#highcharts-qkip48v-39)">
+ <path fill="rgb(124,181,236)" fill-opacity="0.5" d="M 501 123.5 A 13.5 13.5 0 1 1 500.99999325000056 123.48650000225 Z" stroke="#7cb5ec" stroke-width="1" class="highcharts-point highcharts-color-0"/>
+ </g>
+ </g>
+</svg>
diff --git a/svgio/qa/cppunit/data/tdf149880.svg b/svgio/qa/cppunit/data/tdf149880.svg
new file mode 100644
index 000000000..08ba74848
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf149880.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" standalone="no"?>
+<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1">
+ <defs>
+ <pattern id="Pattern" x=".05" y=".05" width=".25" height=".25">
+ <rect x="0" y="0" width="50" height="50" fill="skyblue"/>
+ </pattern>
+
+ </defs>
+
+ <rect fill='url("#Pattern")' stroke="black" x="0" y="0" width="200" height="200"/>
+</svg>
diff --git a/svgio/qa/cppunit/data/tdf149893.svg b/svgio/qa/cppunit/data/tdf149893.svg
new file mode 100644
index 000000000..b6b241566
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf149893.svg
@@ -0,0 +1,3 @@
+<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
+ <rect x="0" y="0" width="100%" height="100%" fill=" GREEN"></rect>
+</svg>
diff --git a/svgio/qa/cppunit/data/tdf45771.svg b/svgio/qa/cppunit/data/tdf45771.svg
new file mode 100644
index 000000000..f49e0f569
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf45771.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg height="600" width="400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+
+<text x="5" y="100" font-size="2em">Sample</text>
+</svg>
diff --git a/svgio/qa/cppunit/data/tdf79163.svg b/svgio/qa/cppunit/data/tdf79163.svg
new file mode 100644
index 000000000..015303723
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf79163.svg
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+
+ <rect x="50" y="50" height="110" width="110"
+ style="fill: #ccccff" opacity="0.5"
+ >
+ </rect>
+</svg>
diff --git a/svgio/qa/cppunit/data/tdf85770.svg b/svgio/qa/cppunit/data/tdf85770.svg
new file mode 100644
index 000000000..b1cf9eb3c
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf85770.svg
@@ -0,0 +1,7 @@
+<svg id="svg-root"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ width="13cm" height="11cm">
+<text x="5" y="35" font-size="x-small">Start Middle End</text>
+<text x="5" y="65" font-size="x-small">Start <tspan visibility="hidden">Middle</tspan> End</text>
+</svg>
diff --git a/svgio/qa/cppunit/data/tdf87309.svg b/svgio/qa/cppunit/data/tdf87309.svg
new file mode 100644
index 000000000..af8a7df25
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf87309.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<svg width="120" height="120" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <rect x="10" y="10" width="100" height="100" fill="currentColor"/>
+</svg> \ No newline at end of file
diff --git a/svgio/qa/cppunit/data/tdf94765.svg b/svgio/qa/cppunit/data/tdf94765.svg
new file mode 100644
index 000000000..009bfc8ed
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf94765.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="841.9px" height="595.3px" viewBox="0 0 841.9 595.3" style="enable-background:new 0 0 841.9 595.3;" xml:space="preserve"
+ >
+<style type="text/css">
+ .st1{fill:url(#SVGID_1_);stroke:#000000;stroke-miterlimit:10;}
+</style>
+<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="432.1587" y1="340.3492" x2="770.254" y2="340.3492">
+ <stop offset="0" style="stop-color:#DBDBDB"/>
+ <stop offset="1" style="stop-color:#737373"/>
+</linearGradient>
+<rect x="70.3" y="48.3" fill="url(#SVGID_1_)" width="338.1" height="252.4"/>
+<rect x="432.2" y="214.2" class="st1" width="338.1" height="252.4"/>
+</svg>
diff --git a/svgio/qa/cppunit/data/tdf97542_1.svg b/svgio/qa/cppunit/data/tdf97542_1.svg
new file mode 100644
index 000000000..328bd971a
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf97542_1.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<svg width="200" height="50" xmlns="http://www.w3.org/2000/svg">
+ <!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
+ <defs>
+ <radialGradient id="svg_2" cx="0.5" cy="0.5" r="0.5">
+ <stop offset="0" stop-color="#ff0000"/>
+ <stop offset="1" stop-color="#000000"/>
+ </radialGradient>
+ </defs>
+ <g fill="url(#svg_2)" >
+ <title>Layer 1</title>
+ <rect id="svg_1" height="50" width="200" y="0" x="0"/>
+ <text x="50" y="40" id="svg_12" font-size="48" font-family="serif" fill="#ffff00">Text</text>
+ </g>
+</svg>
diff --git a/svgio/qa/cppunit/data/tdf97542_2.svg b/svgio/qa/cppunit/data/tdf97542_2.svg
new file mode 100644
index 000000000..03cee9683
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf97542_2.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<svg width="200" height="50" xmlns="http://www.w3.org/2000/svg">
+ <!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
+ <defs>
+ <radialGradient id="svg_2" cx="1" cy="1" r="3">
+ <stop offset="0" stop-color="#ff0000"/>
+ <stop offset="1" stop-color="#000000"/>
+ </radialGradient>
+ </defs>
+ <g fill="#ffff00">
+ <title>Layer 1</title>
+ <rect id="svg_1" height="50" width="200" y="0" x="0" />
+ <text x="50" y="40" id="svg_12" font-size="48" font-family="serif" fill="url(#svg_2)">Text</text>
+ </g>
+</svg>
diff --git a/svgio/qa/cppunit/data/tdf97543.svg b/svgio/qa/cppunit/data/tdf97543.svg
new file mode 100644
index 000000000..fa30b2244
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf97543.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<svg width="120" height="120" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <rect x="10" y="10" width="100" height="100" rx="10" ry="10" fill="#00cc00" visibility="inherit" />
+</svg>
diff --git a/svgio/qa/cppunit/data/tdf97936.svg b/svgio/qa/cppunit/data/tdf97936.svg
new file mode 100644
index 000000000..6c059ec5d
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf97936.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+<rect x="70" y="50" height="50" width="50" style="fill: #ccccff"></rect>
+<rect x="10" y="50" height="50" width="50" style="fill: #ccccff"></rect>
+</svg>
diff --git a/svgio/qa/cppunit/data/tdf97941.svg b/svgio/qa/cppunit/data/tdf97941.svg
new file mode 100644
index 000000000..cfe1ca8c4
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf97941.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg height="600" width="400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+
+<text x="5" y="100">
+ <tspan font-size="3em">Sample</tspan></text>
+</svg>
diff --git a/svgio/qa/cppunit/data/tdf99115.svg b/svgio/qa/cppunit/data/tdf99115.svg
new file mode 100644
index 000000000..6d4b5e9c1
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf99115.svg
@@ -0,0 +1,40 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="200 px" height="100 px">
+<style type="text/css" id="style1">
+* {font-size:18px;}
+#tspan6 {fill:blue}
+.c1 {fill:green}
+.c2 {fill:red}
+#tspan8 {fill:green}
+#text9 {fill:green}
+</style>
+<text id="text1" style="" x="1" y="20" >
+ <tspan id="tspan1" fill="red">red 1</tspan>
+</text>
+<text id="text2" style="fill:red" x="1" y="40" >
+ <tspan id="tspan2">red 2</tspan>
+</text>
+<text id="text3" style="" x="1" y="60" >
+ <tspan id="tspan3" style="fill:red">red 3</tspan>
+</text>
+
+<text id="text4" style="fill:red" x="60" y="20" >
+ <tspan id="tspan4" fill="blue">blue 4</tspan>
+</text>
+<text id="text5" x="60" y="40" >
+ <tspan id="tspan5" style="fill:blue" fill="red">blue 5</tspan>
+</text>
+<text id="text6" style="fill:red" x="60" y="60" >
+ <tspan id="tspan6">blue 6</tspan>
+</text>
+
+<text id="text7" x="130" y="20" >
+ <tspan id="tspan7" class="c1" fill="blue">green 7</tspan>
+</text>
+<text id="text8" x="130" y="40" >
+ <tspan id="tspan8" class="c2" fill="red">green 8</tspan>
+</text>
+<text id="text9" x="130" y="60" class="c2">
+ <tspan id="tspan9">green 9</tspan>
+</text>
+
+</svg>
diff --git a/svgio/qa/cppunit/data/tdf99994.svg b/svgio/qa/cppunit/data/tdf99994.svg
new file mode 100644
index 000000000..b4dec353e
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf99994.svg
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<style type="text/css" id="style1">
+*{fill:blue;}
+</style>
+<text id="text1" style="font-family:Sans;">
+ <tspan id="tspan1">test</tspan>
+</text>
+</svg>
diff --git a/svgio/qa/cppunit/data/textXmlSpace.svg b/svgio/qa/cppunit/data/textXmlSpace.svg
new file mode 100644
index 000000000..fe1bc8cee
--- /dev/null
+++ b/svgio/qa/cppunit/data/textXmlSpace.svg
@@ -0,0 +1,16 @@
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
+ viewBox="0 0 250 250">
+ <text y="10" xml:space="default"> a b </text>
+ <text y="30" xml:space="default">a b</text>
+ <text y="50" xml:space="default">a
+ b</text>
+ <text y="70" xml:space="default">a
+b</text>
+ <text y="90" xml:space="preserve"> a b </text>
+ <text y="110" xml:space="preserve">a b</text>
+ <text y="130" xml:space="preserve">a
+ b</text>
+ <text y="150" xml:space="preserve">a
+b</text>
+</svg>
+
diff --git a/svgio/qa/cppunit/data/tspan-fill-opacity.svg b/svgio/qa/cppunit/data/tspan-fill-opacity.svg
new file mode 100644
index 000000000..ef6d5352a
--- /dev/null
+++ b/svgio/qa/cppunit/data/tspan-fill-opacity.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.2" width="210mm" height="297mm" viewBox="0 0 21000 29700" preserveAspectRatio="xMidYMid" fill-rule="evenodd" stroke-width="28.222" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" xmlns:presentation="http://sun.com/xmlns/staroffice/presentation" xmlns:smil="http://www.w3.org/2001/SMIL20/" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xml:space="preserve">
+ <g class="ClosedBezierShape">
+ <rect stroke="none" fill="none" x="9737" y="6537" width="7527" height="3527"/>
+ <g style="opacity: 0.30">
+ <path fill="none" stroke="rgb(255,0,0)" stroke-width="25" stroke-linejoin="round" d="M 9875,6550 C 9806,6550 9750,6606 9750,6675 L 9750,9925 C 9750,9994 9806,10050 9875,10050 L 17125,10050 C 17194,10050 17250,9994 17250,9925 L 17250,6675 C 17250,6606 17194,6550 17125,6550 L 17000,6550 9875,6550 Z"/>
+ </g>
+ </g>
+ <g class="TextShape">
+ <rect stroke="none" fill="none" x="9825" y="6550" width="4076" height="955"/>
+ <text>
+ <tspan x="9825" y="7939" font-family="Arial Narrow, sans-serif" font-size="800px" fill-opacity="0.30" fill="rgb(255,0,0)" stroke="none">hello</tspan>
+ </text>
+ </g>
+</svg>