shapes.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:13k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * shapes.cxx
  3.  *
  4.  * Geometric shapes.
  5.  *
  6.  * Portable Windows Library
  7.  *
  8.  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
  9.  *
  10.  * The contents of this file are subject to the Mozilla Public License
  11.  * Version 1.0 (the "License"); you may not use this file except in
  12.  * compliance with the License. You may obtain a copy of the License at
  13.  * http://www.mozilla.org/MPL/
  14.  *
  15.  * Software distributed under the License is distributed on an "AS IS"
  16.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  17.  * the License for the specific language governing rights and limitations
  18.  * under the License.
  19.  *
  20.  * The Original Code is Portable Windows Library.
  21.  *
  22.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  23.  *
  24.  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
  25.  * All Rights Reserved.
  26.  *
  27.  * Contributor(s): ______________________________________.
  28.  *
  29.  * $Log: shapes.cxx,v $
  30.  * Revision 1.12  1999/08/17 03:46:41  robertj
  31.  * Fixed usage of inlines in optimised version.
  32.  *
  33.  * Revision 1.11  1998/12/20 09:14:44  robertj
  34.  * Added pragma implementation for GNU compiler.
  35.  *
  36.  * Revision 1.10  1998/11/30 04:52:17  robertj
  37.  * New directory structure
  38.  *
  39.  * Revision 1.9  1998/09/23 06:29:55  robertj
  40.  * Added open source copyright license.
  41.  *
  42.  * Revision 1.8  1997/04/27 05:50:24  robertj
  43.  * DLL support.
  44.  *
  45.  * Revision 1.7  1996/08/08 10:08:50  robertj
  46.  * Directory structure changes for common files.
  47.  *
  48.  * Revision 1.6  1996/01/28 02:52:08  robertj
  49.  * Added assert into all Compare functions to assure comparison between compatible objects.
  50.  *
  51.  * Revision 1.5  1995/01/21 05:22:36  robertj
  52.  * Documentation.
  53.  *
  54.  * Revision 1.4  1994/10/23  03:38:06  robertj
  55.  * Changed PPixels to pointer to get polymorphism.
  56.  *
  57.  * Revision 1.3  1994/08/01  03:41:24  robertj
  58.  * Use of PNEW instead of new for heap debugging. Need undef for Unix end.
  59.  *
  60.  * Revision 1.2  1994/07/27  05:58:07  robertj
  61.  * Synchronisation.
  62.  *
  63.  * Revision 1.1  1994/04/20  12:17:44  robertj
  64.  * Initial revision
  65.  *
  66.  */
  67. #ifdef __GNUC__
  68. #pragma implementation "shapes.h"
  69. #endif
  70. #include <pwlib.h>
  71. #include <pwclib/shapes.h>
  72. #if !P_USE_INLINES
  73. #include <pwclib/shapes.inl>
  74. #endif
  75. #define new PNEW
  76. //////////////////////////////////////////////////////////////////////////////
  77. // PShape
  78. void PShape::_SetPosition(const PPoint & pt)
  79. {
  80.   position = pt;
  81. }
  82. void PShape::_SetDimensions(const PDim &)
  83. {
  84.   // Do nothing
  85. }
  86. BOOL PShape::InShape(const PPoint & pt) const
  87. {
  88.   return GetBounds().ContainsPoint(pt);
  89. }
  90. BOOL PShape::IsComposite() const
  91. {
  92.   return FALSE;
  93. }
  94. //////////////////////////////////////////////////////////////////////////////
  95. // PLine
  96. PObject::Comparison PLine::Compare(const PObject & obj) const
  97. {
  98.   PAssert(obj.IsDescendant(PLine::Class()), PInvalidCast);
  99.   const PLine & other = (const PLine &)obj;
  100.   return position != other.position || otherEnd != other.otherEnd
  101.                                                       ? GreaterThan : EqualTo;
  102. }
  103. PDim PLine::GetDimensions() const
  104. {
  105.   PPoint d = position - otherEnd;
  106.   return PDim(PABS(d.X()), PABS(d.Y()));
  107. }
  108. BOOL PLine::InShape(const PPoint &) const
  109. {
  110.   return FALSE;
  111. }
  112. void PLine::Draw(PCanvas & canvas) const
  113. {
  114.   canvas = *this;
  115.   canvas.DrawLine(position, otherEnd);
  116. }
  117. //////////////////////////////////////////////////////////////////////////////
  118. // POrthoShape
  119. POrthoShape::POrthoShape(const PPoint & topLeft, const PPoint & botRight)
  120.   : PShape(PMIN(topLeft.X(), botRight.X()), PMIN(topLeft.Y(), botRight.Y())),
  121.     dimensions(PABS(topLeft.X()-botRight.X()), PABS(topLeft.Y()-botRight.Y()))
  122. {
  123. }
  124. PObject::Comparison POrthoShape::Compare(const PObject & obj) const
  125. {
  126.   PAssert(obj.IsDescendant(POrthoShape::Class()), PInvalidCast);
  127.   const POrthoShape & other = (const POrthoShape &)obj;
  128.   if (dimensions != other.dimensions)
  129.     return GreaterThan;
  130.   return position != other.position ? LessThan : EqualTo;
  131. }
  132. PDim POrthoShape::GetDimensions() const
  133. {
  134.   return dimensions;
  135. }
  136. void POrthoShape::_SetDimensions(const PDim & dim)
  137. {
  138.   dimensions = dim;
  139. }
  140. //////////////////////////////////////////////////////////////////////////////
  141. // PRectangle
  142. void PRectangle::Draw(PCanvas & canvas) const
  143. {
  144.   canvas = *this;
  145.   canvas.DrawRect(position, dimensions);
  146. }
  147. //////////////////////////////////////////////////////////////////////////////
  148. // PRoundedRectangle
  149. PObject::Comparison PRoundedRectangle::Compare(const PObject & obj) const
  150. {
  151.   PAssert(obj.IsDescendant(PRoundedRectangle::Class()), PInvalidCast);
  152.   const PRoundedRectangle & other = (const PRoundedRectangle &)obj;
  153.   return position != other.position || dimensions != other.dimensions ||
  154.                                corner != other.corner ? GreaterThan : EqualTo;
  155. }
  156. void PRoundedRectangle::Draw(PCanvas & canvas) const
  157. {
  158.   canvas = *this;
  159.   canvas.DrawRoundRect(PRect(position, dimensions),
  160.                                             corner.Width(), corner.Height());
  161. }
  162. //////////////////////////////////////////////////////////////////////////////
  163. // PEllipse
  164. void PEllipse::Draw(PCanvas & canvas) const
  165. {
  166.   canvas = *this;
  167.   canvas.DrawEllipse(PRect(position, dimensions));
  168. }
  169. //////////////////////////////////////////////////////////////////////////////
  170. // PArc
  171. PObject::Comparison PArc::Compare(const PObject & obj) const
  172. {
  173.   PAssert(obj.IsDescendant(PArc::Class()), PInvalidCast);
  174.   const PArc & other = (const PArc &)obj;
  175.   return position != other.position || dimensions != other.dimensions ||
  176.          startAngle != other.startAngle || endAngle != other.endAngle
  177.                                                       ? GreaterThan : EqualTo;
  178. }
  179. void PArc::Draw(PCanvas & canvas) const
  180. {
  181.   canvas = *this;
  182.   canvas.DrawArc(PRect(position, dimensions), startAngle, endAngle);
  183. }
  184. //////////////////////////////////////////////////////////////////////////////
  185. // PPie
  186. void PPie::Draw(PCanvas & canvas) const
  187. {
  188.   canvas = *this;
  189.   canvas.DrawPie(PRect(position, dimensions), startAngle, endAngle);
  190. }
  191. //////////////////////////////////////////////////////////////////////////////
  192. // PChord
  193. void PChord::Draw(PCanvas & canvas) const
  194. {
  195.   canvas = *this;
  196.   canvas.DrawChord(PRect(position, dimensions), startAngle, endAngle);
  197. }
  198. //////////////////////////////////////////////////////////////////////////////
  199. // PPixShape
  200. PPixShape::PPixShape(PORDINATE x, PORDINATE y, const PPixelImage & pix)
  201.   : POrthoShape(x, y, pix->Width(), pix->Height())
  202. {
  203.   pixels = pix;
  204. }
  205. PPixShape::PPixShape(const PPoint & pt, const PPixelImage & pix)
  206.   : POrthoShape(pt, pix->GetDimensions())
  207. {
  208.   pixels = pix;
  209. }
  210. void PPixShape::Draw(PCanvas & canvas) const
  211. {
  212.   canvas = *this;
  213.   canvas.DrawPixels(PRect(position, dimensions), pixels);
  214. }
  215. //////////////////////////////////////////////////////////////////////////////
  216. // PPicShape
  217. PPicShape::PPicShape(PORDINATE x, PORDINATE y, const PPictImage & pic)
  218.   : POrthoShape(x, y, pic->Width(), pic->Height())
  219. {
  220.   picture = pic;
  221. }
  222. PPicShape::PPicShape(const PPoint & pt, const PPictImage & pic)
  223.   : POrthoShape(pt, pic->GetDimensions())
  224. {
  225.   picture = pic;
  226. }
  227. void PPicShape::Draw(PCanvas & canvas) const
  228. {
  229.   canvas = *this;
  230.   canvas.DrawPict(PRect(position, dimensions), picture);
  231. }
  232. //////////////////////////////////////////////////////////////////////////////
  233. // PTextLines
  234. PObject::Comparison PTextLines::Compare(const PObject & obj) const
  235. {
  236.   PAssert(obj.IsDescendant(PTextLines::Class()), PInvalidCast);
  237.   const PTextLines & other = (const PTextLines &)obj;
  238.   return position != other.position || text != other.text
  239.                                                       ? GreaterThan : EqualTo;
  240. }
  241. PDim PTextLines::GetDimensions() const
  242. {
  243.   PAssert(dimensions.Width() != 0 && dimensions.Height() != 0, PInvalidParameter);
  244.   return dimensions;
  245. }
  246. void PTextLines::Draw(PCanvas & canvas) const
  247. {
  248.   canvas = *this;
  249.   ((PTextLines*)this)->dimensions = canvas.MeasureString(text);
  250.   canvas.DrawString(position, text);
  251. }
  252. void PTextLines::SetText(const PString & str)
  253. {
  254.   text = str;
  255.   dimensions.SetHeight(0); // Needs to be recalculated
  256. }
  257. PDim PTextLines::GetDimensions(PCanvas & canvas)
  258. {
  259.   canvas = *this;
  260.   dimensions = canvas.MeasureString(text);
  261.   return GetDimensions();
  262. }
  263. //////////////////////////////////////////////////////////////////////////////
  264. // PTextBlock
  265. PObject::Comparison PTextBlock::Compare(const PObject & obj) const
  266. {
  267.   PAssert(obj.IsDescendant(PTextBlock::Class()), PInvalidCast);
  268.   const PTextBlock & other = (const PTextBlock &)obj;
  269.   return position != other.position || text != other.text ||
  270.        dimensions.Width() != other.dimensions.Width() ? GreaterThan : EqualTo;
  271. }
  272. void PTextBlock::_SetDimensions(const PDim & dim)
  273. {
  274.   PAssert(dim.Width() > 0, PInvalidParameter);
  275.   if (dim.Width() != dimensions.Width()) {
  276.     dimensions.SetWidth(dim.Width());
  277.     dimensions.SetHeight(0);
  278.   }
  279. }
  280. void PTextBlock::Draw(PCanvas & canvas) const
  281. {
  282.   canvas = *this;
  283.   ((PTextBlock*)this)->dimensions.SetHeight(
  284.                               canvas.MeasureString(text, dimensions.Width()));
  285.   canvas.DrawString(position, text, dimensions.Width());
  286. }
  287. PDim PTextBlock::GetDimensions(PCanvas & canvas)
  288. {
  289.   canvas = *this;
  290.   dimensions.SetHeight(canvas.MeasureString(text, dimensions.Width()));
  291.   return dimensions;
  292. }
  293. //////////////////////////////////////////////////////////////////////////////
  294. // PPolyShape
  295. PPolyShape::PPolyShape(const PPoint * ptArray, PINDEX numPts)
  296.   : PShape(*ptArray)
  297. {
  298.   for (PINDEX i = 0; i < numPts; i++)
  299.     points.Append(new PPoint(ptArray[i]));
  300. }
  301. void PPolyShape::_SetPosition(const PPoint & pt)
  302. {
  303.   PPoint diff = pt - position;
  304.   for (PINDEX i = 0; i < points.GetSize(); i++)
  305.     points[i] += diff;
  306. }
  307. PDim PPolyShape::GetDimensions() const
  308. {
  309.   PPoint min, max;
  310.   for (PINDEX i = 0; i < points.GetSize(); i++) {
  311.     if (min.X() > points[i].X())
  312.       min.SetX(points[i].X());
  313.     if (max.X() < points[i].X())
  314.       max.SetX(points[i].X());
  315.     if (min.Y() > points[i].Y())
  316.       min.SetY(points[i].Y());
  317.     if (max.Y() < points[i].Y())
  318.       max.SetY(points[i].Y());
  319.   }
  320.   max -= min;
  321.   return PDim(max.X(), max.Y());
  322. }
  323. //////////////////////////////////////////////////////////////////////////////
  324. // PPolyLine
  325. void PPolyLine::Draw(PCanvas & canvas) const
  326. {
  327.   canvas = *this;
  328.   canvas.DrawPolyLine(points);
  329. }
  330. //////////////////////////////////////////////////////////////////////////////
  331. // PPolygon
  332. void PPolygon::Draw(PCanvas & canvas) const
  333. {
  334.   canvas = *this;
  335.   canvas.DrawPolygon(points);
  336. }
  337. //////////////////////////////////////////////////////////////////////////////
  338. // PCurve
  339. //////////////////////////////////////////////////////////////////////////////
  340. // PBezier
  341. void PBezier::Draw(PCanvas & canvas) const
  342. {
  343.   canvas = *this;
  344. }
  345. //////////////////////////////////////////////////////////////////////////////
  346. // PBSpline
  347. void PBSpline::Draw(PCanvas & canvas) const
  348. {
  349.   canvas = *this;
  350. }
  351. //////////////////////////////////////////////////////////////////////////////
  352. // PCompositeShape
  353. PCompositeShape::PCompositeShape(PShape & shape)
  354.   : PShape(shape.GetPosition()), dimensions(shape.GetDimensions())
  355. {
  356.   shapes.DisallowDeleteObjects();
  357.   shapes.Append(&shape);
  358. }
  359. void PCompositeShape::_SetPosition(const PPoint & pt)
  360. {
  361.   PPoint delta = position - pt;
  362.   for (PINDEX i = 0; i < shapes.GetSize(); i++)
  363.     shapes[i].Offset(delta);
  364.   position = pt;
  365. }
  366. void PCompositeShape::Draw(PCanvas & canvas) const
  367. {
  368.   for (PINDEX i = 0; i < shapes.GetSize(); i++)
  369.     shapes[i].Draw(canvas);
  370. }
  371. void PCompositeShape::Add(PShape & shape)
  372. {
  373.   shapes.Append(&shape);
  374.   CalculateBounds();
  375. }
  376. void PCompositeShape::Remove(PShape & shape)
  377. {
  378.   shapes.Remove(&shape);
  379.   PAssert(shapes.GetSize() != 0, PInvalidParameter);
  380.   CalculateBounds();
  381. }
  382. void PCompositeShape::Remove(PINDEX idx)
  383. {
  384.   shapes.RemoveAt(idx);
  385.   PAssert(shapes.GetSize() != 0, PInvalidParameter);
  386.   CalculateBounds();
  387. }
  388. PShape * PCompositeShape::Find(const PPoint & pt)
  389. {
  390.   for (PINDEX i = 0; i < shapes.GetSize(); i++) {
  391.     if (shapes[i].InShape(pt))
  392.       return &shapes[i];
  393.   }
  394.   return NULL;
  395. }
  396. PShape * PCompositeShape::FindPrimitive(const PPoint & pt)
  397. {
  398.   for (PINDEX i = 0; i < shapes.GetSize(); i++) {
  399.     if (shapes[i].InShape(pt)) {
  400.       if (shapes[i].IsComposite())
  401.         return ((PCompositeShape&)shapes[i]).FindPrimitive(pt);
  402.       else
  403.         return &shapes[i];
  404.     }
  405.   }
  406.   return NULL;
  407. }
  408. void PCompositeShape::CalculateBounds()
  409. {
  410.   position = shapes[0].GetPosition();
  411.   PPoint otherCorner = position + shapes[0].GetDimensions();
  412.   for (PINDEX i = 1; i < shapes.GetSize(); i++) {
  413.     PPoint p = shapes[i].GetPosition();
  414.     if (position.X() > p.X())
  415.       position.SetX(p.X());
  416.     if (position.Y() > p.Y())
  417.       position.SetY(p.Y());
  418.     p += shapes[i].GetDimensions();
  419.     if (otherCorner.X() > p.X())
  420.       otherCorner.SetX(p.X());
  421.     if (otherCorner.Y() > p.Y())
  422.       otherCorner.SetY(p.Y());
  423.   }
  424.   otherCorner -= position;
  425.   PAssert(otherCorner.X() > 0 && otherCorner.Y() > 0, PInvalidParameter);
  426.   dimensions = PDim(otherCorner.X(), otherCorner.Y());
  427. }
  428. #undef new
  429. // End Of File ///////////////////////////////////////////////////////////////