summaryrefslogtreecommitdiff
path: root/svgio
diff options
context:
space:
mode:
authorXisco Fauli <xiscofauli@libreoffice.org>2022-07-08 11:54:40 +0200
committerXisco Fauli <xiscofauli@libreoffice.org>2022-07-08 13:33:45 +0200
commit6dd0074e5e42467a7f82e363f67ca95d04466fa9 (patch)
tree1d49fbcd2db125036c6b422ffbad4c6acb5916fe /svgio
parenta4acae686c2c55b18b5c27e832827d3c2d8e0f63 (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.hxx17
-rw-r--r--svgio/qa/cppunit/SvgImportTest.cxx33
-rw-r--r--svgio/qa/cppunit/data/MarkerOrient.svg22
-rw-r--r--svgio/source/svgreader/svgmarkernode.cxx8
-rw-r--r--svgio/source/svgreader/svgstyleattributes.cxx13
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())