basegfx/test/LengthUnitTest.cxx      |  131 +++++++++++++++++++++++++----------
 include/basegfx/units/LengthBase.hxx |   10 +-
 include/svx/svdobj.hxx               |    4 -
 include/svx/svdopage.hxx             |    2 
 include/svx/svdtrans.hxx             |    9 ++
 svx/qa/unit/svdraw.cxx               |   69 +++++++++++++++++-
 svx/source/svdraw/svdobj.cxx         |   78 +++++---------------
 svx/source/svdraw/svdopage.cxx       |    5 +
 svx/source/svdraw/svdtrans.cxx       |   16 ++++
 sw/source/core/draw/dflyobj.cxx      |   16 ++++
 sw/source/core/inc/dflyobj.hxx       |    8 +-
 11 files changed, 244 insertions(+), 104 deletions(-)

New commits:
commit a234d39f227aa328d802d987dcd7bf8bc6cd6361
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Sat Feb 11 22:02:11 2023 +0900
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Sat Feb 11 22:02:11 2023 +0900

    make NbcRotate abstract as it's implementation is noop
    
    During testing the NbcRotate function on SdrObject it turned out
    the the function is essentially a noop, because it uses normal
    equality to test the values of a double, which are a product of
    sin and cos functions (to determine the 90 degree angles). So
    because of this the input rectangle was never modified - noop.
    
    Because of this we can just remove the impl. of the function and
    declare it abstract, so that the actual implementations define
    a valid function to rotate.
    
    There were some subclasses that didn't override the NbcRotate so
    they used the one implementation in SdrObject. These subclasses
    now override the function and in the implementation we call
    assert(false), which is never called during a test run. It seems
    we never rotate those objects.
    
    Change-Id: I1b1a45a8e96ed2d061f9b9f80c5fdaa5a84d4c05

diff --git a/include/svx/svdobj.hxx b/include/svx/svdobj.hxx
index 76645d262a68..7c3cad7443ea 100644
--- a/include/svx/svdobj.hxx
+++ b/include/svx/svdobj.hxx
@@ -544,7 +544,7 @@ public:
     virtual void NbcMove  (const Size& rSiz);
     virtual void NbcResize(const Point& rRef, const Fraction& xFact, const 
Fraction& yFact);
     virtual void NbcCrop  (const basegfx::B2DPoint& rRef, double fxFact, 
double fyFact);
-    virtual void NbcRotate(const Point& rRef, Degree100 nAngle, double sn, 
double cs);
+    virtual void NbcRotate(const Point& rRef, Degree100 nAngle, double sn, 
double cs) = 0;
     // Utility for call sites that don't have sin and cos handy
     void NbcRotate(const Point& rRef, Degree100 nAngle);
     virtual void NbcMirror(const Point& rRef1, const Point& rRef2);
diff --git a/include/svx/svdopage.hxx b/include/svx/svdopage.hxx
index abb35d8239cd..279c75c758a6 100644
--- a/include/svx/svdopage.hxx
+++ b/include/svx/svdopage.hxx
@@ -64,6 +64,8 @@ public:
 
     virtual OUString TakeObjNameSingul() const override;
     virtual OUString TakeObjNamePlural() const override;
