summaryrefslogtreecommitdiff
path: root/svgio
diff options
context:
space:
mode:
authorXisco Fauli <xiscofauli@libreoffice.org>2024-05-02 22:16:36 +0200
committerXisco Fauli <xiscofauli@libreoffice.org>2024-05-03 11:50:42 +0200
commitd75a37a5829dfcb915f7190d4453c4d4fa25e579 (patch)
treeb59af90d5b14832a5fdeb73cd95e73a9ffdba65a /svgio
parent2aa310cfe0bc10e7bf079147d379f6eb7d061b74 (diff)
tdf#155651: Add support for "context-stroke"
Change-Id: Ib4f4a7b644d0d6c6b36e31b80fd7adc18999110d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167024 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Diffstat (limited to 'svgio')
-rw-r--r--svgio/inc/svgstyleattributes.hxx8
-rw-r--r--svgio/qa/cppunit/SvgImportTest.cxx11
-rw-r--r--svgio/qa/cppunit/data/contextStroke.svg14
-rw-r--r--svgio/source/svgreader/svgmarkernode.cxx2
-rw-r--r--svgio/source/svgreader/svgstyleattributes.cxx37
5 files changed, 68 insertions, 4 deletions
diff --git a/svgio/inc/svgstyleattributes.hxx b/svgio/inc/svgstyleattributes.hxx
index c5c095462f3d..61a3816e82cb 100644
--- a/svgio/inc/svgstyleattributes.hxx
+++ b/svgio/inc/svgstyleattributes.hxx
@@ -247,10 +247,15 @@ namespace svgio::svgreader
// #121221# Defines if evtl. an empty array *is* set
bool mbStrokeDasharraySet : 1;
+ // tdf#155651 Defines if 'context-stroke' is used in stroke
+ bool mbContextStroke : 1;
+
// tdf#94765 Check id references in gradient/pattern getters
OUString maNodeFillURL;
OUString maNodeStrokeURL;
+ const basegfx::BColor* maContextStroke;
+
/// internal helpers
void add_fillGradient(
const basegfx::B2DPolyPolygon& rPath,
@@ -327,6 +332,9 @@ namespace svgio::svgreader
/// stroke content
const basegfx::BColor* getStroke() const;
+ /// context stroke content
+ const basegfx::BColor* getContextStroke() const;
+
/// stop color content
const basegfx::BColor& getStopColor() const;
diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx
index 01463a894dd5..c12f5abaaf16 100644
--- a/svgio/qa/cppunit/SvgImportTest.cxx
+++ b/svgio/qa/cppunit/SvgImportTest.cxx
@@ -646,6 +646,17 @@ CPPUNIT_TEST_FIXTURE(Test, testMarkerOrient)
assertXPath(pDocument, "/primitive2D/transform/transform[2]"_ostr, "xy33"_ostr, "1");
}
+CPPUNIT_TEST_FIXTURE(Test, testContextStroke)
+{
+ xmlDocUniquePtr pDocument = dumpAndParseSvg(u"/svgio/qa/cppunit/data/contextStroke.svg");
+
+ assertXPath(pDocument, "/primitive2D/transform/polypolygonstroke/line"_ostr, "color"_ostr, "#ff0000");
+ assertXPath(pDocument, "/primitive2D/transform/transform[1]/polypolygonstroke/line"_ostr, "color"_ostr, "#ff0000");
+ assertXPath(pDocument, "/primitive2D/transform/transform[2]/polypolygonstroke/line"_ostr, "color"_ostr, "#ff0000");
+ assertXPath(pDocument, "/primitive2D/transform/transform[3]/polypolygonstroke/line"_ostr, "color"_ostr, "#ff0000");
+ assertXPath(pDocument, "/primitive2D/transform/transform[4]/polypolygonstroke/line"_ostr, "color"_ostr, "#ff0000");
+}
+
CPPUNIT_TEST_FIXTURE(Test, testMarkerInPresentation)
{
xmlDocUniquePtr pDocument = dumpAndParseSvg(u"/svgio/qa/cppunit/data/markerInPresentation.svg");
diff --git a/svgio/qa/cppunit/data/contextStroke.svg b/svgio/qa/cppunit/data/contextStroke.svg
new file mode 100644
index 000000000000..5a9b27d69c84
--- /dev/null
+++ b/svgio/qa/cppunit/data/contextStroke.svg
@@ -0,0 +1,14 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
+ <style>
+ path {
+ fill: none;
+ stroke-width: 4px;
+ marker: url(#diamond);
+ }
+ </style>
+ <path d="M 10,50 v -20 h 40 v -20" stroke="red"/>
+
+ <marker id="diamond" markerWidth="12" markerHeight="12" refX="6" refY="6" markerUnits="userSpaceOnUse">
+ <circle cx="6" cy="6" r="3" fill="white" stroke="context-stroke" stroke-width="2"/>
+ </marker>
+</svg>
diff --git a/svgio/source/svgreader/svgmarkernode.cxx b/svgio/source/svgreader/svgmarkernode.cxx
index 083471b49c6b..2279920634a6 100644
--- a/svgio/source/svgreader/svgmarkernode.cxx
+++ b/svgio/source/svgreader/svgmarkernode.cxx
@@ -174,7 +174,7 @@ namespace svgio::svgreader
const drawinglayer::primitive2d::Primitive2DContainer& SvgMarkerNode::getMarkerPrimitives() const
{
- if(aPrimitives.empty() && Display::None != getDisplay())
+ if(Display::None != getDisplay())
{
decomposeSvgNode(const_cast< SvgMarkerNode* >(this)->aPrimitives, true);
}
diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx
index 763a7a3cdd96..0253aa42e071 100644
--- a/svgio/source/svgreader/svgstyleattributes.cxx
+++ b/svgio/source/svgreader/svgstyleattributes.cxx
@@ -817,6 +817,11 @@ namespace svgio::svgreader
rMarkerTransform.identity();
rClipRange.reset();
+ // Set the current stroke to the marker before calling getMarkerPrimitives,
+ // which calls decomposeSvgNode to decompose the children of the marker.
+ // If any of the children uses 'stroke="context-stroke"', then it will use it
+ const_cast<SvgStyleAttributes*>(rMarker.getSvgStyleAttributes())->maContextStroke = getStroke();
+
// get marker primitive representation
rMarkerPrimitives = rMarker.getMarkerPrimitives();
@@ -1287,8 +1292,9 @@ namespace svgio::svgreader
maBaselineShift(BaselineShift::Baseline),
maBaselineShiftNumber(0),
maDominantBaseline(DominantBaseline::Auto),
- maResolvingParent(32, 0),
- mbStrokeDasharraySet(false)
+ maResolvingParent(33, 0),
+ mbStrokeDasharraySet(false),
+ mbContextStroke(false)
{
}
@@ -1353,7 +1359,11 @@ namespace svgio::svgreader
OUString aURL;
SvgNumber aOpacity;
- if(readSvgPaint(aContent, aSvgPaint, aURL, aOpacity))
+ if(o3tl::equalsIgnoreAsciiCase(o3tl::trim(aContent), u"context-stroke"))
+ {
+ mbContextStroke = true;
+ }
+ else if(readSvgPaint(aContent, aSvgPaint, aURL, aOpacity))
{
maStroke = aSvgPaint;
if(aOpacity.isSet())
@@ -1996,6 +2006,23 @@ namespace svgio::svgreader
}
}
+ const basegfx::BColor* SvgStyleAttributes::getContextStroke() const
+ {
+ if (SVGToken::Marker == mrOwner.getType())
+ return maContextStroke;
+
+ const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();
+ if (pSvgStyleAttributes && maResolvingParent[32] < nStyleDepthLimit)
+ {
+ ++maResolvingParent[32];
+ auto ret = pSvgStyleAttributes->getContextStroke();
+ --maResolvingParent[32];
+ return ret;
+ }
+
+ return nullptr;
+ }
+
bool SvgStyleAttributes::isClipPathContent() const
{
if (SVGToken::ClipPathNode == mrOwner.getType())
@@ -2109,6 +2136,10 @@ namespace svgio::svgreader
return &maStroke.getBColor();
}
}
+ else if (mbContextStroke)
+ {
+ return getContextStroke();
+ }
else if (maNodeStrokeURL.isEmpty())
{
const SvgStyleAttributes* pSvgStyleAttributes = getParentStyle();