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