+
+    void NbcRotate(const Point& rRef, Degree100 nAngle, double sinAngle, 
double cosAngle) override;
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx
index 555e77a11963..3f33e41f7cba 100644
--- a/svx/source/svdraw/svdobj.cxx
+++ b/svx/source/svdraw/svdobj.cxx
@@ -1444,33 +1444,6 @@ void SdrObject::NbcRotate(const Point& rRef, Degree100 
nAngle)
 
 namespace
 {
-
-tools::Rectangle lclRotateRectangle(tools::Rectangle const& rRectangle, Point 
const& rRef, double sn, double cs)
-{
-    tools::Rectangle aRectangle(rRectangle);
-    aRectangle.Move(-rRef.X(),-rRef.Y());
-    tools::Rectangle R(aRectangle);
-    if (sn==1.0 && cs==0.0) { // 90deg
-        aRectangle.SetLeft(-R.Bottom() );
-        aRectangle.SetRight(-R.Top() );
-        aRectangle.SetTop(R.Left() );
-        aRectangle.SetBottom(R.Right() );
-    } else if (sn==0.0 && cs==-1.0) { // 180deg
-        aRectangle.SetLeft(-R.Right() );
-        aRectangle.SetRight(-R.Left() );
-        aRectangle.SetTop(-R.Bottom() );
-        aRectangle.SetBottom(-R.Top() );
-    } else if (sn==-1.0 && cs==0.0) { // 270deg
-        aRectangle.SetLeft(R.Top() );
-        aRectangle.SetRight(R.Bottom() );
-        aRectangle.SetTop(-R.Right() );
-        aRectangle.SetBottom(-R.Left() );
-    }
-    aRectangle.Move(rRef.X(),rRef.Y());
-    aRectangle.Normalize(); // just in case
-    return aRectangle;
-}
-
 tools::Rectangle lclMirrorRectangle(tools::Rectangle const& rRectangle, Point 
const& rRef1, Point const& rRef2)
 {
     tools::Rectangle aRectangle(rRectangle);
@@ -1502,17 +1475,6 @@ tools::Rectangle lclMirrorRectangle(tools::Rectangle 
const& rRectangle, Point co
 
 } // end anonymous namespace
 
-void SdrObject::NbcRotate(const Point& rRef,  Degree100 nAngle, double sn, 
double cs)
-{
-    SetGlueReallyAbsolute(true);
-    tools::Rectangle aRectangle = getOutRectangle();
-    aRectangle = lclRotateRectangle(aRectangle, rRef, sn, cs);
-    setOutRectangle(aRectangle);
-    SetBoundAndSnapRectsDirty();
-    NbcRotateGluePoints(rRef, nAngle, sn, cs);
-    SetGlueReallyAbsolute(false);
-}
-
 void SdrObject::NbcMirror(const Point& rRef1, const Point& rRef2)
 {
     SetGlueReallyAbsolute(true);
diff --git a/svx/source/svdraw/svdopage.cxx b/svx/source/svdraw/svdopage.cxx
index 8bd374fe6b45..448758646afe 100644
--- a/svx/source/svdraw/svdopage.cxx
+++ b/svx/source/svdraw/svdopage.cxx
@@ -172,4 +172,9 @@ OUString SdrPageObj::TakeObjNamePlural() const
     return SvxResId(STR_ObjNamePluralPAGE);
 }
 
+void SdrPageObj::NbcRotate(const Point& /*rRef*/, Degree100 /*nAngle*/, double 
/*sinAngle*/, double /*cosAngle*/)
+{
+    assert(false);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/draw/dflyobj.cxx b/sw/source/core/draw/dflyobj.cxx
index 45068cf1fd89..31a193a45119 100644
--- a/sw/source/core/draw/dflyobj.cxx
+++ b/sw/source/core/draw/dflyobj.cxx
@@ -156,6 +156,11 @@ rtl::Reference<SdrObject> 
SwFlyDrawObj::CloneSdrObject(SdrModel& rTargetModel) c
     return new SwFlyDrawObj(rTargetModel);
 }
 
+void SwFlyDrawObj::NbcRotate(const Point& /*rRef*/, Degree100 /*nAngle*/, 
double /*sinAngle*/, double /*cosAngle*/)
+{
+    assert(false);
+}
+
 // TODO: Need own primitive to get the FlyFrame paint working
 namespace drawinglayer::primitive2d
 {
diff --git a/sw/source/core/inc/dflyobj.hxx b/sw/source/core/inc/dflyobj.hxx
index a75499c9ee6a..809f2a542236 100644
--- a/sw/source/core/inc/dflyobj.hxx
+++ b/sw/source/core/inc/dflyobj.hxx
@@ -53,6 +53,8 @@ public:
     virtual SdrObjKind GetObjIdentifier()   const override;
     virtual bool IsTextBox() const override { return mbIsTextBox; }
     void SetTextBox(bool bIsTextBox) { mbIsTextBox = bIsTextBox; }
+
+    virtual void NbcRotate(const Point& rRef, Degree100 nAngle, double 
sinAnle, double cosAngle) override;
 };
 
 // virtual objects for Flys
@@ -121,6 +123,7 @@ public:
     virtual       void       addCropHandles(SdrHdlList& rTarget) const 
override;
     virtual       void       Rotate(const Point& rRef, Degree100 nAngle, 
double sn, double cs) override;
 
+
     // FullDrag support
     virtual rtl::Reference<SdrObject> getFullDragClone() const override;
 
commit 3a03131df857d4e063c2579cb01b51529cafe32c
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Sat Feb 11 17:08:54 2023 +0900
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Sat Feb 11 17:08:54 2023 +0900

    svx: make SdrObject abstract by making CloneSdrObject pure virtual
    
    This change makes SdrObject an abstract class that can't be as
    we don't want it to be instantiated. With this the ClonseSdrObject
    became a pure virtual function.
    
    With this change also the SwFlyDrawObj needs a implementation of
    the CloneSdrFunction, which was previously provided by SdrObject.
    
    Change-Id: I2efb8c1e6fac12b17ce497285067029d7da1c1fd

diff --git a/include/svx/svdobj.hxx b/include/svx/svdobj.hxx
index 2d16d1ad33e7..76645d262a68 100644
--- a/include/svx/svdobj.hxx
+++ b/include/svx/svdobj.hxx
@@ -444,7 +444,7 @@ public:
     virtual bool HasLimitedRotation() const;
 
     // Returns a copy of the object. Every inherited class must reimplement 
this.
-    virtual rtl::Reference<SdrObject> CloneSdrObject(SdrModel& rTargetModel) 
const;
+    virtual rtl::Reference<SdrObject> CloneSdrObject(SdrModel& rTargetModel) 
const = 0;
     // helper, since Clone always return the type of the current subclass
     template<class T>
     static rtl::Reference<T> Clone(T const & rObj, SdrModel& rTargetModel)
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx
index 2120866eddbb..555e77a11963 100644
--- a/svx/source/svdraw/svdobj.cxx
+++ b/svx/source/svdraw/svdobj.cxx
@@ -1043,11 +1043,6 @@ bool SdrObject::HasLimitedRotation() const
     return false;
 }
 
-rtl::Reference<SdrObject> SdrObject::CloneSdrObject(SdrModel& rTargetModel) 
const
-{
-    return new SdrObject(rTargetModel, *this);
-}
-
 OUString SdrObject::TakeObjNameSingul() const
 {
     OUString sName(SvxResId(STR_ObjNameSingulNONE));
@@ -3348,7 +3343,7 @@ rtl::Reference<SdrObject> SdrObjFactory::MakeNewObject(
                 }
             }
             break;
-            case SdrObjKind::NONE       : pObj=new SdrObject(rSdrModel);       
            break;
+            case SdrObjKind::NONE       : pObj = nullptr; break;
             case SdrObjKind::Group       : pObj=new SdrObjGroup(rSdrModel);    
             break;
             case SdrObjKind::Polygon       : pObj=new SdrPathObj(rSdrModel, 
SdrObjKind::Polygon       ); break;
             case SdrObjKind::PolyLine       : pObj=new SdrPathObj(rSdrModel, 
SdrObjKind::PolyLine       ); break;
diff --git a/sw/source/core/draw/dflyobj.cxx b/sw/source/core/draw/dflyobj.cxx
index 3095d5a2a6f4..45068cf1fd89 100644
--- a/sw/source/core/draw/dflyobj.cxx
+++ b/sw/source/core/draw/dflyobj.cxx
@@ -130,6 +130,12 @@ SwFlyDrawObj::SwFlyDrawObj(SdrModel& rSdrModel)
 {
 }
 
+SwFlyDrawObj::SwFlyDrawObj(SdrModel& rSdrModel, SwFlyDrawObj const& rSource)
+    : SdrObject(rSdrModel, rSource)
+    , mbIsTextBox(false)
+{
+}
+
 SwFlyDrawObj::~SwFlyDrawObj()
 {
 }
@@ -145,6 +151,11 @@ SdrObjKind SwFlyDrawObj::GetObjIdentifier() const
     return SdrObjKind::SwFlyDrawObjIdentifier;
 }
 
