basegfx/test/LengthUnitTest.cxx          |  151 +++++++++++++-----
 include/basegfx/units/Length.hxx         |   77 +--------
 include/basegfx/units/LengthBase.hxx     |  248 +++++++++++++++++++++++++++++++
 include/basegfx/units/LengthTypes.hxx    |  121 +++++++++++++++
 include/basegfx/units/LengthUnitBase.hxx |  197 ------------------------
 5 files changed, 489 insertions(+), 305 deletions(-)

New commits:
commit dab4c34e848f65b06065b5f3f3a3f4051d6e9004
Author:     Tomaž Vajngerl <[email protected]>
AuthorDate: Tue Jan 31 23:40:26 2023 +0900
Commit:     Tomaž Vajngerl <[email protected]>
CommitDate: Wed Feb 1 11:50:45 2023 +0900

    extend Length class
    
    Change-Id: Idd2e17744c6305d8663cb29088150061be6d48c4

diff --git a/basegfx/test/LengthUnitTest.cxx b/basegfx/test/LengthUnitTest.cxx
index b7b072493573..7c4df24fe77c 100644
--- a/basegfx/test/LengthUnitTest.cxx
+++ b/basegfx/test/LengthUnitTest.cxx
@@ -19,7 +19,7 @@ public:
     {
         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_m(), 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());
 
@@ -53,12 +53,12 @@ public:
         CPPUNIT_ASSERT_EQUAL(sal_Int64(18 * 635 * 20), asLength.raw());
 
         gfx::Length maximum = gfx::Length::emu(SAL_MAX_INT64);
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(256204778801.5, maximum.as_m(), 1e-1);
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(256204778801.5, maximum.as_meter(), 1e-1);
         // 256204778 km
         CPPUNIT_ASSERT_EQUAL(sal_Int64(SAL_MAX_INT64), maximum.raw());
 
         gfx::Length minimum = gfx::Length::emu(SAL_MIN_INT64);
-        CPPUNIT_ASSERT_DOUBLES_EQUAL(-256204778801.5, minimum.as_m(), 1e-1);
+        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());
 
@@ -104,34 +104,21 @@ public:
         CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5, aRatio, 1e-9);
     }
 
-    void testInRange()
+    void testGenericFrom()
     {
-        gfx::Range2DL aRange(1_cm, 2_cm, 2_cm, 30_mm);
-        CPPUNIT_ASSERT_EQUAL(1_cm, aRange.getMinX());
-        CPPUNIT_ASSERT_EQUAL(2_cm, aRange.getMaxX());
-        CPPUNIT_ASSERT_EQUAL(2_cm, aRange.getMinY());
-        CPPUNIT_ASSERT_EQUAL(3_cm, aRange.getMaxY());
+        auto hmm1 = gfx::Length::from(gfx::LengthUnit::hmm, 1);
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(360), hmm1.raw());
+        CPPUNIT_ASSERT_EQUAL(gfx::Length::hmm(1), hmm1);
 
-        CPPUNIT_ASSERT_EQUAL(1_cm, aRange.getWidth());
-        CPPUNIT_ASSERT_EQUAL(10_mm, aRange.getHeight());
-
-        aRange.shift(1_cm, 1_cm);
-        CPPUNIT_ASSERT_EQUAL(2_cm, aRange.getMinX());
-        CPPUNIT_ASSERT_EQUAL(3_cm, aRange.getMinY());
-        CPPUNIT_ASSERT_EQUAL(3_cm, aRange.getMaxX());
-        CPPUNIT_ASSERT_EQUAL(40_mm, aRange.getMaxY());
-
-        aRange.setSize(5_cm, 2_cm);
-        CPPUNIT_ASSERT_EQUAL(2_cm, aRange.getMinX());
-        CPPUNIT_ASSERT_EQUAL(3_cm, aRange.getMinY());
-        CPPUNIT_ASSERT_EQUAL(7_cm, aRange.getMaxX());
-        CPPUNIT_ASSERT_EQUAL(5_cm, aRange.getMaxY());
+        auto twip2 = gfx::Length::from(gfx::LengthUnit::twip, 2);
+        CPPUNIT_ASSERT_EQUAL(sal_Int64(1270), twip2.raw());
+        CPPUNIT_ASSERT_EQUAL(gfx::Length::twip(2), twip2);
+    }
 
-        aRange.setPosition(0_cm, 0_cm);
-        CPPUNIT_ASSERT_EQUAL(0_cm, aRange.getMinX());
-        CPPUNIT_ASSERT_EQUAL(0_cm, aRange.getMinY());
-        CPPUNIT_ASSERT_EQUAL(5_cm, aRange.getMaxX());
-        CPPUNIT_ASSERT_EQUAL(2_cm, aRange.getMaxY());
+    void testGenericAs()
+    {
+        CPPUNIT_ASSERT_EQUAL(1.0, (100_hmm).as(gfx::LengthUnit::mm));
+        CPPUNIT_ASSERT_EQUAL(100.0, (1_m).as(gfx::LengthUnit::cm));
     }
 
     void testInTuple()
