svgio/inc/svgcharacternode.hxx              |    2 +
 svgio/qa/cppunit/SvgImportTest.cxx          |   36 ++++++++++++++++++++++++++-
 svgio/qa/cppunit/data/tdf156283.svg         |    4 +++
 svgio/source/svgreader/svgcharacternode.cxx |   37 +++++++++++++++++++---------
 4 files changed, 67 insertions(+), 12 deletions(-)

New commits:
commit 879511812741be3564f00406da6c1e722180f155
Author:     Xisco Fauli <xiscofa...@libreoffice.org>
AuthorDate: Tue Aug 1 18:19:20 2023 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Thu Aug 3 10:04:47 2023 +0200

    tdf#156283: take remaing dx value into consideration too
    
    Change-Id: I27c6f12edacd68c7f956b67dcf9ef0cc5045e3d1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155169
    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/+/155212

diff --git a/svgio/inc/svgcharacternode.hxx b/svgio/inc/svgcharacternode.hxx
index 5fad2008ba1c..8861055f8e65 100644
--- a/svgio/inc/svgcharacternode.hxx
+++ b/svgio/inc/svgcharacternode.hxx
@@ -82,6 +82,7 @@ namespace svgio::svgreader
             SvgTextPosition*            mpParent;
             ::std::vector< double >     maX;
             ::std::vector< double >     maY;
+            ::std::vector< double >     maDx;
             ::std::vector< double >     maRotate;
             double                      mfTextLength;
 
@@ -103,6 +104,7 @@ namespace svgio::svgreader
             // data read access
             const SvgTextPosition* getParent() const { return mpParent; }
             const ::std::vector< double >& getX() const { return maX; }
+            const ::std::vector< double >& getDx() const { return maDx; }
             double getTextLength() const { return mfTextLength; }
             bool getLengthAdjust() const { return mbLengthAdjust; }
             bool getAbsoluteX() const { return mbAbsoluteX; }
diff --git a/svgio/qa/cppunit/SvgImportTest.cxx 
b/svgio/qa/cppunit/SvgImportTest.cxx
index ea327dfa0011..17736515010a 100644
--- a/svgio/qa/cppunit/SvgImportTest.cxx
+++ b/svgio/qa/cppunit/SvgImportTest.cxx
@@ -1427,6 +1427,39 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf156269)
     assertXPath(pDocument, "//textsimpleportion[@text='two']", "fontcolor", 
"#000000");
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf156283)
+{
+    Primitive2DSequence aSequence = 
parseSvg(u"/svgio/qa/cppunit/data/tdf156283.svg");
+    CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
+
+    drawinglayer::Primitive2dXmlDump dumper;
+    xmlDocUniquePtr pDocument = 
dumper.dumpAndParse(Primitive2DContainer(aSequence));
+
+    CPPUNIT_ASSERT (pDocument);
+
+    assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", 
"width", "16");
+    assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", 
"height", "16");
+    assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "x", 
"30");
+    assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", "y", 
"20");
+    assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", 
"text", "ABC");
+    assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", 
"dx0", "41");
+    assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", 
"dx1", "52");
+    assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[1]", 
"dx2", "63");
+
+    assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", 
"width", "16");
+    assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", 
"height", "16");
+    assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "x", 
"30");
+    assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", "y", 
"30");
+    assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", 
"text", "ABC");
+
+    // Without the fix in place, this test would have failed with
+    // - Expected: 41
+    // - Actual  : 12
+    assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", 
"dx0", "41");
+    assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", 
"dx1", "52");
+    assertXPath(pDocument, "/primitive2D/transform/textsimpleportion[2]", 
"dx2", "63");
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testTdf156271)
 {
     Primitive2DSequence aSequence = 
parseSvg(u"/svgio/qa/cppunit/data/tdf156271.svg");
@@ -1470,7 +1503,8 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf156271)
     assertXPath(pDocument, "/primitive2D/transform/mask/textsimpleportion[4]", 
"x", "40");
     assertXPath(pDocument, "/primitive2D/transform/mask/textsimpleportion[4]", 
"y", "40");
     assertXPath(pDocument, "/primitive2D/transform/mask/textsimpleportion[4]", 
"text", "AB");
-    assertXPathNoAttribute(pDocument, 
"/primitive2D/transform/mask/textsimpleportion[4]", "dx0");
+    assertXPath(pDocument, "/primitive2D/transform/mask/textsimpleportion[4]", 
"dx0", "12");
+    assertXPath(pDocument, "/primitive2D/transform/mask/textsimpleportion[4]", 
"dx1", "23");
 }
 
 CPPUNIT_TEST_FIXTURE(Test, testTdf149880)
