diff options
author | Xisco Fauli <xiscofauli@libreoffice.org> | 2022-07-08 11:54:40 +0200 |
---|---|---|
committer | Xisco Fauli <xiscofauli@libreoffice.org> | 2022-07-08 13:33:45 +0200 |
commit | 6dd0074e5e42467a7f82e363f67ca95d04466fa9 (patch) | |
tree | 1d49fbcd2db125036c6b422ffbad4c6acb5916fe /svgio | |
parent | a4acae686c2c55b18b5c27e832827d3c2d8e0f63 (diff) |
tdf#149913: add support for auto-start-reverse
See https://svgwg.org/svg2-draft/painting.html#OrientAttribute
Change-Id: Iedcca7bc79a54333c0f80927364caec82ce61167
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136894
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Diffstat (limited to 'svgio')
-rw-r--r-- | svgio/inc/svgmarkernode.hxx | 17 | ||||
-rw-r--r-- | svgio/qa/cppunit/SvgImportTest.cxx | 33 | ||||
-rw-r--r-- | svgio/qa/cppunit/data/MarkerOrient.svg | 22 | ||||
-rw-r--r-- | svgio/source/svgreader/svgmarkernode.cxx | 8 | ||||
-rw-r--r-- | svgio/source/svgreader/svgstyleattributes.cxx | 13 |
5 files changed, 83 insertions, 10 deletions
diff --git a/svgio/inc/svgmarkernode.hxx b/svgio/inc/svgmarkernode.hxx index 41c2d71efe41..3f4b08791bd0 100644 --- a/svgio/inc/svgmarkernode.hxx +++ b/svgio/inc/svgmarkernode.hxx @@ -34,6 +34,13 @@ namespace svgio::svgreader userSpaceOnUse }; + enum class MarkerOrient + { + notset, + auto_start, + auto_start_reverse + }; + private: /// buffered decomposition drawinglayer::primitive2d::Primitive2DContainer aPrimitives; @@ -51,8 +58,7 @@ namespace svgio::svgreader SvgNumber maMarkerWidth; SvgNumber maMarkerHeight; double mfAngle; - - bool mbOrientAuto : 1; // true == on, false == fAngle valid + MarkerOrient maMarkerOrient; public: SvgMarkerNode( @@ -94,10 +100,11 @@ namespace svgio::svgreader /// Angle content, set if found in current context double getAngle() const { return mfAngle; } - void setAngle(double fAngle) { mfAngle = fAngle; mbOrientAuto = false; } + void setAngle(double fAngle) { mfAngle = fAngle;} - /// OrientAuto content, set if found in current context - bool getOrientAuto() const { return mbOrientAuto; } + /// MarkerOrient content + MarkerOrient getMarkerOrient() const { return maMarkerOrient; } + void setMarkerOrient(const MarkerOrient aMarkerOrient) { maMarkerOrient = aMarkerOrient; } }; diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx index 060c18478aae..1ce9b2e0fbfe 100644 --- a/svgio/qa/cppunit/SvgImportTest.cxx +++ b/svgio/qa/cppunit/SvgImportTest.cxx @@ -44,6 +44,7 @@ class Test : public test::BootstrapFixture, public XmlTestTools void testFontsizeKeywords(); void testFontsizePercentage(); void testFontsizeRelative(); + void testMarkerOrient(); void testTdf45771(); void testTdf97941(); void testTdf104339(); @@ -83,6 +84,7 @@ public: CPPUNIT_TEST(testFontsizeKeywords); CPPUNIT_TEST(testFontsizePercentage); CPPUNIT_TEST(testFontsizeRelative); + CPPUNIT_TEST(testMarkerOrient); CPPUNIT_TEST(testTdf45771); CPPUNIT_TEST(testTdf97941); CPPUNIT_TEST(testTdf104339); @@ -310,6 +312,37 @@ void Test::testFontsizeRelative() 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::testTdf45771() { //Check text fontsize when using relative units diff --git a/svgio/qa/cppunit/data/MarkerOrient.svg b/svgio/qa/cppunit/data/MarkerOrient.svg new file mode 100644 index 000000000000..7997e1cce94f --- /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/source/svgreader/svgmarkernode.cxx b/svgio/source/svgreader/svgmarkernode.cxx index 0c2ea6a7a50e..21223c918032 100644 --- a/svgio/source/svgreader/svgmarkernode.cxx +++ b/svgio/source/svgreader/svgmarkernode.cxx @@ -33,7 +33,7 @@ namespace svgio::svgreader maMarkerWidth(3), maMarkerHeight(3), mfAngle(0.0), - mbOrientAuto(false) + maMarkerOrient(MarkerOrient::notset) { } @@ -146,7 +146,11 @@ namespace svgio::svgreader { if(o3tl::equalsIgnoreAsciiCase(o3tl::trim(aContent), u"auto")) { - mbOrientAuto = true; + setMarkerOrient(MarkerOrient::auto_start); + } + if(o3tl::equalsIgnoreAsciiCase(o3tl::trim(aContent), u"auto-start-reverse")) + { + setMarkerOrient(MarkerOrient::auto_start_reverse); } else { diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx index 9e0e24b0e1a0..70b019594248 100644 --- a/svgio/source/svgreader/svgstyleattributes.cxx +++ b/svgio/source/svgreader/svgstyleattributes.cxx @@ -998,7 +998,8 @@ namespace svgio::svgreader basegfx::B2DHomMatrix aCombinedTransform(aPreparedMarkerTransform); // get rotation - if(pPrepared->getOrientAuto()) + if(pPrepared->getMarkerOrient() == SvgMarkerNode::MarkerOrient::auto_start || + pPrepared->getMarkerOrient() == SvgMarkerNode::MarkerOrient::auto_start_reverse) { const sal_uInt32 nPointIndex(b % nSubPolygonPointCount); @@ -1027,12 +1028,18 @@ namespace svgio::svgreader if(bEntering) { - aSum += aEntering.normalize(); + if(bIsFirstMarker && pPrepared->getMarkerOrient() == SvgMarkerNode::MarkerOrient::auto_start_reverse) + aSum -= aEntering.normalize(); + else + aSum += aEntering.normalize(); } if(bLeaving) { - aSum += aLeaving.normalize(); + if(bIsFirstMarker && pPrepared->getMarkerOrient() == SvgMarkerNode::MarkerOrient::auto_start_reverse) + aSum -= aLeaving.normalize(); + else + aSum += aLeaving.normalize(); } if(!aSum.equalZero()) |