+rtl::Reference<SdrObject> SwFlyDrawObj::CloneSdrObject(SdrModel& rTargetModel) 
const
+{
+    return new SwFlyDrawObj(rTargetModel);
+}
+
 // TODO: Need own primitive to get the FlyFrame paint working
 namespace drawinglayer::primitive2d
 {
diff --git a/sw/source/core/inc/dflyobj.hxx b/sw/source/core/inc/dflyobj.hxx
index db853d2262b2..a75499c9ee6a 100644
--- a/sw/source/core/inc/dflyobj.hxx
+++ b/sw/source/core/inc/dflyobj.hxx
@@ -44,8 +44,11 @@ private:
 
 public:
     SwFlyDrawObj(SdrModel& rSdrModel);
+    SwFlyDrawObj(SdrModel& rSdrModel, SwFlyDrawObj const& rSource);
+
+    // for instantiation of this class while loading (via factory
+    virtual rtl::Reference<SdrObject> CloneSdrObject(SdrModel& rTargetModel) 
const;
 
-    // for instantiation of this class while loading (via factory)
     virtual SdrInventor GetObjInventor()     const override;
     virtual SdrObjKind GetObjIdentifier()   const override;
     virtual bool IsTextBox() const override { return mbIsTextBox; }
commit 60f7be43a726ed9331af3926a96cdfdc5b3c7679
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: Fri Feb 10 18:19:14 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 c491dddb00a1..6a40dca7a081 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>
@@ -24,6 +24,7 @@
 #include <svx/sdr/contact/displayinfo.hxx>
 #include <svx/sdr/contact/viewcontact.hxx>
 #include <svx/sdr/contact/viewobjectcontact.hxx>
+#include <svx/svdtrans.hxx>
 #include <svx/svdorect.hxx>
 #include <svx/unopage.hxx>
 #include <svx/svdview.hxx>
@@ -37,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
 {
@@ -549,6 +550,68 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testPageViewDrawLayerClip)
     // i.e. the 2nd page had a line shape from the first page's footer.
     CPPUNIT_ASSERT_EQUAL(2, pPage2->getObjectCount());
 }
