1ce9c7ef7SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3ce9c7ef7SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4ce9c7ef7SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5ce9c7ef7SAndrew Rist  * distributed with this work for additional information
6ce9c7ef7SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7ce9c7ef7SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8ce9c7ef7SAndrew Rist  * "License"); you may not use this file except in compliance
9ce9c7ef7SAndrew Rist  * with the License.  You may obtain a copy of the License at
10ce9c7ef7SAndrew Rist  *
11ce9c7ef7SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12ce9c7ef7SAndrew Rist  *
13ce9c7ef7SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14ce9c7ef7SAndrew Rist  * software distributed under the License is distributed on an
15ce9c7ef7SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16ce9c7ef7SAndrew Rist  * KIND, either express or implied.  See the License for the
17ce9c7ef7SAndrew Rist  * specific language governing permissions and limitations
18ce9c7ef7SAndrew Rist  * under the License.
19ce9c7ef7SAndrew Rist  *
20ce9c7ef7SAndrew Rist  *************************************************************/
21ce9c7ef7SAndrew Rist 
22ce9c7ef7SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #ifndef _BGFX_TUPLE_B2ITUPLE_HXX
25cdf0e10cSrcweir #define _BGFX_TUPLE_B2ITUPLE_HXX
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <sal/types.h>
28*7024eca9SArmin Le Grand #include <basegfx/numeric/ftools.hxx>
29*7024eca9SArmin Le Grand #undef min
30*7024eca9SArmin Le Grand #undef max
31*7024eca9SArmin Le Grand #include <algorithm>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir namespace basegfx
34cdf0e10cSrcweir {
35cdf0e10cSrcweir 	/** Base class for all Points/Vectors with two sal_Int32 values
36cdf0e10cSrcweir 
37cdf0e10cSrcweir 		This class provides all methods common to Point
38cdf0e10cSrcweir 		avd Vector classes which are derived from here.
39cdf0e10cSrcweir 
40cdf0e10cSrcweir 		@derive Use this class to implement Points or Vectors
41cdf0e10cSrcweir 		which are based on two sal_Int32 values
42cdf0e10cSrcweir 	*/
43cdf0e10cSrcweir 	class B2ITuple
44cdf0e10cSrcweir 	{
45cdf0e10cSrcweir 	protected:
46cdf0e10cSrcweir 		sal_Int32										mnX;
47cdf0e10cSrcweir 		sal_Int32										mnY;
48cdf0e10cSrcweir 
49cdf0e10cSrcweir 	public:
50cdf0e10cSrcweir 		/**	Create a 2D Tuple
51cdf0e10cSrcweir 
52cdf0e10cSrcweir         	The tuple is initialized to (0, 0)
53cdf0e10cSrcweir 		*/
B2ITuple()54cdf0e10cSrcweir 		B2ITuple()
55cdf0e10cSrcweir 		:	mnX(0),
56cdf0e10cSrcweir 			mnY(0)
57cdf0e10cSrcweir 		{}
58cdf0e10cSrcweir 
59cdf0e10cSrcweir 		/**	Create a 2D Tuple
60cdf0e10cSrcweir 
61cdf0e10cSrcweir 			@param fX
62cdf0e10cSrcweir 			This parameter is used to initialize the X-coordinate
63cdf0e10cSrcweir 			of the 2D Tuple.
64cdf0e10cSrcweir 
65cdf0e10cSrcweir 			@param fY
66cdf0e10cSrcweir 			This parameter is used to initialize the Y-coordinate
67cdf0e10cSrcweir 			of the 2D Tuple.
68cdf0e10cSrcweir 		*/
B2ITuple(sal_Int32 fX,sal_Int32 fY)69cdf0e10cSrcweir 		B2ITuple(sal_Int32 fX, sal_Int32 fY)
70cdf0e10cSrcweir 		:	mnX( fX ),
71cdf0e10cSrcweir 			mnY( fY )
72cdf0e10cSrcweir 		{}
73cdf0e10cSrcweir 
74cdf0e10cSrcweir 		/**	Create a copy of a 2D Tuple
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 			@param rTup
77cdf0e10cSrcweir 			The 2D Tuple which will be copied.
78cdf0e10cSrcweir 		*/
B2ITuple(const B2ITuple & rTup)79cdf0e10cSrcweir 		B2ITuple(const B2ITuple& rTup)
80cdf0e10cSrcweir 		:	mnX( rTup.mnX ),
81cdf0e10cSrcweir 			mnY( rTup.mnY )
82cdf0e10cSrcweir 		{}
83cdf0e10cSrcweir 
~B2ITuple()84cdf0e10cSrcweir 		~B2ITuple()
85cdf0e10cSrcweir 		{}
86cdf0e10cSrcweir 
87cdf0e10cSrcweir 		/// Get X-Coordinate of 2D Tuple
getX() const88cdf0e10cSrcweir 		sal_Int32 getX() const
89cdf0e10cSrcweir 		{
90cdf0e10cSrcweir 			return mnX;
91cdf0e10cSrcweir 		}
92cdf0e10cSrcweir 
93cdf0e10cSrcweir 		/// Get Y-Coordinate of 2D Tuple
getY() const94cdf0e10cSrcweir 		sal_Int32 getY() const
95cdf0e10cSrcweir 		{
96cdf0e10cSrcweir 			return mnY;
97cdf0e10cSrcweir 		}
98cdf0e10cSrcweir 
99cdf0e10cSrcweir 		/// Set X-Coordinate of 2D Tuple
setX(sal_Int32 fX)100cdf0e10cSrcweir 		void setX(sal_Int32 fX)
101cdf0e10cSrcweir 		{
102cdf0e10cSrcweir 			mnX = fX;
103cdf0e10cSrcweir 		}
104cdf0e10cSrcweir 
105cdf0e10cSrcweir 		/// Set Y-Coordinate of 2D Tuple
setY(sal_Int32 fY)106cdf0e10cSrcweir 		void setY(sal_Int32 fY)
107cdf0e10cSrcweir 		{
108cdf0e10cSrcweir 			mnY = fY;
109cdf0e10cSrcweir 		}
110cdf0e10cSrcweir 
111cdf0e10cSrcweir 		/// Array-access to 2D Tuple
operator [](int nPos) const112cdf0e10cSrcweir 		const sal_Int32& operator[] (int nPos) const
113cdf0e10cSrcweir 		{
114cdf0e10cSrcweir 			// Here, normally one if(...) should be used. In the assumption that
115cdf0e10cSrcweir 			// both sal_Int32 members can be accessed as an array a shortcut is used here.
116cdf0e10cSrcweir 			// if(0 == nPos) return mnX; return mnY;
117cdf0e10cSrcweir 			return *((&mnX) + nPos);
118cdf0e10cSrcweir 		}
119cdf0e10cSrcweir 
120cdf0e10cSrcweir 		/// Array-access to 2D Tuple
operator [](int nPos)121cdf0e10cSrcweir 		sal_Int32& operator[] (int nPos)
122cdf0e10cSrcweir 		{
123cdf0e10cSrcweir 			// Here, normally one if(...) should be used. In the assumption that
124cdf0e10cSrcweir 			// both sal_Int32 members can be accessed as an array a shortcut is used here.
125cdf0e10cSrcweir 			// if(0 == nPos) return mnX; return mnY;
126cdf0e10cSrcweir 			return *((&mnX) + nPos);
127cdf0e10cSrcweir 		}
128cdf0e10cSrcweir 
129cdf0e10cSrcweir 		// operators
130cdf0e10cSrcweir 		//////////////////////////////////////////////////////////////////////
131cdf0e10cSrcweir 
operator +=(const B2ITuple & rTup)132cdf0e10cSrcweir 		B2ITuple& operator+=( const B2ITuple& rTup )
133cdf0e10cSrcweir 		{
134cdf0e10cSrcweir 			mnX += rTup.mnX;
135cdf0e10cSrcweir 			mnY += rTup.mnY;
136cdf0e10cSrcweir 			return *this;
137cdf0e10cSrcweir 		}
138cdf0e10cSrcweir 
operator -=(const B2ITuple & rTup)139cdf0e10cSrcweir 		B2ITuple& operator-=( const B2ITuple& rTup )
140cdf0e10cSrcweir 		{
141cdf0e10cSrcweir 			mnX -= rTup.mnX;
142cdf0e10cSrcweir 			mnY -= rTup.mnY;
143cdf0e10cSrcweir 			return *this;
144cdf0e10cSrcweir 		}
145cdf0e10cSrcweir 
operator /=(const B2ITuple & rTup)146cdf0e10cSrcweir 		B2ITuple& operator/=( const B2ITuple& rTup )
147cdf0e10cSrcweir 		{
148cdf0e10cSrcweir 			mnX /= rTup.mnX;
149cdf0e10cSrcweir 			mnY /= rTup.mnY;
150cdf0e10cSrcweir 			return *this;
151cdf0e10cSrcweir 		}
152cdf0e10cSrcweir 
operator *=(const B2ITuple & rTup)153cdf0e10cSrcweir 		B2ITuple& operator*=( const B2ITuple& rTup )
154cdf0e10cSrcweir 		{
155cdf0e10cSrcweir 			mnX *= rTup.mnX;
156cdf0e10cSrcweir 			mnY *= rTup.mnY;
157cdf0e10cSrcweir 			return *this;
158cdf0e10cSrcweir 		}
159cdf0e10cSrcweir 
operator *=(sal_Int32 t)160cdf0e10cSrcweir 		B2ITuple& operator*=(sal_Int32 t)
161cdf0e10cSrcweir 		{
162cdf0e10cSrcweir 			mnX *= t;
163cdf0e10cSrcweir 			mnY *= t;
164cdf0e10cSrcweir 			return *this;
165cdf0e10cSrcweir 		}
166cdf0e10cSrcweir 
operator /=(sal_Int32 t)167cdf0e10cSrcweir 		B2ITuple& operator/=(sal_Int32 t)
168cdf0e10cSrcweir 		{
169cdf0e10cSrcweir 			mnX /= t;
170cdf0e10cSrcweir 			mnY /= t;
171cdf0e10cSrcweir 			return *this;
172cdf0e10cSrcweir 		}
173cdf0e10cSrcweir 
operator -(void) const174cdf0e10cSrcweir 		B2ITuple operator-(void) const
175cdf0e10cSrcweir 		{
176cdf0e10cSrcweir 			return B2ITuple(-mnX, -mnY);
177cdf0e10cSrcweir 		}
178cdf0e10cSrcweir 
equalZero() const179*7024eca9SArmin Le Grand 		bool equalZero() const
180*7024eca9SArmin Le Grand         {
181*7024eca9SArmin Le Grand             return mnX == 0 && mnY == 0;
182*7024eca9SArmin Le Grand         }
183cdf0e10cSrcweir 
operator ==(const B2ITuple & rTup) const184cdf0e10cSrcweir 		bool operator==( const B2ITuple& rTup ) const
185cdf0e10cSrcweir 		{
186cdf0e10cSrcweir 			return this == &rTup || (rTup.mnX == mnX && rTup.mnY == mnY);
187cdf0e10cSrcweir 		}
188cdf0e10cSrcweir 
operator !=(const B2ITuple & rTup) const189cdf0e10cSrcweir 		bool operator!=( const B2ITuple& rTup ) const
190cdf0e10cSrcweir 		{
191cdf0e10cSrcweir 			return !(*this == rTup);
192cdf0e10cSrcweir 		}
193cdf0e10cSrcweir 
operator =(const B2ITuple & rTup)194cdf0e10cSrcweir 		B2ITuple& operator=( const B2ITuple& rTup )
195cdf0e10cSrcweir 		{
196cdf0e10cSrcweir 			mnX = rTup.mnX;
197cdf0e10cSrcweir 			mnY = rTup.mnY;
198cdf0e10cSrcweir 			return *this;
199cdf0e10cSrcweir 		}
200cdf0e10cSrcweir 
201cdf0e10cSrcweir 		static const B2ITuple& getEmptyTuple();
202cdf0e10cSrcweir 	};
203cdf0e10cSrcweir 
204cdf0e10cSrcweir 	// external operators
205cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////
206cdf0e10cSrcweir 
minimum(const B2ITuple & rTupA,const B2ITuple & rTupB)207*7024eca9SArmin Le Grand 	inline B2ITuple minimum(const B2ITuple& rTupA, const B2ITuple& rTupB)
208*7024eca9SArmin Le Grand 	{
209*7024eca9SArmin Le Grand         return B2ITuple(
210*7024eca9SArmin Le Grand             std::min(rTupB.getX(), rTupA.getX()),
211*7024eca9SArmin Le Grand             std::min(rTupB.getY(), rTupA.getY()));
212*7024eca9SArmin Le Grand 	}
213*7024eca9SArmin Le Grand 
maximum(const B2ITuple & rTupA,const B2ITuple & rTupB)214*7024eca9SArmin Le Grand 	inline B2ITuple maximum(const B2ITuple& rTupA, const B2ITuple& rTupB)
215*7024eca9SArmin Le Grand 	{
216*7024eca9SArmin Le Grand         return B2ITuple(
217*7024eca9SArmin Le Grand             std::max(rTupB.getX(), rTupA.getX()),
218*7024eca9SArmin Le Grand             std::max(rTupB.getY(), rTupA.getY()));
219*7024eca9SArmin Le Grand 	}
220*7024eca9SArmin Le Grand 
absolute(const B2ITuple & rTup)221*7024eca9SArmin Le Grand 	inline B2ITuple absolute(const B2ITuple& rTup)
222*7024eca9SArmin Le Grand 	{
223*7024eca9SArmin Le Grand 		B2ITuple aAbs(
224*7024eca9SArmin Le Grand 			(0 > rTup.getX()) ? -rTup.getX() : rTup.getX(),
225*7024eca9SArmin Le Grand 			(0 > rTup.getY()) ? -rTup.getY() : rTup.getY());
226*7024eca9SArmin Le Grand 		return aAbs;
227*7024eca9SArmin Le Grand 	}
228*7024eca9SArmin Le Grand 
interpolate(const B2ITuple & rOld1,const B2ITuple & rOld2,double t)229*7024eca9SArmin Le Grand 	inline B2ITuple interpolate(const B2ITuple& rOld1, const B2ITuple& rOld2, double t)
230*7024eca9SArmin Le Grand 	{
231*7024eca9SArmin Le Grand         if(rOld1 == rOld2)
232*7024eca9SArmin Le Grand         {
233*7024eca9SArmin Le Grand             return rOld1;
234*7024eca9SArmin Le Grand         }
235*7024eca9SArmin Le Grand         else if(0.0 >= t)
236*7024eca9SArmin Le Grand         {
237*7024eca9SArmin Le Grand             return rOld1;
238*7024eca9SArmin Le Grand         }
239*7024eca9SArmin Le Grand         else if(1.0 <= t)
240*7024eca9SArmin Le Grand         {
241*7024eca9SArmin Le Grand             return rOld2;
242*7024eca9SArmin Le Grand         }
243*7024eca9SArmin Le Grand         else
244*7024eca9SArmin Le Grand         {
245*7024eca9SArmin Le Grand 		    return B2ITuple(
246*7024eca9SArmin Le Grand 			    basegfx::fround(((rOld2.getX() - rOld1.getX()) * t) + rOld1.getX()),
247*7024eca9SArmin Le Grand 			    basegfx::fround(((rOld2.getY() - rOld1.getY()) * t) + rOld1.getY()));
248*7024eca9SArmin Le Grand         }
249*7024eca9SArmin Le Grand 	}
250*7024eca9SArmin Le Grand 
average(const B2ITuple & rOld1,const B2ITuple & rOld2)251*7024eca9SArmin Le Grand 	inline B2ITuple average(const B2ITuple& rOld1, const B2ITuple& rOld2)
252*7024eca9SArmin Le Grand 	{
253*7024eca9SArmin Le Grand         return B2ITuple(
254*7024eca9SArmin Le Grand             rOld1.getX() == rOld2.getX() ? rOld1.getX() : basegfx::fround((rOld1.getX() + rOld2.getX()) * 0.5),
255*7024eca9SArmin Le Grand             rOld1.getY() == rOld2.getY() ? rOld1.getY() : basegfx::fround((rOld1.getY() + rOld2.getY()) * 0.5));
256*7024eca9SArmin Le Grand 	}
257cdf0e10cSrcweir 
average(const B2ITuple & rOld1,const B2ITuple & rOld2,const B2ITuple & rOld3)258*7024eca9SArmin Le Grand 	inline B2ITuple average(const B2ITuple& rOld1, const B2ITuple& rOld2, const B2ITuple& rOld3)
259*7024eca9SArmin Le Grand 	{
260*7024eca9SArmin Le Grand         return B2ITuple(
261*7024eca9SArmin Le Grand             (rOld1.getX() == rOld2.getX() && rOld2.getX() == rOld3.getX()) ? rOld1.getX() : basegfx::fround((rOld1.getX() + rOld2.getX() + rOld3.getX()) * (1.0 / 3.0)),
262*7024eca9SArmin Le Grand             (rOld1.getY() == rOld2.getY() && rOld2.getY() == rOld3.getY()) ? rOld1.getY() : basegfx::fround((rOld1.getY() + rOld2.getY() + rOld3.getY()) * (1.0 / 3.0)));
263*7024eca9SArmin Le Grand 	}
264*7024eca9SArmin Le Grand 
operator +(const B2ITuple & rTupA,const B2ITuple & rTupB)265*7024eca9SArmin Le Grand 	inline B2ITuple operator+(const B2ITuple& rTupA, const B2ITuple& rTupB)
266*7024eca9SArmin Le Grand 	{
267*7024eca9SArmin Le Grand 		B2ITuple aSum(rTupA);
268*7024eca9SArmin Le Grand 		aSum += rTupB;
269*7024eca9SArmin Le Grand 		return aSum;
270*7024eca9SArmin Le Grand 	}
271*7024eca9SArmin Le Grand 
operator -(const B2ITuple & rTupA,const B2ITuple & rTupB)272*7024eca9SArmin Le Grand 	inline B2ITuple operator-(const B2ITuple& rTupA, const B2ITuple& rTupB)
273*7024eca9SArmin Le Grand 	{
274*7024eca9SArmin Le Grand 		B2ITuple aSub(rTupA);
275*7024eca9SArmin Le Grand 		aSub -= rTupB;
276*7024eca9SArmin Le Grand 		return aSub;
277*7024eca9SArmin Le Grand 	}
278*7024eca9SArmin Le Grand 
operator /(const B2ITuple & rTupA,const B2ITuple & rTupB)279*7024eca9SArmin Le Grand 	inline B2ITuple operator/(const B2ITuple& rTupA, const B2ITuple& rTupB)
280*7024eca9SArmin Le Grand 	{
281*7024eca9SArmin Le Grand 		B2ITuple aDiv(rTupA);
282*7024eca9SArmin Le Grand 		aDiv /= rTupB;
283*7024eca9SArmin Le Grand 		return aDiv;
284*7024eca9SArmin Le Grand 	}
285*7024eca9SArmin Le Grand 
operator *(const B2ITuple & rTupA,const B2ITuple & rTupB)286*7024eca9SArmin Le Grand 	inline B2ITuple operator*(const B2ITuple& rTupA, const B2ITuple& rTupB)
287*7024eca9SArmin Le Grand 	{
288*7024eca9SArmin Le Grand 		B2ITuple aMul(rTupA);
289*7024eca9SArmin Le Grand 		aMul *= rTupB;
290*7024eca9SArmin Le Grand 		return aMul;
291*7024eca9SArmin Le Grand 	}
292*7024eca9SArmin Le Grand 
operator *(const B2ITuple & rTup,sal_Int32 t)293*7024eca9SArmin Le Grand 	inline B2ITuple operator*(const B2ITuple& rTup, sal_Int32 t)
294*7024eca9SArmin Le Grand 	{
295*7024eca9SArmin Le Grand 		B2ITuple aNew(rTup);
296*7024eca9SArmin Le Grand 		aNew *= t;
297*7024eca9SArmin Le Grand 		return aNew;
298*7024eca9SArmin Le Grand 	}
299*7024eca9SArmin Le Grand 
operator *(sal_Int32 t,const B2ITuple & rTup)300*7024eca9SArmin Le Grand 	inline B2ITuple operator*(sal_Int32 t, const B2ITuple& rTup)
301*7024eca9SArmin Le Grand 	{
302*7024eca9SArmin Le Grand 		B2ITuple aNew(rTup);
303*7024eca9SArmin Le Grand 		aNew *= t;
304*7024eca9SArmin Le Grand 		return aNew;
305*7024eca9SArmin Le Grand 	}
306*7024eca9SArmin Le Grand 
operator /(const B2ITuple & rTup,sal_Int32 t)307*7024eca9SArmin Le Grand 	inline B2ITuple operator/(const B2ITuple& rTup, sal_Int32 t)
308*7024eca9SArmin Le Grand 	{
309*7024eca9SArmin Le Grand 		B2ITuple aNew(rTup);
310*7024eca9SArmin Le Grand 		aNew /= t;
311*7024eca9SArmin Le Grand 		return aNew;
312*7024eca9SArmin Le Grand 	}
313*7024eca9SArmin Le Grand 
operator /(sal_Int32 t,const B2ITuple & rTup)314*7024eca9SArmin Le Grand 	inline B2ITuple operator/(sal_Int32 t, const B2ITuple& rTup)
315*7024eca9SArmin Le Grand 	{
316*7024eca9SArmin Le Grand 		B2ITuple aNew(t, t);
317*7024eca9SArmin Le Grand 		B2ITuple aTmp(rTup);
318*7024eca9SArmin Le Grand 		aNew /= aTmp;
319*7024eca9SArmin Le Grand 		return aNew;
320*7024eca9SArmin Le Grand 	}
321cdf0e10cSrcweir } // end of namespace basegfx
322cdf0e10cSrcweir 
323cdf0e10cSrcweir #endif /* _BGFX_TUPLE_B2ITUPLE_HXX */
324