shapes.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:13k
- /*
- * shapes.cxx
- *
- * Geometric shapes.
- *
- * Portable Windows Library
- *
- * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Portable Windows Library.
- *
- * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
- *
- * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
- * All Rights Reserved.
- *
- * Contributor(s): ______________________________________.
- *
- * $Log: shapes.cxx,v $
- * Revision 1.12 1999/08/17 03:46:41 robertj
- * Fixed usage of inlines in optimised version.
- *
- * Revision 1.11 1998/12/20 09:14:44 robertj
- * Added pragma implementation for GNU compiler.
- *
- * Revision 1.10 1998/11/30 04:52:17 robertj
- * New directory structure
- *
- * Revision 1.9 1998/09/23 06:29:55 robertj
- * Added open source copyright license.
- *
- * Revision 1.8 1997/04/27 05:50:24 robertj
- * DLL support.
- *
- * Revision 1.7 1996/08/08 10:08:50 robertj
- * Directory structure changes for common files.
- *
- * Revision 1.6 1996/01/28 02:52:08 robertj
- * Added assert into all Compare functions to assure comparison between compatible objects.
- *
- * Revision 1.5 1995/01/21 05:22:36 robertj
- * Documentation.
- *
- * Revision 1.4 1994/10/23 03:38:06 robertj
- * Changed PPixels to pointer to get polymorphism.
- *
- * Revision 1.3 1994/08/01 03:41:24 robertj
- * Use of PNEW instead of new for heap debugging. Need undef for Unix end.
- *
- * Revision 1.2 1994/07/27 05:58:07 robertj
- * Synchronisation.
- *
- * Revision 1.1 1994/04/20 12:17:44 robertj
- * Initial revision
- *
- */
- #ifdef __GNUC__
- #pragma implementation "shapes.h"
- #endif
- #include <pwlib.h>
- #include <pwclib/shapes.h>
- #if !P_USE_INLINES
- #include <pwclib/shapes.inl>
- #endif
- #define new PNEW
- //////////////////////////////////////////////////////////////////////////////
- // PShape
- void PShape::_SetPosition(const PPoint & pt)
- {
- position = pt;
- }
- void PShape::_SetDimensions(const PDim &)
- {
- // Do nothing
- }
- BOOL PShape::InShape(const PPoint & pt) const
- {
- return GetBounds().ContainsPoint(pt);
- }
- BOOL PShape::IsComposite() const
- {
- return FALSE;
- }
- //////////////////////////////////////////////////////////////////////////////
- // PLine
- PObject::Comparison PLine::Compare(const PObject & obj) const
- {
- PAssert(obj.IsDescendant(PLine::Class()), PInvalidCast);
- const PLine & other = (const PLine &)obj;
- return position != other.position || otherEnd != other.otherEnd
- ? GreaterThan : EqualTo;
- }
- PDim PLine::GetDimensions() const
- {
- PPoint d = position - otherEnd;
- return PDim(PABS(d.X()), PABS(d.Y()));
- }
- BOOL PLine::InShape(const PPoint &) const
- {
- return FALSE;
- }
- void PLine::Draw(PCanvas & canvas) const
- {
- canvas = *this;
- canvas.DrawLine(position, otherEnd);
- }
- //////////////////////////////////////////////////////////////////////////////
- // POrthoShape
- POrthoShape::POrthoShape(const PPoint & topLeft, const PPoint & botRight)
- : PShape(PMIN(topLeft.X(), botRight.X()), PMIN(topLeft.Y(), botRight.Y())),
- dimensions(PABS(topLeft.X()-botRight.X()), PABS(topLeft.Y()-botRight.Y()))
- {
- }
- PObject::Comparison POrthoShape::Compare(const PObject & obj) const
- {
- PAssert(obj.IsDescendant(POrthoShape::Class()), PInvalidCast);
- const POrthoShape & other = (const POrthoShape &)obj;
- if (dimensions != other.dimensions)
- return GreaterThan;
- return position != other.position ? LessThan : EqualTo;
- }
- PDim POrthoShape::GetDimensions() const
- {
- return dimensions;
- }
- void POrthoShape::_SetDimensions(const PDim & dim)
- {
- dimensions = dim;
- }
- //////////////////////////////////////////////////////////////////////////////
- // PRectangle
- void PRectangle::Draw(PCanvas & canvas) const
- {
- canvas = *this;
- canvas.DrawRect(position, dimensions);
- }
- //////////////////////////////////////////////////////////////////////////////
- // PRoundedRectangle
- PObject::Comparison PRoundedRectangle::Compare(const PObject & obj) const
- {
- PAssert(obj.IsDescendant(PRoundedRectangle::Class()), PInvalidCast);
- const PRoundedRectangle & other = (const PRoundedRectangle &)obj;
- return position != other.position || dimensions != other.dimensions ||
- corner != other.corner ? GreaterThan : EqualTo;
- }
- void PRoundedRectangle::Draw(PCanvas & canvas) const
- {
- canvas = *this;
- canvas.DrawRoundRect(PRect(position, dimensions),
- corner.Width(), corner.Height());
- }
- //////////////////////////////////////////////////////////////////////////////
- // PEllipse
- void PEllipse::Draw(PCanvas & canvas) const
- {
- canvas = *this;
- canvas.DrawEllipse(PRect(position, dimensions));
- }
- //////////////////////////////////////////////////////////////////////////////
- // PArc
- PObject::Comparison PArc::Compare(const PObject & obj) const
- {
- PAssert(obj.IsDescendant(PArc::Class()), PInvalidCast);
- const PArc & other = (const PArc &)obj;
- return position != other.position || dimensions != other.dimensions ||
- startAngle != other.startAngle || endAngle != other.endAngle
- ? GreaterThan : EqualTo;
- }
- void PArc::Draw(PCanvas & canvas) const
- {
- canvas = *this;
- canvas.DrawArc(PRect(position, dimensions), startAngle, endAngle);
- }
- //////////////////////////////////////////////////////////////////////////////
- // PPie
- void PPie::Draw(PCanvas & canvas) const
- {
- canvas = *this;
- canvas.DrawPie(PRect(position, dimensions), startAngle, endAngle);
- }
- //////////////////////////////////////////////////////////////////////////////
- // PChord
- void PChord::Draw(PCanvas & canvas) const
- {
- canvas = *this;
- canvas.DrawChord(PRect(position, dimensions), startAngle, endAngle);
- }
- //////////////////////////////////////////////////////////////////////////////
- // PPixShape
- PPixShape::PPixShape(PORDINATE x, PORDINATE y, const PPixelImage & pix)
- : POrthoShape(x, y, pix->Width(), pix->Height())
- {
- pixels = pix;
- }
- PPixShape::PPixShape(const PPoint & pt, const PPixelImage & pix)
- : POrthoShape(pt, pix->GetDimensions())
- {
- pixels = pix;
- }
- void PPixShape::Draw(PCanvas & canvas) const
- {
- canvas = *this;
- canvas.DrawPixels(PRect(position, dimensions), pixels);
- }
- //////////////////////////////////////////////////////////////////////////////
- // PPicShape
- PPicShape::PPicShape(PORDINATE x, PORDINATE y, const PPictImage & pic)
- : POrthoShape(x, y, pic->Width(), pic->Height())
- {
- picture = pic;
- }
- PPicShape::PPicShape(const PPoint & pt, const PPictImage & pic)
- : POrthoShape(pt, pic->GetDimensions())
- {
- picture = pic;
- }
- void PPicShape::Draw(PCanvas & canvas) const
- {
- canvas = *this;
- canvas.DrawPict(PRect(position, dimensions), picture);
- }
- //////////////////////////////////////////////////////////////////////////////
- // PTextLines
- PObject::Comparison PTextLines::Compare(const PObject & obj) const
- {
- PAssert(obj.IsDescendant(PTextLines::Class()), PInvalidCast);
- const PTextLines & other = (const PTextLines &)obj;
- return position != other.position || text != other.text
- ? GreaterThan : EqualTo;
- }
- PDim PTextLines::GetDimensions() const
- {
- PAssert(dimensions.Width() != 0 && dimensions.Height() != 0, PInvalidParameter);
- return dimensions;
- }
- void PTextLines::Draw(PCanvas & canvas) const
- {
- canvas = *this;
- ((PTextLines*)this)->dimensions = canvas.MeasureString(text);
- canvas.DrawString(position, text);
- }
- void PTextLines::SetText(const PString & str)
- {
- text = str;
- dimensions.SetHeight(0); // Needs to be recalculated
- }
- PDim PTextLines::GetDimensions(PCanvas & canvas)
- {
- canvas = *this;
- dimensions = canvas.MeasureString(text);
- return GetDimensions();
- }
- //////////////////////////////////////////////////////////////////////////////
- // PTextBlock
- PObject::Comparison PTextBlock::Compare(const PObject & obj) const
- {
- PAssert(obj.IsDescendant(PTextBlock::Class()), PInvalidCast);
- const PTextBlock & other = (const PTextBlock &)obj;
- return position != other.position || text != other.text ||
- dimensions.Width() != other.dimensions.Width() ? GreaterThan : EqualTo;
- }
- void PTextBlock::_SetDimensions(const PDim & dim)
- {
- PAssert(dim.Width() > 0, PInvalidParameter);
- if (dim.Width() != dimensions.Width()) {
- dimensions.SetWidth(dim.Width());
- dimensions.SetHeight(0);
- }
- }
- void PTextBlock::Draw(PCanvas & canvas) const
- {
- canvas = *this;
- ((PTextBlock*)this)->dimensions.SetHeight(
- canvas.MeasureString(text, dimensions.Width()));
- canvas.DrawString(position, text, dimensions.Width());
- }
- PDim PTextBlock::GetDimensions(PCanvas & canvas)
- {
- canvas = *this;
- dimensions.SetHeight(canvas.MeasureString(text, dimensions.Width()));
- return dimensions;
- }
- //////////////////////////////////////////////////////////////////////////////
- // PPolyShape
- PPolyShape::PPolyShape(const PPoint * ptArray, PINDEX numPts)
- : PShape(*ptArray)
- {
- for (PINDEX i = 0; i < numPts; i++)
- points.Append(new PPoint(ptArray[i]));
- }
- void PPolyShape::_SetPosition(const PPoint & pt)
- {
- PPoint diff = pt - position;
- for (PINDEX i = 0; i < points.GetSize(); i++)
- points[i] += diff;
- }
- PDim PPolyShape::GetDimensions() const
- {
- PPoint min, max;
- for (PINDEX i = 0; i < points.GetSize(); i++) {
- if (min.X() > points[i].X())
- min.SetX(points[i].X());
- if (max.X() < points[i].X())
- max.SetX(points[i].X());
- if (min.Y() > points[i].Y())
- min.SetY(points[i].Y());
- if (max.Y() < points[i].Y())
- max.SetY(points[i].Y());
- }
- max -= min;
- return PDim(max.X(), max.Y());
- }
- //////////////////////////////////////////////////////////////////////////////
- // PPolyLine
- void PPolyLine::Draw(PCanvas & canvas) const
- {
- canvas = *this;
- canvas.DrawPolyLine(points);
- }
- //////////////////////////////////////////////////////////////////////////////
- // PPolygon
- void PPolygon::Draw(PCanvas & canvas) const
- {
- canvas = *this;
- canvas.DrawPolygon(points);
- }
- //////////////////////////////////////////////////////////////////////////////
- // PCurve
- //////////////////////////////////////////////////////////////////////////////
- // PBezier
- void PBezier::Draw(PCanvas & canvas) const
- {
- canvas = *this;
- }
- //////////////////////////////////////////////////////////////////////////////
- // PBSpline
- void PBSpline::Draw(PCanvas & canvas) const
- {
- canvas = *this;
- }
- //////////////////////////////////////////////////////////////////////////////
- // PCompositeShape
- PCompositeShape::PCompositeShape(PShape & shape)
- : PShape(shape.GetPosition()), dimensions(shape.GetDimensions())
- {
- shapes.DisallowDeleteObjects();
- shapes.Append(&shape);
- }
- void PCompositeShape::_SetPosition(const PPoint & pt)
- {
- PPoint delta = position - pt;
- for (PINDEX i = 0; i < shapes.GetSize(); i++)
- shapes[i].Offset(delta);
- position = pt;
- }
- void PCompositeShape::Draw(PCanvas & canvas) const
- {
- for (PINDEX i = 0; i < shapes.GetSize(); i++)
- shapes[i].Draw(canvas);
- }
- void PCompositeShape::Add(PShape & shape)
- {
- shapes.Append(&shape);
- CalculateBounds();
- }
- void PCompositeShape::Remove(PShape & shape)
- {
- shapes.Remove(&shape);
- PAssert(shapes.GetSize() != 0, PInvalidParameter);
- CalculateBounds();
- }
- void PCompositeShape::Remove(PINDEX idx)
- {
- shapes.RemoveAt(idx);
- PAssert(shapes.GetSize() != 0, PInvalidParameter);
- CalculateBounds();
- }
- PShape * PCompositeShape::Find(const PPoint & pt)
- {
- for (PINDEX i = 0; i < shapes.GetSize(); i++) {
- if (shapes[i].InShape(pt))
- return &shapes[i];
- }
- return NULL;
- }
- PShape * PCompositeShape::FindPrimitive(const PPoint & pt)
- {
- for (PINDEX i = 0; i < shapes.GetSize(); i++) {
- if (shapes[i].InShape(pt)) {
- if (shapes[i].IsComposite())
- return ((PCompositeShape&)shapes[i]).FindPrimitive(pt);
- else
- return &shapes[i];
- }
- }
- return NULL;
- }
- void PCompositeShape::CalculateBounds()
- {
- position = shapes[0].GetPosition();
- PPoint otherCorner = position + shapes[0].GetDimensions();
- for (PINDEX i = 1; i < shapes.GetSize(); i++) {
- PPoint p = shapes[i].GetPosition();
- if (position.X() > p.X())
- position.SetX(p.X());
- if (position.Y() > p.Y())
- position.SetY(p.Y());
- p += shapes[i].GetDimensions();
- if (otherCorner.X() > p.X())
- otherCorner.SetX(p.X());
- if (otherCorner.Y() > p.Y())
- otherCorner.SetY(p.Y());
- }
- otherCorner -= position;
- PAssert(otherCorner.X() > 0 && otherCorner.Y() > 0, PInvalidParameter);
- dimensions = PDim(otherCorner.X(), otherCorner.Y());
- }
- #undef new
- // End Of File ///////////////////////////////////////////////////////////////