summaryrefslogtreecommitdiffstats
path: root/include/basegfx/utils
diff options
context:
space:
mode:
Diffstat (limited to 'include/basegfx/utils')
-rw-r--r--include/basegfx/utils/b2dclipstate.hxx92
-rw-r--r--include/basegfx/utils/bgradient.hxx329
-rw-r--r--include/basegfx/utils/canvastools.hxx167
-rw-r--r--include/basegfx/utils/common.hxx33
-rw-r--r--include/basegfx/utils/gradienttools.hxx526
-rw-r--r--include/basegfx/utils/keystoplerp.hxx85
-rw-r--r--include/basegfx/utils/lerp.hxx43
-rw-r--r--include/basegfx/utils/rectcliptools.hxx72
-rw-r--r--include/basegfx/utils/systemdependentdata.hxx111
-rw-r--r--include/basegfx/utils/tools.hxx124
-rw-r--r--include/basegfx/utils/unopolypolygon.hxx104
-rw-r--r--include/basegfx/utils/zoomtools.hxx22
12 files changed, 1708 insertions, 0 deletions
diff --git a/include/basegfx/utils/b2dclipstate.hxx b/include/basegfx/utils/b2dclipstate.hxx
new file mode 100644
index 0000000000..f4d9d9e7d6
--- /dev/null
+++ b/include/basegfx/utils/b2dclipstate.hxx
@@ -0,0 +1,92 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <o3tl/cow_wrapper.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+
+namespace basegfx
+{
+ class B2DRange;
+ class B2DPolyPolygon;
+ class B2DHomMatrix;
+}
+
+namespace basegfx::utils
+{
+ class ImplB2DClipState;
+
+ /** This class provides an optimized, symbolic clip state for graphical output
+
+ Having a current 'clip' state is a common attribute of
+ almost all graphic output APIs, most of which internally
+ represent it via a list of rectangular bands. In contrast,
+ this implementation purely uses symbolic clips, but in a
+ quite efficient manner, deferring actual evaluation until
+ a clip representation is requested, and using faster code
+ paths for common special cases (like all-rectangle clips)
+ */
+ class BASEGFX_DLLPUBLIC B2DClipState
+ {
+ public:
+ typedef o3tl::cow_wrapper< ImplB2DClipState > ImplType;
+
+ private:
+ ImplType mpImpl;
+
+ public:
+ /// Init clip, in 'cleared' state - everything is visible
+ B2DClipState();
+ ~B2DClipState();
+ B2DClipState( const B2DClipState& );
+ B2DClipState( B2DClipState&& );
+ explicit B2DClipState( const B2DPolyPolygon& );
+ B2DClipState& operator=( const B2DClipState& );
+ B2DClipState& operator=( B2DClipState&& );
+
+ /// Set clip to 'null' - nothing is visible
+ void makeNull();
+
+ /// returns true when clip is 'cleared' - everything is visible
+ bool isCleared() const;
+
+ bool operator==(const B2DClipState&) const;
+ bool operator!=(const B2DClipState&) const;
+
+ void unionRange(const B2DRange& );
+ void unionPolyPolygon(const B2DPolyPolygon& );
+
+ void intersectRange(const B2DRange& );
+ void intersectPolyPolygon(const B2DPolyPolygon& );
+
+ void subtractRange(const B2DRange& );
+ void subtractPolyPolygon(const B2DPolyPolygon& );
+
+ void xorRange(const B2DRange& );
+ void xorPolyPolygon(const B2DPolyPolygon& );
+
+ void transform(const B2DHomMatrix& );
+
+ B2DPolyPolygon const & getClipPoly() const;
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/utils/bgradient.hxx b/include/basegfx/utils/bgradient.hxx
new file mode 100644
index 0000000000..7d360beee4
--- /dev/null
+++ b/include/basegfx/utils/bgradient.hxx
@@ -0,0 +1,329 @@
+/* -*- 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/color/bcolor.hxx>
+#include <basegfx/basegfxdllapi.h>
+#include <vector>
+#include <com/sun/star/awt/GradientStyle.hpp>
+#include <tools/degree.hxx>
+#include <boost/property_tree/ptree_fwd.hpp>
+
+namespace basegfx
+{
+/* MCGR: Provide ColorStop definition
+
+ This is the needed combination of offset and color:
+
+ Offset is defined as:
+ - being in the range of [0.0 .. 1.0] (unit range)
+ - offsets outside are an error
+ - lowest/1st value equivalent to StartColor
+ - highest/last value equivalent to EndColor
+ - missing 0.0/1.0 entries are allowed
+ - at least one value (usually 0.0, StartColor) is required
+ - this allows to avoid massive testing in all places where
+ this data has to be accessed
+
+ Color is defined as:
+ - RGB with unit values [0.0 .. 1.0]
+
+ These definitions are packed in a std::vector<ColorStop> ColorStops,
+ see typedef below.
+ */
+class BASEGFX_DLLPUBLIC BColorStop
+{
+private:
+ // offset in the range of [0.0 .. 1.0]
+ double mfStopOffset;
+
+ // RGB color of ColorStop entry
+ BColor maStopColor;
+
+public:
+ // constructor - defaults are needed to have a default constructor
+ // e.g. for usage in std::vector::insert (even when only reducing)
+ // ensure [0.0 .. 1.0] range for mfStopOffset
+ BColorStop(double fStopOffset = 0.0, const BColor& rStopColor = BColor())
+ : mfStopOffset(fStopOffset)
+ , maStopColor(rStopColor)
+ {
+ // NOTE: I originally *corrected* mfStopOffset here by using
+ // mfStopOffset(std::max(0.0, std::min(fOffset, 1.0)))
+ // While that is formally correct, it moves an invalid
+ // entry to 0.0 or 1.0, thus creating additional wrong
+ // Start/EndColor entries. That may then 'overlay' the
+ // correct entry when corrections are applied to the
+ // vector of entries (see sortAndCorrectColorStops)
+ // which leads to getting the wanted Start/EndColor
+ // to be factically deleted, what is an error.
+ }
+
+ double getStopOffset() const { return mfStopOffset; }
+ const BColor& getStopColor() const { return maStopColor; }
+
+ // needed for std::sort
+ bool operator<(const BColorStop& rCandidate) const
+ {
+ return getStopOffset() < rCandidate.getStopOffset();
+ }
+
+ bool operator==(const BColorStop& rCandidate) const
+ {
+ return getStopOffset() == rCandidate.getStopOffset()
+ && getStopColor() == rCandidate.getStopColor();
+ }
+
+ bool operator!=(const BColorStop& rCandidate) const { return !(*this == rCandidate); }
+};
+
+/* MCGR: Provide ColorStops definition to the FillGradientAttribute
+
+ This array should be sorted ascending by offsets, from lowest to
+ highest. Since all the primitive data definition where it is used
+ is read-only, this can/will be guaranteed by forcing/checking this
+ in the constructor, see ::FillGradientAttribute
+ */
+class BASEGFX_DLLPUBLIC BColorStops final : public std::vector<BColorStop>
+{
+public:
+ explicit BColorStops()
+ : vector()
+ {
+ }
+ BColorStops(const BColorStops& other)
+ : vector(other)
+ {
+ }
+ BColorStops(BColorStops&& other) noexcept
+ : vector(std::move(other))
+ {
+ }
+ BColorStops(std::initializer_list<BColorStop> init)
+ : vector(init)
+ {
+ }
+ BColorStops(const_iterator first, const_iterator last)
+ : vector(first, last)
+ {
+ }
+
+ // constructor with two colors to explicitly create a
+ // BColorStops for StartColor @0.0 & EndColor @1.0
+ BColorStops(const BColor& rStart, const BColor& rEnd);
+
+ BColorStops& operator=(const BColorStops& r)
+ {
+ vector::operator=(r);
+ return *this;
+ }
+ BColorStops& operator=(BColorStops&& r) noexcept
+ {
+ vector::operator=(std::move(r));
+ return *this;
+ }
+
+ // helper data struct to support buffering entries in
+ // gradient texture mapping, see usages for more info
+ struct BColorStopRange
+ {
+ basegfx::BColor maColorStart;
+ basegfx::BColor maColorEnd;
+ double mfOffsetStart;
+ double mfOffsetEnd;
+
+ BColorStopRange()
+ : maColorStart()
+ , maColorEnd()
+ , mfOffsetStart(0.0)
+ , mfOffsetEnd(0.0)
+ {
+ }
+ };
+
+ /* Helper to grep the correct ColorStop out of
+ ColorStops and interpolate as needed for given
+ relative value in fPosition in the range of [0.0 .. 1.0].
+ It also takes care of evtl. given RequestedSteps.
+ */
+ BColor getInterpolatedBColor(double fPosition, sal_uInt32 nRequestedSteps,
+ BColorStopRange& rLastColorStopRange) const;
+
+ /* Tooling method that allows to replace the StartColor in a
+ vector of ColorStops. A vector in 'ordered state' is expected,
+ so you may use/have used sortAndCorrect.
+ This method is for convenience & backwards compatibility, please
+ think about handling multi-colored gradients directly.
+ */
+ void replaceStartColor(const BColor& rStart);
+
+ /* Tooling method that allows to replace the EndColor in a
+ vector of ColorStops. A vector in 'ordered state' is expected,
+ so you may use/have used sortAndCorrect.
+ This method is for convenience & backwards compatibility, please
+ think about handling multi-colored gradients directly.
+ */
+ void replaceEndColor(const BColor& rEnd);
+
+ /* Tooling method to linearly blend the Colors contained in
+ a given ColorStop vector against a given Color using the
+ given intensity values.
+ The intensity values fStartIntensity, fEndIntensity are
+ in the range of [0.0 .. 1.0] and describe how much the
+ blend is supposed to be done at the start color position
+ and the end color position respectively, where 0.0 means
+ to fully use the given BlendColor, 1.0 means to not change
+ the existing color in the ColorStop.
+ Every color entry in the given ColorStop is blended
+ relative to it's StopPosition, interpolating the
+ given intensities with the range [0.0 .. 1.0] to do so.
+ */
+ void blendToIntensity(double fStartIntensity, double fEndIntensity, const BColor& rBlendColor);
+
+ /* Tooling method to guarantee sort and correctness for
+ the given ColorStops vector.
+ A vector fulfilling these conditions is called to be
+ in 'ordered state'.
+
+ At return, the following conditions are guaranteed:
+ - contains no ColorStops with offset < 0.0 (will
+ be removed)
+ - contains no ColorStops with offset > 1.0 (will
+ be removed)
+ - ColorStops with identical offsets are now allowed
+ - will be sorted from lowest offset to highest
+
+ Some more notes:
+ - It can happen that the result is empty
+ - It is allowed to have consecutive entries with
+ the same color, this represents single-color
+ regions inside the gradient
+ - A entry with 0.0 is not required or forced, so
+ no 'StartColor' is technically required
+ - A entry with 1.0 is not required or forced, so
+ no 'EndColor' is technically required
+
+ All this is done in one run (sort + O(N)) without
+ creating a copy of the data in any form
+ */
+ void sortAndCorrect();
+
+ // check if we need last-ColorStop-correction. This returns true if the last
+ // two ColorStops have the same offset but different Colors. In that case the
+ // tessellation for gradients does have to create an extra ending/closing entry
+ bool checkPenultimate() const;
+
+ /* Tooling method to check if a ColorStop vector is defined
+ by a single color. It returns true if this is the case.
+ If true is returned, rSingleColor contains that single
+ color for convenience.
+ NOTE: If no ColorStop is defined, a fallback to BColor-default
+ (which is black) and true will be returned
+ */
+ bool isSingleColor(BColor& rSingleColor) const;
+
+ /* Tooling method to reverse ColorStops, including offsets.
+ When also mirroring offsets a valid sort keeps valid.
+ */
+ void reverseColorStops();
+
+ // createSpaceAtStart creates fOffset space at start by
+ // translating/scaling all entries to the right
+ void createSpaceAtStart(double fOffset);
+
+ // removeSpaceAtStart removes fOffset space from start by
+ // translating/scaling entries more or equal to fOffset
+ // to the left. Entries less than fOffset will be removed
+ void removeSpaceAtStart(double fOffset);
+
+ // try to detect if an empty/no-color-change area exists
+ // at the start and return offset to it. Returns 0.0 if not.
+ double detectPossibleOffsetAtStart() const;
+
+ // returns true if the color stops are symmetrical in color and offset, otherwise false.
+ bool isSymmetrical() const;
+ // assume that the color stops represent an Axial gradient
+ // and replace with gradient stops to represent the same
+ // gradient as linear gradient
+ void doApplyAxial();
+
+ // apply Steps as 'hard' color stops
+ void doApplySteps(sal_uInt16 nStepCount);
+};
+
+class BASEGFX_DLLPUBLIC BGradient final
+{
+private:
+ css::awt::GradientStyle eStyle;
+
+ // MCGS: ColorStops in the range [0.0 .. 1.0], including StartColor/EndColor
+ basegfx::BColorStops aColorStops;
+
+ Degree10 nAngle;
+ sal_uInt16 nBorder;
+ sal_uInt16 nOfsX;
+ sal_uInt16 nOfsY;
+ sal_uInt16 nIntensStart;
+ sal_uInt16 nIntensEnd;
+ sal_uInt16 nStepCount;
+
+ static std::string GradientStyleToString(css::awt::GradientStyle eStyle);
+
+public:
+ BGradient();
+ BGradient(const basegfx::BColorStops& rColorStops,
+ css::awt::GradientStyle eStyle = css::awt::GradientStyle_LINEAR,
+ Degree10 nAngle = 0_deg10, sal_uInt16 nXOfs = 50, sal_uInt16 nYOfs = 50,
+ sal_uInt16 nBorder = 0, sal_uInt16 nStartIntens = 100, sal_uInt16 nEndIntens = 100,
+ sal_uInt16 nSteps = 0);
+
+ bool operator==(const BGradient& rGradient) const;
+
+ void SetGradientStyle(css::awt::GradientStyle eNewStyle) { eStyle = eNewStyle; }
+ void SetColorStops(const basegfx::BColorStops& rSteps);
+ void SetAngle(Degree10 nNewAngle) { nAngle = nNewAngle; }
+ void SetBorder(sal_uInt16 nNewBorder) { nBorder = nNewBorder; }
+ void SetXOffset(sal_uInt16 nNewOffset) { nOfsX = nNewOffset; }
+ void SetYOffset(sal_uInt16 nNewOffset) { nOfsY = nNewOffset; }
+ void SetStartIntens(sal_uInt16 nNewIntens) { nIntensStart = nNewIntens; }
+ void SetEndIntens(sal_uInt16 nNewIntens) { nIntensEnd = nNewIntens; }
+ void SetSteps(sal_uInt16 nSteps) { nStepCount = nSteps; }
+
+ css::awt::GradientStyle GetGradientStyle() const { return eStyle; }
+ const basegfx::BColorStops& GetColorStops() const { return aColorStops; }
+ Degree10 GetAngle() const { return nAngle; }
+ sal_uInt16 GetBorder() const { return nBorder; }
+ sal_uInt16 GetXOffset() const { return nOfsX; }
+ sal_uInt16 GetYOffset() const { return nOfsY; }
+ sal_uInt16 GetStartIntens() const { return nIntensStart; }
+ sal_uInt16 GetEndIntens() const { return nIntensEnd; }
+ sal_uInt16 GetSteps() const { return nStepCount; }
+
+ boost::property_tree::ptree dumpAsJSON() const;
+ static BGradient fromJSON(std::u16string_view rJSON);
+
+ // Tooling to handle
+ // - border correction/integration
+ // - apply StartStopIntensity to color stops
+ // - convert type from 'axial' to linear
+ // - apply Steps as 'hard' color stops
+ void tryToRecreateBorder(basegfx::BColorStops* pAssociatedTransparencyStops = nullptr);
+ void tryToApplyBorder();
+ void tryToApplyStartEndIntensity();
+
+ // If a linear gradient is symmetrical it is converted to an axial gradient.
+ // Does nothing in other cases and for other gradient types.
+ void tryToConvertToAxial();
+ void tryToApplyAxial();
+ void tryToApplySteps();
+};
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/utils/canvastools.hxx b/include/basegfx/utils/canvastools.hxx
new file mode 100644
index 0000000000..4646609772
--- /dev/null
+++ b/include/basegfx/utils/canvastools.hxx
@@ -0,0 +1,167 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+
+namespace com::sun::star::geometry
+{
+ struct AffineMatrix2D;
+ struct AffineMatrix3D;
+ struct RealPoint2D;
+ struct RealSize2D;
+ struct RealRectangle2D;
+ struct RealRectangle3D;
+ struct IntegerSize2D;
+ struct IntegerRectangle2D;
+ struct RealBezierSegment2D;
+}
+
+namespace com::sun::star::rendering
+{
+ class XGraphicDevice;
+ class XPolyPolygon2D;
+}
+
+namespace com::sun::star::awt
+{
+ struct Rectangle;
+}
+
+namespace basegfx
+{
+ class B2DHomMatrix;
+ class B3DHomMatrix;
+ class B2DVector;
+ class B2DPoint;
+ class B2DRange;
+ class B3DRange;
+ class B2IVector;
+ class B2IRange;
+ class B2DPolygon;
+ class B2DPolyPolygon;
+ class B2DSize;
+ class B2ISize;
+}
+
+namespace basegfx::unotools
+{
+ // Polygon conversions
+
+
+ BASEGFX_DLLPUBLIC css::uno::Reference< css::rendering::XPolyPolygon2D >
+ xPolyPolygonFromB2DPolygon( const css::uno::Reference< css::rendering::XGraphicDevice >& xGraphicDevice,
+ const ::basegfx::B2DPolygon& rPoly );
+
+ BASEGFX_DLLPUBLIC css::uno::Reference< css::rendering::XPolyPolygon2D >
+ xPolyPolygonFromB2DPolyPolygon( const css::uno::Reference< css::rendering::XGraphicDevice >& xGraphicDevice,
+ const ::basegfx::B2DPolyPolygon& rPolyPoly );
+
+
+ css::uno::Sequence<
+ css::uno::Sequence< css::geometry::RealBezierSegment2D > >
+ bezierSequenceSequenceFromB2DPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly );
+
+ css::uno::Sequence<
+ css::uno::Sequence< css::geometry::RealPoint2D > >
+ pointSequenceSequenceFromB2DPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly );
+
+ ::basegfx::B2DPolygon polygonFromPoint2DSequence(
+ const css::uno::Sequence< css::geometry::RealPoint2D >& rPoints );
+
+ BASEGFX_DLLPUBLIC ::basegfx::B2DPolyPolygon polyPolygonFromPoint2DSequenceSequence(
+ const css::uno::Sequence< css::uno::Sequence< css::geometry::RealPoint2D > >& rPoints );
+
+ ::basegfx::B2DPolygon polygonFromBezier2DSequence(
+ const css::uno::Sequence< css::geometry::RealBezierSegment2D >& rPoints );
+
+ BASEGFX_DLLPUBLIC ::basegfx::B2DPolyPolygon polyPolygonFromBezier2DSequenceSequence(
+ const css::uno::Sequence< css::uno::Sequence< css::geometry::RealBezierSegment2D > >& rPoints );
+
+ BASEGFX_DLLPUBLIC ::basegfx::B2DPolyPolygon b2DPolyPolygonFromXPolyPolygon2D(
+ const css::uno::Reference< css::rendering::XPolyPolygon2D >& rPoly );
+
+ // Matrix conversions
+
+
+ BASEGFX_DLLPUBLIC css::geometry::AffineMatrix2D&
+ affineMatrixFromHomMatrix( css::geometry::AffineMatrix2D& matrix,
+ const ::basegfx::B2DHomMatrix& transform);
+
+ css::geometry::AffineMatrix3D& affineMatrixFromHomMatrix3D(
+ css::geometry::AffineMatrix3D& matrix,
+ const ::basegfx::B3DHomMatrix& transform);
+
+ BASEGFX_DLLPUBLIC ::basegfx::B2DHomMatrix&
+ homMatrixFromAffineMatrix( ::basegfx::B2DHomMatrix& transform,
+ const css::geometry::AffineMatrix2D& matrix );
+
+ BASEGFX_DLLPUBLIC ::basegfx::B3DHomMatrix homMatrixFromAffineMatrix3D( const css::geometry::AffineMatrix3D& matrix );
+
+ // Geometry conversions
+
+
+ BASEGFX_DLLPUBLIC css::geometry::RealSize2D size2DFromB2DSize( const ::basegfx::B2DSize& );
+ BASEGFX_DLLPUBLIC css::geometry::RealPoint2D point2DFromB2DPoint( const ::basegfx::B2DPoint& );
+ BASEGFX_DLLPUBLIC css::geometry::RealRectangle2D rectangle2DFromB2DRectangle( const ::basegfx::B2DRange& );
+ BASEGFX_DLLPUBLIC css::geometry::RealRectangle3D rectangle3DFromB3DRectangle( const ::basegfx::B3DRange& );
+
+ BASEGFX_DLLPUBLIC ::basegfx::B2DPoint b2DPointFromRealPoint2D( const css::geometry::RealPoint2D& );
+ BASEGFX_DLLPUBLIC ::basegfx::B2DRange b2DRectangleFromRealRectangle2D( const css::geometry::RealRectangle2D& );
+ ::basegfx::B3DRange b3DRectangleFromRealRectangle3D( const css::geometry::RealRectangle3D& );
+
+ BASEGFX_DLLPUBLIC css::geometry::IntegerSize2D integerSize2DFromB2ISize(basegfx::B2ISize const& rSize);
+
+ BASEGFX_DLLPUBLIC ::basegfx::B2ISize b2ISizeFromIntegerSize2D( const css::geometry::IntegerSize2D& );
+ BASEGFX_DLLPUBLIC ::basegfx::B2IRange b2IRectangleFromIntegerRectangle2D( const css::geometry::IntegerRectangle2D& );
+
+ BASEGFX_DLLPUBLIC ::basegfx::B2IRange b2IRectangleFromAwtRectangle( const css::awt::Rectangle& );
+
+ // Geometry comparisons
+
+
+ /** Return smalltest integer range, which completely contains
+ given floating point range.
+
+ @param rRange
+ Input range. Values must be within the representable
+ bounds of sal_Int32
+
+ @return the closest integer range, which completely
+ contains rRange.
+ */
+ BASEGFX_DLLPUBLIC ::basegfx::B2IRange b2ISurroundingRangeFromB2DRange( const ::basegfx::B2DRange& rRange );
+
+ /** Return smalltest B2DRange with integer values, which
+ completely contains given floating point range.
+
+ @param rRange
+ Input range.
+
+ @return the closest B2DRange with integer coordinates,
+ which completely contains rRange.
+ */
+ BASEGFX_DLLPUBLIC ::basegfx::B2DRange b2DSurroundingIntegerRangeFromB2DRange( const ::basegfx::B2DRange& rRange );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/utils/common.hxx b/include/basegfx/utils/common.hxx
new file mode 100644
index 0000000000..1c11a8bf23
--- /dev/null
+++ b/include/basegfx/utils/common.hxx
@@ -0,0 +1,33 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+namespace basegfx
+{
+// The axis or dimension in a 2D coordinate system
+enum class Axis2D
+{
+ X,
+ Y
+};
+
+} // end of namespace basegfx
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/utils/gradienttools.hxx b/include/basegfx/utils/gradienttools.hxx
new file mode 100644
index 0000000000..d56e73b90d
--- /dev/null
+++ b/include/basegfx/utils/gradienttools.hxx
@@ -0,0 +1,526 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <config_options.h>
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/vector/b2dvector.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/color/bcolor.hxx>
+#include <utility>
+#include <basegfx/basegfxdllapi.h>
+#include <basegfx/utils/bgradient.hxx>
+#include <osl/endian.h>
+
+namespace basegfx { class B2DRange; }
+
+namespace
+{
+ /* Internal helper to convert ::Color from tools::color.hxx to BColor
+ without the need to link against tools library. Be on the
+ safe side by using the same union
+ */
+ struct ColorToBColorConverter
+ {
+ union {
+ sal_uInt32 mValue;
+ struct {
+#ifdef OSL_BIGENDIAN
+ sal_uInt8 T;
+ sal_uInt8 R;
+ sal_uInt8 G;
+ sal_uInt8 B;
+#else
+ sal_uInt8 B;
+ sal_uInt8 G;
+ sal_uInt8 R;
+ sal_uInt8 T;
+#endif
+ };
+ };
+
+ ColorToBColorConverter GetRGBColor() const
+ {
+ return {R, G, B};
+ }
+
+ ColorToBColorConverter(sal_uInt32 nColor)
+ : mValue(nColor)
+ { T=0; }
+
+ constexpr ColorToBColorConverter(sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue)
+ : mValue(sal_uInt32(nBlue) | (sal_uInt32(nGreen) << 8) | (sal_uInt32(nRed) << 16))
+ {}
+
+ explicit ColorToBColorConverter(const basegfx::BColor& rBColor)
+ : ColorToBColorConverter(
+ sal_uInt8(std::lround(rBColor.getRed() * 255.0)),
+ sal_uInt8(std::lround(rBColor.getGreen() * 255.0)),
+ sal_uInt8(std::lround(rBColor.getBlue() * 255.0)))
+ {}
+
+ basegfx::BColor getBColor() const
+ {
+ return basegfx::BColor(R / 255.0, G / 255.0, B / 255.0);
+ }
+
+ constexpr explicit operator sal_Int32() const
+ {
+ return sal_Int32(mValue);
+ }
+
+ constexpr explicit operator sal_uInt32() const
+ {
+ return mValue;
+ }
+ };
+}
+
+namespace basegfx
+{
+ /** Gradient definition as used in ODF 1.2
+
+ This struct collects all data necessary for rendering ODF
+ 1.2-compatible gradients. Use the createXXXODFGradientInfo()
+ methods below for initializing from ODF attributes.
+ */
+ class UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC) ODFGradientInfo
+ {
+ private:
+ /** transformation mapping from [0,1]^2 texture coordinate
+ space to [0,1]^2 shape coordinate space
+ */
+ B2DHomMatrix maTextureTransform;
+
+ /** transformation mapping from [0,1]^2 shape coordinate space
+ to [0,1]^2 texture coordinate space. This is the
+ transformation commonly used to create gradients from a
+ scanline rasterizer (put shape u/v coordinates into it, get
+ texture s/t coordinates out of it)
+ */
+ B2DHomMatrix maBackTextureTransform;
+
+ /** Aspect ratio of the gradient. Only used in drawinglayer
+ for generating nested gradient polygons currently. Already
+ catered for in the transformations above.
+ */
+ double mfAspectRatio;
+
+ /** Requested gradient steps to render. See the
+ implementations of the getXXXGradientAlpha() methods below,
+ the semantic differs slightly for the different gradient
+ types.
+ */
+ sal_uInt32 mnRequestedSteps;
+
+ public:
+ ODFGradientInfo()
+ : mfAspectRatio(1.0),
+ mnRequestedSteps(0)
+ {
+ }
+
+ ODFGradientInfo(
+ B2DHomMatrix aTextureTransform,
+ double fAspectRatio,
+ sal_uInt32 nRequestedSteps)
+ : maTextureTransform(std::move(aTextureTransform)),
+ mfAspectRatio(fAspectRatio),
+ mnRequestedSteps(nRequestedSteps)
+ {
+ }
+
+ ODFGradientInfo(const ODFGradientInfo& rODFGradientInfo)
+ : maTextureTransform(rODFGradientInfo.getTextureTransform()),
+ maBackTextureTransform(rODFGradientInfo.maBackTextureTransform),
+ mfAspectRatio(rODFGradientInfo.getAspectRatio()),
+ mnRequestedSteps(rODFGradientInfo.getRequestedSteps())
+ {
+ }
+
+ ODFGradientInfo& operator=(const ODFGradientInfo& rODFGradientInfo)
+ {
+ maTextureTransform = rODFGradientInfo.getTextureTransform();
+ maBackTextureTransform = rODFGradientInfo.maBackTextureTransform;
+ mfAspectRatio = rODFGradientInfo.getAspectRatio();
+ mnRequestedSteps = rODFGradientInfo.getRequestedSteps();
+
+ return *this;
+ }
+
+ // compare operator
+ bool operator==(const ODFGradientInfo& rGeoTexSvx) const;
+
+ const B2DHomMatrix& getTextureTransform() const { return maTextureTransform; }
+ const B2DHomMatrix& getBackTextureTransform() const;
+ double getAspectRatio() const { return mfAspectRatio; }
+ sal_uInt32 getRequestedSteps() const { return mnRequestedSteps; }
+
+ void setTextureTransform(const B2DHomMatrix& rNew)
+ {
+ maTextureTransform = rNew;
+ maBackTextureTransform.identity();
+ }
+ };
+
+ namespace utils
+ {
+ /* Tooling method to extract data from given BGradient
+ to ColorStops, doing some corrections, partially based
+ on given SingleColor.
+ This is used for export preparations in case these exports
+ do neither support Start/EndIntensity nor Border settings,
+ both will be eliminated if possible (see below).
+ The BGradient rGradient and BColorStops& rColorStops
+ are both return parameters and may be changed.
+ This will do quite some preparations for the gradient
+ as follows:
+ - It will check for single color (resetting rSingleColor when
+ this is the case) and return with empty ColorStops
+ - It will blend ColorStops to Intensity if StartIntensity/
+ EndIntensity != 100 is set in BGradient, so applying
+ that value(s) to the gradient directly
+ - It will adapt to Border if Border != 0 is set at the
+ given BGradient, so applying that value to the gradient
+ directly
+ */
+ BASEGFX_DLLPUBLIC void prepareColorStops(
+ const basegfx::BGradient& rGradient,
+ BColorStops& rColorStops,
+ BColor& rSingleColor);
+
+ /* Tooling method to synchronize the given ColorStops.
+ The intention is that a color GradientStops and an
+ alpha/transparence GradientStops gets synchronized
+ for export.
+ For the corrections the single values for color and
+ alpha may be used, e.g. when ColorStops is given
+ and not empty, but AlphaStops is empty, it will get
+ synchronized so that it will have the same number and
+ offsets in AlphaStops as in ColorStops, but with
+ the given SingleAlpha as value.
+ At return it guarantees that both have the same
+ number of entries with the same StopOffsets, so
+ that synchronized pair of ColorStops can e.g. be used
+ to export a Gradient with defined/adapted alpha
+ being 'coupled' indirectly using the
+ 'FillTransparenceGradient' method (at import time).
+ */
+ BASEGFX_DLLPUBLIC void synchronizeColorStops(
+ BColorStops& rColorStops,
+ BColorStops& rAlphaStops,
+ const BColor& rSingleColor,
+ const BColor& rSingleAlpha);
+
+ /* Helper to calculate numberOfSteps needed to represent
+ gradient for the given two colors:
+ - to define only based on color distance, give 0 == nRequestedSteps
+ as wanted value, so color distance will be used
+ - if a wanted value of nRequestedSteps is given, it gets synched
+ against the maximum number of steps defined by the color
+ distance of the two colors
+ - a minimum result of 1 is returned which means a single
+ step -> no real gradient
+ */
+ BASEGFX_DLLPUBLIC sal_uInt32 calculateNumberOfSteps(
+ sal_uInt32 nRequestedSteps,
+ const BColor& rStart,
+ const BColor& rEnd);
+
+ /** Create matrix for ODF's linear gradient definition
+
+ Note that odf linear gradients are varying in y direction.
+
+ @param o_rGradientInfo
+ Receives the calculated texture transformation matrix (for
+ use with standard [0,1]x[0,1] texture coordinates)
+
+ @param rTargetArea
+ Output area, needed for aspect ratio calculations and
+ texture transformation
+
+ @param nRequestedSteps
+ Number of gradient steps (from ODF)
+
+ @param fBorder
+ Width of gradient border (from ODF)
+
+ @param fAngle
+ Gradient angle (from ODF)
+ */
+ BASEGFX_DLLPUBLIC ODFGradientInfo createLinearODFGradientInfo(
+ const B2DRange& rTargetArea,
+ sal_uInt32 nRequestedSteps,
+ double fBorder,
+ double fAngle);
+
+
+ /** Calculate linear gradient blend value
+
+ This method generates you the lerp alpha value for
+ blending linearly between gradient start and end color,
+ according to the formula (startCol*(1.0-alpha) + endCol*alpha)
+
+ @param rUV
+ Current uv coordinate. Values outside [0,1] will be
+ clamped. Assumes gradient color varies along the y axis.
+
+ @param rGradInfo
+ Gradient info, for transformation and number of steps
+ */
+ BASEGFX_DLLPUBLIC double getLinearGradientAlpha(const B2DPoint& rUV,
+ const ODFGradientInfo& rGradInfo);
+
+ /** Create matrix for ODF's axial gradient definition
+
+ Note that odf axial gradients are varying in y
+ direction. Note further that you can map the axial
+ gradient to a linear gradient (in case you want or need to
+ avoid an extra gradient renderer), by using
+ createLinearODFGradientInfo() instead, shifting the
+ resulting texture transformation by 0.5 to the top and
+ appending the same stop colors again, but mirrored.
+
+ @param o_rGradientInfo
+ Receives the calculated texture transformation matrix (for
+ use with standard [0,1]x[0,1] texture coordinates)
+
+ @param rTargetArea
+ Output area, needed for aspect ratio calculations and
+ texture transformation
+
+ @param nRequestedSteps
+ Number of gradient steps (from ODF)
+
+ @param fBorder
+ Width of gradient border (from ODF)
+
+ @param fAngle
+ Gradient angle (from ODF)
+ */
+ BASEGFX_DLLPUBLIC ODFGradientInfo createAxialODFGradientInfo(
+ const B2DRange& rTargetArea,
+ sal_uInt32 nRequestedSteps,
+ double fBorder,
+ double fAngle);
+
+
+ /** Calculate axial gradient blend value
+
+ This method generates you the lerp alpha value for
+ blending linearly between gradient start and end color,
+ according to the formula (startCol*(1.0-alpha) + endCol*alpha)
+
+ @param rUV
+ Current uv coordinate. Values outside [0,1] will be
+ clamped. Assumes gradient color varies along the y axis.
+
+ @param rGradInfo
+ Gradient info, for transformation and number of steps
+ */
+ BASEGFX_DLLPUBLIC double getAxialGradientAlpha(const B2DPoint& rUV,
+ const ODFGradientInfo& rGradInfo);
+
+ /** Create matrix for ODF's radial gradient definition
+
+ @param o_rGradientInfo
+ Receives the calculated texture transformation matrix (for
+ use with standard [0,1]x[0,1] texture coordinates)
+
+ @param rTargetArea
+ Output area, needed for aspect ratio calculations and
+ texture transformation
+
+ @param rOffset
+ Gradient offset value (from ODF)
+
+ @param nRequestedSteps
+ Number of gradient steps (from ODF)
+
+ @param fBorder
+ Width of gradient border (from ODF)
+
+ @param fAngle
+ Gradient angle (from ODF)
+ */
+ BASEGFX_DLLPUBLIC ODFGradientInfo createRadialODFGradientInfo(
+ const B2DRange& rTargetArea,
+ const B2DVector& rOffset,
+ sal_uInt32 nRequestedSteps,
+ double fBorder);
+
+
+ /** Calculate radial gradient blend value
+
+ This method generates you the lerp alpha value for
+ blending linearly between gradient start and end color,
+ according to the formula (startCol*(1.0-alpha) + endCol*alpha)
+
+ @param rUV
+ Current uv coordinate. Values outside [0,1] will be
+ clamped.
+
+ @param rGradInfo
+ Gradient info, for transformation and number of steps
+ */
+ BASEGFX_DLLPUBLIC double getRadialGradientAlpha(const B2DPoint& rUV,
+ const ODFGradientInfo& rGradInfo);
+
+ /** Create matrix for ODF's elliptical gradient definition
+
+ @param o_rGradientInfo
+ Receives the calculated texture transformation matrix (for
+ use with standard [0,1]x[0,1] texture coordinates)
+
+ @param rTargetArea
+ Output area, needed for aspect ratio calculations and
+ texture transformation
+
+ @param rOffset
+ Gradient offset value (from ODF)
+
+ @param nRequestedSteps
+ Number of gradient steps (from ODF)
+
+ @param fBorder
+ Width of gradient border (from ODF)
+
+ @param fAngle
+ Gradient angle (from ODF)
+ */
+ BASEGFX_DLLPUBLIC ODFGradientInfo createEllipticalODFGradientInfo(
+ const B2DRange& rTargetArea,
+ const B2DVector& rOffset,
+ sal_uInt32 nRequestedSteps,
+ double fBorder,
+ double fAngle);
+
+
+ /** Calculate elliptical gradient blend value
+
+ This method generates you the lerp alpha value for
+ blending linearly between gradient start and end color,
+ according to the formula (startCol*(1.0-alpha) + endCol*alpha)
+
+ @param rUV
+ Current uv coordinate. Values outside [0,1] will be
+ clamped.
+
+ @param rGradInfo
+ Gradient info, for transformation and number of steps
+ */
+ BASEGFX_DLLPUBLIC double getEllipticalGradientAlpha(const B2DPoint& rUV,
+ const ODFGradientInfo& rGradInfo);
+
+ /** Create matrix for ODF's square gradient definition
+
+ @param o_rGradientInfo
+ Receives the calculated texture transformation matrix (for
+ use with standard [0,1]x[0,1] texture coordinates)
+
+ @param rTargetArea
+ Output area, needed for aspect ratio calculations and
+ texture transformation
+
+ @param rOffset
+ Gradient offset value (from ODF)
+
+ @param nRequestedSteps
+ Number of gradient steps (from ODF)
+
+ @param fBorder
+ Width of gradient border (from ODF)
+
+ @param fAngle
+ Gradient angle (from ODF)
+ */
+ BASEGFX_DLLPUBLIC ODFGradientInfo createSquareODFGradientInfo(
+ const B2DRange& rTargetArea,
+ const B2DVector& rOffset,
+ sal_uInt32 nRequestedSteps,
+ double fBorder,
+ double fAngle);
+
+
+ /** Calculate square gradient blend value
+
+ This method generates you the lerp alpha value for
+ blending linearly between gradient start and end color,
+ according to the formula (startCol*(1.0-alpha) + endCol*alpha)
+
+ @param rUV
+ Current uv coordinate. Values outside [0,1] will be
+ clamped.
+
+ @param rGradInfo
+ Gradient info, for transformation and number of steps
+ */
+ BASEGFX_DLLPUBLIC double getSquareGradientAlpha(const B2DPoint& rUV,
+ const ODFGradientInfo& rGradInfo);
+
+ /** Create matrix for ODF's rectangular gradient definition
+
+ @param o_rGradientInfo
+ Receives the calculated texture transformation matrix (for
+ use with standard [0,1]x[0,1] texture coordinates)
+
+ @param rTargetArea
+ Output area, needed for aspect ratio calculations and
+ texture transformation
+
+ @param rOffset
+ Gradient offset value (from ODF)
+
+ @param nRequestedSteps
+ Number of gradient steps (from ODF)
+
+ @param fBorder
+ Width of gradient border (from ODF)
+
+ @param fAngle
+ Gradient angle (from ODF)
+ */
+ BASEGFX_DLLPUBLIC ODFGradientInfo createRectangularODFGradientInfo(
+ const B2DRange& rTargetArea,
+ const B2DVector& rOffset,
+ sal_uInt32 nRequestedSteps,
+ double fBorder,
+ double fAngle);
+
+
+ /** Calculate rectangular gradient blend value
+
+ This method generates you the lerp alpha value for
+ blending linearly between gradient start and end color,
+ according to the formula (startCol*(1.0-alpha) + endCol*alpha)
+
+ @param rUV
+ Current uv coordinate. Values outside [0,1] will be
+ clamped.
+
+ @param rGradInfo
+ Gradient info, for transformation and number of steps
+ */
+ BASEGFX_DLLPUBLIC double getRectangularGradientAlpha(const B2DPoint& rUV,
+ const ODFGradientInfo& rGradInfo);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/utils/keystoplerp.hxx b/include/basegfx/utils/keystoplerp.hxx
new file mode 100644
index 0000000000..f8a821e7a5
--- /dev/null
+++ b/include/basegfx/utils/keystoplerp.hxx
@@ -0,0 +1,85 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <vector>
+#include <basegfx/basegfxdllapi.h>
+
+namespace com::sun::star::uno {
+ template<typename T> class Sequence;
+}
+
+namespace basegfx::utils
+{
+ /** Lerp in a vector of key stops
+
+ This class holds a key stop vector and provides the
+ functionality to lerp inside it. Useful e.g. for
+ multi-stop gradients, or the SMIL key time activity.
+
+ For those, given a global [0,1] lerp alpha, one need to
+ find the suitable bucket index from key stop vector, and
+ then calculate the relative alpha between the two buckets
+ found.
+ */
+ class BASEGFX_DLLPUBLIC KeyStopLerp
+ {
+ public:
+ typedef std::pair<std::ptrdiff_t,double> ResultType;
+
+ /** Create lerper with given vector of stops
+
+ @param rKeyStops
+
+ Vector of stops, must contain at least two elements
+ (though preferably more, otherwise you probably don't
+ need key stop lerping in the first place). All
+ elements must be of monotonically increasing value.
+ */
+ explicit KeyStopLerp( std::vector<double>&& rKeyStops );
+
+ /** Create lerper with given sequence of stops
+
+ @param rKeyStops
+
+ Sequence of stops, must contain at least two elements
+ (though preferably more, otherwise you probably don't
+ need key stop lerping in the first place). All
+ elements must be of monotonically increasing value.
+ */
+ explicit KeyStopLerp( const css::uno::Sequence<double>& rKeyStops );
+
+ /** Find two nearest bucket index & interpolate
+
+ @param fAlpha
+ Find bucket index i, with keyStops[i] < fAlpha <=
+ keyStops[i+1]. Return new alpha value in [0,1),
+ proportional to fAlpha's position between keyStops[i]
+ and keyStops[i+1]
+ */
+ ResultType lerp(double fAlpha) const;
+
+ private:
+ std::vector<double> maKeyStops;
+ mutable std::ptrdiff_t mnLastIndex;
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/utils/lerp.hxx b/include/basegfx/utils/lerp.hxx
new file mode 100644
index 0000000000..e02b3b0fa5
--- /dev/null
+++ b/include/basegfx/utils/lerp.hxx
@@ -0,0 +1,43 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+namespace basegfx::utils
+{
+ /** Generic linear interpolator
+
+ @tpl ValueType
+ Must have operator+ and operator* defined, and should
+ have value semantics.
+
+ @param t
+ As usual, t must be in the [0,1] range
+ */
+ template< typename ValueType > ValueType lerp( const ValueType& rFrom,
+ const ValueType& rTo,
+ double t )
+ {
+ // This is only to suppress a double->int warning. All other
+ // types should be okay here.
+ return static_cast<ValueType>( (1.0-t)*rFrom + t*rTo );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/utils/rectcliptools.hxx b/include/basegfx/utils/rectcliptools.hxx
new file mode 100644
index 0000000000..af6be75bfc
--- /dev/null
+++ b/include/basegfx/utils/rectcliptools.hxx
@@ -0,0 +1,72 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/types.h>
+#include <basegfx/range/b2ibox.hxx>
+
+
+namespace basegfx::utils
+{
+ namespace RectClipFlags
+ {
+ const sal_uInt32 LEFT = sal_Int32(0x01);
+ const sal_uInt32 RIGHT = sal_Int32(0x02);
+ const sal_uInt32 TOP = sal_Int32(0x04);
+ const sal_uInt32 BOTTOM = sal_Int32(0x08);
+ }
+
+ /** Calc clip mask for Cohen-Sutherland rectangle clip
+
+ This function returns a clip mask used for the
+ Cohen-Sutherland rectangle clip method, where one or more
+ of the lower four bits are set, if the given point is
+ outside one or more of the four half planes defining the
+ rectangle (see RectClipFlags for possible values)
+ */
+ template< class Point, class Rect > inline
+ sal_uInt32 getCohenSutherlandClipFlags( const Point& rP,
+ const Rect& rR )
+ {
+ // maxY | minY | maxX | minX
+ sal_uInt32 clip;
+ clip = (rP.getX() < rR.getMinX()) << 0;
+ clip |= (rP.getX() > rR.getMaxX()) << 1;
+ clip |= (rP.getY() < rR.getMinY()) << 2;
+ clip |= (rP.getY() > rR.getMaxY()) << 3;
+ return clip;
+ }
+
+ /// Cohen-Sutherland mask calculation - overload for boxes.
+ template< class Point > inline
+ sal_uInt32 getCohenSutherlandClipFlags( const Point& rP,
+ const B2IBox& rB )
+ {
+ // maxY | minY | maxX | minX
+ sal_uInt32 clip;
+ clip = (rP.getX() < rB.getMinX()) << 0;
+ clip |= (rP.getX() >= rB.getMaxX()) << 1;
+ clip |= (rP.getY() < rB.getMinY()) << 2;
+ clip |= (rP.getY() >= rB.getMaxY()) << 3;
+ return clip;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/utils/systemdependentdata.hxx b/include/basegfx/utils/systemdependentdata.hxx
new file mode 100644
index 0000000000..9304153c13
--- /dev/null
+++ b/include/basegfx/utils/systemdependentdata.hxx
@@ -0,0 +1,111 @@
+/* -*- 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 <basegfx/basegfxdllapi.h>
+#include <memory>
+#include <map>
+
+namespace basegfx
+{
+ class SystemDependentData;
+ typedef std::shared_ptr<SystemDependentData> SystemDependentData_SharedPtr;
+ typedef std::weak_ptr<SystemDependentData> SystemDependentData_WeakPtr;
+
+ class BASEGFX_DLLPUBLIC SystemDependentDataManager
+ {
+ private:
+ // noncopyable
+ SystemDependentDataManager(const SystemDependentDataManager&) = delete;
+ SystemDependentDataManager& operator=(const SystemDependentDataManager&) = delete;
+
+ public:
+ SystemDependentDataManager();
+ virtual ~SystemDependentDataManager();
+
+ // call from (and with) SystemDependentData objects when start/end/touch
+ // usage is needed
+ virtual void startUsage(basegfx::SystemDependentData_SharedPtr& rData) = 0;
+ virtual void endUsage(basegfx::SystemDependentData_SharedPtr& rData) = 0;
+ virtual void touchUsage(basegfx::SystemDependentData_SharedPtr& rData) = 0;
+
+ // flush all buffered data (e.g. cleanup/shutdown)
+ virtual void flushAll() = 0;
+ };
+
+ class BASEGFX_DLLPUBLIC SystemDependentData
+ {
+ private:
+ // noncopyable
+ SystemDependentData(const SystemDependentData&) = delete;
+ SystemDependentData& operator=(const SystemDependentData&) = delete;
+
+ // reference to a SystemDependentDataManager, probably
+ // a single, globally used one, but not necessarily
+ SystemDependentDataManager& mrSystemDependentDataManager;
+
+ // Buffered CalculatedCycles, result of estimations using
+ // getHoldCyclesInSeconds and estimateUsageInBytes, executed
+ // using getHoldCyclesInSeconds. StartValue is 0 to detect
+ // not-yet-calculated state
+ sal_uInt32 mnCalculatedCycles;
+
+ public:
+ SystemDependentData(
+ SystemDependentDataManager& rSystemDependentDataManager);
+
+ // CAUTION! It is VERY important to keep this base class
+ // virtual, else typeid(class).hash_code() from derived classes
+ // will NOT work what is ESSENTIAL for the SystemDependentData
+ // mechanism to work properly. So DO NOT REMOVE virtual here, please.
+ virtual ~SystemDependentData();
+
+ // allow access to call startUsage/endUsage/touchUsage
+ // using getSystemDependentDataManager()
+ SystemDependentDataManager& getSystemDependentDataManager() { return mrSystemDependentDataManager; }
+
+ // Calculate HoldCyclesInSeconds based on using
+ // getHoldCyclesInSeconds and estimateUsageInBytes, the
+ // result is created once on-demand and buffered in
+ // mnCalculatedCycles
+ sal_uInt32 calculateCombinedHoldCyclesInSeconds() const;
+
+ // Allow read access to the calculated cycles in seconds, this
+ // can be e.g. used to determine if this instance got added
+ sal_uInt32 getCombinedHoldCyclesInSeconds() const { return mnCalculatedCycles; }
+
+ // Size estimation of the entry in bytes - does not have to
+ // be used, but should be. Default returns zero what
+ // means there is no size estimation available. Override to
+ // offer useful data if you want to have better caching.
+ virtual sal_Int64 estimateUsageInBytes() const;
+ };
+
+ class BASEGFX_DLLPUBLIC SystemDependentDataHolder
+ {
+ private:
+ // Possibility to hold System-Dependent B2DPolygon-Representations
+ std::map< size_t, SystemDependentData_WeakPtr > maSystemDependentReferences;
+
+ // noncopyable
+ SystemDependentDataHolder(const SystemDependentDataHolder&) = delete;
+ SystemDependentDataHolder& operator=(const SystemDependentDataHolder&) = delete;
+
+ public:
+ SystemDependentDataHolder();
+ virtual ~SystemDependentDataHolder();
+
+ void addOrReplaceSystemDependentData(SystemDependentData_SharedPtr& rData);
+ SystemDependentData_SharedPtr getSystemDependentData(size_t hash_code) const;
+ };
+} // end of namespace basegfx
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/utils/tools.hxx b/include/basegfx/utils/tools.hxx
new file mode 100644
index 0000000000..f8fc619995
--- /dev/null
+++ b/include/basegfx/utils/tools.hxx
@@ -0,0 +1,124 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/types.h>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ class B2DPoint;
+ class B2DRange;
+ class B2DPolyPolygon;
+}
+
+namespace basegfx::utils
+{
+ /** Expand given parallelogram, such that it extends beyond
+ bound rect in a given direction.
+
+ This method is useful when e.g. generating one-dimensional
+ gradients, such as linear or axial gradients: those
+ gradients vary only in one direction, the other has
+ constant color. Most of the time, those gradients extends
+ infinitely in the direction with the constant color, but
+ practically, one always has a limiting bound rect into
+ which the gradient is painted. The method at hand now
+ extends a given parallelogram (e.g. the transformed
+ bounding box of a gradient) virtually into infinity to the
+ top and to the bottom (i.e. normal to the line io_rLeftTop
+ io_rRightTop), such that the given rectangle is guaranteed
+ to be covered in that direction.
+
+ @attention There might be some peculiarities with this
+ method, that might limit its usage to the described
+ gradients. One of them is the fact that when determining
+ how far the parallelogram has to be extended to the top or
+ the bottom, the upper and lower border are assumed to be
+ infinite lines.
+
+ @param io_rLeftTop
+ Left, top edge of the parallelogramm. Note that this need
+ not be the left, top edge geometrically, it's just used
+ when determining the extension direction. Thus, it's
+ perfectly legal to affine-transform a rectangle, and given
+ the transformed point here. On method return, this
+ parameter will contain the adapted output.
+
+ @param io_rLeftBottom
+ Left, bottom edge of the parallelogramm. Note that this need
+ not be the left, bottom edge geometrically, it's just used
+ when determining the extension direction. Thus, it's
+ perfectly legal to affine-transform a rectangle, and given
+ the transformed point here. On method return, this
+ parameter will contain the adapted output.
+
+ @param io_rRightTop
+ Right, top edge of the parallelogramm. Note that this need
+ not be the right, top edge geometrically, it's just used
+ when determining the extension direction. Thus, it's
+ perfectly legal to affine-transform a rectangle, and given
+ the transformed point here. On method return, this
+ parameter will contain the adapted output.
+
+ @param io_rRightBottom
+ Right, bottom edge of the parallelogramm. Note that this need
+ not be the right, bottom edge geometrically, it's just used
+ when determining the extension direction. Thus, it's
+ perfectly legal to affine-transform a rectangle, and given
+ the transformed point here. On method return, this
+ parameter will contain the adapted output.
+
+ @param rFitTarget
+ The rectangle to fit the parallelogram into.
+ */
+ BASEGFX_DLLPUBLIC void infiniteLineFromParallelogram( ::basegfx::B2DPoint& io_rLeftTop,
+ ::basegfx::B2DPoint& io_rLeftBottom,
+ ::basegfx::B2DPoint& io_rRightTop,
+ ::basegfx::B2DPoint& io_rRightBottom,
+ const ::basegfx::B2DRange& rFitTarget );
+
+ /** Creates polypolygon with the given number as seven-segment
+ digits
+
+ @param fVal
+ Value to convert
+
+ @param nTotalDigits
+ Total number of digits to display. If less is needed for
+ given number, fill space with blanks.
+
+ @param nDecPlaces
+ Decimal places to show. When 0, display as integer. When
+ negative, fill given number of before-the-decimal point
+ with zero.
+
+ @param bLitSegments
+ When true, return a polygon containing the segments that
+ are 'lit' for the given number. Return un-lit segments
+ otherwise.
+ */
+ BASEGFX_DLLPUBLIC B2DPolyPolygon number2PolyPolygon(double fVal,
+ sal_Int32 nTotalDigits,
+ sal_Int32 nDecPlaces,
+ bool bLitSegments=true);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/utils/unopolypolygon.hxx b/include/basegfx/utils/unopolypolygon.hxx
new file mode 100644
index 0000000000..48788b074e
--- /dev/null
+++ b/include/basegfx/utils/unopolypolygon.hxx
@@ -0,0 +1,104 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <comphelper/compbase.hxx>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/rendering/FillRule.hpp>
+#include <com/sun/star/rendering/XLinePolyPolygon2D.hpp>
+#include <com/sun/star/rendering/XBezierPolyPolygon2D.hpp>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/basegfxdllapi.h>
+#include <o3tl/safeint.hxx>
+
+namespace basegfx::unotools
+{
+ typedef comphelper::WeakComponentImplHelper<
+ css::rendering::XLinePolyPolygon2D,
+ css::rendering::XBezierPolyPolygon2D,
+ css::lang::XServiceInfo > UnoPolyPolygonBase;
+
+ class BASEGFX_DLLPUBLIC UnoPolyPolygon
+ : public UnoPolyPolygonBase
+ {
+ public:
+ explicit UnoPolyPolygon( B2DPolyPolygon );
+
+ // XPolyPolygon2D
+ SAL_DLLPRIVATE virtual void SAL_CALL addPolyPolygon( const css::geometry::RealPoint2D& position, const css::uno::Reference< css::rendering::XPolyPolygon2D >& polyPolygon ) override;
+ SAL_DLLPRIVATE virtual ::sal_Int32 SAL_CALL getNumberOfPolygons( ) override;
+ SAL_DLLPRIVATE virtual ::sal_Int32 SAL_CALL getNumberOfPolygonPoints( ::sal_Int32 polygon ) override;
+ SAL_DLLPRIVATE virtual css::rendering::FillRule SAL_CALL getFillRule( ) override;
+ SAL_DLLPRIVATE virtual void SAL_CALL setFillRule( css::rendering::FillRule fillRule ) override;
+ SAL_DLLPRIVATE virtual sal_Bool SAL_CALL isClosed( ::sal_Int32 index ) override;
+ SAL_DLLPRIVATE virtual void SAL_CALL setClosed( ::sal_Int32 index, sal_Bool closedState ) override;
+
+ // XLinePolyPolygon2D
+ SAL_DLLPRIVATE virtual css::uno::Sequence< css::uno::Sequence< css::geometry::RealPoint2D > > SAL_CALL getPoints( ::sal_Int32 nPolygonIndex, ::sal_Int32 nNumberOfPolygons, ::sal_Int32 nPointIndex, ::sal_Int32 nNumberOfPoints ) override;
+ SAL_DLLPRIVATE virtual void SAL_CALL setPoints( const css::uno::Sequence< css::uno::Sequence< css::geometry::RealPoint2D > >& points, ::sal_Int32 nPolygonIndex ) override;
+ SAL_DLLPRIVATE virtual css::geometry::RealPoint2D SAL_CALL getPoint( ::sal_Int32 nPolygonIndex, ::sal_Int32 nPointIndex ) override;
+ SAL_DLLPRIVATE virtual void SAL_CALL setPoint( const css::geometry::RealPoint2D& point, ::sal_Int32 nPolygonIndex, ::sal_Int32 nPointIndex ) override;
+
+ // XBezierPolyPolygon2D
+ SAL_DLLPRIVATE virtual css::uno::Sequence< css::uno::Sequence< css::geometry::RealBezierSegment2D > > SAL_CALL getBezierSegments( ::sal_Int32 nPolygonIndex, ::sal_Int32 nNumberOfPolygons, ::sal_Int32 nPointIndex, ::sal_Int32 nNumberOfPoints ) override;
+ SAL_DLLPRIVATE virtual void SAL_CALL setBezierSegments( const css::uno::Sequence< css::uno::Sequence< css::geometry::RealBezierSegment2D > >& points, ::sal_Int32 nPolygonIndex ) override;
+ SAL_DLLPRIVATE virtual css::geometry::RealBezierSegment2D SAL_CALL getBezierSegment( ::sal_Int32 nPolygonIndex, ::sal_Int32 nPointIndex ) override;
+ SAL_DLLPRIVATE virtual void SAL_CALL setBezierSegment( const css::geometry::RealBezierSegment2D& point, ::sal_Int32 nPolygonIndex, ::sal_Int32 nPointIndex ) override;
+
+ // XServiceInfo
+ SAL_DLLPRIVATE virtual OUString SAL_CALL getImplementationName() override;
+ SAL_DLLPRIVATE virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ SAL_DLLPRIVATE virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+
+ SAL_DLLPRIVATE B2DPolyPolygon getPolyPolygon() const;
+
+ protected:
+ /// Check whether index is a valid polygon index
+ void checkIndex( sal_Int32 nIndex ) const // throw (css::lang::IndexOutOfBoundsException);
+ {
+ if( nIndex < 0 || o3tl::make_unsigned(nIndex) >= maPolyPoly.count() )
+ throw css::lang::IndexOutOfBoundsException();
+ }
+
+ SAL_DLLPRIVATE B2DPolyPolygon getSubsetPolyPolygon( sal_Int32 nPolygonIndex,
+ sal_Int32 nNumberOfPolygons,
+ sal_Int32 nPointIndex,
+ sal_Int32 nNumberOfPoints ) const;
+
+ /// Get cow copy of internal polygon. not thread-safe outside this object.
+ const B2DPolyPolygon& getPolyPolygonUnsafe() const
+ {
+ return maPolyPoly;
+ }
+
+ /// Called whenever internal polypolygon gets modified
+ virtual void modifying() const {}
+
+ private:
+ UnoPolyPolygon(const UnoPolyPolygon&) = delete;
+ UnoPolyPolygon& operator=(const UnoPolyPolygon&) = delete;
+
+ B2DPolyPolygon maPolyPoly;
+ css::rendering::FillRule meFillRule;
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/utils/zoomtools.hxx b/include/basegfx/utils/zoomtools.hxx
new file mode 100644
index 0000000000..16a36448af
--- /dev/null
+++ b/include/basegfx/utils/zoomtools.hxx
@@ -0,0 +1,22 @@
+/* -*- 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/basegfxdllapi.h>
+
+namespace basegfx::zoomtools
+{
+/** This namespace provides functions for optimized geometric zooming
+*/
+BASEGFX_DLLPUBLIC sal_uInt16 zoomOut(sal_uInt16 nCurrent);
+BASEGFX_DLLPUBLIC sal_uInt16 zoomIn(sal_uInt16 nCurrent);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */