/* * Copyright (c) 1990, 1991 Stanford University * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Stanford not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Stanford makes no representations about * the suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * Implementation of Rectangles and Polygons, objects derived from Graphic. */ #include #include #include #include #include #include /*****************************************************************************/ Rect::Rect (Coord x0, Coord y0, Coord x1, Coord y1, Graphic* gr) : Graphic(gr){ _x0 = min(x0, x1); _y0 = min(y0, y1); _x1 = max(x0, x1); _y1 = max(y0, y1); } void Rect::GetOriginal (Coord& x0, Coord& y0, Coord& x1, Coord& y1) { x0 = _x0; y0 = _y0; x1 = _x1; y1 = _y1; } void Rect::SetOriginal (Coord x0, Coord y0, Coord x1, Coord y1) { _x0 = x0; _y0 = y0; _x1 = x1; _y1 = y1; uncacheExtent(); } void Rect::s_getExtent ( float& l, float& b, float& cx, float& cy, float& tol, Graphic* gs ) { float width, dummy1, dummy2; width = float(gs->GetBrush()->Width()); tol = (width > 1) ? width/2 : 0; transformRect(_x0, _y0, _x1, _y1, l, b, dummy1, dummy2, gs); transform(float(_x0+_x1)/2, float(_y0+_y1)/2, cx, cy, gs); } void Rect::f_getExtent ( float& l, float& b, float& cx, float& cy, float& tol, Graphic* gs ){ float dummy1, dummy2; transformRect(_x0, _y0, _x1, _y1, l, b, dummy1, dummy2, gs); transform(float(_x0+_x1)/2, float(_y0+_y1)/2, cx, cy, gs); tol = 0; } boolean Rect::s_contains (PointObj& po, Graphic* gs) { PointObj pt (&po); invTransform(pt._x, pt._y, gs); return ( ((pt._x == _x0 || pt._x == _x1) && _y0 <= pt._y && pt._y <= _y1) || ((pt._y == _y0 || pt._y == _y1) && _x0 <= pt._x && pt._x <= _x1) ); } boolean Rect::f_contains (PointObj& po, Graphic* gs) { PointObj pt (&po); invTransform(pt._x, pt._y, gs); BoxObj b (_x0, _y0, _x1, _y1); return b.Contains(pt); } boolean Rect::s_intersects (BoxObj& userb, Graphic* gs) { Coord x[4], tx[5]; Coord y[4], ty[5]; x[0] = x[3] = _x0; y[0] = y[1] = _y0; x[2] = x[1] = _x1; y[2] = y[3] = _y1; transformList(x, y, 4, tx, ty, gs); tx[4] = tx[0]; ty[4] = ty[0]; MultiLineObj ml (tx, ty, 5); return ml.Intersects(userb) || ml.Within(userb); } boolean Rect::f_intersects (BoxObj& userb, Graphic* gs) { Transformer* t = gs->GetTransformer(); Coord tx0, ty0, tx1, ty1; if (t != nil && t->Rotated()) { Coord x[4], tx[5]; Coord y[4], ty[5]; x[0] = x[3] = _x0; y[0] = y[1] = _y0; x[2] = x[1] = _x1; y[2] = y[3] = _y1; transformList(x, y, 4, tx, ty, gs); tx[4] = tx[0]; ty[4] = ty[0]; FillPolygonObj fp (tx, ty, 5); return fp.Intersects(userb); } else if (t != nil) { t->Transform(_x0, _y0, tx0, ty0); t->Transform(_x1, _y1, tx1, ty1); BoxObj b1 (tx0, ty0, tx1, ty1); return b1.Intersects(userb); } else { BoxObj b2 (_x0, _y0, _x1, _y1); return b2.Intersects(userb); } } /*****************************************************************************/ S_Rect::S_Rect ( Coord x0, Coord y0, Coord x1, Coord y1, Graphic* gr ) : Rect(x0, y0, x1, y1, gr) { _br = nil; if (gr != nil) { S_Rect::SetBrush(gr->GetBrush()); } } S_Rect::~S_Rect () { Unref(_br); } void S_Rect::SetBrush (PSBrush* br) { if (_br != br) { Ref(br); Unref(_br); _br = br; invalidateCaches(); } } PSBrush* S_Rect::GetBrush () { return _br; } Graphic* S_Rect::Copy () { return new S_Rect(_x0, _y0, _x1, _y1, this); } void S_Rect::getExtent ( float& l, float& b, float& cx, float& cy, float& tol, Graphic* gs ) { s_getExtent(l, b, cx, cy, tol, gs); } boolean S_Rect::contains (PointObj& po, Graphic* gs) { return s_contains(po, gs); } boolean S_Rect::intersects (BoxObj& userb, Graphic* gs) { return s_intersects(userb, gs); } void S_Rect::draw (Canvas *c, Graphic* gs) { if (!gs->GetBrush()->None()) { update(gs); _p->Rect(c, _x0, _y0, _x1, _y1); } } /*****************************************************************************/ F_Rect::F_Rect ( Coord _x0, Coord _y0, Coord _x1, Coord _y1, Graphic* gr ) : Rect(_x0, _y0, _x1, _y1, gr) { _pat = nil; if (gr != nil) { F_Rect::SetPattern(gr->GetPattern()); } } F_Rect::~F_Rect () { Unref(_pat); } void F_Rect::SetPattern (PSPattern* pat) { Ref(pat); Unref(_pat); _pat = pat; } PSPattern* F_Rect::GetPattern () { return _pat; } Graphic* F_Rect::Copy () { return new F_Rect(_x0, _y0, _x1, _y1, this); } void F_Rect::getExtent ( float& l, float& b, float& cx, float& cy, float& tol, Graphic* gs ) { f_getExtent(l, b, cx, cy, tol, gs); } boolean F_Rect::contains (PointObj& po, Graphic* gs) { return !gs->GetPattern()->None() && f_contains(po, gs); } boolean F_Rect::intersects (BoxObj& userb, Graphic* gs) { return !gs->GetPattern()->None() && f_intersects(userb, gs); } void F_Rect::draw (Canvas *c, Graphic* gs) { if (!gs->GetPattern()->None()) { update(gs); _p->FillRect(c, _x0, _y0, _x1, _y1); } } /*****************************************************************************/ SF_Rect::SF_Rect ( Coord x0, Coord y0, Coord x1, Coord y1, Graphic* gr ) : Rect(x0, y0, x1, y1, gr) { _br = nil; _pat = nil; if (gr != nil) { SF_Rect::SetBrush(gr->GetBrush()); SF_Rect::SetPattern(gr->GetPattern()); } } SF_Rect::~SF_Rect () { Unref(_br); Unref(_pat); } void SF_Rect::SetBrush (PSBrush* br) { if (_br != br) { Ref(br); Unref(_br); _br = br; invalidateCaches(); } } PSBrush* SF_Rect::GetBrush () { return _br; } void SF_Rect::SetPattern (PSPattern* pat) { Ref(pat); Unref(_pat); _pat = pat; } PSPattern* SF_Rect::GetPattern () { return _pat; } Graphic* SF_Rect::Copy () { return new SF_Rect(_x0, _y0, _x1, _y1, this); } ClassId SF_Rect::CompId () { return RECT_COMP; } void SF_Rect::getExtent ( float& l, float& b, float& cx, float& cy, float& tol, Graphic* gs ) { s_getExtent(l, b, cx, cy, tol, gs); } boolean SF_Rect::contains (PointObj& po, Graphic* gs) { return (!gs->GetPattern()->None() && f_contains(po, gs)) || s_contains(po, gs); } boolean SF_Rect::intersects (BoxObj& userb, Graphic* gs) { return (!gs->GetPattern()->None() && f_intersects(userb, gs)) || s_intersects(userb, gs); } void SF_Rect::draw (Canvas* c, Graphic* gs) { update(gs); if (!gs->GetPattern()->None()) { _p->FillRect(c, _x0, _y0, _x1, _y1); } if (!gs->GetBrush()->None()) { _p->Rect(c, _x0, _y0, _x1, _y1); } } /*****************************************************************************/ Polygon::Polygon ( Coord* x, Coord* y, int count, Graphic* gr ) : Vertices(x, y, count, gr) { } boolean Polygon::s_contains (PointObj& po, Graphic* gs) { BoxObj b; PointObj pt (&po); getBox(b, gs); if (b.Contains(pt)) { MultiLineObj &ml = *_pts; LineObj l (x()[count() - 1], y()[count() - 1], *x(), *y()); invTransform(pt._x, pt._y, gs); return ml.Contains(pt) || l.Contains(pt); } return false; } boolean Polygon::f_contains (PointObj& po, Graphic* gs) { BoxObj b; PointObj pt (&po); getBox(b, gs); if (b.Contains(pt)) { FillPolygonObj fp (x(), y(), count()); invTransform(pt._x, pt._y, gs); return fp.Contains(pt); } return false; } boolean Polygon::s_intersects (BoxObj& userb, Graphic* gs) { Coord* convx, *convy; BoxObj b; boolean result = false; getBox(b, gs); if (b.Intersects(userb)) { convx = new Coord[count()+1]; convy = new Coord[count()+1]; transformList(x(), y(), count(), convx, convy, gs); convx[count()] = *convx; convy[count()] = *convy; MultiLineObj ml(convx, convy, count()+1); result = ml.Intersects(userb); delete convx; delete convy; } return result; } boolean Polygon::f_intersects (BoxObj& userb, Graphic* gs) { Coord* convx, *convy; BoxObj b; boolean result = false; getBox(b, gs); if (b.Intersects(userb)) { convx = new Coord[count()+1]; convy = new Coord[count()+1]; transformList(x(), y(), count(), convx, convy, gs); FillPolygonObj fp (convx, convy, count()); result = fp.Intersects(userb); delete convx; delete convy; } return result; } /*****************************************************************************/ S_Polygon::S_Polygon ( Coord* x, Coord* y, int count, Graphic* gr ) : Polygon(x, y, count, gr) { _br = nil; if (gr != nil) { S_Polygon::SetBrush(gr->GetBrush()); } } S_Polygon::~S_Polygon () { Unref(_br); } void S_Polygon::SetBrush (PSBrush* br) { if (_br != br) { Ref(br); Unref(_br); _br = br; invalidateCaches(); } } PSBrush* S_Polygon::GetBrush () { return _br; } Graphic* S_Polygon::Copy () { return new S_Polygon(x(), y(), count(), this); } void S_Polygon::getExtent ( float& l, float& b, float& cx, float& cy, float& tol, Graphic* gs ) { s_getExtent(l, b, cx, cy, tol, gs); } boolean S_Polygon::contains (PointObj& po, Graphic* gs) { return s_contains(po, gs); } boolean S_Polygon::intersects (BoxObj& userb, Graphic* gs) { return s_intersects(userb, gs); } void S_Polygon::draw (Canvas *c, Graphic* gs) { if (!gs->GetBrush()->None()) { update(gs); #if __GNUC__>=2 && __GNUC_MINOR__>=5 || __GNUC__>=3 #undef Polygon _p->Polygon(c, x(), y(), count()); #define Polygon _lib_iv(Polygon) #else _p->Polygon(c, x(), y(), count()); #endif /* Polygon */ } } /*****************************************************************************/ F_Polygon::F_Polygon ( Coord* x, Coord* y, int count, Graphic* gr ) : Polygon(x, y, count, gr) { _pat = nil; if (gr != nil) { F_Polygon::SetPattern(gr->GetPattern()); } } F_Polygon::~F_Polygon () { Unref(_pat); } void F_Polygon::SetPattern (PSPattern* pat) { Ref(pat); Unref(_pat); _pat = pat; } PSPattern* F_Polygon::GetPattern () { return _pat; } Graphic* F_Polygon::Copy () { return new F_Polygon(x(), y(), count(), this); } void F_Polygon::getExtent ( float& l, float& b, float& cx, float& cy, float& tol, Graphic* gs ) { f_getExtent(l, b, cx, cy, tol, gs); } boolean F_Polygon::contains (PointObj& po, Graphic* gs) { return !gs->GetPattern()->None() && f_contains(po, gs); } boolean F_Polygon::intersects (BoxObj& userb, Graphic* gs) { return !gs->GetPattern()->None() && f_intersects(userb, gs); } void F_Polygon::draw (Canvas *c, Graphic* gs) { if (!gs->GetPattern()->None()) { update(gs); _p->FillPolygon(c, x(), y(), count()); } } /*****************************************************************************/ SF_Polygon::SF_Polygon ( Coord* x, Coord* y, int count, Graphic* gr ) : Polygon(x, y, count, gr) { _br = nil; _pat = nil; if (gr != nil) { SF_Polygon::SetBrush(gr->GetBrush()); SF_Polygon::SetPattern(gr->GetPattern()); } } SF_Polygon::~SF_Polygon () { Unref(_br); Unref(_pat); } void SF_Polygon::SetBrush (PSBrush* br) { if (_br != br) { Ref(br); Unref(_br); _br = br; invalidateCaches(); } } PSBrush* SF_Polygon::GetBrush () { return _br; } void SF_Polygon::SetPattern (PSPattern* pat) { Ref(pat); Unref(_pat); _pat = pat; } PSPattern* SF_Polygon::GetPattern () { return _pat; } Graphic* SF_Polygon::Copy () { return new SF_Polygon(x(), y(), count(), this); } ClassId SF_Polygon::CompId () { return POLYGON_COMP; } void SF_Polygon::getExtent ( float& l, float& b, float& cx, float& cy, float& tol, Graphic* gs ) { s_getExtent(l, b, cx, cy, tol, gs); } boolean SF_Polygon::contains (PointObj& po, Graphic* gs) { return (!gs->GetPattern()->None() && f_contains(po, gs)) || s_contains(po, gs); } boolean SF_Polygon::intersects (BoxObj& userb, Graphic* gs) { return (!gs->GetPattern()->None() && f_intersects(userb, gs)) || s_intersects(userb, gs); } void SF_Polygon::draw (Canvas *c, Graphic* gs) { update(gs); if (!gs->GetPattern()->None()) { _p->FillPolygon(c, x(), y(), count()); } if (!gs->GetBrush()->None()) { #if __GNUC__>=2 && __GNUC_MINOR__>=5 || __GNUC__>=3 #undef Polygon _p->Polygon(c, x(), y(), count()); #define Polygon _lib_iv(Polygon) #else _p->Polygon(c, x(), y(), count()); #endif /* Polygon */ } }