home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / odtlktv4.zip / ODTLKT / TOOLKIT / BETA / SAMPLES / OPENDOC / PUBUTILS / ALTPOINT.CPP next >
Text File  |  1995-11-08  |  15KB  |  568 lines

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