1*ce9c7ef7SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*ce9c7ef7SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*ce9c7ef7SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*ce9c7ef7SAndrew Rist * distributed with this work for additional information 6*ce9c7ef7SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*ce9c7ef7SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*ce9c7ef7SAndrew Rist * "License"); you may not use this file except in compliance 9*ce9c7ef7SAndrew Rist * with the License. You may obtain a copy of the License at 10*ce9c7ef7SAndrew Rist * 11*ce9c7ef7SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*ce9c7ef7SAndrew Rist * 13*ce9c7ef7SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*ce9c7ef7SAndrew Rist * software distributed under the License is distributed on an 15*ce9c7ef7SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*ce9c7ef7SAndrew Rist * KIND, either express or implied. See the License for the 17*ce9c7ef7SAndrew Rist * specific language governing permissions and limitations 18*ce9c7ef7SAndrew Rist * under the License. 19*ce9c7ef7SAndrew Rist * 20*ce9c7ef7SAndrew Rist *************************************************************/ 21*ce9c7ef7SAndrew Rist 22*ce9c7ef7SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #ifndef _BGFX_RANGE_BASICRANGE_HXX 25cdf0e10cSrcweir #define _BGFX_RANGE_BASICRANGE_HXX 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <sal/types.h> 28cdf0e10cSrcweir #include <float.h> 29cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx> 30cdf0e10cSrcweir 31cdf0e10cSrcweir 32cdf0e10cSrcweir namespace basegfx 33cdf0e10cSrcweir { 34cdf0e10cSrcweir template< typename T, typename Traits > class BasicRange 35cdf0e10cSrcweir { 36cdf0e10cSrcweir protected: 37cdf0e10cSrcweir T mnMinimum; 38cdf0e10cSrcweir T mnMaximum; 39cdf0e10cSrcweir 40cdf0e10cSrcweir public: 41cdf0e10cSrcweir typedef T ValueType; 42cdf0e10cSrcweir typedef Traits TraitsType; 43cdf0e10cSrcweir BasicRange()44cdf0e10cSrcweir BasicRange() : 45cdf0e10cSrcweir mnMinimum(Traits::maxVal()), 46cdf0e10cSrcweir mnMaximum(Traits::minVal()) 47cdf0e10cSrcweir { 48cdf0e10cSrcweir } 49cdf0e10cSrcweir BasicRange(T nValue)50cdf0e10cSrcweir BasicRange( T nValue ) : 51cdf0e10cSrcweir mnMinimum(nValue), 52cdf0e10cSrcweir mnMaximum(nValue) 53cdf0e10cSrcweir { 54cdf0e10cSrcweir } 55cdf0e10cSrcweir BasicRange(const BasicRange & rRange)56cdf0e10cSrcweir BasicRange(const BasicRange& rRange) : 57cdf0e10cSrcweir mnMinimum(rRange.mnMinimum), 58cdf0e10cSrcweir mnMaximum(rRange.mnMaximum) 59cdf0e10cSrcweir { 60cdf0e10cSrcweir } 61cdf0e10cSrcweir reset()62cdf0e10cSrcweir void reset() 63cdf0e10cSrcweir { 64cdf0e10cSrcweir mnMinimum = Traits::maxVal(); 65cdf0e10cSrcweir mnMaximum = Traits::minVal(); 66cdf0e10cSrcweir } 67cdf0e10cSrcweir isEmpty() const68cdf0e10cSrcweir bool isEmpty() const 69cdf0e10cSrcweir { 70cdf0e10cSrcweir return Traits::maxVal() == mnMinimum; 71cdf0e10cSrcweir } 72cdf0e10cSrcweir getMinimum() const73cdf0e10cSrcweir T getMinimum() const { return mnMinimum; } getMaximum() const74cdf0e10cSrcweir T getMaximum() const { return mnMaximum; } 75cdf0e10cSrcweir getCenter() const76cdf0e10cSrcweir double getCenter() const 77cdf0e10cSrcweir { 78cdf0e10cSrcweir if(isEmpty()) 79cdf0e10cSrcweir { 80cdf0e10cSrcweir return 0.0; 81cdf0e10cSrcweir } 82cdf0e10cSrcweir else 83cdf0e10cSrcweir { 84cdf0e10cSrcweir return ((mnMaximum + mnMinimum) / 2.0); 85cdf0e10cSrcweir } 86cdf0e10cSrcweir } 87cdf0e10cSrcweir isInside(T nValue) const88cdf0e10cSrcweir bool isInside(T nValue) const 89cdf0e10cSrcweir { 90cdf0e10cSrcweir if(isEmpty()) 91cdf0e10cSrcweir { 92cdf0e10cSrcweir return false; 93cdf0e10cSrcweir } 94cdf0e10cSrcweir else 95cdf0e10cSrcweir { 96cdf0e10cSrcweir return (nValue >= mnMinimum) && (nValue <= mnMaximum); 97cdf0e10cSrcweir } 98cdf0e10cSrcweir } 99cdf0e10cSrcweir isInside(const BasicRange & rRange) const100cdf0e10cSrcweir bool isInside(const BasicRange& rRange) const 101cdf0e10cSrcweir { 102cdf0e10cSrcweir if(isEmpty()) 103cdf0e10cSrcweir { 104cdf0e10cSrcweir return false; 105cdf0e10cSrcweir } 106cdf0e10cSrcweir else 107cdf0e10cSrcweir { 108cdf0e10cSrcweir if(rRange.isEmpty()) 109cdf0e10cSrcweir { 110cdf0e10cSrcweir return false; 111cdf0e10cSrcweir } 112cdf0e10cSrcweir else 113cdf0e10cSrcweir { 114cdf0e10cSrcweir return (rRange.mnMinimum >= mnMinimum) && (rRange.mnMaximum <= mnMaximum); 115cdf0e10cSrcweir } 116cdf0e10cSrcweir } 117cdf0e10cSrcweir } 118cdf0e10cSrcweir overlaps(const BasicRange & rRange) const119cdf0e10cSrcweir bool overlaps(const BasicRange& rRange) const 120cdf0e10cSrcweir { 121cdf0e10cSrcweir if(isEmpty()) 122cdf0e10cSrcweir { 123cdf0e10cSrcweir return false; 124cdf0e10cSrcweir } 125cdf0e10cSrcweir else 126cdf0e10cSrcweir { 127cdf0e10cSrcweir if(rRange.isEmpty()) 128cdf0e10cSrcweir { 129cdf0e10cSrcweir return false; 130cdf0e10cSrcweir } 131cdf0e10cSrcweir else 132cdf0e10cSrcweir { 133cdf0e10cSrcweir return !((rRange.mnMaximum < mnMinimum) || (rRange.mnMinimum > mnMaximum)); 134cdf0e10cSrcweir } 135cdf0e10cSrcweir } 136cdf0e10cSrcweir } 137cdf0e10cSrcweir overlapsMore(const BasicRange & rRange) const138cdf0e10cSrcweir bool overlapsMore(const BasicRange& rRange) const 139cdf0e10cSrcweir { 140cdf0e10cSrcweir if(isEmpty() || rRange.isEmpty()) 141cdf0e10cSrcweir return false; 142cdf0e10cSrcweir // returns true if the overlap is more than just a touching at the limits 143cdf0e10cSrcweir return ((rRange.mnMaximum > mnMinimum) && (rRange.mnMinimum < mnMaximum)); 144cdf0e10cSrcweir } 145cdf0e10cSrcweir operator ==(const BasicRange & rRange) const146cdf0e10cSrcweir bool operator==( const BasicRange& rRange ) const 147cdf0e10cSrcweir { 148cdf0e10cSrcweir return (mnMinimum == rRange.mnMinimum && mnMaximum == rRange.mnMaximum); 149cdf0e10cSrcweir } 150cdf0e10cSrcweir operator !=(const BasicRange & rRange) const151cdf0e10cSrcweir bool operator!=( const BasicRange& rRange ) const 152cdf0e10cSrcweir { 153cdf0e10cSrcweir return (mnMinimum != rRange.mnMinimum || mnMaximum != rRange.mnMaximum); 154cdf0e10cSrcweir } 155cdf0e10cSrcweir operator =(const BasicRange & rRange)156cdf0e10cSrcweir BasicRange& operator=(const BasicRange& rRange) 157cdf0e10cSrcweir { 158cdf0e10cSrcweir mnMinimum = rRange.mnMinimum; 159cdf0e10cSrcweir mnMaximum = rRange.mnMaximum; 160cdf0e10cSrcweir return *this; 161cdf0e10cSrcweir } 162cdf0e10cSrcweir equal(const BasicRange & rRange) const163cdf0e10cSrcweir bool equal(const BasicRange& rRange) const 164cdf0e10cSrcweir { 165cdf0e10cSrcweir return ( 166cdf0e10cSrcweir fTools::equal(mnMinimum, rRange.mnMinimum) && 167cdf0e10cSrcweir fTools::equal(mnMaximum, rRange.mnMaximum)); 168cdf0e10cSrcweir } 169cdf0e10cSrcweir expand(T nValue)170cdf0e10cSrcweir void expand(T nValue) 171cdf0e10cSrcweir { 172cdf0e10cSrcweir if(isEmpty()) 173cdf0e10cSrcweir { 174cdf0e10cSrcweir mnMinimum = mnMaximum = nValue; 175cdf0e10cSrcweir } 176cdf0e10cSrcweir else 177cdf0e10cSrcweir { 178cdf0e10cSrcweir if(nValue < mnMinimum) 179cdf0e10cSrcweir { 180cdf0e10cSrcweir mnMinimum = nValue; 181cdf0e10cSrcweir } 182cdf0e10cSrcweir 183cdf0e10cSrcweir if(nValue > mnMaximum) 184cdf0e10cSrcweir { 185cdf0e10cSrcweir mnMaximum = nValue; 186cdf0e10cSrcweir } 187cdf0e10cSrcweir } 188cdf0e10cSrcweir } 189cdf0e10cSrcweir expand(const BasicRange & rRange)190cdf0e10cSrcweir void expand(const BasicRange& rRange) 191cdf0e10cSrcweir { 192cdf0e10cSrcweir if(isEmpty()) 193cdf0e10cSrcweir { 194cdf0e10cSrcweir mnMinimum = rRange.mnMinimum; 195cdf0e10cSrcweir mnMaximum = rRange.mnMaximum; 196cdf0e10cSrcweir } 197cdf0e10cSrcweir else 198cdf0e10cSrcweir { 199cdf0e10cSrcweir if(!rRange.isEmpty()) 200cdf0e10cSrcweir { 201cdf0e10cSrcweir if(rRange.mnMinimum < mnMinimum) 202cdf0e10cSrcweir { 203cdf0e10cSrcweir mnMinimum = rRange.mnMinimum; 204cdf0e10cSrcweir } 205cdf0e10cSrcweir 206cdf0e10cSrcweir if(rRange.mnMaximum > mnMaximum) 207cdf0e10cSrcweir { 208cdf0e10cSrcweir mnMaximum = rRange.mnMaximum; 209cdf0e10cSrcweir } 210cdf0e10cSrcweir } 211cdf0e10cSrcweir } 212cdf0e10cSrcweir } 213cdf0e10cSrcweir intersect(const BasicRange & rRange)214cdf0e10cSrcweir void intersect(const BasicRange& rRange) 215cdf0e10cSrcweir { 216cdf0e10cSrcweir // here, overlaps also tests all isEmpty() conditions already. 217cdf0e10cSrcweir if( !overlaps( rRange ) ) 218cdf0e10cSrcweir { 219cdf0e10cSrcweir reset(); 220cdf0e10cSrcweir } 221cdf0e10cSrcweir else 222cdf0e10cSrcweir { 223cdf0e10cSrcweir if(rRange.mnMinimum > mnMinimum) 224cdf0e10cSrcweir { 225cdf0e10cSrcweir mnMinimum = rRange.mnMinimum; 226cdf0e10cSrcweir } 227cdf0e10cSrcweir 228cdf0e10cSrcweir if(rRange.mnMaximum < mnMaximum) 229cdf0e10cSrcweir { 230cdf0e10cSrcweir mnMaximum = rRange.mnMaximum; 231cdf0e10cSrcweir } 232cdf0e10cSrcweir } 233cdf0e10cSrcweir } 234cdf0e10cSrcweir grow(T nValue)235cdf0e10cSrcweir void grow(T nValue) 236cdf0e10cSrcweir { 237cdf0e10cSrcweir if(!isEmpty()) 238cdf0e10cSrcweir { 239cdf0e10cSrcweir bool bLessThanZero(nValue < 0); 240cdf0e10cSrcweir 241cdf0e10cSrcweir if(nValue > 0 || bLessThanZero) 242cdf0e10cSrcweir { 243cdf0e10cSrcweir mnMinimum -= nValue; 244cdf0e10cSrcweir mnMaximum += nValue; 245cdf0e10cSrcweir 246cdf0e10cSrcweir if(bLessThanZero) 247cdf0e10cSrcweir { 248cdf0e10cSrcweir // test if range did collapse 249cdf0e10cSrcweir if(mnMinimum > mnMaximum) 250cdf0e10cSrcweir { 251cdf0e10cSrcweir // if yes, collapse to center 252cdf0e10cSrcweir mnMinimum = mnMaximum = (mnMinimum + mnMaximum) / 2; 253cdf0e10cSrcweir } 254cdf0e10cSrcweir } 255cdf0e10cSrcweir } 256cdf0e10cSrcweir } 257cdf0e10cSrcweir } 258cdf0e10cSrcweir getRange() const259cdf0e10cSrcweir typename Traits::DifferenceType getRange() const 260cdf0e10cSrcweir { 261cdf0e10cSrcweir if(isEmpty()) 262cdf0e10cSrcweir { 263cdf0e10cSrcweir return Traits::neutral(); 264cdf0e10cSrcweir } 265cdf0e10cSrcweir else 266cdf0e10cSrcweir { 267cdf0e10cSrcweir return (mnMaximum - mnMinimum); 268cdf0e10cSrcweir } 269cdf0e10cSrcweir } 270cdf0e10cSrcweir }; 271cdf0e10cSrcweir 272cdf0e10cSrcweir // some pre-fabricated traits 273cdf0e10cSrcweir struct DoubleTraits 274cdf0e10cSrcweir { minValbasegfx::DoubleTraits275cdf0e10cSrcweir static double minVal() { return DBL_MIN; }; maxValbasegfx::DoubleTraits276cdf0e10cSrcweir static double maxVal() { return DBL_MAX; }; neutralbasegfx::DoubleTraits277cdf0e10cSrcweir static double neutral() { return 0.0; }; 278cdf0e10cSrcweir 279cdf0e10cSrcweir typedef double DifferenceType; 280cdf0e10cSrcweir }; 281cdf0e10cSrcweir 282cdf0e10cSrcweir struct Int32Traits 283cdf0e10cSrcweir { minValbasegfx::Int32Traits284cdf0e10cSrcweir static sal_Int32 minVal() { return SAL_MIN_INT32; }; maxValbasegfx::Int32Traits285cdf0e10cSrcweir static sal_Int32 maxVal() { return SAL_MAX_INT32; }; neutralbasegfx::Int32Traits286cdf0e10cSrcweir static sal_Int32 neutral() { return 0L; }; 287cdf0e10cSrcweir 288cdf0e10cSrcweir typedef sal_Int64 DifferenceType; 289cdf0e10cSrcweir }; 290cdf0e10cSrcweir 291cdf0e10cSrcweir } // end of namespace basegfx 292cdf0e10cSrcweir 293cdf0e10cSrcweir #endif /* _BGFX_RANGE_BASICRANGE_HXX */ 294