home *** CD-ROM | disk | FTP | other *** search
- /*
- File: PolyShpe.cpp
-
- Contains: Polygon shape class, private to ODShape.
-
- Owned by: Jens Alfke
-
- Copyright: © 1993 - 1995 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <12> 8/18/95 NP 1274946: Remove kODErrInvalidParameter
- <11> 8/16/95 NP 1274946: ErrorDef.idl problems. Add include
- file.
- <10> 5/25/95 jpa Use new GX headers [1241078, 1253324]
- <9> 3/20/95 jpa No need to wrap TRY around use of
- ODTempPolygon. [1215160
- <8> 12/20/94 jpa Removed bogus call to Simplify in
- InitQDRegion. [1168281]
- <7> 12/5/94 jpa Removed fSimple; assume client will call
- Simplify after SetPolygon. [1191192,
- 1196018]. Also code-review cleanup
- [1203923]
- <6> 10/24/94 jpa Implemented Outset. [1186719, 1190423].
- Added fSimple flag, and simplified before
- converting to Region. [1191192]
- <5> 9/29/94 RA 1189812: Mods for 68K build.
- <4> 9/9/94 jpa Partial implementation of Outset; right now
- punts to RgnShape since poly outsetter is
- unimplemented. [1178690]
- <3> 8/8/94 jpa Added Outset method [1178690]
- <2> 8/2/94 jpa Added no-op case to ::Combine.
- <1> 6/15/94 jpa first checked in
-
- In Progress:
- */
-
-
- #ifndef _ALTPOINT_
- #include "AltPoint.h" /* Use C++ savvy ODPoint and ODRect*/
- #endif
-
- #ifndef _ALTPOLY_
- #include "AltPoly.h"
- #endif
-
- #ifndef _POLYSHPE_
- #include "PolyShpe.h"
- #endif
-
- #ifndef _RECTSHPE_
- #include "RectShpe.h"
- #endif
-
- #ifndef _RGNSHPE_
- #include "RgnShpe.h"
- #endif
-
- #ifndef _EXCEPT_
- #include "Except.h"
- #endif
-
- #ifndef SOM_ODTransform_xh
- #include "Trnsform.xh"
- #endif
-
- #ifndef _RGN2POLY_
- #include "Rgn2PlyM.h"
- #endif
-
- #ifndef _POLYCLIP_
- #include "PolyClip.h"
- #endif
-
- #ifndef _ODDEBUG_
- #include "ODDebug.h"
- #endif
-
- #ifndef _ODMEMORY_
- #include "ODMemory.h"
- #endif
-
- #ifndef _UTILERRS_
- #include "UtilErrs.h"
- #endif
-
- #ifndef __GXGRAPHICS__
- #include <GXGraphics.h>
- #endif
-
-
- PolygonShape::PolygonShape( ODGeometryMode mode )
- :RealShape(mode),
- fPolygon(),
- fBoundsValid(kODFalse)
- {
- #if ODDebug
- fType = 2;
- WASSERTM(!gGX,"PolygonShape is not worthy: GX installed");
- #endif
- }
-
-
- PolygonShape::~PolygonShape( )
- {
- fPolygon.Clear();
- }
-
-
- ODSize
- PolygonShape::Purge( ODSize bytes )
- {
- if( bytes==0 )
- fBoundsValid = kODFalse; // Means just flush cache
- return RealShape::Purge(bytes);
- }
-
-
- void
- PolygonShape::GetBoundingBox( ODRect *bounds )
- {
- if( !fBoundsValid )
- fPolygon.ComputeBoundingBox(&fBounds);
- if( bounds )
- *bounds = fBounds;
- }
-
-
- RealShape*
- PolygonShape::SetRectangle( const ODRect *r )
- {
- RealShape *rect = new RectShape(fMode,*r);
- delete this;
- return rect;
- }
-
-
- void
- PolygonShape::CopyPolygon( ODPolygon &poly )
- {
- poly.CopyFrom(fPolygon);
- }
-
-
- RealShape*
- PolygonShape::SetPolygon( const ODPolygon &poly )
- {
- fPolygon.CopyFrom(poly);
- this->Purge(0);
- return this;
- }
-
-
- void
- PolygonShape::Simplify( )
- {
- // Client is responsible for calling this method after SetPolygon
- // if the polygon is not known to be simple. PolygonShape assumes
- // its fPolygon is always simple.
-
- PolySimplify(fPolygon,fPolygon);
- }
-
-
- void
- PolygonShape::InitQDRegion( )
- {
- RgnHandle rgn = fPolygon.AsQDRegion();
- ODDisposeHandle((ODHandle)fQDRegion);
- fQDRegion = rgn;
- }
-
-
- gxShape
- PolygonShape::CopyGXShape( )
- {
- ASSERT(gGX>0,kODErrAssertionFailed);
- return fPolygon.AsGXShape();
- }
-
-
- ODBoolean
- PolygonShape::IsSameAs( RealShape *shape )
- {
- if( shape == this )
- return kODTrue;
-
- else if( this->IsEmpty() )
- return shape->IsEmpty();
-
- else if( shape->IsEmpty() )
- return kODFalse;
-
- else if( shape->IsRectangular() )
- if( this->IsRectangular() ) {
- ODRect itsBox;
- this->GetBoundingBox(NULL);
- shape->GetBoundingBox(&itsBox);
- return fBounds==itsBox;
-
- } else
- return kODFalse;
-
- else if( this->IsRectangular() )
- return kODFalse;
-
- else if( shape->HasGeometry() ) {
- ODTempPolygon poly;
- shape->CopyPolygon(poly);
- ODBoolean same;
- same = (fPolygon == poly);
- return same;
-
- } else
- return kODFalse;
- }
-
-
- ODBoolean
- PolygonShape::IsEmpty( )
- {
- return fPolygon.IsEmpty();
- }
-
-
- ODBoolean
- PolygonShape::ContainsPoint( ODPoint point )
- {
- if( fPolygon.HasData() ) {
- ODRect bbox;
- this->GetBoundingBox(NULL);
- if( !fBounds.Contains(point) )
- return kODFalse; // Not in bounding-box
- return fPolygon.Contains(point) != 0;
- } else
- return kODFalse;
- }
-
-
- ODBoolean
- PolygonShape::IsRectangular( )
- {
- return fPolygon.IsRectangular();
- }
-
-
- RealShape*
- PolygonShape::Copy( )
- {
- PolygonShape *s = new PolygonShape(fMode);
- TRY{
- s->SetPolygon(fPolygon);
- }CATCH_ALL{
- delete s;
- RERAISE;
- }ENDTRY
- return s;
- }
-
-
- RealShape*
- PolygonShape::Transform( Environment *ev, ODTransform *xform )
- {
- fPolygon.Transform(ev,xform);
- this->Purge(0);
- return this;
- }
-
-
- RealShape*
- PolygonShape::Outset( ODCoordinate distance )
- {
- if( distance!=0 && fPolygon.HasData() ) {
- if( fMode==kODLoseGeometry ) {
- // Convert to QD region:
- RgnHandle rgn = (RgnHandle) ODCopyHandle(
- (ODHandle)this->GetPlatformShape(kODQuickDraw) );
- RealShape *s;
- TRY{
- s = new RgnShape(fMode);
- }CATCH_ALL{
- DisposeRgn(rgn);
- RERAISE;
- }ENDTRY
-
- TRY{
- s->SetPlatformShape(kODQuickDraw,rgn);
- s = s->Outset(distance);
- }CATCH_ALL{
- delete s;
- RERAISE;
- }ENDTRY
- delete this;
- return s;
-
- } else {
- if( PolyOutset(fPolygon,distance) )
- PolySimplify(fPolygon,fPolygon);
- }
- }
- return this;
- }
-
-
- RealShape*
- PolygonShape::Combine( ODShapeOp op, RealShape *shape )
- {
- if( op==kShapeNoOp )
- return this;
- else if( op==kShapeOutset )
- ASSERT(shape!=kODNULL, kODErrIllegalNullInput);
-
- ODPolygon result;
- {
- ODTempPolygon shapePoly;
- shape->CopyPolygon(shapePoly);
-
- ODPolygon* poly[2];
- poly[0] = &fPolygon;
- poly[1] = &shapePoly;
- PolyClip(2,(const ODPolygon**)poly,op, result);
- }
-
- if( result.HasData() ) {
- fPolygon.MoveFrom(result);
- this->Purge(0);
- return this;
- } else
- return this->Clear();
- }
-
-
- RealShape*
- PolygonShape::Subtract( RealShape *shape )
- {
- if( shape==this )
- return this->Clear();
- else if( shape->IsEmpty() || this->IsEmpty() )
- return this;
-
- // Check bounding boxes:
- ODRect itsBox;
- this->GetBoundingBox(NULL);
- shape->GetBoundingBox(&itsBox);
- if( !fBounds.Intersects(itsBox) )
- return this; // BBoxes do not intersect: no-op
- else if( itsBox.Contains(fBounds) && shape->IsRectangular() )
- return this->Clear(); // shape is a rectangle containing me: clear
-
- if( fMode!=kODLoseGeometry && shape->HasGeometry() )
- return this->Combine(kShapeDifference,shape);
- else
- return this->Promote(kShapeDifference,shape);
- }
-
-
- RealShape*
- PolygonShape::Intersect( RealShape *shape )
- {
- if( shape==this || this->IsEmpty() )
- return this;
- else if( shape->IsEmpty() )
- return this->Clear();
-
- // Check bounding boxes:
- ODRect itsBox;
- this->GetBoundingBox(NULL);
- shape->GetBoundingBox(&itsBox);
- if( !fBounds.Intersects(itsBox) )
- return this->Clear(); // BBoxes do not intersect: clear
- else if( itsBox.Contains(fBounds) && shape->IsRectangular() )
- return this; // shape is a rectangle containing me: no-op
-
- // OK, must intersect:
- if( fMode!=kODLoseGeometry && shape->HasGeometry() )
- return this->Combine(kShapeIntersection,shape);
- else
- return this->Promote(kShapeIntersection,shape);
- }
-
-
- RealShape*
- PolygonShape::Union( RealShape *shape )
- {
- if( shape==this || shape->IsEmpty() )
- return this;
- else if( this->IsEmpty() )
- return this->ReplaceWith(shape);
-
- // Check bounding boxes:
- if( shape->IsRectangular() ) {
- ODRect itsBox;
- this->GetBoundingBox(NULL);
- shape->GetBoundingBox(&itsBox);
- if( itsBox.Contains(fBounds) )
- return this->ReplaceWith(shape);
- }
-
- if( fMode!=kODLoseGeometry && shape->HasGeometry() )
- return this->Combine(kShapeUnion,shape);
- else
- return this->Promote(kShapeUnion,shape);
- }
-