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_RANGE_BASICRANGE_HXX 25 #define _BGFX_RANGE_BASICRANGE_HXX 26 27 #include <sal/types.h> 28 #include <float.h> 29 #include <basegfx/numeric/ftools.hxx> 30 31 32 namespace basegfx 33 { 34 template< typename T, typename Traits > class BasicRange 35 { 36 protected: 37 T mnMinimum; 38 T mnMaximum; 39 40 public: 41 typedef T ValueType; 42 typedef Traits TraitsType; 43 BasicRange()44 BasicRange() : 45 mnMinimum(Traits::maxVal()), 46 mnMaximum(Traits::minVal()) 47 { 48 } 49 BasicRange(T nValue)50 BasicRange( T nValue ) : 51 mnMinimum(nValue), 52 mnMaximum(nValue) 53 { 54 } 55 BasicRange(const BasicRange & rRange)56 BasicRange(const BasicRange& rRange) : 57 mnMinimum(rRange.mnMinimum), 58 mnMaximum(rRange.mnMaximum) 59 { 60 } 61 reset()62 void reset() 63 { 64 mnMinimum = Traits::maxVal(); 65 mnMaximum = Traits::minVal(); 66 } 67 isEmpty() const68 bool isEmpty() const 69 { 70 return Traits::maxVal() == mnMinimum; 71 } 72 getMinimum() const73 T getMinimum() const { return mnMinimum; } getMaximum() const74 T getMaximum() const { return mnMaximum; } 75 getCenter() const76 double getCenter() const 77 { 78 if(isEmpty()) 79 { 80 return 0.0; 81 } 82 else 83 { 84 return ((mnMaximum + mnMinimum) / 2.0); 85 } 86 } 87 isInside(T nValue) const88 bool isInside(T nValue) const 89 { 90 if(isEmpty()) 91 { 92 return false; 93 } 94 else 95 { 96 return (nValue >= mnMinimum) && (nValue <= mnMaximum); 97 } 98 } 99 isInside(const BasicRange & rRange) const100 bool isInside(const BasicRange& rRange) const 101 { 102 if(isEmpty()) 103 { 104 return false; 105 } 106 else 107 { 108 if(rRange.isEmpty()) 109 { 110 return false; 111 } 112 else 113 { 114 return (rRange.mnMinimum >= mnMinimum) && (rRange.mnMaximum <= mnMaximum); 115 } 116 } 117 } 118 overlaps(const BasicRange & rRange) const119 bool overlaps(const BasicRange& rRange) const 120 { 121 if(isEmpty()) 122 { 123 return false; 124 } 125 else 126 { 127 if(rRange.isEmpty()) 128 { 129 return false; 130 } 131 else 132 { 133 return !((rRange.mnMaximum < mnMinimum) || (rRange.mnMinimum > mnMaximum)); 134 } 135 } 136 } 137 overlapsMore(const BasicRange & rRange) const138 bool overlapsMore(const BasicRange& rRange) const 139 { 140 if(isEmpty() || rRange.isEmpty()) 141 return false; 142 // returns true if the overlap is more than just a touching at the limits 143 return ((rRange.mnMaximum > mnMinimum) && (rRange.mnMinimum < mnMaximum)); 144 } 145 operator ==(const BasicRange & rRange) const146 bool operator==( const BasicRange& rRange ) const 147 { 148 return (mnMinimum == rRange.mnMinimum && mnMaximum == rRange.mnMaximum); 149 } 150 operator !=(const BasicRange & rRange) const151 bool operator!=( const BasicRange& rRange ) const 152 { 153 return (mnMinimum != rRange.mnMinimum || mnMaximum != rRange.mnMaximum); 154 } 155 operator =(const BasicRange & rRange)156 BasicRange& operator=(const BasicRange& rRange) 157 { 158 mnMinimum = rRange.mnMinimum; 159 mnMaximum = rRange.mnMaximum; 160 return *this; 161 } 162 equal(const BasicRange & rRange) const163 bool equal(const BasicRange& rRange) const 164 { 165 return ( 166 fTools::equal(mnMinimum, rRange.mnMinimum) && 167 fTools::equal(mnMaximum, rRange.mnMaximum)); 168 } 169 expand(T nValue)170 void expand(T nValue) 171 { 172 if(isEmpty()) 173 { 174 mnMinimum = mnMaximum = nValue; 175 } 176 else 177 { 178 if(nValue < mnMinimum) 179 { 180 mnMinimum = nValue; 181 } 182 183 if(nValue > mnMaximum) 184 { 185 mnMaximum = nValue; 186 } 187 } 188 } 189 expand(const BasicRange & rRange)190 void expand(const BasicRange& rRange) 191 { 192 if(isEmpty()) 193 { 194 mnMinimum = rRange.mnMinimum; 195 mnMaximum = rRange.mnMaximum; 196 } 197 else 198 { 199 if(!rRange.isEmpty()) 200 { 201 if(rRange.mnMinimum < mnMinimum) 202 { 203 mnMinimum = rRange.mnMinimum; 204 } 205 206 if(rRange.mnMaximum > mnMaximum) 207 { 208 mnMaximum = rRange.mnMaximum; 209 } 210 } 211 } 212 } 213 intersect(const BasicRange & rRange)214 void intersect(const BasicRange& rRange) 215 { 216 // here, overlaps also tests all isEmpty() conditions already. 217 if( !overlaps( rRange ) ) 218 { 219 reset(); 220 } 221 else 222 { 223 if(rRange.mnMinimum > mnMinimum) 224 { 225 mnMinimum = rRange.mnMinimum; 226 } 227 228 if(rRange.mnMaximum < mnMaximum) 229 { 230 mnMaximum = rRange.mnMaximum; 231 } 232 } 233 } 234 grow(T nValue)235 void grow(T nValue) 236 { 237 if(!isEmpty()) 238 { 239 bool bLessThanZero(nValue < 0); 240 241 if(nValue > 0 || bLessThanZero) 242 { 243 mnMinimum -= nValue; 244 mnMaximum += nValue; 245 246 if(bLessThanZero) 247 { 248 // test if range did collapse 249 if(mnMinimum > mnMaximum) 250 { 251 // if yes, collapse to center 252 mnMinimum = mnMaximum = (mnMinimum + mnMaximum) / 2; 253 } 254 } 255 } 256 } 257 } 258 getRange() const259 typename Traits::DifferenceType getRange() const 260 { 261 if(isEmpty()) 262 { 263 return Traits::neutral(); 264 } 265 else 266 { 267 return (mnMaximum - mnMinimum); 268 } 269 } 270 }; 271 272 // some pre-fabricated traits 273 struct DoubleTraits 274 { minValbasegfx::DoubleTraits275 static double minVal() { return DBL_MIN; }; maxValbasegfx::DoubleTraits276 static double maxVal() { return DBL_MAX; }; neutralbasegfx::DoubleTraits277 static double neutral() { return 0.0; }; 278 279 typedef double DifferenceType; 280 }; 281 282 struct Int32Traits 283 { minValbasegfx::Int32Traits284 static sal_Int32 minVal() { return SAL_MIN_INT32; }; maxValbasegfx::Int32Traits285 static sal_Int32 maxVal() { return SAL_MAX_INT32; }; neutralbasegfx::Int32Traits286 static sal_Int32 neutral() { return 0L; }; 287 288 typedef sal_Int64 DifferenceType; 289 }; 290 291 } // end of namespace basegfx 292 293 #endif /* _BGFX_RANGE_BASICRANGE_HXX */ 294