home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / Utilities / AltPoint.cpp next >
Encoding:
C/C++ Source or Header  |  1996-04-22  |  11.6 KB  |  537 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        AltPoint.cpp
  3.  
  4.     Contains:    Alternate ODPoint, ODRect (C++ savvy)
  5.  
  6.     Owned by:    Jens Alfke
  7.  
  8.     Copyright:    © 1993 - 1995 by Apple Computer, Inc., all rights reserved.
  9.  
  10. */
  11.  
  12. #ifndef _ALTPOINT_
  13. #include "AltPoint.h"
  14. #endif
  15.  
  16. #ifndef SOM_Module_OpenDoc_Global_Types_defined
  17. #include "ODTypesM.xh"
  18. #endif
  19.  
  20. #ifndef _EXCEPT_
  21. #include "Except.h"
  22. #endif
  23.  
  24. #ifndef _ODDEBUG_
  25. #include "ODDebug.h"
  26. #endif
  27.  
  28. #ifndef _LINEOPS_
  29. #include "LineOps.h"        /* For kFixedEpsilon */
  30. #endif
  31.  
  32. #include <string.h>
  33.  
  34.  
  35. #ifdef _PLATFORM_MACINTOSH_
  36.     #ifndef __GXMATH__
  37.     #include <GXMath.h>
  38.     #endif
  39. #endif
  40.  
  41. #ifndef _ODDEBUG_
  42. #include "ODDebug.h"
  43. #endif
  44.  
  45. #pragma segment ODShape
  46.  
  47.  
  48. //==============================================================================
  49. // ODPoint
  50. //==============================================================================
  51.  
  52.  
  53. #ifdef _PLATFORM_MACINTOSH_
  54. ODPoint::ODPoint( Point qdpt )
  55. {
  56.     x = IntToFixed(qdpt.h);
  57.     y = IntToFixed(qdpt.v);
  58. }
  59. #endif
  60.  
  61.  
  62. ODPoint::ODPoint( const ODPoint &pt )
  63. {
  64.     x = pt.x;
  65.     y = pt.y;
  66. }
  67.  
  68.  
  69. ODPoint& ODPoint::operator= ( const ODPoint &pt )
  70. {
  71.     x = pt.x;
  72.     y = pt.y;
  73.     return *this;
  74. }
  75.  
  76.  
  77. #ifdef _PLATFORM_MACINTOSH_
  78. ODPoint& ODPoint::operator= ( const Point &pt )
  79. {
  80.     x = IntToFixed(pt.h);
  81.     y = IntToFixed(pt.v);
  82.     return *this;
  83. }
  84. #endif
  85.  
  86.  
  87. void ODPoint::Offset ( ODCoordinate xx, ODCoordinate yy )
  88. {
  89.     x += xx;
  90.     y += yy;
  91. }
  92.  
  93.  
  94. void ODPoint::operator+= ( const ODPoint &pt )
  95. {
  96.     x += pt.x;
  97.     y += pt.y;
  98. }
  99.  
  100.  
  101. void ODPoint::operator-= ( const ODPoint &pt )
  102. {
  103.     x -= pt.x;
  104.     y -= pt.y;
  105. }
  106.  
  107.  
  108. #ifdef _PLATFORM_MACINTOSH_
  109. void ODPoint::operator+= ( const Point &pt )
  110. {
  111.     x += IntToFixed(pt.h);
  112.     y += IntToFixed(pt.v);
  113. }
  114.  
  115.  
  116. void ODPoint::operator-= ( const Point &pt )
  117. {
  118.     x -= IntToFixed(pt.h);
  119.     y -= IntToFixed(pt.v);
  120. }
  121.  
  122. Point
  123. ODPoint::AsQDPoint( ) const
  124. {
  125.     Point pt;
  126.     pt.h = FixedToInt(x);
  127.     pt.v = FixedToInt(y);
  128.     return pt;
  129. }
  130. #endif
  131.  
  132.  
  133. ODSShort
  134. ODPoint::IntX( ) const
  135. {
  136.     return FixedToInt(x);
  137. }
  138.  
  139.  
  140. ODSShort
  141. ODPoint::IntY( ) const
  142. {
  143.     return FixedToInt(y);
  144. }
  145.  
  146.  
  147. ODBoolean
  148. ODPoint::operator==( const ODPoint &pt ) const
  149. {
  150.     return x==pt.x && y==pt.y;
  151. }
  152.  
  153.  
  154. ODBoolean
  155. ODPoint::operator!=( const ODPoint &pt ) const
  156. {
  157.     return x!=pt.x || y!=pt.y;
  158. }
  159.  
  160.  
  161. ODBoolean
  162. ODPoint::ApproxEquals( const ODPoint& pt ) const
  163. {
  164.     ODFixed delta;
  165.     delta = x-pt.x;
  166.     if( delta>kFixedEpsilon || delta<-kFixedEpsilon )
  167.         return kODFalse;
  168.     delta = y-pt.y;
  169.     if( delta>kFixedEpsilon || delta<-kFixedEpsilon )
  170.         return kODFalse;
  171.     return kODTrue;
  172. }
  173.  
  174.  
  175. //==============================================================================
  176. // ODRect
  177. //==============================================================================
  178.  
  179.  
  180. #pragma segment ODShape
  181.  
  182.  
  183. #define ASSERTVALID()        WASSERT(right>=left && bottom>=top)
  184.  
  185.  
  186. //------------------------------------------------------------------------------
  187. // ::ODRect( corner1, corner2 )
  188. //
  189. // Construct a rectangle given two opposite corners (not necessarily topLeft,botRight)
  190. //------------------------------------------------------------------------------
  191.  
  192. ODRect::ODRect( const ODPoint &a, const ODPoint &b )
  193. {
  194.     this->Set(a,b);
  195. }
  196.  
  197.  
  198. //------------------------------------------------------------------------------
  199. // ::ODRect( topLeft, width, height )
  200. //
  201. // Construct a rectangle given its origin, width and height.
  202. //------------------------------------------------------------------------------
  203.  
  204. ODRect::ODRect( const ODPoint &topLeft, ODCoordinate width, ODCoordinate height )
  205. {
  206.     WASSERT(width>=0);
  207.     WASSERT(height>=0);
  208.     
  209.     left = topLeft.x;        right = topLeft.x + width;
  210.     top  = topLeft.y;        bottom= topLeft.y + height;
  211. }
  212.  
  213.  
  214. #ifdef _PLATFORM_MACINTOSH_
  215. //------------------------------------------------------------------------------
  216. // ::ODRect( Rect )
  217. //
  218. // Construct an ODRect from a QuickDraw Rect
  219. //------------------------------------------------------------------------------
  220.  
  221. ODRect::ODRect( const Rect &r )
  222. {
  223.     left = ff(r.left);        right = ff(r.right);
  224.     top  = ff(r.top);        bottom= ff(r.bottom);
  225. }
  226.  
  227.  
  228. //------------------------------------------------------------------------------
  229. // ::= Rect
  230. //
  231. // Set an ODRect from a QuickDraw Rect
  232. //------------------------------------------------------------------------------
  233.  
  234. ODRect&
  235. ODRect:: operator= ( const Rect &r )
  236. {
  237.     left = ff(r.left);        right = ff(r.right);
  238.     top  = ff(r.top);        bottom= ff(r.bottom);
  239.     ASSERTVALID();
  240.     return *this;
  241. }
  242. #endif
  243.  
  244.  
  245. //------------------------------------------------------------------------------
  246. // ::Set
  247. //
  248. // Set all four coordinates of a rectangle. Warn if the resulting rect is bogus.
  249. //------------------------------------------------------------------------------
  250.  
  251. void
  252. ODRect::Set( ODCoordinate l, ODCoordinate t, ODCoordinate r, ODCoordinate b )
  253. {
  254.     left = l;                right = r;
  255.     top  = t;                bottom= b;
  256.     ASSERTVALID();
  257. }
  258.  
  259.  
  260. //------------------------------------------------------------------------------
  261. // ::Set
  262. //
  263. // Set all four coordinates of a rectangle. Warn if the resulting rect is bogus.
  264. //------------------------------------------------------------------------------
  265.  
  266. void
  267. ODRect::Set( const ODPoint &origin, ODCoordinate width, ODCoordinate height )
  268. {
  269.     WASSERT(width>=0);
  270.     WASSERT(height>=0);
  271.     left = origin.x;                right = left+width;
  272.     top  = origin.y;                bottom= top +height;
  273. }
  274.  
  275.  
  276. //------------------------------------------------------------------------------
  277. // ::Set
  278. //
  279. // Construct a rectangle given two opposite corners (not necessarily topLeft,botRight)
  280. //------------------------------------------------------------------------------
  281.  
  282. void
  283. ODRect::Set( const ODPoint &a, const ODPoint &b )
  284. {
  285.     if( a.x<b.x ) {
  286.         left = a.x;
  287.         right= b.x;
  288.     } else {
  289.         left = b.x;
  290.         right= a.x;
  291.     }
  292.     if( a.y<b.y ) {
  293.         top   = a.y;
  294.         bottom= b.y;
  295.     } else {
  296.         top   = b.y;
  297.         bottom= a.y;
  298.     }
  299. }
  300.  
  301.  
  302. //------------------------------------------------------------------------------
  303. // ::SetInt
  304. //
  305. // Set coordinates of a rectangle from integers. Warn if the resulting rect is bogus.
  306. //------------------------------------------------------------------------------
  307.  
  308. void
  309. ODRect::SetInt( short l, short t, short r, short b )
  310. {
  311.     left = ff(l);            right = ff(r);
  312.     top  = ff(t);            bottom= ff(b);
  313.     ASSERTVALID();
  314. }
  315.  
  316.  
  317. //------------------------------------------------------------------------------
  318. // ::Offset
  319. //
  320. // Move a rectangle.
  321. //------------------------------------------------------------------------------
  322.  
  323. void
  324. ODRect::Offset( ODCoordinate x, ODCoordinate y )
  325. {
  326.     left += x;                right += x;
  327.     top  += y;                bottom+= y;
  328. }
  329.  
  330. void
  331. ODRect::Offset( const ODPoint &pt )
  332. {
  333.     left += pt.x;            right += pt.x;
  334.     top  += pt.y;            bottom+= pt.y;
  335. }
  336.  
  337.  
  338. //------------------------------------------------------------------------------
  339. // ::Inset
  340. //
  341. // Inset the edges of a rectangle, without collapsing to negative dimensions.
  342. //------------------------------------------------------------------------------
  343.  
  344. void
  345. ODRect::Inset( ODCoordinate x, ODCoordinate y )
  346. {
  347.     left += x;
  348.     right = Max(left,right-x);
  349.     top += y;
  350.     bottom = Max(top,bottom-y);
  351. }
  352.  
  353.  
  354. //------------------------------------------------------------------------------
  355. // ::Clear
  356. //
  357. // Zero all coordinates
  358. //------------------------------------------------------------------------------
  359.  
  360. void
  361. ODRect::Clear( )
  362. {
  363.     left = right = top = bottom = 0;
  364. }
  365.  
  366.  
  367. //------------------------------------------------------------------------------
  368. // :: &=
  369. //
  370. // Intersect me with another rectangle (result stored in me)
  371. //------------------------------------------------------------------------------
  372.  
  373. void
  374. ODRect:: operator&= ( const ODRect &r )
  375. {
  376.     left = Max(left,r.left);    right = Min(right, r.right);
  377.     top  = Max(top, r.top);        bottom= Min(bottom,r.bottom);
  378.     if( this->IsEmpty() )
  379.         this->Clear();
  380. }
  381.  
  382.  
  383. //------------------------------------------------------------------------------
  384. // :: |=
  385. //
  386. // Union me with another rectangle (result stored in me)
  387. //------------------------------------------------------------------------------
  388.  
  389. void
  390. ODRect:: operator|= ( const ODRect &r )
  391. {
  392.     if( this->IsEmpty() )
  393.         *this = r;
  394.     else if( !r.IsEmpty() ) {
  395.         left = Min(left,r.left);
  396.         right= Max(right,r.right);
  397.         top  = Min(top,r.top);
  398.         bottom=Max(bottom,r.bottom);
  399.     }
  400. }
  401.  
  402.  
  403. //------------------------------------------------------------------------------
  404. // :: |= ODPoint
  405. //
  406. // Union me with a point (expand to fit point)
  407. //------------------------------------------------------------------------------
  408.  
  409. void
  410. ODRect:: operator|= ( const ODPoint &pt )
  411. {
  412.     left = Min(left,pt.x);
  413.     right= Max(right,pt.x);
  414.     top  = Min(top,pt.y);
  415.     bottom=Max(bottom,pt.y);
  416. }
  417.  
  418.  
  419. #ifdef _PLATFORM_MACINTOSH_
  420. //------------------------------------------------------------------------------
  421. // :: AsQDRect
  422. //
  423. // Turn me into a QuickDraw rect
  424. //------------------------------------------------------------------------------
  425.  
  426. void
  427. ODRect::AsQDRect( Rect &r ) const
  428. {
  429.     SetRect(&r, FixedToInt(left), FixedToInt(top), FixedToInt(right), FixedToInt(bottom));
  430. }
  431. #endif
  432.  
  433.  
  434. //------------------------------------------------------------------------------
  435. // :: IsEmpty
  436. //
  437. // Do I have no area?
  438. //------------------------------------------------------------------------------
  439.  
  440. Boolean
  441. ODRect::IsEmpty( ) const
  442. {
  443.     return right<=left || bottom<=top;
  444. }
  445.  
  446.  
  447. //------------------------------------------------------------------------------
  448. // :: Contains( Point )
  449. //
  450. // Do I contain a point? (Remember, I don't contain my right and bottom edges.)
  451. //------------------------------------------------------------------------------
  452.  
  453. Boolean
  454. ODRect::Contains( const ODPoint &pt ) const
  455. {
  456.     return left<=pt.x && pt.x<right
  457.         && top <=pt.y && pt.y<bottom;
  458. }
  459.  
  460.  
  461. //------------------------------------------------------------------------------
  462. // :: Contains( Rect )
  463. //
  464. // Do I contain an entire rect?
  465. //------------------------------------------------------------------------------
  466.  
  467. Boolean
  468. ODRect::Contains( const ODRect &r ) const
  469. {
  470.     if( r.right<=r.left || r.bottom<=r.top )
  471.         return kODTrue;                    // Empty rect contained in anything
  472.     else
  473.         return left<=r.left && r.right<=right
  474.             && top <=r.top  && r.bottom<=bottom;
  475. }
  476.  
  477.  
  478. //------------------------------------------------------------------------------
  479. // :: ApproxContains( Rect )
  480. //
  481. // Do I approximately (within epsilon) contain an entire rect?
  482. //------------------------------------------------------------------------------
  483.  
  484. Boolean
  485. ODRect::ApproxContains( const ODRect &r ) const
  486. {
  487.     if( r.right<=r.left || r.bottom<=r.top )
  488.         return kODTrue;                    // Empty rect contained in anything
  489.     else
  490.         return left-kFixedEpsilon<=r.left && r.right<=right+kFixedEpsilon
  491.             && top-kFixedEpsilon <=r.top  && r.bottom<=bottom+kFixedEpsilon;
  492. }
  493.  
  494.  
  495. //------------------------------------------------------------------------------
  496. // :: ==
  497. //
  498. // Am I equal to another rect?
  499. //------------------------------------------------------------------------------
  500.  
  501. Boolean
  502. ODRect::operator==( const ODRect &r ) const
  503. {
  504.     return memcmp(this,&r,sizeof(ODRect)) == 0;
  505. }
  506.  
  507.  
  508. //------------------------------------------------------------------------------
  509. // :: ApproxEquals
  510. //
  511. // Am I approximately equal (within epsilon) to another rect?
  512. //------------------------------------------------------------------------------
  513.  
  514. ODBoolean
  515. ODRect::ApproxEquals( const ODRect &r ) const
  516. {
  517.     return left-r.left<=kFixedEpsilon     && left-r.left>=-kFixedEpsilon
  518.         && right-r.right<=kFixedEpsilon   && right-r.right>=-kFixedEpsilon
  519.         && top-r.top<=kFixedEpsilon       && top-r.top>=-kFixedEpsilon
  520.         && bottom-r.bottom<=kFixedEpsilon && bottom-r.bottom>=-kFixedEpsilon;
  521. }
  522.  
  523.  
  524. //------------------------------------------------------------------------------
  525. // :: Intersects
  526. //
  527. // Do I intersect another rectangle?
  528. // (Remember, I don't contain my right and bottom edges.)
  529. //------------------------------------------------------------------------------
  530.  
  531. Boolean
  532. ODRect::Intersects( const ODRect &r ) const
  533. {
  534.     return Max(left,r.left) < Min(right,r.right)
  535.         && Max(top,r.top) < Min(bottom,r.bottom);
  536. }
  537.