Rebased ref, commits from common ancestor:
commit 2808e39cc88f54aa87a65da9599ff7dd8350040c
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Sun Mar 5 14:46:10 2023 +0900
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Sun Mar 5 14:54:23 2023 +0900

    svx: use gfx::Length based types directly in SdrTextObj::NbcMove
    
    Change-Id: Ib0d4a9f60a2ae7f64d914c7a39aa146fef6a9f74

diff --git a/svx/source/svdraw/svdotxtr.cxx b/svx/source/svdraw/svdotxtr.cxx
index b3afdb9a5779..74afe966425f 100644
--- a/svx/source/svdraw/svdotxtr.cxx
+++ b/svx/source/svdraw/svdotxtr.cxx
@@ -40,6 +40,18 @@
 
 using namespace com::sun::star;
 
+namespace
+{
+
+gfx::Tuple2DL createTupleFromPoint(Point const& rPoint, gfx::LengthUnit eUnit 
= gfx::LengthUnit::hmm)
+{
+    auto x = gfx::Length::from(eUnit, rPoint.X());
+    auto y = gfx::Length::from(eUnit, rPoint.Y());
+    return gfx::Tuple2DL(x, y);
+}
+
+} // end anonymous
+
 void SdrTextObj::NbcSetSnapRect(const tools::Rectangle& rRect)
 {
     if (maGeo.nRotationAngle || maGeo.nShearAngle)
@@ -95,8 +107,15 @@ Degree100 SdrTextObj::GetShearAngle(bool /*bVertical*/) 
const
 
 void SdrTextObj::NbcMove(const Size& rSize)
 {
-    moveRectangle(rSize.Width(), rSize.Height());
-    moveOutRectangle(rSize.Width(), rSize.Height());
+    gfx::Tuple2DL aDelta = createTupleFromPoint(Point(rSize.Width(), 
rSize.Height()), getSdrModelFromSdrObject().getUnit());
+    gfx::Length xDelta = aDelta.getX();
+    gfx::Length yDelta = aDelta.getY();
+
+    if (xDelta == 0_emu && yDelta == 0_emu)
+        return;
+
+    maRectangleRange.shift(xDelta, yDelta);
+    m_aOutterRange.shift(xDelta, yDelta);
     maSnapRect.Move(rSize);
     SetBoundAndSnapRectsDirty(true);
 }
@@ -186,19 +205,6 @@ void SdrTextObj::NbcResize(const Point& rRef, const 
Fraction& xFact, const Fract
     SetBoundAndSnapRectsDirty();
 }
 
-namespace
-{
-
-gfx::Tuple2DL createTupleFromPoint(Point const& rPoint, gfx::LengthUnit eUnit 
= gfx::LengthUnit::hmm)
-{
-    auto x = gfx::Length::from(eUnit, rPoint.X());
-    auto y = gfx::Length::from(eUnit, rPoint.Y());
-    return gfx::Tuple2DL(x, y);
-}
-
-} // end anonymous
-
-
 void SdrTextObj::NbcRotate(const Point& rRef, Degree100 nAngle, double sn, 
double cs)
 {
     SetGlueReallyAbsolute(true);
commit d40210f220d5b5a1c79a90ca5467f4410896ae29
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Sat Mar 4 22:12:51 2023 +0900
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Sun Mar 5 14:54:23 2023 +0900

    svx: use gfx::Length based types directly in SdrTextObj::NbcRotate
    
    Change-Id: Ic5ee712fa7507e016441595f8847649fd18b50ee

diff --git a/include/svx/svdtrans.hxx b/include/svx/svdtrans.hxx
index e213d5f1ea61..549e84ed9d67 100644
--- a/include/svx/svdtrans.hxx
+++ b/include/svx/svdtrans.hxx
@@ -46,13 +46,15 @@ SVXCORE_DLLPUBLIC void ResizeRect(tools::Rectangle& rRect, 
const Point& rRef, co
 namespace svx
 {
 SVXCORE_DLLPUBLIC void resizeRange(gfx::Range2DLWrap& rRange, gfx::Tuple2DL 
const& rReference, double fFactorX, double fFactorY);
+SVXCORE_DLLPUBLIC gfx::Tuple2DL rotatePoint(gfx::Tuple2DL const& rPoint, 
gfx::Tuple2DL const& rReference, double sinAngle, double cosAngle);
 }
 
 inline void ResizePoint(Point& rPnt, const Point& rRef, const Fraction& 
xFract, const Fraction& yFract);
 void ResizePoly(tools::Polygon& rPoly, const Point& rRef, const Fraction& 
xFact, const Fraction& yFact);
 void ResizeXPoly(XPolygon& rPoly, const Point& rRef, const Fraction& xFact, 
const Fraction& yFact);
 
-inline void RotatePoint(Point& rPnt, const Point& rRef, double sn, double cs);
+SVXCORE_DLLPUBLIC void RotatePoint(Point& rPnt, const Point& rRef, double sn, 
double cs);
+
 SVXCORE_DLLPUBLIC void RotatePoly(tools::Polygon& rPoly, const Point& rRef, 
double sn, double cs);
 void RotateXPoly(XPolygon& rPoly, const Point& rRef, double sn, double cs);
 void RotateXPoly(XPolyPolygon& rPoly, const Point& rRef, double sn, double cs);
@@ -107,14 +109,6 @@ inline void ResizePoint(Point& rPnt, const Point& rRef, 
const Fraction& xFract,
     rPnt.setY(rRef.Y() + FRound( (rPnt.Y() - rRef.Y()) * nyFract ));
 }
 
-inline void RotatePoint(Point& rPnt, const Point& rRef, double sn, double cs)
-{
-    tools::Long dx=rPnt.X()-rRef.X();
-    tools::Long dy=rPnt.Y()-rRef.Y();
-    rPnt.setX(FRound(rRef.X()+dx*cs+dy*sn));
-    rPnt.setY(FRound(rRef.Y()+dy*cs-dx*sn));
-}
-
 inline void ShearPoint(Point& rPnt, const Point& rRef, double tn, bool bVShear)
 {
     if (!bVShear) { // Horizontal
diff --git a/svx/qa/unit/svdraw.cxx b/svx/qa/unit/svdraw.cxx
index e513d49284e4..b632fc642aeb 100644
--- a/svx/qa/unit/svdraw.cxx
+++ b/svx/qa/unit/svdraw.cxx
@@ -734,4 +734,162 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testResizeRect)
 }
 }
 
+CPPUNIT_TEST_FIXTURE(SvdrawTest, testRotatePoint)
+{
+    {
+        auto angle = 18000_deg100;
+        double angleRadians = toRadians(angle);
+        Point aPoint(2000, 1000);
+        Point aReference(1000, 1000);
+        RotatePoint(aPoint, aReference, std::sin(angleRadians), 
std::cos(angleRadians));
+
+        CPPUNIT_ASSERT_EQUAL(Point(0, 1000), aPoint);
+    }
+
+    {
+        auto angle = 9000_deg100;
+        double angleRadians = toRadians(angle);
+        Point aPoint(2000, 1000);
+        Point aReference(1000, 1000);
+        RotatePoint(aPoint, aReference, std::sin(angleRadians), 
std::cos(angleRadians));
+
+        CPPUNIT_ASSERT_EQUAL(Point(1000, 0), aPoint);
+    }
+
+    {
+        auto angle = 18000_deg100;
+        double angleRadians = toRadians(angle);
+        Point aPoint(100, 100);
+        Point aReference(200, 200);
+        RotatePoint(aPoint, aReference, std::sin(angleRadians), 
std::cos(angleRadians));
+
+        CPPUNIT_ASSERT_EQUAL(Point(300, 300), aPoint);
+    }
+}
+
+CPPUNIT_TEST_FIXTURE(SvdrawTest, testRectangleObjectMove)
+{
+    std::unique_ptr<SdrModel> pModel(new SdrModel(nullptr, nullptr, true));
+    pModel->GetItemPool().FreezeIdRanges();
+
+    rtl::Reference<SdrPage> pPage(new SdrPage(*pModel, false));
+    pPage->setSize({ 50_cm, 50_cm });
+    pModel->InsertPage(pPage.get(), 0);
+
+    tools::Rectangle aRect(Point(), Size(100, 100));
+    rtl::Reference<SdrRectObj> pRectangleObject = new SdrRectObj(*pModel, 
aRect);
+    pPage->NbcInsertObject(pRectangleObject.get());
+
+    CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(), Size(100, 100)),
+                         pRectangleObject->GetLogicRect());
+    pRectangleObject->NbcMove({ 100, 100 });
+    CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(100, 100), Size(100, 100)),
+                         pRectangleObject->GetLogicRect());
+
+    pPage->RemoveObject(0);
+}
+
+CPPUNIT_TEST_FIXTURE(SvdrawTest, testRectangleObjectRotate)
+{
+    std::unique_ptr<SdrModel> pModel(new SdrModel(nullptr, nullptr, true));
+    pModel->GetItemPool().FreezeIdRanges();
+
+    rtl::Reference<SdrPage> pPage(new SdrPage(*pModel, false));
+    pPage->setSize({ 50_cm, 50_cm });
+    pModel->InsertPage(pPage.get(), 0);
+
+    {
+        tools::Rectangle aObjectSize(Point(), Size(100, 100));
+        rtl::Reference<SdrRectObj> pRectangleObject = new SdrRectObj(*pModel, 
aObjectSize);
+        pPage->NbcInsertObject(pRectangleObject.get());
+
+        CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(0, 0), Size(100, 100)),
+                             pRectangleObject->GetLogicRect());
+        CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(0, 0), Size(100, 100)),
+                             pRectangleObject->GetSnapRect());
+        CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(-1, -1), Size(102, 102)),
+                             pRectangleObject->GetCurrentBoundRect());
+
+        auto angle = 9000_deg100;
+        double angleRadians = toRadians(angle);
+        pRectangleObject->NbcRotate(aObjectSize.Center(), angle, 
std::sin(angleRadians),
+                                    std::cos(angleRadians));
+
+        CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(0, 98), Size(100, 100)),
+                             pRectangleObject->GetLogicRect());
+        CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(0, -1), Size(100, 100)),
+                             pRectangleObject->GetSnapRect());
+        CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(-1, -2), Size(102, 102)),
+                             pRectangleObject->GetCurrentBoundRect());
+
+        pPage->RemoveObject(0);
+    }
+
+    {
+        tools::Rectangle aObjectSize(Point(), Size(100, 100));
+        rtl::Reference<SdrRectObj> pRectangleObject = new SdrRectObj(*pModel, 
aObjectSize);
+        pPage->NbcInsertObject(pRectangleObject.get());
+
+        CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(0, 0), Size(100, 100)),
+                             pRectangleObject->GetLogicRect());
+        CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(0, 0), Size(100, 100)),
+                             pRectangleObject->GetSnapRect());
+        CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(-1, -1), Size(102, 102)),
+                             pRectangleObject->GetCurrentBoundRect());
+
+        auto angle = -4500_deg100;
+        double angleRadians = toRadians(angle);
+        pRectangleObject->NbcRotate(aObjectSize.Center(), angle, 
std::sin(angleRadians),
+                                    std::cos(angleRadians));
+
+        CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(49, -20), Size(100, 100)),
+                             pRectangleObject->GetLogicRect());
+        CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(-21, -20), Size(141, 141)),
+                             pRectangleObject->GetSnapRect());
+        CPPUNIT_ASSERT_EQUAL(tools::Rectangle(Point(-22, -21), Size(143, 143)),
+                             pRectangleObject->GetCurrentBoundRect());
+
+        pPage->RemoveObject(0);
+    }
+}
+
+CPPUNIT_TEST_FIXTURE(SvdrawTest, testRotatePoint2D)
+{
+    {
+        auto angle = 18000_deg100;
+        double angleRadians = toRadians(angle);
+        gfx::Tuple2DL aPoint(2_cm, 1_cm);
+        gfx::Tuple2DL aReference(1_cm, 1_cm);
+        aPoint
+            = svx::rotatePoint(aPoint, aReference, std::sin(angleRadians), 
std::cos(angleRadians));
+
+        CPPUNIT_ASSERT_EQUAL(0_cm, aPoint.getX());
+        CPPUNIT_ASSERT_EQUAL(1_cm, aPoint.getY());
+    }
+
+    {
+        auto angle = 9000_deg100;
+        double angleRadians = toRadians(angle);
+        gfx::Tuple2DL aPoint(2_cm, 1_cm);
+        gfx::Tuple2DL aReference(1_cm, 1_cm);
+        aPoint
+            = svx::rotatePoint(aPoint, aReference, std::sin(angleRadians), 
std::cos(angleRadians));
+
+        CPPUNIT_ASSERT_EQUAL(1_cm, aPoint.getX());
+        CPPUNIT_ASSERT_EQUAL(0_cm, aPoint.getY());
+    }
+
+    {
+        auto angle = 18000_deg100;
+        double angleRadians = toRadians(angle);
+        gfx::Tuple2DL aPoint(1_cm, 1_cm);
+        gfx::Tuple2DL aReference(2_cm, 2_cm);
+        aPoint
+            = svx::rotatePoint(aPoint, aReference, std::sin(angleRadians), 
std::cos(angleRadians));
+
+        CPPUNIT_ASSERT_EQUAL(3_cm, aPoint.getX());
+        CPPUNIT_ASSERT_EQUAL(3_cm, aPoint.getY());
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/svdraw/svdotxtr.cxx b/svx/source/svdraw/svdotxtr.cxx
index f2df68068717..b3afdb9a5779 100644
--- a/svx/source/svdraw/svdotxtr.cxx
+++ b/svx/source/svdraw/svdotxtr.cxx
@@ -186,28 +186,50 @@ void SdrTextObj::NbcResize(const Point& rRef, const 
Fraction& xFact, const Fract
     SetBoundAndSnapRectsDirty();
 }
 
+namespace
+{
+
+gfx::Tuple2DL createTupleFromPoint(Point const& rPoint, gfx::LengthUnit eUnit 
= gfx::LengthUnit::hmm)
+{
+    auto x = gfx::Length::from(eUnit, rPoint.X());
+    auto y = gfx::Length::from(eUnit, rPoint.Y());
+    return gfx::Tuple2DL(x, y);
+}
+
+} // end anonymous
+
+
 void SdrTextObj::NbcRotate(const Point& rRef, Degree100 nAngle, double sn, 
double cs)
 {
     SetGlueReallyAbsolute(true);
-    tools::Rectangle aRectangle = getRectangle();
-    tools::Long dx = aRectangle.Right() - aRectangle.Left();
-    tools::Long dy = aRectangle.Bottom() - aRectangle.Top();
-    Point aPoint1(aRectangle.TopLeft());
-    RotatePoint(aPoint1, rRef, sn, cs);
-    Point aPoint2(aPoint1.X() + dx, aPoint1.Y() + dy);
-    aRectangle = tools::Rectangle(aPoint1, aPoint2);
-    setRectangle(aRectangle);
+    gfx::Tuple2DL aReference = createTupleFromPoint(rRef, 
getSdrModelFromSdrObject().getUnit());
 
-    if (maGeo.nRotationAngle==0_deg100) {
-        maGeo.nRotationAngle=NormAngle36000(nAngle);
-        maGeo.mfSinRotationAngle=sn;
-        maGeo.mfCosRotationAngle=cs;
-    } else {
-        maGeo.nRotationAngle=NormAngle36000(maGeo.nRotationAngle+nAngle);
+    gfx::Length aWidth = maRectangleRange.getWidth();
+    gfx::Length aHeight = maRectangleRange.getHeight();
+
+    gfx::Tuple2DL aPoint(maRectangleRange.getMinX(), 
maRectangleRange.getMinY());
+    gfx::Tuple2DL aRotated = svx::rotatePoint(aPoint, aReference, sn, cs);
+
+    maRectangleRange = gfx::Range2DLWrap(
+        aRotated.getX(),
+        aRotated.getY(),
+        aRotated.getX() + aWidth,
+        aRotated.getY() + aHeight);
+
+    if (maGeo.nRotationAngle == 0_deg100)
+    {
+        maGeo.nRotationAngle = NormAngle36000(nAngle);
+        maGeo.mfSinRotationAngle = sn;
+        maGeo.mfCosRotationAngle = cs;
+    }
+    else
+    {
+        maGeo.nRotationAngle = NormAngle36000(maGeo.nRotationAngle + nAngle);
         maGeo.RecalcSinCos();
     }
+
     SetBoundAndSnapRectsDirty();
-    NbcRotateGluePoints(rRef,nAngle,sn,cs);
+    NbcRotateGluePoints(rRef, nAngle, sn, cs);
     SetGlueReallyAbsolute(false);
 }
 
diff --git a/svx/source/svdraw/svdtrans.cxx b/svx/source/svdraw/svdtrans.cxx
index 04b02e9184c6..5afacc34dd9a 100644
--- a/svx/source/svdraw/svdtrans.cxx
+++ b/svx/source/svdraw/svdtrans.cxx
@@ -75,8 +75,24 @@ void resizeRange(gfx::Range2DLWrap& rRange, gfx::Tuple2DL 
const& rReference, dou
     rRange = gfx::Range2DLWrap(left, top, right, bottom, rRange.getUnit());
 }
 
+gfx::Tuple2DL rotatePoint(gfx::Tuple2DL const& rPoint, gfx::Tuple2DL const& 
rReference, double sinAngle, double cosAngle)
+{
+    gfx::Length dx = rPoint.getX() - rReference.getX();
+    gfx::Length dy = rPoint.getY() - rReference.getY();
+    gfx::Length x = rReference.getX() + dx * cosAngle + dy * sinAngle;
+    gfx::Length y = rReference.getY() + dy * cosAngle - dx * sinAngle;
+    return {x, y};
+}
+
 } // end svx namespace
 
+void RotatePoint(Point& rPnt, const Point& rRef, double sn, double cs)
+{
+    tools::Long dx=rPnt.X()-rRef.X();
+    tools::Long dy=rPnt.Y()-rRef.Y();
+    rPnt.setX(FRound(rRef.X()+dx*cs+dy*sn));
+    rPnt.setY(FRound(rRef.Y()+dy*cs-dx*sn));
+}
 
 void ResizePoly(tools::Polygon& rPoly, const Point& rRef, const Fraction& 
xFact, const Fraction& yFact)
 {
commit 1119816a7a2c13803777351c86ea2b13a03fb31f
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Tue Feb 21 22:05:02 2023 +0900
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Sun Mar 5 14:54:23 2023 +0900

    svx: change SdrObjGeoData aBoundRectangle using gfx::Range2DLWrap
    
    Change-Id: I13213ea2bdbfc5badb87d1bbd836192b8ae45e72

diff --git a/include/svx/svdobj.hxx b/include/svx/svdobj.hxx
index 55d800e9852d..9202bd575c3a 100644
--- a/include/svx/svdobj.hxx
+++ b/include/svx/svdobj.hxx
@@ -173,8 +173,20 @@ public:
  */
 class SVXCORE_DLLPUBLIC SdrObjGeoData
 {
+private:
+    gfx::Range2DLWrap maBoundRange;
+
 public:
-    tools::Rectangle                   aBoundRect;
+    gfx::Range2DLWrap const& getBoundRange() const
+    {
+        return maBoundRange;
+    }
+
+    void setBoundRange(gfx::Range2DLWrap const& rRange)
+    {
+        maBoundRange = rRange;
+    }
+
     Point                       aAnchor;
     std::unique_ptr<SdrGluePointList>
                                 pGPL;
@@ -185,7 +197,6 @@ public:
     bool                        mbVisible;
     SdrLayerID                  mnLayerID;
 
-public:
     SdrObjGeoData();
     virtual ~SdrObjGeoData();
 };
@@ -417,6 +428,7 @@ public:
     // non-useful BoundRects sometimes) i rename that method from 
GetBoundRect() to
     // GetCurrentBoundRect().
     virtual const tools::Rectangle& GetCurrentBoundRect() const;
+    virtual const gfx::Range2DLWrap& getCurrentBoundRange() const;
 
     // To have a possibility to get the last calculated BoundRect e.g for 
producing
     // the first rectangle for repaints (old and new need to be used) without 
forcing
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx
index 791229023d79..5e7333e1afa3 100644
--- a/svx/source/svdraw/svdobj.cxx
+++ b/svx/source/svdraw/svdobj.cxx
@@ -932,6 +932,13 @@ const tools::Rectangle& SdrObject::GetCurrentBoundRect() 
const
     return getOutRectangle();
 }
 
+const gfx::Range2DLWrap& SdrObject::getCurrentBoundRange() const
+{
+    if (m_aOutterRange.isEmpty())
+        const_cast<SdrObject*>(this)->RecalcBoundRect();
+    return m_aOutterRange;
+}
+
 // To have a possibility to get the last calculated BoundRect e.g for producing
 // the first rectangle for repaints (old and new need to be used) without 
forcing
 // a RecalcBoundRect (which may be problematical and expensive sometimes) I 
add here
@@ -1866,7 +1873,7 @@ std::unique_ptr<SdrObjGeoData> SdrObject::NewGeoData() 
const
 
 void SdrObject::SaveGeoData(SdrObjGeoData& rGeo) const
 {
-    rGeo.aBoundRect    =GetCurrentBoundRect();
+    rGeo.setBoundRange(getCurrentBoundRange());
     rGeo.aAnchor       =m_aAnchor       ;
     rGeo.bMovProt      =m_bMovProt      ;
     rGeo.bSizProt      =m_bSizProt      ;
@@ -1890,7 +1897,7 @@ void SdrObject::SaveGeoData(SdrObjGeoData& rGeo) const
 void SdrObject::RestoreGeoData(const SdrObjGeoData& rGeo)
 {
     SetBoundAndSnapRectsDirty();
-    setOutRectangle(rGeo.aBoundRect);
+    m_aOutterRange = rGeo.getBoundRange();
     m_aAnchor       =rGeo.aAnchor       ;
     m_bMovProt      =rGeo.bMovProt      ;
     m_bSizProt      =rGeo.bSizProt      ;
commit fa1dc625299992ba44fa8d05be8d4d8a23a2ec85
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Fri Feb 10 18:10:33 2023 +0900
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Sun Mar 5 14:54:23 2023 +0900

    svx: refactor SdrObject resize to use m_aOutterRange directly
    
    Change-Id: I77aad10b32a53545c7f7bbf8fd87b914395a5bad

diff --git a/include/svx/svdtrans.hxx b/include/svx/svdtrans.hxx
index dea845a26bc1..e213d5f1ea61 100644
--- a/include/svx/svdtrans.hxx
+++ b/include/svx/svdtrans.hxx
@@ -29,6 +29,9 @@
 #include <tools/mapunit.hxx>
 #include <tools/poly.hxx>
 
+#include <basegfx/units/Range2DLWrap.hxx>
+#include <basegfx/units/LengthTypes.hxx>
+
 // That maximum shear angle
 constexpr Degree100 SDRMAXSHEAR(8900);
 
@@ -39,6 +42,12 @@ inline void MovePoly(tools::Polygon& rPoly, const Size& S)   
   { rPoly.Move(S.W
 void MoveXPoly(XPolygon& rPoly, const Size& S);
 
 SVXCORE_DLLPUBLIC void ResizeRect(tools::Rectangle& rRect, const Point& rRef, 
const Fraction& xFact, const Fraction& yFact);
+
+namespace svx
+{
+SVXCORE_DLLPUBLIC void resizeRange(gfx::Range2DLWrap& rRange, gfx::Tuple2DL 
const& rReference, double fFactorX, double fFactorY);
+}
+
 inline void ResizePoint(Point& rPnt, const Point& rRef, const Fraction& 
xFract, const Fraction& yFract);
 void ResizePoly(tools::Polygon& rPoly, const Point& rRef, const Fraction& 
xFact, const Fraction& yFact);
 void ResizeXPoly(XPolygon& rPoly, const Point& rRef, const Fraction& xFact, 
const Fraction& yFact);
diff --git a/svx/qa/unit/svdraw.cxx b/svx/qa/unit/svdraw.cxx
index 006158bbe49e..e513d49284e4 100644
--- a/svx/qa/unit/svdraw.cxx
+++ b/svx/qa/unit/svdraw.cxx
@@ -7,7 +7,7 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-#include <test/unoapixml_test.hxx>
+#include <basegfx/units/Length.hxx>
 
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
@@ -38,10 +38,10 @@
 
 #include <sdr/contact/objectcontactofobjlistpainter.hxx>
 
+#include <test/unoapixml_test.hxx>
+
 using namespace ::com::sun::star;
 
-namespace
-{
 /// Tests for svx/source/svdraw/ code.
 class SvdrawTest : public UnoApiXmlTest
 {
@@ -669,6 +669,69 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testRotatePoint)
         CPPUNIT_ASSERT_EQUAL(Point(300, 300), aPoint);
     }
 }
+
+CPPUNIT_TEST_FIXTURE(SvdrawTest, testResizeRect)
+{
+    {
+        tools::Rectangle aRectangle(1, 1, 10, 10);
+        Point aReference(1, 1);
+        ResizeRect(aRectangle, aReference, Fraction(1, 2), Fraction(1, 2));
+
+        CPPUNIT_ASSERT_EQUAL(tools::Rectangle(1, 1, 6, 6), aRectangle);
+    }
+
+    {
+        tools::Rectangle aRectangle(1, 1, 10, 10);
+        Point aReference(10, 10);
+        ResizeRect(aRectangle, aReference, Fraction(1, 2), Fraction(1, 2));
+
+        CPPUNIT_ASSERT_EQUAL(tools::Rectangle(5, 5, 10, 10), aRectangle);
+    }
+
+    {
+        gfx::Range2DLWrap aRange(1_hmm, 1_hmm, 10_hmm, 10_hmm);
+        CPPUNIT_ASSERT_EQUAL(9_hmm, aRange.getWidth());
+        CPPUNIT_ASSERT_EQUAL(9_hmm, aRange.getHeight());
+
+        gfx::Tuple2DL aReference(1_hmm, 1_hmm);
+        svx::resizeRange(aRange, aReference, 0.5, 0.5);
+
+        CPPUNIT_ASSERT_EQUAL(false, aRange.isEmpty());
+
+        CPPUNIT_ASSERT_EQUAL(1_hmm, aRange.getMinX());
+        CPPUNIT_ASSERT_EQUAL(5.5_hmm, aRange.getMaxX());
+        CPPUNIT_ASSERT_EQUAL(1_hmm, aRange.getMinY());
+        CPPUNIT_ASSERT_EQUAL(5.5_hmm, aRange.getMaxY());
+
+        CPPUNIT_ASSERT_EQUAL(4.5_hmm, aRange.getWidth());
+        CPPUNIT_ASSERT_EQUAL(4.5_hmm, aRange.getHeight());
+
+        auto aRectangle = aRange.toToolsRect();
+        CPPUNIT_ASSERT_EQUAL(tools::Rectangle(1, 1, 6, 6), aRectangle);
+    }
+
+    {
+        gfx::Range2DLWrap aRange(1_hmm, 1_hmm, 10_hmm, 10_hmm);
+        CPPUNIT_ASSERT_EQUAL(9_hmm, aRange.getWidth());
+        CPPUNIT_ASSERT_EQUAL(9_hmm, aRange.getHeight());
+
+        gfx::Tuple2DL aReference(10_hmm, 10_hmm);
+        svx::resizeRange(aRange, aReference, 0.5, 0.5);
+
+        CPPUNIT_ASSERT_EQUAL(false, aRange.isEmpty());
+
+        CPPUNIT_ASSERT_EQUAL(5.5_hmm, aRange.getMinX());
+        CPPUNIT_ASSERT_EQUAL(10_hmm, aRange.getMaxX());
+        CPPUNIT_ASSERT_EQUAL(5.5_hmm, aRange.getMinY());
+        CPPUNIT_ASSERT_EQUAL(10_hmm, aRange.getMaxY());
+
+        CPPUNIT_ASSERT_EQUAL(4.5_hmm, aRange.getWidth());
+        CPPUNIT_ASSERT_EQUAL(4.5_hmm, aRange.getHeight());
+
+        auto aRectangle = aRange.toToolsRect();
+        CPPUNIT_ASSERT_EQUAL(tools::Rectangle(6, 6, 10, 10), aRectangle);
+    }
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx
index 514eddd80595..791229023d79 100644
--- a/svx/source/svdraw/svdobj.cxx
+++ b/svx/source/svdraw/svdobj.cxx
@@ -35,6 +35,7 @@
 #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
 #include <basegfx/polygon/b2dpolypolygontools.hxx>
 #include <basegfx/units/Range2DLWrap.hxx>
+#include <basegfx/units/LengthTypes.hxx>
 #include <basegfx/range/b2drange.hxx>
 #include <drawinglayer/processor2d/contourextractor2d.hxx>
 #include <drawinglayer/processor2d/linegeometryextractor2d.hxx>
@@ -946,10 +947,8 @@ void SdrObject::RecalcBoundRect()
     if ((getSdrModelFromSdrObject().isLocked()) || 
utl::ConfigManager::IsFuzzing())
         return;
 
-    auto const& rRectangle = getOutRectangle();
-
     // central new method which will calculate the BoundRect using primitive 
geometry
-    if (!rRectangle.IsEmpty())
+    if (!isOutRectangleEmpty())
         return;
 
     // Use view-independent data - we do not want any connections
@@ -1404,24 +1403,32 @@ void SdrObject::NbcMove(const Size& rSize)
 
 void SdrObject::NbcResize(const Point& rRef, const Fraction& xFact, const 
Fraction& yFact)
 {
-    bool bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
-    bool bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
-    if (bXMirr || bYMirr) {
+    bool bXMirror = (xFact.GetNumerator() < 0) != (xFact.GetDenominator() < 0);
+    bool bYMirror = (yFact.GetNumerator() < 0) != (yFact.GetDenominator() < 0);
+    if (bXMirror || bYMirror)
+    {
         Point aRef1(GetSnapRect().Center());
-        if (bXMirr) {
+        if (bXMirror)
+        {
             Point aRef2(aRef1);
             aRef2.AdjustY( 1 );
-            NbcMirrorGluePoints(aRef1,aRef2);
+            NbcMirrorGluePoints(aRef1, aRef2);
         }
-        if (bYMirr) {
+        if (bYMirror)
+        {
             Point aRef2(aRef1);
             aRef2.AdjustX( 1 );
-            NbcMirrorGluePoints(aRef1,aRef2);
+            NbcMirrorGluePoints(aRef1, aRef2);
         }
     }
-    auto aRectangle = getOutRectangle();
-    ResizeRect(aRectangle, rRef, xFact, yFact);
-    setOutRectangle(aRectangle);
+
+    auto eUnit = getSdrModelFromSdrObject().getUnit();
+    gfx::Tuple2DL aReference{
+        gfx::Length::from(eUnit, rRef.X()),
+        gfx::Length::from(eUnit, rRef.Y())};
+    double fFactorX = xFact.IsValid() ? double(xFact) : 1.0;
+    double fFactorY = yFact.IsValid() ? double(yFact) : 1.0;
+    svx::resizeRange(m_aOutterRange, aReference, fFactorX, fFactorY);
 
     SetBoundAndSnapRectsDirty();
 }
diff --git a/svx/source/svdraw/svdtrans.cxx b/svx/source/svdraw/svdtrans.cxx
index ad44aa230e17..04b02e9184c6 100644
--- a/svx/source/svdraw/svdtrans.cxx
+++ b/svx/source/svdraw/svdtrans.cxx
@@ -61,6 +61,22 @@ void ResizeRect(tools::Rectangle& rRect, const Point& rRef, 
const Fraction& rxFa
     rRect.Normalize();
 }
 
+namespace svx
+{
+
+void resizeRange(gfx::Range2DLWrap& rRange, gfx::Tuple2DL const& rReference, 
double fFactorX, double fFactorY)
+{
+    auto left = rReference.getX() + ((rRange.getMinX() - rReference.getX()) * 
fFactorX);
+    auto right = rReference.getX() + ((rRange.getMaxX() - rReference.getX()) * 
fFactorX);
+
+    auto top = rReference.getY() + ((rRange.getMinY() - rReference.getY()) * 
fFactorY);
+    auto bottom = rReference.getY() + ((rRange.getMaxY() - rReference.getY()) 
* fFactorY);
+
+    rRange = gfx::Range2DLWrap(left, top, right, bottom, rRange.getUnit());
+}
+
+} // end svx namespace
+
 
 void ResizePoly(tools::Polygon& rPoly, const Point& rRef, const Fraction& 
xFact, const Fraction& yFact)
 {
commit f2b0424936cd69fe272e43294691efb1fa235b9e
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Thu Feb 9 10:03:43 2023 +0900
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Sun Mar 5 14:54:14 2023 +0900

    use Range2DLWrap for the main rectangle in SdrTextObject
    
    Change-Id: I0d8ac090f9442fe561b4f87aa767185a987874c4

diff --git a/include/svx/svdotext.hxx b/include/svx/svdotext.hxx
index a1cccb0804a4..4861eb3bf5ce 100644
--- a/include/svx/svdotext.hxx
+++ b/include/svx/svdotext.hxx
@@ -28,6 +28,7 @@
 #include <tools/datetime.hxx>
 #include <svl/style.hxx>
 #include <svx/svdtext.hxx>
+#include <svx/svdmodel.hxx>
 #include <svx/svxdllapi.h>
 #include <drawinglayer/primitive2d/Primitive2DContainer.hxx>
 #include <memory>
@@ -165,31 +166,44 @@ protected:
     // The "aRect" is also the rect of RectObj and CircObj.
     // When mbTextFrame=true the text will be formatted into this rect
     // When mbTextFrame=false the text will be centered around its middle
-    tools::Rectangle maRectangle;
+    gfx::Range2DLWrap maRectangleRange;
 
     tools::Rectangle const& getRectangle() const
     {
-        return maRectangle;
+        return maRectangleRange.toToolsRect();
     }
 
     void setRectangle(tools::Rectangle const& rRectangle)
     {
-        maRectangle = rRectangle;
+        auto eUnit = getSdrModelFromSdrObject().getUnit();
+        maRectangleRange = gfx::Range2DLWrap::create(rRectangle, eUnit);
     }
 
     void setRectangleSize(sal_Int32 nWidth, sal_Int32 nHeight)
     {
-        maRectangle.SetSize(Size(nWidth, nHeight));
+        auto eUnit = getSdrModelFromSdrObject().getUnit();
+        auto width = gfx::Length::from(eUnit, nWidth);
+        auto height = gfx::Length::from(eUnit, nHeight);
+        maRectangleRange.setSize(width, height);
     }
 
     void moveRectangle(sal_Int32 nXDelta, sal_Int32 nYDelta)
     {
-        maRectangle.Move(nXDelta, nYDelta);
+        if (nXDelta == 0 && nYDelta == 0)
+            return;
+
+        auto eUnit = getSdrModelFromSdrObject().getUnit();
+        auto xDelta = gfx::Length::from(eUnit, nXDelta);
+        auto yDelta = gfx::Length::from(eUnit, nYDelta);
+        maRectangleRange.shift(xDelta, yDelta);
     }
 
     void moveRectanglePosition(sal_Int32 nX, sal_Int32 nY)
     {
-        maRectangle.SetPos(Point(nX, nY));
+        auto eUnit = getSdrModelFromSdrObject().getUnit();
+        auto x = gfx::Length::from(eUnit, nX);
+        auto y = gfx::Length::from(eUnit, nY);
+        maRectangleRange.setPosition(x, y);
     }
 
     // The GeoStat contains the rotation and shear angles
diff --git a/svx/source/svdraw/svdocirc.cxx b/svx/source/svdraw/svdocirc.cxx
index ab8bc58ddf85..020551bcdf5e 100644
--- a/svx/source/svdraw/svdocirc.cxx
+++ b/svx/source/svdraw/svdocirc.cxx
@@ -706,8 +706,9 @@ bool SdrCircObj::MovCreate(SdrDragStat& rStat)
     ImpSetCreateParams(rStat);
     ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
     rStat.SetActionRect(pU->aR);
-    setRectangle(pU->aR); // for ObjName
-    ImpJustifyRect(maRectangle);
+    auto aRectangle = pU->aR;
+    ImpJustifyRect(aRectangle);
+    setRectangle(aRectangle); // for ObjName
     nStartAngle=pU->nStart;
     nEndAngle=pU->nEnd;
     SetBoundRectDirty();
@@ -1048,8 +1049,9 @@ void SdrCircObj::NbcSetSnapRect(const tools::Rectangle& 
rRect)
         
NbcResize(maSnapRect.TopLeft(),Fraction(nWdt1,nWdt0),Fraction(nHgt1,nHgt0));
         NbcMove(Size(rRect.Left()-aSR0.Left(),rRect.Top()-aSR0.Top()));
     } else {
-        setRectangle(rRect);
-        ImpJustifyRect(maRectangle);
+        tools::Rectangle aRectangle(rRect);
+        ImpJustifyRect(aRectangle);
+        setRectangle(aRectangle);
     }
     SetBoundAndSnapRectsDirty();
     SetXPolyDirty();
diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx
index 20e54ca976ac..7b33092dfc48 100644
--- a/svx/source/svdraw/svdotext.cxx
+++ b/svx/source/svdraw/svdotext.cxx
@@ -101,7 +101,7 @@ SdrTextObj::SdrTextObj(SdrModel& rSdrModel, SdrTextObj 
const & rSource)
     // #i25616#
     mbSupportTextIndentingOnLineWidthChange = true;
 
-    maRectangle = rSource.maRectangle;
+    maRectangleRange = rSource.maRectangleRange;
     maGeo = rSource.maGeo;
     maTextSize = rSource.maTextSize;
 
@@ -201,8 +201,6 @@ SdrTextObj::~SdrTextObj()
 
 void SdrTextObj::FitFrameToTextSize()
 {
-    ImpJustifyRect(maRectangle);
-
     SdrText* pText = getActiveText();
     if(pText==nullptr || !pText->GetOutlinerParaObject())
         return;
diff --git a/svx/source/svdraw/svdotxtr.cxx b/svx/source/svdraw/svdotxtr.cxx
index 1454bc52f946..f2df68068717 100644
--- a/svx/source/svdraw/svdotxtr.cxx
+++ b/svx/source/svdraw/svdotxtr.cxx
@@ -56,9 +56,9 @@ void SdrTextObj::NbcSetSnapRect(const tools::Rectangle& rRect)
     else
     {
         // No rotation or shear.
-
-        setRectangle(rRect);
-        ImpJustifyRect(maRectangle);
+        tools::Rectangle aRectangle(rRect);
+        ImpJustifyRect(aRectangle);
+        setRectangle(aRectangle);
 
         AdaptTextMinSize();
 
@@ -74,8 +74,9 @@ const tools::Rectangle& SdrTextObj::GetLogicRect() const
 
 void SdrTextObj::NbcSetLogicRect(const tools::Rectangle& rRect)
 {
-    setRectangle(rRect);
-    ImpJustifyRect(maRectangle);
+    tools::Rectangle aRectangle(rRect);
+    ImpJustifyRect(aRectangle);
+    setRectangle(aRectangle);
 
     AdaptTextMinSize();
 
@@ -126,7 +127,7 @@ void SdrTextObj::NbcResize(const Point& rRef, const 
Fraction& xFact, const Fract
         setRectangle(aRectangle);
         if (bYMirr)
         {
-            maRectangle.Normalize();
+            //maRectangle.Normalize();
             moveRectangle(aRectangle.Right() - aRectangle.Left(), 
aRectangle.Bottom() - aRectangle.Top());
             maGeo.nRotationAngle=18000_deg100;
             maGeo.RecalcSinCos();
@@ -174,8 +175,6 @@ void SdrTextObj::NbcResize(const Point& rRef, const 
Fraction& xFact, const Fract
         }
     }
 
-    ImpJustifyRect(maRectangle);
-
     AdaptTextMinSize();
 
     if(mbTextFrame && !getSdrModelFromSdrObject().IsPasteResize())
@@ -190,12 +189,13 @@ void SdrTextObj::NbcResize(const Point& rRef, const 
Fraction& xFact, const Fract
 void SdrTextObj::NbcRotate(const Point& rRef, Degree100 nAngle, double sn, 
double cs)
 {
     SetGlueReallyAbsolute(true);
-    tools::Long dx = getRectangle().Right() - getRectangle().Left();
-    tools::Long dy = getRectangle().Bottom() - getRectangle().Top();
-    Point aPoint1(getRectangle().TopLeft());
+    tools::Rectangle aRectangle = getRectangle();
+    tools::Long dx = aRectangle.Right() - aRectangle.Left();
+    tools::Long dy = aRectangle.Bottom() - aRectangle.Top();
+    Point aPoint1(aRectangle.TopLeft());
     RotatePoint(aPoint1, rRef, sn, cs);
     Point aPoint2(aPoint1.X() + dx, aPoint1.Y() + dy);
-    tools::Rectangle aRectangle(aPoint1, aPoint2);
+    aRectangle = tools::Rectangle(aPoint1, aPoint2);
     setRectangle(aRectangle);
 
     if (maGeo.nRotationAngle==0_deg100) {
@@ -215,16 +215,17 @@ void SdrTextObj::NbcShear(const Point& rRef, Degree100 
/*nAngle*/, double tn, bo
 {
     SetGlueReallyAbsolute(true);
 
+    auto aRectangle = getRectangle();
     // when this is a SdrPathObj, aRect may be uninitialized
-    tools::Polygon aPol(Rect2Poly(getRectangle().IsEmpty() ? GetSnapRect() : 
getRectangle(), maGeo));
+    tools::Polygon aPol(Rect2Poly(aRectangle.IsEmpty() ? GetSnapRect() : 
aRectangle, maGeo));
 
     sal_uInt16 nPointCount=aPol.GetSize();
     for (sal_uInt16 i=0; i<nPointCount; i++) {
          ShearPoint(aPol[i],rRef,tn,bVShear);
     }
-    tools::Rectangle aRectangle = svx::polygonToRectangle(aPol, maGeo);
+    aRectangle = svx::polygonToRectangle(aPol, maGeo);
+    ImpJustifyRect(aRectangle);
     setRectangle(aRectangle);
-    ImpJustifyRect(maRectangle);
 
     if (mbTextFrame) {
         NbcAdjustTextFrameWidthAndHeight();
@@ -245,7 +246,7 @@ void SdrTextObj::NbcMirror(const Point& rRef1, const Point& 
rRef2)
          std::abs(rRef1.X()-rRef2.X())==std::abs(rRef1.Y()-rRef2.Y()))) {
         bRotate90=maGeo.nRotationAngle.get() % 9000 ==0;
     }
-    tools::Polygon aPol(Rect2Poly(getRectangle(),maGeo));
+    tools::Polygon aPol(Rect2Poly(getRectangle(), maGeo));
     sal_uInt16 i;
     sal_uInt16 nPointCount=aPol.GetSize();
     for (i=0; i<nPointCount; i++) {
@@ -279,7 +280,6 @@ void SdrTextObj::NbcMirror(const Point& rRef1, const Point& 
rRef2)
         maGeo.RecalcTan();
     }
 
-    ImpJustifyRect(maRectangle);
     if (mbTextFrame) {
         NbcAdjustTextFrameWidthAndHeight();
     }
diff --git a/svx/source/table/svdotable.cxx b/svx/source/table/svdotable.cxx
index 25ab8715d307..b927bfbd2ebe 100644
--- a/svx/source/table/svdotable.cxx
+++ b/svx/source/table/svdotable.cxx
@@ -842,7 +842,7 @@ SdrTableObj::SdrTableObj(SdrModel& rSdrModel, SdrTableObj 
const & rSource)
     TableModelNotifyGuard aGuard( mpImpl.is() ? mpImpl->mxTable.get() : 
nullptr );
 
     maLogicRect = rSource.maLogicRect;
-    maRectangle = rSource.maRectangle;
+    maRectangleRange = rSource.maRectangleRange;
     maGeo = rSource.maGeo;
     meTextKind = rSource.meTextKind;
     mbTextFrame = rSource.mbTextFrame;

Reply via email to