+
+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 f8ef26561a71..2120866eddbb 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
@@ -1409,24 +1408,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 28ccfb0730f7d673930eac06a2b8c9a91095e35c
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Fri Feb 10 00:28:22 2023 +0900
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Fri Feb 10 00:28:22 2023 +0900

    update length
    
    Change-Id: I0025f13c55382ab7d6b543c871db1b3f7bbaacf2

diff --git a/basegfx/test/LengthUnitTest.cxx b/basegfx/test/LengthUnitTest.cxx
index 2f597f0274d2..02da22fc17f5 100644
--- a/basegfx/test/LengthUnitTest.cxx
+++ b/basegfx/test/LengthUnitTest.cxx
@@ -18,25 +18,49 @@
 class LengthTest : public CppUnit::TestFixture
 {
 public:
-    void testBasic()
+    void testCreation()
     {
-        gfx::Length cm = 1_cm + 5_cm - 2_cm;
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0, cm.as_cm(), 1e-4);
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(0.04, cm.as_meter(), 1e-4);
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(40.0, cm.as_mm(), 1e-4);
-        CPPUNIT_ASSERT_EQUAL(sal_Int64(1440000), cm.raw());
+        //  Creation from integer number
+        int number = 10;
+        auto asCm = gfx::Length::cm(number);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(10.0, asCm.as_cm(), 1e-4);
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(3600000), asCm.raw());
 
-        gfx::Length cm2 = 5_cm * 2;
-        CPPUNIT_ASSERT_EQUAL(sal_Int64(3600000), cm2.raw());
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(10.0, cm2.as_cm(), 1e-4);
+        auto asMm = gfx::Length::mm(number);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(10.0, asMm.as_mm(), 1e-4);
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(360000), asMm.raw());
 
-        // 1 km - 50 m = 950 m = 95000 cm
-        gfx::Length cm3 = 100000_cm - 5000_cm;
-        CPPUNIT_ASSERT_EQUAL(sal_Int64(34200000000), cm3.raw());
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(95000.0, cm3.as_cm(), 1e-4);
+        auto asInch = gfx::Length::in(number);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(10.0, asInch.as_in(), 1e-4);
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(9144000), asInch.raw());
 
