sd/qa/unit/data/pptx/tdf128206.pptx                  |binary
 sd/qa/unit/layout-tests.cxx                          |   32 +++++++++++++++++++
 svx/source/sdr/primitive2d/sdrdecompositiontools.cxx |    8 ++--
 3 files changed, 36 insertions(+), 4 deletions(-)

New commits:
commit 6686f0230822154ad8d19494197e84b0d991efe2
Author:     Mike Kaganski <[email protected]>
AuthorDate: Tue Mar 10 12:43:39 2026 +0500
Commit:     Mike Kaganski <[email protected]>
CommitDate: Tue Mar 10 14:27:27 2026 +0100

    tdf#128206, tdf#139808: avoid negative distance
    
    When e.g. fTextLeftDistance was 0, and fTextRightDistance was large,
    the old code made fTextLeftDistance negative.
    
    Interestingly, a scale-to-textsize approach does not work, I tried this:
    
     const double correctionFactor = fWidthForText / (fTextLeftDistance + 
fTextRightDistance);
     fTextLeftDistance *= correctionFactor;
     fTextRightDistance *= correctionFactor;
    
    which correctly gave non-negative distances with their sum equal to
    fHeightForText; but the text was still not positioned correctly. But
    this change puts the text to the expected position, despite the sum
    of the distances is still greater than text size.
    
    The numbers in the unit test reflect correct rendering using current
    method.
    
    Change-Id: Ie6fab6570a4a5675d4356c074d5f7eb54e6b5026
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/201337
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <[email protected]>

diff --git a/sd/qa/unit/data/pptx/tdf128206.pptx 
b/sd/qa/unit/data/pptx/tdf128206.pptx
new file mode 100644
index 000000000000..6ec2f20b1cb7
Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf128206.pptx differ
diff --git a/sd/qa/unit/layout-tests.cxx b/sd/qa/unit/layout-tests.cxx
index befec96e91e4..afffbf4cfb37 100644
--- a/sd/qa/unit/layout-tests.cxx
+++ b/sd/qa/unit/layout-tests.cxx
@@ -637,6 +637,38 @@ CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf168010_PPTX)
     }
 }
 
+CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf128206)
+{
+    createSdImpressDoc("pptx/tdf128206.pptx");
+    xmlDocUniquePtr pXmlDoc = parseLayout();
+
+    // translation
+    assertXPath(pXmlDoc, "//push[@flags='PushMapMode']", 1);
+    assertXPath(pXmlDoc, "//push[@flags='PushMapMode']/mapmode", "mapunit", 
u"MapRelative");
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(
+        14416.0, getXPath(pXmlDoc, "//push[@flags='PushMapMode']/mapmode", 
"x").toDouble(), 3.0);
+    // Without the fix, this failed with
+    // - Expected: 1658
+    // - Actual  : 1415872
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(
+        1658.0, getXPath(pXmlDoc, "//push[@flags='PushMapMode']/mapmode", 
"y").toDouble(), 3.0);
+    // no scaling
+    assertXPath(pXmlDoc, "//push[@flags='PushMapMode']/mapmode", "scalex", 
u"(1/1)");
+    assertXPath(pXmlDoc, "//push[@flags='PushMapMode']/mapmode", "scaley", 
u"(1/1)");
+
+    // text position
+    // Without the fix, this failed with
+    // - Expected: -11031
+    // - Actual  : -718138
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(
+        -11031.0, getXPath(pXmlDoc, "//push[@flags='PushMapMode']/textarray", 
"x").toDouble(), 3.0);
+    // Without the fix, this failed with
+    // - Expected: 3617
+    // - Actual  : -703490
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(
+        3617.0, getXPath(pXmlDoc, "//push[@flags='PushMapMode']/textarray", 
"y").toDouble(), 3.0);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx 
b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
index 00e84afcc520..3ce3b80dcc04 100644
--- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
+++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
@@ -117,8 +117,8 @@ basegfx::B2DRange getTextAnchorRange(const 
attribute::SdrTextAttribute& rText,
     if (fWidthForText > 0 && fTextLeftDistance + fTextRightDistance >= 
fWidthForText)
     {
         const double diffFactor = (fTextLeftDistance + fTextRightDistance - 
fWidthForText) / 2.0;
-        fTextLeftDistance -= diffFactor;
-        fTextRightDistance -= diffFactor;
+        fTextLeftDistance = std::max(fTextLeftDistance - diffFactor, 0.0);
+        fTextRightDistance = std::max(fTextRightDistance - diffFactor, 0.0);
     }
     // If top + bottom margins exceed the available height, reduce each by 
half the excess.
     // Guard on fWidthForText > 0 for consistency with the horizontal check: 
skip for
@@ -128,8 +128,8 @@ basegfx::B2DRange getTextAnchorRange(const 
attribute::SdrTextAttribute& rText,
     if (fWidthForText > 0 && fHeightForText > 0 && fTextUpperDistance + 
fTextLowerDistance >= fHeightForText)
     {
         const double diffFactor = (fTextUpperDistance + fTextLowerDistance - 
fHeightForText) / 2.0;
-        fTextUpperDistance -= diffFactor;
-        fTextLowerDistance -= diffFactor;
+        fTextUpperDistance = std::max(fTextUpperDistance - diffFactor, 0.0);
+        fTextLowerDistance = std::max(fTextLowerDistance - diffFactor, 0.0);
     }
     double fDistanceForTextL, fDistanceForTextT, fDistanceForTextR, 
fDistanceForTextB;
     if (!bVerticalWriting)

Reply via email to