summaryrefslogtreecommitdiff
path: root/include/basegfx
diff options
context:
space:
mode:
authorBjoern Michaelsen <bjoern.michaelsen@canonical.com>2013-04-18 18:26:28 +0200
committerBjoern Michaelsen <bjoern.michaelsen@canonical.com>2013-04-23 22:20:31 +0200
commitb9337e22ce1dbf2eba0e8c8db294ae99f4111f91 (patch)
tree53ee1bd3dfd213815a21579151983cb997922b05 /include/basegfx
parentf4e1642a1761d5eab6ccdd89928869c2b2f1528a (diff)
execute move of global headers
see https://gerrit.libreoffice.org/#/c/3367/ and Change-Id: I00c96fa77d04b33a6f8c8cd3490dfcd9bdc9e84a for details Change-Id: I199a75bc4042af20817265d5ef85b1134a96ff5a
Diffstat (limited to 'include/basegfx')
-rw-r--r--include/basegfx/basegfxdllapi.h42
-rw-r--r--include/basegfx/color/bcolor.hxx229
-rw-r--r--include/basegfx/color/bcolormodifier.hxx137
-rw-r--r--include/basegfx/color/bcolortools.hxx52
-rw-r--r--include/basegfx/curve/b2dbeziertools.hxx57
-rw-r--r--include/basegfx/curve/b2dcubicbezier.hxx200
-rw-r--r--include/basegfx/matrix/b2dhommatrix.hxx139
-rw-r--r--include/basegfx/matrix/b2dhommatrixtools.hxx225
-rw-r--r--include/basegfx/matrix/b3dhommatrix.hxx155
-rw-r--r--include/basegfx/numeric/ftools.hxx198
-rw-r--r--include/basegfx/pixel/bpixel.hxx217
-rw-r--r--include/basegfx/point/b2dpoint.hxx146
-rw-r--r--include/basegfx/point/b2ipoint.hxx117
-rw-r--r--include/basegfx/point/b3dpoint.hxx145
-rw-r--r--include/basegfx/point/b3ipoint.hxx129
-rw-r--r--include/basegfx/polygon/b2dlinegeometry.hxx141
-rw-r--r--include/basegfx/polygon/b2dpolygon.hxx230
-rw-r--r--include/basegfx/polygon/b2dpolygonclipper.hxx70
-rw-r--r--include/basegfx/polygon/b2dpolygoncutandtouch.hxx58
-rw-r--r--include/basegfx/polygon/b2dpolygontools.hxx442
-rw-r--r--include/basegfx/polygon/b2dpolygontriangulator.hxx43
-rw-r--r--include/basegfx/polygon/b2dpolypolygon.hxx137
-rw-r--r--include/basegfx/polygon/b2dpolypolygoncutter.hxx153
-rw-r--r--include/basegfx/polygon/b2dpolypolygonfillrule.hxx54
-rw-r--r--include/basegfx/polygon/b2dpolypolygontools.hxx236
-rw-r--r--include/basegfx/polygon/b2dtrapezoid.hxx124
-rw-r--r--include/basegfx/polygon/b3dpolygon.hxx130
-rw-r--r--include/basegfx/polygon/b3dpolygontools.hxx135
-rw-r--r--include/basegfx/polygon/b3dpolypolygon.hxx117
-rw-r--r--include/basegfx/polygon/b3dpolypolygontools.hxx133
-rw-r--r--include/basegfx/range/b1drange.hxx174
-rw-r--r--include/basegfx/range/b1ibox.hxx164
-rw-r--r--include/basegfx/range/b1irange.hxx169
-rw-r--r--include/basegfx/range/b2dconnectedranges.hxx257
-rw-r--r--include/basegfx/range/b2dpolyrange.hxx94
-rw-r--r--include/basegfx/range/b2drange.hxx320
-rw-r--r--include/basegfx/range/b2drangeclipper.hxx45
-rw-r--r--include/basegfx/range/b2drectangle.hxx36
-rw-r--r--include/basegfx/range/b2ibox.hxx261
-rw-r--r--include/basegfx/range/b2irange.hxx287
-rw-r--r--include/basegfx/range/b2irectangle.hxx36
-rw-r--r--include/basegfx/range/b3drange.hxx273
-rw-r--r--include/basegfx/range/b3irange.hxx240
-rw-r--r--include/basegfx/range/basicbox.hxx127
-rw-r--r--include/basegfx/range/basicrange.hxx278
-rw-r--r--include/basegfx/raster/bpixelraster.hxx99
-rw-r--r--include/basegfx/raster/bzpixelraster.hxx90
-rw-r--r--include/basegfx/raster/rasterconvert3d.hxx340
-rw-r--r--include/basegfx/tools/b2dclipstate.hxx94
-rw-r--r--include/basegfx/tools/canvastools.hxx205
-rw-r--r--include/basegfx/tools/gradienttools.hxx405
-rw-r--r--include/basegfx/tools/keystoplerp.hxx92
-rw-r--r--include/basegfx/tools/lerp.hxx51
-rw-r--r--include/basegfx/tools/rectcliptools.hxx96
-rw-r--r--include/basegfx/tools/tools.hxx102
-rw-r--r--include/basegfx/tools/unopolypolygon.hxx110
-rw-r--r--include/basegfx/tools/unotools.hxx40
-rw-r--r--include/basegfx/tools/zoomtools.hxx50
-rw-r--r--include/basegfx/tuple/b2dtuple.hxx352
-rw-r--r--include/basegfx/tuple/b2i64tuple.hxx305
-rw-r--r--include/basegfx/tuple/b2ituple.hxx208
-rw-r--r--include/basegfx/tuple/b3dtuple.hxx421
-rw-r--r--include/basegfx/tuple/b3i64tuple.hxx336
-rw-r--r--include/basegfx/tuple/b3ituple.hxx335
-rw-r--r--include/basegfx/vector/b2dsize.hxx36
-rw-r--r--include/basegfx/vector/b2dvector.hxx254
-rw-r--r--include/basegfx/vector/b2enums.hxx70
-rw-r--r--include/basegfx/vector/b2isize.hxx36
-rw-r--r--include/basegfx/vector/b2ivector.hxx146
-rw-r--r--include/basegfx/vector/b3dvector.hxx322
-rw-r--r--include/basegfx/vector/b3ivector.hxx249
71 files changed, 11996 insertions, 0 deletions
diff --git a/include/basegfx/basegfxdllapi.h b/include/basegfx/basegfxdllapi.h
new file mode 100644
index 000000000000..b71f0755d277
--- /dev/null
+++ b/include/basegfx/basegfxdllapi.h
@@ -0,0 +1,42 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_BASEGFXDLLAPI_H
+#define INCLUDED_BASEGFXDLLAPI_H
+
+#if defined BASEGFX_STATICLIBRARY
+
+#define BASEGFX_DLLPUBLIC
+#define BASEGFX_DLLPRIVATE
+
+#else /*BASEGFX_STATICLIBRARY*/
+
+#if defined BASEGFX_DLLIMPLEMENTATION
+#define BASEGFX_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
+#else
+#define BASEGFX_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
+#endif
+#define BASEGFX_DLLPRIVATE SAL_DLLPRIVATE
+
+#endif /*BASEGFX_STATICLIBRARY*/
+
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/color/bcolor.hxx b/include/basegfx/color/bcolor.hxx
new file mode 100644
index 000000000000..9b91e212ec89
--- /dev/null
+++ b/include/basegfx/color/bcolor.hxx
@@ -0,0 +1,229 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_COLOR_BCOLOR_HXX
+#define _BGFX_COLOR_BCOLOR_HXX
+
+#include <basegfx/tuple/b3dtuple.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <vector>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+// predeclarations
+
+namespace com { namespace sun { namespace star { namespace rendering {
+ class XGraphicDevice;
+}}}}
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ /** Base Color class with three double values
+
+ This class derives all operators and common handling for
+ a 3D data class from B3DTuple. All necessary extensions
+ which are special for colors will be added here.
+
+ @see B3DTuple
+ */
+ class BASEGFX_DLLPUBLIC SAL_WARN_UNUSED BColor : public B3DTuple
+ {
+ public:
+ /** Create a Color with red, green and blue components from [0.0 to 1.0]
+
+ The color is initialized to (0.0, 0.0, 0.0)
+ */
+ BColor()
+ : B3DTuple()
+ {}
+
+ /** Create a 3D Color
+
+ @param fRed
+ @param fGreen
+ @param fBlue
+ These parameters are used to initialize the red, green and blue intensities of the color
+ */
+ BColor(double fRed, double fGreen, double fBlue)
+ : B3DTuple(fRed, fGreen, fBlue)
+ {}
+
+ /** Create a 3D Color
+
+ @param fLuminosity
+ The parameter is used to initialize the red, green and blue intensities of the color
+ */
+ explicit BColor(double fLuminosity)
+ : B3DTuple(fLuminosity, fLuminosity, fLuminosity)
+ {}
+
+ /** Create a copy of a Color
+
+ @param rVec
+ The Color which will be copied.
+ */
+ BColor(const BColor& rVec)
+ : B3DTuple(rVec)
+ {}
+
+ /** constructor with tuple to allow copy-constructing
+ from B3DTuple-based classes
+ */
+ BColor(const ::basegfx::B3DTuple& rTuple)
+ : B3DTuple(rTuple)
+ {}
+
+ ~BColor()
+ {}
+
+ // data access read
+ double getRed() const { return mfX; }
+ double getGreen() const { return mfY; }
+ double getBlue() const { return mfZ; }
+
+ // data access write
+ void setRed(double fNew) { mfX = fNew; }
+ void setGreen(double fNew) { mfY = fNew; }
+ void setBlue(double fNew) { mfZ = fNew; }
+
+ /** *=operator to allow usage from BColor, too
+ */
+ BColor& operator*=( const BColor& rPnt )
+ {
+ mfX *= rPnt.mfX;
+ mfY *= rPnt.mfY;
+ mfZ *= rPnt.mfZ;
+ return *this;
+ }
+
+ /** *=operator to allow usage from BColor, too
+ */
+ BColor& operator*=(double t)
+ {
+ mfX *= t;
+ mfY *= t;
+ mfZ *= t;
+ return *this;
+ }
+
+ /** assignment operator to allow assigning the results
+ of B3DTuple calculations
+ */
+ BColor& operator=( const ::basegfx::B3DTuple& rVec )
+ {
+ mfX = rVec.getX();
+ mfY = rVec.getY();
+ mfZ = rVec.getZ();
+ return *this;
+ }
+
+ // blend to another color using luminance
+ void blend(const BColor& rColor)
+ {
+ const double fLuminance(luminance());
+ mfX = rColor.getRed() * fLuminance;
+ mfY = rColor.getGreen() * fLuminance;
+ mfZ = rColor.getBlue() * fLuminance;
+ }
+
+ // luminance
+ double luminance() const
+ {
+ const double fRedWeight(77.0 / 256.0); // 0.30
+ const double fGreenWeight(151.0 / 256.0); // 0.59
+ const double fBlueWeight(28.0 / 256.0); // 0.11
+
+ return (mfX * fRedWeight + mfY * fGreenWeight + mfZ * fBlueWeight);
+ }
+
+ // distances in color space
+ double getDistanceRed(const BColor& rColor) const { return (getRed() > rColor.getRed() ? getRed() - rColor.getRed() : rColor.getRed() - getRed()); }
+ double getDistanceGreen(const BColor& rColor) const { return (getGreen() > rColor.getGreen() ? getGreen() - rColor.getGreen() : rColor.getGreen() - getGreen()); }
+ double getDistanceBlue(const BColor& rColor) const { return (getBlue() > rColor.getBlue() ? getBlue() - rColor.getBlue() : rColor.getBlue() - getBlue()); }
+
+ double getDistance(const BColor& rColor) const
+ {
+ const double fDistR(getDistanceRed(rColor));
+ const double fDistG(getDistanceGreen(rColor));
+ const double fDistB(getDistanceBlue(rColor));
+
+ return sqrt(fDistR * fDistR + fDistG * fDistG + fDistB * fDistB);
+ }
+
+ double getMinimumDistance(const BColor& rColor) const
+ {
+ const double fDistR(getDistanceRed(rColor));
+ const double fDistG(getDistanceGreen(rColor));
+ const double fDistB(getDistanceBlue(rColor));
+
+ double fRetval(fDistR < fDistG ? fDistR : fDistG);
+ return (fRetval < fDistB ? fRetval : fDistB);
+ }
+
+ double getMaximumDistance(const BColor& rColor) const
+ {
+ const double fDistR(getDistanceRed(rColor));
+ const double fDistG(getDistanceGreen(rColor));
+ const double fDistB(getDistanceBlue(rColor));
+
+ double fRetval(fDistR > fDistG ? fDistR : fDistG);
+ return (fRetval > fDistB ? fRetval : fDistB);
+ }
+
+ // clamp color to [0.0..1.0] values in all three intensity components
+ void clamp()
+ {
+ mfX = basegfx::clamp(mfX, 0.0, 1.0);
+ mfY = basegfx::clamp(mfY, 0.0, 1.0);
+ mfZ = basegfx::clamp(mfZ, 0.0, 1.0);
+ }
+
+ void invert()
+ {
+ mfX = 1.0 - mfX;
+ mfY = 1.0 - mfY;
+ mfZ = 1.0 - mfZ;
+ }
+
+ static const BColor& getEmptyBColor()
+ {
+ return (const BColor&) ::basegfx::B3DTuple::getEmptyTuple();
+ }
+
+ com::sun::star::uno::Sequence< double > colorToDoubleSequence(const com::sun::star::uno::Reference< com::sun::star::rendering::XGraphicDevice >& /*xGraphicDevice*/) const
+ {
+ com::sun::star::uno::Sequence< double > aRet(4);
+ double* pRet = aRet.getArray();
+
+ pRet[0] = mfX;
+ pRet[1] = mfY;
+ pRet[2] = mfZ;
+ pRet[3] = 1.0;
+
+ return aRet;
+ }
+ };
+} // end of namespace basegfx
+
+#endif /* _BGFX_COLOR_BCOLOR_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/color/bcolormodifier.hxx b/include/basegfx/color/bcolormodifier.hxx
new file mode 100644
index 000000000000..4b6f04efc8e9
--- /dev/null
+++ b/include/basegfx/color/bcolormodifier.hxx
@@ -0,0 +1,137 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_COLOR_BCOLORMODIFIER_HXX
+#define _BGFX_COLOR_BCOLORMODIFIER_HXX
+
+#include <basegfx/color/bcolor.hxx>
+#include <vector>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ /** Descriptor for type of color modification
+ */
+ enum BColorModifyMode
+ {
+ BCOLORMODIFYMODE_REPLACE, // replace all color with local color
+ BCOLORMODIFYMODE_INTERPOLATE, // interpolate color between given and local with local value
+ BCOLORMODIFYMODE_GRAY, // convert color to gray
+ BCOLORMODIFYMODE_BLACKANDWHITE, // convert color to B&W, local value is treshhold
+ BCOLORMODIFYMODE_INVERT, // invert color
+ BCOLORMODIFYMODE_LUMINANCE_TO_ALPHA // convert color to alpha value (used for Svg Mask)
+ };
+
+ /** Class to hold a color, value and mode for a color modification. Color modification is
+ done calling the getModifiedColor() method
+ */
+ class BASEGFX_DLLPUBLIC SAL_WARN_UNUSED BColorModifier
+ {
+ protected:
+ ::basegfx::BColor maBColor;
+ double mfValue;
+ BColorModifyMode meMode;
+
+ public:
+ BColorModifier(
+ const ::basegfx::BColor& rBColor,
+ double fValue = 0.5,
+ BColorModifyMode eMode = BCOLORMODIFYMODE_REPLACE)
+ : maBColor(rBColor),
+ mfValue(fValue),
+ meMode(eMode)
+ {}
+
+ // compare operator(s)
+ bool operator==(const BColorModifier& rCompare) const
+ {
+ return (maBColor == rCompare.maBColor && mfValue == rCompare.mfValue && meMode == rCompare.meMode);
+ }
+
+ bool operator!=(const BColorModifier& rCompare) const
+ {
+ return !(operator==(rCompare));
+ }
+
+ // data access
+ const ::basegfx::BColor& getBColor() const { return maBColor; }
+ double getValue() const { return mfValue; }
+ BColorModifyMode getMode() const { return meMode; }
+
+ // compute modified color
+ ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const;
+ };
+
+ /** Class to hold a stack of BColorModifiers and to get the modified color with
+ applying all existing entry changes
+ */
+ class BASEGFX_DLLPUBLIC BColorModifierStack
+ {
+ protected:
+ ::std::vector< BColorModifier > maBColorModifiers;
+
+ public:
+ sal_uInt32 count() const
+ {
+ return maBColorModifiers.size();
+ }
+
+ const BColorModifier& getBColorModifier(sal_uInt32 nIndex) const
+ {
+ OSL_ENSURE(nIndex < count(), "BColorModifierStack: Access out of range (!)");
+ return maBColorModifiers[nIndex];
+ }
+
+ ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& rSource) const
+ {
+ if(count())
+ {
+ ::basegfx::BColor aRetval(rSource);
+ ::std::vector< BColorModifier >::const_iterator aEnd(maBColorModifiers.end());
+
+ while(aEnd != maBColorModifiers.begin())
+ {
+ aRetval = (--aEnd)->getModifiedColor(aRetval);
+ }
+
+ return aRetval;
+ }
+ else
+ {
+ return rSource;
+ }
+ }
+
+ void push(const BColorModifier& rNew)
+ {
+ maBColorModifiers.push_back(rNew);
+ }
+
+ void pop()
+ {
+ maBColorModifiers.pop_back();
+ }
+ };
+} // end of namespace basegfx
+
+#endif // _BGFX_COLOR_BCOLORMODIFIER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/color/bcolortools.hxx b/include/basegfx/color/bcolortools.hxx
new file mode 100644
index 000000000000..42ac7aafb3cc
--- /dev/null
+++ b/include/basegfx/color/bcolortools.hxx
@@ -0,0 +1,52 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_COLOR_BCOLORTOOLS_HXX
+#define _BGFX_COLOR_BCOLORTOOLS_HXX
+
+#include <sal/types.h>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ class BColor;
+
+ namespace tools
+ {
+ /// Transform from RGB to HSL
+ BASEGFX_DLLPUBLIC BColor rgb2hsl(const BColor& rRGBColor);
+ /// Transform from HSL to RGB
+ BASEGFX_DLLPUBLIC BColor hsl2rgb(const BColor& rHSLColor);
+
+ /// Transform from RGB to HSV
+ BASEGFX_DLLPUBLIC BColor rgb2hsv(const BColor& rRGBColor);
+ /// Transform from HSV to RGB
+ BASEGFX_DLLPUBLIC BColor hsv2rgb(const BColor& rHSVColor);
+
+ /// Transform from Rec. 709 RGB (D65 white point) into CIE XYZ
+ BASEGFX_DLLPUBLIC BColor rgb2ciexyz( const BColor& rRGBColor );
+
+ }
+} // end of namespace basegfx
+
+#endif /* _BGFX_COLOR_BCOLORTOOLS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/curve/b2dbeziertools.hxx b/include/basegfx/curve/b2dbeziertools.hxx
new file mode 100644
index 000000000000..f52f00a1912f
--- /dev/null
+++ b/include/basegfx/curve/b2dbeziertools.hxx
@@ -0,0 +1,57 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_CURVE_B2DBEZIERTOOLS_HXX
+#define _BGFX_CURVE_B2DBEZIERTOOLS_HXX
+
+#include <sal/types.h>
+#include <vector>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+// predefines
+
+namespace basegfx
+{
+ class B2DCubicBezier;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ class BASEGFX_DLLPUBLIC B2DCubicBezierHelper
+ {
+ private:
+ ::std::vector< double > maLengthArray;
+ sal_uInt32 mnEdgeCount;
+
+ public:
+ explicit B2DCubicBezierHelper(const B2DCubicBezier& rBase, sal_uInt32 nDivisions = 9);
+
+ double getLength() const { if(!maLengthArray.empty()) return maLengthArray[maLengthArray.size() - 1]; else return 0.0; }
+ double distanceToRelative(double fDistance) const;
+ };
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif /* _BGFX_CURVE_B2DBEZIERTOOLS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/curve/b2dcubicbezier.hxx b/include/basegfx/curve/b2dcubicbezier.hxx
new file mode 100644
index 000000000000..003a1970bb0a
--- /dev/null
+++ b/include/basegfx/curve/b2dcubicbezier.hxx
@@ -0,0 +1,200 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_CURVE_B2DCUBICBEZIER_HXX
+#define _BGFX_CURVE_B2DCUBICBEZIER_HXX
+
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+// predeclarations
+
+namespace basegfx
+{
+ class B2DPolygon;
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ class BASEGFX_DLLPUBLIC B2DCubicBezier
+ {
+ B2DPoint maStartPoint;
+ B2DPoint maEndPoint;
+ B2DPoint maControlPointA;
+ B2DPoint maControlPointB;
+
+ public:
+ B2DCubicBezier();
+ B2DCubicBezier(const B2DCubicBezier& rBezier);
+ B2DCubicBezier(const B2DPoint& rStart, const B2DPoint& rControlPointA, const B2DPoint& rControlPointB, const B2DPoint& rEnd);
+ ~B2DCubicBezier();
+
+ // assignment operator
+ B2DCubicBezier& operator=(const B2DCubicBezier& rBezier);
+
+ // compare operators
+ bool operator==(const B2DCubicBezier& rBezier) const;
+ bool operator!=(const B2DCubicBezier& rBezier) const;
+ bool equal(const B2DCubicBezier& rBezier) const;
+
+ // test if vectors are used
+ bool isBezier() const;
+
+ // test if contained bezier is trivial and reset vectors accordingly
+ void testAndSolveTrivialBezier();
+
+ /** get length of edge
+
+ This method handles beziers and simple edges. For
+ beziers, the deviation describes the maximum allowed
+ deviation from the real edge length. The default
+ allows a deviation of 1% from the correct length.
+
+ For beziers, there is no direct way to get the length,
+ thus this method may subdivide the bezier edge and may
+ not be cheap.
+
+ @param fDeviation
+ The maximal allowed deviation between correct length
+ and bezier edge length
+
+ @return
+ The length of the edge
+ */
+ double getLength(double fDeviation = 0.01) const;
+
+ // get distance between start and end point
+ double getEdgeLength() const;
+
+ // get length of control polygon
+ double getControlPolygonLength() const;
+
+ // data interface
+ B2DPoint getStartPoint() const { return maStartPoint; }
+ void setStartPoint(const B2DPoint& rValue) { maStartPoint = rValue; }
+
+ B2DPoint getEndPoint() const { return maEndPoint; }
+ void setEndPoint(const B2DPoint& rValue) { maEndPoint = rValue; }
+
+ B2DPoint getControlPointA() const { return maControlPointA; }
+ void setControlPointA(const B2DPoint& rValue) { maControlPointA = rValue; }
+
+ B2DPoint getControlPointB() const { return maControlPointB; }
+ void setControlPointB(const B2DPoint& rValue) { maControlPointB = rValue; }
+
+ /** get the tangent in point t
+
+ This method handles all the exceptions, e.g. when control point
+ A is equal to start point and/or control point B is equal to end
+ point
+
+ @param t
+ The bezier index in the range [0.0 .. 1.0]. It will be truncated.
+
+ @return
+ The tangent vector in point t
+ */
+ B2DVector getTangent(double t) const;
+
+ /** adaptive subdivide by angle criteria
+ no start point is added, but all necessary created edges
+ and the end point
+ #i37443# allow the criteria to get unsharp in recursions
+ */
+ void adaptiveSubdivideByAngle(B2DPolygon& rTarget, double fAngleBound, bool bAllowUnsharpen) const;
+
+ /** #i37443# adaptive subdivide by nCount subdivisions
+ no start point is added, but all necessary created edges
+ and the end point
+ */
+ void adaptiveSubdivideByCount(B2DPolygon& rTarget, sal_uInt32 nCount) const;
+
+ /** Subdivide cubic bezier segment.
+
+ This function adaptively subdivides the bezier
+ segment into as much straight line segments as necessary,
+ such that the maximal orthogonal distance from any of the
+ segments to the true curve is less than the given error
+ value.
+ No start point is added, but all necessary created edges
+ and the end point
+
+ @param rPoly
+ Output polygon. The subdivided bezier segment is added to
+ this polygon via B2DPolygon::append().
+
+ @param rCurve
+ The cubic bezier curve to subdivide
+
+ @param fDistanceBound
+ Bound on the maximal distance of the approximation to the
+ true curve.
+ */
+ void adaptiveSubdivideByDistance(B2DPolygon& rTarget, double fDistanceBound) const;
+
+ // get point at given relative position
+ B2DPoint interpolatePoint(double t) const;
+
+ // calculate the smallest distance from given point to this cubic bezier segment
+ // and return the value. The relative position on the segment is returned in rCut.
+ double getSmallestDistancePointToBezierSegment(const B2DPoint& rTestPoint, double& rCut) const;
+
+ // do a split at position t and fill both resulting segments
+ void split(double t, B2DCubicBezier* pBezierA, B2DCubicBezier* pBezierB) const;
+
+ // extract snippet from fStart to fEnd from this bezier
+ B2DCubicBezier snippet(double fStart, double fEnd) const;
+
+ // get range including conrol points
+ B2DRange getRange() const;
+
+ /** Get the minimum extremum position t
+
+ @param rfResult
+ Will be changed and set to a eventually found split value which should be in the
+ range [0.0 .. 1.0]. It will be the smallest current extremum; there may be more
+
+ @return
+ Returns true if there was at least one extremum found
+ */
+ bool getMinimumExtremumPosition(double& rfResult) const;
+
+ /** Get all extremum pos of this segment
+
+ This method will calculate all extremum positions of the segment
+ and add them to rResults if they are in the range ]0.0 .. 1.0[
+
+ @param rResults
+ The vector of doubles where the results will be added. Evtl.
+ existing contents will be removed since an empty vector is a
+ necessary result to express that there are no extreme positions
+ anymore. Since there is an upper maximum of 4 values, it makes
+ sense to use reserve(4) at the vector as preparation.
+ */
+ void getAllExtremumPositions(::std::vector< double >& rResults) const;
+ };
+} // end of namespace basegfx
+
+#endif /* _BGFX_CURVE_B2DCUBICBEZIER_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/matrix/b2dhommatrix.hxx b/include/basegfx/matrix/b2dhommatrix.hxx
new file mode 100644
index 000000000000..30204b91fad5
--- /dev/null
+++ b/include/basegfx/matrix/b2dhommatrix.hxx
@@ -0,0 +1,139 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_MATRIX_B2DHOMMATRIX_HXX
+#define _BGFX_MATRIX_B2DHOMMATRIX_HXX
+
+#include <sal/types.h>
+#include <o3tl/cow_wrapper.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ class B2DTuple;
+ class Impl2DHomMatrix;
+
+ class BASEGFX_DLLPUBLIC B2DHomMatrix
+ {
+ public:
+ typedef o3tl::cow_wrapper< Impl2DHomMatrix > ImplType;
+
+ private:
+ ImplType mpImpl;
+
+ public:
+ B2DHomMatrix();
+ B2DHomMatrix(const B2DHomMatrix& rMat);
+ ~B2DHomMatrix();
+
+ /** constructor to allow setting all needed values for a 3x2 matrix at once. The
+ parameter f_0x1 e.g. is the same as using set(0, 1, f)
+ */
+ B2DHomMatrix(double f_0x0, double f_0x1, double f_0x2, double f_1x0, double f_1x1, double f_1x2);
+
+ double get(sal_uInt16 nRow, sal_uInt16 nColumn) const;
+ void set(sal_uInt16 nRow, sal_uInt16 nColumn, double fValue);
+
+ /** allow setting all needed values for a 3x2 matrix in one call. The
+ parameter f_0x1 e.g. is the same as using set(0, 1, f)
+ */
+ void set3x2(double f_0x0, double f_0x1, double f_0x2, double f_1x0, double f_1x1, double f_1x2);
+
+ // test if last line is default to see if last line needs to be
+ // involved in calculations
+ bool isLastLineDefault() const;
+
+ // reset to a standard matrix
+ bool isIdentity() const;
+ void identity();
+
+ bool isInvertible() const;
+ bool invert();
+
+ void rotate(double fRadiant);
+
+ void translate(double fX, double fY);
+
+ void scale(double fX, double fY);
+
+ // Shearing-Matrices
+ void shearX(double fSx);
+ void shearY(double fSy);
+
+ B2DHomMatrix& operator+=(const B2DHomMatrix& rMat);
+ B2DHomMatrix& operator-=(const B2DHomMatrix& rMat);
+
+ bool operator==(const B2DHomMatrix& rMat) const;
+ bool operator!=(const B2DHomMatrix& rMat) const;
+
+ B2DHomMatrix& operator*=(double fValue);
+ B2DHomMatrix& operator/=(double fValue);
+
+ // matrix multiplication from the left to the local
+ B2DHomMatrix& operator*=(const B2DHomMatrix& rMat);
+
+ // assignment operator
+ B2DHomMatrix& operator=(const B2DHomMatrix& rMat);
+
+ // Help routine to decompose given homogen 3x3 matrix to components. A correction of
+ // the components is done to avoid inaccuracies.
+ bool decompose(B2DTuple& rScale, B2DTuple& rTranslate, double& rRotate, double& rShearX) const;
+ };
+
+ // addition, subtraction
+ inline B2DHomMatrix operator+(const B2DHomMatrix& rMatA, const B2DHomMatrix& rMatB)
+ {
+ B2DHomMatrix aSum(rMatA);
+ aSum += rMatB;
+ return aSum;
+ }
+
+ inline B2DHomMatrix operator-(const B2DHomMatrix& rMatA, const B2DHomMatrix& rMatB)
+ {
+ B2DHomMatrix aDiv(rMatA);
+ aDiv -= rMatB;
+ return aDiv;
+ }
+
+ // multiplication, division by a constant
+ inline B2DHomMatrix operator*(const B2DHomMatrix& rMat, double fValue)
+ {
+ B2DHomMatrix aNew(rMat);
+ aNew *= fValue;
+ return aNew;
+ }
+
+ inline B2DHomMatrix operator/(const B2DHomMatrix& rMat, double fValue)
+ {
+ B2DHomMatrix aNew(rMat);
+ aNew *= 1.0 / fValue;
+ return aNew;
+ }
+
+ inline B2DHomMatrix operator*(const B2DHomMatrix& rMatA, const B2DHomMatrix& rMatB)
+ {
+ B2DHomMatrix aMul(rMatB);
+ aMul *= rMatA;
+ return aMul;
+ }
+} // end of namespace basegfx
+
+#endif /* _BGFX_MATRIX_B2DHOMMATRIX_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/matrix/b2dhommatrixtools.hxx b/include/basegfx/matrix/b2dhommatrixtools.hxx
new file mode 100644
index 000000000000..ed255360f831
--- /dev/null
+++ b/include/basegfx/matrix/b2dhommatrixtools.hxx
@@ -0,0 +1,225 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_MATRIX_B2DHOMMATRIXTOOLS_HXX
+#define _BGFX_MATRIX_B2DHOMMATRIXTOOLS_HXX
+
+#include <sal/types.h>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/vector/b2dvector.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ namespace tools
+ {
+ /** If the rotation angle is an approximate multiple of pi/2,
+ force fSin/fCos to -1/0/1, to maintain orthogonality (which
+ might also be advantageous for the other cases, but: for
+ multiples of pi/2, the exact values _can_ be attained. It
+ would be largely unintuitive, if a 180 degrees rotation
+ would introduce slight roundoff errors, instead of exactly
+ mirroring the coordinate system)
+ */
+ BASEGFX_DLLPUBLIC void createSinCosOrthogonal(double& o_rSin, double& rCos, double fRadiant);
+
+ /** Tooling methods for on-the-fly matrix generation e.g. for inline
+ multiplications
+ */
+ BASEGFX_DLLPUBLIC B2DHomMatrix createScaleB2DHomMatrix(double fScaleX, double fScaleY);
+ BASEGFX_DLLPUBLIC B2DHomMatrix createShearXB2DHomMatrix(double fShearX);
+ BASEGFX_DLLPUBLIC B2DHomMatrix createShearYB2DHomMatrix(double fShearY);
+ BASEGFX_DLLPUBLIC B2DHomMatrix createRotateB2DHomMatrix(double fRadiant);
+ BASEGFX_DLLPUBLIC B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY);
+
+ /// inline versions for parameters as tuples
+ inline B2DHomMatrix createScaleB2DHomMatrix(const B2DTuple& rScale)
+ {
+ return createScaleB2DHomMatrix(rScale.getX(), rScale.getY());
+ }
+
+ inline B2DHomMatrix createTranslateB2DHomMatrix(const B2DTuple& rTranslate)
+ {
+ return createTranslateB2DHomMatrix(rTranslate.getX(), rTranslate.getY());
+ }
+
+ /** Tooling methods for faster completely combined matrix creation
+ when scale, shearX, rotation and translation needs to be done in
+ exactly that order. It's faster since it direcly calculates
+ each matrix value based on a symbolic calculation of the three
+ matrix multiplications.
+ Inline versions for parameters as tuples added, too.
+ */
+ BASEGFX_DLLPUBLIC B2DHomMatrix createScaleShearXRotateTranslateB2DHomMatrix(
+ double fScaleX, double fScaleY,
+ double fShearX,
+ double fRadiant,
+ double fTranslateX, double fTranslateY);
+ inline B2DHomMatrix createScaleShearXRotateTranslateB2DHomMatrix(
+ const B2DTuple& rScale,
+ double fShearX,
+ double fRadiant,
+ const B2DTuple& rTranslate)
+ {
+ return createScaleShearXRotateTranslateB2DHomMatrix(
+ rScale.getX(), rScale.getY(),
+ fShearX,
+ fRadiant,
+ rTranslate.getX(), rTranslate.getY());
+ }
+
+ BASEGFX_DLLPUBLIC B2DHomMatrix createShearXRotateTranslateB2DHomMatrix(
+ double fShearX,
+ double fRadiant,
+ double fTranslateX, double fTranslateY);
+ inline B2DHomMatrix createShearXRotateTranslateB2DHomMatrix(
+ double fShearX,
+ double fRadiant,
+ const B2DTuple& rTranslate)
+ {
+ return createShearXRotateTranslateB2DHomMatrix(
+ fShearX,
+ fRadiant,
+ rTranslate.getX(), rTranslate.getY());
+ }
+
+ BASEGFX_DLLPUBLIC B2DHomMatrix createScaleTranslateB2DHomMatrix(
+ double fScaleX, double fScaleY,
+ double fTranslateX, double fTranslateY);
+ inline B2DHomMatrix createScaleTranslateB2DHomMatrix(
+ const B2DTuple& rScale,
+ const B2DTuple& rTranslate)
+ {
+ return createScaleTranslateB2DHomMatrix(
+ rScale.getX(), rScale.getY(),
+ rTranslate.getX(), rTranslate.getY());
+ }
+
+ /// special for the often used case of rotation around a point
+ BASEGFX_DLLPUBLIC B2DHomMatrix createRotateAroundPoint(
+ double fPointX, double fPointY,
+ double fRadiant);
+ inline B2DHomMatrix createRotateAroundPoint(
+ const B2DTuple& rPoint,
+ double fRadiant)
+ {
+ return createRotateAroundPoint(
+ rPoint.getX(), rPoint.getY(),
+ fRadiant);
+ }
+
+ } // end of namespace tools
+} // end of namespace basegfx
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ namespace tools
+ {
+ class BASEGFX_DLLPUBLIC B2DHomMatrixBufferedDecompose
+ {
+ private:
+ B2DVector maScale;
+ B2DVector maTranslate;
+ double mfRotate;
+ double mfShearX;
+
+ public:
+ B2DHomMatrixBufferedDecompose(const B2DHomMatrix& rB2DHomMatrix = B2DHomMatrix())
+ : maScale(),
+ maTranslate(),
+ mfRotate(0.0),
+ mfShearX(0.0)
+ {
+ rB2DHomMatrix.decompose(maScale, maTranslate, mfRotate, mfShearX);
+ }
+
+ // data access
+ B2DHomMatrix getB2DHomMatrix() const
+ {
+ return createScaleShearXRotateTranslateB2DHomMatrix(
+ maScale, mfShearX, mfRotate, maTranslate);
+ }
+
+ const B2DVector& getScale() const { return maScale; }
+ const B2DVector& getTranslate() const { return maTranslate; }
+ double getRotate() const { return mfRotate; }
+ double getShearX() const { return mfShearX; }
+ };
+ } // end of namespace tools
+} // end of namespace basegfx
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ namespace tools
+ {
+ class BASEGFX_DLLPUBLIC B2DHomMatrixBufferedOnDemandDecompose
+ {
+ private:
+ B2DHomMatrix maB2DHomMatrix;
+ B2DVector maScale;
+ B2DVector maTranslate;
+ double mfRotate;
+ double mfShearX;
+
+ // bitfield
+ unsigned mbDecomposed : 1;
+
+ void impCheckDecompose()
+ {
+ if(!mbDecomposed)
+ {
+ maB2DHomMatrix.decompose(maScale, maTranslate, mfRotate, mfShearX);
+ mbDecomposed = true;
+ }
+ }
+
+ public:
+ B2DHomMatrixBufferedOnDemandDecompose(const B2DHomMatrix& rB2DHomMatrix = B2DHomMatrix())
+ : maB2DHomMatrix(rB2DHomMatrix),
+ maScale(),
+ maTranslate(),
+ mfRotate(0.0),
+ mfShearX(0.0),
+ mbDecomposed(false)
+ {
+ }
+
+ // data access
+ const B2DHomMatrix& getB2DHomMatrix() const { return maB2DHomMatrix; }
+ const B2DVector& getScale() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return maScale; }
+ const B2DVector& getTranslate() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return maTranslate; }
+ double getRotate() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return mfRotate; }
+ double getShearX() const { const_cast< B2DHomMatrixBufferedOnDemandDecompose* >(this)->impCheckDecompose(); return mfShearX; }
+ };
+ } // end of namespace tools
+
+} // end of namespace basegfx
+
+///////////////////////////////////////////////////////////////////////////////
+
+#endif /* _BGFX_MATRIX_B2DHOMMATRIXTOOLS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/matrix/b3dhommatrix.hxx b/include/basegfx/matrix/b3dhommatrix.hxx
new file mode 100644
index 000000000000..037d400d674f
--- /dev/null
+++ b/include/basegfx/matrix/b3dhommatrix.hxx
@@ -0,0 +1,155 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_MATRIX_B3DHOMMATRIX_HXX
+#define _BGFX_MATRIX_B3DHOMMATRIX_HXX
+
+#include <sal/types.h>
+#include <basegfx/point/b3dpoint.hxx>
+#include <basegfx/vector/b3dvector.hxx>
+#include <o3tl/cow_wrapper.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ class B3DTuple;
+ class Impl3DHomMatrix;
+
+ class BASEGFX_DLLPUBLIC B3DHomMatrix
+ {
+ public:
+ typedef o3tl::cow_wrapper< Impl3DHomMatrix > ImplType;
+
+ private:
+ ImplType mpImpl;
+
+ public:
+ B3DHomMatrix();
+ B3DHomMatrix(const B3DHomMatrix& rMat);
+ ~B3DHomMatrix();
+
+ double get(sal_uInt16 nRow, sal_uInt16 nColumn) const;
+ void set(sal_uInt16 nRow, sal_uInt16 nColumn, double fValue);
+
+ // test if last line is default to see if last line needs to be
+ // involved in calculations
+ bool isLastLineDefault() const;
+
+ bool isIdentity() const;
+ /// Reset to the identity matrix
+ void identity();
+
+ /// Invert the matrix (if possible)
+ bool invert();
+
+ /// Calc the matrix determinant
+ double determinant() const;
+
+ /// Rotation
+ void rotate(double fAngleX,double fAngleY,double fAngleZ);
+
+ /// Translation
+ void translate(double fX, double fY, double fZ);
+
+ /// Scaling
+ void scale(double fX, double fY, double fZ);
+
+ // Shearing-Matrices
+ void shearXY(double fSx, double fSy);
+ void shearXZ(double fSx, double fSz);
+
+ // Projection matrices, used for converting between eye and
+ // clip coordinates
+ void frustum(double fLeft = -1.0, double fRight = 1.0,
+ double fBottom = -1.0, double fTop = 1.0,
+ double fNear = 0.001, double fFar = 1.0);
+
+ void ortho(double fLeft = -1.0, double fRight = 1.0,
+ double fBottom = -1.0, double fTop = 1.0,
+ double fNear = 0.0, double fFar = 1.0);
+
+ // build orientation matrix
+ void orientation(
+ B3DPoint aVRP = B3DPoint(0.0,0.0,1.0),
+ B3DVector aVPN = B3DVector(0.0,0.0,1.0),
+ B3DVector aVUV = B3DVector(0.0,1.0,0.0));
+
+ // addition, subtraction
+ B3DHomMatrix& operator+=(const B3DHomMatrix& rMat);
+ B3DHomMatrix& operator-=(const B3DHomMatrix& rMat);
+
+ // comparison
+ bool operator==(const B3DHomMatrix& rMat) const;
+ bool operator!=(const B3DHomMatrix& rMat) const;
+
+ // multiplication, division by constant value
+ B3DHomMatrix& operator*=(double fValue);
+ B3DHomMatrix& operator/=(double fValue);
+
+ // matrix multiplication (from the left)
+ B3DHomMatrix& operator*=(const B3DHomMatrix& rMat);
+
+ // assignment operator
+ B3DHomMatrix& operator=(const B3DHomMatrix& rMat);
+
+ // decomposition
+ bool decompose(B3DTuple& rScale, B3DTuple& rTranslate, B3DTuple& rRotate, B3DTuple& rShear) const;
+ };
+
+ // addition, subtraction
+ inline B3DHomMatrix operator+(const B3DHomMatrix& rMatA, const B3DHomMatrix& rMatB)
+ {
+ B3DHomMatrix aSum(rMatA);
+ aSum += rMatB;
+ return aSum;
+ }
+
+ inline B3DHomMatrix operator-(const B3DHomMatrix& rMatA, const B3DHomMatrix& rMatB)
+ {
+ B3DHomMatrix aDiv(rMatA);
+ aDiv -= rMatB;
+ return aDiv;
+ }
+
+ // multiplication, division by constant value
+ inline B3DHomMatrix operator*(const B3DHomMatrix& rMat, double fValue)
+ {
+ B3DHomMatrix aNew(rMat);
+ aNew *= fValue;
+ return aNew;
+ }
+
+ inline B3DHomMatrix operator/(const B3DHomMatrix& rMat, double fValue)
+ {
+ B3DHomMatrix aNew(rMat);
+ aNew *= 1.0 / fValue;
+ return aNew;
+ }
+
+ inline B3DHomMatrix operator*(const B3DHomMatrix& rMatA, const B3DHomMatrix& rMatB)
+ {
+ B3DHomMatrix aMul(rMatB);
+ aMul *= rMatA;
+ return aMul;
+ }
+} // end of namespace basegfx
+
+#endif /* _BGFX_MATRIX_B3DHOMMATRIX_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/numeric/ftools.hxx b/include/basegfx/numeric/ftools.hxx
new file mode 100644
index 000000000000..70dcabe1a190
--- /dev/null
+++ b/include/basegfx/numeric/ftools.hxx
@@ -0,0 +1,198 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_NUMERIC_FTOOLS_HXX
+#define _BGFX_NUMERIC_FTOOLS_HXX
+
+#include <rtl/math.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+// standard PI defines from solar.h, but we do not want to link against tools
+
+#ifndef F_PI
+#define F_PI M_PI
+#endif
+#ifndef F_PI2
+#define F_PI2 M_PI_2
+#endif
+#ifndef F_PI4
+#define F_PI4 M_PI_4
+#endif
+#ifndef F_PI180
+#define F_PI180 (M_PI/180.0)
+#endif
+#ifndef F_PI1800
+#define F_PI1800 (M_PI/1800.0)
+#endif
+#ifndef F_PI18000
+#define F_PI18000 (M_PI/18000.0)
+#endif
+#ifndef F_2PI
+#define F_2PI (2.0*M_PI)
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// fTools defines
+
+namespace basegfx
+{
+ /** Round double to nearest integer
+
+ @return the nearest integer
+ */
+ inline sal_Int32 fround( double fVal )
+ {
+ return fVal > 0.0 ? static_cast<sal_Int32>( fVal + .5 ) : -static_cast<sal_Int32>( -fVal + .5 );
+ }
+
+ /** Round double to nearest integer
+
+ @return the nearest 64 bit integer
+ */
+ inline sal_Int64 fround64( double fVal )
+ {
+ return fVal > 0.0 ? static_cast<sal_Int64>( fVal + .5 ) : -static_cast<sal_Int64>( -fVal + .5 );
+ }
+
+ /** Prune a small epsilon range around zero.
+
+ Use this method e.g. for calculating scale values. There, it
+ is usually advisable not to set a scaling to 0.0, because that
+ yields singular transformation matrices.
+
+ @param fVal
+ An arbitrary, but finite and valid number
+
+ @return either fVal, or a small value slightly above (when
+ fVal>0) or below (when fVal<0) zero.
+ */
+ inline double pruneScaleValue( double fVal )
+ {
+ // old version used ::std::min/max, but this collides if min is defined as preprocessor
+ // macro which is the case e.g with windows.h headers. The simplest way to avoid this is to
+ // just use the full comparison. I keep the original here, maybe there will be a better
+ // solution some day.
+ //
+ //return fVal < 0.0 ?
+ // (::std::min(fVal,-0.00001)) :
+ // (::std::max(fVal,0.00001));
+
+ if(fVal < 0.0)
+ return (fVal < -0.00001 ? fVal : -0.00001);
+ else
+ return (fVal > 0.00001 ? fVal : 0.00001);
+ }
+
+ /** clamp given value against given minimum and maximum values
+ */
+ template <class T> inline const T& clamp(const T& value, const T& minimum, const T& maximum)
+ {
+ if(value < minimum)
+ {
+ return minimum;
+ }
+ else if(value > maximum)
+ {
+ return maximum;
+ }
+ else
+ {
+ return value;
+ }
+ }
+
+ /** Convert value from degrees to radians
+ */
+ inline double deg2rad( double v )
+ {
+ // divide first, to get exact values for v being a multiple of
+ // 90 degrees
+ return v / 90.0 * M_PI_2;
+ }
+
+ /** Convert value radians to degrees
+ */
+ inline double rad2deg( double v )
+ {
+ // divide first, to get exact values for v being a multiple of
+ // pi/2
+ return v / M_PI_2 * 90.0;
+ }
+
+
+ class BASEGFX_DLLPUBLIC fTools
+ {
+ /// Threshold value for equalZero()
+ static double mfSmallValue;
+
+ public:
+ /// Get threshold value for equalZero and friends
+ static double getSmallValue() { return mfSmallValue; }
+ /// Set threshold value for equalZero and friends
+ static void setSmallValue(const double& rfNew) { mfSmallValue = rfNew; }
+
+ /// Compare against small value
+ static bool equalZero(const double& rfVal)
+ {
+ return (fabs(rfVal) <= getSmallValue());
+ }
+
+ /// Compare against given small value
+ static bool equalZero(const double& rfVal, const double& rfSmallValue)
+ {
+ return (fabs(rfVal) <= rfSmallValue);
+ }
+
+ static bool equal(const double& rfValA, const double& rfValB)
+ {
+ // changed to approxEqual usage for better numerical correctness
+ return rtl::math::approxEqual(rfValA, rfValB);
+ }
+
+ static bool equal(const double& rfValA, const double& rfValB, const double& rfSmallValue)
+ {
+ return (fabs(rfValA - rfValB) <= rfSmallValue);
+ }
+
+ static bool less(const double& rfValA, const double& rfValB)
+ {
+ return (rfValA < rfValB && !equal(rfValA, rfValB));
+ }
+
+ static bool lessOrEqual(const double& rfValA, const double& rfValB)
+ {
+ return (rfValA < rfValB || equal(rfValA, rfValB));
+ }
+
+ static bool more(const double& rfValA, const double& rfValB)
+ {
+ return (rfValA > rfValB && !equal(rfValA, rfValB));
+ }
+
+ static bool moreOrEqual(const double& rfValA, const double& rfValB)
+ {
+ return (rfValA > rfValB || equal(rfValA, rfValB));
+ }
+ };
+} // end of namespace basegfx
+
+#endif /* _BGFX_NUMERIC_FTOOLS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/pixel/bpixel.hxx b/include/basegfx/pixel/bpixel.hxx
new file mode 100644
index 000000000000..a2c59101fa78
--- /dev/null
+++ b/include/basegfx/pixel/bpixel.hxx
@@ -0,0 +1,217 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_PIXEL_BPIXEL_HXX
+#define _BGFX_PIXEL_BPIXEL_HXX
+
+#include <sal/types.h>
+#include <basegfx/numeric/ftools.hxx>
+#include <basegfx/color/bcolor.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+// predeclarations
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ class BASEGFX_DLLPUBLIC BPixel
+ {
+ protected:
+ union
+ {
+ struct
+ {
+ // bitfield
+ unsigned mnR : 8; // red intensity
+ unsigned mnG : 8; // green intensity
+ unsigned mnB : 8; // blue intensity
+ unsigned mnO : 8; // opacity, 0 == full transparence
+ } maRGBO;
+
+ struct
+ {
+ // bitfield
+ unsigned mnValue : 32; // all values
+ } maCombinedRGBO;
+ } maPixelUnion;
+
+ public:
+ BPixel()
+ {
+ maPixelUnion.maCombinedRGBO.mnValue = 0L;
+ }
+
+ // use explicit here to make sure everyone knows what he is doing. Values range from
+ // 0..255 integer here.
+ explicit BPixel(sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue, sal_uInt8 nOpacity)
+ {
+ maPixelUnion.maRGBO.mnR = nRed;
+ maPixelUnion.maRGBO.mnG = nGreen;
+ maPixelUnion.maRGBO.mnB = nBlue;
+ maPixelUnion.maRGBO.mnO = nOpacity;
+ }
+
+ // constructor from BColor which uses double precision color, so change it
+ // to local integer format. It will also be clamped here.
+ BPixel(const BColor& rColor, sal_uInt8 nOpacity)
+ {
+ maPixelUnion.maRGBO.mnR = sal_uInt8((rColor.getRed() * 255.0) + 0.5);
+ maPixelUnion.maRGBO.mnG = sal_uInt8((rColor.getGreen() * 255.0) + 0.5);
+ maPixelUnion.maRGBO.mnB = sal_uInt8((rColor.getBlue() * 255.0) + 0.5);
+ maPixelUnion.maRGBO.mnO = nOpacity;
+ }
+
+ // copy constructor
+ BPixel(const BPixel& rPixel)
+ {
+ maPixelUnion.maCombinedRGBO.mnValue = rPixel.maPixelUnion.maCombinedRGBO.mnValue;
+ }
+
+ ~BPixel()
+ {}
+
+ // assignment operator
+ BPixel& operator=( const BPixel& rPixel )
+ {
+ maPixelUnion.maCombinedRGBO.mnValue = rPixel.maPixelUnion.maCombinedRGBO.mnValue;
+ return *this;
+ }
+
+ // data access read
+ sal_uInt8 getRed() const { return maPixelUnion.maRGBO.mnR; }
+ sal_uInt8 getGreen() const { return maPixelUnion.maRGBO.mnG; }
+ sal_uInt8 getBlue() const { return maPixelUnion.maRGBO.mnB; }
+ sal_uInt8 getOpacity() const { return maPixelUnion.maRGBO.mnO; }
+ sal_uInt32 getRedGreenBlueOpacity() const { return maPixelUnion.maCombinedRGBO.mnValue; }
+
+ // data access write
+ void setRed(sal_uInt8 nNew) { maPixelUnion.maRGBO.mnR = nNew; }
+ void setGreen(sal_uInt8 nNew) { maPixelUnion.maRGBO.mnG = nNew; }
+ void setBlue(sal_uInt8 nNew) { maPixelUnion.maRGBO.mnB = nNew; }
+ void setOpacity(sal_uInt8 nNew) { maPixelUnion.maRGBO.mnO = nNew; }
+ void setRedGreenBlueOpacity(sal_uInt32 nRedGreenBlueOpacity) { maPixelUnion.maCombinedRGBO.mnValue = nRedGreenBlueOpacity; }
+ void setRedGreenBlue(sal_uInt8 nR, sal_uInt8 nG, sal_uInt8 nB) { maPixelUnion.maRGBO.mnR = nR; maPixelUnion.maRGBO.mnG = nG; maPixelUnion.maRGBO.mnB = nB; }
+
+ // comparators
+ bool isInvisible() const { return (0 == maPixelUnion.maRGBO.mnO); }
+ bool isVisible() const { return (0 != maPixelUnion.maRGBO.mnO); }
+ bool isEmpty() const { return isInvisible(); }
+ bool isUsed() const { return isVisible(); }
+
+ bool operator==( const BPixel& rPixel ) const
+ {
+ return (rPixel.maPixelUnion.maCombinedRGBO.mnValue == maPixelUnion.maCombinedRGBO.mnValue);
+ }
+
+ bool operator!=( const BPixel& rPixel ) const
+ {
+ return (rPixel.maPixelUnion.maCombinedRGBO.mnValue != maPixelUnion.maCombinedRGBO.mnValue);
+ }
+
+ // empty element
+ static const BPixel& getEmptyBPixel();
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // external operators
+
+ inline BPixel minimum(const BPixel& rTupA, const BPixel& rTupB)
+ {
+ BPixel aMin(
+ (rTupB.getRed() < rTupA.getRed()) ? rTupB.getRed() : rTupA.getRed(),
+ (rTupB.getGreen() < rTupA.getGreen()) ? rTupB.getGreen() : rTupA.getGreen(),
+ (rTupB.getBlue() < rTupA.getBlue()) ? rTupB.getBlue() : rTupA.getBlue(),
+ (rTupB.getOpacity() < rTupA.getOpacity()) ? rTupB.getOpacity() : rTupA.getOpacity());
+ return aMin;
+ }
+
+ inline BPixel maximum(const BPixel& rTupA, const BPixel& rTupB)
+ {
+ BPixel aMax(
+ (rTupB.getRed() > rTupA.getRed()) ? rTupB.getRed() : rTupA.getRed(),
+ (rTupB.getGreen() > rTupA.getGreen()) ? rTupB.getGreen() : rTupA.getGreen(),
+ (rTupB.getBlue() > rTupA.getBlue()) ? rTupB.getBlue() : rTupA.getBlue(),
+ (rTupB.getOpacity() > rTupA.getOpacity()) ? rTupB.getOpacity() : rTupA.getOpacity());
+ return aMax;
+ }
+
+ inline BPixel interpolate(const BPixel& rOld1, const BPixel& rOld2, double t)
+ {
+ if(rOld1 == rOld2)
+ {
+ return rOld1;
+ }
+ else if(0.0 >= t)
+ {
+ return rOld1;
+ }
+ else if(1.0 <= t)
+ {
+ return rOld2;
+ }
+ else
+ {
+ const sal_uInt32 nFactor(fround(256.0 * t));
+ const sal_uInt32 nNegFac(256L - nFactor);
+ return BPixel(
+ (sal_uInt8)(((sal_uInt32)rOld1.getRed() * nNegFac + (sal_uInt32)rOld2.getRed() * nFactor) >> 8L),
+ (sal_uInt8)(((sal_uInt32)rOld1.getGreen() * nNegFac + (sal_uInt32)rOld2.getGreen() * nFactor) >> 8L),
+ (sal_uInt8)(((sal_uInt32)rOld1.getBlue() * nNegFac + (sal_uInt32)rOld2.getBlue() * nFactor) >> 8L),
+ (sal_uInt8)(((sal_uInt32)rOld1.getOpacity() * nNegFac + (sal_uInt32)rOld2.getOpacity() * nFactor) >> 8L));
+ }
+ }
+
+ inline BPixel average(const BPixel& rOld1, const BPixel& rOld2)
+ {
+ if(rOld1 == rOld2)
+ {
+ return rOld1;
+ }
+ else
+ {
+ return BPixel(
+ (sal_uInt8)(((sal_uInt32)rOld1.getRed() + (sal_uInt32)rOld2.getRed()) >> 1L),
+ (sal_uInt8)(((sal_uInt32)rOld1.getGreen() + (sal_uInt32)rOld2.getGreen()) >> 1L),
+ (sal_uInt8)(((sal_uInt32)rOld1.getBlue() + (sal_uInt32)rOld2.getBlue()) >> 1L),
+ (sal_uInt8)(((sal_uInt32)rOld1.getOpacity() + (sal_uInt32)rOld2.getOpacity()) >> 1L));
+ }
+ }
+
+ inline BPixel average(const BPixel& rOld1, const BPixel& rOld2, const BPixel& rOld3)
+ {
+ if(rOld1 == rOld2 && rOld2 == rOld3)
+ {
+ return rOld1;
+ }
+ else
+ {
+ return BPixel(
+ (sal_uInt8)(((sal_uInt32)rOld1.getRed() + (sal_uInt32)rOld2.getRed() + (sal_uInt32)rOld3.getRed()) / 3L),
+ (sal_uInt8)(((sal_uInt32)rOld1.getGreen() + (sal_uInt32)rOld2.getGreen() + (sal_uInt32)rOld3.getGreen()) / 3L),
+ (sal_uInt8)(((sal_uInt32)rOld1.getBlue() + (sal_uInt32)rOld2.getBlue() + (sal_uInt32)rOld3.getBlue()) / 3L),
+ (sal_uInt8)(((sal_uInt32)rOld1.getOpacity() + (sal_uInt32)rOld2.getOpacity() + (sal_uInt32)rOld3.getOpacity()) / 3L));
+ }
+ }
+} // end of namespace basegfx
+
+#endif /* _BGFX_PIXEL_BPIXEL_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/point/b2dpoint.hxx b/include/basegfx/point/b2dpoint.hxx
new file mode 100644
index 000000000000..ef73c8ab46c9
--- /dev/null
+++ b/include/basegfx/point/b2dpoint.hxx
@@ -0,0 +1,146 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_POINT_B2DPOINT_HXX
+#define _BGFX_POINT_B2DPOINT_HXX
+
+#include <basegfx/tuple/b2dtuple.hxx>
+#include <basegfx/point/b2ipoint.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ // predeclaration
+ class B2DHomMatrix;
+
+ /** Base Point class with two double values
+
+ This class derives all operators and common handling for
+ a 2D data class from B2DTuple. All necessary extensions
+ which are special for points will be added here.
+
+ @see B2DTuple
+ */
+ class SAL_WARN_UNUSED B2DPoint : public ::basegfx::B2DTuple
+ {
+ public:
+ /** Create a 2D Point
+
+ The point is initialized to (0.0, 0.0)
+ */
+ B2DPoint()
+ : B2DTuple()
+ {}
+
+ /** Create a 2D Point
+
+ @param fX
+ This parameter is used to initialize the X-coordinate
+ of the 2D Point.
+
+ @param fY
+ This parameter is used to initialize the Y-coordinate
+ of the 2D Point.
+ */
+ B2DPoint(double fX, double fY)
+ : B2DTuple(fX, fY)
+ {}
+
+ /** Create a copy of a 2D Point
+
+ @param rPoint
+ The 2D Point which will be copied.
+ */
+ B2DPoint(const B2DPoint& rPoint)
+ : B2DTuple(rPoint)
+ {}
+
+ /** Create a copy of a 2D Point
+
+ @param rPoint
+ The 2D Point which will be copied.
+ */
+ explicit B2DPoint(const ::basegfx::B2IPoint& rPoint)
+ : B2DTuple(rPoint)
+ {}
+
+ /** constructor with tuple to allow copy-constructing
+ from B2DTuple-based classes
+ */
+ B2DPoint(const ::basegfx::B2DTuple& rTuple)
+ : B2DTuple(rTuple)
+ {}
+
+ ~B2DPoint()
+ {}
+
+ /** *=operator to allow usage from B2DPoint, too
+ */
+ B2DPoint& operator*=( const B2DPoint& rPnt )
+ {
+ mfX *= rPnt.mfX;
+ mfY *= rPnt.mfY;
+ return *this;
+ }
+
+ /** *=operator to allow usage from B2DPoint, too
+ */
+ B2DPoint& operator*=(double t)
+ {
+ mfX *= t;
+ mfY *= t;
+ return *this;
+ }
+
+ /** assignment operator to allow assigning the results
+ of B2DTuple calculations
+ */
+ BASEGFX_DLLPUBLIC B2DPoint& operator=( const ::basegfx::B2DTuple& rPoint );
+
+ /** Transform point by given transformation matrix.
+
+ The translational components of the matrix are, in
+ contrast to B2DVector, applied.
+ */
+ BASEGFX_DLLPUBLIC B2DPoint& operator*=( const ::basegfx::B2DHomMatrix& rMat );
+
+ static const B2DPoint& getEmptyPoint()
+ {
+ return (const B2DPoint&) ::basegfx::B2DTuple::getEmptyTuple();
+ }
+ };
+
+ // external operators
+ //////////////////////////////////////////////////////////////////////////
+
+ /** Transform B2DPoint by given transformation matrix.
+
+ Since this is a Point, translational components of the
+ matrix are used.
+ */
+ BASEGFX_DLLPUBLIC B2DPoint operator*( const B2DHomMatrix& rMat, const B2DPoint& rPoint );
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif /* _BGFX_POINT_B2DPOINT_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/point/b2ipoint.hxx b/include/basegfx/point/b2ipoint.hxx
new file mode 100644
index 000000000000..33b225a2a36d
--- /dev/null
+++ b/include/basegfx/point/b2ipoint.hxx
@@ -0,0 +1,117 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_POINT_B2IPOINT_HXX
+#define _BGFX_POINT_B2IPOINT_HXX
+
+#include <basegfx/tuple/b2ituple.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ // predeclaration
+ class B2DHomMatrix;
+
+ /** Base Point class with two sal_Int32 values
+
+ This class derives all operators and common handling for
+ a 2D data class from B2ITuple. All necessary extensions
+ which are special for points will be added here.
+
+ @see B2ITuple
+ */
+ class BASEGFX_DLLPUBLIC SAL_WARN_UNUSED B2IPoint : public ::basegfx::B2ITuple
+ {
+ public:
+ /** Create a 2D Point
+
+ The point is initialized to (0, 0)
+ */
+ B2IPoint()
+ : B2ITuple()
+ {}
+
+ /** Create a 2D Point
+
+ @param nX
+ This parameter is used to initialize the X-coordinate
+ of the 2D Point.
+
+ @param nY
+ This parameter is used to initialize the Y-coordinate
+ of the 2D Point.
+ */
+ B2IPoint(sal_Int32 nX, sal_Int32 nY)
+ : B2ITuple(nX, nY)
+ {}
+
+ /** Create a copy of a 2D Point
+
+ @param rPoint
+ The 2D Point which will be copied.
+ */
+ B2IPoint(const B2IPoint& rPoint)
+ : B2ITuple(rPoint)
+ {}
+
+ /** constructor with tuple to allow copy-constructing
+ from B2ITuple-based classes
+ */
+ B2IPoint(const ::basegfx::B2ITuple& rTuple)
+ : B2ITuple(rTuple)
+ {}
+
+ ~B2IPoint()
+ {}
+
+ /** *=operator to allow usage from B2IPoint, too
+ */
+ B2IPoint& operator*=( const B2IPoint& rPnt )
+ {
+ mnX *= rPnt.mnX;
+ mnY *= rPnt.mnY;
+ return *this;
+ }
+
+ /** *=operator to allow usage from B2IPoint, too
+ */
+ B2IPoint& operator*=(sal_Int32 t)
+ {
+ mnX *= t;
+ mnY *= t;
+ return *this;
+ }
+
+ /** assignment operator to allow assigning the results
+ of B2ITuple calculations
+ */
+ B2IPoint& operator=( const ::basegfx::B2ITuple& rPoint );
+
+ /** Transform point by given transformation matrix.
+
+ The translational components of the matrix are, in
+ contrast to B2DVector, applied.
+ */
+ B2IPoint& operator*=( const ::basegfx::B2DHomMatrix& rMat );
+ };
+} // end of namespace basegfx
+
+#endif /* _BGFX_POINT_B2IPOINT_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/point/b3dpoint.hxx b/include/basegfx/point/b3dpoint.hxx
new file mode 100644
index 000000000000..391bc128b9fb
--- /dev/null
+++ b/include/basegfx/point/b3dpoint.hxx
@@ -0,0 +1,145 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_POINT_B3DPOINT_HXX
+#define _BGFX_POINT_B3DPOINT_HXX
+
+#include <basegfx/tuple/b3dtuple.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ // predeclaration
+ class B3DHomMatrix;
+
+ /** Base Point class with three double values
+
+ This class derives all operators and common handling for
+ a 3D data class from B3DTuple. All necessary extensions
+ which are special for points will be added here.
+
+ @see B3DTuple
+ */
+ class BASEGFX_DLLPUBLIC SAL_WARN_UNUSED B3DPoint : public ::basegfx::B3DTuple
+ {
+ public:
+ /** Create a 3D Point
+
+ The point is initialized to (0.0, 0.0, 0.0)
+ */
+ B3DPoint()
+ : B3DTuple()
+ {}
+
+ /** Create a 3D Point
+
+ @param fX
+ This parameter is used to initialize the X-coordinate
+ of the 3D Point.
+
+ @param fY
+ This parameter is used to initialize the Y-coordinate
+ of the 3D Point.
+
+ @param fZ
+ This parameter is used to initialize the Z-coordinate
+ of the 3D Point.
+ */
+ B3DPoint(double fX, double fY, double fZ)
+ : B3DTuple(fX, fY, fZ)
+ {}
+
+ /** Create a copy of a 3D Point
+
+ @param rVec
+ The 3D Point which will be copied.
+ */
+ B3DPoint(const B3DPoint& rVec)
+ : B3DTuple(rVec)
+ {}
+
+ /** constructor with tuple to allow copy-constructing
+ from B3DTuple-based classes
+ */
+ B3DPoint(const ::basegfx::B3DTuple& rTuple)
+ : B3DTuple(rTuple)
+ {}
+
+ ~B3DPoint()
+ {}
+
+ /** *=operator to allow usage from B3DPoint, too
+ */
+ B3DPoint& operator*=( const B3DPoint& rPnt )
+ {
+ mfX *= rPnt.mfX;
+ mfY *= rPnt.mfY;
+ mfZ *= rPnt.mfZ;
+ return *this;
+ }
+
+ /** *=operator to allow usage from B3DPoint, too
+ */
+ B3DPoint& operator*=(double t)
+ {
+ mfX *= t;
+ mfY *= t;
+ mfZ *= t;
+ return *this;
+ }
+
+ /** assignment operator to allow assigning the results
+ of B3DTuple calculations
+ */
+ B3DPoint& operator=( const ::basegfx::B3DTuple& rVec )
+ {
+ mfX = rVec.getX();
+ mfY = rVec.getY();
+ mfZ = rVec.getZ();
+ return *this;
+ }
+
+ /** Transform point by given transformation matrix.
+
+ The translational components of the matrix are, in
+ contrast to B3DVector, applied.
+ */
+ B3DPoint& operator*=( const ::basegfx::B3DHomMatrix& rMat );
+
+ static const B3DPoint& getEmptyPoint()
+ {
+ return (const B3DPoint&) ::basegfx::B3DTuple::getEmptyTuple();
+ }
+ };
+
+ // external operators
+ //////////////////////////////////////////////////////////////////////////
+
+ /** Transform B3DPoint by given transformation matrix.
+
+ Since this is a Point, translational components of the
+ matrix are used.
+ */
+ BASEGFX_DLLPUBLIC B3DPoint operator*( const B3DHomMatrix& rMat, const B3DPoint& rPoint );
+
+} // end of namespace basegfx
+
+#endif /* _BGFX_POINT_B3DPOINT_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/point/b3ipoint.hxx b/include/basegfx/point/b3ipoint.hxx
new file mode 100644
index 000000000000..e80514c13de2
--- /dev/null
+++ b/include/basegfx/point/b3ipoint.hxx
@@ -0,0 +1,129 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_POINT_B3IPOINT_HXX
+#define _BGFX_POINT_B3IPOINT_HXX
+
+#include <basegfx/tuple/b3ituple.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ // predeclaration
+ class B3DHomMatrix;
+
+ /** Base Point class with three sal_Int32 values
+
+ This class derives all operators and common handling for
+ a 3D data class from B3ITuple. All necessary extensions
+ which are special for points will be added here.
+
+ @see B3ITuple
+ */
+ class BASEGFX_DLLPUBLIC SAL_WARN_UNUSED B3IPoint : public ::basegfx::B3ITuple
+ {
+ public:
+ /** Create a 3D Point
+
+ The point is initialized to (0, 0, 0)
+ */
+ B3IPoint()
+ : B3ITuple()
+ {}
+
+ /** Create a 3D Point
+
+ @param nX
+ This parameter is used to initialize the X-coordinate
+ of the 3D Point.
+
+ @param nY
+ This parameter is used to initialize the Y-coordinate
+ of the 3D Point.
+
+ @param nZ
+ This parameter is used to initialize the Z-coordinate
+ of the 3D Point.
+ */
+ B3IPoint(sal_Int32 nX, sal_Int32 nY, sal_Int32 nZ)
+ : B3ITuple(nX, nY, nZ)
+ {}
+
+ /** Create a copy of a 3D Point
+
+ @param rVec
+ The 3D Point which will be copied.
+ */
+ B3IPoint(const B3IPoint& rVec)
+ : B3ITuple(rVec)
+ {}
+
+ /** constructor with tuple to allow copy-constructing
+ from B3ITuple-based classes
+ */
+ B3IPoint(const ::basegfx::B3ITuple& rTuple)
+ : B3ITuple(rTuple)
+ {}
+
+ ~B3IPoint()
+ {}
+
+ /** *=operator to allow usage from B3IPoint, too
+ */
+ B3IPoint& operator*=( const B3IPoint& rPnt )
+ {
+ mnX *= rPnt.mnX;
+ mnY *= rPnt.mnY;
+ mnZ *= rPnt.mnZ;
+ return *this;
+ }
+
+ /** *=operator to allow usage from B3IPoint, too
+ */
+ B3IPoint& operator*=(sal_Int32 t)
+ {
+ mnX *= t;
+ mnY *= t;
+ mnZ *= t;
+ return *this;
+ }
+
+ /** assignment operator to allow assigning the results
+ of B3ITuple calculations
+ */
+ B3IPoint& operator=( const ::basegfx::B3ITuple& rVec )
+ {
+ mnX = rVec.getX();
+ mnY = rVec.getY();
+ mnZ = rVec.getZ();
+ return *this;
+ }
+
+ /** Transform point by given transformation matrix.
+
+ The translational components of the matrix are, in
+ contrast to B3DVector, applied.
+ */
+ B3IPoint& operator*=( const ::basegfx::B3DHomMatrix& rMat );
+ };
+} // end of namespace basegfx
+
+#endif /* _BGFX_POINT_B3IPOINT_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/polygon/b2dlinegeometry.hxx b/include/basegfx/polygon/b2dlinegeometry.hxx
new file mode 100644
index 000000000000..934158f88a2f
--- /dev/null
+++ b/include/basegfx/polygon/b2dlinegeometry.hxx
@@ -0,0 +1,141 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_POLYGON_B2DLINEGEOMETRY_HXX
+#define _BGFX_POLYGON_B2DLINEGEOMETRY_HXX
+
+#include <sal/types.h>
+#include <basegfx/numeric/ftools.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <com/sun/star/drawing/LineCap.hpp>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ namespace tools
+ {
+ /** Create line start/end geometry element, mostly arrows and things like that.
+
+ @param rCandidate
+ The polygon which needs to get that line ends and needs to have two points
+ at least.
+
+ @param rArrow
+ The line start/end geometry. It is assumed that the tip is pointing
+ upwards. Result will be rotated and scaled to fit.
+
+ @param bStart
+ describes if creation is for start or end of candidate.
+
+ @param fWidth
+ defines the size of the element, it's describing the target width in X
+ of the arrow.
+
+ @param fDockingPosition needs to be in [0.0 ..1.0] range, where 0.0 means
+ that the tip of the arrow will be aligned with the polygon start, 1.0 means
+ the bottom. The default of 0.5 describes a centered arrow.
+
+ @param pConsumedLength
+ Using this parameter it is possible to get back how much from the candidate
+ geometry is overlapped by the created element (consumed).
+
+ @param fCandidateLength
+ This should contain the length of rCandidate to allow work without
+ again calculating the length (which may be expensive with beziers). If 0.0 is
+ given, the length is calculated on demand.
+
+ @return
+ The Line start and end polygon, correctly rotated and scaled
+ */
+ BASEGFX_DLLPUBLIC B2DPolyPolygon createAreaGeometryForLineStartEnd(
+ const B2DPolygon& rCandidate,
+ const B2DPolyPolygon& rArrow,
+ bool bStart,
+ double fWidth,
+ double fCandidateLength = 0.0, // 0.0 -> calculate self
+ double fDockingPosition = 0.5, // 0->top, 1->bottom
+ double* pConsumedLength = 0L);
+
+ /** create filled polygon geometry for lines with a line width
+
+ This method will create bezier based, fillable polygons which
+ will resample the curve if it was extended for the given half
+ line width. It will remove extrema positions from contained
+ bezier segments and get as close as possible and defined by
+ the given parameters to the ideal result.
+
+ It will check edges for trivial bezier to avoid unnecessary
+ bezier polygons. Care is taken to produce the in-between
+ polygon points (the ones original on the source poygon) since
+ it has showed that without those, the raster converters leave
+ non-filled gaps.
+
+ @param rCandidate
+ The source polygon defining the hairline polygon path
+
+ @param fHalfLineWidth
+ The width of the line to one side
+
+ @param eJoin
+ The LineJoin if the edges meeting in a point do not have a C1
+ or C2 continuity
+
+ @param eCap
+ The kind of cap, which is added to the line.
+
+ @param fMaxAllowedAngle
+ Allows to hand over the maximum allowed angle between an edge and
+ it's control vectors. The smaller, the more subdivisions will be
+ needed to create the filled geometry. Allowed range is cropped to
+ [F_PI2 .. 0.01 * F_PI2].
+
+ @param fMaxPartOfEdge
+ Allows to influence from with relative length of a control vector
+ compared to it's edge a split is forced. The smaller, the more
+ subdivisions will be needed to create the filled geometry. Allowed
+ range is cropped to [1.0 .. 0.01]
+
+ @praram fMiterMinimumAngle
+ The minimum wanted angle between two edges when edge rounding
+ is using miter. When an edge is smaller than this (tighter)
+ the usual fallback to bevel is used. Allowed range is cropped
+ to [F_PI .. 0.01 * F_PI].
+
+ @return
+ The PolyPolygon containing the geometry of the extended line by
+ it's line width. Contains bezier segments and edge roundings as
+ needed and defined.
+ */
+ BASEGFX_DLLPUBLIC B2DPolyPolygon createAreaGeometry(
+ const B2DPolygon& rCandidate,
+ double fHalfLineWidth,
+ B2DLineJoin eJoin = B2DLINEJOIN_ROUND,
+ com::sun::star::drawing::LineCap eCap = com::sun::star::drawing::LineCap_BUTT,
+ double fMaxAllowedAngle = (12.5 * F_PI180),
+ double fMaxPartOfEdge = 0.4,
+ double fMiterMinimumAngle = (15.0 * F_PI180));
+ } // end of namespace tools
+} // end of namespace basegfx
+
+#endif /* _BGFX_POLYGON_B2DLINEGEOMETRY_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/polygon/b2dpolygon.hxx b/include/basegfx/polygon/b2dpolygon.hxx
new file mode 100644
index 000000000000..7c854fdc8a0e
--- /dev/null
+++ b/include/basegfx/polygon/b2dpolygon.hxx
@@ -0,0 +1,230 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_POLYGON_B2DPOLYGON_HXX
+#define _BGFX_POLYGON_B2DPOLYGON_HXX
+
+#include <sal/types.h>
+#include <o3tl/cow_wrapper.hxx>
+#include <basegfx/vector/b2enums.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+// predeclarations
+class ImplB2DPolygon;
+
+namespace basegfx
+{
+ class B2DPolygon;
+ class B2DPoint;
+ class B2DVector;
+ class B2DHomMatrix;
+ class B2DCubicBezier;
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ class BASEGFX_DLLPUBLIC B2DPolygon
+ {
+ public:
+ typedef o3tl::cow_wrapper< ImplB2DPolygon > ImplType;
+
+ private:
+ // internal data.
+ ImplType mpPolygon;
+
+ public:
+ /// diverse constructors
+ B2DPolygon();
+ B2DPolygon(const B2DPolygon& rPolygon);
+ B2DPolygon(const B2DPolygon& rPolygon, sal_uInt32 nIndex, sal_uInt32 nCount);
+ ~B2DPolygon();
+
+ /// assignment operator
+ B2DPolygon& operator=(const B2DPolygon& rPolygon);
+
+ /// unshare this polygon with all internally shared instances
+ void makeUnique();
+
+ /// compare operators
+ bool operator==(const B2DPolygon& rPolygon) const;
+ bool operator!=(const B2DPolygon& rPolygon) const;
+
+ /// member count
+ sal_uInt32 count() const;
+
+ /// Coordinate interface
+ basegfx::B2DPoint getB2DPoint(sal_uInt32 nIndex) const;
+ void setB2DPoint(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue);
+
+ /// Coordinate insert/append
+ void insert(sal_uInt32 nIndex, const basegfx::B2DPoint& rPoint, sal_uInt32 nCount = 1);
+ void append(const basegfx::B2DPoint& rPoint, sal_uInt32 nCount);
+ void append(const basegfx::B2DPoint& rPoint);
+ void reserve(sal_uInt32 nCount);
+
+ /// Basic ControlPoint interface
+ basegfx::B2DPoint getPrevControlPoint(sal_uInt32 nIndex) const;
+ basegfx::B2DPoint getNextControlPoint(sal_uInt32 nIndex) const;
+ void setPrevControlPoint(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue);
+ void setNextControlPoint(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue);
+ void setControlPoints(sal_uInt32 nIndex, const basegfx::B2DPoint& rPrev, const basegfx::B2DPoint& rNext);
+
+ /// ControlPoint resets
+ void resetPrevControlPoint(sal_uInt32 nIndex);
+ void resetNextControlPoint(sal_uInt32 nIndex);
+ void resetControlPoints();
+
+ /// Bezier segment append with control points. The current last polygon point is implicitly taken as start point.
+ void appendBezierSegment(const basegfx::B2DPoint& rNextControlPoint, const basegfx::B2DPoint& rPrevControlPoint, const basegfx::B2DPoint& rPoint);
+
+ /// ControlPoint checks
+ bool areControlPointsUsed() const;
+ bool isPrevControlPointUsed(sal_uInt32 nIndex) const;
+ bool isNextControlPointUsed(sal_uInt32 nIndex) const;
+ B2VectorContinuity getContinuityInPoint(sal_uInt32 nIndex) const;
+
+ /** bezier segment access
+
+ This method also works when it is no bezier segment at all and will fill
+ the given B2DCubicBezier as needed.
+ In any case, the given B2DCubicBezier will be filled, if necessary with
+ the single start point (if no valid edge exists).
+
+ @param nIndex
+ Index of the addressed edge's start point
+
+ @param rTarget
+ The B2DCubicBezier to be filled. It's data WILL be changed.
+ */
+ void getBezierSegment(sal_uInt32 nIndex, B2DCubicBezier& rTarget) const;
+
+ /** Default adaptive subdivision access
+
+ This method will return a default adapive subdivision of the polygon.
+ If the polygon does not contain any bezier curve segments, it will
+ just return itself.
+
+ The subdivision is created on first request and buffered, so when using
+ this subdivision You have the guarantee for fast accesses for multiple
+ usages. It is intended for tooling usage for tasks which would be hard
+ to accomplish on bezier segments (e.g. isInEpsilonRange).
+
+ The current default subdivision uses adaptiveSubdivideByCount with 9
+ subdivisions which gives 10 edges and 11 points per segment and is
+ usually pretty usable for processing purposes. There is no parameter
+ passing here ATM but it may be changed on demand. If needed, a TYPE
+ and PARAMETER (both defaulted) may be added to allow for switching
+ between the different kinds of subdivisiond and passing them one
+ parameter.
+
+ The lifetime of the buffered subdivision is based on polygon changes.
+ When changing the polygon, it will be flushed. It is buffered at the
+ refcounted implementation class, so it will survive copy by value and
+ combinations in PolyPolygons.
+
+ @return
+ The default (and buffered) subdivision of this polygon. It may
+ be this polygon itself when it has no bezier segments. It is guaranteed
+ to have no more bezier segments
+ */
+ B2DPolygon getDefaultAdaptiveSubdivision() const;
+
+ /** Get the B2DRange (Rectangle dimensions) of this B2DPolygon
+
+ A polygon may have up to three ranges:
+
+ (a) the range of the polygon points
+ (b) the range of the polygon points and control points
+ (c) the outer range of the subdivided bezier curve
+
+ Ranges (a) and (c) are produced by tools::getRange(); resp. this
+ getB2DRange(). tools::getRangeWithControlPoints handles case (b).
+
+ To get range (c) a simple solution would be to subdivide the polygon
+ and use getRange() on it. Since subdivision is expensive and decreases
+ the polygon quality, i added this new method. It will use a
+ methodology suggested by HDU. First, it gets the range (a).
+ Then it iterates over the bezier segments and for each it
+ first tests if the outer range of the bezier segment is already
+ contained in the result range.
+
+ The subdivision itself uses getAllExtremumPositions() to only
+ calculate extremum points and to expand the result accordingly.
+ Thus it calculates maximal four extremum points on the bezier
+ segment, no split is used at all.
+
+ @return
+ The outer range of the bezier curve/polygon
+ */
+ B2DRange getB2DRange() const;
+
+ /** append other 2D polygons
+
+ The default (nIndex ==0 && nCount == 0) will append
+ the whole rPoly
+
+ @param rPoly
+ The source polygon
+
+ @param nIndex
+ The index to the first point of rPoly to append
+
+ @param nCount
+ The number of points to append from rPoly, starting
+ from nIndex. If zero, as much as possibel is appended
+ */
+ void append(const B2DPolygon& rPoly, sal_uInt32 nIndex = 0, sal_uInt32 nCount = 0);
+
+ /// remove points
+ void remove(sal_uInt32 nIndex, sal_uInt32 nCount = 1);
+
+ /// clear all points
+ void clear();
+
+ /// closed state interface
+ bool isClosed() const;
+ void setClosed(bool bNew);
+
+ /// flip polygon direction
+ void flip();
+
+ /// test if Polygon has double points
+ bool hasDoublePoints() const;
+
+ /// remove double points, at the begin/end and follow-ups, too
+ void removeDoublePoints();
+
+ /// apply transformation given in matrix form
+ void transform(const basegfx::B2DHomMatrix& rMatrix);
+ };
+
+ // typedef for a vector of B2DPolygons
+ typedef ::std::vector< B2DPolygon > B2DPolygonVector;
+
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif /* _BGFX_POLYGON_B2DPOLYGON_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/polygon/b2dpolygonclipper.hxx b/include/basegfx/polygon/b2dpolygonclipper.hxx
new file mode 100644
index 000000000000..197958e45a00
--- /dev/null
+++ b/include/basegfx/polygon/b2dpolygonclipper.hxx
@@ -0,0 +1,70 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_POLYPOLYGON_B2DPOLYGONCLIPPER_HXX
+#define _BGFX_POLYPOLYGON_B2DPOLYGONCLIPPER_HXX
+
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ // predefinitions
+ class B2DRange;
+
+ namespace tools
+ {
+ // This method clips the given PolyPolygon against a horizontal or vertical axis (parallell to X or Y axis). The axis is
+ // defined by bParallelToXAxis (true -> it's parallel to the X-Axis of the coordinate system, else to the Y-Axis) and the
+ // fValueOnOtherAxis (gives the translation to the coordinate system axis). For example, when You want to define
+ // a clip axis parallel to X.Axis and 100 above it, use bParallelToXAxis = true and fValueOnOtherAxis = 100.
+ // The value bAboveAxis defines on which side the return value will be (true -> above X, right of Y).
+ // The switch bStroke decides if the polygon is interpreted as area (false) or strokes (true).
+ BASEGFX_DLLPUBLIC B2DPolyPolygon clipPolyPolygonOnParallelAxis(const B2DPolyPolygon& rCandidate, bool bParallelToXAxis, bool bAboveAxis, double fValueOnOtherAxis, bool bStroke);
+ BASEGFX_DLLPUBLIC B2DPolyPolygon clipPolygonOnParallelAxis(const B2DPolygon& rCandidate, bool bParallelToXAxis, bool bAboveAxis, double fValueOnOtherAxis, bool bStroke);
+
+ // Clip the given PolyPolygon against the given range. bInside defines if the result will contain the
+ // parts which are contained in the range or vice versa.
+ // The switch bStroke decides if the polygon is interpreted as area (false) or strokes (true).
+ BASEGFX_DLLPUBLIC B2DPolyPolygon clipPolyPolygonOnRange(const B2DPolyPolygon& rCandidate, const B2DRange& rRange, bool bInside, bool bStroke);
+ BASEGFX_DLLPUBLIC B2DPolyPolygon clipPolygonOnRange(const B2DPolygon& rCandidate, const B2DRange& rRange, bool bInside, bool bStroke);
+
+ // Clip given PolyPolygon against given clipping polygon.
+ // The switch bStroke decides if the polygon is interpreted as area (false) or strokes (true).
+ // With stroke polygons, You get all line snippets inside rCip.
+ // With filled polygons, You get all PolyPolygon parts which were inside rClip.
+ // The switch bInside decides if the parts inside the clip polygon or outside shall be created.
+ // The clip polygon is always assumed closed, even when it's isClosed() is false.
+ BASEGFX_DLLPUBLIC B2DPolyPolygon clipPolyPolygonOnPolyPolygon(const B2DPolyPolygon& rCandidate, const B2DPolyPolygon& rClip, bool bInside, bool bStroke);
+ BASEGFX_DLLPUBLIC B2DPolyPolygon clipPolygonOnPolyPolygon(const B2DPolygon& rCandidate, const B2DPolyPolygon& rClip, bool bInside, bool bStroke);
+
+ // clip the given polygon against the given range. the resulting polygon will always contain
+ // the inside parts which will always be interpreted as areas. the incoming polygon is expected
+ // to be a simple triangle list. the result is also a simple triangle list.
+ BASEGFX_DLLPUBLIC B2DPolygon clipTriangleListOnRange( const B2DPolygon& rCandidate, const B2DRange& rRange );
+
+ } // end of namespace tools
+} // end of namespace basegfx
+
+#endif /* _BGFX_POLYPOLYGON_B2DPOLYGONCLIPPER_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/polygon/b2dpolygoncutandtouch.hxx b/include/basegfx/polygon/b2dpolygoncutandtouch.hxx
new file mode 100644
index 000000000000..05f8e0e0cb3a
--- /dev/null
+++ b/include/basegfx/polygon/b2dpolygoncutandtouch.hxx
@@ -0,0 +1,58 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_POLYGON_CUTANDTOUCH_HXX
+#define _BGFX_POLYGON_CUTANDTOUCH_HXX
+
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ namespace tools
+ {
+ // look for self-intersections and self-touches (points on an edge) in given polygon and add
+ // extra points there. Result will have no touches or intersections on an edge, only on points
+ BASEGFX_DLLPUBLIC B2DPolygon addPointsAtCutsAndTouches(const B2DPolygon& rCandidate);
+
+ // look for polypolygon-intersections and polypolygon-touches (point of poly A on an edge of poly B) in given PolyPolygon and add
+ // extra points there. Result will have no touches or intersections between contained polygons on an edge, only on points. For
+ // convenience, the correction for self-intersections for each member polygon will be used, too.
+ // Changed: Self intersections are searched by default, but may be switched off by 2nd parameter.
+ BASEGFX_DLLPUBLIC B2DPolyPolygon addPointsAtCutsAndTouches(const B2DPolyPolygon& rCandidate, bool bSelfIntersections = true);
+
+ // look for intersections of rCandidate with the edge from rStart to rEnd and add extra points there.
+ // Points are only added in the range of the edge, not on the endless vector.
+ BASEGFX_DLLPUBLIC B2DPolygon addPointsAtCuts(const B2DPolygon& rCandidate, const B2DPoint& rStart, const B2DPoint& rEnd);
+
+ // look for intersections of rCandidate with the mask Polygon and add extra points there.
+ // The mask polygon is assumed to be closed, even when it's not explicitly.
+ BASEGFX_DLLPUBLIC B2DPolygon addPointsAtCuts(const B2DPolygon& rCandidate, const B2DPolyPolygon& rMask);
+
+ } // end of namespace tools
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif /* _BGFX_POLYGON_CUTANDTOUCH_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/polygon/b2dpolygontools.hxx b/include/basegfx/polygon/b2dpolygontools.hxx
new file mode 100644
index 000000000000..dce479847d65
--- /dev/null
+++ b/include/basegfx/polygon/b2dpolygontools.hxx
@@ -0,0 +1,442 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_POLYGON_B2DPOLYGONTOOLS_HXX
+#define _BGFX_POLYGON_B2DPOLYGONTOOLS_HXX
+
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/vector/b2dvector.hxx>
+#include <basegfx/range/b2drectangle.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/polygon/b3dpolygon.hxx>
+#include <vector>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ // predefinitions
+ class B2DPolygon;
+ class B2DRange;
+
+ namespace tools
+ {
+ // B2DPolygon tools
+
+ // open/close with point add/remove and control point corrections
+ BASEGFX_DLLPUBLIC void openWithGeometryChange(B2DPolygon& rCandidate);
+ BASEGFX_DLLPUBLIC void closeWithGeometryChange(B2DPolygon& rCandidate);
+
+ /** Check if given polygon is closed.
+
+ This is kind of a 'classic' method to support old polygon
+ definitions. Those old polygon definitions define the
+ closed state of the polygon using identical start and
+ endpoints. This method corrects this (removes double
+ start/end points) and sets the Closed()-state of the
+ polygon correctly.
+ */
+ BASEGFX_DLLPUBLIC void checkClosed(B2DPolygon& rCandidate);
+
+ // Get successor and predecessor indices. Returning the same index means there
+ // is none. Same for successor.
+ BASEGFX_DLLPUBLIC sal_uInt32 getIndexOfPredecessor(sal_uInt32 nIndex, const B2DPolygon& rCandidate);
+ BASEGFX_DLLPUBLIC sal_uInt32 getIndexOfSuccessor(sal_uInt32 nIndex, const B2DPolygon& rCandidate);
+
+ // Get orientation of Polygon
+ BASEGFX_DLLPUBLIC B2VectorOrientation getOrientation(const B2DPolygon& rCandidate);
+
+ // isInside tests for B2dPoint and other B2dPolygon. On border is not inside as long as
+ // not true is given in bWithBorder flag.
+ BASEGFX_DLLPUBLIC bool isInside(const B2DPolygon& rCandidate, const B2DPoint& rPoint, bool bWithBorder = false);
+ BASEGFX_DLLPUBLIC bool isInside(const B2DPolygon& rCandidate, const B2DPolygon& rPolygon, bool bWithBorder = false);
+
+ /** Get the range of a polygon
+
+ This method creates the outer range of the subdivided bezier curve.
+ For detailed discussion see B2DPolygon::getB2DRange()
+
+ @param rCandidate
+ The B2DPolygon eventually containing bezier segments
+
+ @return
+ The outer range of the bezier curve
+ */
+ BASEGFX_DLLPUBLIC B2DRange getRange(const B2DPolygon& rCandidate);
+
+ // get signed area of polygon
+ BASEGFX_DLLPUBLIC double getSignedArea(const B2DPolygon& rCandidate);
+
+ // get area of polygon
+ BASEGFX_DLLPUBLIC double getArea(const B2DPolygon& rCandidate);
+
+ /** get length of polygon edge from point nIndex to nIndex + 1 */
+ BASEGFX_DLLPUBLIC double getEdgeLength(const B2DPolygon& rCandidate, sal_uInt32 nIndex);
+
+ /** get length of polygon */
+ BASEGFX_DLLPUBLIC double getLength(const B2DPolygon& rCandidate);
+
+ // get position on polygon for absolute given distance. If
+ // length is given, it is assumed the correct polygon length, if 0.0 it is calculated
+ // using getLength(...)
+ BASEGFX_DLLPUBLIC B2DPoint getPositionAbsolute(const B2DPolygon& rCandidate, double fDistance, double fLength = 0.0);
+
+ // get position on polygon for relative given distance in range [0.0 .. 1.0]. If
+ // length is given, it is assumed the correct polygon length, if 0.0 it is calculated
+ // using getLength(...)
+ BASEGFX_DLLPUBLIC B2DPoint getPositionRelative(const B2DPolygon& rCandidate, double fDistance, double fLength = 0.0);
+
+ // get a snippet from given polygon for absolute distances. The polygon is assumed
+ // to be opened (not closed). fFrom and fTo need to be in range [0.0 .. fLength], where
+ // fTo >= fFrom. If length is given, it is assumed the correct polygon length,
+ // if 0.0 it is calculated using getLength(...)
+ BASEGFX_DLLPUBLIC B2DPolygon getSnippetAbsolute(const B2DPolygon& rCandidate, double fFrom, double fTo, double fLength = 0.0);
+
+ // Continuity check for point with given index
+ BASEGFX_DLLPUBLIC B2VectorContinuity getContinuityInPoint(const B2DPolygon& rCandidate, sal_uInt32 nIndex);
+
+ // Subdivide all contained curves. Use distanceBound value if given.
+ BASEGFX_DLLPUBLIC B2DPolygon adaptiveSubdivideByDistance(const B2DPolygon& rCandidate, double fDistanceBound = 0.0);
+
+ // Subdivide all contained curves. Use angleBound value if given.
+ BASEGFX_DLLPUBLIC B2DPolygon adaptiveSubdivideByAngle(const B2DPolygon& rCandidate, double fAngleBound = 0.0);
+
+ // #i37443# Subdivide all contained curves.
+ BASEGFX_DLLPUBLIC B2DPolygon adaptiveSubdivideByCount(const B2DPolygon& rCandidate, sal_uInt32 nCount = 0L);
+
+ // Definitions for the cut flags used from the findCut methods
+ typedef sal_uInt16 CutFlagValue;
+
+ #define CUTFLAG_NONE (0x0000)
+ #define CUTFLAG_LINE (0x0001)
+ #define CUTFLAG_START1 (0x0002)
+ #define CUTFLAG_START2 (0x0004)
+ #define CUTFLAG_END1 (0x0008)
+ #define CUTFLAG_END2 (0x0010)
+ #define CUTFLAG_ALL (CUTFLAG_LINE|CUTFLAG_START1|CUTFLAG_START2|CUTFLAG_END1|CUTFLAG_END2)
+ #define CUTFLAG_DEFAULT (CUTFLAG_LINE|CUTFLAG_START2|CUTFLAG_END2)
+
+ // This version works with two points and vectors to define the
+ // edges for the cut test.
+ BASEGFX_DLLPUBLIC CutFlagValue findCut(
+ const B2DPoint& rEdge1Start, const B2DVector& rEdge1Delta,
+ const B2DPoint& rEdge2Start, const B2DVector& rEdge2Delta,
+ CutFlagValue aCutFlags = CUTFLAG_DEFAULT,
+ double* pCut1 = 0L, double* pCut2 = 0L);
+
+ // test if point is on the given edge in range ]0.0..1.0[ without
+ // the start/end points. If so, return true and put the parameter
+ // value in pCut (if provided)
+ BASEGFX_DLLPUBLIC bool isPointOnEdge(
+ const B2DPoint& rPoint,
+ const B2DPoint& rEdgeStart,
+ const B2DVector& rEdgeDelta,
+ double* pCut = 0L);
+
+ /** Apply given LineDashing to given polygon
+
+ This method is used to cut down line polygons to the needed
+ pieces when a dashing needs to be applied.
+ It is now capable of keeping contained bezier segments.
+ It is also capable of delivering line and non-line portions
+ depending on what target polygons You provide. This is useful
+ e.g. for dashed lines with two colors.
+ If the last and the first snippet in one of the results have
+ a common start/end ppoint, they will be merged to achieve as
+ view as needed result line snippets. This is also relevant for
+ further processing the results.
+
+ @param rCandidate
+ The polygon based on which the snippets will be created.
+
+ @param rDotDashArray
+ The line pattern given as array of length values
+
+ @param pLineTarget
+ The target for line snippets, e.g. the first entry will be
+ a line segment with length rDotDashArray[0]. The given
+ polygon will be emptied as preparation.
+
+ @param pGapTarget
+ The target for gap snippets, e.g. the first entry will be
+ a line segment with length rDotDashArray[1]. The given
+ polygon will be emptied as preparation.
+
+ @param fFullDashDotLen
+ The sumed-up length of the rDotDashArray. If zero, it will
+ be calculated internally.
+ */
+ BASEGFX_DLLPUBLIC void applyLineDashing(
+ const B2DPolygon& rCandidate,
+ const ::std::vector<double>& rDotDashArray,
+ B2DPolyPolygon* pLineTarget,
+ B2DPolyPolygon* pGapTarget = 0,
+ double fFullDashDotLen = 0.0);
+
+ // test if point is inside epsilon-range around an edge defined
+ // by the two given points. Can be used for HitTesting. The epsilon-range
+ // is defined to be the rectangle centered to the given edge, using height
+ // 2 x fDistance, and the circle around both points with radius fDistance.
+ BASEGFX_DLLPUBLIC bool isInEpsilonRange(const B2DPoint& rEdgeStart, const B2DPoint& rEdgeEnd, const B2DPoint& rTestPosition, double fDistance);
+
+ // test if point is inside epsilon-range around the given Polygon. Can be used
+ // for HitTesting. The epsilon-range is defined to be the rectangle centered
+ // to the given edge, using height 2 x fDistance, and the circle around both points
+ // with radius fDistance.
+ BASEGFX_DLLPUBLIC bool isInEpsilonRange(const B2DPolygon& rCandidate, const B2DPoint& rTestPosition, double fDistance);
+
+ /** Create a polygon from a rectangle.
+
+ @param rRect
+ The rectangle which describes the polygon size
+
+ @param fRadiusX
+ @param fRadiusY
+ Radius of the edge rounding, relative to the rectangle size. 0.0 means no
+ rounding, 1.0 will lead to an ellipse
+ */
+ BASEGFX_DLLPUBLIC B2DPolygon createPolygonFromRect( const B2DRectangle& rRect, double fRadiusX, double fRadiusY );
+
+ /** Create a polygon from a rectangle.
+ */
+ BASEGFX_DLLPUBLIC B2DPolygon createPolygonFromRect( const B2DRectangle& rRect );
+
+ /** Create the unit polygon
+ */
+ BASEGFX_DLLPUBLIC B2DPolygon createUnitPolygon();
+
+ /** Create a circle polygon with given radius.
+
+ This method creates a circle approximation consisting of
+ four cubic bezier segments, which approximate the given
+ circle with an error of less than 0.5 percent.
+
+ @param rCenter
+ Center point of the circle
+
+ @param fRadius
+ Radius of the circle
+ */
+ BASEGFX_DLLPUBLIC B2DPolygon createPolygonFromCircle( const B2DPoint& rCenter, double fRadius );
+
+ /// create half circle centered on (0,0) from [0 .. F_PI]
+ B2DPolygon createHalfUnitCircle();
+
+ /** create a polygon which describes the unit circle and close it
+
+ @param nStartQuadrant
+ To be able to rebuild the old behaviour where the circles started at bottom,
+ this parameter is used. Default is 0 which is the first quadrant and the
+ polygon's start point will be the rightmost one. When using e.g. 1, the
+ first created quadrant will start at the YMax-position (with Y down on screens,
+ this is the lowest one). This is needed since when lines are dashed, toe old
+ geometry started at bottom point, else it would look different.
+ */
+ BASEGFX_DLLPUBLIC B2DPolygon createPolygonFromUnitCircle(sal_uInt32 nStartQuadrant = 0);
+
+ /** Create an ellipse polygon with given radii.
+
+ This method creates an ellipse approximation consisting of
+ four cubic bezier segments, which approximate the given
+ ellipse with an error of less than 0.5 percent.
+
+ @param rCenter
+ Center point of the circle
+
+ @param fRadiusX
+ Radius of the ellipse in X direction
+
+ @param fRadiusY
+ Radius of the ellipse in Y direction
+ */
+ BASEGFX_DLLPUBLIC B2DPolygon createPolygonFromEllipse( const B2DPoint& rCenter, double fRadiusX, double fRadiusY );
+
+ /** Create an unit ellipse polygon with the given angles, from start to end
+ */
+ BASEGFX_DLLPUBLIC B2DPolygon createPolygonFromEllipseSegment( const B2DPoint& rCenter, double fRadiusX, double fRadiusY, double fStart, double fEnd );
+
+ BASEGFX_DLLPUBLIC B2DPolygon createPolygonFromUnitEllipseSegment( double fStart, double fEnd );
+
+ /** Predicate whether a given polygon is a rectangle.
+
+ @param rPoly
+ Polygon to check
+
+ @return true, if the polygon describes a rectangle
+ (polygon is closed, and the points are either cw or ccw
+ enumerations of a rectangle's vertices). Note that
+ intermediate points and duplicate points are ignored.
+ */
+ BASEGFX_DLLPUBLIC bool isRectangle( const B2DPolygon& rPoly );
+
+ // create 3d polygon from given 2d polygon. The given fZCoordinate is used to expand the
+ // third coordinate.
+ BASEGFX_DLLPUBLIC B3DPolygon createB3DPolygonFromB2DPolygon(const B2DPolygon& rCandidate, double fZCoordinate = 0.0);
+
+ // create 2d PolyPolygon from given 3d PolyPolygon. All coordinates are transformed using the given
+ // matrix and the resulting x,y is used to form the new polygon.
+ BASEGFX_DLLPUBLIC B2DPolygon createB2DPolygonFromB3DPolygon(const B3DPolygon& rCandidate, const B3DHomMatrix& rMat);
+
+ // calculate the smallest distance to given edge and return. The relative position on the edge is returned in Cut.
+ // That position is in the range [0.0 .. 1.0] and the returned distance is adapted accordingly to the start or end
+ // point of the edge
+ BASEGFX_DLLPUBLIC double getSmallestDistancePointToEdge(const B2DPoint& rPointA, const B2DPoint& rPointB, const B2DPoint& rTestPoint, double& rCut);
+
+ // for each contained edge calculate the smallest distance. Return the index to the smallest
+ // edge in rEdgeIndex. The relative position on the edge is returned in rCut.
+ // If nothing was found (e.g. empty input plygon), DBL_MAX is returned.
+ BASEGFX_DLLPUBLIC double getSmallestDistancePointToPolygon(const B2DPolygon& rCandidate, const B2DPoint& rTestPoint, sal_uInt32& rEdgeIndex, double& rCut);
+
+ // distort single point. rOriginal describes the original range, where the given points describe the distorted corresponding points.
+ BASEGFX_DLLPUBLIC B2DPoint distort(const B2DPoint& rCandidate, const B2DRange& rOriginal, const B2DPoint& rTopLeft, const B2DPoint& rTopRight, const B2DPoint& rBottomLeft, const B2DPoint& rBottomRight);
+
+ // distort polygon. rOriginal describes the original range, where the given points describe the distorted corresponding points.
+ BASEGFX_DLLPUBLIC B2DPolygon distort(const B2DPolygon& rCandidate, const B2DRange& rOriginal, const B2DPoint& rTopLeft, const B2DPoint& rTopRight, const B2DPoint& rBottomLeft, const B2DPoint& rBottomRight);
+
+ // expand all segments (which are not yet) to curve segments. This is done with setting the control
+ // vectors on the 1/3 resp. 2/3 distances on each segment.
+ BASEGFX_DLLPUBLIC B2DPolygon expandToCurve(const B2DPolygon& rCandidate);
+
+ // expand given segment to curve segment. This is done with setting the control
+ // vectors on the 1/3 resp. 2/3 distances. The return value describes if a change took place.
+ BASEGFX_DLLPUBLIC bool expandToCurveInPoint(B2DPolygon& rCandidate, sal_uInt32 nIndex);
+
+ // set continuity for given index. If not a curve, nothing will change. Non-curve points are not changed, too.
+ // The return value describes if a change took place.
+ BASEGFX_DLLPUBLIC bool setContinuityInPoint(B2DPolygon& rCandidate, sal_uInt32 nIndex, B2VectorContinuity eContinuity);
+
+ // test if polygon contains neutral points. A neutral point is one whos orientation is neutral
+ // e.g. positioned on the edge of it's predecessor and successor
+ BASEGFX_DLLPUBLIC bool hasNeutralPoints(const B2DPolygon& rCandidate);
+
+ // remove neutral points. A neutral point is one whos orientation is neutral
+ // e.g. positioned on the edge of it's predecessor and successor
+ BASEGFX_DLLPUBLIC B2DPolygon removeNeutralPoints(const B2DPolygon& rCandidate);
+
+ // tests if polygon is convex
+ BASEGFX_DLLPUBLIC bool isConvex(const B2DPolygon& rCandidate);
+
+ // calculates the orientation at edge nIndex
+ BASEGFX_DLLPUBLIC B2VectorOrientation getOrientationForIndex(const B2DPolygon& rCandidate, sal_uInt32 nIndex);
+
+ // calculates if given point is on given line, taking care of the numerical epsilon
+ BASEGFX_DLLPUBLIC bool isPointOnLine(const B2DPoint& rStart, const B2DPoint& rEnd, const B2DPoint& rCandidate, bool bWithPoints = false);
+
+ // calculates if given point is on given polygon, taking care of the numerical epsilon. Uses
+ // isPointOnLine internally
+ BASEGFX_DLLPUBLIC bool isPointOnPolygon(const B2DPolygon& rCandidate, const B2DPoint& rPoint, bool bWithPoints = true);
+
+ // test if candidate is inside triangle
+ BASEGFX_DLLPUBLIC bool isPointInTriangle(const B2DPoint& rA, const B2DPoint& rB, const B2DPoint& rC, const B2DPoint& rCandidate, bool bWithBorder = false);
+
+ // test if candidateA and candidateB are on the same side of the given line
+ BASEGFX_DLLPUBLIC bool arePointsOnSameSideOfLine(const B2DPoint& rStart, const B2DPoint& rEnd, const B2DPoint& rCandidateA, const B2DPoint& rCandidateB, bool bWithLine = false);
+
+ // add triangles for given rCandidate to rTarget. For each triangle, 3 points will be added to rCandidate.
+ // All triangles will go from the start point of rCandidate to two consecutive points, building (rCandidate.count() - 2)
+ // triangles.
+ BASEGFX_DLLPUBLIC void addTriangleFan(const B2DPolygon& rCandidate, B2DPolygon& rTarget);
+
+ // grow for polygon. Move all geometry in each point in the direction of the normal in that point
+ // with the given amount. Value may be negative.
+ BASEGFX_DLLPUBLIC B2DPolygon growInNormalDirection(const B2DPolygon& rCandidate, double fValue);
+
+ // force all sub-polygons to a point count of nSegments
+ BASEGFX_DLLPUBLIC B2DPolygon reSegmentPolygon(const B2DPolygon& rCandidate, sal_uInt32 nSegments);
+
+ // create polygon state at t from 0.0 to 1.0 between the two polygons. Both polygons must have the same
+ // organisation, e.g. same amount of points
+ BASEGFX_DLLPUBLIC B2DPolygon interpolate(const B2DPolygon& rOld1, const B2DPolygon& rOld2, double t);
+
+ // #i76891# Try to remove existing curve segments if they are simply edges
+ BASEGFX_DLLPUBLIC B2DPolygon simplifyCurveSegments(const B2DPolygon& rCandidate);
+
+ // makes the given indexed point the new polygon start point. To do that, the points in the
+ // polygon will be rotated. This is only valid for closed polygons, for non-closed ones
+ // an assertion will be triggered
+ BASEGFX_DLLPUBLIC B2DPolygon makeStartPoint(const B2DPolygon& rCandidate, sal_uInt32 nIndexOfNewStatPoint);
+
+ /** create edges of given length along given B2DPolygon
+
+ @param rCandidate
+ The polygon to move along. Points at the given polygon are created, starting
+ at position fStart and stopping at less or equal to fEnd. The closed state is
+ preserved.
+ The polygon is subdivided if curve segments are included. That subdivision is the base
+ for the newly created points.
+ If the source is closed, the indirectly existing last edge may NOT have the
+ given length.
+ If the source is open, all edges will have the given length. You may use the last
+ point of the original when You want to add the last edge Yourself.
+
+ @param fLength
+ The length of the created edges. If less or equal zero, an empty polygon is returned.
+
+ @param fStart
+ The start distance for the first to be generated point. Use 0.0 to get the
+ original start point. Negative values are truncated to 0.0.
+
+ @param fEnd
+ The maximum distance for the last point. No more points behind this distance will be created.
+ Use 0.0 to proccess the whole polygon. Negative values are truncated to 0.0. It also
+ needs to be more or equal to fStart, else it is truncated to fStart.
+
+ @return
+ The newly created polygon
+ */
+ BASEGFX_DLLPUBLIC B2DPolygon createEdgesOfGivenLength(const B2DPolygon& rCandidate, double fLength, double fStart = 0.0, double fEnd = 0.0);
+
+ /** Create Waveline along given polygon
+ The implementation is based on createEdgesOfGivenLength and creates a curve
+ segment with the given dimensions for each created line segment. The polygon
+ is treated as if opened (closed state will be ignored) and only for whole
+ edges a curve segment will be created (no rest handling)
+
+ @param rCandidate
+ The polygon along which the waveline will be created
+
+ @param fWaveWidth
+ The length of a single waveline curve segment
+
+ @param fgWaveHeight
+ The height of the waveline (amplitude)
+ */
+ BASEGFX_DLLPUBLIC B2DPolygon createWaveline(const B2DPolygon& rCandidate, double fWaveWidth, double fWaveHeight);
+
+ /** snap some polygon coordinates to discrete coordinates
+
+ This method allows to snap some polygon points to discrete (integer) values
+ which equals e.g. a snap to discrete coordinates. It will snap points of
+ horizontal and vertical edges
+
+ @param rCandidate
+ The source polygon
+
+ @return
+ The modified version of the source polygon
+ */
+ BASEGFX_DLLPUBLIC B2DPolygon snapPointsOfHorizontalOrVerticalEdges(const B2DPolygon& rCandidate);
+
+ } // end of namespace tools
+} // end of namespace basegfx
+
+#endif /* _BGFX_POLYGON_B2DPOLYGONTOOLS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/polygon/b2dpolygontriangulator.hxx b/include/basegfx/polygon/b2dpolygontriangulator.hxx
new file mode 100644
index 000000000000..5af34ae1ecd2
--- /dev/null
+++ b/include/basegfx/polygon/b2dpolygontriangulator.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 .
+ */
+
+#ifndef _BGFX_POLYGON_B2DPOLYGONTRIANGULATOR_HXX
+#define _BGFX_POLYGON_B2DPOLYGONTRIANGULATOR_HXX
+
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ namespace triangulator
+ {
+ // triangulate given polygon
+ BASEGFX_DLLPUBLIC ::basegfx::B2DPolygon triangulate(const ::basegfx::B2DPolygon& rCandidate);
+
+ // triangulate given PolyPolygon
+ BASEGFX_DLLPUBLIC ::basegfx::B2DPolygon triangulate(const ::basegfx::B2DPolyPolygon& rCandidate);
+
+ } // end of namespace triangulator
+} // end of namespace basegfx
+
+#endif /* _BGFX_POLYGON_B2DPOLYGONTRIANGULATOR_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/polygon/b2dpolypolygon.hxx b/include/basegfx/polygon/b2dpolypolygon.hxx
new file mode 100644
index 000000000000..cd22644ab8ce
--- /dev/null
+++ b/include/basegfx/polygon/b2dpolypolygon.hxx
@@ -0,0 +1,137 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_POLYGON_B2DPOLYPOLYGON_HXX
+#define _BGFX_POLYGON_B2DPOLYPOLYGON_HXX
+
+#include <sal/types.h>
+#include <o3tl/cow_wrapper.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/basegfxdllapi.h>
+#include <vector>
+
+// predeclarations
+class ImplB2DPolyPolygon;
+
+namespace basegfx
+{
+ class B2DPolygon;
+ class B2DHomMatrix;
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ class BASEGFX_DLLPUBLIC B2DPolyPolygon
+ {
+ public:
+ typedef o3tl::cow_wrapper< ImplB2DPolyPolygon > ImplType;
+
+ private:
+ ImplType mpPolyPolygon;
+
+ public:
+ B2DPolyPolygon();
+ B2DPolyPolygon(const B2DPolyPolygon& rPolyPolygon);
+ explicit B2DPolyPolygon(const B2DPolygon& rPolygon);
+ ~B2DPolyPolygon();
+
+ // assignment operator
+ B2DPolyPolygon& operator=(const B2DPolyPolygon& rPolyPolygon);
+
+ /// unshare this poly-polygon (and all included polygons) with all internally shared instances
+ void makeUnique();
+
+ // compare operators
+ bool operator==(const B2DPolyPolygon& rPolyPolygon) const;
+ bool operator!=(const B2DPolyPolygon& rPolyPolygon) const;
+
+ // polygon interface
+ sal_uInt32 count() const;
+
+ B2DPolygon getB2DPolygon(sal_uInt32 nIndex) const;
+ void setB2DPolygon(sal_uInt32 nIndex, const B2DPolygon& rPolygon);
+
+ // test for curve
+ bool areControlPointsUsed() const;
+
+ // insert/append single polygon
+ void insert(sal_uInt32 nIndex, const B2DPolygon& rPolygon, sal_uInt32 nCount = 1);
+ void append(const B2DPolygon& rPolygon, sal_uInt32 nCount = 1);
+
+ /** Default adaptive subdivision access
+
+ For details refer to B2DPolygon::getDefaultAdaptiveSubdivision()
+
+ @return
+ The default subdivision of this polygon
+ */
+ B2DPolyPolygon getDefaultAdaptiveSubdivision() const;
+
+ /** Get the B2DRange (Rectangle dimensions) of this B2DPolyPolygon
+
+ For details refer to B2DPolygon::getB2DRange()
+
+ @return
+ The outer range of the bezier curve/polygon
+ */
+ B2DRange getB2DRange() const;
+
+ // insert/append multiple polygons
+ void insert(sal_uInt32 nIndex, const B2DPolyPolygon& rPolyPolygon);
+ void append(const B2DPolyPolygon& rPolyPolygon);
+
+ // remove
+ void remove(sal_uInt32 nIndex, sal_uInt32 nCount = 1);
+
+ // reset to empty state
+ void clear();
+
+ // closed state
+ bool isClosed() const;
+ void setClosed(bool bNew);
+
+ // flip polygon direction
+ void flip();
+
+ // test if PolyPolygon has double points
+ bool hasDoublePoints() const;
+
+ // remove double points, at the begin/end and follow-ups, too
+ void removeDoublePoints();
+
+ // apply transformation given in matrix form to the polygon
+ void transform(const basegfx::B2DHomMatrix& rMatrix);
+
+ // polygon iterators (same iterator validity conditions as for vector)
+ const B2DPolygon* begin() const;
+ const B2DPolygon* end() const;
+ B2DPolygon* begin();
+ B2DPolygon* end();
+ };
+
+ // typedef for a vector of B2DPolyPolygons
+ typedef ::std::vector< B2DPolyPolygon > B2DPolyPolygonVector;
+
+} // end of namespace basegfx
+
+#endif /* _BGFX_POLYGON_B2DPOLYPOLYGON_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/polygon/b2dpolypolygoncutter.hxx b/include/basegfx/polygon/b2dpolypolygoncutter.hxx
new file mode 100644
index 000000000000..31bd8b6279f9
--- /dev/null
+++ b/include/basegfx/polygon/b2dpolypolygoncutter.hxx
@@ -0,0 +1,153 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_POLYGON_B2DPOLYPOLYGONCUTTER_HXX
+#define _BGFX_POLYGON_B2DPOLYPOLYGONCUTTER_HXX
+
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ namespace tools
+ {
+ /** Solve all crossovers (aka self-intersections) in a polyPolygon.
+
+ This re-layouts all contained polygons so that the result
+ will contain only non-cutting polygons. For that reason,
+ points will be added at crossover and touch points and the
+ single Polygons may be re-combined. The orientations of
+ the contained polygons in not changed but used as
+ topological information. Self crossovers of the contained
+ sub-polygons are implicitely handled, but to not lose the
+ topological information, it may be necessary to remove
+ self-intersections of the contained sub-polygons in a
+ preparing step and to explicitly correct their
+ orientations.
+ */
+ BASEGFX_DLLPUBLIC B2DPolyPolygon solveCrossovers(const B2DPolyPolygon& rCandidate);
+
+ /** Solve all crossovers (aka self-intersections) in a Polygon
+
+ Same as above, but for single polygons. Result will be
+ free of self-intersections. When result contains multiple
+ polygons, it may be necessary to rearrange their
+ orientations since holes may have been created (use
+ correctOrientations eventually).
+ */
+ BASEGFX_DLLPUBLIC B2DPolyPolygon solveCrossovers(const B2DPolygon& rCandidate);
+
+ /** Strip neutral polygons from PolyPolygon.
+
+ Neutral polygons are ones who's orientation is neutral, so
+ normally they have no volume -> just closed paths. A
+ polygon with the same positive and negative oriented
+ volume is also neutral, so this may not be wanted. It is
+ safe to call with self-intersection-free polygons, though
+ (that's where it's mostly used).
+ */
+ BASEGFX_DLLPUBLIC B2DPolyPolygon stripNeutralPolygons(const B2DPolyPolygon& rCandidate);
+
+ /** Remove unnecessary/non-displayed polygons.
+
+ Works only correct with self-intersection-free
+ polygons. For each polygon, the depth for the PolyPolygon
+ is calculated. The orientation is used to identify holes.
+ Start value for holes is -1, for polygons it's zero. Ech
+ time a polygon is contained in another one, it's depth is
+ increased when inside a polygon, decreased when inside a
+ hole. The result is a depth which e.g. is -1 for holes
+ outside everything, 1 for a polygon covered by another
+ polygon and zero for e.g. holes in a polygon or polygons
+ outside everythig else. In the 2nd step, all polygons
+ with depth other than zero are removed. If bKeepAboveZero
+ is used, all polygons < 1 are removed. The bKeepAboveZero
+ mode is useful for clipping, e.g. just append one polygon
+ to another and use this mode -> only parts where two
+ polygons overlapped will be kept. In combination with
+ correct orientation of the input orientations and the
+ SolveCrossover calls this can be combined for logical
+ polygon operations or polygon clipping.
+ */
+ BASEGFX_DLLPUBLIC B2DPolyPolygon stripDispensablePolygons(const B2DPolyPolygon& rCandidate, bool bKeepAboveZero = false);
+
+ /** Emulate nonzero winding rule filling.
+
+ Geometrically convert PolyPolygons which are proposed to
+ use nonzero fill rule to a representation where evenodd
+ paint will give the same result. To do this all
+ intersections and self-intersections get solved (the
+ polygons will be rearranged if needed). Then all polygons
+ which are inside another one with the same orientation get
+ deleted
+ */
+ BASEGFX_DLLPUBLIC B2DPolyPolygon createNonzeroConform(const B2DPolyPolygon& rCandidate);
+
+ // For convenience: The four basic operations OR, XOR, AND and DIFF for
+ // two PolyPolygons. These are combinations of the above methods. To not be forced
+ // to do evtl. already done preparations twice, You have to do the operations Yourself.
+ //
+ // A source preparation consists of preparing it to be seen as XOR-Rule PolyPolygon,
+ // so it is freed of intersections, self-intersections and the orientations are corrected.
+ // Important is that it will define the same areas as before, but is intersection-free.
+ // As an example think about a single polygon looping in itself and having holes. To
+ // topologically correctly handle this, it is necessary to remove all intersections and
+ // to correct the orientations. The orientation of the isolated holes e.g. will be negative.
+ // Topologically it is necessary to prepare each polygon which is seen as entity. It is
+ // not sufficient just to concatenate them and prepare the result, this may be topologically
+ // different since the simple concatenation will be seen as XOR. To work correctly, You
+ // may need to OR those polygons.
+
+ /// prep for ops - solve self-intersections and intersections, remove neutral parts and check orientations.
+ BASEGFX_DLLPUBLIC B2DPolyPolygon prepareForPolygonOperation(const B2DPolygon& rCandidate);
+ /// prep for ops - solve self-intersections and intersections, remove neutral parts and check orientations.
+ BASEGFX_DLLPUBLIC B2DPolyPolygon prepareForPolygonOperation(const B2DPolyPolygon& rCandidate);
+
+ /// OR: Return all areas where CandidateA or CandidateB exist
+ BASEGFX_DLLPUBLIC B2DPolyPolygon solvePolygonOperationOr(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB);
+
+ /// XOR: Return all areas where CandidateA or CandidateB exist, but not both
+ BASEGFX_DLLPUBLIC B2DPolyPolygon solvePolygonOperationXor(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB);
+
+ /// AND: Return all areas where CandidateA and CandidateB exist
+ BASEGFX_DLLPUBLIC B2DPolyPolygon solvePolygonOperationAnd(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB);
+
+ /// DIFF: Return all areas where CandidateA is not covered by CandidateB (cut B out of A)
+ BASEGFX_DLLPUBLIC B2DPolyPolygon solvePolygonOperationDiff(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB);
+
+ /** merge all single PolyPolygons to a single, OR-ed PolyPolygon
+
+ @param rInput
+ The source PolyPolygons
+
+ @return A single PolyPolygon containing the Or-merged result
+ */
+ BASEGFX_DLLPUBLIC B2DPolyPolygon mergeToSinglePolyPolygon(const B2DPolyPolygonVector& rInput);
+
+ } // end of namespace tools
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+
+#endif /* _BGFX_POLYGON_B2DPOLYPOLYGONCUTTER_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/polygon/b2dpolypolygonfillrule.hxx b/include/basegfx/polygon/b2dpolypolygonfillrule.hxx
new file mode 100644
index 000000000000..390dd9bac9f0
--- /dev/null
+++ b/include/basegfx/polygon/b2dpolypolygonfillrule.hxx
@@ -0,0 +1,54 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_POLYGON_B2DPOLYPOLYGONFILLRULE_HXX
+#define _BGFX_POLYGON_B2DPOLYPOLYGONFILLRULE_HXX
+
+#include <sal/types.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ /** Fill rule to use for poly-polygon filling.
+
+ The fill rule determines which areas are inside, and which are
+ outside the poly-polygon.
+ */
+ enum FillRule
+ {
+ /** Areas, for which a scanline has crossed an odd number of
+ vertices, are regarded 'inside', the remainder 'outside'
+ of the poly-polygon.
+ */
+ FillRule_EVEN_ODD,
+
+ /** For each edge a scanline crosses, a current winding number
+ is updated. Downward edges count +1, upward edges count
+ -1. If the total accumulated winding number for one area
+ is not zero, this area is regarded 'inside', otherwise,
+ 'outside'.
+ */
+ FillRule_NONZERO_WINDING_NUMBER
+ };
+}
+
+#endif /* _BGFX_POLYGON_B2DPOLYPOLYGONFILLRULE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/polygon/b2dpolypolygontools.hxx b/include/basegfx/polygon/b2dpolypolygontools.hxx
new file mode 100644
index 000000000000..29ae3e042133
--- /dev/null
+++ b/include/basegfx/polygon/b2dpolypolygontools.hxx
@@ -0,0 +1,236 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_POLYPOLYGON_B2DPOLYGONTOOLS_HXX
+#define _BGFX_POLYPOLYGON_B2DPOLYGONTOOLS_HXX
+
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/vector/b2dvector.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b3dpolypolygon.hxx>
+#include <vector>
+#include <basegfx/basegfxdllapi.h>
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ // predefinitions
+ class B2DPolyPolygon;
+ class B2DRange;
+
+ namespace tools
+ {
+ // B2DPolyPolygon tools
+
+ // Check and evtl. correct orientations of all contained Polygons so that
+ // the orientations of contained polygons will variate to express areas and
+ // holes
+ BASEGFX_DLLPUBLIC B2DPolyPolygon correctOrientations(const B2DPolyPolygon& rCandidate);
+
+ // make sure polygon with index 0L is not a hole. This may evtl. change the
+ // sequence of polygons, but allows to use polygon with index 0L to
+ // get the correct normal for the whole polyPolygon
+ BASEGFX_DLLPUBLIC B2DPolyPolygon correctOutmostPolygon(const B2DPolyPolygon& rCandidate);
+
+ // Subdivide all contained curves. Use distanceBound value if given.
+ BASEGFX_DLLPUBLIC B2DPolyPolygon adaptiveSubdivideByDistance(const B2DPolyPolygon& rCandidate, double fDistanceBound = 0.0);
+
+ // Subdivide all contained curves. Use distanceBound value if given. Else, a convenient one
+ // is created.
+ BASEGFX_DLLPUBLIC B2DPolyPolygon adaptiveSubdivideByAngle(const B2DPolyPolygon& rCandidate, double fAngleBound = 0.0);
+
+ // Subdivide all contained curves. Use nCount divisions if given. Else, a convenient one
+ // is created.
+ BASEGFX_DLLPUBLIC B2DPolyPolygon adaptiveSubdivideByCount(const B2DPolyPolygon& rCandidate, sal_uInt32 nCount = 0L);
+
+ // isInside test for B2dPoint. On border is not inside as long as not true is given
+ // in bWithBorder flag. It is assumed that the orientations of the given polygon are correct.
+ BASEGFX_DLLPUBLIC bool isInside(const B2DPolyPolygon& rCandidate, const B2DPoint& rPoint, bool bWithBorder = false);
+
+ /** Get the range of a polyPolygon
+
+ For detailed description look at getRange(const B2DPolygon&).
+ This method just expands by the range of every sub-Polygon.
+
+ @param rCandidate
+ The B2DPolyPolygon eventually containing bezier segments
+
+ @return
+ The outer range of the polygon
+ */
+ BASEGFX_DLLPUBLIC B2DRange getRange(const B2DPolyPolygon& rCandidate);
+
+ /** Apply given LineDashing to given polyPolygon
+
+ For a description see applyLineDashing in b2dpolygontoos.hxx
+ */
+ BASEGFX_DLLPUBLIC void applyLineDashing(
+ const B2DPolyPolygon& rCandidate,
+ const ::std::vector<double>& rDotDashArray,
+ B2DPolyPolygon* pLineTarget,
+ B2DPolyPolygon* pGapTarget = 0,
+ double fFullDashDotLen = 0.0);
+
+ // test if point is inside epsilon-range around the given PolyPolygon. Can be used
+ // for HitTesting. The epsilon-range is defined to be the tube around the PolyPolygon
+ // with distance fDistance and rounded edges (start and end point).
+ BASEGFX_DLLPUBLIC bool isInEpsilonRange(const B2DPolyPolygon& rCandidate, const B2DPoint& rTestPosition, double fDistance);
+
+ /** Read poly-polygon from SVG.
+
+ This function imports a poly-polygon from an SVG-D
+ attribute.
+
+ @param o_rPolyPoly
+ The output poly-polygon
+
+ @param rSvgDAttribute
+ A valid SVG-D attribute string
+
+ @param rWrongPositionAfterZ
+ Indicates wheter the generator interprets wrongly
+ the position in the path after Z or z elements
+ https://bugs.freedesktop.org/show_bug.cgi?id=47406
+
+ @return true, if the string was successfully parsed
+ */
+ BASEGFX_DLLPUBLIC bool importFromSvgD( B2DPolyPolygon& o_rPolyPoly,
+ const OUString& rSvgDAttribute, bool bWrongPositionAfterZ = false );
+
+ /** Read poly-polygon from SVG.
+
+ This function imports a poly-polygon from an SVG points
+ attribute (a plain list of coordinate pairs).
+
+ @param o_rPoly
+ The output polygon. Note that svg:points can only define a
+ single polygon
+
+ @param rSvgPointsAttribute
+ A valid SVG points attribute string
+
+ @return true, if the string was successfully parsed
+ */
+ BASEGFX_DLLPUBLIC bool importFromSvgPoints( B2DPolygon& o_rPoly,
+ const OUString& rSvgPointsAttribute );
+
+
+ // grow for polyPolygon. Move all geometry in each point in the direction of the normal in that point
+ // with the given amount. Value may be negative.
+ BASEGFX_DLLPUBLIC B2DPolyPolygon growInNormalDirection(const B2DPolyPolygon& rCandidate, double fValue);
+
+ // This method will correct a pair of polyPolygons where the goal is to keep same point count
+ // to allow direct point association and also to remove self-intersections produced by shrinks.
+ // This method will eventually change both polyPolygons to reach that goal because there are cases
+ // where it is necessary to add new cut points to the original
+ BASEGFX_DLLPUBLIC void correctGrowShrinkPolygonPair(B2DPolyPolygon& rOriginal, B2DPolyPolygon& rGrown);
+
+ // force all sub-polygons to a point count of nSegments
+ BASEGFX_DLLPUBLIC B2DPolyPolygon reSegmentPolyPolygon(const B2DPolyPolygon& rCandidate, sal_uInt32 nSegments);
+
+ // create polygon state at t from 0.0 to 1.0 between the two polygons. Both polygons must have the same
+ // organisation, e.g. same amount of polygons
+ BASEGFX_DLLPUBLIC B2DPolyPolygon interpolate(const B2DPolyPolygon& rOld1, const B2DPolyPolygon& rOld2, double t);
+
+ // create 3d PolyPolygon from given 2d PolyPolygon. The given fZCoordinate is used to expand the
+ // third coordinate.
+ BASEGFX_DLLPUBLIC B3DPolyPolygon createB3DPolyPolygonFromB2DPolyPolygon(const B2DPolyPolygon& rCandidate, double fZCoordinate = 0.0);
+
+ // create 2d PolyPolygon from given 3d PolyPolygon. All coordinates are transformed using the given
+ // matrix and the resulting x,y is used to form the new polygon.
+ BASEGFX_DLLPUBLIC B2DPolyPolygon createB2DPolyPolygonFromB3DPolyPolygon(const B3DPolyPolygon& rCandidate, const B3DHomMatrix& rMat);
+
+ // for each contained edge in each contained polygon calculate the smallest distance. Return the index to the smallest
+ // edge in rEdgeIndex and the index to the polygon in rPolygonIndex. The relative position on the edge is returned in rCut.
+ // If nothing was found (e.g. empty input plygon), DBL_MAX is returned.
+ BASEGFX_DLLPUBLIC double getSmallestDistancePointToPolyPolygon(const B2DPolyPolygon& rCandidate, const B2DPoint& rTestPoint, sal_uInt32& rPolygonIndex, sal_uInt32& rEdgeIndex, double& rCut);
+
+ // distort PolyPolygon. rOriginal describes the original range, where the given points describe the distorted
+ // corresponding points.
+ BASEGFX_DLLPUBLIC B2DPolyPolygon distort(const B2DPolyPolygon& rCandidate, const B2DRange& rOriginal, const B2DPoint& rTopLeft, const B2DPoint& rTopRight, const B2DPoint& rBottomLeft, const B2DPoint& rBottomRight);
+
+ // expand all segments (which are not yet) to curve segments. This is done with setting the control
+ // vectors on the 1/3 resp. 2/3 distances on each segment.
+ BASEGFX_DLLPUBLIC B2DPolyPolygon expandToCurve(const B2DPolyPolygon& rCandidate);
+
+ /** Predicate whether a given poly-polygon is a rectangle.
+
+ @param rPoly
+ PolyPolygon to check
+
+ @return true, if the poly-polygon describes a rectangle
+ (contains exactly one polygon, polygon is closed, and the
+ points are either cw or ccw enumerations of a rectangle's
+ vertices). Note that intermediate points and duplicate
+ points are ignored.
+ */
+ BASEGFX_DLLPUBLIC bool isRectangle( const B2DPolyPolygon& rPoly );
+
+ /** Export poly-polygon to SVG.
+
+ This function exports a poly-polygon into an SVG-D
+ statement. Currently, output of relative point sequences
+ is not yet supported (might cause slightly larger output)
+
+ @param rPolyPoly
+ The poly-polygon to export
+
+ @param bUseRelativeCoordinates
+ When true, all coordinate values are exported as relative
+ to the current position. This tends to save some space,
+ since fewer digits needs to be written.
+
+ @param bDetectQuadraticBeziers
+ When true, the export tries to detect cubic bezier
+ segments in the input polygon, which can be represented by
+ quadratic bezier segments. Note that the generated string
+ causes versions prior to OOo2.0 to crash.
+
+ @return the generated SVG-D statement (the XML d attribute
+ value alone, without any "<path ...>" or "d="...")
+ */
+ BASEGFX_DLLPUBLIC OUString exportToSvgD( const B2DPolyPolygon& rPolyPoly,
+ bool bUseRelativeCoordinates=true,
+ bool bDetectQuadraticBeziers=true );
+
+ // #i76891# Try to remove existing curve segments if they are simply edges
+ BASEGFX_DLLPUBLIC B2DPolyPolygon simplifyCurveSegments(const B2DPolyPolygon& rCandidate);
+
+ /** snap some polygon coordinates to discrete coordinates
+
+ This method allows to snap some polygon points to discrete (integer) values
+ which equals e.g. a snap to discrete coordinates. It will snap points of
+ horizontal and vertical edges
+
+ @param rCandidate
+ The source polygon
+
+ @return
+ The modified version of the source polygon
+ */
+ BASEGFX_DLLPUBLIC B2DPolyPolygon snapPointsOfHorizontalOrVerticalEdges(const B2DPolyPolygon& rCandidate);
+
+ } // end of namespace tools
+} // end of namespace basegfx
+
+#endif /* _BGFX_POLYPOLYGON_B2DPOLYGONTOOLS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/polygon/b2dtrapezoid.hxx b/include/basegfx/polygon/b2dtrapezoid.hxx
new file mode 100644
index 000000000000..43ee9fb37f6c
--- /dev/null
+++ b/include/basegfx/polygon/b2dtrapezoid.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 .
+ */
+
+#ifndef _BGFX_POLYGON_B2DTRAPEZOID_HXX
+#define _BGFX_POLYGON_B2DTRAPEZOID_HXX
+
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <vector>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ // class to hold a single trapezoid
+ class BASEGFX_DLLPUBLIC B2DTrapezoid
+ {
+ private:
+ // Geometry data. YValues are down-oriented, this means bottom should
+ // be bigger than top to be below it. The constructor implementation
+ // guarantees:
+ //
+ // - mfBottomY >= mfTopY
+ // - mfTopXRight >= mfTopXLeft
+ // - mfBottomXRight >= mfBottomXLeft
+ double mfTopXLeft;
+ double mfTopXRight;
+ double mfTopY;
+ double mfBottomXLeft;
+ double mfBottomXRight;
+ double mfBottomY;
+
+ public:
+ // constructor
+ B2DTrapezoid(
+ const double& rfTopXLeft,
+ const double& rfTopXRight,
+ const double& rfTopY,
+ const double& rfBottomXLeft,
+ const double& rfBottomXRight,
+ const double& rfBottomY);
+
+ // data read access
+ const double& getTopXLeft() const { return mfTopXLeft; }
+ const double& getTopXRight() const { return mfTopXRight; }
+ const double& getTopY() const { return mfTopY; }
+ const double& getBottomXLeft() const { return mfBottomXLeft; }
+ const double& getBottomXRight() const { return mfBottomXRight; }
+ const double& getBottomY() const { return mfBottomY; }
+
+ // convenience method to get content as Polygon
+ B2DPolygon getB2DPolygon() const;
+ };
+
+ typedef ::std::vector< B2DTrapezoid > B2DTrapezoidVector;
+
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ namespace tools
+ {
+ // convert SourcePolyPolygon to trapezoids. The trapezoids will be appended to
+ // ro_Result. ro_Result will not be cleared. If SourcePolyPolygon contains curves,
+ // it's default AdaptiveSubdivision will be used.
+ // CAUTION: Trapezoids are oreintation-dependent in the sense that the upper and lower
+ // lines have to be parallel to the X-Axis, thus this subdivision is NOT simply usable
+ // for primitive decompositions. To use it, the shear and rotate parts of the
+ // involved transformations HAVE to be taken into account.
+ BASEGFX_DLLPUBLIC void trapezoidSubdivide(
+ B2DTrapezoidVector& ro_Result,
+ const B2DPolyPolygon& rSourcePolyPolygon);
+
+ // directly create trapezoids from given edge. Depending on the given geometry,
+ // none up to three trapezoids will be created
+ BASEGFX_DLLPUBLIC void createLineTrapezoidFromEdge(
+ B2DTrapezoidVector& ro_Result,
+ const B2DPoint& rPointA,
+ const B2DPoint& rPointB,
+ double fLineWidth = 1.0);
+
+ // create trapezoids for all edges of the given polygon. The closed state of
+ // the polygon is taken into account. If curves are contaned, the default
+ // AdaptiveSubdivision will be used.
+ BASEGFX_DLLPUBLIC void createLineTrapezoidFromB2DPolygon(
+ B2DTrapezoidVector& ro_Result,
+ const B2DPolygon& rPolygon,
+ double fLineWidth = 1.0);
+
+ // create trapezoids for all edges of the given polyPolygon. The closed state of
+ // the PolyPolygon is taken into account. If curves are contaned, the default
+ // AdaptiveSubdivision will be used.
+ BASEGFX_DLLPUBLIC void createLineTrapezoidFromB2DPolyPolygon(
+ B2DTrapezoidVector& ro_Result,
+ const B2DPolyPolygon& rPolyPolygon,
+ double fLineWidth = 1.0);
+
+ } // end of namespace tools
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif /* _BGFX_POLYGON_B2DTRAPEZOID_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/polygon/b3dpolygon.hxx b/include/basegfx/polygon/b3dpolygon.hxx
new file mode 100644
index 000000000000..7199eea9684c
--- /dev/null
+++ b/include/basegfx/polygon/b3dpolygon.hxx
@@ -0,0 +1,130 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_POLYGON_B3DPOLYGON_HXX
+#define _BGFX_POLYGON_B3DPOLYGON_HXX
+
+#include <sal/types.h>
+#include <o3tl/cow_wrapper.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+// predeclarations
+class ImplB3DPolygon;
+
+namespace basegfx
+{
+ class B3DPolygon;
+ class B3DPoint;
+ class B3DHomMatrix;
+ class B3DVector;
+ class B2DPoint;
+ class B2DHomMatrix;
+ class BColor;
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ class BASEGFX_DLLPUBLIC B3DPolygon
+ {
+ public:
+ typedef o3tl::cow_wrapper< ImplB3DPolygon > ImplType;
+
+ private:
+ // internal data.
+ ImplType mpPolygon;
+
+ public:
+ B3DPolygon();
+ B3DPolygon(const B3DPolygon& rPolygon);
+ ~B3DPolygon();
+
+ // assignment operator
+ B3DPolygon& operator=(const B3DPolygon& rPolygon);
+
+ // compare operators
+ bool operator==(const B3DPolygon& rPolygon) const;
+ bool operator!=(const B3DPolygon& rPolygon) const;
+
+ // member count
+ sal_uInt32 count() const;
+
+ // Coordinate interface
+ B3DPoint getB3DPoint(sal_uInt32 nIndex) const;
+ void setB3DPoint(sal_uInt32 nIndex, const B3DPoint& rValue);
+
+ // Coordinate append
+ void append(const B3DPoint& rPoint, sal_uInt32 nCount = 1);
+
+ // BColor interface
+ BColor getBColor(sal_uInt32 nIndex) const;
+ void setBColor(sal_uInt32 nIndex, const BColor& rValue);
+ bool areBColorsUsed() const;
+ void clearBColors();
+
+ // Normals interface
+ B3DVector getNormal() const; // plane normal
+ B3DVector getNormal(sal_uInt32 nIndex) const; // normal in each point
+ void setNormal(sal_uInt32 nIndex, const B3DVector& rValue);
+ void transformNormals(const B3DHomMatrix& rMatrix);
+ bool areNormalsUsed() const;
+ void clearNormals();
+
+ // TextureCoordinate interface
+ B2DPoint getTextureCoordinate(sal_uInt32 nIndex) const;
+ void setTextureCoordinate(sal_uInt32 nIndex, const B2DPoint& rValue);
+ void transformTextureCoordiantes(const B2DHomMatrix& rMatrix);
+ bool areTextureCoordinatesUsed() const;
+ void clearTextureCoordinates();
+
+ // append other 2D polygons
+ void append(const B3DPolygon& rPoly, sal_uInt32 nIndex = 0, sal_uInt32 nCount = 0);
+
+ // remove
+ void remove(sal_uInt32 nIndex, sal_uInt32 nCount = 1);
+
+ // clear all points
+ void clear();
+
+ // closed state
+ bool isClosed() const;
+ void setClosed(bool bNew);
+
+ // flip polygon direction
+ void flip();
+
+ // test if Polygon has double points
+ bool hasDoublePoints() const;
+
+ // remove double points, at the begin/end and follow-ups, too
+ void removeDoublePoints();
+
+ // apply transformation given in matrix form to the polygon
+ void transform(const B3DHomMatrix& rMatrix);
+ };
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+
+#endif /* _BGFX_POLYGON_B3DPOLYGON_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/polygon/b3dpolygontools.hxx b/include/basegfx/polygon/b3dpolygontools.hxx
new file mode 100644
index 000000000000..9ed32b42fb90
--- /dev/null
+++ b/include/basegfx/polygon/b3dpolygontools.hxx
@@ -0,0 +1,135 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_POLYGON_B3DPOLYGONTOOLS_HXX
+#define _BGFX_POLYGON_B3DPOLYGONTOOLS_HXX
+
+#include <basegfx/point/b3dpoint.hxx>
+#include <basegfx/vector/b3dvector.hxx>
+#include <basegfx/polygon/b3dpolypolygon.hxx>
+#include <basegfx/vector/b2enums.hxx>
+#include <vector>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ // predefinitions
+ class B3DPolygon;
+ class B3DRange;
+
+ namespace tools
+ {
+ // B3DPolygon tools
+
+ /** Check if given polygon is closed. This is kind of a
+ 'classic' method to support old polygon definitions.
+ Those old polygon definitions define the closed state
+ of the polygon using identical start and endpoints. This
+ method corrects this (removes double start/end points)
+ and sets the Closed()-state of the polygon correctly.
+ */
+ BASEGFX_DLLPUBLIC void checkClosed(B3DPolygon& rCandidate);
+
+ // Get successor and predecessor indices. Returning the same index means there
+ // is none. Same for successor.
+ BASEGFX_DLLPUBLIC sal_uInt32 getIndexOfSuccessor(sal_uInt32 nIndex, const B3DPolygon& rCandidate);
+
+ // get size of polygon. Control vectors are included in that ranges.
+ BASEGFX_DLLPUBLIC B3DRange getRange(const B3DPolygon& rCandidate);
+
+ // get normal vector of polygon
+ BASEGFX_DLLPUBLIC B3DVector getNormal(const B3DPolygon& rCandidate);
+
+ // get area of polygon
+ BASEGFX_DLLPUBLIC double getArea(const ::basegfx::B3DPolygon& rCandidate);
+
+ // get length of polygon
+ BASEGFX_DLLPUBLIC double getLength(const B3DPolygon& rCandidate);
+
+ /** Apply given LineDashing to given polygon
+
+ For a description see applyLineDashing in b2dpolygontoos.hxx
+ */
+ BASEGFX_DLLPUBLIC void applyLineDashing(
+ const B3DPolygon& rCandidate,
+ const ::std::vector<double>& rDotDashArray,
+ B3DPolyPolygon* pLineTarget,
+ B3DPolyPolygon* pGapTarget = 0,
+ double fFullDashDotLen = 0.0);
+
+ /** Create/replace normals for given 3d geometry with default normals from given center to outside.
+ rCandidate: the 3d geometry to change
+ rCenter: the center of the 3d geometry
+ */
+ BASEGFX_DLLPUBLIC B3DPolygon applyDefaultNormalsSphere( const B3DPolygon& rCandidate, const B3DPoint& rCenter);
+
+ /** invert normals for given 3d geometry.
+ */
+ BASEGFX_DLLPUBLIC B3DPolygon invertNormals( const B3DPolygon& rCandidate);
+
+ /** Create/replace texture coordinates for given 3d geometry with parallel projected one
+ rRange: the full range of the 3d geometry
+ If bChangeX, x texture coordinate will be recalculated.
+ If bChangeY, y texture coordinate will be recalculated.
+ */
+ BASEGFX_DLLPUBLIC B3DPolygon applyDefaultTextureCoordinatesParallel( const B3DPolygon& rCandidate, const B3DRange& rRange, bool bChangeX = true, bool bChangeY = true);
+
+ /** Create/replace texture coordinates for given 3d geometry with spherical one
+ rCenter: the centre of the used 3d geometry
+ If bChangeX, x texture coordinate will be recalculated.
+ If bChangeY, y texture coordinate will be recalculated.
+ */
+ BASEGFX_DLLPUBLIC B3DPolygon applyDefaultTextureCoordinatesSphere( const B3DPolygon& rCandidate, const B3DPoint& rCenter, bool bChangeX = true, bool bChangeY = true);
+
+ // isInside tests for B3DPoint. On border is not inside as long as not true is given in bWithBorder flag.
+ BASEGFX_DLLPUBLIC bool isInside(const B3DPolygon& rCandidate, const B3DPoint& rPoint, bool bWithBorder = false);
+
+ // calculates if given point is on given line, taking care of the numerical epsilon
+ BASEGFX_DLLPUBLIC bool isPointOnLine(const B3DPoint& rStart, const B3DPoint& rEnd, const B3DPoint& rCandidate, bool bWithPoints = false);
+
+ // calculates if given point is on given polygon, taking care of the numerical epsilon. Uses
+ // isPointOnLine internally
+ BASEGFX_DLLPUBLIC bool isPointOnPolygon(const B3DPolygon& rCandidate, const B3DPoint& rPoint, bool bWithPoints = true);
+
+ // helper to get a fCut position between a plane (given with normal and a point)
+ // and a line given by start and end point
+ BASEGFX_DLLPUBLIC bool getCutBetweenLineAndPlane(const B3DVector& rPlaneNormal, const B3DPoint& rPlanePoint, const B3DPoint& rEdgeStart, const B3DPoint& rEdgeEnd, double& fCut);
+
+ /** snap some polygon coordinates to discrete coordinates
+
+ This method allows to snap some polygon points to discrete (integer) values
+ which equals e.g. a snap to discrete coordinates. It will snap points of
+ horizontal and vertical edges
+
+ @param rCandidate
+ The source polygon
+
+ @return
+ The modified version of the source polygon
+ */
+ BASEGFX_DLLPUBLIC B3DPolygon snapPointsOfHorizontalOrVerticalEdges(const B3DPolygon& rCandidate);
+
+ } // end of namespace tools
+} // end of namespace basegfx
+
+#endif /* _BGFX_POLYGON_B3DPOLYGONTOOLS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/polygon/b3dpolypolygon.hxx b/include/basegfx/polygon/b3dpolypolygon.hxx
new file mode 100644
index 000000000000..d67da6ad690b
--- /dev/null
+++ b/include/basegfx/polygon/b3dpolypolygon.hxx
@@ -0,0 +1,117 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_POLYGON_B3DPOLYPOLYGON_HXX
+#define _BGFX_POLYGON_B3DPOLYPOLYGON_HXX
+
+#include <sal/types.h>
+#include <o3tl/cow_wrapper.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+// predeclarations
+class ImplB3DPolyPolygon;
+
+namespace basegfx
+{
+ class B3DPolygon;
+ class B3DHomMatrix;
+ class B2DHomMatrix;
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ class BASEGFX_DLLPUBLIC B3DPolyPolygon
+ {
+ public:
+ typedef o3tl::cow_wrapper< ImplB3DPolyPolygon > ImplType;
+
+ private:
+ ImplType mpPolyPolygon;
+
+ public:
+ B3DPolyPolygon();
+ B3DPolyPolygon(const B3DPolyPolygon& rPolyPolygon);
+ explicit B3DPolyPolygon(const B3DPolygon& rPolygon);
+ ~B3DPolyPolygon();
+
+ // assignment operator
+ B3DPolyPolygon& operator=(const B3DPolyPolygon& rPolyPolygon);
+
+ // compare operators
+ bool operator==(const B3DPolyPolygon& rPolyPolygon) const;
+ bool operator!=(const B3DPolyPolygon& rPolyPolygon) const;
+
+ // polygon interface
+ sal_uInt32 count() const;
+
+ // B3DPolygon interface
+ B3DPolygon getB3DPolygon(sal_uInt32 nIndex) const;
+ void setB3DPolygon(sal_uInt32 nIndex, const B3DPolygon& rPolygon);
+
+ // BColor interface
+ bool areBColorsUsed() const;
+ void clearBColors();
+
+ // Normals interface
+ void transformNormals(const B3DHomMatrix& rMatrix);
+ bool areNormalsUsed() const;
+ void clearNormals();
+
+ // TextureCoordinate interface
+ void transformTextureCoordiantes(const B2DHomMatrix& rMatrix);
+ bool areTextureCoordinatesUsed() const;
+ void clearTextureCoordinates();
+
+ // append single polygon
+ void append(const B3DPolygon& rPolygon, sal_uInt32 nCount = 1);
+
+ // append multiple polygons
+ void append(const B3DPolyPolygon& rPolyPolygon);
+
+ // remove
+ void remove(sal_uInt32 nIndex, sal_uInt32 nCount = 1);
+
+ // reset to empty state
+ void clear();
+
+ // flip polygon direction
+ void flip();
+
+ // test if PolyPolygon has double points
+ bool hasDoublePoints() const;
+
+ // remove double points, at the begin/end and follow-ups, too
+ void removeDoublePoints();
+
+ // apply transformation given in matrix form to the polygon
+ void transform(const basegfx::B3DHomMatrix& rMatrix);
+
+ // polygon iterators (same iterator validity conditions as for vector)
+ const B3DPolygon* begin() const;
+ const B3DPolygon* end() const;
+ B3DPolygon* begin();
+ B3DPolygon* end();
+ };
+} // end of namespace basegfx
+
+#endif /* _BGFX_POLYGON_B3DPOLYPOLYGON_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/polygon/b3dpolypolygontools.hxx b/include/basegfx/polygon/b3dpolypolygontools.hxx
new file mode 100644
index 000000000000..a50167f9b4de
--- /dev/null
+++ b/include/basegfx/polygon/b3dpolypolygontools.hxx
@@ -0,0 +1,133 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_POLYPOLYGON_B3DPOLYGONTOOLS_HXX
+#define _BGFX_POLYPOLYGON_B3DPOLYGONTOOLS_HXX
+
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/vector/b2dvector.hxx>
+#include <vector>
+#include <basegfx/numeric/ftools.hxx>
+#include <basegfx/point/b3dpoint.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ // predefinitions
+ class B3DPolyPolygon;
+ class B3DRange;
+
+ namespace tools
+ {
+ // B3DPolyPolygon tools
+
+ // get size of PolyPolygon. Control vectors are included in that ranges.
+ BASEGFX_DLLPUBLIC B3DRange getRange(const B3DPolyPolygon& rCandidate);
+
+ /** Create a unit 3D line polyPolygon which defines a cube.
+ */
+ BASEGFX_DLLPUBLIC B3DPolyPolygon createUnitCubePolyPolygon();
+
+ /** Create a unit 3D fill polyPolygon which defines a cube.
+ */
+ BASEGFX_DLLPUBLIC B3DPolyPolygon createUnitCubeFillPolyPolygon();
+
+ /** Create a 3D line polyPolygon from a B3DRange which defines a cube.
+ */
+ BASEGFX_DLLPUBLIC B3DPolyPolygon createCubePolyPolygonFromB3DRange( const B3DRange& rRange);
+
+ /** Create a 3D fill polyPolygon from a B3DRange which defines a cube.
+ */
+ BASEGFX_DLLPUBLIC B3DPolyPolygon createCubeFillPolyPolygonFromB3DRange( const B3DRange& rRange);
+
+ /** Create a unit 3D line polyPolygon which defines a sphere with the given count of hor and ver segments.
+ Result will be centered at (0.0, 0.0, 0.0) and sized [-1.0 .. 1.0] in all dimensions.
+ If nHorSeg == 0 and/or nVerSeg == 0, a default will be calculated to have a step at least each 15 degrees.
+ With VerStart, VerStop and hor range in cartesian may be specified to create a partial sphere only.
+ */
+ BASEGFX_DLLPUBLIC B3DPolyPolygon createUnitSpherePolyPolygon(
+ sal_uInt32 nHorSeg = 0L, sal_uInt32 nVerSeg = 0L,
+ double fVerStart = F_PI2, double fVerStop = -F_PI2,
+ double fHorStart = 0.0, double fHorStop = F_2PI);
+
+ /** Create a 3D line polyPolygon from a B3DRange which defines a sphere with the given count of hor and ver segments.
+ If nHorSeg == 0 and/or nVerSeg == 0, a default will be calculated to have a step at least each 15 degrees.
+ With VerStart, VerStop and hor range in cartesian may be specified to create a partial sphere only.
+ */
+ BASEGFX_DLLPUBLIC B3DPolyPolygon createSpherePolyPolygonFromB3DRange(
+ const B3DRange& rRange,
+ sal_uInt32 nHorSeg = 0L, sal_uInt32 nVerSeg = 0L,
+ double fVerStart = F_PI2, double fVerStop = -F_PI2,
+ double fHorStart = 0.0, double fHorStop = F_2PI);
+
+ /** same as createUnitSpherePolyPolygon, but creates filled polygons (closed and oriented)
+ There is one extra, the bool bNormals defines if normals will be set, default is false
+ */
+ BASEGFX_DLLPUBLIC B3DPolyPolygon createUnitSphereFillPolyPolygon(
+ sal_uInt32 nHorSeg = 0L, sal_uInt32 nVerSeg = 0L,
+ bool bNormals = false,
+ double fVerStart = F_PI2, double fVerStop = -F_PI2,
+ double fHorStart = 0.0, double fHorStop = F_2PI);
+
+ /** same as createSpherePolyPolygonFromB3DRange, but creates filled polygons (closed and oriented)
+ There is one extra, the bool bNormals defines if normals will be set, default is false
+ */
+ BASEGFX_DLLPUBLIC B3DPolyPolygon createSphereFillPolyPolygonFromB3DRange(
+ const B3DRange& rRange,
+ sal_uInt32 nHorSeg = 0L, sal_uInt32 nVerSeg = 0L,
+ bool bNormals = false,
+ double fVerStart = F_PI2, double fVerStop = -F_PI2,
+ double fHorStart = 0.0, double fHorStop = F_2PI);
+
+ /** Create/replace normals for given 3d geometry with default normals from given center to outside.
+ rCandidate: the 3d geometry to change
+ rCenter: the center of the 3d geometry
+ */
+ BASEGFX_DLLPUBLIC B3DPolyPolygon applyDefaultNormalsSphere( const B3DPolyPolygon& rCandidate, const B3DPoint& rCenter);
+
+ /** invert normals for given 3d geometry.
+ */
+ BASEGFX_DLLPUBLIC B3DPolyPolygon invertNormals( const B3DPolyPolygon& rCandidate);
+
+ /** Create/replace texture coordinates for given 3d geometry with parallel projected one
+ rRange: the full range of the 3d geometry
+ If bChangeX, x texture coordinate will be recalculated.
+ If bChangeY, y texture coordinate will be recalculated.
+ */
+ BASEGFX_DLLPUBLIC B3DPolyPolygon applyDefaultTextureCoordinatesParallel( const B3DPolyPolygon& rCandidate, const B3DRange& rRange, bool bChangeX = true, bool bChangeY = true);
+
+ /** Create/replace texture coordinates for given 3d geometry with spherical one
+ rCenter: the centre of the used 3d geometry
+ If bChangeX, x texture coordinate will be recalculated.
+ If bChangeY, y texture coordinate will be recalculated.
+ */
+ BASEGFX_DLLPUBLIC B3DPolyPolygon applyDefaultTextureCoordinatesSphere( const B3DPolyPolygon& rCandidate, const B3DPoint& rCenter, bool bChangeX = true, bool bChangeY = true);
+
+ // isInside test for B3DPoint. On border is not inside as long as not true is given
+ // in bWithBorder flag. It is assumed that the orientations of the given polygon are correct.
+ BASEGFX_DLLPUBLIC bool isInside(const B3DPolyPolygon& rCandidate, const B3DPoint& rPoint, bool bWithBorder = false);
+
+ } // end of namespace tools
+} // end of namespace basegfx
+
+#endif /* _BGFX_POLYPOLYGON_B3DPOLYGONTOOLS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/range/b1drange.hxx b/include/basegfx/range/b1drange.hxx
new file mode 100644
index 000000000000..ffe704a1b845
--- /dev/null
+++ b/include/basegfx/range/b1drange.hxx
@@ -0,0 +1,174 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RANGE_B1DRANGE_HXX
+#define _BGFX_RANGE_B1DRANGE_HXX
+
+#include <basegfx/range/basicrange.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+
+namespace basegfx
+{
+ class B1IRange;
+
+ /** A one-dimensional interval over doubles
+
+ This is a set of real numbers, bounded by a lower and an upper
+ value. All inbetween values are included in the set (see also
+ http://en.wikipedia.org/wiki/Interval_%28mathematics%29).
+
+ The set is closed, i.e. the upper and the lower bound are
+ included (if you're used to the notation - we're talking about
+ [a,b] here, compared to half-open [a,b) or open intervals
+ (a,b)).
+
+ That means, isInside(val) will return true also for values of
+ val=a or val=b.
+ */
+ class B1DRange
+ {
+ ::basegfx::BasicRange< double, DoubleTraits > maRange;
+
+ public:
+ B1DRange() {}
+
+ /// Create degenerate interval consisting of a single double number
+ explicit B1DRange(double fStartValue)
+ : maRange(fStartValue)
+ {
+ }
+
+ /// Create proper interval between the two given double values
+ B1DRange(double fStartValue1, double fStartValue2)
+ : maRange(fStartValue1)
+ {
+ expand(fStartValue2);
+ }
+
+ /** Check if the interval set is empty
+
+ @return false, if no value is in this set - having a
+ single value included will already return true.
+ */
+ bool isEmpty() const
+ {
+ return maRange.isEmpty();
+ }
+
+ /// reset the object to empty state again, clearing all values
+ void reset()
+ {
+ maRange.reset();
+ }
+
+ bool operator==( const B1DRange& rRange ) const
+ {
+ return (maRange == rRange.maRange);
+ }
+
+ bool operator!=( const B1DRange& rRange ) const
+ {
+ return (maRange != rRange.maRange);
+ }
+
+ bool equal(const B1DRange& rRange) const
+ {
+ return (maRange.equal(rRange.maRange));
+ }
+
+ /// get lower bound of the set. returns arbitrary values for empty sets.
+ double getMinimum() const
+ {
+ return maRange.getMinimum();
+ }
+
+ /// get upper bound of the set. returns arbitrary values for empty sets.
+ double getMaximum() const
+ {
+ return maRange.getMaximum();
+ }
+
+ /// return difference between upper and lower value. returns 0 for empty sets.
+ double getRange() const
+ {
+ return maRange.getRange();
+ }
+
+ /// return middle of upper and lower value. returns 0 for empty sets.
+ double getCenter() const
+ {
+ return maRange.getCenter();
+ }
+
+ /// yields true if value is contained in set
+ bool isInside(double fValue) const
+ {
+ return maRange.isInside(fValue);
+ }
+
+ /// yields true if rRange is inside, or equal to set
+ bool isInside(const B1DRange& rRange) const
+ {
+ return maRange.isInside(rRange.maRange);
+ }
+
+ /// yields true if rRange at least partly inside set
+ bool overlaps(const B1DRange& rRange) const
+ {
+ return maRange.overlaps(rRange.maRange);
+ }
+
+ /// yields true if overlaps(rRange) does, and the overlap is larger than infinitesimal
+ bool overlapsMore(const B1DRange& rRange) const
+ {
+ return maRange.overlapsMore(rRange.maRange);
+ }
+
+ /// add fValue to the set, expanding as necessary
+ void expand(double fValue)
+ {
+ maRange.expand(fValue);
+ }
+
+ /// add rRange to the set, expanding as necessary
+ void expand(const B1DRange& rRange)
+ {
+ maRange.expand(rRange.maRange);
+ }
+
+ /// calc set intersection
+ void intersect(const B1DRange& rRange)
+ {
+ maRange.intersect(rRange.maRange);
+ }
+
+ /// grow set by fValue on both sides
+ void grow(double fValue)
+ {
+ maRange.grow(fValue);
+ }
+ };
+
+} // end of namespace basegfx
+
+
+#endif /* _BGFX_RANGE_B1DRANGE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/range/b1ibox.hxx b/include/basegfx/range/b1ibox.hxx
new file mode 100644
index 000000000000..7c81e37c1288
--- /dev/null
+++ b/include/basegfx/range/b1ibox.hxx
@@ -0,0 +1,164 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RANGE_B1IBOX_HXX
+#define _BGFX_RANGE_B1IBOX_HXX
+
+#include <basegfx/range/basicbox.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+
+namespace basegfx
+{
+ /** A one-dimensional interval over integers
+
+ This is most easily depicted as a set of integers, bounded by
+ a lower and an upper value - but excluding the upper
+ value. All inbetween values are included in the set (see also
+ http://en.wikipedia.org/wiki/Interval_%28mathematics%29).
+
+ The set is half-open, i.e. the lower bound is included, the
+ upper bound not (if you're used to the notation - we're
+ talking about [a,b) here, compared to closed [a,b] or fully
+ open intervals (a,b)).
+
+ If you don't need a half-open interval, check B1IRange.
+
+ That means, isInside(val) will return true also for values of
+ val=a, but not for val=b.
+
+ @see B1IRange
+ */
+ class B1IBox
+ {
+ ::basegfx::BasicBox maRange;
+
+ public:
+ B1IBox() {}
+
+ /// Create degenerate interval that's still empty
+ explicit B1IBox(sal_Int32 nStartValue)
+ : maRange(nStartValue)
+ {
+ }
+
+ /// Create proper interval between the two given values
+ B1IBox(sal_Int32 nStartValue1, sal_Int32 nStartValue2)
+ : maRange(nStartValue1)
+ {
+ expand(nStartValue2);
+ }
+
+ /** Check if the interval set is empty
+
+ @return false, if no value is in this set - having a
+ single value included will still return false.
+ */
+ bool isEmpty() const
+ {
+ return maRange.isEmpty();
+ }
+
+ /// reset the object to empty state again, clearing all values
+ void reset()
+ {
+ maRange.reset();
+ }
+
+ bool operator==( const B1IBox& rBox ) const
+ {
+ return (maRange == rBox.maRange);
+ }
+
+ bool operator!=( const B1IBox& rBox ) const
+ {
+ return (maRange != rBox.maRange);
+ }
+
+ /// get lower bound of the set. returns arbitrary values for empty sets.
+ sal_Int32 getMinimum() const
+ {
+ return maRange.getMinimum();
+ }
+
+ /// get upper bound of the set. returns arbitrary values for empty sets.
+ sal_Int32 getMaximum() const
+ {
+ return maRange.getMaximum();
+ }
+
+ /// return difference between upper and lower value. returns 0 for empty sets.
+ Int32Traits::DifferenceType getRange() const
+ {
+ return maRange.getRange();
+ }
+
+ /// return middle of upper and lower value. returns 0 for empty sets.
+ double getCenter() const
+ {
+ return maRange.getCenter();
+ }
+
+ /// yields true if value is contained in set
+ bool isInside(sal_Int32 nValue) const
+ {
+ return maRange.isInside(nValue);
+ }
+
+ /// yields true if rRange is inside, or equal to set
+ bool isInside(const B1IBox& rBox) const
+ {
+ return maRange.isInside(rBox.maRange);
+ }
+
+ /// yields true if rRange at least partly inside set
+ bool overlaps(const B1IBox& rBox) const
+ {
+ return maRange.overlaps(rBox.maRange);
+ }
+
+ /// add nValue to the set, expanding as necessary
+ void expand(sal_Int32 nValue)
+ {
+ maRange.expand(nValue);
+ }
+
+ /// add rBox to the set, expanding as necessary
+ void expand(const B1IBox& rBox)
+ {
+ maRange.expand(rBox.maRange);
+ }
+
+ /// calc set intersection
+ void intersect(const B1IBox& rBox)
+ {
+ maRange.intersect(rBox.maRange);
+ }
+
+ /// grow set by nValue on both sides
+ void grow(sal_Int32 nValue)
+ {
+ maRange.grow(nValue);
+ }
+ };
+} // end of namespace basegfx
+
+#endif /* _BGFX_RANGE_B1IBOX_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/range/b1irange.hxx b/include/basegfx/range/b1irange.hxx
new file mode 100644
index 000000000000..0ba5878fb0c8
--- /dev/null
+++ b/include/basegfx/range/b1irange.hxx
@@ -0,0 +1,169 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RANGE_B1IRANGE_HXX
+#define _BGFX_RANGE_B1IRANGE_HXX
+
+#include <basegfx/range/basicrange.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+
+namespace basegfx
+{
+ /** A one-dimensional interval over integers
+
+ This is a set of real numbers, bounded by a lower and an upper
+ value. All inbetween values are included in the set (see also
+ http://en.wikipedia.org/wiki/Interval_%28mathematics%29).
+
+ Probably you rather want B1IBox for integers.
+
+ The set is closed, i.e. the upper and the lower bound are
+ included (if you're used to the notation - we're talking about
+ [a,b] here, compared to half-open [a,b) or open intervals
+ (a,b)).
+
+ That means, isInside(val) will return true also for values of
+ val=a or val=b.
+
+ @see B1IBox
+ */
+ class B1IRange
+ {
+ ::basegfx::BasicRange< sal_Int32, Int32Traits > maRange;
+
+ public:
+ B1IRange() {}
+
+ /// Create degenerate interval consisting of a single double number
+ explicit B1IRange(sal_Int32 nStartValue)
+ : maRange(nStartValue)
+ {
+ }
+
+ /// Create proper interval between the two given values
+ B1IRange(sal_Int32 nStartValue1, sal_Int32 nStartValue2)
+ : maRange(nStartValue1)
+ {
+ expand(nStartValue2);
+ }
+
+ /** Check if the interval set is empty
+
+ @return false, if no value is in this set - having a
+ single value included will already return true.
+ */
+ bool isEmpty() const
+ {
+ return maRange.isEmpty();
+ }
+
+ /// reset the object to empty state again, clearing all values
+ void reset()
+ {
+ maRange.reset();
+ }
+
+ bool operator==( const B1IRange& rRange ) const
+ {
+ return (maRange == rRange.maRange);
+ }
+
+ bool operator!=( const B1IRange& rRange ) const
+ {
+ return (maRange != rRange.maRange);
+ }
+
+ /// get lower bound of the set. returns arbitrary values for empty sets.
+ sal_Int32 getMinimum() const
+ {
+ return maRange.getMinimum();
+ }
+
+ /// get upper bound of the set. returns arbitrary values for empty sets.
+ sal_Int32 getMaximum() const
+ {
+ return maRange.getMaximum();
+ }
+
+ /// return difference between upper and lower value. returns 0 for empty sets.
+ Int32Traits::DifferenceType getRange() const
+ {
+ return maRange.getRange();
+ }
+
+ /// return middle of upper and lower value. returns 0 for empty sets.
+ double getCenter() const
+ {
+ return maRange.getCenter();
+ }
+
+ /// yields true if value is contained in set
+ bool isInside(sal_Int32 nValue) const
+ {
+ return maRange.isInside(nValue);
+ }
+
+ /// yields true if rRange is inside, or equal to set
+ bool isInside(const B1IRange& rRange) const
+ {
+ return maRange.isInside(rRange.maRange);
+ }
+
+ /// yields true if rRange at least partly inside set
+ bool overlaps(const B1IRange& rRange) const
+ {
+ return maRange.overlaps(rRange.maRange);
+ }
+
+ /// yields true if overlaps(rRange) does, and the overlap is larger than infinitesimal
+ bool overlapsMore(const B1IRange& rRange) const
+ {
+ return maRange.overlapsMore(rRange.maRange);
+ }
+
+ /// add nValue to the set, expanding as necessary
+ void expand(sal_Int32 nValue)
+ {
+ maRange.expand(nValue);
+ }
+
+ /// add rRange to the set, expanding as necessary
+ void expand(const B1IRange& rRange)
+ {
+ maRange.expand(rRange.maRange);
+ }
+
+ /// calc set intersection
+ void intersect(const B1IRange& rRange)
+ {
+ maRange.intersect(rRange.maRange);
+ }
+
+ /// grow set by nValue on both sides
+ void grow(sal_Int32 nValue)
+ {
+ maRange.grow(nValue);
+ }
+ };
+} // end of namespace basegfx
+
+#endif /* _BGFX_RANGE_B1IRANGE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/range/b2dconnectedranges.hxx b/include/basegfx/range/b2dconnectedranges.hxx
new file mode 100644
index 000000000000..f1d65196bd8f
--- /dev/null
+++ b/include/basegfx/range/b2dconnectedranges.hxx
@@ -0,0 +1,257 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RANGE_B2DCONNECTEDRANGES_HXX
+#define _BGFX_RANGE_B2DCONNECTEDRANGES_HXX
+
+#include <osl/diagnose.h>
+#include <basegfx/range/b2drange.hxx>
+#include <list>
+#include <utility>
+#include <algorithm>
+
+
+namespace basegfx
+{
+ /** Calculate connected ranges from input ranges.
+
+ This template constructs a list of connected ranges from the
+ given input ranges. That is, the output will contain a set of
+ ranges, itself containing a number of input ranges, which will
+ be mutually non-intersecting.
+
+ Example:
+ <code>
+ -------------------
+ | -------|
+ | | ||
+ | --- | ||
+ | | | -------| --------
+ | | +--------- | | |
+ | --+ | | | |
+ | | | | --------
+ | ---------- |
+ -------------------
+ </code
+
+ Here, the outer rectangles represent the output
+ ranges. Contained are the input rectangles that comprise these
+ output ranges.
+
+ @tpl UserData
+ User data to be stored along with the range, to later identify
+ which range went into which connected component. Must be
+ assignable, default- and copy-constructible.
+ */
+ template< typename UserData > class B2DConnectedRanges
+ {
+ public:
+ /// Type of the basic entity (rect + user data)
+ typedef ::std::pair< B2DRange, UserData > ComponentType;
+ typedef ::std::list< ComponentType > ComponentListType;
+
+ /// List of (intersecting) components, plus overall bounds
+ struct ConnectedComponents
+ {
+ ComponentListType maComponentList;
+ B2DRange maTotalBounds;
+ };
+
+ typedef ::std::list< ConnectedComponents > ConnectedComponentsType;
+
+
+ /// Create the range calculator
+ B2DConnectedRanges() :
+ maDisjunctAggregatesList(),
+ maTotalBounds()
+ {
+ }
+
+ /** Query total bounds of all added ranges.
+
+ @return the union bound rect over all added ranges.
+ */
+ B2DRange getBounds() const
+ {
+ return maTotalBounds;
+ }
+
+ /** Add an additional range.
+
+ This method integrates a new range into the connected
+ ranges lists. The method has a worst-case time complexity
+ of O(n^2), with n denoting the number of already added
+ ranges (typically, for well-behaved input, it is O(n)
+ though).
+ */
+ void addRange( const B2DRange& rRange,
+ const UserData& rUserData )
+ {
+ // check whether fast path is possible: if new range is
+ // outside accumulated total range, can add it as a
+ // separate component right away.
+ const bool bNotOutsideEverything(
+ maTotalBounds.overlaps( rRange ) );
+
+ // update own global bounds range
+ maTotalBounds.expand( rRange );
+
+ // assemble anything intersecting with rRange into
+ // this new connected component
+ ConnectedComponents aNewConnectedComponent;
+
+ // as at least rRange will be a member of
+ // aNewConnectedComponent (will be added below), can
+ // preset the overall bounds here.
+ aNewConnectedComponent.maTotalBounds = rRange;
+
+
+ //
+ // STAGE 1: Search for intersecting maDisjunctAggregatesList entries
+ // =================================================================
+ //
+
+ // if rRange is empty, it will intersect with no
+ // maDisjunctAggregatesList member. Thus, we can safe us
+ // the check.
+ // if rRange is outside all other rectangle, skip here,
+ // too
+ if( bNotOutsideEverything &&
+ !rRange.isEmpty() )
+ {
+ typename ConnectedComponentsType::iterator aCurrAggregate;
+ typename ConnectedComponentsType::iterator aLastAggregate;
+
+ // flag, determining whether we touched one or more of
+ // the maDisjunctAggregatesList entries. _If_ we did,
+ // we have to repeat the intersection process, because
+ // these changes might have generated new
+ // intersections.
+ bool bSomeAggregatesChanged;
+
+ // loop, until bSomeAggregatesChanged stays false
+ do
+ {
+ // only continue loop if 'intersects' branch below was hit
+ bSomeAggregatesChanged = false;
+
+ // iterate over all current members of maDisjunctAggregatesList
+ for( aCurrAggregate=maDisjunctAggregatesList.begin(),
+ aLastAggregate=maDisjunctAggregatesList.end();
+ aCurrAggregate != aLastAggregate; )
+ {
+ // first check if current component's bounds
+ // are empty. This ensures that distinct empty
+ // components are not merged into one
+ // aggregate. As a matter of fact, they have
+ // no position and size.
+
+ if( !aCurrAggregate->maTotalBounds.isEmpty() &&
+ aCurrAggregate->maTotalBounds.overlaps(
+ aNewConnectedComponent.maTotalBounds ) )
+ {
+ // union the intersecting
+ // maDisjunctAggregatesList element into
+ // aNewConnectedComponent
+
+ // calc union bounding box
+ aNewConnectedComponent.maTotalBounds.expand( aCurrAggregate->maTotalBounds );
+
+ // extract all aCurrAggregate components
+ // to aNewConnectedComponent
+ aNewConnectedComponent.maComponentList.splice(
+ aNewConnectedComponent.maComponentList.end(),
+ aCurrAggregate->maComponentList );
+
+ // remove and delete aCurrAggregate entry
+ // from list (we've gutted it's content
+ // above). list::erase() will update our
+ // iterator with the predecessor here.
+ aCurrAggregate = maDisjunctAggregatesList.erase( aCurrAggregate );
+
+ // at least one aggregate changed, need to rescan everything
+ bSomeAggregatesChanged = true;
+ }
+ else
+ {
+ aCurrAggregate++;
+ }
+ }
+ }
+ while( bSomeAggregatesChanged );
+ }
+
+ //
+ // STAGE 2: Add newly generated connected component list element
+ // =============================================================
+ //
+
+ // add new component to the end of the component list
+ aNewConnectedComponent.maComponentList.push_back(
+ ComponentType( rRange, rUserData ) );
+
+ // do some consistency checks (aka post conditions)
+ OSL_ENSURE( !aNewConnectedComponent.maComponentList.empty(),
+ "B2DConnectedRanges::addRange(): empty aggregate list" );
+ OSL_ENSURE( !aNewConnectedComponent.maTotalBounds.isEmpty() ||
+ (aNewConnectedComponent.maTotalBounds.isEmpty() &&
+ aNewConnectedComponent.maComponentList.size() == 1),
+ "B2DConnectedRanges::addRange(): empty ranges must be solitary");
+
+ // add aNewConnectedComponent as a new entry to
+ // maDisjunctAggregatesList
+ maDisjunctAggregatesList.push_back( aNewConnectedComponent );
+ }
+
+ /** Apply a functor to each of the disjunct component
+ aggregates.
+
+ @param aFunctor
+ Functor to apply. Must provide an operator( const ConnectedComponents& ).
+
+ @return a copy of the functor, as applied to all aggregates.
+ */
+ template< typename UnaryFunctor > UnaryFunctor forEachAggregate( UnaryFunctor aFunctor ) const
+ {
+ return ::std::for_each( maDisjunctAggregatesList.begin(),
+ maDisjunctAggregatesList.end(),
+ aFunctor );
+ }
+
+ private:
+ // default: disabled copy/assignment
+ B2DConnectedRanges(const B2DConnectedRanges&);
+ B2DConnectedRanges& operator=( const B2DConnectedRanges& );
+
+ /** Current list of disjunct sets of connected components
+
+ Each entry corresponds to one of the top-level rectangles
+ in the drawing above.
+ */
+ ConnectedComponentsType maDisjunctAggregatesList;
+
+ /** Global bound rect over all added ranges.
+ */
+ B2DRange maTotalBounds;
+ };
+}
+
+#endif /* _BGFX_RANGE_B2DCONNECTEDRANGES_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/range/b2dpolyrange.hxx b/include/basegfx/range/b2dpolyrange.hxx
new file mode 100644
index 000000000000..b910062d11a3
--- /dev/null
+++ b/include/basegfx/range/b2dpolyrange.hxx
@@ -0,0 +1,94 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RANGE_B2DPOLYRANGE_HXX
+#define _BGFX_RANGE_B2DPOLYRANGE_HXX
+
+#include <o3tl/cow_wrapper.hxx>
+#include <boost/tuple/tuple.hpp>
+#include <basegfx/vector/b2enums.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ class B2DTuple;
+ class B2DRange;
+ class B2DPolyPolygon;
+ class ImplB2DPolyRange;
+
+ /** Multiple ranges in one object.
+
+ This class combines multiple ranges in one object, providing a
+ total, enclosing range for it.
+
+ You can use this class e.g. when updating views containing
+ rectangular objects. Add each modified object to a
+ B2DMultiRange, then test each viewable object against
+ intersection with the multi range.
+
+ Similar in spirit to the poly-polygon vs. polygon relationship.
+
+ Note that comparable to polygons, a poly-range can also
+ contain 'holes' - this is encoded via polygon orientation at
+ the poly-polygon, and via explicit flags for the poly-range.
+ */
+ class BASEGFX_DLLPUBLIC B2DPolyRange
+ {
+ public:
+ typedef boost::tuple<B2DRange,B2VectorOrientation> ElementType ;
+
+ B2DPolyRange();
+ ~B2DPolyRange();
+
+ /** Create a multi range with exactly one containing range
+ */
+ B2DPolyRange( const B2DPolyRange& );
+ B2DPolyRange& operator=( const B2DPolyRange& );
+
+ bool operator==(const B2DPolyRange&) const;
+ bool operator!=(const B2DPolyRange&) const;
+
+ /// Number of included ranges
+ sal_uInt32 count() const;
+
+ ElementType getElement(sal_uInt32 nIndex) const;
+
+ // insert/append a single range
+ void appendElement(const B2DRange& rRange, B2VectorOrientation eOrient, sal_uInt32 nCount = 1);
+
+ void clear();
+
+ /** Test whether given range overlaps one or more of the
+ included ranges. Does *not* use overall range, but checks
+ individually.
+ */
+ bool overlaps( const B2DRange& rRange ) const;
+
+ /** Request a poly-polygon with solved cross-overs
+ */
+ B2DPolyPolygon solveCrossovers() const;
+
+ private:
+ o3tl::cow_wrapper< ImplB2DPolyRange > mpImpl;
+ };
+}
+
+#endif /* _BGFX_RANGE_B2DPOLYRANGE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/range/b2drange.hxx b/include/basegfx/range/b2drange.hxx
new file mode 100644
index 000000000000..1f3884c1c9ce
--- /dev/null
+++ b/include/basegfx/range/b2drange.hxx
@@ -0,0 +1,320 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RANGE_B2DRANGE_HXX
+#define _BGFX_RANGE_B2DRANGE_HXX
+
+#include <basegfx/vector/b2dvector.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/tuple/b2dtuple.hxx>
+#include <basegfx/range/basicrange.hxx>
+#include <vector>
+#include <basegfx/basegfxdllapi.h>
+
+
+namespace basegfx
+{
+ // predeclarations
+ class B2IRange;
+ class B2DHomMatrix;
+
+ /** A two-dimensional interval over doubles
+
+ This is a set of real numbers, bounded by a lower and an upper
+ pair. All inbetween values are included in the set (see also
+ http://en.wikipedia.org/wiki/Interval_%28mathematics%29).
+
+ The set is closed, i.e. the upper and the lower bound are
+ included (if you're used to the notation - we're talking about
+ [a,b] here, compared to half-open [a,b) or open intervals
+ (a,b)).
+
+ That means, isInside(val) will return true also for values of
+ val=a or val=b.
+
+ @see B1DRange
+ */
+ class B2DRange
+ {
+ public:
+ typedef double ValueType;
+ typedef DoubleTraits TraitsType;
+
+ B2DRange() {}
+
+ /// Create degenerate interval consisting of a single point
+ explicit B2DRange(const B2DTuple& rTuple)
+ : maRangeX(rTuple.getX()),
+ maRangeY(rTuple.getY())
+ {
+ }
+
+ /// Create proper interval between the two given double pairs
+ B2DRange(double x1,
+ double y1,
+ double x2,
+ double y2)
+ : maRangeX(x1),
+ maRangeY(y1)
+ {
+ maRangeX.expand(x2);
+ maRangeY.expand(y2);
+ }
+
+ /// Create proper interval between the two given points
+ B2DRange(const B2DTuple& rTuple1,
+ const B2DTuple& rTuple2)
+ : maRangeX(rTuple1.getX()),
+ maRangeY(rTuple1.getY())
+ {
+ expand( rTuple2 );
+ }
+
+ BASEGFX_DLLPUBLIC explicit B2DRange(const B2IRange& rRange);
+
+ /** Check if the interval set is empty
+
+ @return false, if no value is in this set - having a
+ single point included will already return true.
+ */
+ bool isEmpty() const
+ {
+ return (
+ maRangeX.isEmpty()
+ || maRangeY.isEmpty()
+ );
+ }
+
+ /// reset the object to empty state again, clearing all values
+ void reset()
+ {
+ maRangeX.reset();
+ maRangeY.reset();
+ }
+
+ bool operator==( const B2DRange& rRange ) const
+ {
+ return (maRangeX == rRange.maRangeX
+ && maRangeY == rRange.maRangeY);
+ }
+
+ bool operator!=( const B2DRange& rRange ) const
+ {
+ return (maRangeX != rRange.maRangeX
+ || maRangeY != rRange.maRangeY);
+ }
+
+ bool equal(const B2DRange& rRange) const
+ {
+ return (maRangeX.equal(rRange.maRangeX)
+ && maRangeY.equal(rRange.maRangeY));
+ }
+
+ /// get lower bound of the set. returns arbitrary values for empty sets.
+ double getMinX() const
+ {
+ return maRangeX.getMinimum();
+ }
+
+ /// get lower bound of the set. returns arbitrary values for empty sets.
+ double getMinY() const
+ {
+ return maRangeY.getMinimum();
+ }
+
+ /// get upper bound of the set. returns arbitrary values for empty sets.
+ double getMaxX() const
+ {
+ return maRangeX.getMaximum();
+ }
+
+ /// get upper bound of the set. returns arbitrary values for empty sets.
+ double getMaxY() const
+ {
+ return maRangeY.getMaximum();
+ }
+
+ /// return difference between upper and lower X value. returns 0 for empty sets.
+ double getWidth() const
+ {
+ return maRangeX.getRange();
+ }
+
+ /// return difference between upper and lower Y value. returns 0 for empty sets.
+ double getHeight() const
+ {
+ return maRangeY.getRange();
+ }
+
+ /// get lower bound of the set. returns arbitrary values for empty sets.
+ B2DPoint getMinimum() const
+ {
+ return B2DPoint(
+ maRangeX.getMinimum(),
+ maRangeY.getMinimum()
+ );
+ }
+
+ /// get upper bound of the set. returns arbitrary values for empty sets.
+ B2DPoint getMaximum() const
+ {
+ return B2DPoint(
+ maRangeX.getMaximum(),
+ maRangeY.getMaximum()
+ );
+ }
+
+ /// return difference between upper and lower point. returns (0,0) for empty sets.
+ B2DVector getRange() const
+ {
+ return B2DVector(
+ maRangeX.getRange(),
+ maRangeY.getRange()
+ );
+ }
+
+ /// return center point of set. returns (0,0) for empty sets.
+ B2DPoint getCenter() const
+ {
+ return B2DPoint(
+ maRangeX.getCenter(),
+ maRangeY.getCenter()
+ );
+ }
+
+ /// return center X value of set. returns 0 for empty sets.
+ double getCenterX() const
+ {
+ return maRangeX.getCenter();
+ }
+
+ /// return center Y value of set. returns 0 for empty sets.
+ double getCenterY() const
+ {
+ return maRangeY.getCenter();
+ }
+
+ /// yields true if given point is contained in set
+ bool isInside(const B2DTuple& rTuple) const
+ {
+ return (
+ maRangeX.isInside(rTuple.getX())
+ && maRangeY.isInside(rTuple.getY())
+ );
+ }
+
+ /// yields true if rRange is inside, or equal to set
+ bool isInside(const B2DRange& rRange) const
+ {
+ return (
+ maRangeX.isInside(rRange.maRangeX)
+ && maRangeY.isInside(rRange.maRangeY)
+ );
+ }
+
+ /// yields true if rRange at least partly inside set
+ bool overlaps(const B2DRange& rRange) const
+ {
+ return (
+ maRangeX.overlaps(rRange.maRangeX)
+ && maRangeY.overlaps(rRange.maRangeY)
+ );
+ }
+
+ /// yields true if overlaps(rRange) does, and the overlap is larger than infinitesimal
+ bool overlapsMore(const B2DRange& rRange) const
+ {
+ return (
+ maRangeX.overlapsMore(rRange.maRangeX)
+ && maRangeY.overlapsMore(rRange.maRangeY)
+ );
+ }
+
+ /// add point to the set, expanding as necessary
+ void expand(const B2DTuple& rTuple)
+ {
+ maRangeX.expand(rTuple.getX());
+ maRangeY.expand(rTuple.getY());
+ }
+
+ /// add rRange to the set, expanding as necessary
+ void expand(const B2DRange& rRange)
+ {
+ maRangeX.expand(rRange.maRangeX);
+ maRangeY.expand(rRange.maRangeY);
+ }
+
+ /// calc set intersection
+ void intersect(const B2DRange& rRange)
+ {
+ maRangeX.intersect(rRange.maRangeX);
+ maRangeY.intersect(rRange.maRangeY);
+ }
+
+ /// grow set by fValue on all sides
+ void grow(double fValue)
+ {
+ maRangeX.grow(fValue);
+ maRangeY.grow(fValue);
+ }
+
+ BASEGFX_DLLPUBLIC void transform(const B2DHomMatrix& rMatrix);
+
+ private:
+ typedef ::basegfx::BasicRange< ValueType, TraitsType > MyBasicRange;
+
+ MyBasicRange maRangeX;
+ MyBasicRange maRangeY;
+ };
+
+ /** Round double to nearest integer for 2D range
+
+ @return the nearest integer for this range
+ */
+ BASEGFX_DLLPUBLIC B2IRange fround(const B2DRange& rRange);
+
+ /** Compute the set difference of the two given ranges
+
+ This method calculates the symmetric difference (aka XOR)
+ between the two given ranges, and returning the resulting
+ ranges. Thus, the result will contain all areas where one, but
+ not both ranges lie.
+
+ @param o_rResult
+ Result vector. The up to four difference ranges are returned
+ within this vector
+
+ @param rFirst
+ The first range
+
+ @param rSecond
+ The second range
+
+ @return the input vector
+ */
+ BASEGFX_DLLPUBLIC ::std::vector< B2DRange >& computeSetDifference( ::std::vector< B2DRange >& o_rResult,
+ const B2DRange& rFirst,
+ const B2DRange& rSecond );
+
+} // end of namespace basegfx
+
+
+#endif /* _BGFX_RANGE_B2DRANGE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/range/b2drangeclipper.hxx b/include/basegfx/range/b2drangeclipper.hxx
new file mode 100644
index 000000000000..99bc8763369d
--- /dev/null
+++ b/include/basegfx/range/b2drangeclipper.hxx
@@ -0,0 +1,45 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RANGE_B2DRANGECLIPPER_HXX
+#define _BGFX_RANGE_B2DRANGECLIPPER_HXX
+
+#include <basegfx/range/b2dpolyrange.hxx>
+#include <vector>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ namespace tools
+ {
+ /** Extract poly-polygon w/o self-intersections from poly-range
+
+ Similar to the solveCrossovers(const B2DPolyPolygon&)
+ method, this one calculates a self-intersection-free
+ poly-polygon with the same topology, and encoding
+ inside/outsidedness via polygon orientation and layering.
+ */
+ BASEGFX_DLLPUBLIC B2DPolyPolygon solveCrossovers(const std::vector<B2DRange>& rRanges,
+ const std::vector<B2VectorOrientation>& rOrientations);
+ }
+}
+
+#endif /* _BGFX_RANGE_B2DRANGECLIPPER_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/range/b2drectangle.hxx b/include/basegfx/range/b2drectangle.hxx
new file mode 100644
index 000000000000..8d4715d64410
--- /dev/null
+++ b/include/basegfx/range/b2drectangle.hxx
@@ -0,0 +1,36 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RANGE_B2DRECTANGLE_HXX
+#define _BGFX_RANGE_B2DRECTANGLE_HXX
+
+#include <basegfx/range/b2drange.hxx>
+
+namespace basegfx
+{
+ // syntactic sugar: a B2DRange exactly models a Rectangle, thus,
+ // for interface clarity, we provide an alias name
+
+ /// Alias name for interface clarity (not everybody is aware of the identity)
+ typedef B2DRange B2DRectangle;
+}
+
+#endif /* _BGFX_RANGE_B2DRECTANGLE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/range/b2ibox.hxx b/include/basegfx/range/b2ibox.hxx
new file mode 100644
index 000000000000..7c182a4ab327
--- /dev/null
+++ b/include/basegfx/range/b2ibox.hxx
@@ -0,0 +1,261 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RANGE_B2IBOX_HXX
+#define _BGFX_RANGE_B2IBOX_HXX
+
+#include <basegfx/point/b2ipoint.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/tuple/b2ituple.hxx>
+#include <basegfx/tuple/b2i64tuple.hxx>
+#include <basegfx/range/basicbox.hxx>
+#include <vector>
+#include <basegfx/basegfxdllapi.h>
+
+
+namespace basegfx
+{
+ /** A two-dimensional interval over integers
+
+ This is most easily depicted as a set of integers, bounded by
+ a lower and an upper value - but excluding the upper
+ value. All inbetween values are included in the set (see also
+ http://en.wikipedia.org/wiki/Interval_%28mathematics%29).
+
+ The set is half-open, i.e. the lower bound is included, the
+ upper bound not (if you're used to the notation - we're
+ talking about [a,b) here, compared to closed [a,b] or fully
+ open intervals (a,b)).
+
+ If you don't need a half-open interval, check B2IRange.
+
+ That means, isInside(val) will return true also for values of
+ val=a, but not for val=b.
+
+ Alternatively, consider this a rectangle, where the rightmost
+ pixel column and the bottommost pixel row are excluded - this
+ is much like polygon filling. As a result, filling a given
+ rectangle with basebmp::BitmapDevice::fillPolyPolygon(), will
+ affect exactly the same set of pixel as isInside() would
+ return true for.
+
+ @see B2IRange
+ */
+ class B2IBox
+ {
+ public:
+ typedef sal_Int32 ValueType;
+ typedef Int32Traits TraitsType;
+
+ B2IBox() {}
+
+ /// Create degenerate interval that's still empty
+ explicit B2IBox(const B2ITuple& rTuple)
+ : maRangeX(rTuple.getX()),
+ maRangeY(rTuple.getY())
+ {
+ }
+
+ /// Create proper interval between the two given points
+ B2IBox(sal_Int32 x1,
+ sal_Int32 y1,
+ sal_Int32 x2,
+ sal_Int32 y2) :
+ maRangeX(x1),
+ maRangeY(y1)
+ {
+ maRangeX.expand(x2);
+ maRangeY.expand(y2);
+ }
+
+ /// Create proper interval between the two given points
+ B2IBox(const B2ITuple& rTuple1,
+ const B2ITuple& rTuple2) :
+ maRangeX(rTuple1.getX()),
+ maRangeY(rTuple1.getY())
+ {
+ expand( rTuple2 );
+ }
+
+ /** Check if the interval set is empty
+
+ @return false, if no value is in this set - having a
+ single value included will still return false.
+ */
+ bool isEmpty() const
+ {
+ return maRangeX.isEmpty() || maRangeY.isEmpty();
+ }
+
+ /// reset the object to empty state again, clearing all values
+ void reset()
+ {
+ maRangeX.reset();
+ maRangeY.reset();
+ }
+
+ bool operator==( const B2IBox& rBox ) const
+ {
+ return (maRangeX == rBox.maRangeX
+ && maRangeY == rBox.maRangeY);
+ }
+
+ bool operator!=( const B2IBox& rBox ) const
+ {
+ return (maRangeX != rBox.maRangeX
+ || maRangeY != rBox.maRangeY);
+ }
+
+ /// get lower bound of the set. returns arbitrary values for empty sets.
+ sal_Int32 getMinX() const
+ {
+ return maRangeX.getMinimum();
+ }
+
+ /// get lower bound of the set. returns arbitrary values for empty sets.
+ sal_Int32 getMinY() const
+ {
+ return maRangeY.getMinimum();
+ }
+
+ /// get upper bound of the set. returns arbitrary values for empty sets.
+ sal_Int32 getMaxX() const
+ {
+ return maRangeX.getMaximum();
+ }
+
+ /// get upper bound of the set. returns arbitrary values for empty sets.
+ sal_Int32 getMaxY() const
+ {
+ return maRangeY.getMaximum();
+ }
+
+ /// return difference between upper and lower X value. returns 0 for empty sets.
+ sal_Int64 getWidth() const
+ {
+ return maRangeX.getRange();
+ }
+
+ /// return difference between upper and lower Y value. returns 0 for empty sets.
+ sal_Int64 getHeight() const
+ {
+ return maRangeY.getRange();
+ }
+
+ /// get lower bound of the set. returns arbitrary values for empty sets.
+ B2IPoint getMinimum() const
+ {
+ return B2IPoint(
+ maRangeX.getMinimum(),
+ maRangeY.getMinimum()
+ );
+ }
+
+ /// get upper bound of the set. returns arbitrary values for empty sets.
+ B2IPoint getMaximum() const
+ {
+ return B2IPoint(
+ maRangeX.getMaximum(),
+ maRangeY.getMaximum()
+ );
+ }
+
+ /// return difference between upper and lower value. returns (0,0) for empty sets.
+ B2I64Tuple getRange() const
+ {
+ return B2I64Tuple(
+ maRangeX.getRange(),
+ maRangeY.getRange()
+ );
+ }
+
+ /// return center point of set. returns (0,0) for empty sets.
+ B2DPoint getCenter() const
+ {
+ return B2DPoint(
+ maRangeX.getCenter(),
+ maRangeY.getCenter()
+ );
+ }
+
+ /// yields true if point is contained in set
+ bool isInside(const B2ITuple& rTuple) const
+ {
+ return (
+ maRangeX.isInside(rTuple.getX())
+ && maRangeY.isInside(rTuple.getY())
+ );
+ }
+
+ /// yields true if rBox is inside, or equal to set
+ bool isInside(const B2IBox& rBox) const
+ {
+ return (
+ maRangeX.isInside(rBox.maRangeX)
+ && maRangeY.isInside(rBox.maRangeY)
+ );
+ }
+
+ /// yields true if rBox at least partly inside set
+ bool overlaps(const B2IBox& rBox) const
+ {
+ return (
+ maRangeX.overlaps(rBox.maRangeX)
+ && maRangeY.overlaps(rBox.maRangeY)
+ );
+ }
+
+ /// add point to the set, expanding as necessary
+ void expand(const B2ITuple& rTuple)
+ {
+ maRangeX.expand(rTuple.getX());
+ maRangeY.expand(rTuple.getY());
+ }
+
+ /// add rBox to the set, expanding as necessary
+ void expand(const B2IBox& rBox)
+ {
+ maRangeX.expand(rBox.maRangeX);
+ maRangeY.expand(rBox.maRangeY);
+ }
+
+ /// calc set intersection
+ void intersect(const B2IBox& rBox)
+ {
+ maRangeX.intersect(rBox.maRangeX);
+ maRangeY.intersect(rBox.maRangeY);
+ }
+
+ /// grow set by nValue on all sides
+ void grow(sal_Int32 nValue)
+ {
+ maRangeX.grow(nValue);
+ maRangeY.grow(nValue);
+ }
+
+ private:
+ BasicBox maRangeX;
+ BasicBox maRangeY;
+ };
+
+} // end of namespace basegfx
+
+#endif /* _BGFX_RANGE_B2IBOX_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/range/b2irange.hxx b/include/basegfx/range/b2irange.hxx
new file mode 100644
index 000000000000..60f9fc79fa67
--- /dev/null
+++ b/include/basegfx/range/b2irange.hxx
@@ -0,0 +1,287 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RANGE_B2IRANGE_HXX
+#define _BGFX_RANGE_B2IRANGE_HXX
+
+#include <basegfx/point/b2ipoint.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/tuple/b2ituple.hxx>
+#include <basegfx/tuple/b2i64tuple.hxx>
+#include <basegfx/range/basicrange.hxx>
+#include <vector>
+#include <basegfx/basegfxdllapi.h>
+
+
+namespace basegfx
+{
+ /** A two-dimensional interval over integers
+
+ This is a set of real numbers, bounded by a lower and an upper
+ pair. All inbetween values are included in the set (see also
+ http://en.wikipedia.org/wiki/Interval_%28mathematics%29).
+
+ Probably you rather want B2IBox for integers.
+
+ The set is closed, i.e. the upper and the lower bound are
+ included (if you're used to the notation - we're talking about
+ [a,b] here, compared to half-open [a,b) or open intervals
+ (a,b)).
+
+ That means, isInside(val) will return true also for values of
+ val=a or val=b.
+
+ @see B2IBox
+ */
+ class B2IRange
+ {
+ public:
+ typedef sal_Int32 ValueType;
+ typedef Int32Traits TraitsType;
+
+ B2IRange() {}
+
+ /// Create degenerate interval consisting of a single point
+ explicit B2IRange(const B2ITuple& rTuple)
+ : maRangeX(rTuple.getX()),
+ maRangeY(rTuple.getY())
+ {
+ }
+
+ /// Create proper interval between the two given integer pairs
+ B2IRange(sal_Int32 x1,
+ sal_Int32 y1,
+ sal_Int32 x2,
+ sal_Int32 y2)
+ : maRangeX(x1),
+ maRangeY(y1)
+ {
+ maRangeX.expand(x2);
+ maRangeY.expand(y2);
+ }
+
+ /// Create proper interval between the two given points
+ B2IRange(const B2ITuple& rTuple1,
+ const B2ITuple& rTuple2)
+ : maRangeX(rTuple1.getX()),
+ maRangeY(rTuple1.getY())
+ {
+ expand( rTuple2 );
+ }
+
+ /** Check if the interval set is empty
+
+ @return false, if no value is in this set - having a
+ single point included will already return true.
+ */
+ bool isEmpty() const
+ {
+ return maRangeX.isEmpty() || maRangeY.isEmpty();
+ }
+
+ /// reset the object to empty state again, clearing all values
+ void reset()
+ {
+ maRangeX.reset();
+ maRangeY.reset();
+ }
+
+ bool operator==( const B2IRange& rRange ) const
+ {
+ return (maRangeX == rRange.maRangeX
+ && maRangeY == rRange.maRangeY);
+ }
+
+ bool operator!=( const B2IRange& rRange ) const
+ {
+ return (maRangeX != rRange.maRangeX
+ || maRangeY != rRange.maRangeY);
+ }
+
+ /// get lower bound of the set. returns arbitrary values for empty sets.
+ sal_Int32 getMinX() const
+ {
+ return maRangeX.getMinimum();
+ }
+
+ /// get lower bound of the set. returns arbitrary values for empty sets.
+ sal_Int32 getMinY() const
+ {
+ return maRangeY.getMinimum();
+ }
+
+ /// get upper bound of the set. returns arbitrary values for empty sets.
+ sal_Int32 getMaxX() const
+ {
+ return maRangeX.getMaximum();
+ }
+
+ /// get upper bound of the set. returns arbitrary values for empty sets.
+ sal_Int32 getMaxY() const
+ {
+ return maRangeY.getMaximum();
+ }
+
+ /// return difference between upper and lower X value. returns 0 for empty sets.
+ sal_Int64 getWidth() const
+ {
+ return maRangeX.getRange();
+ }
+
+ /// return difference between upper and lower Y value. returns 0 for empty sets.
+ sal_Int64 getHeight() const
+ {
+ return maRangeY.getRange();
+ }
+
+ /// get lower bound of the set. returns arbitrary values for empty sets.
+ B2IPoint getMinimum() const
+ {
+ return B2IPoint(
+ maRangeX.getMinimum(),
+ maRangeY.getMinimum()
+ );
+ }
+
+ /// get upper bound of the set. returns arbitrary values for empty sets.
+ B2IPoint getMaximum() const
+ {
+ return B2IPoint(
+ maRangeX.getMaximum(),
+ maRangeY.getMaximum()
+ );
+ }
+
+ /// return difference between upper and lower point. returns (0,0) for empty sets.
+ B2I64Tuple getRange() const
+ {
+ return B2I64Tuple(
+ maRangeX.getRange(),
+ maRangeY.getRange()
+ );
+ }
+
+ /// return center point of set. returns (0,0) for empty sets.
+ B2DPoint getCenter() const
+ {
+ return B2DPoint(
+ maRangeX.getCenter(),
+ maRangeY.getCenter()
+ );
+ }
+
+ /// yields true if given point is contained in set
+ bool isInside(const B2ITuple& rTuple) const
+ {
+ return (
+ maRangeX.isInside(rTuple.getX())
+ && maRangeY.isInside(rTuple.getY())
+ );
+ }
+
+ /// yields true if rRange is inside, or equal to set
+ bool isInside(const B2IRange& rRange) const
+ {
+ return (
+ maRangeX.isInside(rRange.maRangeX)
+ && maRangeY.isInside(rRange.maRangeY)
+ );
+ }
+
+ /// yields true if rRange at least partly inside set
+ bool overlaps(const B2IRange& rRange) const
+ {
+ return (
+ maRangeX.overlaps(rRange.maRangeX)
+ && maRangeY.overlaps(rRange.maRangeY)
+ );
+ }
+
+ /// yields true if overlaps(rRange) does, and the overlap is larger than infinitesimal
+ bool overlapsMore(const B2IRange& rRange) const
+ {
+ return (
+ maRangeX.overlapsMore(rRange.maRangeX)
+ && maRangeY.overlapsMore(rRange.maRangeY)
+ );
+ }
+
+ /// add point to the set, expanding as necessary
+ void expand(const B2ITuple& rTuple)
+ {
+ maRangeX.expand(rTuple.getX());
+ maRangeY.expand(rTuple.getY());
+ }
+
+ /// add rRange to the set, expanding as necessary
+ void expand(const B2IRange& rRange)
+ {
+ maRangeX.expand(rRange.maRangeX);
+ maRangeY.expand(rRange.maRangeY);
+ }
+
+ /// calc set intersection
+ void intersect(const B2IRange& rRange)
+ {
+ maRangeX.intersect(rRange.maRangeX);
+ maRangeY.intersect(rRange.maRangeY);
+ }
+
+ /// grow set by nValue on all sides
+ void grow(sal_Int32 nValue)
+ {
+ maRangeX.grow(nValue);
+ maRangeY.grow(nValue);
+ }
+
+ private:
+ typedef ::basegfx::BasicRange< ValueType, TraitsType > MyBasicRange;
+
+ MyBasicRange maRangeX;
+ MyBasicRange maRangeY;
+ };
+
+ /** Compute the set difference of the two given ranges
+
+ This method calculates the symmetric difference (aka XOR)
+ between the two given ranges, and returning the resulting
+ ranges. Thus, the result will contain all areas where one, but
+ not both ranges lie.
+
+ @param o_rResult
+ Result vector. The up to four difference ranges are returned
+ within this vector
+
+ @param rFirst
+ The first range
+
+ @param rSecond
+ The second range
+
+ @return the input vector
+ */
+ BASEGFX_DLLPUBLIC ::std::vector< B2IRange >& computeSetDifference( ::std::vector< B2IRange >& o_rResult,
+ const B2IRange& rFirst,
+ const B2IRange& rSecond );
+
+} // end of namespace basegfx
+
+#endif /* _BGFX_RANGE_B2IRANGE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/range/b2irectangle.hxx b/include/basegfx/range/b2irectangle.hxx
new file mode 100644
index 000000000000..40792732ab1d
--- /dev/null
+++ b/include/basegfx/range/b2irectangle.hxx
@@ -0,0 +1,36 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RANGE_B2IRECTANGLE_HXX
+#define _BGFX_RANGE_B2IRECTANGLE_HXX
+
+#include <basegfx/range/b2irange.hxx>
+
+namespace basegfx
+{
+ // syntactic sugar: a B2IRange exactly models a Rectangle, thus,
+ // for interface clarity, we provide an alias name
+
+ /// Alias name for interface clarity (not everybody is aware of the identity)
+ typedef B2IRange B2IRectangle;
+}
+
+#endif /* _BGFX_RANGE_B2IRECTANGLE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/range/b3drange.hxx b/include/basegfx/range/b3drange.hxx
new file mode 100644
index 000000000000..7b17f04e4964
--- /dev/null
+++ b/include/basegfx/range/b3drange.hxx
@@ -0,0 +1,273 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RANGE_B3DRANGE_HXX
+#define _BGFX_RANGE_B3DRANGE_HXX
+
+#include <basegfx/vector/b3dvector.hxx>
+#include <basegfx/point/b3dpoint.hxx>
+#include <basegfx/tuple/b3dtuple.hxx>
+#include <basegfx/range/basicrange.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ // predeclarations
+ class B3IRange;
+ class B3DHomMatrix;
+
+ class B3DRange
+ {
+ typedef ::basegfx::BasicRange< double, DoubleTraits > MyBasicRange;
+
+ MyBasicRange maRangeX;
+ MyBasicRange maRangeY;
+ MyBasicRange maRangeZ;
+
+ public:
+ B3DRange() {}
+
+ explicit B3DRange(const B3DTuple& rTuple)
+ : maRangeX(rTuple.getX()),
+ maRangeY(rTuple.getY()),
+ maRangeZ(rTuple.getZ())
+ {
+ }
+
+ B3DRange(double x1,
+ double y1,
+ double z1,
+ double x2,
+ double y2,
+ double z2)
+ : maRangeX(x1),
+ maRangeY(y1),
+ maRangeZ(z1)
+ {
+ maRangeX.expand(x2);
+ maRangeY.expand(y2);
+ maRangeZ.expand(z2);
+ }
+
+ B3DRange(const B3DTuple& rTuple1,
+ const B3DTuple& rTuple2)
+ : maRangeX(rTuple1.getX()),
+ maRangeY(rTuple1.getY()),
+ maRangeZ(rTuple1.getZ())
+ {
+ expand(rTuple2);
+ }
+
+ bool isEmpty() const
+ {
+ return (
+ maRangeX.isEmpty()
+ || maRangeY.isEmpty()
+ || maRangeZ.isEmpty()
+ );
+ }
+
+ void reset()
+ {
+ maRangeX.reset();
+ maRangeY.reset();
+ maRangeZ.reset();
+ }
+
+ bool operator==( const B3DRange& rRange ) const
+ {
+ return (maRangeX == rRange.maRangeX
+ && maRangeY == rRange.maRangeY
+ && maRangeZ == rRange.maRangeZ);
+ }
+
+ bool operator!=( const B3DRange& rRange ) const
+ {
+ return (maRangeX != rRange.maRangeX
+ || maRangeY != rRange.maRangeY
+ || maRangeZ != rRange.maRangeZ);
+ }
+
+ bool equal(const B3DRange& rRange) const
+ {
+ return (maRangeX.equal(rRange.maRangeX)
+ && maRangeY.equal(rRange.maRangeY)
+ && maRangeZ.equal(rRange.maRangeZ));
+ }
+
+ double getMinX() const
+ {
+ return maRangeX.getMinimum();
+ }
+
+ double getMinY() const
+ {
+ return maRangeY.getMinimum();
+ }
+
+ double getMinZ() const
+ {
+ return maRangeZ.getMinimum();
+ }
+
+ double getMaxX() const
+ {
+ return maRangeX.getMaximum();
+ }
+
+ double getMaxY() const
+ {
+ return maRangeY.getMaximum();
+ }
+
+ double getMaxZ() const
+ {
+ return maRangeZ.getMaximum();
+ }
+
+ double getWidth() const
+ {
+ return maRangeX.getRange();
+ }
+
+ double getHeight() const
+ {
+ return maRangeY.getRange();
+ }
+
+ double getDepth() const
+ {
+ return maRangeZ.getRange();
+ }
+
+ B3DPoint getMinimum() const
+ {
+ return B3DPoint(
+ maRangeX.getMinimum(),
+ maRangeY.getMinimum(),
+ maRangeZ.getMinimum()
+ );
+ }
+
+ B3DPoint getMaximum() const
+ {
+ return B3DPoint(
+ maRangeX.getMaximum(),
+ maRangeY.getMaximum(),
+ maRangeZ.getMaximum()
+ );
+ }
+
+ B3DVector getRange() const
+ {
+ return B3DVector(
+ maRangeX.getRange(),
+ maRangeY.getRange(),
+ maRangeZ.getRange()
+ );
+ }
+
+ B3DPoint getCenter() const
+ {
+ return B3DPoint(
+ maRangeX.getCenter(),
+ maRangeY.getCenter(),
+ maRangeZ.getCenter()
+ );
+ }
+
+ double getCenterX() const
+ {
+ return maRangeX.getCenter();
+ }
+
+ double getCenterY() const
+ {
+ return maRangeY.getCenter();
+ }
+
+ double getCenterZ() const
+ {
+ return maRangeZ.getCenter();
+ }
+
+ bool isInside(const B3DTuple& rTuple) const
+ {
+ return (
+ maRangeX.isInside(rTuple.getX())
+ && maRangeY.isInside(rTuple.getY())
+ && maRangeZ.isInside(rTuple.getZ())
+ );
+ }
+
+ bool isInside(const B3DRange& rRange) const
+ {
+ return (
+ maRangeX.isInside(rRange.maRangeX)
+ && maRangeY.isInside(rRange.maRangeY)
+ && maRangeZ.isInside(rRange.maRangeZ)
+ );
+ }
+
+ bool overlaps(const B3DRange& rRange) const
+ {
+ return (
+ maRangeX.overlaps(rRange.maRangeX)
+ && maRangeY.overlaps(rRange.maRangeY)
+ && maRangeZ.overlaps(rRange.maRangeZ)
+ );
+ }
+
+ void expand(const B3DTuple& rTuple)
+ {
+ maRangeX.expand(rTuple.getX());
+ maRangeY.expand(rTuple.getY());
+ maRangeZ.expand(rTuple.getZ());
+ }
+
+ void expand(const B3DRange& rRange)
+ {
+ maRangeX.expand(rRange.maRangeX);
+ maRangeY.expand(rRange.maRangeY);
+ maRangeZ.expand(rRange.maRangeZ);
+ }
+
+ void intersect(const B3DRange& rRange)
+ {
+ maRangeX.intersect(rRange.maRangeX);
+ maRangeY.intersect(rRange.maRangeY);
+ maRangeZ.intersect(rRange.maRangeZ);
+ }
+
+ void grow(double fValue)
+ {
+ maRangeX.grow(fValue);
+ maRangeY.grow(fValue);
+ maRangeZ.grow(fValue);
+ }
+
+ BASEGFX_DLLPUBLIC void transform(const B3DHomMatrix& rMatrix);
+ };
+
+} // end of namespace basegfx
+
+
+#endif /* _BGFX_RANGE_B3DRANGE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/range/b3irange.hxx b/include/basegfx/range/b3irange.hxx
new file mode 100644
index 000000000000..558c2abb4d62
--- /dev/null
+++ b/include/basegfx/range/b3irange.hxx
@@ -0,0 +1,240 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RANGE_B3IRANGE_HXX
+#define _BGFX_RANGE_B3IRANGE_HXX
+
+#include <basegfx/point/b3ipoint.hxx>
+#include <basegfx/point/b3dpoint.hxx>
+#include <basegfx/tuple/b3ituple.hxx>
+#include <basegfx/tuple/b3i64tuple.hxx>
+#include <basegfx/range/basicrange.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ class B3IRange
+ {
+ typedef ::basegfx::BasicRange< sal_Int32, Int32Traits > MyBasicRange;
+
+ MyBasicRange maRangeX;
+ MyBasicRange maRangeY;
+ MyBasicRange maRangeZ;
+
+ public:
+ B3IRange() {}
+
+ explicit B3IRange(const B3ITuple& rTuple)
+ : maRangeX(rTuple.getX()),
+ maRangeY(rTuple.getY()),
+ maRangeZ(rTuple.getZ())
+ {
+ }
+
+ B3IRange(sal_Int32 x1,
+ sal_Int32 y1,
+ sal_Int32 z1,
+ sal_Int32 x2,
+ sal_Int32 y2,
+ sal_Int32 z2)
+ : maRangeX(x1),
+ maRangeY(y1),
+ maRangeZ(z1)
+ {
+ maRangeX.expand(x2);
+ maRangeY.expand(y2);
+ maRangeZ.expand(z2);
+ }
+
+ B3IRange(const B3ITuple& rTuple1,
+ const B3ITuple& rTuple2)
+ : maRangeX(rTuple1.getX()),
+ maRangeY(rTuple1.getY()),
+ maRangeZ(rTuple1.getZ())
+ {
+ expand(rTuple2);
+ }
+
+ bool isEmpty() const
+ {
+ return maRangeX.isEmpty() || maRangeY.isEmpty() || maRangeZ.isEmpty();
+ }
+
+ void reset()
+ {
+ maRangeX.reset();
+ maRangeY.reset();
+ maRangeZ.reset();
+ }
+
+ bool operator==( const B3IRange& rRange ) const
+ {
+ return (maRangeX == rRange.maRangeX
+ && maRangeY == rRange.maRangeY
+ && maRangeZ == rRange.maRangeZ);
+ }
+
+ bool operator!=( const B3IRange& rRange ) const
+ {
+ return (maRangeX != rRange.maRangeX
+ || maRangeY != rRange.maRangeY
+ || maRangeZ != rRange.maRangeZ);
+ }
+
+ sal_Int32 getMinX() const
+ {
+ return maRangeX.getMinimum();
+ }
+
+ sal_Int32 getMinY() const
+ {
+ return maRangeY.getMinimum();
+ }
+
+ sal_Int32 getMinZ() const
+ {
+ return maRangeZ.getMinimum();
+ }
+
+ sal_Int32 getMaxX() const
+ {
+ return maRangeX.getMaximum();
+ }
+
+ sal_Int32 getMaxY() const
+ {
+ return maRangeY.getMaximum();
+ }
+
+ sal_Int32 getMaxZ() const
+ {
+ return maRangeZ.getMaximum();
+ }
+
+ sal_Int64 getWidth() const
+ {
+ return maRangeX.getRange();
+ }
+
+ sal_Int64 getHeight() const
+ {
+ return maRangeY.getRange();
+ }
+
+ sal_Int64 getDepth() const
+ {
+ return maRangeZ.getRange();
+ }
+
+ B3IPoint getMinimum() const
+ {
+ return B3IPoint(
+ maRangeX.getMinimum(),
+ maRangeY.getMinimum(),
+ maRangeZ.getMinimum()
+ );
+ }
+
+ B3IPoint getMaximum() const
+ {
+ return B3IPoint(
+ maRangeX.getMaximum(),
+ maRangeY.getMaximum(),
+ maRangeZ.getMaximum()
+ );
+ }
+
+ B3I64Tuple getRange() const
+ {
+ return B3I64Tuple(
+ maRangeX.getRange(),
+ maRangeY.getRange(),
+ maRangeZ.getRange()
+ );
+ }
+
+ B3DPoint getCenter() const
+ {
+ return B3DPoint(
+ maRangeX.getCenter(),
+ maRangeY.getCenter(),
+ maRangeZ.getCenter()
+ );
+ }
+
+ bool isInside(const B3ITuple& rTuple) const
+ {
+ return (
+ maRangeX.isInside(rTuple.getX())
+ && maRangeY.isInside(rTuple.getY())
+ && maRangeZ.isInside(rTuple.getZ())
+ );
+ }
+
+ bool isInside(const B3IRange& rRange) const
+ {
+ return (
+ maRangeX.isInside(rRange.maRangeX)
+ && maRangeY.isInside(rRange.maRangeY)
+ && maRangeZ.isInside(rRange.maRangeZ)
+ );
+ }
+
+ bool overlaps(const B3IRange& rRange) const
+ {
+ return (
+ maRangeX.overlaps(rRange.maRangeX)
+ && maRangeY.overlaps(rRange.maRangeY)
+ && maRangeZ.overlaps(rRange.maRangeZ)
+ );
+ }
+
+ void expand(const B3ITuple& rTuple)
+ {
+ maRangeX.expand(rTuple.getX());
+ maRangeY.expand(rTuple.getY());
+ maRangeZ.expand(rTuple.getZ());
+ }
+
+ void expand(const B3IRange& rRange)
+ {
+ maRangeX.expand(rRange.maRangeX);
+ maRangeY.expand(rRange.maRangeY);
+ maRangeZ.expand(rRange.maRangeZ);
+ }
+
+ void intersect(const B3IRange& rRange)
+ {
+ maRangeX.intersect(rRange.maRangeX);
+ maRangeY.intersect(rRange.maRangeY);
+ maRangeZ.intersect(rRange.maRangeZ);
+ }
+
+ void grow(sal_Int32 nValue)
+ {
+ maRangeX.grow(nValue);
+ maRangeY.grow(nValue);
+ maRangeZ.grow(nValue);
+ }
+ };
+} // end of namespace basegfx
+
+#endif /* _BGFX_RANGE_B3IRANGE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/range/basicbox.hxx b/include/basegfx/range/basicbox.hxx
new file mode 100644
index 000000000000..bab84c17f89a
--- /dev/null
+++ b/include/basegfx/range/basicbox.hxx
@@ -0,0 +1,127 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RANGE_BASICBOX_HXX
+#define _BGFX_RANGE_BASICBOX_HXX
+
+#include <basegfx/range/basicrange.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+
+namespace basegfx
+{
+ /** Explicitely different from BasicRange, handling the inside predicates
+ differently.
+
+ This is modelled after how polygon fill algorithms set pixel -
+ typically excluding rightmost and bottommost ones.
+ */
+ class BasicBox : public BasicRange< sal_Int32, Int32Traits >
+ {
+ typedef BasicRange< sal_Int32, Int32Traits > Base;
+ public:
+ BasicBox() {}
+
+ explicit BasicBox( sal_Int32 nValue ) :
+ Base( nValue )
+ {
+ }
+
+ bool isEmpty() const
+ {
+ return mnMinimum >= mnMaximum;
+ }
+
+ double getCenter() const
+ {
+ if(isEmpty())
+ {
+ return 0.0;
+ }
+ else
+ {
+ return ((mnMaximum + mnMinimum - 1.0) / 2.0);
+ }
+ }
+
+ using Base::isInside;
+
+ bool isInside(sal_Int32 nValue) const
+ {
+ if(isEmpty())
+ {
+ return false;
+ }
+ else
+ {
+ return (nValue >= mnMinimum) && (nValue < mnMaximum);
+ }
+ }
+
+ using Base::overlaps;
+
+ bool overlaps(const BasicBox& rBox) const
+ {
+ if(isEmpty())
+ {
+ return false;
+ }
+ else
+ {
+ if(rBox.isEmpty())
+ {
+ return false;
+ }
+ else
+ {
+ return !((rBox.mnMaximum <= mnMinimum) || (rBox.mnMinimum >= mnMaximum));
+ }
+ }
+ }
+
+ void grow(sal_Int32 nValue)
+ {
+ if(!isEmpty())
+ {
+ bool bLessThanZero(nValue < 0);
+
+ if(nValue > 0 || bLessThanZero)
+ {
+ mnMinimum -= nValue;
+ mnMaximum += nValue;
+
+ if(bLessThanZero)
+ {
+ // test if range did collapse
+ if(mnMinimum > mnMaximum)
+ {
+ // if yes, collapse to center
+ mnMinimum = mnMaximum = ((mnMaximum + mnMinimum - 1) / 2);
+ }
+ }
+ }
+ }
+ }
+ };
+
+} // end of namespace basegfx
+
+#endif /* _BGFX_RANGE_BASICBOX_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/range/basicrange.hxx b/include/basegfx/range/basicrange.hxx
new file mode 100644
index 000000000000..51b5593ae61d
--- /dev/null
+++ b/include/basegfx/range/basicrange.hxx
@@ -0,0 +1,278 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RANGE_BASICRANGE_HXX
+#define _BGFX_RANGE_BASICRANGE_HXX
+
+#include <sal/types.h>
+#include <float.h>
+#include <basegfx/numeric/ftools.hxx>
+
+
+namespace basegfx
+{
+ template< typename T, typename Traits > class BasicRange
+ {
+ protected:
+ T mnMinimum;
+ T mnMaximum;
+
+ public:
+ typedef T ValueType;
+ typedef Traits TraitsType;
+
+ BasicRange() :
+ mnMinimum(Traits::maxVal()),
+ mnMaximum(Traits::minVal())
+ {
+ }
+
+ explicit BasicRange( T nValue ) :
+ mnMinimum(nValue),
+ mnMaximum(nValue)
+ {
+ }
+
+ void reset()
+ {
+ mnMinimum = Traits::maxVal();
+ mnMaximum = Traits::minVal();
+ }
+
+ bool isEmpty() const
+ {
+ return Traits::maxVal() == mnMinimum;
+ }
+
+ T getMinimum() const { return mnMinimum; }
+ T getMaximum() const { return mnMaximum; }
+
+ double getCenter() const
+ {
+ if(isEmpty())
+ {
+ return 0.0;
+ }
+ else
+ {
+ return ((mnMaximum + mnMinimum) / 2.0);
+ }
+ }
+
+ bool isInside(T nValue) const
+ {
+ if(isEmpty())
+ {
+ return false;
+ }
+ else
+ {
+ return (nValue >= mnMinimum) && (nValue <= mnMaximum);
+ }
+ }
+
+ bool isInside(const BasicRange& rRange) const
+ {
+ if(isEmpty())
+ {
+ return false;
+ }
+ else
+ {
+ if(rRange.isEmpty())
+ {
+ return false;
+ }
+ else
+ {
+ return (rRange.mnMinimum >= mnMinimum) && (rRange.mnMaximum <= mnMaximum);
+ }
+ }
+ }
+
+ bool overlaps(const BasicRange& rRange) const
+ {
+ if(isEmpty())
+ {
+ return false;
+ }
+ else
+ {
+ if(rRange.isEmpty())
+ {
+ return false;
+ }
+ else
+ {
+ return !((rRange.mnMaximum < mnMinimum) || (rRange.mnMinimum > mnMaximum));
+ }
+ }
+ }
+
+ bool overlapsMore(const BasicRange& rRange) const
+ {
+ if(isEmpty() || rRange.isEmpty())
+ return false;
+ // returns true if the overlap is more than just a touching at the limits
+ return ((rRange.mnMaximum > mnMinimum) && (rRange.mnMinimum < mnMaximum));
+ }
+
+ bool operator==( const BasicRange& rRange ) const
+ {
+ return (mnMinimum == rRange.mnMinimum && mnMaximum == rRange.mnMaximum);
+ }
+
+ bool operator!=( const BasicRange& rRange ) const
+ {
+ return (mnMinimum != rRange.mnMinimum || mnMaximum != rRange.mnMaximum);
+ }
+
+ bool equal(const BasicRange& rRange) const
+ {
+ return (
+ fTools::equal(mnMinimum, rRange.mnMinimum) &&
+ fTools::equal(mnMaximum, rRange.mnMaximum));
+ }
+
+ void expand(T nValue)
+ {
+ if(isEmpty())
+ {
+ mnMinimum = mnMaximum = nValue;
+ }
+ else
+ {
+ if(nValue < mnMinimum)
+ {
+ mnMinimum = nValue;
+ }
+
+ if(nValue > mnMaximum)
+ {
+ mnMaximum = nValue;
+ }
+ }
+ }
+
+ void expand(const BasicRange& rRange)
+ {
+ if(isEmpty())
+ {
+ mnMinimum = rRange.mnMinimum;
+ mnMaximum = rRange.mnMaximum;
+ }
+ else
+ {
+ if(!rRange.isEmpty())
+ {
+ if(rRange.mnMinimum < mnMinimum)
+ {
+ mnMinimum = rRange.mnMinimum;
+ }
+
+ if(rRange.mnMaximum > mnMaximum)
+ {
+ mnMaximum = rRange.mnMaximum;
+ }
+ }
+ }
+ }
+
+ void intersect(const BasicRange& rRange)
+ {
+ // here, overlaps also tests all isEmpty() conditions already.
+ if( !overlaps( rRange ) )
+ {
+ reset();
+ }
+ else
+ {
+ if(rRange.mnMinimum > mnMinimum)
+ {
+ mnMinimum = rRange.mnMinimum;
+ }
+
+ if(rRange.mnMaximum < mnMaximum)
+ {
+ mnMaximum = rRange.mnMaximum;
+ }
+ }
+ }
+
+ void grow(T nValue)
+ {
+ if(!isEmpty())
+ {
+ bool bLessThanZero(nValue < 0);
+
+ if(nValue > 0 || bLessThanZero)
+ {
+ mnMinimum -= nValue;
+ mnMaximum += nValue;
+
+ if(bLessThanZero)
+ {
+ // test if range did collapse
+ if(mnMinimum > mnMaximum)
+ {
+ // if yes, collapse to center
+ mnMinimum = mnMaximum = (mnMinimum + mnMaximum) / 2;
+ }
+ }
+ }
+ }
+ }
+
+ typename Traits::DifferenceType getRange() const
+ {
+ if(isEmpty())
+ {
+ return Traits::neutral();
+ }
+ else
+ {
+ return (mnMaximum - mnMinimum);
+ }
+ }
+ };
+
+ // some pre-fabricated traits
+ struct DoubleTraits
+ {
+ static double minVal() { return DBL_MIN; };
+ static double maxVal() { return DBL_MAX; };
+ static double neutral() { return 0.0; };
+
+ typedef double DifferenceType;
+ };
+
+ struct Int32Traits
+ {
+ static sal_Int32 minVal() { return SAL_MIN_INT32; };
+ static sal_Int32 maxVal() { return SAL_MAX_INT32; };
+ static sal_Int32 neutral() { return 0L; };
+
+ typedef sal_Int64 DifferenceType;
+ };
+
+} // end of namespace basegfx
+
+#endif /* _BGFX_RANGE_BASICRANGE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/raster/bpixelraster.hxx b/include/basegfx/raster/bpixelraster.hxx
new file mode 100644
index 000000000000..ed7ac931d805
--- /dev/null
+++ b/include/basegfx/raster/bpixelraster.hxx
@@ -0,0 +1,99 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RASTER_BPIXELRASTER_HXX
+#define _BGFX_RASTER_BPIXELRASTER_HXX
+
+#include <algorithm>
+#include <string.h>
+#include <sal/types.h>
+#include <basegfx/pixel/bpixel.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+// predeclarations
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ class BPixelRaster
+ {
+ private:
+ // do not allow copy constructor and assignment operator
+ BPixelRaster(const BPixelRaster&);
+ BPixelRaster& operator=(const BPixelRaster&);
+
+ protected:
+ sal_uInt32 mnWidth;
+ sal_uInt32 mnHeight;
+ sal_uInt32 mnCount;
+ BPixel* mpContent;
+
+ public:
+ // reset
+ void reset()
+ {
+ memset(mpContent, 0, sizeof(BPixel) * mnCount);
+ }
+
+ // constructor/destructor
+ BPixelRaster(sal_uInt32 nWidth, sal_uInt32 nHeight)
+ : mnWidth(nWidth),
+ mnHeight(nHeight),
+ mnCount(nWidth * nHeight),
+ mpContent(new BPixel[mnCount])
+ {
+ reset();
+ }
+
+ ~BPixelRaster()
+ {
+ delete [] mpContent;
+ }
+
+ // coordinate calcs between X/Y and span
+ sal_uInt32 getIndexFromXY(sal_uInt32 nX, sal_uInt32 nY) const { return (nX + (nY * mnWidth)); }
+ sal_uInt32 getXFromIndex(sal_uInt32 nIndex) const { return (nIndex % mnWidth); }
+ sal_uInt32 getYFromIndex(sal_uInt32 nIndex) const { return (nIndex / mnWidth); }
+
+ // data access read
+ sal_uInt32 getWidth() const { return mnWidth; }
+ sal_uInt32 getHeight() const { return mnHeight; }
+ sal_uInt32 getCount() const { return mnCount; }
+
+ // data access read only
+ const BPixel& getBPixel(sal_uInt32 nIndex) const
+ {
+ assert(nIndex < mnCount); //Access out of range
+ return mpContent[nIndex];
+ }
+
+ // data access read/write
+ BPixel& getBPixel(sal_uInt32 nIndex)
+ {
+ assert(nIndex < mnCount); //Access out of range
+ return mpContent[nIndex];
+ }
+ };
+} // end of namespace basegfx
+
+#endif /* _BGFX_RASTER_BPIXELRASTER_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/raster/bzpixelraster.hxx b/include/basegfx/raster/bzpixelraster.hxx
new file mode 100644
index 000000000000..ddd4f1e56cb0
--- /dev/null
+++ b/include/basegfx/raster/bzpixelraster.hxx
@@ -0,0 +1,90 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RASTER_BZPIXELRASTER_HXX
+#define _BGFX_RASTER_BZPIXELRASTER_HXX
+
+#include <basegfx/raster/bpixelraster.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+// predeclarations
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ class BZPixelRaster : public BPixelRaster
+ {
+ protected:
+ // additionally, host a ZBuffer
+ sal_uInt16* mpZBuffer;
+
+ public:
+ // reset
+ void resetZ()
+ {
+ reset();
+ memset(mpZBuffer, 0, sizeof(sal_uInt16) * mnCount);
+ }
+
+ // constructor/destructor
+ BZPixelRaster(sal_uInt32 nWidth, sal_uInt32 nHeight)
+ : BPixelRaster(nWidth, nHeight),
+ mpZBuffer(new sal_uInt16[mnCount])
+ {
+ memset(mpZBuffer, 0, sizeof(sal_uInt16) * mnCount);
+ }
+
+ ~BZPixelRaster()
+ {
+ delete [] mpZBuffer;
+ }
+
+ // data access read only
+ const sal_uInt16& getZ(sal_uInt32 nIndex) const
+ {
+#ifdef DBG_UTIL
+ if(nIndex >= mnCount)
+ {
+ OSL_FAIL("getZ: Access out of range (!)");
+ return mpZBuffer[0L];
+ }
+#endif
+ return mpZBuffer[nIndex];
+ }
+
+ // data access read/write
+ sal_uInt16& getZ(sal_uInt32 nIndex)
+ {
+#ifdef DBG_UTIL
+ if(nIndex >= mnCount)
+ {
+ OSL_FAIL("getZ: Access out of range (!)");
+ return mpZBuffer[0L];
+ }
+#endif
+ return mpZBuffer[nIndex];
+ }
+ };
+} // end of namespace basegfx
+
+#endif /* _BGFX_RASTER_BZPIXELRASTER_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/raster/rasterconvert3d.hxx b/include/basegfx/raster/rasterconvert3d.hxx
new file mode 100644
index 000000000000..1bfbe20b1cf0
--- /dev/null
+++ b/include/basegfx/raster/rasterconvert3d.hxx
@@ -0,0 +1,340 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_RASTER_RASTERCONVERT3D_HXX
+#define _BGFX_RASTER_RASTERCONVERT3D_HXX
+
+#include <sal/types.h>
+#include <vector>
+#include <basegfx/color/bcolor.hxx>
+#include <basegfx/vector/b3dvector.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/vector/b2dvector.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+// predeclarations
+
+namespace basegfx
+{
+ class B3DPolygon;
+ class B3DPolyPolygon;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// interpolators for double precision
+
+namespace basegfx
+{
+ class ip_single
+ {
+ private:
+ double mfVal;
+ double mfInc;
+
+ public:
+ ip_single()
+ : mfVal(0.0),
+ mfInc(0.0)
+ {}
+
+ ip_single(double fVal, double fInc)
+ : mfVal(fVal),
+ mfInc(fInc)
+ {}
+
+ double getVal() const { return mfVal; }
+ double getInc() const { return mfInc; }
+
+ void increment(double fStep) { mfVal += fStep * mfInc; }
+ };
+} // end of namespace basegfx
+
+namespace basegfx
+{
+ class ip_double
+ {
+ private:
+ ip_single maX;
+ ip_single maY;
+
+ public:
+ ip_double()
+ : maX(),
+ maY()
+ {}
+
+ ip_double(double fXVal, double fXInc, double fYVal, double fYInc)
+ : maX(fXVal, fXInc),
+ maY(fYVal, fYInc)
+ {}
+
+ const ip_single& getX() const { return maX; }
+ const ip_single& getY() const { return maY; }
+
+ void increment(double fStep) { maX.increment(fStep); maY.increment(fStep); }
+ };
+} // end of namespace basegfx
+
+namespace basegfx
+{
+ class ip_triple
+ {
+ private:
+ ip_single maX;
+ ip_single maY;
+ ip_single maZ;
+
+ public:
+ ip_triple()
+ : maX(),
+ maY(),
+ maZ()
+ {}
+
+ ip_triple(double fXVal, double fXInc, double fYVal, double fYInc, double fZVal, double fZInc)
+ : maX(fXVal, fXInc),
+ maY(fYVal, fYInc),
+ maZ(fZVal, fZInc)
+ {}
+
+ const ip_single& getX() const { return maX; }
+ const ip_single& getY() const { return maY; }
+ const ip_single& getZ() const { return maZ; }
+
+ void increment(double fStep) { maX.increment(fStep); maY.increment(fStep); maZ.increment(fStep); }
+ };
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+// InterpolatorProvider3D to have a common source for allocating interpolators
+// which may then be addressed using the index to the vectors
+
+namespace basegfx
+{
+ #define SCANLINE_EMPTY_INDEX (0xffffffff)
+
+ class InterpolatorProvider3D
+ {
+ private:
+ ::std::vector< ip_triple > maColorInterpolators;
+ ::std::vector< ip_triple > maNormalInterpolators;
+ ::std::vector< ip_double > maTextureInterpolators;
+ ::std::vector< ip_triple > maInverseTextureInterpolators;
+
+ protected:
+ sal_uInt32 addColorInterpolator(const BColor& rA, const BColor& rB, double fInvYDelta)
+ {
+ B3DVector aDelta(rB.getRed() - rA.getRed(), rB.getGreen() - rA.getGreen(), rB.getBlue() - rA.getBlue());
+ aDelta *= fInvYDelta;
+ maColorInterpolators.push_back(ip_triple(rA.getRed(), aDelta.getX(), rA.getGreen(), aDelta.getY(), rA.getBlue(), aDelta.getZ()));
+ return (maColorInterpolators.size() - 1L);
+ }
+
+ sal_uInt32 addNormalInterpolator(const B3DVector& rA, const B3DVector& rB, double fInvYDelta)
+ {
+ B3DVector aDelta(rB.getX() - rA.getX(), rB.getY() - rA.getY(), rB.getZ() - rA.getZ());
+ aDelta *= fInvYDelta;
+ maNormalInterpolators.push_back(ip_triple(rA.getX(), aDelta.getX(), rA.getY(), aDelta.getY(), rA.getZ(), aDelta.getZ()));
+ return (maNormalInterpolators.size() - 1L);
+ }
+
+ sal_uInt32 addTextureInterpolator(const B2DPoint& rA, const B2DPoint& rB, double fInvYDelta)
+ {
+ B2DVector aDelta(rB.getX() - rA.getX(), rB.getY() - rA.getY());
+ aDelta *= fInvYDelta;
+ maTextureInterpolators.push_back(ip_double(rA.getX(), aDelta.getX(), rA.getY(), aDelta.getY()));
+ return (maTextureInterpolators.size() - 1L);
+ }
+
+ sal_uInt32 addInverseTextureInterpolator(const B2DPoint& rA, const B2DPoint& rB, double fZEyeA, double fZEyeB, double fInvYDelta)
+ {
+ const double fInvZEyeA(fTools::equalZero(fZEyeA) ? fZEyeA : 1.0 / fZEyeA);
+ const double fInvZEyeB(fTools::equalZero(fZEyeB) ? fZEyeB : 1.0 / fZEyeB);
+ const B2DPoint aInvA(rA * fInvZEyeA);
+ const B2DPoint aInvB(rB * fInvZEyeB);
+ double fZDelta(fInvZEyeB - fInvZEyeA);
+ B2DVector aDelta(aInvB.getX() - aInvA.getX(), aInvB.getY() - aInvA.getY());
+
+ fZDelta *= fInvYDelta;
+ aDelta *= fInvYDelta;
+
+ maInverseTextureInterpolators.push_back(ip_triple(aInvA.getX(), aDelta.getX(), aInvA.getY(), aDelta.getY(), fInvZEyeA, fZDelta));
+ return (maInverseTextureInterpolators.size() - 1L);
+ }
+
+ void reset()
+ {
+ maColorInterpolators.clear();
+ maNormalInterpolators.clear();
+ maTextureInterpolators.clear();
+ maInverseTextureInterpolators.clear();
+ }
+
+ public:
+ InterpolatorProvider3D() {}
+
+ ::std::vector< ip_triple >& getColorInterpolators() { return maColorInterpolators; }
+ ::std::vector< ip_triple >& getNormalInterpolators() { return maNormalInterpolators; }
+ ::std::vector< ip_double >& getTextureInterpolators() { return maTextureInterpolators; }
+ ::std::vector< ip_triple >& getInverseTextureInterpolators() { return maInverseTextureInterpolators; }
+ };
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+// RasterConversionLineEntry3D for Raterconversion of 3D PolyPolygons
+
+namespace basegfx
+{
+ class RasterConversionLineEntry3D
+ {
+ private:
+ ip_single maX;
+ ip_single maZ;
+ sal_Int32 mnY;
+ sal_uInt32 mnCount;
+
+ sal_uInt32 mnColorIndex;
+ sal_uInt32 mnNormalIndex;
+ sal_uInt32 mnTextureIndex;
+ sal_uInt32 mnInverseTextureIndex;
+
+ public:
+ RasterConversionLineEntry3D(const double& rfX, const double& rfDeltaX, const double& rfZ, const double& rfDeltaZ, sal_Int32 nY, sal_uInt32 nCount)
+ : maX(rfX, rfDeltaX),
+ maZ(rfZ, rfDeltaZ),
+ mnY(nY),
+ mnCount(nCount),
+ mnColorIndex(SCANLINE_EMPTY_INDEX),
+ mnNormalIndex(SCANLINE_EMPTY_INDEX),
+ mnTextureIndex(SCANLINE_EMPTY_INDEX),
+ mnInverseTextureIndex(SCANLINE_EMPTY_INDEX)
+ {}
+
+ void setColorIndex(sal_uInt32 nIndex) { mnColorIndex = nIndex; }
+ void setNormalIndex(sal_uInt32 nIndex) { mnNormalIndex = nIndex; }
+ void setTextureIndex(sal_uInt32 nIndex) { mnTextureIndex = nIndex; }
+ void setInverseTextureIndex(sal_uInt32 nIndex) { mnInverseTextureIndex = nIndex; }
+
+ bool operator<(const RasterConversionLineEntry3D& rComp) const
+ {
+ if(mnY == rComp.mnY)
+ {
+ return maX.getVal() < rComp.maX.getVal();
+ }
+
+ return mnY < rComp.mnY;
+ }
+
+ bool decrementRasterConversionLineEntry3D(sal_uInt32 nStep)
+ {
+ if(nStep >= mnCount)
+ {
+ return false;
+ }
+ else
+ {
+ mnCount -= nStep;
+ return true;
+ }
+ }
+
+ void incrementRasterConversionLineEntry3D(sal_uInt32 nStep, InterpolatorProvider3D& rProvider)
+ {
+ const double fStep((double)nStep);
+ maX.increment(fStep);
+ maZ.increment(fStep);
+ mnY += nStep;
+
+ if(SCANLINE_EMPTY_INDEX != mnColorIndex)
+ {
+ rProvider.getColorInterpolators()[mnColorIndex].increment(fStep);
+ }
+
+ if(SCANLINE_EMPTY_INDEX != mnNormalIndex)
+ {
+ rProvider.getNormalInterpolators()[mnNormalIndex].increment(fStep);
+ }
+
+ if(SCANLINE_EMPTY_INDEX != mnTextureIndex)
+ {
+ rProvider.getTextureInterpolators()[mnTextureIndex].increment(fStep);
+ }
+
+ if(SCANLINE_EMPTY_INDEX != mnInverseTextureIndex)
+ {
+ rProvider.getInverseTextureInterpolators()[mnInverseTextureIndex].increment(fStep);
+ }
+ }
+
+ // data read access
+ const ip_single& getX() const { return maX; }
+ sal_Int32 getY() const { return mnY; }
+ const ip_single& getZ() const { return maZ; }
+ sal_uInt32 getColorIndex() const { return mnColorIndex; }
+ sal_uInt32 getNormalIndex() const { return mnNormalIndex; }
+ sal_uInt32 getTextureIndex() const { return mnTextureIndex; }
+ sal_uInt32 getInverseTextureIndex() const { return mnInverseTextureIndex; }
+ };
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+// the basic RaterConverter itself. Only one method needs to be overloaded. The
+// class itself is strictly virtual
+
+namespace basegfx
+{
+ class BASEGFX_DLLPUBLIC RasterConverter3D : public InterpolatorProvider3D
+ {
+ private:
+ // the line entries for an area conversion run
+ ::std::vector< RasterConversionLineEntry3D > maLineEntries;
+
+ struct lineComparator
+ {
+ bool operator()(const RasterConversionLineEntry3D* pA, const RasterConversionLineEntry3D* pB)
+ {
+ OSL_ENSURE(pA && pB, "lineComparator: empty pointer (!)");
+ return pA->getX().getVal() < pB->getX().getVal();
+ }
+ };
+
+ void addArea(const B3DPolygon& rFill, const B3DHomMatrix* pViewToEye);
+ void addArea(const B3DPolyPolygon& rFill, const B3DHomMatrix* pViewToEye);
+ void addEdge(const B3DPolygon& rFill, sal_uInt32 a, sal_uInt32 b, const B3DHomMatrix* pViewToEye);
+
+ void rasterconvertB3DArea(sal_Int32 nStartLine, sal_Int32 nStopLine);
+ void rasterconvertB3DEdge(const B3DPolygon& rLine, sal_uInt32 nA, sal_uInt32 nB, sal_Int32 nStartLine, sal_Int32 nStopLine, sal_uInt16 nLineWidth);
+
+ virtual void processLineSpan(const RasterConversionLineEntry3D& rA, const RasterConversionLineEntry3D& rB, sal_Int32 nLine, sal_uInt32 nSpanCount) = 0;
+
+ public:
+ RasterConverter3D();
+ virtual ~RasterConverter3D();
+
+ void rasterconvertB3DPolyPolygon(const B3DPolyPolygon& rFill, const B3DHomMatrix* pViewToEye, sal_Int32 nStartLine, sal_Int32 nStopLine);
+ void rasterconvertB3DPolygon(const B3DPolygon& rLine, sal_Int32 nStartLine, sal_Int32 nStopLine, sal_uInt16 nLineWidth);
+ };
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif /* _BGFX_RASTER_RASTERCONVERT3D_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/tools/b2dclipstate.hxx b/include/basegfx/tools/b2dclipstate.hxx
new file mode 100644
index 000000000000..f1d750ae636b
--- /dev/null
+++ b/include/basegfx/tools/b2dclipstate.hxx
@@ -0,0 +1,94 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_TOOLS_CLIPSTATE_HXX
+#define _BGFX_TOOLS_CLIPSTATE_HXX
+
+#include <sal/types.h>
+#include <o3tl/cow_wrapper.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ class B2DRange;
+ class B2DPolyRange;
+ class B2DPolygon;
+ class B2DPolyPolygon;
+
+ namespace tools
+ {
+ 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& );
+ explicit B2DClipState( const B2DPolyPolygon& );
+ B2DClipState& operator=( const 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& );
+
+ B2DPolyPolygon getClipPoly() const;
+ };
+ }
+}
+
+#endif // _BGFX_TOOLS_CLIPSTATE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/tools/canvastools.hxx b/include/basegfx/tools/canvastools.hxx
new file mode 100644
index 000000000000..819a62e47b28
--- /dev/null
+++ b/include/basegfx/tools/canvastools.hxx
@@ -0,0 +1,205 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_TOOLS_CANVASTOOLS_HXX
+#define _BGFX_TOOLS_CANVASTOOLS_HXX
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+
+namespace com { namespace sun { namespace star { namespace geometry
+{
+ struct AffineMatrix2D;
+ struct AffineMatrix3D;
+ struct Matrix2D;
+ struct RealPoint2D;
+ struct RealSize2D;
+ struct RealRectangle2D;
+ struct RealRectangle3D;
+ struct IntegerPoint2D;
+ struct IntegerSize2D;
+ struct IntegerRectangle2D;
+ struct RealBezierSegment2D;
+} } } }
+
+namespace com { namespace sun { namespace star { namespace rendering
+{
+ class XGraphicDevice;
+ class XPolyPolygon2D;
+} } } }
+
+namespace com { namespace sun { namespace star { namespace awt
+{
+ struct Point;
+ struct Size;
+ struct Rectangle;
+} } } }
+
+namespace basegfx
+{
+ class B2DHomMatrix;
+ class B3DHomMatrix;
+ class B2DVector;
+ class B2DPoint;
+ class B2DRange;
+ class B3DRange;
+ class B2IBox;
+ class B2IVector;
+ class B2IPoint;
+ class B2IRange;
+ class B2DPolygon;
+ class B2DPolyPolygon;
+
+ namespace unotools
+ {
+ // Polygon conversions
+ // ===================================================================
+
+ BASEGFX_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XPolyPolygon2D >
+ xPolyPolygonFromB2DPolygon( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::rendering::XGraphicDevice >& xGraphicDevice,
+ const ::basegfx::B2DPolygon& rPoly );
+
+ BASEGFX_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XPolyPolygon2D >
+ xPolyPolygonFromB2DPolyPolygon( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::rendering::XGraphicDevice >& xGraphicDevice,
+ const ::basegfx::B2DPolyPolygon& rPolyPoly );
+
+
+ BASEGFX_DLLPUBLIC ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Sequence<
+ ::com::sun::star::geometry::RealBezierSegment2D > >
+ bezierSequenceSequenceFromB2DPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly );
+
+ BASEGFX_DLLPUBLIC ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Sequence<
+ ::com::sun::star::geometry::RealPoint2D > >
+ pointSequenceSequenceFromB2DPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly );
+
+ BASEGFX_DLLPUBLIC ::basegfx::B2DPolygon polygonFromPoint2DSequence(
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::geometry::RealPoint2D >& rPoints );
+
+ BASEGFX_DLLPUBLIC ::basegfx::B2DPolyPolygon polyPolygonFromPoint2DSequenceSequence(
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Sequence< ::com::sun::star::geometry::RealPoint2D > >& rPoints );
+
+ BASEGFX_DLLPUBLIC ::basegfx::B2DPolygon polygonFromBezier2DSequence(
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::geometry::RealBezierSegment2D >& rPoints );
+
+ BASEGFX_DLLPUBLIC ::basegfx::B2DPolyPolygon polyPolygonFromBezier2DSequenceSequence(
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Sequence< ::com::sun::star::geometry::RealBezierSegment2D > >& rPoints );
+
+ BASEGFX_DLLPUBLIC ::basegfx::B2DPolyPolygon b2DPolyPolygonFromXPolyPolygon2D(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::rendering::XPolyPolygon2D >& rPoly );
+
+ // Matrix conversions
+ // ===================================================================
+
+ BASEGFX_DLLPUBLIC ::com::sun::star::geometry::AffineMatrix2D&
+ affineMatrixFromHomMatrix( ::com::sun::star::geometry::AffineMatrix2D& matrix,
+ const ::basegfx::B2DHomMatrix& transform);
+
+ BASEGFX_DLLPUBLIC ::com::sun::star::geometry::AffineMatrix3D& affineMatrixFromHomMatrix3D(
+ ::com::sun::star::geometry::AffineMatrix3D& matrix,
+ const ::basegfx::B3DHomMatrix& transform);
+
+ BASEGFX_DLLPUBLIC ::basegfx::B2DHomMatrix&
+ homMatrixFromAffineMatrix( ::basegfx::B2DHomMatrix& transform,
+ const ::com::sun::star::geometry::AffineMatrix2D& matrix );
+
+ BASEGFX_DLLPUBLIC ::basegfx::B3DHomMatrix homMatrixFromAffineMatrix3D( const ::com::sun::star::geometry::AffineMatrix3D& matrix );
+
+ BASEGFX_DLLPUBLIC ::com::sun::star::geometry::Matrix2D&
+ matrixFromHomMatrix( ::com::sun::star::geometry::Matrix2D& matrix,
+ const ::basegfx::B2DHomMatrix& transform);
+
+ BASEGFX_DLLPUBLIC ::basegfx::B2DHomMatrix&
+ homMatrixFromMatrix( ::basegfx::B2DHomMatrix& transform,
+ const ::com::sun::star::geometry::Matrix2D& matrix );
+
+ // Geometry conversions
+ // ===================================================================
+
+ BASEGFX_DLLPUBLIC ::com::sun::star::geometry::RealSize2D size2DFromB2DSize( const ::basegfx::B2DVector& );
+ BASEGFX_DLLPUBLIC ::com::sun::star::geometry::RealPoint2D point2DFromB2DPoint( const ::basegfx::B2DPoint& );
+ BASEGFX_DLLPUBLIC ::com::sun::star::geometry::RealRectangle2D rectangle2DFromB2DRectangle( const ::basegfx::B2DRange& );
+ BASEGFX_DLLPUBLIC ::com::sun::star::geometry::RealRectangle3D rectangle3DFromB3DRectangle( const ::basegfx::B3DRange& );
+
+ BASEGFX_DLLPUBLIC ::basegfx::B2DPoint b2DPointFromRealPoint2D( const ::com::sun::star::geometry::RealPoint2D& );
+ BASEGFX_DLLPUBLIC ::basegfx::B2DRange b2DRectangleFromRealRectangle2D( const ::com::sun::star::geometry::RealRectangle2D& );
+ BASEGFX_DLLPUBLIC ::basegfx::B3DRange b3DRectangleFromRealRectangle3D( const ::com::sun::star::geometry::RealRectangle3D& );
+
+ BASEGFX_DLLPUBLIC ::com::sun::star::geometry::IntegerSize2D integerSize2DFromB2ISize( const ::basegfx::B2IVector& );
+
+ BASEGFX_DLLPUBLIC ::basegfx::B2IVector b2ISizeFromIntegerSize2D( const ::com::sun::star::geometry::IntegerSize2D& );
+ BASEGFX_DLLPUBLIC ::basegfx::B2IRange b2IRectangleFromIntegerRectangle2D( const ::com::sun::star::geometry::IntegerRectangle2D& );
+
+ BASEGFX_DLLPUBLIC ::basegfx::B2IRange b2IRectangleFromAwtRectangle( const ::com::sun::star::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 integer box, 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 box, which completely contains
+ rRange. Note that this box will contain all pixel affected
+ by a polygon fill operation over the input range.
+ */
+ BASEGFX_DLLPUBLIC ::basegfx::B2IBox b2ISurroundingBoxFromB2DRange( 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 );
+
+ }
+}
+
+#endif /* _BGFX_TOOLS_CANVASTOOLS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/tools/gradienttools.hxx b/include/basegfx/tools/gradienttools.hxx
new file mode 100644
index 000000000000..aa7479d2c369
--- /dev/null
+++ b/include/basegfx/tools/gradienttools.hxx
@@ -0,0 +1,405 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_TOOLS_GRADIENTTOOLS_HXX
+#define _BGFX_TOOLS_GRADIENTTOOLS_HXX
+
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/vector/b2dvector.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/numeric/ftools.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+#include <vector>
+#include <algorithm>
+
+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.
+ */
+ struct BASEGFX_DLLPUBLIC ODFGradientInfo
+ {
+ /** 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 mnSteps;
+ };
+
+ namespace tools
+ {
+ /** 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 nSteps
+ Number of gradient steps (from ODF)
+
+ @param fBorder
+ Width of gradient border (from ODF)
+
+ @param fAngle
+ Gradient angle (from ODF)
+ */
+ BASEGFX_DLLPUBLIC ODFGradientInfo& createLinearODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
+ const B2DRange& rTargetArea,
+ sal_uInt32 nSteps,
+ 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
+ */
+ inline double getLinearGradientAlpha(const B2DPoint& rUV,
+ const ODFGradientInfo& rGradInfo )
+ {
+ const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV);
+ const double t(clamp(aCoor.getY(), 0.0, 1.0));
+ const sal_uInt32 nSteps(rGradInfo.mnSteps);
+
+ if(nSteps > 2L && nSteps < 128L)
+ return floor(t * nSteps) / double(nSteps + 1L);
+
+ return t;
+ }
+
+ /** 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 nSteps
+ Number of gradient steps (from ODF)
+
+ @param fBorder
+ Width of gradient border (from ODF)
+
+ @param fAngle
+ Gradient angle (from ODF)
+ */
+ BASEGFX_DLLPUBLIC ODFGradientInfo& createAxialODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
+ const B2DRange& rTargetArea,
+ sal_uInt32 nSteps,
+ 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
+ */
+ inline double getAxialGradientAlpha(const B2DPoint& rUV,
+ const ODFGradientInfo& rGradInfo )
+ {
+ const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV);
+ const double t(clamp(fabs(aCoor.getY()), 0.0, 1.0));
+ const sal_uInt32 nSteps(rGradInfo.mnSteps);
+ const double fInternalSteps((nSteps * 2L) - 1L);
+
+ if(nSteps > 2L && nSteps < 128L)
+ return floor(((t * fInternalSteps) + 1.0) / 2.0) / double(nSteps - 1L);
+
+ return t;
+ }
+
+ /** 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 nSteps
+ Number of gradient steps (from ODF)
+
+ @param fBorder
+ Width of gradient border (from ODF)
+
+ @param fAngle
+ Gradient angle (from ODF)
+ */
+ BASEGFX_DLLPUBLIC ODFGradientInfo& createRadialODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
+ const B2DRange& rTargetArea,
+ const B2DVector& rOffset,
+ sal_uInt32 nSteps,
+ 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
+ */
+ inline double getRadialGradientAlpha(const B2DPoint& rUV,
+ const ODFGradientInfo& rGradInfo )
+ {
+ const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV);
+ const double fDist(
+ clamp(aCoor.getX() * aCoor.getX() + aCoor.getY() * aCoor.getY(),
+ 0.0,
+ 1.0));
+
+ const double t(1.0 - sqrt(fDist));
+ const sal_uInt32 nSteps(rGradInfo.mnSteps);
+
+ if(nSteps > 2L && nSteps < 128L)
+ return floor(t * nSteps) / double(nSteps - 1L);
+
+ return t;
+ }
+
+ /** 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 nSteps
+ Number of gradient steps (from ODF)
+
+ @param fBorder
+ Width of gradient border (from ODF)
+
+ @param fAngle
+ Gradient angle (from ODF)
+ */
+ BASEGFX_DLLPUBLIC ODFGradientInfo& createEllipticalODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
+ const B2DRange& rTargetArea,
+ const B2DVector& rOffset,
+ sal_uInt32 nSteps,
+ 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
+ */
+ inline double getEllipticalGradientAlpha(const B2DPoint& rUV,
+ const ODFGradientInfo& rGradInfo )
+ {
+ return getRadialGradientAlpha(rUV,rGradInfo); // only matrix setup differs
+ }
+
+ /** 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 nSteps
+ Number of gradient steps (from ODF)
+
+ @param fBorder
+ Width of gradient border (from ODF)
+
+ @param fAngle
+ Gradient angle (from ODF)
+ */
+ BASEGFX_DLLPUBLIC ODFGradientInfo& createSquareODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
+ const B2DRange& rTargetArea,
+ const B2DVector& rOffset,
+ sal_uInt32 nSteps,
+ 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
+ */
+ inline double getSquareGradientAlpha(const B2DPoint& rUV,
+ const ODFGradientInfo& rGradInfo )
+ {
+ const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV);
+ const double fAbsX(fabs(aCoor.getX()));
+ const double fAbsY(fabs(aCoor.getY()));
+
+ if(fTools::moreOrEqual(fAbsX, 1.0) || fTools::moreOrEqual(fAbsY, 1.0))
+ return 0.0;
+
+ const double t(1.0 - (fAbsX > fAbsY ? fAbsX : fAbsY));
+ const sal_uInt32 nSteps(rGradInfo.mnSteps);
+
+ if(nSteps > 2L && nSteps < 128L)
+ return floor(t * nSteps) / double(nSteps - 1L);
+
+ return t;
+ }
+
+ /** 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 nSteps
+ Number of gradient steps (from ODF)
+
+ @param fBorder
+ Width of gradient border (from ODF)
+
+ @param fAngle
+ Gradient angle (from ODF)
+ */
+ BASEGFX_DLLPUBLIC ODFGradientInfo& createRectangularODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
+ const B2DRange& rTargetArea,
+ const B2DVector& rOffset,
+ sal_uInt32 nSteps,
+ 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
+ */
+ inline double getRectangularGradientAlpha(const B2DPoint& rUV,
+ const ODFGradientInfo& rGradInfo )
+ {
+ return getSquareGradientAlpha(rUV, rGradInfo); // only matrix setup differs
+ }
+ }
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/tools/keystoplerp.hxx b/include/basegfx/tools/keystoplerp.hxx
new file mode 100644
index 000000000000..8d6d41af63d9
--- /dev/null
+++ b/include/basegfx/tools/keystoplerp.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 .
+ */
+
+#ifndef _BGFX_TOOLS_KEYSTOPLERP_HXX
+#define _BGFX_TOOLS_KEYSTOPLERP_HXX
+
+#include <basegfx/numeric/ftools.hxx>
+#include <vector>
+#include <basegfx/basegfxdllapi.h>
+
+namespace com{ namespace sun{ namespace star{ namespace uno {
+ template<typename T> class Sequence;
+}}}}
+
+namespace basegfx
+{
+ namespace tools
+ {
+ /** 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 preferrably 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 std::vector<double>& rKeyStops );
+
+ /** Create lerper with given sequence of stops
+
+ @param rKeyStops
+
+ Sequence of stops, must contain at least two elements
+ (though preferrably 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 ::com::sun::star::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;
+ };
+ }
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/tools/lerp.hxx b/include/basegfx/tools/lerp.hxx
new file mode 100644
index 000000000000..a0c0d714a295
--- /dev/null
+++ b/include/basegfx/tools/lerp.hxx
@@ -0,0 +1,51 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_TOOLS_LERP_HXX
+#define _BGFX_TOOLS_LERP_HXX
+
+#include <sal/types.h>
+
+namespace basegfx
+{
+ namespace tools
+ {
+ /** 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 );
+ }
+ }
+}
+
+#endif /* _BGFX_TOOLS_LERP_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/tools/rectcliptools.hxx b/include/basegfx/tools/rectcliptools.hxx
new file mode 100644
index 000000000000..3d5f77e18e0e
--- /dev/null
+++ b/include/basegfx/tools/rectcliptools.hxx
@@ -0,0 +1,96 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_TOOLS_RECTCLIPTOOLS_HXX
+#define _BGFX_TOOLS_RECTCLIPTOOLS_HXX
+
+#include <sal/types.h>
+#include <basegfx/range/b2ibox.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ namespace tools
+ {
+ namespace RectClipFlags
+ {
+ static const sal_uInt32 LEFT = (sal_Int32)0x01;
+ static const sal_uInt32 RIGHT = (sal_Int32)0x02;
+ static const sal_uInt32 TOP = (sal_Int32)0x04;
+ static 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 = (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 = (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;
+ }
+
+ /** Determine number of clip planes hit by given clip mask
+
+ This method returns the number of one bits in the four
+ least significant bits of the argument, which amounts to
+ the number of clip planes hit within the
+ getCohenSutherlandClipFlags() method.
+ */
+ inline sal_uInt32 getNumberOfClipPlanes( sal_uInt32 nFlags )
+ {
+ // classic bit count algo, see e.g. Reingold, Nievergelt,
+ // Deo: Combinatorial Algorithms, Theory and Practice,
+ // Prentice-Hall 1977
+ nFlags = (nFlags & 0x05) + ((nFlags >> 1) & 0x05);
+ nFlags = (nFlags & 0x03) + (nFlags >> 2); // no need for &
+ // 0x03, can't
+ // overflow
+ return nFlags;
+ }
+ }
+}
+
+#endif // _BGFX_TOOLS_RECTCLIPTOOLS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/tools/tools.hxx b/include/basegfx/tools/tools.hxx
new file mode 100644
index 000000000000..c1fa0940ae35
--- /dev/null
+++ b/include/basegfx/tools/tools.hxx
@@ -0,0 +1,102 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_TOOLS_TOOLS_HXX
+#define _BGFX_TOOLS_TOOLS_HXX
+
+#include <sal/types.h>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ class B2DPoint;
+ class B2DRange;
+
+ namespace tools
+ {
+ /** 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 );
+
+ }
+}
+
+#endif /* _BGFX_TOOLS_TOOLS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/tools/unopolypolygon.hxx b/include/basegfx/tools/unopolypolygon.hxx
new file mode 100644
index 000000000000..72ed9418663a
--- /dev/null
+++ b/include/basegfx/tools/unopolypolygon.hxx
@@ -0,0 +1,110 @@
+/* -*- 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 .
+ */
+
+#ifndef INCLUDED_BASEGFX_UNOPOLYPOLYGON_HXX
+#define INCLUDED_BASEGFX_UNOPOLYPOLYGON_HXX
+
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase3.hxx>
+#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 <boost/utility.hpp>
+
+
+namespace basegfx
+{
+namespace unotools
+{
+ typedef ::cppu::WeakComponentImplHelper3<
+ ::com::sun::star::rendering::XLinePolyPolygon2D,
+ ::com::sun::star::rendering::XBezierPolyPolygon2D,
+ ::com::sun::star::lang::XServiceInfo > UnoPolyPolygonBase;
+
+ class BASEGFX_DLLPUBLIC UnoPolyPolygon
+ : private cppu::BaseMutex
+ , private boost::noncopyable
+ , public UnoPolyPolygonBase
+ {
+ public:
+ explicit UnoPolyPolygon( const B2DPolyPolygon& );
+
+ // XPolyPolygon2D
+ virtual void SAL_CALL addPolyPolygon( const ::com::sun::star::geometry::RealPoint2D& position, const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XPolyPolygon2D >& polyPolygon ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getNumberOfPolygons( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getNumberOfPolygonPoints( ::sal_Int32 polygon ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::rendering::FillRule SAL_CALL getFillRule( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setFillRule( ::com::sun::star::rendering::FillRule fillRule ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL isClosed( ::sal_Int32 index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setClosed( ::sal_Int32 index, ::sal_Bool closedState ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ // XLinePolyPolygon2D
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::geometry::RealPoint2D > > SAL_CALL getPoints( ::sal_Int32 nPolygonIndex, ::sal_Int32 nNumberOfPolygons, ::sal_Int32 nPointIndex, ::sal_Int32 nNumberOfPoints ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setPoints( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::geometry::RealPoint2D > >& points, ::sal_Int32 nPolygonIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::geometry::RealPoint2D SAL_CALL getPoint( ::sal_Int32 nPolygonIndex, ::sal_Int32 nPointIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setPoint( const ::com::sun::star::geometry::RealPoint2D& point, ::sal_Int32 nPolygonIndex, ::sal_Int32 nPointIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ // XBezierPolyPolygon2D
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::geometry::RealBezierSegment2D > > SAL_CALL getBezierSegments( ::sal_Int32 nPolygonIndex, ::sal_Int32 nNumberOfPolygons, ::sal_Int32 nPointIndex, ::sal_Int32 nNumberOfPoints ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setBezierSegments( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::geometry::RealBezierSegment2D > >& points, ::sal_Int32 nPolygonIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::geometry::RealBezierSegment2D SAL_CALL getBezierSegment( ::sal_Int32 nPolygonIndex, ::sal_Int32 nPointIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setBezierSegment( const ::com::sun::star::geometry::RealBezierSegment2D& point, ::sal_Int32 nPolygonIndex, ::sal_Int32 nPointIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException );
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException );
+
+ B2DPolyPolygon getPolyPolygon() const;
+
+ protected:
+ /// Check whether index is a valid polygon index
+ void checkIndex( sal_Int32 nIndex ) const // throw (::com::sun::star::lang::IndexOutOfBoundsException);
+ {
+ if( nIndex < 0 || nIndex >= static_cast<sal_Int32>(maPolyPoly.count()) )
+ throw ::com::sun::star::lang::IndexOutOfBoundsException();
+ }
+
+ 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.
+ B2DPolyPolygon getPolyPolygonUnsafe() const
+ {
+ return maPolyPoly;
+ }
+
+ /// Called whenever internal polypolygon gets modified
+ virtual void modifying() const {}
+
+ private:
+ B2DPolyPolygon maPolyPoly;
+ ::com::sun::star::rendering::FillRule meFillRule;
+ };
+}
+}
+
+#endif /* INCLUDED_BASEGFX_UNOPOLYPOLYGON_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/tools/unotools.hxx b/include/basegfx/tools/unotools.hxx
new file mode 100644
index 000000000000..c95eb5361f5c
--- /dev/null
+++ b/include/basegfx/tools/unotools.hxx
@@ -0,0 +1,40 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_BASEGFX_UNOTOOLS_HXX
+#define INCLUDED_BASEGFX_UNOTOOLS_HXX
+
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase3.hxx>
+#include <com/sun/star/drawing/PolyPolygonBezierCoords.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>
+
+
+namespace basegfx
+{
+class B2DPolyPolygon;
+
+namespace unotools
+{
+
+ BASEGFX_DLLPUBLIC B2DPolyPolygon polyPolygonBezierToB2DPolyPolygon(const ::com::sun::star::drawing::PolyPolygonBezierCoords& rSourcePolyPolygon)
+ throw( ::com::sun::star::lang::IllegalArgumentException );
+
+ BASEGFX_DLLPUBLIC void b2DPolyPolygonToPolyPolygonBezier( const B2DPolyPolygon& rPolyPoly,
+ ::com::sun::star::drawing::PolyPolygonBezierCoords& rRetval );
+}
+}
+
+#endif /* INCLUDED_BASEGFX_UNOTOOLS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/tools/zoomtools.hxx b/include/basegfx/tools/zoomtools.hxx
new file mode 100644
index 000000000000..44d9052a2552
--- /dev/null
+++ b/include/basegfx/tools/zoomtools.hxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2012 Tim Hardeck <thardeck@suse.com>
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef _BGFX_TOOLS_ZOOMTOOLS_HXX
+#define _BGFX_TOOLS_ZOOMTOOLS_HXX
+
+#include <sal/types.h>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ /** This namespace provides functions for optimized geometric zooming
+ */
+ namespace zoomtools
+ {
+ BASEGFX_DLLPUBLIC long zoomOut(long nCurrent);
+ BASEGFX_DLLPUBLIC long zoomIn(long nCurrent);
+ }
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/tuple/b2dtuple.hxx b/include/basegfx/tuple/b2dtuple.hxx
new file mode 100644
index 000000000000..380ba8adf493
--- /dev/null
+++ b/include/basegfx/tuple/b2dtuple.hxx
@@ -0,0 +1,352 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_TUPLE_B2DTUPLE_HXX
+#define _BGFX_TUPLE_B2DTUPLE_HXX
+
+#include <sal/types.h>
+#include <basegfx/numeric/ftools.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ // predeclarations
+ class B2ITuple;
+
+ /** Base class for all Points/Vectors with two double values
+
+ This class provides all methods common to Point
+ avd Vector classes which are derived from here.
+
+ @derive Use this class to implement Points or Vectors
+ which are based on two double values
+ */
+ class SAL_WARN_UNUSED B2DTuple
+ {
+ protected:
+ double mfX;
+ double mfY;
+
+ public:
+ /** Create a 2D Tuple
+
+ The tuple is initialized to (0.0, 0.0)
+ */
+ B2DTuple()
+ : mfX(0.0),
+ mfY(0.0)
+ {}
+
+ /** Create a 2D Tuple
+
+ @param fX
+ This parameter is used to initialize the X-coordinate
+ of the 2D Tuple.
+
+ @param fY
+ This parameter is used to initialize the Y-coordinate
+ of the 2D Tuple.
+ */
+ B2DTuple(double fX, double fY)
+ : mfX( fX ),
+ mfY( fY )
+ {}
+
+ /** Create a copy of a 2D Tuple
+
+ @param rTup
+ The 2D Tuple which will be copied.
+ */
+ B2DTuple(const B2DTuple& rTup)
+ : mfX( rTup.mfX ),
+ mfY( rTup.mfY )
+ {}
+
+ /** Create a copy of a 2D integer Tuple
+
+ @param rTup
+ The 2D Tuple which will be copied.
+ */
+ BASEGFX_DLLPUBLIC explicit B2DTuple(const B2ITuple& rTup);
+
+ ~B2DTuple()
+ {}
+
+ /// Get X-Coordinate of 2D Tuple
+ double getX() const
+ {
+ return mfX;
+ }
+
+ /// Get Y-Coordinate of 2D Tuple
+ double getY() const
+ {
+ return mfY;
+ }
+
+ /// Set X-Coordinate of 2D Tuple
+ void setX(double fX)
+ {
+ mfX = fX;
+ }
+
+ /// Set Y-Coordinate of 2D Tuple
+ void setY(double fY)
+ {
+ mfY = fY;
+ }
+
+ /// Array-access to 2D Tuple
+ const double& operator[] (int nPos) const
+ {
+ // Here, normally one if(...) should be used. In the assumption that
+ // both double members can be accessed as an array a shortcut is used here.
+ // if(0 == nPos) return mfX; return mfY;
+ return *((&mfX) + nPos);
+ }
+
+ /// Array-access to 2D Tuple
+ double& operator[] (int nPos)
+ {
+ // Here, normally one if(...) should be used. In the assumption that
+ // both double members can be accessed as an array a shortcut is used here.
+ // if(0 == nPos) return mfX; return mfY;
+ return *((&mfX) + nPos);
+ }
+
+ // comparators with tolerance
+ //////////////////////////////////////////////////////////////////////
+
+ bool equalZero() const
+ {
+ return (this == &getEmptyTuple() ||
+ (fTools::equalZero(mfX) && fTools::equalZero(mfY)));
+ }
+
+ bool equalZero(const double& rfSmallValue) const
+ {
+ return (this == &getEmptyTuple() ||
+ (fTools::equalZero(mfX, rfSmallValue) && fTools::equalZero(mfY, rfSmallValue)));
+ }
+
+ bool equal(const B2DTuple& rTup) const
+ {
+ return (
+ this == &rTup ||
+ (fTools::equal(mfX, rTup.mfX) &&
+ fTools::equal(mfY, rTup.mfY)));
+ }
+
+ bool equal(const B2DTuple& rTup, const double& rfSmallValue) const
+ {
+ return (
+ this == &rTup ||
+ (fTools::equal(mfX, rTup.mfX, rfSmallValue) &&
+ fTools::equal(mfY, rTup.mfY, rfSmallValue)));
+ }
+
+ // operators
+ //////////////////////////////////////////////////////////////////////
+
+ B2DTuple& operator+=( const B2DTuple& rTup )
+ {
+ mfX += rTup.mfX;
+ mfY += rTup.mfY;
+ return *this;
+ }
+
+ B2DTuple& operator-=( const B2DTuple& rTup )
+ {
+ mfX -= rTup.mfX;
+ mfY -= rTup.mfY;
+ return *this;
+ }
+
+ B2DTuple& operator/=( const B2DTuple& rTup )
+ {
+ mfX /= rTup.mfX;
+ mfY /= rTup.mfY;
+ return *this;
+ }
+
+ B2DTuple& operator*=( const B2DTuple& rTup )
+ {
+ mfX *= rTup.mfX;
+ mfY *= rTup.mfY;
+ return *this;
+ }
+
+ B2DTuple& operator*=(double t)
+ {
+ mfX *= t;
+ mfY *= t;
+ return *this;
+ }
+
+ B2DTuple& operator/=(double t)
+ {
+ const double fVal(1.0 / t);
+ mfX *= fVal;
+ mfY *= fVal;
+ return *this;
+ }
+
+ B2DTuple operator-(void) const
+ {
+ return B2DTuple(-mfX, -mfY);
+ }
+
+ bool operator==( const B2DTuple& rTup ) const
+ {
+ return equal(rTup);
+ }
+
+ bool operator!=( const B2DTuple& rTup ) const
+ {
+ return !equal(rTup);
+ }
+
+ B2DTuple& operator=( const B2DTuple& rTup )
+ {
+ mfX = rTup.mfX;
+ mfY = rTup.mfY;
+ return *this;
+ }
+
+ BASEGFX_DLLPUBLIC static const B2DTuple& getEmptyTuple();
+ };
+
+ // external operators
+ //////////////////////////////////////////////////////////////////////////
+
+ inline B2DTuple minimum(const B2DTuple& rTupA, const B2DTuple& rTupB)
+ {
+ B2DTuple aMin(
+ (rTupB.getX() < rTupA.getX()) ? rTupB.getX() : rTupA.getX(),
+ (rTupB.getY() < rTupA.getY()) ? rTupB.getY() : rTupA.getY());
+ return aMin;
+ }
+
+ inline B2DTuple maximum(const B2DTuple& rTupA, const B2DTuple& rTupB)
+ {
+ B2DTuple aMax(
+ (rTupB.getX() > rTupA.getX()) ? rTupB.getX() : rTupA.getX(),
+ (rTupB.getY() > rTupA.getY()) ? rTupB.getY() : rTupA.getY());
+ return aMax;
+ }
+
+ inline B2DTuple absolute(const B2DTuple& rTup)
+ {
+ B2DTuple aAbs(
+ (0.0 > rTup.getX()) ? -rTup.getX() : rTup.getX(),
+ (0.0 > rTup.getY()) ? -rTup.getY() : rTup.getY());
+ return aAbs;
+ }
+
+ inline B2DTuple interpolate(const B2DTuple& rOld1, const B2DTuple& rOld2, double t)
+ {
+ B2DTuple aInt(
+ ((rOld2.getX() - rOld1.getX()) * t) + rOld1.getX(),
+ ((rOld2.getY() - rOld1.getY()) * t) + rOld1.getY());
+ return aInt;
+ }
+
+ inline B2DTuple average(const B2DTuple& rOld1, const B2DTuple& rOld2)
+ {
+ B2DTuple aAvg(
+ (rOld1.getX() + rOld2.getX()) * 0.5,
+ (rOld1.getY() + rOld2.getY()) * 0.5);
+ return aAvg;
+ }
+
+ inline B2DTuple average(const B2DTuple& rOld1, const B2DTuple& rOld2, const B2DTuple& rOld3)
+ {
+ B2DTuple aAvg(
+ (rOld1.getX() + rOld2.getX() + rOld3.getX()) * (1.0 / 3.0),
+ (rOld1.getY() + rOld2.getY() + rOld3.getY()) * (1.0 / 3.0));
+ return aAvg;
+ }
+
+ inline B2DTuple operator+(const B2DTuple& rTupA, const B2DTuple& rTupB)
+ {
+ B2DTuple aSum(rTupA);
+ aSum += rTupB;
+ return aSum;
+ }
+
+ inline B2DTuple operator-(const B2DTuple& rTupA, const B2DTuple& rTupB)
+ {
+ B2DTuple aSub(rTupA);
+ aSub -= rTupB;
+ return aSub;
+ }
+
+ inline B2DTuple operator/(const B2DTuple& rTupA, const B2DTuple& rTupB)
+ {
+ B2DTuple aDiv(rTupA);
+ aDiv /= rTupB;
+ return aDiv;
+ }
+
+ inline B2DTuple operator*(const B2DTuple& rTupA, const B2DTuple& rTupB)
+ {
+ B2DTuple aMul(rTupA);
+ aMul *= rTupB;
+ return aMul;
+ }
+
+ inline B2DTuple operator*(const B2DTuple& rTup, double t)
+ {
+ B2DTuple aNew(rTup);
+ aNew *= t;
+ return aNew;
+ }
+
+ inline B2DTuple operator*(double t, const B2DTuple& rTup)
+ {
+ B2DTuple aNew(rTup);
+ aNew *= t;
+ return aNew;
+ }
+
+ inline B2DTuple operator/(const B2DTuple& rTup, double t)
+ {
+ B2DTuple aNew(rTup);
+ aNew /= t;
+ return aNew;
+ }
+
+ inline B2DTuple operator/(double t, const B2DTuple& rTup)
+ {
+ B2DTuple aNew(t, t);
+ B2DTuple aTmp(rTup);
+ aNew /= aTmp;
+ return aNew;
+ }
+
+ /** Round double to nearest integer for 2D tuple
+
+ @return the nearest integer for this tuple
+ */
+ BASEGFX_DLLPUBLIC B2ITuple fround(const B2DTuple& rTup);
+} // end of namespace basegfx
+
+#endif /* _BGFX_TUPLE_B2DTUPLE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/tuple/b2i64tuple.hxx b/include/basegfx/tuple/b2i64tuple.hxx
new file mode 100644
index 000000000000..debb4cabe578
--- /dev/null
+++ b/include/basegfx/tuple/b2i64tuple.hxx
@@ -0,0 +1,305 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_TUPLE_B2I64TUPLE_HXX
+#define _BGFX_TUPLE_B2I64TUPLE_HXX
+
+#include <sal/types.h>
+#include <basegfx/tuple/b2dtuple.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+
+namespace basegfx
+{
+ /** Base class for all Points/Vectors with two sal_Int64 values
+
+ This class provides all methods common to Point
+ avd Vector classes which are derived from here.
+
+ @derive Use this class to implement Points or Vectors
+ which are based on two sal_Int64 values
+ */
+ class BASEGFX_DLLPUBLIC SAL_WARN_UNUSED B2I64Tuple
+ {
+ protected:
+ sal_Int64 mnX;
+ sal_Int64 mnY;
+
+ public:
+ /** Create a 2D Tuple
+
+ The tuple is initialized to (0, 0)
+ */
+ B2I64Tuple()
+ : mnX(0),
+ mnY(0)
+ {}
+
+ /** Create a 2D Tuple
+
+ @param fX
+ This parameter is used to initialize the X-coordinate
+ of the 2D Tuple.
+
+ @param fY
+ This parameter is used to initialize the Y-coordinate
+ of the 2D Tuple.
+ */
+ B2I64Tuple(sal_Int64 fX, sal_Int64 fY)
+ : mnX( fX ),
+ mnY( fY )
+ {}
+
+ /** Create a copy of a 2D Tuple
+
+ @param rTup
+ The 2D Tuple which will be copied.
+ */
+ B2I64Tuple(const B2I64Tuple& rTup)
+ : mnX( rTup.mnX ),
+ mnY( rTup.mnY )
+ {}
+
+ ~B2I64Tuple()
+ {}
+
+ /// Get X-Coordinate of 2D Tuple
+ sal_Int64 getX() const
+ {
+ return mnX;
+ }
+
+ /// Get Y-Coordinate of 2D Tuple
+ sal_Int64 getY() const
+ {
+ return mnY;
+ }
+
+ /// Set X-Coordinate of 2D Tuple
+ void setX(sal_Int64 fX)
+ {
+ mnX = fX;
+ }
+
+ /// Set Y-Coordinate of 2D Tuple
+ void setY(sal_Int64 fY)
+ {
+ mnY = fY;
+ }
+
+ /// Array-access to 2D Tuple
+ const sal_Int64& operator[] (int nPos) const
+ {
+ // Here, normally one if(...) should be used. In the assumption that
+ // both sal_Int64 members can be accessed as an array a shortcut is used here.
+ // if(0 == nPos) return mnX; return mnY;
+ return *((&mnX) + nPos);
+ }
+
+ /// Array-access to 2D Tuple
+ sal_Int64& operator[] (int nPos)
+ {
+ // Here, normally one if(...) should be used. In the assumption that
+ // both sal_Int64 members can be accessed as an array a shortcut is used here.
+ // if(0 == nPos) return mnX; return mnY;
+ return *((&mnX) + nPos);
+ }
+
+ // operators
+ //////////////////////////////////////////////////////////////////////
+
+ B2I64Tuple& operator+=( const B2I64Tuple& rTup )
+ {
+ mnX += rTup.mnX;
+ mnY += rTup.mnY;
+ return *this;
+ }
+
+ B2I64Tuple& operator-=( const B2I64Tuple& rTup )
+ {
+ mnX -= rTup.mnX;
+ mnY -= rTup.mnY;
+ return *this;
+ }
+
+ B2I64Tuple& operator/=( const B2I64Tuple& rTup )
+ {
+ mnX /= rTup.mnX;
+ mnY /= rTup.mnY;
+ return *this;
+ }
+
+ B2I64Tuple& operator*=( const B2I64Tuple& rTup )
+ {
+ mnX *= rTup.mnX;
+ mnY *= rTup.mnY;
+ return *this;
+ }
+
+ B2I64Tuple& operator*=(sal_Int64 t)
+ {
+ mnX *= t;
+ mnY *= t;
+ return *this;
+ }
+
+ B2I64Tuple& operator/=(sal_Int64 t)
+ {
+ mnX /= t;
+ mnY /= t;
+ return *this;
+ }
+
+ B2I64Tuple operator-(void) const
+ {
+ return B2I64Tuple(-mnX, -mnY);
+ }
+
+ bool equalZero() const { return mnX == 0 && mnY == 0; }
+
+ bool operator==( const B2I64Tuple& rTup ) const
+ {
+ return this == &rTup || (rTup.mnX == mnX && rTup.mnY == mnY);
+ }
+
+ bool operator!=( const B2I64Tuple& rTup ) const
+ {
+ return !(*this == rTup);
+ }
+
+ B2I64Tuple& operator=( const B2I64Tuple& rTup )
+ {
+ mnX = rTup.mnX;
+ mnY = rTup.mnY;
+ return *this;
+ }
+ };
+
+ // external operators
+ //////////////////////////////////////////////////////////////////////////
+
+ inline B2I64Tuple minimum(const B2I64Tuple& rTupA, const B2I64Tuple& rTupB)
+ {
+ B2I64Tuple aMin(
+ (rTupB.getX() < rTupA.getX()) ? rTupB.getX() : rTupA.getX(),
+ (rTupB.getY() < rTupA.getY()) ? rTupB.getY() : rTupA.getY());
+ return aMin;
+ }
+
+ inline B2I64Tuple maximum(const B2I64Tuple& rTupA, const B2I64Tuple& rTupB)
+ {
+ B2I64Tuple aMax(
+ (rTupB.getX() > rTupA.getX()) ? rTupB.getX() : rTupA.getX(),
+ (rTupB.getY() > rTupA.getY()) ? rTupB.getY() : rTupA.getY());
+ return aMax;
+ }
+
+ inline B2I64Tuple absolute(const B2I64Tuple& rTup)
+ {
+ B2I64Tuple aAbs(
+ (0 > rTup.getX()) ? -rTup.getX() : rTup.getX(),
+ (0 > rTup.getY()) ? -rTup.getY() : rTup.getY());
+ return aAbs;
+ }
+
+ inline B2DTuple interpolate(const B2I64Tuple& rOld1, const B2I64Tuple& rOld2, double t)
+ {
+ B2DTuple aInt(
+ ((rOld2.getX() - rOld1.getX()) * t) + rOld1.getX(),
+ ((rOld2.getY() - rOld1.getY()) * t) + rOld1.getY());
+ return aInt;
+ }
+
+ inline B2DTuple average(const B2I64Tuple& rOld1, const B2I64Tuple& rOld2)
+ {
+ B2DTuple aAvg(
+ (rOld1.getX() + rOld2.getX()) * 0.5,
+ (rOld1.getY() + rOld2.getY()) * 0.5);
+ return aAvg;
+ }
+
+ inline B2DTuple average(const B2I64Tuple& rOld1, const B2I64Tuple& rOld2, const B2I64Tuple& rOld3)
+ {
+ B2DTuple aAvg(
+ (rOld1.getX() + rOld2.getX() + rOld3.getX()) * (1.0 / 3.0),
+ (rOld1.getY() + rOld2.getY() + rOld3.getY()) * (1.0 / 3.0));
+ return aAvg;
+ }
+
+ inline B2I64Tuple operator+(const B2I64Tuple& rTupA, const B2I64Tuple& rTupB)
+ {
+ B2I64Tuple aSum(rTupA);
+ aSum += rTupB;
+ return aSum;
+ }
+
+ inline B2I64Tuple operator-(const B2I64Tuple& rTupA, const B2I64Tuple& rTupB)
+ {
+ B2I64Tuple aSub(rTupA);
+ aSub -= rTupB;
+ return aSub;
+ }
+
+ inline B2I64Tuple operator/(const B2I64Tuple& rTupA, const B2I64Tuple& rTupB)
+ {
+ B2I64Tuple aDiv(rTupA);
+ aDiv /= rTupB;
+ return aDiv;
+ }
+
+ inline B2I64Tuple operator*(const B2I64Tuple& rTupA, const B2I64Tuple& rTupB)
+ {
+ B2I64Tuple aMul(rTupA);
+ aMul *= rTupB;
+ return aMul;
+ }
+
+ inline B2I64Tuple operator*(const B2I64Tuple& rTup, sal_Int64 t)
+ {
+ B2I64Tuple aNew(rTup);
+ aNew *= t;
+ return aNew;
+ }
+
+ inline B2I64Tuple operator*(sal_Int64 t, const B2I64Tuple& rTup)
+ {
+ B2I64Tuple aNew(rTup);
+ aNew *= t;
+ return aNew;
+ }
+
+ inline B2I64Tuple operator/(const B2I64Tuple& rTup, sal_Int64 t)
+ {
+ B2I64Tuple aNew(rTup);
+ aNew /= t;
+ return aNew;
+ }
+
+ inline B2I64Tuple operator/(sal_Int64 t, const B2I64Tuple& rTup)
+ {
+ B2I64Tuple aNew(t, t);
+ B2I64Tuple aTmp(rTup);
+ aNew /= aTmp;
+ return aNew;
+ }
+} // end of namespace basegfx
+
+#endif /* _BGFX_TUPLE_B2I64TUPLE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/tuple/b2ituple.hxx b/include/basegfx/tuple/b2ituple.hxx
new file mode 100644
index 000000000000..41203a0c58c4
--- /dev/null
+++ b/include/basegfx/tuple/b2ituple.hxx
@@ -0,0 +1,208 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_TUPLE_B2ITUPLE_HXX
+#define _BGFX_TUPLE_B2ITUPLE_HXX
+
+#include <sal/types.h>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ /** Base class for all Points/Vectors with two sal_Int32 values
+
+ This class provides all methods common to Point
+ avd Vector classes which are derived from here.
+
+ @derive Use this class to implement Points or Vectors
+ which are based on two sal_Int32 values
+ */
+ class BASEGFX_DLLPUBLIC SAL_WARN_UNUSED B2ITuple
+ {
+ protected:
+ sal_Int32 mnX;
+ sal_Int32 mnY;
+
+ public:
+ /** Create a 2D Tuple
+
+ The tuple is initialized to (0, 0)
+ */
+ B2ITuple()
+ : mnX(0),
+ mnY(0)
+ {}
+
+ /** Create a 2D Tuple
+
+ @param fX
+ This parameter is used to initialize the X-coordinate
+ of the 2D Tuple.
+
+ @param fY
+ This parameter is used to initialize the Y-coordinate
+ of the 2D Tuple.
+ */
+ B2ITuple(sal_Int32 fX, sal_Int32 fY)
+ : mnX( fX ),
+ mnY( fY )
+ {}
+
+ /** Create a copy of a 2D Tuple
+
+ @param rTup
+ The 2D Tuple which will be copied.
+ */
+ B2ITuple(const B2ITuple& rTup)
+ : mnX( rTup.mnX ),
+ mnY( rTup.mnY )
+ {}
+
+ ~B2ITuple()
+ {}
+
+ /// Get X-Coordinate of 2D Tuple
+ sal_Int32 getX() const
+ {
+ return mnX;
+ }
+
+ /// Get Y-Coordinate of 2D Tuple
+ sal_Int32 getY() const
+ {
+ return mnY;
+ }
+
+ /// Set X-Coordinate of 2D Tuple
+ void setX(sal_Int32 fX)
+ {
+ mnX = fX;
+ }
+
+ /// Set Y-Coordinate of 2D Tuple
+ void setY(sal_Int32 fY)
+ {
+ mnY = fY;
+ }
+
+ /// Array-access to 2D Tuple
+ const sal_Int32& operator[] (int nPos) const
+ {
+ // Here, normally one if(...) should be used. In the assumption that
+ // both sal_Int32 members can be accessed as an array a shortcut is used here.
+ // if(0 == nPos) return mnX; return mnY;
+ return *((&mnX) + nPos);
+ }
+
+ /// Array-access to 2D Tuple
+ sal_Int32& operator[] (int nPos)
+ {
+ // Here, normally one if(...) should be used. In the assumption that
+ // both sal_Int32 members can be accessed as an array a shortcut is used here.
+ // if(0 == nPos) return mnX; return mnY;
+ return *((&mnX) + nPos);
+ }
+
+ // operators
+ //////////////////////////////////////////////////////////////////////
+
+ B2ITuple& operator+=( const B2ITuple& rTup )
+ {
+ mnX += rTup.mnX;
+ mnY += rTup.mnY;
+ return *this;
+ }
+
+ B2ITuple& operator-=( const B2ITuple& rTup )
+ {
+ mnX -= rTup.mnX;
+ mnY -= rTup.mnY;
+ return *this;
+ }
+
+ B2ITuple& operator/=( const B2ITuple& rTup )
+ {
+ mnX /= rTup.mnX;
+ mnY /= rTup.mnY;
+ return *this;
+ }
+
+ B2ITuple& operator*=( const B2ITuple& rTup )
+ {
+ mnX *= rTup.mnX;
+ mnY *= rTup.mnY;
+ return *this;
+ }
+
+ B2ITuple& operator*=(sal_Int32 t)
+ {
+ mnX *= t;
+ mnY *= t;
+ return *this;
+ }
+
+ B2ITuple& operator/=(sal_Int32 t)
+ {
+ mnX /= t;
+ mnY /= t;
+ return *this;
+ }
+
+ B2ITuple operator-(void) const
+ {
+ return B2ITuple(-mnX, -mnY);
+ }
+
+ bool equalZero() const { return mnX == 0 && mnY == 0; }
+
+ bool operator==( const B2ITuple& rTup ) const
+ {
+ return this == &rTup || (rTup.mnX == mnX && rTup.mnY == mnY);
+ }
+
+ bool operator!=( const B2ITuple& rTup ) const
+ {
+ return !(*this == rTup);
+ }
+
+ B2ITuple& operator=( const B2ITuple& rTup )
+ {
+ mnX = rTup.mnX;
+ mnY = rTup.mnY;
+ return *this;
+ }
+ };
+
+ // external operators
+ //////////////////////////////////////////////////////////////////////////
+ class B2DTuple;
+
+ BASEGFX_DLLPUBLIC B2ITuple operator+(const B2ITuple& rTupA, const B2ITuple& rTupB);
+ BASEGFX_DLLPUBLIC B2ITuple operator-(const B2ITuple& rTupA, const B2ITuple& rTupB);
+ BASEGFX_DLLPUBLIC B2ITuple operator/(const B2ITuple& rTupA, const B2ITuple& rTupB);
+ BASEGFX_DLLPUBLIC B2ITuple operator*(const B2ITuple& rTupA, const B2ITuple& rTupB);
+ BASEGFX_DLLPUBLIC B2ITuple operator*(const B2ITuple& rTup, sal_Int32 t);
+ BASEGFX_DLLPUBLIC B2ITuple operator*(sal_Int32 t, const B2ITuple& rTup);
+ BASEGFX_DLLPUBLIC B2ITuple operator/(const B2ITuple& rTup, sal_Int32 t);
+ BASEGFX_DLLPUBLIC B2ITuple operator/(sal_Int32 t, const B2ITuple& rTup);
+} // end of namespace basegfx
+
+#endif /* _BGFX_TUPLE_B2ITUPLE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/tuple/b3dtuple.hxx b/include/basegfx/tuple/b3dtuple.hxx
new file mode 100644
index 000000000000..1eb4dd38de09
--- /dev/null
+++ b/include/basegfx/tuple/b3dtuple.hxx
@@ -0,0 +1,421 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_TUPLE_B3DTUPLE_HXX
+#define _BGFX_TUPLE_B3DTUPLE_HXX
+
+#include <sal/types.h>
+#include <basegfx/numeric/ftools.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ // predeclarations
+ class B3ITuple;
+
+ /** Base class for all Points/Vectors with three double values
+
+ This class provides all methods common to Point
+ avd Vector classes which are derived from here.
+
+ @derive Use this class to implement Points or Vectors
+ which are based on three double values
+ */
+ class BASEGFX_DLLPUBLIC SAL_WARN_UNUSED B3DTuple
+ {
+ protected:
+ double mfX;
+ double mfY;
+ double mfZ;
+
+ public:
+ /** Create a 3D Tuple
+
+ The tuple is initialized to (0.0, 0.0, 0.0)
+ */
+ B3DTuple()
+ : mfX(0.0),
+ mfY(0.0),
+ mfZ(0.0)
+ {}
+
+ /** Create a 3D Tuple
+
+ @param fX
+ This parameter is used to initialize the X-coordinate
+ of the 3D Tuple.
+
+ @param fY
+ This parameter is used to initialize the Y-coordinate
+ of the 3D Tuple.
+
+ @param fZ
+ This parameter is used to initialize the Z-coordinate
+ of the 3D Tuple.
+ */
+ B3DTuple(double fX, double fY, double fZ)
+ : mfX(fX),
+ mfY(fY),
+ mfZ(fZ)
+ {}
+
+ /** Create a copy of a 3D Tuple
+
+ @param rTup
+ The 3D Tuple which will be copied.
+ */
+ B3DTuple(const B3DTuple& rTup)
+ : mfX( rTup.mfX ),
+ mfY( rTup.mfY ),
+ mfZ( rTup.mfZ )
+ {}
+
+ ~B3DTuple()
+ {}
+
+ /// get X-Coordinate of 3D Tuple
+ double getX() const
+ {
+ return mfX;
+ }
+
+ /// get Y-Coordinate of 3D Tuple
+ double getY() const
+ {
+ return mfY;
+ }
+
+ /// get Z-Coordinate of 3D Tuple
+ double getZ() const
+ {
+ return mfZ;
+ }
+
+ /// set X-Coordinate of 3D Tuple
+ void setX(double fX)
+ {
+ mfX = fX;
+ }
+
+ /// set Y-Coordinate of 3D Tuple
+ void setY(double fY)
+ {
+ mfY = fY;
+ }
+
+ /// set Z-Coordinate of 3D Tuple
+ void setZ(double fZ)
+ {
+ mfZ = fZ;
+ }
+
+ /// Array-access to 3D Tuple
+ const double& operator[] (int nPos) const
+ {
+ // Here, normally two if(...)'s should be used. In the assumption that
+ // both double members can be accessed as an array a shortcut is used here.
+ // if(0 == nPos) return mfX; if(1 == nPos) return mfY; return mfZ;
+ return *((&mfX) + nPos);
+ }
+
+ /// Array-access to 3D Tuple
+ double& operator[] (int nPos)
+ {
+ // Here, normally two if(...)'s should be used. In the assumption that
+ // both double members can be accessed as an array a shortcut is used here.
+ // if(0 == nPos) return mfX; if(1 == nPos) return mfY; return mfZ;
+ return *((&mfX) + nPos);
+ }
+
+ // comparators with tolerance
+ //////////////////////////////////////////////////////////////////////
+
+ bool equalZero() const
+ {
+ return (this == &getEmptyTuple() ||
+ (::basegfx::fTools::equalZero(mfX)
+ && ::basegfx::fTools::equalZero(mfY)
+ && ::basegfx::fTools::equalZero(mfZ)));
+ }
+
+ bool equalZero(const double& rfSmallValue) const
+ {
+ return (this == &getEmptyTuple() ||
+ (::basegfx::fTools::equalZero(mfX, rfSmallValue)
+ && ::basegfx::fTools::equalZero(mfY, rfSmallValue)
+ && ::basegfx::fTools::equalZero(mfZ, rfSmallValue)));
+ }
+
+ bool equal(const B3DTuple& rTup) const
+ {
+ return (
+ this == &rTup ||
+ (::basegfx::fTools::equal(mfX, rTup.mfX) &&
+ ::basegfx::fTools::equal(mfY, rTup.mfY) &&
+ ::basegfx::fTools::equal(mfZ, rTup.mfZ)));
+ }
+
+ bool equal(const B3DTuple& rTup, const double& rfSmallValue) const
+ {
+ return (
+ this == &rTup ||
+ (::basegfx::fTools::equal(mfX, rTup.mfX, rfSmallValue) &&
+ ::basegfx::fTools::equal(mfY, rTup.mfY, rfSmallValue) &&
+ ::basegfx::fTools::equal(mfZ, rTup.mfZ, rfSmallValue)));
+ }
+
+ // operators
+ //////////////////////////////////////////////////////////////////////
+
+ B3DTuple& operator+=( const B3DTuple& rTup )
+ {
+ mfX += rTup.mfX;
+ mfY += rTup.mfY;
+ mfZ += rTup.mfZ;
+ return *this;
+ }
+
+ B3DTuple& operator-=( const B3DTuple& rTup )
+ {
+ mfX -= rTup.mfX;
+ mfY -= rTup.mfY;
+ mfZ -= rTup.mfZ;
+ return *this;
+ }
+
+ B3DTuple& operator/=( const B3DTuple& rTup )
+ {
+ mfX /= rTup.mfX;
+ mfY /= rTup.mfY;
+ mfZ /= rTup.mfZ;
+ return *this;
+ }
+
+ B3DTuple& operator*=( const B3DTuple& rTup )
+ {
+ mfX *= rTup.mfX;
+ mfY *= rTup.mfY;
+ mfZ *= rTup.mfZ;
+ return *this;
+ }
+
+ B3DTuple& operator*=(double t)
+ {
+ mfX *= t;
+ mfY *= t;
+ mfZ *= t;
+ return *this;
+ }
+
+ B3DTuple& operator/=(double t)
+ {
+ const double fVal(1.0 / t);
+ mfX *= fVal;
+ mfY *= fVal;
+ mfZ *= fVal;
+ return *this;
+ }
+
+ B3DTuple operator-(void) const
+ {
+ return B3DTuple(-mfX, -mfY, -mfZ);
+ }
+
+ bool operator==( const B3DTuple& rTup ) const
+ {
+ return equal(rTup);
+ }
+
+ bool operator!=( const B3DTuple& rTup ) const
+ {
+ return !equal(rTup);
+ }
+
+ B3DTuple& operator=( const B3DTuple& rTup )
+ {
+ mfX = rTup.mfX;
+ mfY = rTup.mfY;
+ mfZ = rTup.mfZ;
+ return *this;
+ }
+
+ void correctValues(const double fCompareValue = 0.0)
+ {
+ if(0.0 == fCompareValue)
+ {
+ if(::basegfx::fTools::equalZero(mfX))
+ {
+ mfX = 0.0;
+ }
+
+ if(::basegfx::fTools::equalZero(mfY))
+ {
+ mfY = 0.0;
+ }
+
+ if(::basegfx::fTools::equalZero(mfZ))
+ {
+ mfZ = 0.0;
+ }
+ }
+ else
+ {
+ if(::basegfx::fTools::equal(mfX, fCompareValue))
+ {
+ mfX = fCompareValue;
+ }
+
+ if(::basegfx::fTools::equal(mfY, fCompareValue))
+ {
+ mfY = fCompareValue;
+ }
+
+ if(::basegfx::fTools::equal(mfZ, fCompareValue))
+ {
+ mfZ = fCompareValue;
+ }
+ }
+ }
+
+ static const B3DTuple& getEmptyTuple();
+ };
+
+ // external operators
+ //////////////////////////////////////////////////////////////////////////
+
+ inline B3DTuple minimum(const B3DTuple& rTupA, const B3DTuple& rTupB)
+ {
+ B3DTuple aMin(
+ (rTupB.getX() < rTupA.getX()) ? rTupB.getX() : rTupA.getX(),
+ (rTupB.getY() < rTupA.getY()) ? rTupB.getY() : rTupA.getY(),
+ (rTupB.getZ() < rTupA.getZ()) ? rTupB.getZ() : rTupA.getZ());
+ return aMin;
+ }
+
+ inline B3DTuple maximum(const B3DTuple& rTupA, const B3DTuple& rTupB)
+ {
+ B3DTuple aMax(
+ (rTupB.getX() > rTupA.getX()) ? rTupB.getX() : rTupA.getX(),
+ (rTupB.getY() > rTupA.getY()) ? rTupB.getY() : rTupA.getY(),
+ (rTupB.getZ() > rTupA.getZ()) ? rTupB.getZ() : rTupA.getZ());
+ return aMax;
+ }
+
+ inline B3DTuple absolute(const B3DTuple& rTup)
+ {
+ B3DTuple aAbs(
+ (0.0 > rTup.getX()) ? -rTup.getX() : rTup.getX(),
+ (0.0 > rTup.getY()) ? -rTup.getY() : rTup.getY(),
+ (0.0 > rTup.getZ()) ? -rTup.getZ() : rTup.getZ());
+ return aAbs;
+ }
+
+ inline B3DTuple interpolate(const B3DTuple& rOld1, const B3DTuple& rOld2, double t)
+ {
+ B3DTuple aInt(
+ ((rOld2.getX() - rOld1.getX()) * t) + rOld1.getX(),
+ ((rOld2.getY() - rOld1.getY()) * t) + rOld1.getY(),
+ ((rOld2.getZ() - rOld1.getZ()) * t) + rOld1.getZ());
+ return aInt;
+ }
+
+ inline B3DTuple average(const B3DTuple& rOld1, const B3DTuple& rOld2)
+ {
+ B3DTuple aAvg(
+ (rOld1.getX() + rOld2.getX()) * 0.5,
+ (rOld1.getY() + rOld2.getY()) * 0.5,
+ (rOld1.getZ() + rOld2.getZ()) * 0.5);
+ return aAvg;
+ }
+
+ inline B3DTuple average(const B3DTuple& rOld1, const B3DTuple& rOld2, const B3DTuple& rOld3)
+ {
+ B3DTuple aAvg(
+ (rOld1.getX() + rOld2.getX() + rOld3.getX()) * (1.0 / 3.0),
+ (rOld1.getY() + rOld2.getY() + rOld3.getY()) * (1.0 / 3.0),
+ (rOld1.getZ() + rOld2.getZ() + rOld3.getZ()) * (1.0 / 3.0));
+ return aAvg;
+ }
+
+ inline B3DTuple operator+(const B3DTuple& rTupA, const B3DTuple& rTupB)
+ {
+ B3DTuple aSum(rTupA);
+ aSum += rTupB;
+ return aSum;
+ }
+
+ inline B3DTuple operator-(const B3DTuple& rTupA, const B3DTuple& rTupB)
+ {
+ B3DTuple aSub(rTupA);
+ aSub -= rTupB;
+ return aSub;
+ }
+
+ inline B3DTuple operator/(const B3DTuple& rTupA, const B3DTuple& rTupB)
+ {
+ B3DTuple aDiv(rTupA);
+ aDiv /= rTupB;
+ return aDiv;
+ }
+
+ inline B3DTuple operator*(const B3DTuple& rTupA, const B3DTuple& rTupB)
+ {
+ B3DTuple aMul(rTupA);
+ aMul *= rTupB;
+ return aMul;
+ }
+
+ inline B3DTuple operator*(const B3DTuple& rTup, double t)
+ {
+ B3DTuple aNew(rTup);
+ aNew *= t;
+ return aNew;
+ }
+
+ inline B3DTuple operator*(double t, const B3DTuple& rTup)
+ {
+ B3DTuple aNew(rTup);
+ aNew *= t;
+ return aNew;
+ }
+
+ inline B3DTuple operator/(const B3DTuple& rTup, double t)
+ {
+ B3DTuple aNew(rTup);
+ aNew /= t;
+ return aNew;
+ }
+
+ inline B3DTuple operator/(double t, const B3DTuple& rTup)
+ {
+ B3DTuple aNew(rTup);
+ aNew /= t;
+ return aNew;
+ }
+
+ /** Round double to nearest integer for 3D tuple
+
+ @return the nearest integer for this tuple
+ */
+ BASEGFX_DLLPUBLIC B3ITuple fround(const B3DTuple& rTup);
+} // end of namespace basegfx
+
+#endif /* _BGFX_TUPLE_B3DTUPLE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/tuple/b3i64tuple.hxx b/include/basegfx/tuple/b3i64tuple.hxx
new file mode 100644
index 000000000000..bcc1acaee6b1
--- /dev/null
+++ b/include/basegfx/tuple/b3i64tuple.hxx
@@ -0,0 +1,336 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_TUPLE_B3I64TUPLE_HXX
+#define _BGFX_TUPLE_B3I64TUPLE_HXX
+
+#include <sal/types.h>
+#include <basegfx/tuple/b3dtuple.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+
+namespace basegfx
+{
+ /** Base class for all Points/Vectors with three sal_Int64 values
+
+ This class provides all methods common to Point
+ avd Vector classes which are derived from here.
+
+ @derive Use this class to implement Points or Vectors
+ which are based on three sal_Int64 values
+ */
+ class BASEGFX_DLLPUBLIC SAL_WARN_UNUSED B3I64Tuple
+ {
+ protected:
+ sal_Int64 mnX;
+ sal_Int64 mnY;
+ sal_Int64 mnZ;
+
+ public:
+ /** Create a 3D Tuple
+
+ The tuple is initialized to (0, 0, 0)
+ */
+ B3I64Tuple()
+ : mnX(0),
+ mnY(0),
+ mnZ(0)
+ {}
+
+ /** Create a 3D Tuple
+
+ @param nX
+ This parameter is used to initialize the X-coordinate
+ of the 3D Tuple.
+
+ @param nY
+ This parameter is used to initialize the Y-coordinate
+ of the 3D Tuple.
+
+ @param nZ
+ This parameter is used to initialize the Z-coordinate
+ of the 3D Tuple.
+ */
+ B3I64Tuple(sal_Int64 nX, sal_Int64 nY, sal_Int64 nZ)
+ : mnX(nX),
+ mnY(nY),
+ mnZ(nZ)
+ {}
+
+ /** Create a copy of a 3D Tuple
+
+ @param rTup
+ The 3D Tuple which will be copied.
+ */
+ B3I64Tuple(const B3I64Tuple& rTup)
+ : mnX( rTup.mnX ),
+ mnY( rTup.mnY ),
+ mnZ( rTup.mnZ )
+ {}
+
+ ~B3I64Tuple()
+ {}
+
+ /// get X-Coordinate of 3D Tuple
+ sal_Int64 getX() const
+ {
+ return mnX;
+ }
+
+ /// get Y-Coordinate of 3D Tuple
+ sal_Int64 getY() const
+ {
+ return mnY;
+ }
+
+ /// get Z-Coordinate of 3D Tuple
+ sal_Int64 getZ() const
+ {
+ return mnZ;
+ }
+
+ /// set X-Coordinate of 3D Tuple
+ void setX(sal_Int64 nX)
+ {
+ mnX = nX;
+ }
+
+ /// set Y-Coordinate of 3D Tuple
+ void setY(sal_Int64 nY)
+ {
+ mnY = nY;
+ }
+
+ /// set Z-Coordinate of 3D Tuple
+ void setZ(sal_Int64 nZ)
+ {
+ mnZ = nZ;
+ }
+
+ /// Array-access to 3D Tuple
+ const sal_Int64& operator[] (int nPos) const
+ {
+ // Here, normally two if(...)'s should be used. In the assumption that
+ // both sal_Int64 members can be accessed as an array a shortcut is used here.
+ // if(0 == nPos) return mnX; if(1 == nPos) return mnY; return mnZ;
+ return *((&mnX) + nPos);
+ }
+
+ /// Array-access to 3D Tuple
+ sal_Int64& operator[] (int nPos)
+ {
+ // Here, normally two if(...)'s should be used. In the assumption that
+ // both sal_Int64 members can be accessed as an array a shortcut is used here.
+ // if(0 == nPos) return mnX; if(1 == nPos) return mnY; return mnZ;
+ return *((&mnX) + nPos);
+ }
+
+ // operators
+ //////////////////////////////////////////////////////////////////////
+
+ B3I64Tuple& operator+=( const B3I64Tuple& rTup )
+ {
+ mnX += rTup.mnX;
+ mnY += rTup.mnY;
+ mnZ += rTup.mnZ;
+ return *this;
+ }
+
+ B3I64Tuple& operator-=( const B3I64Tuple& rTup )
+ {
+ mnX -= rTup.mnX;
+ mnY -= rTup.mnY;
+ mnZ -= rTup.mnZ;
+ return *this;
+ }
+
+ B3I64Tuple& operator/=( const B3I64Tuple& rTup )
+ {
+ mnX /= rTup.mnX;
+ mnY /= rTup.mnY;
+ mnZ /= rTup.mnZ;
+ return *this;
+ }
+
+ B3I64Tuple& operator*=( const B3I64Tuple& rTup )
+ {
+ mnX *= rTup.mnX;
+ mnY *= rTup.mnY;
+ mnZ *= rTup.mnZ;
+ return *this;
+ }
+
+ B3I64Tuple& operator*=(sal_Int64 t)
+ {
+ mnX *= t;
+ mnY *= t;
+ mnZ *= t;
+ return *this;
+ }
+
+ B3I64Tuple& operator/=(sal_Int64 t)
+ {
+ mnX /= t;
+ mnY /= t;
+ mnZ /= t;
+ return *this;
+ }
+
+ B3I64Tuple operator-(void) const
+ {
+ return B3I64Tuple(-mnX, -mnY, -mnZ);
+ }
+
+ bool operator==( const B3I64Tuple& rTup ) const
+ {
+ return this == &rTup || (rTup.mnX == mnX && rTup.mnY == mnY && rTup.mnZ == mnZ);
+ }
+
+ bool operator!=( const B3I64Tuple& rTup ) const
+ {
+ return !(*this == rTup);
+ }
+
+ B3I64Tuple& operator=( const B3I64Tuple& rTup )
+ {
+ mnX = rTup.mnX;
+ mnY = rTup.mnY;
+ mnZ = rTup.mnZ;
+ return *this;
+ }
+ };
+
+ // external operators
+ //////////////////////////////////////////////////////////////////////////
+
+ inline B3I64Tuple minimum(const B3I64Tuple& rTupA, const B3I64Tuple& rTupB)
+ {
+ B3I64Tuple aMin(
+ (rTupB.getX() < rTupA.getX()) ? rTupB.getX() : rTupA.getX(),
+ (rTupB.getY() < rTupA.getY()) ? rTupB.getY() : rTupA.getY(),
+ (rTupB.getZ() < rTupA.getZ()) ? rTupB.getZ() : rTupA.getZ());
+ return aMin;
+ }
+
+ inline B3I64Tuple maximum(const B3I64Tuple& rTupA, const B3I64Tuple& rTupB)
+ {
+ B3I64Tuple aMax(
+ (rTupB.getX() > rTupA.getX()) ? rTupB.getX() : rTupA.getX(),
+ (rTupB.getY() > rTupA.getY()) ? rTupB.getY() : rTupA.getY(),
+ (rTupB.getZ() > rTupA.getZ()) ? rTupB.getZ() : rTupA.getZ());
+ return aMax;
+ }
+
+ inline B3I64Tuple absolute(const B3I64Tuple& rTup)
+ {
+ B3I64Tuple aAbs(
+ (0 > rTup.getX()) ? -rTup.getX() : rTup.getX(),
+ (0 > rTup.getY()) ? -rTup.getY() : rTup.getY(),
+ (0 > rTup.getZ()) ? -rTup.getZ() : rTup.getZ());
+ return aAbs;
+ }
+
+ inline B3DTuple interpolate(const B3I64Tuple& rOld1, const B3I64Tuple& rOld2, double t)
+ {
+ B3DTuple aInt(
+ ((rOld2.getX() - rOld1.getX()) * t) + rOld1.getX(),
+ ((rOld2.getY() - rOld1.getY()) * t) + rOld1.getY(),
+ ((rOld2.getZ() - rOld1.getZ()) * t) + rOld1.getZ());
+ return aInt;
+ }
+
+ inline B3DTuple average(const B3I64Tuple& rOld1, const B3I64Tuple& rOld2)
+ {
+ B3DTuple aAvg(
+ (rOld1.getX() + rOld2.getX()) * 0.5,
+ (rOld1.getY() + rOld2.getY()) * 0.5,
+ (rOld1.getZ() + rOld2.getZ()) * 0.5);
+ return aAvg;
+ }
+
+ inline B3DTuple average(const B3I64Tuple& rOld1, const B3I64Tuple& rOld2, const B3I64Tuple& rOld3)
+ {
+ B3DTuple aAvg(
+ (rOld1.getX() + rOld2.getX() + rOld3.getX()) * (1.0 / 3.0),
+ (rOld1.getY() + rOld2.getY() + rOld3.getY()) * (1.0 / 3.0),
+ (rOld1.getZ() + rOld2.getZ() + rOld3.getZ()) * (1.0 / 3.0));
+ return aAvg;
+ }
+
+ inline B3I64Tuple operator+(const B3I64Tuple& rTupA, const B3I64Tuple& rTupB)
+ {
+ B3I64Tuple aSum(rTupA);
+ aSum += rTupB;
+ return aSum;
+ }
+
+ inline B3I64Tuple operator-(const B3I64Tuple& rTupA, const B3I64Tuple& rTupB)
+ {
+ B3I64Tuple aSub(rTupA);
+ aSub -= rTupB;
+ return aSub;
+ }
+
+ inline B3I64Tuple operator/(const B3I64Tuple& rTupA, const B3I64Tuple& rTupB)
+ {
+ B3I64Tuple aDiv(rTupA);
+ aDiv /= rTupB;
+ return aDiv;
+ }
+
+ inline B3I64Tuple operator*(const B3I64Tuple& rTupA, const B3I64Tuple& rTupB)
+ {
+ B3I64Tuple aMul(rTupA);
+ aMul *= rTupB;
+ return aMul;
+ }
+
+ inline B3I64Tuple operator*(const B3I64Tuple& rTup, sal_Int64 t)
+ {
+ B3I64Tuple aNew(rTup);
+ aNew *= t;
+ return aNew;
+ }
+
+ inline B3I64Tuple operator*(sal_Int64 t, const B3I64Tuple& rTup)
+ {
+ B3I64Tuple aNew(rTup);
+ aNew *= t;
+ return aNew;
+ }
+
+ inline B3I64Tuple operator/(const B3I64Tuple& rTup, sal_Int64 t)
+ {
+ B3I64Tuple aNew(rTup);
+ aNew /= t;
+ return aNew;
+ }
+
+ inline B3I64Tuple operator/(sal_Int64 t, const B3I64Tuple& rTup)
+ {
+ B3I64Tuple aNew(t, t, t);
+ B3I64Tuple aTmp(rTup);
+ aNew /= aTmp;
+ return aNew;
+ }
+} // end of namespace basegfx
+
+#endif /* _BGFX_TUPLE_B3I64TUPLE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/tuple/b3ituple.hxx b/include/basegfx/tuple/b3ituple.hxx
new file mode 100644
index 000000000000..49fb24634ed4
--- /dev/null
+++ b/include/basegfx/tuple/b3ituple.hxx
@@ -0,0 +1,335 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_TUPLE_B3ITUPLE_HXX
+#define _BGFX_TUPLE_B3ITUPLE_HXX
+
+#include <sal/types.h>
+#include <basegfx/tuple/b3dtuple.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ /** Base class for all Points/Vectors with three sal_Int32 values
+
+ This class provides all methods common to Point
+ avd Vector classes which are derived from here.
+
+ @derive Use this class to implement Points or Vectors
+ which are based on three sal_Int32 values
+ */
+ class BASEGFX_DLLPUBLIC SAL_WARN_UNUSED B3ITuple
+ {
+ protected:
+ sal_Int32 mnX;
+ sal_Int32 mnY;
+ sal_Int32 mnZ;
+
+ public:
+ /** Create a 3D Tuple
+
+ The tuple is initialized to (0, 0, 0)
+ */
+ B3ITuple()
+ : mnX(0),
+ mnY(0),
+ mnZ(0)
+ {}
+
+ /** Create a 3D Tuple
+
+ @param nX
+ This parameter is used to initialize the X-coordinate
+ of the 3D Tuple.
+
+ @param nY
+ This parameter is used to initialize the Y-coordinate
+ of the 3D Tuple.
+
+ @param nZ
+ This parameter is used to initialize the Z-coordinate
+ of the 3D Tuple.
+ */
+ B3ITuple(sal_Int32 nX, sal_Int32 nY, sal_Int32 nZ)
+ : mnX(nX),
+ mnY(nY),
+ mnZ(nZ)
+ {}
+
+ /** Create a copy of a 3D Tuple
+
+ @param rTup
+ The 3D Tuple which will be copied.
+ */
+ B3ITuple(const B3ITuple& rTup)
+ : mnX( rTup.mnX ),
+ mnY( rTup.mnY ),
+ mnZ( rTup.mnZ )
+ {}
+
+ ~B3ITuple()
+ {}
+
+ /// get X-Coordinate of 3D Tuple
+ sal_Int32 getX() const
+ {
+ return mnX;
+ }
+
+ /// get Y-Coordinate of 3D Tuple
+ sal_Int32 getY() const
+ {
+ return mnY;
+ }
+
+ /// get Z-Coordinate of 3D Tuple
+ sal_Int32 getZ() const
+ {
+ return mnZ;
+ }
+
+ /// set X-Coordinate of 3D Tuple
+ void setX(sal_Int32 nX)
+ {
+ mnX = nX;
+ }
+
+ /// set Y-Coordinate of 3D Tuple
+ void setY(sal_Int32 nY)
+ {
+ mnY = nY;
+ }
+
+ /// set Z-Coordinate of 3D Tuple
+ void setZ(sal_Int32 nZ)
+ {
+ mnZ = nZ;
+ }
+
+ /// Array-access to 3D Tuple
+ const sal_Int32& operator[] (int nPos) const
+ {
+ // Here, normally two if(...)'s should be used. In the assumption that
+ // both sal_Int32 members can be accessed as an array a shortcut is used here.
+ // if(0 == nPos) return mnX; if(1 == nPos) return mnY; return mnZ;
+ return *((&mnX) + nPos);
+ }
+
+ /// Array-access to 3D Tuple
+ sal_Int32& operator[] (int nPos)
+ {
+ // Here, normally two if(...)'s should be used. In the assumption that
+ // both sal_Int32 members can be accessed as an array a shortcut is used here.
+ // if(0 == nPos) return mnX; if(1 == nPos) return mnY; return mnZ;
+ return *((&mnX) + nPos);
+ }
+
+ // operators
+ //////////////////////////////////////////////////////////////////////
+
+ B3ITuple& operator+=( const B3ITuple& rTup )
+ {
+ mnX += rTup.mnX;
+ mnY += rTup.mnY;
+ mnZ += rTup.mnZ;
+ return *this;
+ }
+
+ B3ITuple& operator-=( const B3ITuple& rTup )
+ {
+ mnX -= rTup.mnX;
+ mnY -= rTup.mnY;
+ mnZ -= rTup.mnZ;
+ return *this;
+ }
+
+ B3ITuple& operator/=( const B3ITuple& rTup )
+ {
+ mnX /= rTup.mnX;
+ mnY /= rTup.mnY;
+ mnZ /= rTup.mnZ;
+ return *this;
+ }
+
+ B3ITuple& operator*=( const B3ITuple& rTup )
+ {
+ mnX *= rTup.mnX;
+ mnY *= rTup.mnY;
+ mnZ *= rTup.mnZ;
+ return *this;
+ }
+
+ B3ITuple& operator*=(sal_Int32 t)
+ {
+ mnX *= t;
+ mnY *= t;
+ mnZ *= t;
+ return *this;
+ }
+
+ B3ITuple& operator/=(sal_Int32 t)
+ {
+ mnX /= t;
+ mnY /= t;
+ mnZ /= t;
+ return *this;
+ }
+
+ B3ITuple operator-(void) const
+ {
+ return B3ITuple(-mnX, -mnY, -mnZ);
+ }
+
+ bool operator==( const B3ITuple& rTup ) const
+ {
+ return this == &rTup || (rTup.mnX == mnX && rTup.mnY == mnY && rTup.mnZ == mnZ);
+ }
+
+ bool operator!=( const B3ITuple& rTup ) const
+ {
+ return !(*this == rTup);
+ }
+
+ B3ITuple& operator=( const B3ITuple& rTup )
+ {
+ mnX = rTup.mnX;
+ mnY = rTup.mnY;
+ mnZ = rTup.mnZ;
+ return *this;
+ }
+ };
+
+ // external operators
+ //////////////////////////////////////////////////////////////////////////
+
+ inline B3ITuple minimum(const B3ITuple& rTupA, const B3ITuple& rTupB)
+ {
+ B3ITuple aMin(
+ (rTupB.getX() < rTupA.getX()) ? rTupB.getX() : rTupA.getX(),
+ (rTupB.getY() < rTupA.getY()) ? rTupB.getY() : rTupA.getY(),
+ (rTupB.getZ() < rTupA.getZ()) ? rTupB.getZ() : rTupA.getZ());
+ return aMin;
+ }
+
+ inline B3ITuple maximum(const B3ITuple& rTupA, const B3ITuple& rTupB)
+ {
+ B3ITuple aMax(
+ (rTupB.getX() > rTupA.getX()) ? rTupB.getX() : rTupA.getX(),
+ (rTupB.getY() > rTupA.getY()) ? rTupB.getY() : rTupA.getY(),
+ (rTupB.getZ() > rTupA.getZ()) ? rTupB.getZ() : rTupA.getZ());
+ return aMax;
+ }
+
+ inline B3ITuple absolute(const B3ITuple& rTup)
+ {
+ B3ITuple aAbs(
+ (0 > rTup.getX()) ? -rTup.getX() : rTup.getX(),
+ (0 > rTup.getY()) ? -rTup.getY() : rTup.getY(),
+ (0 > rTup.getZ()) ? -rTup.getZ() : rTup.getZ());
+ return aAbs;
+ }
+
+ inline B3DTuple interpolate(const B3ITuple& rOld1, const B3ITuple& rOld2, double t)
+ {
+ B3DTuple aInt(
+ ((rOld2.getX() - rOld1.getX()) * t) + rOld1.getX(),
+ ((rOld2.getY() - rOld1.getY()) * t) + rOld1.getY(),
+ ((rOld2.getZ() - rOld1.getZ()) * t) + rOld1.getZ());
+ return aInt;
+ }
+
+ inline B3DTuple average(const B3ITuple& rOld1, const B3ITuple& rOld2)
+ {
+ B3DTuple aAvg(
+ (rOld1.getX() + rOld2.getX()) * 0.5,
+ (rOld1.getY() + rOld2.getY()) * 0.5,
+ (rOld1.getZ() + rOld2.getZ()) * 0.5);
+ return aAvg;
+ }
+
+ inline B3DTuple average(const B3ITuple& rOld1, const B3ITuple& rOld2, const B3ITuple& rOld3)
+ {
+ B3DTuple aAvg(
+ (rOld1.getX() + rOld2.getX() + rOld3.getX()) * (1.0 / 3.0),
+ (rOld1.getY() + rOld2.getY() + rOld3.getY()) * (1.0 / 3.0),
+ (rOld1.getZ() + rOld2.getZ() + rOld3.getZ()) * (1.0 / 3.0));
+ return aAvg;
+ }
+
+ inline B3ITuple operator+(const B3ITuple& rTupA, const B3ITuple& rTupB)
+ {
+ B3ITuple aSum(rTupA);
+ aSum += rTupB;
+ return aSum;
+ }
+
+ inline B3ITuple operator-(const B3ITuple& rTupA, const B3ITuple& rTupB)
+ {
+ B3ITuple aSub(rTupA);
+ aSub -= rTupB;
+ return aSub;
+ }
+
+ inline B3ITuple operator/(const B3ITuple& rTupA, const B3ITuple& rTupB)
+ {
+ B3ITuple aDiv(rTupA);
+ aDiv /= rTupB;
+ return aDiv;
+ }
+
+ inline B3ITuple operator*(const B3ITuple& rTupA, const B3ITuple& rTupB)
+ {
+ B3ITuple aMul(rTupA);
+ aMul *= rTupB;
+ return aMul;
+ }
+
+ inline B3ITuple operator*(const B3ITuple& rTup, sal_Int32 t)
+ {
+ B3ITuple aNew(rTup);
+ aNew *= t;
+ return aNew;
+ }
+
+ inline B3ITuple operator*(sal_Int32 t, const B3ITuple& rTup)
+ {
+ B3ITuple aNew(rTup);
+ aNew *= t;
+ return aNew;
+ }
+
+ inline B3ITuple operator/(const B3ITuple& rTup, sal_Int32 t)
+ {
+ B3ITuple aNew(rTup);
+ aNew /= t;
+ return aNew;
+ }
+
+ inline B3ITuple operator/(sal_Int32 t, const B3ITuple& rTup)
+ {
+ B3ITuple aNew(t, t, t);
+ B3ITuple aTmp(rTup);
+ aNew /= aTmp;
+ return aNew;
+ }
+} // end of namespace basegfx
+
+#endif /* _BGFX_TUPLE_B3ITUPLE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/vector/b2dsize.hxx b/include/basegfx/vector/b2dsize.hxx
new file mode 100644
index 000000000000..bde343b46685
--- /dev/null
+++ b/include/basegfx/vector/b2dsize.hxx
@@ -0,0 +1,36 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_VECTOR_B2DSIZE_HXX
+#define _BGFX_VECTOR_B2DSIZE_HXX
+
+#include <basegfx/vector/b2dvector.hxx>
+
+namespace basegfx
+{
+ // syntactic sugar: a B2DVector exactly models a Size object,
+ // thus, for interface clarity, we provide an alias name
+
+ /// Alias name for interface clarity (not everybody is aware of the identity)
+ typedef B2DVector B2DSize;
+}
+
+#endif /* _BGFX_VECTOR_B2DSIZE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/vector/b2dvector.hxx b/include/basegfx/vector/b2dvector.hxx
new file mode 100644
index 000000000000..99489eb7169c
--- /dev/null
+++ b/include/basegfx/vector/b2dvector.hxx
@@ -0,0 +1,254 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_VECTOR_B2DVECTOR_HXX
+#define _BGFX_VECTOR_B2DVECTOR_HXX
+
+#include <basegfx/tuple/b2dtuple.hxx>
+#include <basegfx/vector/b2ivector.hxx>
+#include <basegfx/vector/b2enums.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ // predeclaration
+ class B2DHomMatrix;
+
+ /** Base Point class with two double values
+
+ This class derives all operators and common handling for
+ a 2D data class from B2DTuple. All necessary extensions
+ which are special for 2D Vectors are added here.
+
+ @see B2DTuple
+ */
+ class BASEGFX_DLLPUBLIC B2DVector : public ::basegfx::B2DTuple
+ {
+ public:
+ /** Create a 2D Vector
+
+ The vector is initialized to (0.0, 0.0)
+ */
+ B2DVector()
+ : B2DTuple()
+ {}
+
+ /** Create a 2D Vector
+
+ @param fX
+ This parameter is used to initialize the X-coordinate
+ of the 2D Vector.
+
+ @param fY
+ This parameter is used to initialize the Y-coordinate
+ of the 2D Vector.
+ */
+ B2DVector(double fX, double fY)
+ : B2DTuple(fX, fY)
+ {}
+
+ /** Create a copy of a 2D Vector
+
+ @param rVec
+ The 2D Vector which will be copied.
+ */
+ B2DVector(const B2DVector& rVec)
+ : B2DTuple(rVec)
+ {}
+
+ /** Create a copy of a 2D Vector
+
+ @param rVec
+ The 2D Vector which will be copied.
+ */
+ explicit B2DVector(const ::basegfx::B2IVector& rVec)
+ : B2DTuple(rVec)
+ {}
+
+ /** constructor with tuple to allow copy-constructing
+ from B2DTuple-based classes
+ */
+ B2DVector(const ::basegfx::B2DTuple& rTuple)
+ : B2DTuple(rTuple)
+ {}
+
+ ~B2DVector()
+ {}
+
+ /** *=operator to allow usage from B2DVector, too
+ */
+ B2DVector& operator*=( const B2DVector& rPnt )
+ {
+ mfX *= rPnt.mfX;
+ mfY *= rPnt.mfY;
+ return *this;
+ }
+
+ /** *=operator to allow usage from B2DVector, too
+ */
+ B2DVector& operator*=(double t)
+ {
+ mfX *= t;
+ mfY *= t;
+ return *this;
+ }
+
+ /** assignment operator to allow assigning the results
+ of B2DTuple calculations
+ */
+ B2DVector& operator=( const ::basegfx::B2DTuple& rVec );
+
+ /** Calculate the length of this 2D Vector
+
+ @return The Length of the 2D Vector
+ */
+ double getLength() const;
+
+ /** Set the length of this 2D Vector
+
+ @param fLen
+ The to be achieved length of the 2D Vector
+ */
+ B2DVector& setLength(double fLen);
+
+ /** Normalize this 2D Vector
+
+ The length of the 2D Vector is set to 1.0
+ */
+ B2DVector& normalize();
+
+ /** Calculate the Scalar with another 2D Vector
+
+ @param rVec
+ The second 2D Vector
+
+ @return
+ The Scalar value of the two involved 2D Vectors
+ */
+ double scalar( const B2DVector& rVec ) const;
+
+ /** Calculate the length of the cross product with another 2D Vector
+
+ In 2D, returning an actual vector does not make much
+ sense here. The magnitude, although, can be readily
+ used for tasks such as angle calculations, since for
+ the returned value, the following equation holds:
+ retVal = getLength(this)*getLength(rVec)*sin(theta),
+ with theta being the angle between the two vectors.
+
+ @param rVec
+ The second 2D Vector
+
+ @return
+ The length of the cross product of the two involved 2D Vectors
+ */
+ double cross( const B2DVector& rVec ) const;
+
+ /** Calculate the Angle with another 2D Vector
+
+ @param rVec
+ The second 2D Vector
+
+ @return
+ The Angle value of the two involved 2D Vectors in -pi/2 < return < pi/2
+ */
+ double angle( const B2DVector& rVec ) const;
+
+ /** Transform vector by given transformation matrix.
+
+ Since this is a vector, translational components of the
+ matrix are disregarded.
+ */
+ B2DVector& operator*=( const B2DHomMatrix& rMat );
+
+ static const B2DVector& getEmptyVector();
+ };
+
+ // external operators
+ //////////////////////////////////////////////////////////////////////////
+
+ /** Calculate the orientation to another 2D Vector
+
+ @param rVecA
+ The first 2D Vector
+
+ @param rVecB
+ The second 2D Vector
+
+ @return
+ The mathematical Orientation of the two involved 2D Vectors
+ */
+ BASEGFX_DLLPUBLIC B2VectorOrientation getOrientation( const B2DVector& rVecA, const B2DVector& rVecB );
+
+ /** Calculate a perpendicular 2D Vector to the given one
+
+ @param rVec
+ The source 2D Vector
+
+ @attention This only works if the given 2D Vector is normalized.
+
+ @return
+ A 2D Vector perpendicular to the one given in parameter rVec
+ */
+ BASEGFX_DLLPUBLIC B2DVector getPerpendicular( const B2DVector& rNormalizedVec );
+
+ /** Calculate a perpendicular 2D Vector to the given one,
+ normalize the given one as preparation
+
+ @param rVec
+ The source 2D Vector
+
+ @return
+ A normalized 2D Vector perpendicular to the one given in parameter rVec
+ */
+ BASEGFX_DLLPUBLIC B2DVector getNormalizedPerpendicular( const B2DVector& rVec );
+
+ /** Test two vectors which need not to be normalized for parallelism
+
+ @param rVecA
+ The first 2D Vector
+
+ @param rVecB
+ The second 2D Vector
+
+ @return
+ bool if the two values are parallel. Also true if
+ one of the vectors is empty.
+ */
+ BASEGFX_DLLPUBLIC bool areParallel( const B2DVector& rVecA, const B2DVector& rVecB );
+
+ /** Transform vector by given transformation matrix.
+
+ Since this is a vector, translational components of the
+ matrix are disregarded.
+ */
+ BASEGFX_DLLPUBLIC B2DVector operator*( const B2DHomMatrix& rMat, const B2DVector& rVec );
+
+ /** Test continuity between given vectors.
+
+ The two given vectors are assumed to describe control points on a
+ common point. Calculate if there is a continuity between them.
+ */
+ BASEGFX_DLLPUBLIC B2VectorContinuity getContinuity( const B2DVector& rBackVector, const B2DVector& rForwardVector );
+
+} // end of namespace basegfx
+
+#endif /* _BGFX_VECTOR_B2DVECTOR_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/vector/b2enums.hxx b/include/basegfx/vector/b2enums.hxx
new file mode 100644
index 000000000000..abbf4cfaf546
--- /dev/null
+++ b/include/basegfx/vector/b2enums.hxx
@@ -0,0 +1,70 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_VECTOR_B2ENUMS_HXX
+#define _BGFX_VECTOR_B2ENUMS_HXX
+
+#include <sal/types.h>
+
+namespace basegfx
+{
+ /** Descriptor for the mathematical orientations of two 2D Vectors
+ */
+ enum B2VectorOrientation
+ {
+ /// mathematically positive oriented
+ ORIENTATION_POSITIVE = 0,
+
+ /// mathematically negative oriented
+ ORIENTATION_NEGATIVE,
+
+ /// mathematically neutral, thus parallel
+ ORIENTATION_NEUTRAL
+ };
+
+ /** Descriptor for the mathematical continuity of two 2D Vectors
+ */
+ enum B2VectorContinuity
+ {
+ /// none
+ CONTINUITY_NONE = 0,
+
+ /// mathematically negative oriented
+ CONTINUITY_C1,
+
+ /// mathematically neutral, thus parallel
+ CONTINUITY_C2
+ };
+
+ /** Descriptor for possible line joins between two line segments
+ */
+ enum B2DLineJoin
+ {
+ B2DLINEJOIN_NONE, // no rounding
+ B2DLINEJOIN_MIDDLE, // calc middle value between joints
+ B2DLINEJOIN_BEVEL, // join edges with line
+ B2DLINEJOIN_MITER, // extend till cut
+ B2DLINEJOIN_ROUND // create arc
+ };
+
+} // end of namespace basegfx
+
+#endif /* _BGFX_VECTOR_B2ENUMS_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/vector/b2isize.hxx b/include/basegfx/vector/b2isize.hxx
new file mode 100644
index 000000000000..4a2fe2228661
--- /dev/null
+++ b/include/basegfx/vector/b2isize.hxx
@@ -0,0 +1,36 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_VECTOR_B2ISIZE_HXX
+#define _BGFX_VECTOR_B2ISIZE_HXX
+
+#include <basegfx/vector/b2ivector.hxx>
+
+namespace basegfx
+{
+ // syntactic sugar: a B2IVector exactly models a Size object,
+ // thus, for interface clarity, we provide an alias name
+
+ /// Alias name for interface clarity (not everybody is aware of the identity)
+ typedef B2IVector B2ISize;
+}
+
+#endif /* _BGFX_VECTOR_B2ISIZE_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/vector/b2ivector.hxx b/include/basegfx/vector/b2ivector.hxx
new file mode 100644
index 000000000000..63ce2ae28fba
--- /dev/null
+++ b/include/basegfx/vector/b2ivector.hxx
@@ -0,0 +1,146 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_VECTOR_B2IVECTOR_HXX
+#define _BGFX_VECTOR_B2IVECTOR_HXX
+
+#include <basegfx/tuple/b2ituple.hxx>
+#include <basegfx/vector/b2enums.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ // predeclaration
+ class B2DHomMatrix;
+
+ /** Base Point class with two sal_Int32 values
+
+ This class derives all operators and common handling for
+ a 2D data class from B2ITuple. All necessary extensions
+ which are special for 2D Vectors are added here.
+
+ @see B2ITuple
+ */
+ class BASEGFX_DLLPUBLIC B2IVector : public ::basegfx::B2ITuple
+ {
+ public:
+ /** Create a 2D Vector
+
+ The vector is initialized to (0, 0)
+ */
+ B2IVector()
+ : B2ITuple()
+ {}
+
+ /** Create a 2D Vector
+
+ @param nX
+ This parameter is used to initialize the X-coordinate
+ of the 2D Vector.
+
+ @param nY
+ This parameter is used to initialize the Y-coordinate
+ of the 2D Vector.
+ */
+ B2IVector(sal_Int32 nX, sal_Int32 nY)
+ : B2ITuple(nX, nY)
+ {}
+
+ /** Create a copy of a 2D Vector
+
+ @param rVec
+ The 2D Vector which will be copied.
+ */
+ B2IVector(const B2IVector& rVec)
+ : B2ITuple(rVec)
+ {}
+
+ /** constructor with tuple to allow copy-constructing
+ from B2ITuple-based classes
+ */
+ B2IVector(const ::basegfx::B2ITuple& rTuple)
+ : B2ITuple(rTuple)
+ {}
+
+ ~B2IVector()
+ {}
+
+ /** *=operator to allow usage from B2IVector, too
+ */
+ B2IVector& operator*=( const B2IVector& rPnt )
+ {
+ mnX *= rPnt.mnX;
+ mnY *= rPnt.mnY;
+ return *this;
+ }
+
+ /** *=operator to allow usage from B2IVector, too
+ */
+ B2IVector& operator*=(sal_Int32 t)
+ {
+ mnX *= t;
+ mnY *= t;
+ return *this;
+ }
+
+ /** assignment operator to allow assigning the results
+ of B2ITuple calculations
+ */
+ B2IVector& operator=( const ::basegfx::B2ITuple& rVec );
+
+ /** Set the length of this 2D Vector
+
+ @param fLen
+ The to be achieved length of the 2D Vector
+ */
+ B2IVector& setLength(double fLen);
+
+ /** Calculate the Scalar with another 2D Vector
+
+ @param rVec
+ The second 2D Vector
+
+ @return
+ The Scalar value of the two involved 2D Vectors
+ */
+ double scalar( const B2IVector& rVec ) const;
+
+ /** Transform vector by given transformation matrix.
+
+ Since this is a vector, translational components of the
+ matrix are disregarded.
+ */
+ B2IVector& operator*=( const B2DHomMatrix& rMat );
+ };
+
+ // external operators
+ //////////////////////////////////////////////////////////////////////////
+
+ /** Transform vector by given transformation matrix.
+
+ Since this is a vector, translational components of the
+ matrix are disregarded.
+ */
+ BASEGFX_DLLPUBLIC B2IVector operator*( const B2DHomMatrix& rMat, const B2IVector& rVec );
+
+} // end of namespace basegfx
+
+#endif /* _BGFX_VECTOR_B2IVECTOR_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/vector/b3dvector.hxx b/include/basegfx/vector/b3dvector.hxx
new file mode 100644
index 000000000000..99f23bc7b6d3
--- /dev/null
+++ b/include/basegfx/vector/b3dvector.hxx
@@ -0,0 +1,322 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_VECTOR_B3DVECTOR_HXX
+#define _BGFX_VECTOR_B3DVECTOR_HXX
+
+#include <basegfx/tuple/b3dtuple.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace basegfx
+{
+ // predeclaration
+ class B3DHomMatrix;
+
+ /** Base Point class with three double values
+
+ This class derives all operators and common handling for
+ a 3D data class from B3DTuple. All necessary extensions
+ which are special for 3D Vectors are added here.
+
+ @see B3DTuple
+ */
+ class BASEGFX_DLLPUBLIC B3DVector : public ::basegfx::B3DTuple
+ {
+ public:
+ /** Create a 3D Vector
+
+ The vector is initialized to (0.0, 0.0, 0.0)
+ */
+ B3DVector()
+ : B3DTuple()
+ {}
+
+ /** Create a 3D Vector
+
+ @param fX
+ This parameter is used to initialize the X-coordinate
+ of the 3D Vector.
+
+ @param fY
+ This parameter is used to initialize the Y-coordinate
+ of the 3D Vector.
+
+ @param fZ
+ This parameter is used to initialize the Z-coordinate
+ of the 3D Vector.
+ */
+ B3DVector(double fX, double fY, double fZ)
+ : B3DTuple(fX, fY, fZ)
+ {}
+
+ /** Create a copy of a 3D Vector
+
+ @param rVec
+ The 3D Vector which will be copied.
+ */
+ B3DVector(const B3DVector& rVec)
+ : B3DTuple(rVec)
+ {}
+
+ /** constructor with tuple to allow copy-constructing
+ from B3DTuple-based classes
+ */
+ B3DVector(const ::basegfx::B3DTuple& rTuple)
+ : B3DTuple(rTuple)
+ {}
+
+ ~B3DVector()
+ {}
+
+ /** *=operator to allow usage from B3DVector, too
+ */
+ B3DVector& operator*=( const B3DVector& rPnt )
+ {
+ mfX *= rPnt.mfX;
+ mfY *= rPnt.mfY;
+ mfZ *= rPnt.mfZ;
+ return *this;
+ }
+
+ /** *=operator to allow usage from B3DVector, too
+ */
+ B3DVector& operator*=(double t)
+ {
+ mfX *= t;
+ mfY *= t;
+ mfZ *= t;
+ return *this;
+ }
+
+ /** assignment operator to allow assigning the results
+ of B3DTuple calculations
+ */
+ B3DVector& operator=( const ::basegfx::B3DTuple& rVec )
+ {
+ mfX = rVec.getX();
+ mfY = rVec.getY();
+ mfZ = rVec.getZ();
+ return *this;
+ }
+
+ /** Calculate the length of this 3D Vector
+
+ @return The Length of the 3D Vector
+ */
+ double getLength(void) const
+ {
+ double fLen(scalar(*this));
+ if((0.0 == fLen) || (1.0 == fLen))
+ return fLen;
+ return sqrt(fLen);
+ }
+
+ /** Calculate the length in the XY-Plane for this 3D Vector
+
+ @return The XY-Plane Length of the 3D Vector
+ */
+ double getXYLength(void) const
+ {
+ double fLen((mfX * mfX) + (mfY * mfY));
+ if((0.0 == fLen) || (1.0 == fLen))
+ return fLen;
+ return sqrt(fLen);
+ }
+
+ /** Calculate the length in the XZ-Plane for this 3D Vector
+
+ @return The XZ-Plane Length of the 3D Vector
+ */
+ double getXZLength(void) const
+ {
+ double fLen((mfX * mfX) + (mfZ * mfZ)); // #i73040#
+ if((0.0 == fLen) || (1.0 == fLen))
+ return fLen;
+ return sqrt(fLen);
+ }
+
+ /** Calculate the length in the YZ-Plane for this 3D Vector
+
+ @return The YZ-Plane Length of the 3D Vector
+ */
+ double getYZLength(void) const
+ {
+ double fLen((mfY * mfY) + (mfZ * mfZ));
+ if((0.0 == fLen) || (1.0 == fLen))
+ return fLen;
+ return sqrt(fLen);
+ }
+
+ /** Set the length of this 3D Vector
+
+ @param fLen
+ The to be achieved length of the 3D Vector
+ */
+ B3DVector& setLength(double fLen)
+ {
+ double fLenNow(scalar(*this));
+
+ if(!::basegfx::fTools::equalZero(fLenNow))
+ {
+ const double fOne(1.0);
+
+ if(!::basegfx::fTools::equal(fOne, fLenNow))
+ {
+ fLen /= sqrt(fLenNow);
+ }
+
+ mfX *= fLen;
+ mfY *= fLen;
+ mfZ *= fLen;
+ }
+
+ return *this;
+ }
+
+ /** Normalize this 3D Vector
+
+ The length of the 3D Vector is set to 1.0
+ */
+ B3DVector& normalize();
+
+ /** Test if this 3D Vector is normalized
+
+ @return
+ true if lenth of vector is equal to 1.0
+ false else
+ */
+ bool isNormalized() const
+ {
+ const double fOne(1.0);
+ const double fScalar(scalar(*this));
+
+ return (::basegfx::fTools::equal(fOne, fScalar));
+ }
+
+ /** get a 3D Vector which is perpendicular to this and a given 3D Vector
+
+ @attention This only works if this and the given 3D Vector are
+ both normalized.
+
+ @param rNormalizedVec
+ A normalized 3D Vector.
+
+ @return
+ A 3D Vector perpendicular to this and the given one
+ */
+ B3DVector getPerpendicular(const B3DVector& rNormalizedVec) const;
+
+ /** Calculate the Scalar product
+
+ This method calculates the Scalar product between this
+ and the given 3D Vector.
+
+ @param rVec
+ A second 3D Vector.
+
+ @return
+ The Scalar Product of two 3D Vectors
+ */
+ double scalar(const B3DVector& rVec) const
+ {
+ return ((mfX * rVec.mfX) + (mfY * rVec.mfY) + (mfZ * rVec.mfZ));
+ }
+
+ /** Transform vector by given transformation matrix.
+
+ Since this is a vector, translational components of the
+ matrix are disregarded.
+ */
+ B3DVector& operator*=( const B3DHomMatrix& rMat );
+
+ static const B3DVector& getEmptyVector()
+ {
+ return (const B3DVector&) ::basegfx::B3DTuple::getEmptyTuple();
+ }
+ };
+
+ // external operators
+ //////////////////////////////////////////////////////////////////////////
+
+ /** get a 3D Vector which is in 2D (ignoring
+ the Z-Coordinate) perpendicular to a given 3D Vector
+
+ @attention This only works if the given 3D Vector is normalized.
+
+ @param rNormalizedVec
+ A normalized 3D Vector.
+
+ @return
+ A 3D Vector perpendicular to the given one in X,Y (2D).
+ */
+ inline B3DVector getPerpendicular2D( const B3DVector& rNormalizedVec )
+ {
+ B3DVector aPerpendicular(-rNormalizedVec.getY(), rNormalizedVec.getX(), rNormalizedVec.getZ());
+ return aPerpendicular;
+ }
+
+ /** Test two vectors which need not to be normalized for parallelism
+
+ @param rVecA
+ The first 3D Vector
+
+ @param rVecB
+ The second 3D Vector
+
+ @return
+ bool if the two values are parallel. Also true if
+ one of the vectors is empty.
+ */
+ BASEGFX_DLLPUBLIC bool areParallel( const B3DVector& rVecA, const B3DVector& rVecB );
+
+ /** Transform vector by given transformation matrix.
+
+ Since this is a vector, translational components of the
+ matrix are disregarded.
+ */
+ BASEGFX_DLLPUBLIC B3DVector operator*( const B3DHomMatrix& rMat, const B3DVector& rVec );
+
+ /** Calculate the Cross Product of two 3D Vectors
+
+ @param rVecA
+ A first 3D Vector.
+
+ @param rVecB
+ A second 3D Vector.
+
+ @return
+ The Cross Product of both 3D Vectors
+ */
+ inline B3DVector cross(const B3DVector& rVecA, const B3DVector& rVecB)
+ {
+ B3DVector aVec(
+ rVecA.getY() * rVecB.getZ() - rVecA.getZ() * rVecB.getY(),
+ rVecA.getZ() * rVecB.getX() - rVecA.getX() * rVecB.getZ(),
+ rVecA.getX() * rVecB.getY() - rVecA.getY() * rVecB.getX());
+ return aVec;
+ }
+} // end of namespace basegfx
+
+//////////////////////////////////////////////////////////////////////////////
+
+#endif /* _BGFX_VECTOR_B3DVECTOR_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/vector/b3ivector.hxx b/include/basegfx/vector/b3ivector.hxx
new file mode 100644
index 000000000000..8248ade15cb0
--- /dev/null
+++ b/include/basegfx/vector/b3ivector.hxx
@@ -0,0 +1,249 @@
+/* -*- 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 .
+ */
+
+#ifndef _BGFX_VECTOR_B3IVECTOR_HXX
+#define _BGFX_VECTOR_B3IVECTOR_HXX
+
+#include <basegfx/tuple/b3ituple.hxx>
+#include <basegfx/basegfxdllapi.h>
+
+namespace basegfx
+{
+ // predeclaration
+ class B3DHomMatrix;
+
+ /** Base Point class with three sal_Int32 values
+
+ This class derives all operators and common handling for
+ a 3D data class from B3ITuple. All necessary extensions
+ which are special for 3D Vectors are added here.
+
+ @see B3ITuple
+ */
+ class BASEGFX_DLLPUBLIC B3IVector : public ::basegfx::B3ITuple
+ {
+ public:
+ /** Create a 3D Vector
+
+ The vector is initialized to (0, 0, 0)
+ */
+ B3IVector()
+ : B3ITuple()
+ {}
+
+ /** Create a 3D Vector
+
+ @param nX
+ This parameter is used to initialize the X-coordinate
+ of the 3D Vector.
+
+ @param nY
+ This parameter is used to initialize the Y-coordinate
+ of the 3D Vector.
+
+ @param nZ
+ This parameter is used to initialize the Z-coordinate
+ of the 3D Vector.
+ */
+ B3IVector(sal_Int32 nX, sal_Int32 nY, sal_Int32 nZ)
+ : B3ITuple(nX, nY, nZ)
+ {}
+
+ /** Create a copy of a 3D Vector
+
+ @param rVec
+ The 3D Vector which will be copied.
+ */
+ B3IVector(const B3IVector& rVec)
+ : B3ITuple(rVec)
+ {}
+
+ /** constructor with tuple to allow copy-constructing
+ from B3ITuple-based classes
+ */
+ B3IVector(const ::basegfx::B3ITuple& rTuple)
+ : B3ITuple(rTuple)
+ {}
+
+ ~B3IVector()
+ {}
+
+ /** *=operator to allow usage from B3IVector, too
+ */
+ B3IVector& operator*=( const B3IVector& rPnt )
+ {
+ mnX *= rPnt.mnX;
+ mnY *= rPnt.mnY;
+ mnZ *= rPnt.mnZ;
+ return *this;
+ }
+
+ /** *=operator to allow usage from B3IVector, too
+ */
+ B3IVector& operator*=(sal_Int32 t)
+ {
+ mnX *= t;
+ mnY *= t;
+ mnZ *= t;
+ return *this;
+ }
+
+ /** assignment operator to allow assigning the results
+ of B3ITuple calculations
+ */
+ B3IVector& operator=( const ::basegfx::B3ITuple& rVec )
+ {
+ mnX = rVec.getX();
+ mnY = rVec.getY();
+ mnZ = rVec.getZ();
+ return *this;
+ }
+
+ /** Calculate the length of this 3D Vector
+
+ @return The Length of the 3D Vector
+ */
+ double getLength(void) const
+ {
+ double fLen(scalar(*this));
+ if((0 == fLen) || (1.0 == fLen))
+ return fLen;
+ return sqrt(fLen);
+ }
+
+ /** Calculate the length in the XY-Plane for this 3D Vector
+
+ @return The XY-Plane Length of the 3D Vector
+ */
+ double getXYLength(void) const
+ {
+ double fLen((mnX * mnX) + (mnY * mnY));
+ if((0 == fLen) || (1.0 == fLen))
+ return fLen;
+ return sqrt(fLen);
+ }
+
+ /** Calculate the length in the XZ-Plane for this 3D Vector
+
+ @return The XZ-Plane Length of the 3D Vector
+ */
+ double getXZLength(void) const
+ {
+ double fLen((mnX * mnZ) + (mnY * mnZ));
+ if((0 == fLen) || (1.0 == fLen))
+ return fLen;
+ return sqrt(fLen);
+ }
+
+ /** Calculate the length in the YZ-Plane for this 3D Vector
+
+ @return The YZ-Plane Length of the 3D Vector
+ */
+ double getYZLength(void) const
+ {
+ double fLen((mnY * mnY) + (mnZ * mnZ));
+ if((0 == fLen) || (1.0 == fLen))
+ return fLen;
+ return sqrt(fLen);
+ }
+
+ /** Set the length of this 3D Vector
+
+ @param fLen
+ The to be achieved length of the 3D Vector
+ */
+ B3IVector& setLength(double fLen)
+ {
+ double fLenNow(scalar(*this));
+
+ if(!::basegfx::fTools::equalZero(fLenNow))
+ {
+ const double fOne(1.0);
+
+ if(!::basegfx::fTools::equal(fOne, fLenNow))
+ {
+ fLen /= sqrt(fLenNow);
+ }
+
+ mnX = fround(mnX*fLen);
+ mnY = fround(mnY*fLen);
+ mnZ = fround(mnZ*fLen);
+ }
+
+ return *this;
+ }
+
+ /** Calculate the Scalar product
+
+ This method calculates the Scalar product between this
+ and the given 3D Vector.
+
+ @param rVec
+ A second 3D Vector.
+
+ @return
+ The Scalar Product of two 3D Vectors
+ */
+ double scalar(const B3IVector& rVec) const
+ {
+ return ((mnX * rVec.mnX) + (mnY * rVec.mnY) + (mnZ * rVec.mnZ));
+ }
+
+ /** Transform vector by given transformation matrix.
+
+ Since this is a vector, translational components of the
+ matrix are disregarded.
+ */
+ B3IVector& operator*=( const B3DHomMatrix& rMat );
+ };
+
+ // external operators
+ //////////////////////////////////////////////////////////////////////////
+
+ /** Transform vector by given transformation matrix.
+
+ Since this is a vector, translational components of the
+ matrix are disregarded.
+ */
+ BASEGFX_DLLPUBLIC B3IVector operator*( const B3DHomMatrix& rMat, const B3IVector& rVec );
+
+ /** Calculate the Cross Product of two 3D Vectors
+
+ @param rVecA
+ A first 3D Vector.
+
+ @param rVecB
+ A second 3D Vector.
+
+ @return
+ The Cross Product of both 3D Vectors
+ */
+ inline B3IVector cross(const B3IVector& rVecA, const B3IVector& rVecB)
+ {
+ B3IVector aVec(
+ rVecA.getY() * rVecB.getZ() - rVecA.getZ() * rVecB.getY(),
+ rVecA.getZ() * rVecB.getX() - rVecA.getX() * rVecB.getZ(),
+ rVecA.getX() * rVecB.getY() - rVecA.getY() * rVecB.getX());
+ return aVec;
+ }
+} // end of namespace basegfx
+
+#endif /* _BGFX_VECTOR_B3DVECTOR_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */