summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--svgio/inc/svgcharacternode.hxx2
-rw-r--r--svgio/qa/cppunit/SvgImportTest.cxx24
-rw-r--r--svgio/qa/cppunit/data/tspan-fill-opacity.svg15
-rw-r--r--svgio/source/svgreader/svgcharacternode.cxx19
4 files changed, 57 insertions, 3 deletions
diff --git a/svgio/inc/svgcharacternode.hxx b/svgio/inc/svgcharacternode.hxx
index 50ecda7e3a89..738ddf4d9e73 100644
--- a/svgio/inc/svgcharacternode.hxx
+++ b/svgio/inc/svgcharacternode.hxx
@@ -123,7 +123,7 @@ namespace svgio::svgreader
OUString maText;
/// local helpers
- rtl::Reference<drawinglayer::primitive2d::TextSimplePortionPrimitive2D> createSimpleTextPrimitive(
+ rtl::Reference<drawinglayer::primitive2d::BasePrimitive2D> createSimpleTextPrimitive(
SvgTextPosition& rSvgTextPosition,
const SvgStyleAttributes& rSvgStyleAttributes) const;
void decomposeTextWithStyle(
diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx
index 9d9fb93dc8c1..cf678964b996 100644
--- a/svgio/qa/cppunit/SvgImportTest.cxx
+++ b/svgio/qa/cppunit/SvgImportTest.cxx
@@ -84,6 +84,7 @@ class Test : public test::BootstrapFixture, public XmlTestTools
void testTdf97663();
void testTdf149880();
void testCssClassRedefinition();
+ void testTspanFillOpacity();
Primitive2DSequence parseSvg(std::u16string_view aSource);
@@ -134,6 +135,7 @@ public:
CPPUNIT_TEST(testTdf97663);
CPPUNIT_TEST(testTdf149880);
CPPUNIT_TEST(testCssClassRedefinition);
+ CPPUNIT_TEST(testTspanFillOpacity);
CPPUNIT_TEST_SUITE_END();
};
@@ -1127,6 +1129,28 @@ void Test::testCssClassRedefinition()
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);
}
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 000000000000..ef6d5352a8d2
--- /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>
diff --git a/svgio/source/svgreader/svgcharacternode.cxx b/svgio/source/svgreader/svgcharacternode.cxx
index d2949d5a0630..4ca8a3468c02 100644
--- a/svgio/source/svgreader/svgcharacternode.cxx
+++ b/svgio/source/svgreader/svgcharacternode.cxx
@@ -24,6 +24,7 @@
#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
#include <drawinglayer/primitive2d/textbreakuphelper.hxx>
#include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx>
+#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
#include <utility>
#include <o3tl/string_view.hxx>
#include <osl/diagnose.h>
@@ -208,12 +209,12 @@ namespace svgio::svgreader
}
}
- rtl::Reference<TextSimplePortionPrimitive2D> SvgCharacterNode::createSimpleTextPrimitive(
+ rtl::Reference<BasePrimitive2D> SvgCharacterNode::createSimpleTextPrimitive(
SvgTextPosition& rSvgTextPosition,
const SvgStyleAttributes& rSvgStyleAttributes) const
{
// prepare retval, index and length
- rtl::Reference<TextSimplePortionPrimitive2D> pRetval;
+ rtl::Reference<BasePrimitive2D> pRetval;
sal_uInt32 nLength(getText().getLength());
if(nLength)
@@ -412,6 +413,13 @@ namespace svgio::svgreader
if(rSvgStyleAttributes.getFill())
aFill = *rSvgStyleAttributes.getFill();
+ // get fill opacity
+ double fFillOpacity = 1.0;
+ if (rSvgStyleAttributes.getFillOpacity().isSet())
+ {
+ fFillOpacity = rSvgStyleAttributes.getFillOpacity().getNumber();
+ }
+
// prepare TextTransformation
basegfx::B2DHomMatrix aTextTransform;
@@ -487,6 +495,13 @@ namespace svgio::svgreader
aFill);
}
+ if (fFillOpacity != 1.0)
+ {
+ pRetval = new UnifiedTransparencePrimitive2D(
+ drawinglayer::primitive2d::Primitive2DContainer{ pRetval },
+ 1.0 - fFillOpacity);
+ }
+
// advance current TextPosition
rSvgTextPosition.setPosition(rSvgTextPosition.getPosition() + basegfx::B2DVector(fTextWidth, 0.0));
}