xref: /AOO41X/main/basegfx/inc/basegfx/range/basicrange.hxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #ifndef _BGFX_RANGE_BASICRANGE_HXX
29*cdf0e10cSrcweir #define _BGFX_RANGE_BASICRANGE_HXX
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <sal/types.h>
32*cdf0e10cSrcweir #include <float.h>
33*cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx>
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir namespace basegfx
37*cdf0e10cSrcweir {
38*cdf0e10cSrcweir 	template< typename T, typename Traits > class BasicRange
39*cdf0e10cSrcweir 	{
40*cdf0e10cSrcweir 	protected:
41*cdf0e10cSrcweir 		T		mnMinimum;
42*cdf0e10cSrcweir 		T		mnMaximum;
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir 	public:
45*cdf0e10cSrcweir         typedef T 		ValueType;
46*cdf0e10cSrcweir         typedef Traits	TraitsType;
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir         BasicRange() :
49*cdf0e10cSrcweir             mnMinimum(Traits::maxVal()),
50*cdf0e10cSrcweir 			mnMaximum(Traits::minVal())
51*cdf0e10cSrcweir 		{
52*cdf0e10cSrcweir 		}
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir         BasicRange( T nValue ) :
55*cdf0e10cSrcweir             mnMinimum(nValue),
56*cdf0e10cSrcweir 			mnMaximum(nValue)
57*cdf0e10cSrcweir 		{
58*cdf0e10cSrcweir 		}
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir 		BasicRange(const BasicRange& rRange) :
61*cdf0e10cSrcweir             mnMinimum(rRange.mnMinimum),
62*cdf0e10cSrcweir 			mnMaximum(rRange.mnMaximum)
63*cdf0e10cSrcweir 		{
64*cdf0e10cSrcweir 		}
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir 		void reset()
67*cdf0e10cSrcweir 		{
68*cdf0e10cSrcweir 			mnMinimum = Traits::maxVal();
69*cdf0e10cSrcweir 			mnMaximum = Traits::minVal();
70*cdf0e10cSrcweir 		}
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir 		bool isEmpty() const
73*cdf0e10cSrcweir 		{
74*cdf0e10cSrcweir 			return Traits::maxVal() == mnMinimum;
75*cdf0e10cSrcweir 		}
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir         T getMinimum() const { return mnMinimum; }
78*cdf0e10cSrcweir         T getMaximum() const { return mnMaximum; }
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir 		double getCenter() const
81*cdf0e10cSrcweir 		{
82*cdf0e10cSrcweir 			if(isEmpty())
83*cdf0e10cSrcweir 			{
84*cdf0e10cSrcweir 				return 0.0;
85*cdf0e10cSrcweir 			}
86*cdf0e10cSrcweir 			else
87*cdf0e10cSrcweir 			{
88*cdf0e10cSrcweir 				return ((mnMaximum + mnMinimum) / 2.0);
89*cdf0e10cSrcweir 			}
90*cdf0e10cSrcweir 		}
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir 		bool isInside(T nValue) const
93*cdf0e10cSrcweir 		{
94*cdf0e10cSrcweir 			if(isEmpty())
95*cdf0e10cSrcweir 			{
96*cdf0e10cSrcweir 				return false;
97*cdf0e10cSrcweir 			}
98*cdf0e10cSrcweir 			else
99*cdf0e10cSrcweir 			{
100*cdf0e10cSrcweir 				return (nValue >= mnMinimum) && (nValue <= mnMaximum);
101*cdf0e10cSrcweir 			}
102*cdf0e10cSrcweir 		}
103*cdf0e10cSrcweir 
104*cdf0e10cSrcweir 		bool isInside(const BasicRange& rRange) const
105*cdf0e10cSrcweir 		{
106*cdf0e10cSrcweir 			if(isEmpty())
107*cdf0e10cSrcweir 			{
108*cdf0e10cSrcweir 				return false;
109*cdf0e10cSrcweir 			}
110*cdf0e10cSrcweir 			else
111*cdf0e10cSrcweir 			{
112*cdf0e10cSrcweir 				if(rRange.isEmpty())
113*cdf0e10cSrcweir 				{
114*cdf0e10cSrcweir 					return false;
115*cdf0e10cSrcweir 				}
116*cdf0e10cSrcweir 				else
117*cdf0e10cSrcweir 				{
118*cdf0e10cSrcweir 					return (rRange.mnMinimum >= mnMinimum) && (rRange.mnMaximum <= mnMaximum);
119*cdf0e10cSrcweir 				}
120*cdf0e10cSrcweir 			}
121*cdf0e10cSrcweir 		}
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir 		bool overlaps(const BasicRange& rRange) const
124*cdf0e10cSrcweir 		{
125*cdf0e10cSrcweir 			if(isEmpty())
126*cdf0e10cSrcweir 			{
127*cdf0e10cSrcweir 				return false;
128*cdf0e10cSrcweir 			}
129*cdf0e10cSrcweir 			else
130*cdf0e10cSrcweir 			{
131*cdf0e10cSrcweir 				if(rRange.isEmpty())
132*cdf0e10cSrcweir 				{
133*cdf0e10cSrcweir 					return false;
134*cdf0e10cSrcweir 				}
135*cdf0e10cSrcweir 				else
136*cdf0e10cSrcweir 				{
137*cdf0e10cSrcweir 					return !((rRange.mnMaximum < mnMinimum) || (rRange.mnMinimum > mnMaximum));
138*cdf0e10cSrcweir 				}
139*cdf0e10cSrcweir 			}
140*cdf0e10cSrcweir 		}
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir 		bool overlapsMore(const BasicRange& rRange) const
143*cdf0e10cSrcweir 		{
144*cdf0e10cSrcweir 			if(isEmpty() || rRange.isEmpty())
145*cdf0e10cSrcweir 				return false;
146*cdf0e10cSrcweir 			// returns true if the overlap is more than just a touching at the limits
147*cdf0e10cSrcweir 			return ((rRange.mnMaximum > mnMinimum) && (rRange.mnMinimum < mnMaximum));
148*cdf0e10cSrcweir 		}
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir 		bool operator==( const BasicRange& rRange ) const
151*cdf0e10cSrcweir 		{
152*cdf0e10cSrcweir 			return (mnMinimum == rRange.mnMinimum && mnMaximum == rRange.mnMaximum);
153*cdf0e10cSrcweir 		}
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir 		bool operator!=( const BasicRange& rRange ) const
156*cdf0e10cSrcweir 		{
157*cdf0e10cSrcweir 			return (mnMinimum != rRange.mnMinimum || mnMaximum != rRange.mnMaximum);
158*cdf0e10cSrcweir 		}
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir 		BasicRange& operator=(const BasicRange& rRange)
161*cdf0e10cSrcweir 		{
162*cdf0e10cSrcweir 			mnMinimum = rRange.mnMinimum;
163*cdf0e10cSrcweir 			mnMaximum = rRange.mnMaximum;
164*cdf0e10cSrcweir 			return *this;
165*cdf0e10cSrcweir 		}
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir 		bool equal(const BasicRange& rRange) const
168*cdf0e10cSrcweir         {
169*cdf0e10cSrcweir             return (
170*cdf0e10cSrcweir                 fTools::equal(mnMinimum, rRange.mnMinimum) &&
171*cdf0e10cSrcweir                 fTools::equal(mnMaximum, rRange.mnMaximum));
172*cdf0e10cSrcweir         }
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir 		void expand(T nValue)
175*cdf0e10cSrcweir 		{
176*cdf0e10cSrcweir 			if(isEmpty())
177*cdf0e10cSrcweir 			{
178*cdf0e10cSrcweir 				mnMinimum = mnMaximum = nValue;
179*cdf0e10cSrcweir 			}
180*cdf0e10cSrcweir 			else
181*cdf0e10cSrcweir 			{
182*cdf0e10cSrcweir 				if(nValue < mnMinimum)
183*cdf0e10cSrcweir 				{
184*cdf0e10cSrcweir 					mnMinimum = nValue;
185*cdf0e10cSrcweir 				}
186*cdf0e10cSrcweir 
187*cdf0e10cSrcweir 				if(nValue > mnMaximum)
188*cdf0e10cSrcweir 				{
189*cdf0e10cSrcweir 					mnMaximum = nValue;
190*cdf0e10cSrcweir 				}
191*cdf0e10cSrcweir 			}
192*cdf0e10cSrcweir 		}
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir 		void expand(const BasicRange& rRange)
195*cdf0e10cSrcweir 		{
196*cdf0e10cSrcweir 			if(isEmpty())
197*cdf0e10cSrcweir 			{
198*cdf0e10cSrcweir 				mnMinimum = rRange.mnMinimum;
199*cdf0e10cSrcweir 				mnMaximum = rRange.mnMaximum;
200*cdf0e10cSrcweir 			}
201*cdf0e10cSrcweir 			else
202*cdf0e10cSrcweir 			{
203*cdf0e10cSrcweir 				if(!rRange.isEmpty())
204*cdf0e10cSrcweir 				{
205*cdf0e10cSrcweir 					if(rRange.mnMinimum < mnMinimum)
206*cdf0e10cSrcweir 					{
207*cdf0e10cSrcweir 						mnMinimum = rRange.mnMinimum;
208*cdf0e10cSrcweir 					}
209*cdf0e10cSrcweir 
210*cdf0e10cSrcweir 					if(rRange.mnMaximum > mnMaximum)
211*cdf0e10cSrcweir 					{
212*cdf0e10cSrcweir 						mnMaximum = rRange.mnMaximum;
213*cdf0e10cSrcweir 					}
214*cdf0e10cSrcweir 				}
215*cdf0e10cSrcweir 			}
216*cdf0e10cSrcweir 		}
217*cdf0e10cSrcweir 
218*cdf0e10cSrcweir         void intersect(const BasicRange& rRange)
219*cdf0e10cSrcweir         {
220*cdf0e10cSrcweir 			// here, overlaps also tests all isEmpty() conditions already.
221*cdf0e10cSrcweir             if( !overlaps( rRange ) )
222*cdf0e10cSrcweir             {
223*cdf0e10cSrcweir                 reset();
224*cdf0e10cSrcweir             }
225*cdf0e10cSrcweir             else
226*cdf0e10cSrcweir             {
227*cdf0e10cSrcweir 				if(rRange.mnMinimum > mnMinimum)
228*cdf0e10cSrcweir 				{
229*cdf0e10cSrcweir 					mnMinimum = rRange.mnMinimum;
230*cdf0e10cSrcweir 				}
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir 				if(rRange.mnMaximum < mnMaximum)
233*cdf0e10cSrcweir 				{
234*cdf0e10cSrcweir 					mnMaximum = rRange.mnMaximum;
235*cdf0e10cSrcweir 				}
236*cdf0e10cSrcweir             }
237*cdf0e10cSrcweir         }
238*cdf0e10cSrcweir 
239*cdf0e10cSrcweir 		void grow(T nValue)
240*cdf0e10cSrcweir 		{
241*cdf0e10cSrcweir 			if(!isEmpty())
242*cdf0e10cSrcweir 			{
243*cdf0e10cSrcweir 				bool bLessThanZero(nValue < 0);
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir 				if(nValue > 0 || bLessThanZero)
246*cdf0e10cSrcweir 				{
247*cdf0e10cSrcweir 					mnMinimum -= nValue;
248*cdf0e10cSrcweir 					mnMaximum += nValue;
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir 					if(bLessThanZero)
251*cdf0e10cSrcweir 					{
252*cdf0e10cSrcweir 						// test if range did collapse
253*cdf0e10cSrcweir 						if(mnMinimum > mnMaximum)
254*cdf0e10cSrcweir 						{
255*cdf0e10cSrcweir 							// if yes, collapse to center
256*cdf0e10cSrcweir 							mnMinimum = mnMaximum = (mnMinimum + mnMaximum) / 2;
257*cdf0e10cSrcweir 						}
258*cdf0e10cSrcweir 					}
259*cdf0e10cSrcweir 				}
260*cdf0e10cSrcweir 			}
261*cdf0e10cSrcweir 		}
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir 		typename Traits::DifferenceType getRange() const
264*cdf0e10cSrcweir 		{
265*cdf0e10cSrcweir 			if(isEmpty())
266*cdf0e10cSrcweir 			{
267*cdf0e10cSrcweir 				return Traits::neutral();
268*cdf0e10cSrcweir 			}
269*cdf0e10cSrcweir 			else
270*cdf0e10cSrcweir 			{
271*cdf0e10cSrcweir 				return (mnMaximum - mnMinimum);
272*cdf0e10cSrcweir 			}
273*cdf0e10cSrcweir 		}
274*cdf0e10cSrcweir 	};
275*cdf0e10cSrcweir 
276*cdf0e10cSrcweir     // some pre-fabricated traits
277*cdf0e10cSrcweir     struct DoubleTraits
278*cdf0e10cSrcweir     {
279*cdf0e10cSrcweir         static double minVal() { return DBL_MIN; };
280*cdf0e10cSrcweir         static double maxVal() { return DBL_MAX; };
281*cdf0e10cSrcweir         static double neutral() { return 0.0; };
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir         typedef double DifferenceType;
284*cdf0e10cSrcweir     };
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir     struct Int32Traits
287*cdf0e10cSrcweir     {
288*cdf0e10cSrcweir         static sal_Int32 minVal() { return SAL_MIN_INT32; };
289*cdf0e10cSrcweir         static sal_Int32 maxVal() { return SAL_MAX_INT32; };
290*cdf0e10cSrcweir         static sal_Int32 neutral() { return 0L; };
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir         typedef sal_Int64 DifferenceType;
293*cdf0e10cSrcweir     };
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir } // end of namespace basegfx
296*cdf0e10cSrcweir 
297*cdf0e10cSrcweir #endif /* _BGFX_RANGE_BASICRANGE_HXX */
298