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