diff options
Diffstat (limited to 'kig/misc/rect.cpp')
-rw-r--r-- | kig/misc/rect.cpp | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/kig/misc/rect.cpp b/kig/misc/rect.cpp new file mode 100644 index 00000000..6a7ded12 --- /dev/null +++ b/kig/misc/rect.cpp @@ -0,0 +1,308 @@ +// Copyright (C) 2002 Dominique Devriese <devriese@kde.org> + +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +// 02110-1301, USA. + +#include "rect.h" +#include "common.h" + +bool operator==( const Rect& r, const Rect& s ) +{ + return ( r.bottomLeft() == s.bottomLeft() + && r.width() == s.width() + && r.height() == s.height() ); +} + +kdbgstream& operator<<( kdbgstream& s, const Rect& t ) +{ + s << "left: " << t.left() + << "bottom: " << t.bottom() + << "right: " << t.right() + << "top: " << t.top() + << endl; + return s; +} + +Rect::Rect( const Coordinate bottomLeft, const Coordinate topRight ) + : mBottomLeft(bottomLeft) +{ + mwidth = topRight.x - bottomLeft.x; + mheight = topRight.y - bottomLeft.y; + normalize(); +} + +Rect::Rect( const Coordinate p, const double width, const double height ) + : mBottomLeft(p), + mwidth(width), + mheight(height) +{ + normalize(); +} + +Rect::Rect( double xa, double ya, double width, double height ) + : mBottomLeft( xa, ya ), + mwidth( width ), + mheight( height ) +{ + normalize(); +} + +Rect::Rect( const Rect& r ) + : mBottomLeft (r.mBottomLeft), + mwidth(r.mwidth), + mheight(r.mheight) +{ + normalize(); +} + +Rect::Rect() + : mwidth(0), + mheight(0) +{ +} + +void Rect::setBottomLeft( const Coordinate p ) +{ + mBottomLeft = p; +} + +void Rect::setBottomRight( const Coordinate p ) +{ + mBottomLeft = p - Coordinate(mwidth,0); +} + +void Rect::setTopRight( const Coordinate p ) +{ + mBottomLeft = p - Coordinate(mwidth, mheight); +} + +void Rect::setCenter( const Coordinate p ) +{ + mBottomLeft = p - Coordinate(mwidth, mheight)/2; +} + +void Rect::setLeft( const double p ) +{ + double r = right(); + mBottomLeft.x = p; + setRight( r ); +} + +void Rect::setRight( const double p ) +{ + mwidth = p - left(); +} + +void Rect::setBottom( const double p ) +{ + double t = top(); + mBottomLeft.y = p; + setTop( t ); +} + +void Rect::setTop( const double p ) +{ + mheight = p - bottom(); +} + +void Rect::setWidth( const double w ) +{ + mwidth = w; +} + +void Rect::setHeight( const double h ) +{ + mheight = h; +} + +void Rect::normalize() +{ + if ( mwidth < 0 ) + { + mBottomLeft.x += mwidth; + mwidth = -mwidth; + }; + if ( mheight < 0 ) + { + mBottomLeft.y += mheight; + mheight = -mheight; + }; +} + +void Rect::moveBy( const Coordinate p ) +{ + mBottomLeft += p; +} + +void Rect::scale( const double r ) +{ + mwidth *= r; + mheight *= r; +} + + +TQRect Rect::toTQRect() const +{ + return TQRect(mBottomLeft.toTQPoint(), topRight().toTQPoint()); +} + +Coordinate Rect::bottomLeft() const +{ + return mBottomLeft; +} + +Coordinate Rect::bottomRight() const +{ + return mBottomLeft + Coordinate(mwidth, 0); +} + +Coordinate Rect::topLeft() const +{ + return mBottomLeft + Coordinate(0, mheight); +} + +Coordinate Rect::topRight() const +{ + return mBottomLeft + Coordinate(mwidth, mheight); +} + +Coordinate Rect::center() const +{ + return mBottomLeft + Coordinate(mwidth, mheight)/2; +} + +double Rect::left() const +{ + return mBottomLeft.x; +} +double Rect::right() const +{ + return left() + mwidth; +} +double Rect::bottom() const +{ + return mBottomLeft.y; +} + +double Rect::top() const +{ + return bottom() + mheight; +} + +double Rect::width() const +{ + return mwidth; +} + +double Rect::height() const +{ + return mheight; +} + +bool Rect::contains( const Coordinate& p, double allowed_miss ) const +{ + return p.x - left() >= - allowed_miss && + p.y - bottom() >= - allowed_miss && + p.x - left() - width() <= allowed_miss && + p.y - bottom() - height() <= allowed_miss; +} + +bool Rect::contains( const Coordinate& p ) const +{ + return p.x >= left() && + p.y >= bottom() && + p.x - left() <= width() && + p.y - bottom() <= height(); +} + +bool Rect::intersects( const Rect& p ) const +{ + // never thought it was this simple :) + if( p.left() < left() && p.right() < left()) return false; + if( p.left() > right() && p.right() > right()) return false; + if( p.bottom() < bottom() && p.top() < bottom()) return false; + if( p.bottom() > top() && p.top() > top()) return false; + return true; +} + +void Rect::setContains( Coordinate p ) +{ + normalize(); + if( p.x < left() ) setLeft( p.x ); + if( p.x > right() ) setRight(p.x); + if( p.y < bottom() ) setBottom( p.y ); + if( p.y > top() ) setTop( p.y ); +} + +Rect Rect::normalized() const +{ + Rect t = *this; + (void) t.normalize(); + return t; +} + +Rect Rect::fromTQRect( const TQRect& r ) +{ + return Rect( r.left(), r.top(), r.right(), r.bottom() ); +} + +void Rect::setTopLeft( const Coordinate p ) +{ + Coordinate bl = Coordinate( p.x, p.y - mheight ); + setBottomLeft( bl ); +} + +Rect operator|( const Rect& lhs, const Rect& rhs ) +{ + Rect r( lhs ); + r |= rhs; + return r; +} + +void Rect::eat( const Rect& r ) +{ + setLeft( kigMin( left(), r.left() ) ); + setRight( kigMax( right(), r.right() ) ); + setBottom( kigMin( bottom(), r.bottom() ) ); + setTop( kigMax( top(), r.top() ) ); +} + +Rect Rect::matchShape( const Rect& rhs, bool shrink ) const +{ + Rect ret = *this; + Coordinate c = center(); + double v = width()/height(); // current ratio + double w = rhs.width()/rhs.height(); // wanted ratio + + // we don't show less than r, if the dimensions don't match, we + // extend r into some dimension... + if( ( v > w ) ^ shrink ) + ret.setHeight( ret.width() / w ); + else + ret.setWidth( ret.height() * w ); + + ret.setCenter(c); + return ret.normalized(); +} + +bool Rect::valid() +{ + return mBottomLeft.valid() && mwidth != double_inf && mheight != double_inf; +} + +Rect Rect::invalidRect() +{ + return Rect( Coordinate::invalidCoord(), double_inf, double_inf ); +} |