@@ -173,47 +160,90 @@ public:
         CPPUNIT_ASSERT_EQUAL(true, aSize == aSize - gfx::Size2DL(0_emu, 
0_emu));
         CPPUNIT_ASSERT_EQUAL(true, aSize == aSize + gfx::Size2DL(0_emu, 
0_emu));
     }
+    void testSizeLWrap()
+    {
+        {
+            gfx::Size2DLWrap aSize(0.5_pt, 1_pt);
+            CPPUNIT_ASSERT_EQUAL(6350_emu, aSize.getWidth());
+            CPPUNIT_ASSERT_EQUAL(12700_emu, aSize.getHeight());
+
+            gfx::Size2DLWrap aSize2(0_pt, 0_pt);
+            aSize2.setWidth(0.5_pt);
+            aSize2.setHeight(1_pt);
+
+            CPPUNIT_ASSERT_EQUAL(6350_emu, aSize2.getWidth());
+            CPPUNIT_ASSERT_EQUAL(12700_emu, aSize2.getHeight());
+
+            CPPUNIT_ASSERT_EQUAL(true, aSize == aSize2);
+            CPPUNIT_ASSERT_EQUAL(true, aSize != gfx::Size2DLWrap(0_emu, 
0_emu));
+
+            CPPUNIT_ASSERT_EQUAL(true, aSize == aSize - 
gfx::Size2DLWrap(0_emu, 0_emu));
+            CPPUNIT_ASSERT_EQUAL(true, aSize == aSize + 
gfx::Size2DLWrap(0_emu, 0_emu));
+        }
+        {
+            gfx::Size2DLWrap aSize_Hmm(5_hmm, 8_hmm);
+            Size aBaseSize = aSize_Hmm.toSize();
+            CPPUNIT_ASSERT_EQUAL(tools::Long(5), aBaseSize.Width());
+            CPPUNIT_ASSERT_EQUAL(tools::Long(8), aBaseSize.Height());
+        }
+        {
+            gfx::Size2DLWrap aSize_Twip(5_twip, 8_twip, gfx::LengthUnit::twip);
+            Size aBaseSize = aSize_Twip.toSize();
+            CPPUNIT_ASSERT_EQUAL(tools::Long(5), aBaseSize.Width());
+            CPPUNIT_ASSERT_EQUAL(tools::Long(8), aBaseSize.Height());
+        }
+        {
+            auto aSize = gfx::Size2DLWrap::create(Size(5, 8));
+            CPPUNIT_ASSERT_EQUAL(5_hmm, aSize.getWidth());
+            CPPUNIT_ASSERT_EQUAL(8_hmm, aSize.getHeight());
+        }
+        {
+            auto aSize = gfx::Size2DLWrap::create(Size(5, 8), 
gfx::LengthUnit::twip);
+            CPPUNIT_ASSERT_EQUAL(5_twip, aSize.getWidth());
+            CPPUNIT_ASSERT_EQUAL(8_twip, aSize.getHeight());
+        }
+    }
 
     void testConversionToRectangle()
     {
         {
             tools::Rectangle aEmpty;
-            gfx::Range2DL aEmptyRange = gfx::length::fromRectangleHmm(aEmpty);
+            gfx::Range2DL aEmptyRange = gfx::length::fromRectangle(aEmpty);
             CPPUNIT_ASSERT_EQUAL(true, aEmptyRange.isEmpty());
 
             tools::Rectangle aRectangle(10, 20, 110, 120);
-            gfx::Range2DL aRange = gfx::length::fromRectangleHmm(aRectangle);
+            gfx::Range2DL aRange = gfx::length::fromRectangle(aRectangle);
             CPPUNIT_ASSERT_EQUAL(10_hmm, aRange.getMinX());
             CPPUNIT_ASSERT_EQUAL(20_hmm, aRange.getMinY());
             CPPUNIT_ASSERT_EQUAL(110_hmm, aRange.getMaxX());
             CPPUNIT_ASSERT_EQUAL(120_hmm, aRange.getMaxY());
 
-            tools::Rectangle aRectangleConverted = 
gfx::length::toRectangleHmm(aRange);
+            tools::Rectangle aRectangleConverted = 
gfx::length::toRectangle(aRange);
             CPPUNIT_ASSERT_EQUAL(aRectangle, aRectangleConverted);
         }
         {
             tools::Rectangle aRectangle(10, 20, 110, 120);
-            gfx::Range2DL aRange = gfx::length::fromRectangleHmm(aRectangle);
+            gfx::Range2DL aRange = gfx::length::fromRectangle(aRectangle);
 
             aRectangle.Move(1000, 1000);
             aRange.shift(1000_hmm, 1000_hmm);
-            CPPUNIT_ASSERT_EQUAL(aRectangle, 
gfx::length::toRectangleHmm(aRange));
+            CPPUNIT_ASSERT_EQUAL(aRectangle, gfx::length::toRectangle(aRange));
         }
         {
             tools::Rectangle aRectangle(10, 20, 110, 120);
-            gfx::Range2DL aRange = gfx::length::fromRectangleHmm(aRectangle);
+            gfx::Range2DL aRange = gfx::length::fromRectangle(aRectangle);
 
             aRectangle.SetSize(Size(201, 201));
             aRange.setSize(200_hmm, 200_hmm);
-            CPPUNIT_ASSERT_EQUAL(aRectangle, 
gfx::length::toRectangleHmm(aRange));
+            CPPUNIT_ASSERT_EQUAL(aRectangle, gfx::length::toRectangle(aRange));
         }
         {
             tools::Rectangle aRectangle(10, 20, 110, 120);
-            gfx::Range2DL aRange = gfx::length::fromRectangleHmm(aRectangle);
+            gfx::Range2DL aRange = gfx::length::fromRectangle(aRectangle);
 
             aRectangle.SetPos(Point(500, 500));
             aRange.setPosition(500_hmm, 500_hmm);
-            CPPUNIT_ASSERT_EQUAL(aRectangle, 
gfx::length::toRectangleHmm(aRange));
+            CPPUNIT_ASSERT_EQUAL(aRectangle, gfx::length::toRectangle(aRange));
         }
         {
             tools::Rectangle aRectangle(Point(0, 0), Size(0, 31));
@@ -222,7 +252,7 @@ public:
             CPPUNIT_ASSERT_EQUAL(tools::Long(0), aRectangle.GetWidth());
             CPPUNIT_ASSERT_EQUAL(tools::Long(31), aRectangle.GetHeight());
 
-            gfx::Range2DL aRange = gfx::length::fromRectangleHmm(aRectangle);
+            gfx::Range2DL aRange = gfx::length::fromRectangle(aRectangle);
             CPPUNIT_ASSERT_EQUAL(0_hmm, aRange.getMinX());
             CPPUNIT_ASSERT_EQUAL(0_hmm, aRange.getMinY());
             CPPUNIT_ASSERT_EQUAL(0_hmm, aRange.getMaxX());
@@ -233,10 +263,51 @@ public:
     CPPUNIT_TEST_SUITE(LengthTest);
     CPPUNIT_TEST(testBasic);
     CPPUNIT_TEST(testDivision);
-    CPPUNIT_TEST(testInRange);
+    CPPUNIT_TEST(testGenericFrom);
+    CPPUNIT_TEST(testGenericAs);
+    //
+    CPPUNIT_TEST(testSizeLWrap);
     CPPUNIT_TEST(testInTuple);
     CPPUNIT_TEST(testConversionToRectangle);
     CPPUNIT_TEST_SUITE_END();
 };
-
 CPPUNIT_TEST_SUITE_REGISTRATION(LengthTest);
+
+class Range2DLTest : public CppUnit::TestFixture
+{
+    void testInRange()
+    {
+        gfx::Range2DL aRange(1_cm, 2_cm, 2_cm, 30_mm);
+        CPPUNIT_ASSERT_EQUAL(1_cm, aRange.getMinX());
+        CPPUNIT_ASSERT_EQUAL(2_cm, aRange.getMaxX());
+        CPPUNIT_ASSERT_EQUAL(2_cm, aRange.getMinY());
+        CPPUNIT_ASSERT_EQUAL(3_cm, aRange.getMaxY());
+
+        CPPUNIT_ASSERT_EQUAL(1_cm, aRange.getWidth());
+        CPPUNIT_ASSERT_EQUAL(10_mm, aRange.getHeight());
+
+        aRange.shift(1_cm, 1_cm);
+        CPPUNIT_ASSERT_EQUAL(2_cm, aRange.getMinX());
+        CPPUNIT_ASSERT_EQUAL(3_cm, aRange.getMinY());
+        CPPUNIT_ASSERT_EQUAL(3_cm, aRange.getMaxX());
+        CPPUNIT_ASSERT_EQUAL(40_mm, aRange.getMaxY());
+
+        aRange.setSize(5_cm, 2_cm);
+        CPPUNIT_ASSERT_EQUAL(2_cm, aRange.getMinX());
+        CPPUNIT_ASSERT_EQUAL(3_cm, aRange.getMinY());
+        CPPUNIT_ASSERT_EQUAL(7_cm, aRange.getMaxX());
+        CPPUNIT_ASSERT_EQUAL(5_cm, aRange.getMaxY());
+
+        aRange.setPosition(0_cm, 0_cm);
+        CPPUNIT_ASSERT_EQUAL(0_cm, aRange.getMinX());
+        CPPUNIT_ASSERT_EQUAL(0_cm, aRange.getMinY());
+        CPPUNIT_ASSERT_EQUAL(5_cm, aRange.getMaxX());
+        CPPUNIT_ASSERT_EQUAL(2_cm, aRange.getMaxY());
+    }
+
+    CPPUNIT_TEST_SUITE(Range2DLTest);
+    CPPUNIT_TEST(testInRange);
+    CPPUNIT_TEST_SUITE_END();
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Range2DLTest);
diff --git a/include/basegfx/units/Length.hxx b/include/basegfx/units/Length.hxx
index 33361ba39e39..5fe665526374 100644
--- a/include/basegfx/units/Length.hxx
+++ b/include/basegfx/units/Length.hxx
@@ -9,16 +9,11 @@
 
 #pragma once
 
-#include <basegfx/units/LengthUnitBase.hxx>
-#include <basegfx/range/Range2D.hxx>
-#include <basegfx/tuple/Size2D.hxx>
-#include <basegfx/range/b2drange.hxx>
-
-#include <tools/gen.hxx>
+#include <basegfx/units/LengthBase.hxx>
 
 namespace gfx
 {
-typedef LengthUnitBase<sal_Int64> Length;
+typedef LengthBase<sal_Int64> Length;
 
 struct LengthTraits
 {
@@ -35,6 +30,7 @@ constexpr gfx::Length operator"" _emu(unsigned long long 
value) { return gfx::Le
 constexpr gfx::Length operator"" _in(unsigned long long value) { return 
gfx::Length::in(value); }
 constexpr gfx::Length operator"" _cm(unsigned long long value) { return 
gfx::Length::cm(value); }
 constexpr gfx::Length operator"" _mm(unsigned long long value) { return 
gfx::Length::mm(value); }
+constexpr gfx::Length operator"" _m(unsigned long long value) { return 
gfx::Length::meter(value); }
 constexpr gfx::Length operator"" _hmm(unsigned long long value) { return 
gfx::Length::hmm(value); }
 constexpr gfx::Length operator"" _twip(unsigned long long value)
 {
@@ -57,6 +53,11 @@ constexpr gfx::Length operator"" _mm(long double value)
     return gfx::Length::emu(std::round(gfx::constFactor_mm_to_EMU * value));
 }
 
+constexpr gfx::Length operator"" _m(long double value)
+{
+    return gfx::Length::emu(std::round(gfx::constFactor_meter_to_EMU * value));
+}
+
 constexpr gfx::Length operator"" _hmm(long double value)
 {
     return gfx::Length::emu(std::round(gfx::constFactor_hmm_to_EMU * value));
@@ -86,64 +87,4 @@ inline std::basic_ostream<charT, traits>& 
operator<<(std::basic_ostream<charT, t
                   << ")";
 }
 
-namespace gfx
-{
-typedef basegfx::Range2D<gfx::Length, gfx::LengthTraits> Range2DL;
-typedef basegfx::Tuple2D<gfx::Length> Tuple2DL;
-typedef basegfx::Size2D<gfx::Length> Size2DL;
-
-namespace length
-{
-static inline Size2DL fromSizeHmm(Size const& rSize)
-{
-    if (rSize.IsEmpty())
-        return Size2DL(0_mm, 0_mm);
-    auto width = Length::hmm(rSize.getWidth());
-    auto height = Length::hmm(rSize.getHeight());
-    return Size2DL(width, height);
-}
-
-static inline Size toSizeHmm(Size2DL const& rSize)
-{
-    auto width = rSize.getWidth().as_hmm();
-    auto height = rSize.getHeight().as_hmm();
-    return Size(width, height);
-}
-
-static inline Range2DL fromRectangleHmm(tools::Rectangle const& rRectangle)
-{
-    if (rRectangle.IsWidthEmpty() && rRectangle.IsHeightEmpty())
-        return Range2DL();
-
-    auto left = Length::hmm(rRectangle.Left());
-    auto top = Length::hmm(rRectangle.Top());
-    auto right = Length::hmm(rRectangle.Right());
-    auto bottom = Length::hmm(rRectangle.Bottom());
-
-    return Range2DL(left, top, right, bottom);
-}
-
-static inline basegfx::B2DRange toB2DRange2DHmm(Range2DL const& rRange2D)
-{
-    if (rRange2D.isEmpty())
-        return basegfx::B2DRange();
-    auto left = rRange2D.getMinX().as_hmm();
-    auto top = rRange2D.getMinY().as_hmm();
-    auto right = rRange2D.getMaxX().as_hmm();
-    auto bottom = rRange2D.getMaxY().as_hmm();
-    return basegfx::B2DRange(left, top, right, bottom);
-}
-
-static inline tools::Rectangle toRectangleHmm(Range2DL const& rRange2D)
-{
-    if (rRange2D.isEmpty())
-        return tools::Rectangle();
-    auto left = rRange2D.getMinX().as_hmm();
-    auto top = rRange2D.getMinY().as_hmm();
-    auto right = rRange2D.getMaxX().as_hmm();
-    auto bottom = rRange2D.getMaxY().as_hmm();
-    return tools::Rectangle(left, top, right, bottom);
-}
-
-} // end namespace gfx
-} // end namespace length
+#include <basegfx/units/LengthTypes.hxx>
diff --git a/include/basegfx/units/LengthBase.hxx 
b/include/basegfx/units/LengthBase.hxx
new file mode 100644
index 000000000000..484fa7a19e3a
--- /dev/null
+++ b/include/basegfx/units/LengthBase.hxx
@@ -0,0 +1,248 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <sal/types.h>
+
+#include <ostream>
+#include <cmath>
+
+namespace gfx
+{
+enum class LengthUnit
+{
+    hmm,
+    mm,
+    cm,
+    meter,
+    twip,
+    in,
+    pt,
+    px,
+    emu
+};
+
+namespace
+{
+constexpr sal_Int64 constFactor_hmm_to_EMU = 360ll;
+constexpr sal_Int64 constFactor_mm_to_EMU = constFactor_hmm_to_EMU * 100ll;
+constexpr sal_Int64 constFactor_cm_to_EMU = constFactor_hmm_to_EMU * 1000ll;
+constexpr sal_Int64 constFactor_meter_to_EMU = constFactor_hmm_to_EMU * 
100000ll;
+
+constexpr sal_Int64 constFactor_twip_to_EMU = 635ll;
+constexpr sal_Int64 constFactor_in_to_EMU = constFactor_twip_to_EMU * 1440ll;
+constexpr sal_Int64 constFactor_pt_to_EMU = constFactor_twip_to_EMU * 20ll;
+constexpr sal_Int64 constFactor_px_to_EMU = constFactor_twip_to_EMU * 15ll;
+
+} // end anonymous namespace
+
+template <typename TYPE> class LengthBase
+{
+private:
+    // value in EMU units
+    TYPE m_nValue;
+
+    constexpr explicit LengthBase(TYPE nValue)
+        : m_nValue(nValue)
+    {
+    }
+
+public:
+    static constexpr LengthBase min() { return LengthBase(SAL_MIN_INT64); }
+
+    static constexpr LengthBase max() { return LengthBase(SAL_MAX_INT64); }
+
+    template <typename INPUT_TYPE>
+    static constexpr LengthBase from(LengthUnit eUnit, INPUT_TYPE nValue)
+    {
+        switch (eUnit)
+        {
+            case LengthUnit::hmm:
+                return hmm(nValue);
+            case LengthUnit::mm:
+                return mm(nValue);
+            case LengthUnit::cm:
+                return cm(nValue);
+            case LengthUnit::meter:
+                return meter(nValue);
+            case LengthUnit::twip:
+                return twip(nValue);
+            case LengthUnit::in:
+                return in(nValue);
+            case LengthUnit::pt:
+                return pt(nValue);
+            case LengthUnit::px:
+                return px(nValue);
+            case LengthUnit::emu:
+                return emu(nValue);
+        }
+        return emu(nValue);
+    }
+
+    template <typename INPUT_TYPE> static constexpr LengthBase cm(INPUT_TYPE 
nValue)
+    {
+        return LengthBase(TYPE(gfx::constFactor_cm_to_EMU * nValue));
+    }
+
+    template <typename INPUT_TYPE> static constexpr LengthBase mm(INPUT_TYPE 
nValue)
+    {
+        return LengthBase(TYPE(gfx::constFactor_mm_to_EMU * nValue));
+    }
+
+    template <typename INPUT_TYPE> static constexpr LengthBase hmm(INPUT_TYPE 
nValue)
+    {
+        return LengthBase(TYPE(gfx::constFactor_hmm_to_EMU * nValue));
+    }
+
+    template <typename INPUT_TYPE> static constexpr LengthBase 
meter(INPUT_TYPE nValue)
+    {
+        return LengthBase(TYPE(gfx::constFactor_meter_to_EMU * nValue));
+    }
+
+    template <typename INPUT_TYPE> static constexpr LengthBase in(INPUT_TYPE 
nValue)
+    {
+        return LengthBase(TYPE(gfx::constFactor_in_to_EMU * nValue));
+    }
+
+    template <typename INPUT_TYPE> static constexpr LengthBase twip(INPUT_TYPE 
nValue)
+    {
+        return LengthBase(TYPE(gfx::constFactor_twip_to_EMU * nValue));
+    }
+
+    template <typename INPUT_TYPE> static constexpr LengthBase pt(INPUT_TYPE 
nValue)
+    {
+        return LengthBase(TYPE(gfx::constFactor_pt_to_EMU * nValue));
+    }
+
+    template <typename INPUT_TYPE> static constexpr LengthBase px(INPUT_TYPE 
nValue)
+    {
+        return LengthBase(TYPE(gfx::constFactor_px_to_EMU * nValue));
+    }
+
+    template <typename INPUT_TYPE> static constexpr LengthBase emu(INPUT_TYPE 
nValue)
+    {
+        return LengthBase(TYPE(nValue));
+    }
+
+    constexpr explicit LengthBase()
+        : m_nValue(0)
+    {
+    }
+
+    constexpr explicit operator TYPE() const { return m_nValue; }
+
+    constexpr LengthBase& operator+=(LengthBase const& rhs)
+    {
+        m_nValue += rhs.m_nValue;
+        return *this;
+    }
+
+    constexpr LengthBase& operator-=(LengthBase const& rhs)
+    {
+        m_nValue -= rhs.m_nValue;
+        return *this;
+    }
+
+    constexpr LengthBase& operator*=(TYPE const& rhs)
+    {
+        m_nValue *= rhs;
+        return *this;
+    }
+
+    constexpr LengthBase& operator/=(TYPE const& rhs)
+    {
+        m_nValue /= rhs;
+        return *this;
+    }
+
+    constexpr LengthBase& operator-()
+    {
+        m_nValue = -m_nValue;
+        return *this;
+    }
+
+    constexpr bool operator<(LengthBase const& other) const { return m_nValue 
< other.m_nValue; }
+    constexpr bool operator<=(LengthBase const& other) const { return m_nValue 
<= other.m_nValue; }
+    constexpr bool operator>(LengthBase const& other) const { return m_nValue 
> other.m_nValue; }
+    constexpr bool operator>=(LengthBase const& other) const { return m_nValue 
>= other.m_nValue; }
+    constexpr bool operator==(LengthBase const& other) const { return m_nValue 
== other.m_nValue; }
+    constexpr bool operator!=(LengthBase const& other) const { return m_nValue 
!= other.m_nValue; }
+
+    constexpr TYPE raw() const { return m_nValue; }
+
+    double as(LengthUnit eUnit) const
+    {
+        switch (eUnit)
+        {
+            case LengthUnit::hmm:
+                return as_hmm();
+            case LengthUnit::mm:
+                return as_mm();
+            case LengthUnit::cm:
+                return as_cm();
+            case LengthUnit::meter:
+                return as_meter();
+            case LengthUnit::twip:
+                return as_twip();
+            case LengthUnit::in:
+                return as_in();
+            case LengthUnit::pt:
+                return as_pt();
+            case LengthUnit::px:
+                return as_px();
+            case LengthUnit::emu:
+                return as_emu();
+        }
+        return std::numeric_limits<double>::infinity();
+    }
+
+    double as_hmm() const { return m_nValue / double(constFactor_hmm_to_EMU); }
+    double as_mm() const { return m_nValue / double(constFactor_mm_to_EMU); }
+    double as_cm() const { return m_nValue / double(constFactor_cm_to_EMU); }
+    double as_meter() const { return m_nValue / 
double(constFactor_meter_to_EMU); }
+    double as_twip() const { return m_nValue / 
double(constFactor_twip_to_EMU); }
+    double as_in() const { return m_nValue / double(constFactor_in_to_EMU); }
+    double as_pt() const { return m_nValue / double(constFactor_pt_to_EMU); }
+    double as_px() const { return m_nValue / double(constFactor_px_to_EMU); }
+    double as_emu() const { return double(m_nValue); }
+};
+
+template <typename T> inline LengthBase<T> operator+(LengthBase<T> lhs, const 
LengthBase<T>& rhs)
+{
+    return lhs += rhs;
+}
+
+template <typename T> inline LengthBase<T> operator-(LengthBase<T> lhs, const 
LengthBase<T>& rhs)
+{
+    return lhs -= rhs;
+}
+
+/// 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)
+{
+    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)
+{
+    return lhs /= rhs;
+}
+
+/// Division of 2 length units, which results in a ratio.
+/// example 1cm / 2cm = 0.5
+template <typename T> inline double operator/(LengthBase<T> lhs, const 
LengthBase<T> rhs)
+{
+    return lhs.raw() / double(rhs.raw());
+}
+
+} // end namespace gfx
diff --git a/include/basegfx/units/LengthTypes.hxx 
b/include/basegfx/units/LengthTypes.hxx
new file mode 100644
index 000000000000..a36462d18ce5
--- /dev/null
+++ b/include/basegfx/units/LengthTypes.hxx
@@ -0,0 +1,121 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <basegfx/units/Length.hxx>
+#include <basegfx/range/Range2D.hxx>
+#include <basegfx/tuple/Size2D.hxx>
+#include <basegfx/range/b2drange.hxx>
+
+#include <tools/gen.hxx>
+
+namespace gfx
+{
+typedef basegfx::Range2D<gfx::Length, gfx::LengthTraits> Range2DL;
+typedef basegfx::Tuple2D<gfx::Length> Tuple2DL;
+typedef basegfx::Size2D<gfx::Length> Size2DL;
+
+class Size2DLWrap : public Size2DL
+{
+    LengthUnit meUnit;
+
+public:
+    static Size2DLWrap create(Size const& rSize, LengthUnit eUnit = 
LengthUnit::hmm)
+    {
+        if (rSize.IsEmpty())
+            return Size2DLWrap(0_emu, 0_emu, eUnit);
+        auto width = Length::from(eUnit, rSize.getWidth());
+        auto height = Length::from(eUnit, rSize.getHeight());
+        return Size2DLWrap(width, height, eUnit);
+    }
+
+    Size2DLWrap(LengthUnit eUnit = LengthUnit::hmm)
+        : Size2DL(0_emu, 0_emu)
+        , meUnit(eUnit)
+    {
+    }
+
+    Size2DLWrap(gfx::Length fX, gfx::Length fY, LengthUnit eUnit = 
LengthUnit::hmm)
+        : Size2DL(fX, fY)
+        , meUnit(eUnit)
+    {
+    }
+
+    Size2DLWrap(Size2DLWrap const& rSize)
+        : Size2DL(rSize)
+        , meUnit(rSize.meUnit)
+    {
+    }
+
+    Size toSize()
+    {
+        auto width = getWidth().as(meUnit);
+        auto height = getHeight().as(meUnit);
+        return Size(width, height);
+    }
+
+    using Size2DL::operator+=;
+    using Size2DL::operator-=;
+    using Size2DL::operator*=;
+    using Size2DL::operator/=;
+    using Size2DL::operator-;
+};
+
+namespace length
+{
+static inline Size2DL fromSize(Size const& rSize, gfx::LengthUnit eUnit = 
gfx::LengthUnit::hmm)
+{
+    if (rSize.IsEmpty())
+        return Size2DL(0_emu, 0_emu);
+    auto width = Length::from(eUnit, rSize.getWidth());
+    auto height = Length::from(eUnit, rSize.getHeight());
+    return Size2DL(width, height);
+}
+
+static inline Range2DL fromRectangle(tools::Rectangle const& rRectangle,
+                                     gfx::LengthUnit eUnit = 
gfx::LengthUnit::hmm)
+{
+    if (rRectangle.IsWidthEmpty() && rRectangle.IsHeightEmpty())
+        return Range2DL();
+
+    auto left = Length::from(eUnit, rRectangle.Left());
+    auto top = Length::from(eUnit, rRectangle.Top());
+    auto right = Length::from(eUnit, rRectangle.Right());
+    auto bottom = Length::from(eUnit, rRectangle.Bottom());
+
+    return Range2DL(left, top, right, bottom);
+}
+
+static inline basegfx::B2DRange toB2DRange2D(Range2DL const& rRange2D,
+                                             gfx::LengthUnit eUnit = 
gfx::LengthUnit::hmm)
+{
+    if (rRange2D.isEmpty())
+        return basegfx::B2DRange();
+    auto left = rRange2D.getMinX().as(eUnit);
+    auto top = rRange2D.getMinY().as(eUnit);
+    auto right = rRange2D.getMaxX().as(eUnit);
+    auto bottom = rRange2D.getMaxY().as(eUnit);
+    return basegfx::B2DRange(left, top, right, bottom);
+}
+
+static inline tools::Rectangle toRectangle(Range2DL const& rRange2D,
+                                           gfx::LengthUnit eUnit = 
gfx::LengthUnit::hmm)
+{
+    if (rRange2D.isEmpty())
+        return tools::Rectangle();
+    auto left = rRange2D.getMinX().as(eUnit);
+    auto top = rRange2D.getMinY().as(eUnit);
+    auto right = rRange2D.getMaxX().as(eUnit);
+    auto bottom = rRange2D.getMaxY().as(eUnit);
+    return tools::Rectangle(left, top, right, bottom);
+}
+
+} // end namespace gfx
+} // end namespace length
diff --git a/include/basegfx/units/LengthUnitBase.hxx 
b/include/basegfx/units/LengthUnitBase.hxx
deleted file mode 100644
index 30daccef8015..000000000000
--- a/include/basegfx/units/LengthUnitBase.hxx
+++ /dev/null
@@ -1,197 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#pragma once
-
-#include <sal/types.h>
-
-#include <ostream>
-#include <cmath>
-
-namespace gfx
-{
-namespace
-{
-constexpr sal_Int64 constFactor_hmm_to_EMU = 360ll;
-constexpr sal_Int64 constFactor_mm_to_EMU = constFactor_hmm_to_EMU * 100ll;
-constexpr sal_Int64 constFactor_cm_to_EMU = constFactor_hmm_to_EMU * 1000ll;
-constexpr sal_Int64 constFactor_m_to_EMU = constFactor_hmm_to_EMU * 100000ll;
-
-constexpr sal_Int64 constFactor_twip_to_EMU = 635ll;
-constexpr sal_Int64 constFactor_in_to_EMU = constFactor_twip_to_EMU * 1440ll;
-constexpr sal_Int64 constFactor_pt_to_EMU = constFactor_twip_to_EMU * 20ll;
-constexpr sal_Int64 constFactor_px_to_EMU = constFactor_twip_to_EMU * 15ll;
-
-} // end anonymous namespace
-
-template <typename TYPE> class LengthUnitBase
-{
-private:
-    // value in EMU units
-    TYPE m_nValue;
-
-    constexpr explicit LengthUnitBase(TYPE nValue)
-        : m_nValue(nValue)
-    {
-    }
-
-public:
-    static constexpr LengthUnitBase min() { return 
LengthUnitBase(SAL_MIN_INT64); }
-
-    static constexpr LengthUnitBase max() { return 
LengthUnitBase(SAL_MAX_INT64); }
-
-    template <typename INPUT_TYPE> static constexpr LengthUnitBase 
cm(INPUT_TYPE nValue)
-    {
-        return LengthUnitBase(TYPE(gfx::constFactor_cm_to_EMU * nValue));
-    }
-
-    template <typename INPUT_TYPE> static constexpr LengthUnitBase 
mm(INPUT_TYPE nValue)
-    {
-        return LengthUnitBase(TYPE(gfx::constFactor_mm_to_EMU * nValue));
-    }
-
-    template <typename INPUT_TYPE> static constexpr LengthUnitBase 
hmm(INPUT_TYPE nValue)
-    {
-        return LengthUnitBase(TYPE(gfx::constFactor_hmm_to_EMU * nValue));
-    }
-
-    template <typename INPUT_TYPE> static constexpr LengthUnitBase 
in(INPUT_TYPE nValue)
-    {
-        return LengthUnitBase(TYPE(gfx::constFactor_in_to_EMU * nValue));
-    }
-
-    template <typename INPUT_TYPE> static constexpr LengthUnitBase 
twip(INPUT_TYPE nValue)
-    {
-        return LengthUnitBase(TYPE(gfx::constFactor_twip_to_EMU * nValue));
-    }
-
-    template <typename INPUT_TYPE> static constexpr LengthUnitBase 
pt(INPUT_TYPE nValue)
-    {
-        return LengthUnitBase(TYPE(gfx::constFactor_pt_to_EMU * nValue));
-    }
-
-    template <typename INPUT_TYPE> static constexpr LengthUnitBase 
px(INPUT_TYPE nValue)
-    {
-        return LengthUnitBase(TYPE(gfx::constFactor_px_to_EMU * nValue));
-    }
-
-    template <typename INPUT_TYPE> static constexpr LengthUnitBase 
emu(INPUT_TYPE nValue)
-    {
-        return LengthUnitBase(TYPE(nValue));
-    }
-
-    constexpr explicit LengthUnitBase()
-        : m_nValue(0)
-    {
-    }
-
-    constexpr explicit operator TYPE() const { return m_nValue; }
-
-    constexpr LengthUnitBase& operator+=(LengthUnitBase const& rhs)
-    {
-        m_nValue += rhs.m_nValue;
-        return *this;
-    }
-
-    constexpr LengthUnitBase& operator-=(LengthUnitBase const& rhs)
-    {
-        m_nValue -= rhs.m_nValue;
-        return *this;
-    }
-
-    constexpr LengthUnitBase& operator*=(TYPE const& rhs)
-    {
-        m_nValue *= rhs;
-        return *this;
-    }
-
-    constexpr LengthUnitBase& operator/=(TYPE const& rhs)
-    {
-        m_nValue /= rhs;
-        return *this;
-    }
-
-    constexpr LengthUnitBase& operator-()
-    {
-        m_nValue = -m_nValue;
-        return *this;
-    }
-
-    constexpr bool operator<(LengthUnitBase const& other) const
-    {
-        return m_nValue < other.m_nValue;
-    }
-    constexpr bool operator<=(LengthUnitBase const& other) const
-    {
-        return m_nValue <= other.m_nValue;
-    }
-    constexpr bool operator>(LengthUnitBase const& other) const
-    {
-        return m_nValue > other.m_nValue;
-    }
-    constexpr bool operator>=(LengthUnitBase const& other) const
-    {
-        return m_nValue >= other.m_nValue;
-    }
-    constexpr bool operator==(LengthUnitBase const& other) const
-    {
-        return m_nValue == other.m_nValue;
-    }
-    constexpr bool operator!=(LengthUnitBase const& other) const
-    {
-        return m_nValue != other.m_nValue;
-    }
-
-    constexpr TYPE raw() const { return m_nValue; }
-
-    double as_hmm() const { return m_nValue / double(constFactor_hmm_to_EMU); }
-    double as_mm() const { return m_nValue / double(constFactor_mm_to_EMU); }
-    double as_cm() const { return m_nValue / double(constFactor_cm_to_EMU); }
-    double as_m() const { return m_nValue / double(constFactor_m_to_EMU); }
-    double as_twip() const { return m_nValue / 
double(constFactor_twip_to_EMU); }
-    double as_in() const { return m_nValue / double(constFactor_in_to_EMU); }
-    double as_pt() const { return m_nValue / double(constFactor_pt_to_EMU); }
-    double as_px() const { return m_nValue / double(constFactor_px_to_EMU); }
-    double as_emu() const { return double(m_nValue); }
-};
-
-template <typename T>
-inline LengthUnitBase<T> operator+(LengthUnitBase<T> lhs, const 
LengthUnitBase<T>& rhs)
-{
-    return lhs += rhs;
-}
-
-template <typename T>
-inline LengthUnitBase<T> operator-(LengthUnitBase<T> lhs, const 
LengthUnitBase<T>& rhs)
-{
-    return lhs -= rhs;
-}
-
-/// Multiplication of a length unit with a scalar value.
-/// example 1cm * 2 = 2cm
-template <typename T> inline LengthUnitBase<T> operator*(LengthUnitBase<T> 
lhs, const long rhs)
-{
-    return lhs *= rhs;
-}
-
-/// Division of a length unit with a scalar value.
-/// example 1cm / 2 = 0.5cm
-template <typename T> inline LengthUnitBase<T> operator/(LengthUnitBase<T> 
lhs, const long rhs)
-{
-    return lhs /= rhs;
-}
-
-/// Division of 2 length units, which results in a ratio.
-/// example 1cm / 2cm = 0.5
-template <typename T> inline double operator/(LengthUnitBase<T> lhs, const 
LengthUnitBase<T> rhs)
-{
-    return lhs.raw() / double(rhs.raw());
-}
-
-} // end namespace gfx

Reply via email to