diff --git a/svgio/qa/cppunit/data/tdf156283.svg 
b/svgio/qa/cppunit/data/tdf156283.svg
new file mode 100644
index 000000000000..ee8c46ef5c89
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf156283.svg
@@ -0,0 +1,4 @@
+<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg";>
+       <text x="30 71" y="20">ABC</text>
+       <text x="0" dx="30 29" y="30">ABC</text>
+</svg>
diff --git a/svgio/source/svgreader/svgcharacternode.cxx 
b/svgio/source/svgreader/svgcharacternode.cxx
index e7f08c908ad4..5fab853ed0a0 100644
--- a/svgio/source/svgreader/svgcharacternode.cxx
+++ b/svgio/source/svgreader/svgcharacternode.cxx
@@ -263,7 +263,7 @@ namespace svgio::svgreader
 
                 // prepare TextArray
                 ::std::vector< double > aTextArray(rSvgTextPosition.getX());
-                if(!aTextArray.empty() && aTextArray.size() < nLength)
+                if(aTextArray.size() < nLength)
                 {
                     const sal_uInt32 nArray(aTextArray.size());
 
@@ -273,17 +273,23 @@ namespace svgio::svgreader
                     {
                         fStartX = 
rSvgTextPosition.getParent()->getPosition().getX();
                     }
-                    else
+                    else if (!aTextArray.empty())
                     {
                         fStartX = aTextArray[nArray - 1];
                     }
 
                     ::std::vector< double > 
aExtendArray(aTextLayouterDevice.getTextArray(getText(), nArray, nLength - 
nArray));
-                    aTextArray.reserve(nLength);
+                    ::std::vector< double > aDxArray(rSvgTextPosition.getDx());
+                    double fComulativeDx(0.0);
 
-                    for(const auto &a : aExtendArray)
+                    aTextArray.reserve(nLength);
+                    for(size_t a = 0; a < aExtendArray.size(); ++a)
                     {
-                        aTextArray.push_back(a + fStartX);
+                        if (a < aDxArray.size())
+                        {
+                            fComulativeDx += aDxArray[a];
+                        }
+                        aTextArray.push_back(aExtendArray[a] + fStartX + 
fComulativeDx);
                     }
                 }
 
@@ -642,16 +648,25 @@ namespace svgio::svgreader
             // fill deltas to maX
             maX.reserve(nSizeX);
 
-            for(sal_uInt32 a(1); a < nSizeX; a++)
+            for(sal_uInt32 a(1); a < std::max(nSizeX, nSizeDx); ++a)
             {
-                double nPos = rSvgTextPositions.getX()[a].solve(rInfoProvider, 
NumberType::xcoordinate) - maPosition.getX();
+                if (a < nSizeX)
+                {
+                    double nPos = 
rSvgTextPositions.getX()[a].solve(rInfoProvider, NumberType::xcoordinate) - 
maPosition.getX();
 
-                if(a < nSizeDx)
+                    if(a < nSizeDx)
+                    {
+                        nPos += 
rSvgTextPositions.getDx()[a].solve(rInfoProvider, NumberType::xcoordinate);
+                    }
+
+                    maX.push_back(nPos);
+                }
+                else
                 {
-                    nPos += rSvgTextPositions.getDx()[a].solve(rInfoProvider, 
NumberType::xcoordinate);
+                    // Apply them later since it also needs the character 
width to calculate
+                    // the final character position
+                    
maDx.push_back(rSvgTextPositions.getDx()[a].solve(rInfoProvider, 
NumberType::xcoordinate));
                 }
-
-                maX.push_back(nPos);
             }
 
             // get text positions Y

Reply via email to