include/svx/svdotext.hxx                    |    2 -
 oox/source/drawingml/transform2dcontext.cxx |   33 ++++++++++++++++++++++++++++
 sd/qa/unit/data/pptx/tdf150789.pptx         |binary
 sd/qa/unit/import-tests.cxx                 |   31 ++++++++++++++++++++++++++
 svx/source/svdraw/svdoashp.cxx              |    3 +-
 svx/source/svdraw/svdotext.cxx              |   20 ++++++++++++----
 6 files changed, 82 insertions(+), 7 deletions(-)

New commits:
commit 25c5b910966ab6ca1049d6e34a78ffb448f30899
Author:     Balazs Varga <balazs.varga.ext...@allotropia.de>
AuthorDate: Thu Dec 12 09:23:48 2024 +0100
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Mon Dec 16 16:37:44 2024 +0100

    tdf#150789 - FILEOPEN PPTX: fix text in SmartArt vertically off
    
    Calculate correctly the textbox area of upArrowCallout and
    downArrowCallout shapes in group shapes. In grouped list
    text area does not cover the whole shape but just a part of it at the top.
    
    In case of upArrowCallout and downArrowCallout the arrow size of the shape
    is not included in the textbox area of the full shape.
    
    Change-Id: If732305747c20da55bbd2896522c0b9c05cc4b4b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178343
    Tested-by: Gabor Kelemen <gabor.kelemen.ext...@allotropia.de>
    Reviewed-by: Balazs Varga <balazs.varga.ext...@allotropia.de>
    Tested-by: Jenkins
    (cherry picked from commit 9948c2ed03d227e178b9002dabc6edf34c32a5af)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178546
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/include/svx/svdotext.hxx b/include/svx/svdotext.hxx
index e4099dd6e2ad..c69cfee4c4d6 100644
--- a/include/svx/svdotext.hxx
+++ b/include/svx/svdotext.hxx
@@ -418,7 +418,7 @@ public:
     virtual void TakeTextRect( SdrOutliner& rOutliner, tools::Rectangle& 
rTextRect, bool bNoEditText,
         tools::Rectangle* pAnchorRect, bool bLineWidth = true ) const;
     // Takes writing direction into account when adjusting the rectangle
-    void AdjustRectToTextDistance(tools::Rectangle& rAnchorRect) const;
+    void AdjustRectToTextDistance(tools::Rectangle& rAnchorRect, double 
fExtraRot = 0.0) const;
     virtual void TakeTextAnchorRect(::tools::Rectangle& rAnchorRect) const;
     const GeoStat& GetGeoStat() const { return maGeo; }
 
diff --git a/oox/source/drawingml/transform2dcontext.cxx 
b/oox/source/drawingml/transform2dcontext.cxx
index 656cb41a4b7f..63d197abb81b 100644
--- a/oox/source/drawingml/transform2dcontext.cxx
+++ b/oox/source/drawingml/transform2dcontext.cxx
@@ -135,6 +135,39 @@ bool ConstructPresetTextRectangle(Shape& rShape, 
awt::Rectangle& rRect)
             rRect.Height = rShape.getSize().Height;
             return true;
         }
+        case XML_upArrowCallout:
+        case XML_downArrowCallout:
+        {
+            // The identifiers here reflect the guides name value in 
presetShapeDefinitions.xml
+            sal_Int32 nWidth = rShape.getSize().Width;
+            sal_Int32 nHeight = rShape.getSize().Height;
+            if (nWidth == 0 || nHeight == 0)
+                return false;
+            // double adj1 = 25000.0;
+            // double adj2 = 25000.0;
+            double adj3 = 25000.0; // height of arrow head
+            double adj4 = 64977.0; // height of arrow shaft
+            const auto& aAdjGdList = 
rShape.getCustomShapeProperties()->getAdjustmentGuideList();
+            if (aAdjGdList.size() == 4)
+            {
+                // adj1 = aAdjGdList[0].maFormula.toDouble();
+                // adj2 = aAdjGdList[1].maFormula.toDouble();
+                adj3 = aAdjGdList[2].maFormula.toDouble();
+                adj4 = aAdjGdList[3].maFormula.toDouble();
+            }
+
+            double maxAdj3 = 100000.0 * nHeight / std::min(nWidth, nHeight);
+            adj3 = std::clamp<double>(adj3, 0, maxAdj3);
+            double q2 = adj3 * std::min(nWidth, nHeight) / nHeight;
+            double maxAdj4 = 100000.0 - q2;
+            adj4 = std::clamp<double>(adj4, 0, maxAdj4);
+
+            rRect.X = rShape.getPosition().X;
+            rRect.Y = rShape.getPosition().Y;
+            rRect.Width = rShape.getSize().Width;
+            rRect.Height = nHeight * adj4 / 100000.0;
+            return true;
+        }
         case XML_gear6:
         {
             // The identifiers here reflect the guides name value in 
presetShapeDefinitions.xml
diff --git a/sd/qa/unit/data/pptx/tdf150789.pptx 
b/sd/qa/unit/data/pptx/tdf150789.pptx
new file mode 100644
index 000000000000..6e0a9442949c
Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf150789.pptx differ
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index 3d9423497232..41beb185e0c6 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -1340,6 +1340,37 @@ CPPUNIT_TEST_FIXTURE(SdImportTest, testBnc870237)
     CPPUNIT_ASSERT_EQUAL(sal_Int32(-158), 
pObj->GetMergedItem(SDRATTR_TEXT_LEFTDIST).GetValue());
 }
 
+CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf150789)
+{
+    createSdImpressDoc("pptx/tdf150789.pptx");
+    const SdrPage* pPage = GetPage(1);
+
+    // Simulate a:ext inside dsp:txXfrm with changing the lower distance of 
prst="upArrowCallout" textbox
+    const SdrObjGroup* pGroupObj = 
dynamic_cast<SdrObjGroup*>(pPage->GetObj(0));
+
+    const std::array<size_t, 2> nShapes = { 4, 7 };
+    for (auto i : nShapes)
+    {
+        const SdrObject* pObj = pGroupObj->GetSubList()->GetObj(i);
+        CPPUNIT_ASSERT_MESSAGE("no object", pObj != nullptr);
+
+        OUString sShapeType;
+        const SdrCustomShapeGeometryItem& rGeometryItem(
+            pObj->GetMergedItem(SDRATTR_CUSTOMSHAPE_GEOMETRY));
+        const css::uno::Any aAny = 
*rGeometryItem.GetPropertyValueByName("Type");
+        if (aAny.hasValue())
+            aAny >>= sShapeType;
+        CPPUNIT_ASSERT_EQUAL(OUString("ooxml-upArrowCallout"), sShapeType);
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(395),
+                             
pObj->GetMergedItem(SDRATTR_TEXT_UPPERDIST).GetValue());
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(1424),
+                             
pObj->GetMergedItem(SDRATTR_TEXT_LOWERDIST).GetValue());
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(395),
+                             
pObj->GetMergedItem(SDRATTR_TEXT_RIGHTDIST).GetValue());
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(395), 
pObj->GetMergedItem(SDRATTR_TEXT_LEFTDIST).GetValue());
+    }
+}
+
 CPPUNIT_TEST_FIXTURE(SdImportTest, testCreationDate)
 {
     createSdImpressDoc("fdo71434.pptx");
diff --git a/svx/source/svdraw/svdoashp.cxx b/svx/source/svdraw/svdoashp.cxx
index 2f5e6a21a03e..996071b27e92 100644
--- a/svx/source/svdraw/svdoashp.cxx
+++ b/svx/source/svdraw/svdoashp.cxx
@@ -2650,7 +2650,8 @@ void SdrObjCustomShape::TakeTextAnchorRect( 
tools::Rectangle& rAnchorRect ) cons
     if ( GetTextBounds( rAnchorRect ) )
     {
         Point aRotateRef( maSnapRect.Center() );
-        AdjustRectToTextDistance(rAnchorRect);
+        const double fExtraTextRotation(GetExtraTextRotation());
+        AdjustRectToTextDistance(rAnchorRect, fExtraTextRotation);
 
         if ( rAnchorRect.GetWidth() < 2 )
             rAnchorRect.SetRight( rAnchorRect.Left() + 1 );   // minimal width 
is 2
diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx
index 3b4cf6ba72eb..88def27d0d2c 100644
--- a/svx/source/svdraw/svdotext.cxx
+++ b/svx/source/svdraw/svdotext.cxx
@@ -619,7 +619,7 @@ void SdrTextObj::TakeUnrotatedSnapRect(tools::Rectangle& 
rRect) const
 }
 
 // See also: <unnamed>::getTextAnchorRange in 
svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
-void SdrTextObj::AdjustRectToTextDistance(tools::Rectangle& rAnchorRect) const
+void SdrTextObj::AdjustRectToTextDistance(tools::Rectangle& rAnchorRect, 
double fExtraRot) const
 {
     const tools::Long nLeftDist = GetTextLeftDistance();
     const tools::Long nRightDist = GetTextRightDistance();
@@ -627,10 +627,20 @@ void 
SdrTextObj::AdjustRectToTextDistance(tools::Rectangle& rAnchorRect) const
     const tools::Long nLowerDist = GetTextLowerDistance();
     if (!IsVerticalWriting())
     {
-        rAnchorRect.AdjustLeft(nLeftDist);
-        rAnchorRect.AdjustTop(nUpperDist);
-        rAnchorRect.AdjustRight(-nRightDist);
-        rAnchorRect.AdjustBottom(-nLowerDist);
+        if (fExtraRot == 180.0)
+        {
+            rAnchorRect.AdjustLeft(nLeftDist);
+            rAnchorRect.AdjustTop(-nUpperDist);
+            rAnchorRect.AdjustRight(-nRightDist);
+            rAnchorRect.AdjustBottom(nLowerDist);
+        }
+        else
+        {
+            rAnchorRect.AdjustLeft(nLeftDist);
+            rAnchorRect.AdjustTop(nUpperDist);
+            rAnchorRect.AdjustRight(-nRightDist);
+            rAnchorRect.AdjustBottom(-nLowerDist);
+        }
     }
     else if (IsTopToBottom())
     {

Reply via email to