home *** CD-ROM | disk | FTP | other *** search
- /*
- File: AltPoint.cpp
-
- Contains: Alternate ODPoint, ODRect (C++ savvy)
-
- Owned by: Jens Alfke
-
- Copyright: © 1993 - 1995 by Apple Computer, Inc., all rights reserved.
-
- */
-
- #ifndef _ALTPOINT_
- #include "AltPoint.h"
- #endif
-
- #ifndef SOM_Module_OpenDoc_Global_Types_defined
- #include "ODTypesM.xh"
- #endif
-
- #ifndef _EXCEPT_
- #include "Except.h"
- #endif
-
- #ifndef _ODDEBUG_
- #include "ODDebug.h"
- #endif
-
- #ifndef _LINEOPS_
- #include "LineOps.h" /* For kFixedEpsilon */
- #endif
-
- #include <string.h>
-
-
- #ifdef _PLATFORM_MACINTOSH_
- #ifndef __GXMATH__
- #include <GXMath.h>
- #endif
- #endif
-
- #ifndef _ODDEBUG_
- #include "ODDebug.h"
- #endif
-
- #pragma segment ODShape
-
-
- //==============================================================================
- // ODPoint
- //==============================================================================
-
-
- #ifdef _PLATFORM_MACINTOSH_
- ODPoint::ODPoint( Point qdpt )
- {
- x = IntToFixed(qdpt.h);
- y = IntToFixed(qdpt.v);
- }
- #endif
-
-
- ODPoint::ODPoint( const ODPoint &pt )
- {
- x = pt.x;
- y = pt.y;
- }
-
-
- ODPoint& ODPoint::operator= ( const ODPoint &pt )
- {
- x = pt.x;
- y = pt.y;
- return *this;
- }
-
-
- #ifdef _PLATFORM_MACINTOSH_
- ODPoint& ODPoint::operator= ( const Point &pt )
- {
- x = IntToFixed(pt.h);
- y = IntToFixed(pt.v);
- return *this;
- }
- #endif
-
-
- void ODPoint::Offset ( ODCoordinate xx, ODCoordinate yy )
- {
- x += xx;
- y += yy;
- }
-
-
- void ODPoint::operator+= ( const ODPoint &pt )
- {
- x += pt.x;
- y += pt.y;
- }
-
-
- void ODPoint::operator-= ( const ODPoint &pt )
- {
- x -= pt.x;
- y -= pt.y;
- }
-
-
- #ifdef _PLATFORM_MACINTOSH_
- void ODPoint::operator+= ( const Point &pt )
- {
- x += IntToFixed(pt.h);
- y += IntToFixed(pt.v);
- }
-
-
- void ODPoint::operator-= ( const Point &pt )
- {
- x -= IntToFixed(pt.h);
- y -= IntToFixed(pt.v);
- }
-
- Point
- ODPoint::AsQDPoint( ) const
- {
- Point pt;
- pt.h = FixedToInt(x);
- pt.v = FixedToInt(y);
- return pt;
- }
- #endif
-
-
- ODSShort
- ODPoint::IntX( ) const
- {
- return FixedToInt(x);
- }
-
-
- ODSShort
- ODPoint::IntY( ) const
- {
- return FixedToInt(y);
- }
-
-
- ODBoolean
- ODPoint::operator==( const ODPoint &pt ) const
- {
- return x==pt.x && y==pt.y;
- }
-
-
- ODBoolean
- ODPoint::operator!=( const ODPoint &pt ) const
- {
- return x!=pt.x || y!=pt.y;
- }
-
-
- ODBoolean
- ODPoint::ApproxEquals( const ODPoint& pt ) const
- {
- ODFixed delta;
- delta = x-pt.x;
- if( delta>kFixedEpsilon || delta<-kFixedEpsilon )
- return kODFalse;
- delta = y-pt.y;
- if( delta>kFixedEpsilon || delta<-kFixedEpsilon )
- return kODFalse;
- return kODTrue;
- }
-
-
- //==============================================================================
- // ODRect
- //==============================================================================
-
-
- #pragma segment ODShape
-
-
- #define ASSERTVALID() WASSERT(right>=left && bottom>=top)
-
-
- //------------------------------------------------------------------------------
- // ::ODRect( corner1, corner2 )
- //
- // Construct a rectangle given two opposite corners (not necessarily topLeft,botRight)
- //------------------------------------------------------------------------------
-
- ODRect::ODRect( const ODPoint &a, const ODPoint &b )
- {
- this->Set(a,b);
- }
-
-
- //------------------------------------------------------------------------------
- // ::ODRect( topLeft, width, height )
- //
- // Construct a rectangle given its origin, width and height.
- //------------------------------------------------------------------------------
-
- ODRect::ODRect( const ODPoint &topLeft, ODCoordinate width, ODCoordinate height )
- {
- WASSERT(width>=0);
- WASSERT(height>=0);
-
- left = topLeft.x; right = topLeft.x + width;
- top = topLeft.y; bottom= topLeft.y + height;
- }
-
-
- #ifdef _PLATFORM_MACINTOSH_
- //------------------------------------------------------------------------------
- // ::ODRect( Rect )
- //
- // Construct an ODRect from a QuickDraw Rect
- //------------------------------------------------------------------------------
-
- ODRect::ODRect( const Rect &r )
- {
- left = ff(r.left); right = ff(r.right);
- top = ff(r.top); bottom= ff(r.bottom);
- }
-
-
- //------------------------------------------------------------------------------
- // ::= Rect
- //
- // Set an ODRect from a QuickDraw Rect
- //------------------------------------------------------------------------------
-
- ODRect&
- ODRect:: operator= ( const Rect &r )
- {
- left = ff(r.left); right = ff(r.right);
- top = ff(r.top); bottom= ff(r.bottom);
- ASSERTVALID();
- return *this;
- }
- #endif
-
-
- //------------------------------------------------------------------------------
- // ::Set
- //
- // Set all four coordinates of a rectangle. Warn if the resulting rect is bogus.
- //------------------------------------------------------------------------------
-
- void
- ODRect::Set( ODCoordinate l, ODCoordinate t, ODCoordinate r, ODCoordinate b )
- {
- left = l; right = r;
- top = t; bottom= b;
- ASSERTVALID();
- }
-
-
- //------------------------------------------------------------------------------
- // ::Set
- //
- // Set all four coordinates of a rectangle. Warn if the resulting rect is bogus.
- //------------------------------------------------------------------------------
-
- void
- ODRect::Set( const ODPoint &origin, ODCoordinate width, ODCoordinate height )
- {
- WASSERT(width>=0);
- WASSERT(height>=0);
- left = origin.x; right = left+width;
- top = origin.y; bottom= top +height;
- }
-
-
- //------------------------------------------------------------------------------
- // ::Set
- //
- // Construct a rectangle given two opposite corners (not necessarily topLeft,botRight)
- //------------------------------------------------------------------------------
-
- void
- ODRect::Set( const ODPoint &a, const ODPoint &b )
- {
- if( a.x<b.x ) {
- left = a.x;
- right= b.x;
- } else {
- left = b.x;
- right= a.x;
- }
- if( a.y<b.y ) {
- top = a.y;
- bottom= b.y;
- } else {
- top = b.y;
- bottom= a.y;
- }
- }
-
-
- //------------------------------------------------------------------------------
- // ::SetInt
- //
- // Set coordinates of a rectangle from integers. Warn if the resulting rect is bogus.
- //------------------------------------------------------------------------------
-
- void
- ODRect::SetInt( short l, short t, short r, short b )
- {
- left = ff(l); right = ff(r);
- top = ff(t); bottom= ff(b);
- ASSERTVALID();
- }
-
-
- //------------------------------------------------------------------------------
- // ::Offset
- //
- // Move a rectangle.
- //------------------------------------------------------------------------------
-
- void
- ODRect::Offset( ODCoordinate x, ODCoordinate y )
- {
- left += x; right += x;
- top += y; bottom+= y;
- }
-
- void
- ODRect::Offset( const ODPoint &pt )
- {
- left += pt.x; right += pt.x;
- top += pt.y; bottom+= pt.y;
- }
-
-
- //------------------------------------------------------------------------------
- // ::Inset
- //
- // Inset the edges of a rectangle, without collapsing to negative dimensions.
- //------------------------------------------------------------------------------
-
- void
- ODRect::Inset( ODCoordinate x, ODCoordinate y )
- {
- left += x;
- right = Max(left,right-x);
- top += y;
- bottom = Max(top,bottom-y);
- }
-
-
- //------------------------------------------------------------------------------
- // ::Clear
- //
- // Zero all coordinates
- //------------------------------------------------------------------------------
-
- void
- ODRect::Clear( )
- {
- left = right = top = bottom = 0;
- }
-
-
- //------------------------------------------------------------------------------
- // :: &=
- //
- // Intersect me with another rectangle (result stored in me)
- //------------------------------------------------------------------------------
-
- void
- ODRect:: operator&= ( const ODRect &r )
- {
- left = Max(left,r.left); right = Min(right, r.right);
- top = Max(top, r.top); bottom= Min(bottom,r.bottom);
- if( this->IsEmpty() )
- this->Clear();
- }
-
-
- //------------------------------------------------------------------------------
- // :: |=
- //
- // Union me with another rectangle (result stored in me)
- //------------------------------------------------------------------------------
-
- void
- ODRect:: operator|= ( const ODRect &r )
- {
- if( this->IsEmpty() )
- *this = r;
- else if( !r.IsEmpty() ) {
- left = Min(left,r.left);
- right= Max(right,r.right);
- top = Min(top,r.top);
- bottom=Max(bottom,r.bottom);
- }
- }
-
-
- //------------------------------------------------------------------------------
- // :: |= ODPoint
- //
- // Union me with a point (expand to fit point)
- //------------------------------------------------------------------------------
-
- void
- ODRect:: operator|= ( const ODPoint &pt )
- {
- left = Min(left,pt.x);
- right= Max(right,pt.x);
- top = Min(top,pt.y);
- bottom=Max(bottom,pt.y);
- }
-
-
- #ifdef _PLATFORM_MACINTOSH_
- //------------------------------------------------------------------------------
- // :: AsQDRect
- //
- // Turn me into a QuickDraw rect
- //------------------------------------------------------------------------------
-
- void
- ODRect::AsQDRect( Rect &r ) const
- {
- SetRect(&r, FixedToInt(left), FixedToInt(top), FixedToInt(right), FixedToInt(bottom));
- }
- #endif
-
-
- //------------------------------------------------------------------------------
- // :: IsEmpty
- //
- // Do I have no area?
- //------------------------------------------------------------------------------
-
- Boolean
- ODRect::IsEmpty( ) const
- {
- return right<=left || bottom<=top;
- }
-
-
- //------------------------------------------------------------------------------
- // :: Contains( Point )
- //
- // Do I contain a point? (Remember, I don't contain my right and bottom edges.)
- //------------------------------------------------------------------------------
-
- Boolean
- ODRect::Contains( const ODPoint &pt ) const
- {
- return left<=pt.x && pt.x<right
- && top <=pt.y && pt.y<bottom;
- }
-
-
- //------------------------------------------------------------------------------
- // :: Contains( Rect )
- //
- // Do I contain an entire rect?
- //------------------------------------------------------------------------------
-
- Boolean
- ODRect::Contains( const ODRect &r ) const
- {
- if( r.right<=r.left || r.bottom<=r.top )
- return kODTrue; // Empty rect contained in anything
- else
- return left<=r.left && r.right<=right
- && top <=r.top && r.bottom<=bottom;
- }
-
-
- //------------------------------------------------------------------------------
- // :: ApproxContains( Rect )
- //
- // Do I approximately (within epsilon) contain an entire rect?
- //------------------------------------------------------------------------------
-
- Boolean
- ODRect::ApproxContains( const ODRect &r ) const
- {
- if( r.right<=r.left || r.bottom<=r.top )
- return kODTrue; // Empty rect contained in anything
- else
- return left-kFixedEpsilon<=r.left && r.right<=right+kFixedEpsilon
- && top-kFixedEpsilon <=r.top && r.bottom<=bottom+kFixedEpsilon;
- }
-
-
- //------------------------------------------------------------------------------
- // :: ==
- //
- // Am I equal to another rect?
- //------------------------------------------------------------------------------
-
- Boolean
- ODRect::operator==( const ODRect &r ) const
- {
- return memcmp(this,&r,sizeof(ODRect)) == 0;
- }
-
-
- //------------------------------------------------------------------------------
- // :: ApproxEquals
- //
- // Am I approximately equal (within epsilon) to another rect?
- //------------------------------------------------------------------------------
-
- ODBoolean
- ODRect::ApproxEquals( const ODRect &r ) const
- {
- return left-r.left<=kFixedEpsilon && left-r.left>=-kFixedEpsilon
- && right-r.right<=kFixedEpsilon && right-r.right>=-kFixedEpsilon
- && top-r.top<=kFixedEpsilon && top-r.top>=-kFixedEpsilon
- && bottom-r.bottom<=kFixedEpsilon && bottom-r.bottom>=-kFixedEpsilon;
- }
-
-
- //------------------------------------------------------------------------------
- // :: Intersects
- //
- // Do I intersect another rectangle?
- // (Remember, I don't contain my right and bottom edges.)
- //------------------------------------------------------------------------------
-
- Boolean
- ODRect::Intersects( const ODRect &r ) const
- {
- return Max(left,r.left) < Min(right,r.right)
- && Max(top,r.top) < Min(bottom,r.bottom);
- }
-