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