svgio/inc/svgmarkernode.hxx                   |   17 +++++++++----
 svgio/qa/cppunit/SvgImportTest.cxx            |   33 ++++++++++++++++++++++++++
 svgio/qa/cppunit/data/MarkerOrient.svg        |   22 +++++++++++++++++
 svgio/source/svgreader/svgmarkernode.cxx      |   11 ++++++--
 svgio/source/svgreader/svgstyleattributes.cxx |   13 +++++++---
 5 files changed, 85 insertions(+), 11 deletions(-)

New commits:
commit 15f73fab655cc3da29fc19a3951843000719483a
Author:     Xisco Fauli <xiscofa...@libreoffice.org>
AuthorDate: Fri Jul 8 11:54:40 2022 +0200
Commit:     Adolfo Jayme Barrientos <fit...@ubuntu.com>
CommitDate: Tue Jul 12 01:12:52 2022 +0200

    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 <xiscofa...@libreoffice.org>
    Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136899
    Reviewed-by: Adolfo Jayme Barrientos <fit...@ubuntu.com>

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 b97185f36af7..75eaf28c04c5 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 0c930685c7f9..394e11a5586f 100644
--- a/svgio/source/svgreader/svgmarkernode.cxx
+++ b/svgio/source/svgreader/svgmarkernode.cxx
@@ -18,6 +18,7 @@
  */
 
 #include <svgmarkernode.hxx>
+#include <o3tl/string_view.hxx>
 
 namespace svgio::svgreader
 {
@@ -32,7 +33,7 @@ namespace svgio::svgreader
             maMarkerWidth(3),
             maMarkerHeight(3),
             mfAngle(0.0),
-            mbOrientAuto(false)
+            maMarkerOrient(MarkerOrient::notset)
         {
         }
 
@@ -143,9 +144,13 @@ namespace svgio::svgreader
 
                     if(nLen)
                     {
-                        if(aContent.startsWith("auto"))
+                        if(o3tl::equalsIgnoreAsciiCase(o3tl::trim(aContent), 
u"auto"))
                         {
-                            mbOrientAuto = true;
+                            setMarkerOrient(MarkerOrient::auto_start);
+                        }
+                        else 
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 df200e40f428..e41d561a11e1 100644
--- a/svgio/source/svgreader/svgstyleattributes.cxx
+++ b/svgio/source/svgreader/svgstyleattributes.cxx
@@ -997,7 +997,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);
 
@@ -1026,12 +1027,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())

Reply via email to