-        gfx::Length cm4 = -100_cm - 10_cm;
-        CPPUNIT_ASSERT_EQUAL(sal_Int64(-39600000), cm4.raw());
+        auto forceInteger = gfx::Length::hmm<sal_Int64>(10.1);
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(3600), forceInteger.raw());
+
+        auto forceDouble = gfx::Length::hmm<double>(10.1);
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(3636), forceDouble.raw());
+    }
+
+    void testUnitConversion()
+    {
+        // Big values
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(34200000000), (950_m).raw());
+        CPPUNIT_ASSERT_EQUAL(95000_cm, 950_m);
+        CPPUNIT_ASSERT_EQUAL(950000_mm, 950_m);
+        CPPUNIT_ASSERT_EQUAL(95000000_hmm, 950_m);
+        CPPUNIT_ASSERT_EQUAL(34200000000_emu, 950_m);
+
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(-34200000000), (-950_m).raw());
+        CPPUNIT_ASSERT_EQUAL(-95000_cm, -950_m);
+        CPPUNIT_ASSERT_EQUAL(-950000_mm, -950_m);
+        CPPUNIT_ASSERT_EQUAL(-95000000_hmm, -950_m);
+        CPPUNIT_ASSERT_EQUAL(-34200000000_emu, -950_m);
+
+        // To double value in chosen unit
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(4.0, (4_cm).as_cm(), 1e-4);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(0.04, (4_cm).as_meter(), 1e-4);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(40.0, (4_cm).as_mm(), 1e-4);
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(1440000), (4_cm).raw());
 
         // (635 * 20) + 3 * (635 * 15) = 41275EMU
         gfx::Length pt = 1_pt + 3_px;
@@ -51,13 +75,10 @@ public:
         CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, inch.as_in(), 1e-4);
         CPPUNIT_ASSERT_DOUBLES_EQUAL(914400.0, inch.as_emu(), 1e-4);
         CPPUNIT_ASSERT_EQUAL(sal_Int64(914400), inch.raw());
+    }
 
-        // Conversion
-        sal_Int64 asNumber(17_pt);
-        asNumber += sal_Int64(1_pt);
-        gfx::Length asLength = gfx::Length::emu(asNumber);
-        CPPUNIT_ASSERT_EQUAL(sal_Int64(18 * 635 * 20), asLength.raw());
-
+    void testLimits()
+    {
         gfx::Length maximum = gfx::Length::emu(SAL_MAX_INT64);
         CPPUNIT_ASSERT_DOUBLES_EQUAL(256204778801.5, maximum.as_meter(), 1e-1);
         // 256204778 km
@@ -67,30 +88,62 @@ public:
         CPPUNIT_ASSERT_DOUBLES_EQUAL(-256204778801.5, minimum.as_meter(), 
1e-1);
         CPPUNIT_ASSERT_DOUBLES_EQUAL(double(SAL_MIN_INT64), minimum.as_emu(), 
1e-1);
         CPPUNIT_ASSERT_EQUAL(sal_Int64(SAL_MIN_INT64), minimum.raw());
+    }
+
+    void testAdditionAndSubstitution()
+    {
+        // results in zero
+        CPPUNIT_ASSERT_EQUAL(0_cm, 100_cm - 100_cm);
+        CPPUNIT_ASSERT_EQUAL(0_cm, -100_cm + 100_cm);
+
+        // + and - with zero
+        CPPUNIT_ASSERT_EQUAL(10_cm, 10_cm + 0_cm);
+        CPPUNIT_ASSERT_EQUAL(10_cm, 10_cm - 0_cm);
+        CPPUNIT_ASSERT_EQUAL(10_cm, 10_cm - 0_cm + 0_emu - 0_twip);
+
+        // common
+        CPPUNIT_ASSERT_EQUAL(6_cm, 1_cm + 5_cm);
+        CPPUNIT_ASSERT_EQUAL(-4_cm, 1_cm - 5_cm);
+        CPPUNIT_ASSERT_EQUAL(4_cm, -1_cm + 5_cm);
+        CPPUNIT_ASSERT_EQUAL(-6_cm, -1_cm - 5_cm);
+
+        // long chain
+        CPPUNIT_ASSERT_EQUAL(35129_hmm, 1_mm - 5_cm + 40_cm - 1_hmm + 30_hmm);
+
+        // floating point
+        CPPUNIT_ASSERT_EQUAL(1_mm, 0.5_mm + 0.5_mm);
+
+        // mixed units
+        CPPUNIT_ASSERT_EQUAL(180_emu + 635_emu, 0.5_hmm + 1_twip);
+        CPPUNIT_ASSERT_EQUAL(554400_emu, 1_in - 1_cm);
+
+        // Big values - 1km - 50m
+        CPPUNIT_ASSERT_EQUAL(95000_cm, 1000_m - 5000_cm);
 
         // 27 emu + 33 emu + 360 emu = 420
         gfx::Length emus = 27_emu + 33_emu + 1_hmm;
         CPPUNIT_ASSERT_EQUAL(sal_Int64(420), emus.raw());
+    }
 
