home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / OS / FWGraphx / Sources / FWPolySh.cpp < prev    next >
Encoding:
Text File  |  1995-11-08  |  10.5 KB  |  379 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWPolySh.cpp
  4. //    Release Version:    $ 1.0d11 $
  5. //
  6. //    Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef FWPOLYSH_H
  13. #include "FWPolySh.h"
  14. #endif
  15.  
  16. #ifndef FWGRGLOB_H
  17. #include "FWGrGlob.h"
  18. #endif
  19.  
  20. #ifndef FWGRUTIL_H
  21. #include "FWGrUtil.h"
  22. #endif
  23.  
  24. #ifndef FWGC_H
  25. #include "FWGC.h"
  26. #endif
  27.  
  28. #ifndef FWINK_H
  29. #include "FWInk.h"
  30. #endif
  31.  
  32. #ifndef FWSTYLE_H
  33. #include "FWStyle.h"
  34. #endif
  35.  
  36. #ifndef FWRASTER_H
  37. #include "FWRaster.h"
  38. #endif
  39.  
  40. #ifndef FWPOLY_H
  41. #include "FWPoly.h"
  42. #endif
  43.  
  44. // ----- Foundation Includes -----
  45.  
  46. #ifndef FWSTREAM_H
  47. #include "FWStream.h"
  48. #endif
  49.  
  50. // ----- OpenDoc Includes -----
  51.  
  52. #ifndef _TRANSFORM_
  53. #include <Trnsform.xh>
  54. #endif
  55.  
  56. //========================================================================================
  57. //    RunTime Info
  58. //========================================================================================
  59.  
  60. #if FW_LIB_EXPORT_PRAGMAS
  61. #pragma lib_export on
  62. #endif
  63.  
  64. #ifdef FW_BUILD_MAC
  65. #pragma segment FWGraphx_PolygonShape
  66. #endif
  67.  
  68. FW_DEFINE_CLASS_M1(FW_CPolygonShape, FW_CShape)
  69. FW_REGISTER_ARCHIVABLE_CLASS(FW_LPolygonShape, FW_CPolygonShape, FW_CPolygonShape::Read, FW_CShape::Write)
  70.  
  71. //========================================================================================
  72. //    Polygon hit-testing functions
  73. //========================================================================================
  74.  
  75. static FW_CFixed XIntersect(const FW_CPoint* vtx0, const FW_CPoint* vtx1, FW_CFixed ty)
  76. {
  77.     return
  78.         vtx1->x -
  79.             FW_WideMultiply(vtx1->y - ty, vtx0->x - vtx1->x) /
  80.                 (vtx0->y - vtx1->y);
  81. }
  82.  
  83. static FW_Boolean IsPointInPolygon(unsigned long pointCount, const FW_CPoint* points, FW_CPoint point)
  84. {
  85.     FW_Boolean yFlag0, yFlag1, isInside = FALSE, xFlag0;
  86.  
  87.     FW_CFixed tx = point.x;
  88.     FW_CFixed ty = point.y;
  89.  
  90.     const FW_CPoint* vtx0 = points + pointCount - 1;
  91.     const FW_CPoint* vtx1 = points;
  92.  
  93.     yFlag0 = vtx0->y >= ty;
  94.  
  95.     for(unsigned long j = 0; j < pointCount; j ++)
  96.     {
  97.         yFlag1 = vtx1->y >= ty;
  98.  
  99.         if(yFlag1 != yFlag0)
  100.         {
  101.             xFlag0 = vtx0->x >= tx;
  102.  
  103.             if(xFlag0 == (vtx1->x >= tx))
  104.             {
  105.                 if(xFlag0)
  106.                     isInside = !isInside;
  107.             }
  108.             else
  109.             {
  110.                 if(::XIntersect(vtx0, vtx1, ty) >= tx)
  111.                     isInside = !isInside;
  112.             }
  113.         }
  114.  
  115.         yFlag0 = yFlag1;
  116.         vtx0 = vtx1;
  117.         vtx1 ++;
  118.     }
  119.  
  120.     return isInside;
  121. }
  122.  
  123. //========================================================================================
  124. //    class FW_CPolygonShape
  125. //========================================================================================
  126.  
  127. //----------------------------------------------------------------------------------------
  128. //    FW_CPolygonShape::FW_CPolygonShape
  129. //----------------------------------------------------------------------------------------
  130.  
  131. FW_CPolygonShape::FW_CPolygonShape(const FW_PPolygon& polygon,
  132.                                     FW_ERenderVerbs renderVerb,
  133.                                    FW_Boolean autoCloseFrame,
  134.                                    const FW_PInk& ink,
  135.                                    const FW_PStyle& style) :
  136.     FW_CShape(renderVerb, ink, style, FW_kNormalFont),
  137.     fPolygon(polygon),
  138.     fAutoCloseFrame(autoCloseFrame)
  139. {
  140.     FW_END_CONSTRUCTOR
  141. }
  142.  
  143. //----------------------------------------------------------------------------------------
  144. //    FW_CPolygonShape::FW_CPolygonShape
  145. //----------------------------------------------------------------------------------------
  146.  
  147. FW_CPolygonShape::FW_CPolygonShape(const FW_CPolygonShape& other) :
  148.     FW_CShape(other),
  149.     fPolygon(other.fPolygon),
  150.     fAutoCloseFrame(other.fAutoCloseFrame)
  151. {
  152.     FW_END_CONSTRUCTOR
  153. }
  154.  
  155. //----------------------------------------------------------------------------------------
  156. //    FW_CPolygonShape::FW_CPolygonShape
  157. //----------------------------------------------------------------------------------------
  158.  
  159. FW_CPolygonShape::FW_CPolygonShape(FW_CReadableStream& archive) :
  160.     FW_CShape(archive)
  161. {
  162.     archive >> fPolygon;
  163.  
  164.     FW_END_CONSTRUCTOR
  165. }
  166.  
  167. //----------------------------------------------------------------------------------------
  168. //    FW_CPolygonShape::~FW_CPolygonShape
  169. //----------------------------------------------------------------------------------------
  170.  
  171. FW_CPolygonShape::~FW_CPolygonShape()
  172. {
  173.     FW_START_DESTRUCTOR
  174. }
  175.  
  176. //----------------------------------------------------------------------------------------
  177. //    FW_CPolygonShape::operator=
  178. //----------------------------------------------------------------------------------------
  179.  
  180. FW_CPolygonShape& FW_CPolygonShape::operator=(const FW_CPolygonShape& other)
  181. {
  182.     fPolygon = other.fPolygon;
  183.     return *this;
  184. }
  185.  
  186. //----------------------------------------------------------------------------------------
  187. //    FW_CPolygonShape::SetAutoCloseFrame
  188. //----------------------------------------------------------------------------------------
  189.  
  190. void FW_CPolygonShape::SetAutoCloseFrame(FW_Boolean autoCloseFrame)
  191. {
  192.     fAutoCloseFrame = autoCloseFrame;
  193. }
  194.  
  195. //----------------------------------------------------------------------------------------
  196. //    FW_CPolygonShape::GetAutoCloseFrame
  197. //----------------------------------------------------------------------------------------
  198.  
  199. FW_Boolean FW_CPolygonShape::GetAutoCloseFrame() const
  200. {
  201.     return fAutoCloseFrame;
  202. }
  203.  
  204. //----------------------------------------------------------------------------------------
  205. //    FW_CPolygonShape::Render
  206. //----------------------------------------------------------------------------------------
  207.  
  208. void FW_CPolygonShape::Render(FW_CGraphicContext& gc) const
  209. {
  210.     gc.GetRasterizer()->RenderPolygon(
  211.         gc,
  212.         fPolygon,
  213.         GetRenderVerb(),
  214.         fAutoCloseFrame,
  215.         fInk,
  216.         fStyle);
  217. }
  218.  
  219. //----------------------------------------------------------------------------------------
  220. //    FW_CPolygonShape::HitTest
  221. //----------------------------------------------------------------------------------------
  222.  
  223. FW_Boolean FW_CPolygonShape::HitTest(FW_CGraphicContext& gc,
  224.                                      const FW_CPoint& test,
  225.                                      FW_CFixed tolerance) const
  226. {
  227. FW_UNUSED(gc);
  228.  
  229.     if(fRenderVerb == FW_kNoRendering)
  230.         return FALSE;
  231.  
  232.     // Quickly check the bounds
  233.     FW_CRect bounds;
  234.     fPolygon->GetBounds(bounds);
  235.     
  236.     bounds.Inset(-tolerance, -tolerance);
  237.  
  238.     if(bounds.Contains(test))
  239.     {
  240.         // Bounds check out OK, now do a more thourough test
  241.         unsigned long pointCount = fPolygon->GetCount();
  242.         const FW_CPoint* points = fPolygon->GetPoints();
  243.         if(fRenderVerb == FW_kFrame)
  244.         {
  245.             for(unsigned long i = 0; i < pointCount - 1; i ++)
  246.                 if(::FW_HitTestLine(points[i], points[i + 1], test, tolerance))
  247.                     return TRUE;
  248.         }
  249.         else
  250.             return ::IsPointInPolygon(pointCount, points, test);
  251.     }
  252.     
  253.     return FALSE;
  254. }
  255.  
  256. //----------------------------------------------------------------------------------------
  257. //    FW_CPolygonShape::Copy
  258. //----------------------------------------------------------------------------------------
  259.  
  260. FW_CShape* FW_CPolygonShape::Copy() const
  261. {
  262.     return FW_NEW(FW_CPolygonShape, (*this));
  263. }
  264.  
  265. //----------------------------------------------------------------------------------------
  266. //    FW_CPolygonShape::Transform
  267. //----------------------------------------------------------------------------------------
  268.  
  269. void FW_CPolygonShape::Transform(Environment *ev, ODTransform* transform)
  270. {
  271.     fPolygon->Transform(ev, transform);
  272. }
  273.  
  274. //----------------------------------------------------------------------------------------
  275. //    FW_CPolygonShape::InverseTransform
  276. //----------------------------------------------------------------------------------------
  277.  
  278. void FW_CPolygonShape::InverseTransform(Environment *ev, ODTransform* transform)
  279. {
  280.     fPolygon->InverseTransform(ev, transform);
  281. }
  282.  
  283. //----------------------------------------------------------------------------------------
  284. //    FW_CPolygonShape::MoveShape
  285. //----------------------------------------------------------------------------------------
  286.  
  287. void FW_CPolygonShape::MoveShape(FW_CFixed deltaX, FW_CFixed deltaY)
  288. {
  289.     fPolygon->Move(deltaX, deltaY);
  290. }
  291.  
  292. //----------------------------------------------------------------------------------------
  293. //    FW_CPolygonShape::MoveShapeTo
  294. //----------------------------------------------------------------------------------------
  295.  
  296. void FW_CPolygonShape::MoveShapeTo(FW_CFixed x, FW_CFixed y)
  297. {
  298.     fPolygon->MoveTo(x, y);
  299. }
  300.  
  301. //----------------------------------------------------------------------------------------
  302. //    FW_CPolygonShape::Inset
  303. //----------------------------------------------------------------------------------------
  304.  
  305. void FW_CPolygonShape::Inset(FW_CFixed x, FW_CFixed y)
  306. {
  307.     fPolygon->Inset(x, y);
  308. }
  309.     
  310. //----------------------------------------------------------------------------------------
  311. //    FW_CPolygonShape::GetBounds
  312. //----------------------------------------------------------------------------------------
  313.  
  314. void FW_CPolygonShape::GetBounds(FW_CGraphicContext& gc, FW_CRect& rect) const
  315. {
  316. FW_UNUSED(gc);
  317.  
  318.     fPolygon->GetBounds(rect);
  319. }
  320.  
  321. //----------------------------------------------------------------------------------------
  322. //    FW_CPolygonShape::Flatten
  323. //----------------------------------------------------------------------------------------
  324.  
  325. void FW_CPolygonShape::Flatten(FW_CWritableStream& archive) const
  326. {
  327.     FW_CShape::Flatten(archive);
  328.     
  329.     archive << fPolygon;
  330. }
  331.  
  332. //----------------------------------------------------------------------------------------
  333. //    FW_CPolygonShape::RenderPolygon
  334. //----------------------------------------------------------------------------------------
  335.  
  336. void FW_CPolygonShape::RenderPolygon(FW_CGraphicContext& gc,
  337.                                          const FW_PPolygon& polygon,
  338.                                          FW_ERenderVerbs renderVerb,
  339.                                      FW_Boolean autoCloseFrame,
  340.                                      const FW_PInk& ink,
  341.                                          const FW_PStyle& style)
  342. {
  343.     gc.GetRasterizer()->RenderPolygon(
  344.         gc,
  345.         polygon,
  346.         renderVerb,
  347.         autoCloseFrame,
  348.         ink,
  349.         style);
  350. }
  351.  
  352. //----------------------------------------------------------------------------------------
  353. //    FW_CPolygonShape::Read
  354. //----------------------------------------------------------------------------------------
  355.  
  356. void* FW_CPolygonShape::Read(FW_CReadableStream& archive)
  357. {
  358.     return FW_NEW(FW_CPolygonShape, (archive));
  359. }
  360.  
  361. //----------------------------------------------------------------------------------------
  362. //    FW_CPolygonShape::GetGeometry
  363. //----------------------------------------------------------------------------------------
  364.  
  365. void FW_CPolygonShape::GetGeometry(FW_PPolygon& polygon) const
  366. {
  367.     polygon = fPolygon;
  368. }
  369.  
  370. //----------------------------------------------------------------------------------------
  371. //    FW_CPolygonShape::SetGeometry
  372. //----------------------------------------------------------------------------------------
  373.  
  374. void FW_CPolygonShape::SetGeometry(const FW_PPolygon& polygon)
  375. {
  376.     fPolygon = polygon;
  377. }
  378.  
  379.