-        //  Creation from number
-        int number = 10;
-        auto asCm = gfx::Length::cm(number);
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(10.0, asCm.as_cm(), 1e-4);
-        CPPUNIT_ASSERT_EQUAL(sal_Int64(3600000), asCm.raw());
+    void testMultiplication()
+    {
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(0), (1_hmm * 0).raw());
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(720), (1_hmm * 2).raw());
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(-720), (1_hmm * -2).raw());
 
-        auto asMm = gfx::Length::mm(number);
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(10.0, asMm.as_mm(), 1e-4);
-        CPPUNIT_ASSERT_EQUAL(sal_Int64(360000), asMm.raw());
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(0), (1_hmm * 0.0).raw());
 
-        auto asInch = gfx::Length::in(number);
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(10.0, asInch.as_in(), 1e-4);
-        CPPUNIT_ASSERT_EQUAL(sal_Int64(9144000), asInch.raw());
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(720), (1_hmm * 2.0).raw());
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(-720), (1_hmm * -2.0).raw());
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(-720), (-1_hmm * 2.0).raw());
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(720), (-1_hmm * -2.0).raw());
 
-        auto aa = gfx::Length::hmm<sal_Int64>(10.1);
-        CPPUNIT_ASSERT_EQUAL(sal_Int64(3600), aa.raw());
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(180), (1_hmm * 0.5).raw());
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(-180), (-1_hmm * 0.5).raw());
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(-180), (1_hmm * -0.5).raw());
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(180), (-1_hmm * -0.5).raw());
 
-        auto bb = gfx::Length::hmm<double>(10.1);
-        CPPUNIT_ASSERT_EQUAL(sal_Int64(3636), bb.raw());
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(90), (0.5_hmm * 0.5).raw());
     }
 
     void testDivision()
@@ -308,7 +361,11 @@ public:
     }
 
     CPPUNIT_TEST_SUITE(LengthTest);
-    CPPUNIT_TEST(testBasic);
+    CPPUNIT_TEST(testCreation);
+    CPPUNIT_TEST(testUnitConversion);
+    CPPUNIT_TEST(testLimits);
+    CPPUNIT_TEST(testAdditionAndSubstitution);
+    CPPUNIT_TEST(testMultiplication);
     CPPUNIT_TEST(testDivision);
     CPPUNIT_TEST(testGenericFrom);
     CPPUNIT_TEST(testGenericAs);
diff --git a/include/basegfx/units/LengthBase.hxx 
b/include/basegfx/units/LengthBase.hxx
index 8768d4abd8f9..7f9f48026820 100644
--- a/include/basegfx/units/LengthBase.hxx
+++ b/include/basegfx/units/LengthBase.hxx
@@ -160,13 +160,13 @@ public:
         return *this;
     }
 
-    constexpr LengthBase& operator*=(TYPE const& rhs)
+    template <typename INPUT> constexpr LengthBase& operator*=(INPUT const& 
rhs)
     {
         m_nValue *= rhs;
         return *this;
     }
 
-    constexpr LengthBase& operator/=(TYPE const& rhs)
+    template <typename INPUT> constexpr LengthBase& operator/=(INPUT const& 
rhs)
     {
         m_nValue /= rhs;
         return *this;
@@ -238,14 +238,16 @@ template <typename T> inline LengthBase<T> 
operator-(LengthBase<T> lhs, const Le
 
 /// Multiplication of a length unit with a scalar value.
 /// example 1cm * 2 = 2cm
-template <typename T> inline LengthBase<T> operator*(LengthBase<T> lhs, const 
long rhs)
+template <typename T, typename INPUT_TYPE>
+inline LengthBase<T> operator*(LengthBase<T> lhs, const INPUT_TYPE rhs)
 {
     return lhs *= rhs;
 }
 
 /// Division of a length unit with a scalar value.
 /// example 1cm / 2 = 0.5cm
-template <typename T> inline LengthBase<T> operator/(LengthBase<T> lhs, const 
long rhs)
+template <typename T, typename INPUT_TYPE>
+inline LengthBase<T> operator/(LengthBase<T> lhs, const INPUT_TYPE rhs)
 {
     return lhs /= rhs;
 }

Reply via email to