home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / OS / FWODMisc / FWRect.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  24.2 KB  |  798 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWRect.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:            (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef FWRECT_H
  13. #include "FWRect.h"
  14. #endif
  15.  
  16. // ----- Foundation Includes -----
  17.  
  18. #ifndef FWFXMATH_H
  19. #include "FWFxMath.h"
  20. #endif
  21.  
  22. #ifndef FWSTREAM_H
  23. #include "FWStream.h"
  24. #endif
  25.  
  26. //========================================================================================
  27. //    RunTime Info
  28. //========================================================================================
  29.  
  30. #ifdef FW_BUILD_MAC
  31. #pragma segment fwodmisc_rect
  32. #endif
  33.  
  34. //========================================================================================
  35. //    struct FW_CPlatformRect
  36. //========================================================================================
  37.  
  38. //----------------------------------------------------------------------------------------
  39. //    FW_CPlatformRect::FW_CPlatformRect
  40. //----------------------------------------------------------------------------------------
  41.  
  42. FW_CPlatformRect::FW_CPlatformRect(const FW_SRect& rect)
  43. {
  44.     left    = FW_FixedToInt(rect.left);
  45.     top        = FW_FixedToInt(rect.top);
  46.     right    = FW_FixedToInt(rect.right);
  47.     bottom    = FW_FixedToInt(rect.bottom);
  48. }
  49.  
  50. //----------------------------------------------------------------------------------------
  51. //    FW_CPlatformRect::operator =
  52. //----------------------------------------------------------------------------------------
  53.  
  54. FW_CPlatformRect& FW_CPlatformRect::operator =(const FW_SRect& rect)
  55. {
  56.     left    = FW_FixedToInt(rect.left);
  57.     top        = FW_FixedToInt(rect.top);
  58.     right    = FW_FixedToInt(rect.right);
  59.     bottom    = FW_FixedToInt(rect.bottom);
  60.     
  61.     return *this;
  62. }
  63.  
  64. //----------------------------------------------------------------------------------------
  65. //    FW_CPlatformRect::operator==
  66. //----------------------------------------------------------------------------------------
  67.  
  68. FW_Boolean FW_CPlatformRect::operator==(const FW_CPlatformRect& rect) const
  69. {
  70.     return
  71.         left    ==    rect.left    &&
  72.         top        ==    rect.top    &&
  73.         right    ==    rect.right    &&
  74.         bottom    ==    rect.bottom;
  75. }
  76.  
  77. //----------------------------------------------------------------------------------------
  78. //    FW_CPlatformRect::operator!=
  79. //----------------------------------------------------------------------------------------
  80.  
  81. FW_Boolean FW_CPlatformRect::operator!=(const FW_CPlatformRect& rect) const
  82. {
  83.     return
  84.         left    !=    rect.left    ||
  85.         top        !=    rect.top    ||
  86.         right    !=    rect.right    ||
  87.         bottom    !=    rect.bottom;
  88. }
  89.  
  90. //----------------------------------------------------------------------------------------
  91. //    FW_CPlatformRect::TopRight
  92. //----------------------------------------------------------------------------------------
  93.  
  94. FW_CPlatformPoint FW_CPlatformRect::TopRight() const
  95. {
  96.     FW_CPlatformPoint point(right, top);
  97.     return point;
  98. }
  99.  
  100. //----------------------------------------------------------------------------------------
  101. //    FW_CPlatformRect::BotLeft
  102. //----------------------------------------------------------------------------------------
  103.  
  104. FW_CPlatformPoint FW_CPlatformRect::BotLeft() const
  105. {
  106.     FW_CPlatformPoint point(left, bottom);
  107.     return point;
  108. }
  109.  
  110. //========================================================================================
  111. //    class FW_CRect
  112. //========================================================================================
  113.  
  114. //----------------------------------------------------------------------------------------
  115. //    FW_CRect::FW_CRect
  116. //----------------------------------------------------------------------------------------
  117.  
  118. FW_CRect::FW_CRect()
  119. {
  120.     left = top = right = bottom    = FW_IntToFixed(0);
  121. }
  122.         
  123. //----------------------------------------------------------------------------------------
  124. //    FW_CRect::FW_CRect
  125. //----------------------------------------------------------------------------------------
  126.  
  127. FW_CRect::FW_CRect(FW_Fixed l, FW_Fixed t, FW_Fixed r, FW_Fixed b)
  128. {
  129.     left    =    l;
  130.     top        =    t;
  131.     right    =    r;
  132.     bottom    =    b;
  133. }
  134.  
  135. //----------------------------------------------------------------------------------------
  136. //    FW_CRect::FW_CRect
  137. //----------------------------------------------------------------------------------------
  138.  
  139. FW_CRect::FW_CRect(const FW_SPoint &topLeft, const FW_SPoint &botRight)
  140. {
  141.     left = topLeft.x;        right = botRight.x;
  142.     top = topLeft.y;        bottom = botRight.y;
  143. }
  144.  
  145. //----------------------------------------------------------------------------------------
  146. //    FW_CRect::FW_CRect
  147. //----------------------------------------------------------------------------------------
  148.  
  149. FW_CRect::FW_CRect(const FW_SPoint &startPoint, const FW_SPoint &endPoint, FW_Fixed penSize)
  150. {
  151.     left = startPoint.x;                
  152.     right = endPoint.x;
  153.     top  = startPoint.y;                
  154.     bottom= endPoint.y;
  155.     
  156.     Sort();
  157.     
  158.     right -= penSize;
  159.     bottom -= penSize;
  160. }
  161.  
  162. //----------------------------------------------------------------------------------------
  163. //    FW_CRect::FW_CRect
  164. //----------------------------------------------------------------------------------------
  165.  
  166. FW_CRect::FW_CRect(const FW_SPoint &topLeft, FW_Fixed width, FW_Fixed height )
  167. {
  168.     left = topLeft.x;        right = left + width;
  169.     top  = topLeft.y;        bottom= top + height;
  170. }
  171.  
  172. //----------------------------------------------------------------------------------------
  173. //    FW_CRect::FW_CRect
  174. //----------------------------------------------------------------------------------------
  175.  
  176. FW_CRect::FW_CRect(const ODRect& odRect)
  177. {
  178.     left    =    FW_ODFixedToFixed(odRect.left);
  179.     top        =    FW_ODFixedToFixed(odRect.top);
  180.     right    =    FW_ODFixedToFixed(odRect.right);
  181.     bottom    =    FW_ODFixedToFixed(odRect.bottom);
  182. }
  183.  
  184. //----------------------------------------------------------------------------------------
  185. //    FW_CRect::FW_CPoint
  186. //----------------------------------------------------------------------------------------
  187.  
  188. FW_CRect::FW_CRect(FW_CReadableStream& stream)
  189. {
  190.     stream
  191.         >> left
  192.         >> top
  193.         >> right
  194.         >> bottom;
  195. }
  196.  
  197. //----------------------------------------------------------------------------------------
  198. //    FW_CRect:: operator=
  199. //----------------------------------------------------------------------------------------
  200.  
  201. FW_CRect& FW_CRect:: operator=(const ODRect& odRect)
  202. {
  203.     left = FW_ODFixedToFixed(odRect.left);    right = FW_ODFixedToFixed(odRect.right);
  204.     top  = FW_ODFixedToFixed(odRect.top);    bottom= FW_ODFixedToFixed(odRect.bottom);
  205.  
  206.     return *this;
  207. }
  208.  
  209. //----------------------------------------------------------------------------------------
  210. //    FW_CRect::FW_CRect
  211. //----------------------------------------------------------------------------------------
  212.  
  213. FW_CRect::FW_CRect(const FW_PlatformRect& plfmRect)
  214. {
  215.     left     =    FW_IntToFixed(plfmRect.left);
  216.     top      =    FW_IntToFixed(plfmRect.top);
  217.     right    =    FW_IntToFixed(plfmRect.right);
  218.     bottom    =    FW_IntToFixed(plfmRect.bottom);
  219. }
  220.  
  221. //----------------------------------------------------------------------------------------
  222. //    FW_CRect::FW_CRect
  223. //----------------------------------------------------------------------------------------
  224.  
  225. FW_CRect::FW_CRect(const FW_CRect& other)
  226. {
  227.     left    =    other.left;
  228.     top        =    other.top;
  229.     right    =    other.right;
  230.     bottom    =    other.bottom;
  231. }
  232.  
  233. //----------------------------------------------------------------------------------------
  234. //    FW_CRect::FW_CRect
  235. //----------------------------------------------------------------------------------------
  236.  
  237. FW_CRect::FW_CRect(const FW_SRect& sRect)
  238. {
  239.     left    =    sRect.left;
  240.     top        =    sRect.top;
  241.     right    =    sRect.right;
  242.     bottom    =    sRect.bottom;
  243. }
  244.  
  245. //----------------------------------------------------------------------------------------
  246. //    FW_CRect::operator=
  247. //----------------------------------------------------------------------------------------
  248.  
  249. FW_CRect& FW_CRect::operator=(const FW_PlatformRect& plfmRect)
  250. {
  251.     left = FW_IntToFixed(plfmRect.left);    right = FW_IntToFixed(plfmRect.right);
  252.     top  = FW_IntToFixed(plfmRect.top);        bottom= FW_IntToFixed(plfmRect.bottom);
  253.  
  254.     return *this;
  255. }
  256.  
  257. //----------------------------------------------------------------------------------------
  258. //    FW_CRect:: operator=
  259. //----------------------------------------------------------------------------------------
  260.  
  261. FW_CRect& FW_CRect:: operator=(const FW_CRect& other)
  262. {
  263.     left = other.left;        right = other.right;
  264.     top  = other.top;        bottom= other.bottom;
  265.  
  266.     return *this;
  267. }
  268.  
  269. //----------------------------------------------------------------------------------------
  270. //    FW_CRect:: operator=
  271. //----------------------------------------------------------------------------------------
  272.  
  273. FW_CRect& FW_CRect:: operator=(const FW_SRect& rect)
  274. {
  275.     left = rect.left;        right = rect.right;
  276.     top  = rect.top;        bottom= rect.bottom;
  277.  
  278.     return *this;
  279. }
  280.  
  281. //----------------------------------------------------------------------------------------
  282. //    FW_CRect::Set
  283. //----------------------------------------------------------------------------------------
  284.  
  285. void FW_CRect::Set(FW_Fixed l, FW_Fixed t, FW_Fixed r, FW_Fixed b)
  286. {
  287.     left = l;                right = r;
  288.     top  = t;                bottom= b;
  289. }
  290.  
  291. //----------------------------------------------------------------------------------------
  292. //    FW_CRect::Set
  293. //----------------------------------------------------------------------------------------
  294.  
  295. void FW_CRect::Set(const FW_SPoint &topLeft, FW_Fixed width, FW_Fixed height)
  296. {
  297.     left = topLeft.x;                right = left+width;
  298.     top  = topLeft.y;                bottom= top +height;
  299. }
  300.  
  301. //----------------------------------------------------------------------------------------
  302. //    FW_CRect::Set
  303. //----------------------------------------------------------------------------------------
  304.  
  305. void FW_CRect::Set(const FW_SPoint &topLeft, const FW_SPoint &botRight)
  306. {
  307.     left = topLeft.x;                right = botRight.x;
  308.     top  = topLeft.y;                bottom= botRight.y;
  309. }
  310.  
  311. //----------------------------------------------------------------------------------------
  312. //     FW_CRect::SetInt
  313. //----------------------------------------------------------------------------------------
  314.  
  315. void FW_CRect::SetInt(short l, short t, short r, short b)
  316. {
  317.     left = FW_IntToFixed(l);            right = FW_IntToFixed(r);
  318.     top  = FW_IntToFixed(t);            bottom= FW_IntToFixed(b);
  319. }
  320.  
  321. //----------------------------------------------------------------------------------------
  322. //    FW_CRect::Offset
  323. //----------------------------------------------------------------------------------------
  324.  
  325. void FW_CRect::Offset(FW_Fixed x, FW_Fixed y)
  326. {
  327.     left += x;                right += x;
  328.     top  += y;                bottom+= y;
  329. }
  330.  
  331. //----------------------------------------------------------------------------------------
  332. //    FW_CRect::Offset
  333. //----------------------------------------------------------------------------------------
  334.  
  335. void FW_CRect::Offset(const FW_SPoint &pt)
  336. {
  337.     left += pt.x;            right += pt.x;
  338.     top  += pt.y;            bottom+= pt.y;
  339. }
  340.  
  341. //----------------------------------------------------------------------------------------
  342. //    FW_CRect::Place
  343. //----------------------------------------------------------------------------------------
  344.  
  345. void FW_CRect::Place(FW_Fixed x, FW_Fixed y)
  346. {
  347.     right += x - left;
  348.     left = x;
  349.     bottom += y - top;
  350.     top = y;
  351. }
  352.  
  353. //----------------------------------------------------------------------------------------
  354. //    FW_CRect::Place
  355. //----------------------------------------------------------------------------------------
  356.  
  357. void FW_CRect::Place(const FW_SPoint &pt)
  358. {
  359.     right += pt.x - left;
  360.     left = pt.x;
  361.     bottom += pt.y - top;
  362.     top = pt.y;
  363. }
  364.  
  365. //----------------------------------------------------------------------------------------
  366. //    FW_CRect::PlaceInCenterOf
  367. //----------------------------------------------------------------------------------------
  368.  
  369. void FW_CRect::PlaceInCenterOf(const FW_SRect& otherRect)
  370. {
  371.     FW_Fixed newTop     = FW_Half(otherRect.bottom + otherRect.top - bottom + top);
  372.     bottom = newTop + bottom - top;
  373.     top = newTop;
  374.  
  375.     FW_Fixed newLeft    = FW_Half(otherRect.right + otherRect.left - right + left);
  376.     right = newLeft + right - left;
  377.     left = newLeft;        
  378. }
  379.  
  380. //----------------------------------------------------------------------------------------
  381. //    FW_CRect::Center
  382. //----------------------------------------------------------------------------------------
  383.  
  384. FW_CPoint FW_CRect::Center() const
  385. {
  386.     FW_CPoint center(FW_Half(left + right), FW_Half(top + bottom));
  387.     return center;
  388. }
  389.  
  390. //----------------------------------------------------------------------------------------
  391. //    FW_CRect::Inset
  392. //----------------------------------------------------------------------------------------
  393.  
  394. void FW_CRect::Inset(FW_Fixed x, FW_Fixed y )
  395. {
  396.     left += x;
  397.     right -= x;
  398.     top += y;
  399.     bottom -= y;
  400. }
  401.  
  402. //----------------------------------------------------------------------------------------
  403. //    FW_CRect::Clear
  404. //----------------------------------------------------------------------------------------
  405.  
  406. void FW_CRect::Clear( )
  407. {
  408.     left = right = top = bottom = FW_IntToFixed(0);
  409. }
  410.  
  411. //----------------------------------------------------------------------------------------
  412. //    operator|= FW_CPoint
  413. //----------------------------------------------------------------------------------------
  414.  
  415. void FW_CRect:: operator|= (const FW_SPoint &pt)
  416. {
  417.     left     = FW_Minimum(left,pt.x);
  418.     right    = FW_Maximum(right,pt.x);
  419.     top      = FW_Minimum(top,pt.y);
  420.     bottom    = FW_Maximum(bottom,pt.y);
  421. }
  422.  
  423. //----------------------------------------------------------------------------------------
  424. //    FW_CRect::AsPlatformRect
  425. //----------------------------------------------------------------------------------------
  426.  
  427. FW_CPlatformRect FW_CRect::AsPlatformRect() const
  428. {
  429.     return FW_CPlatformRect(
  430.         FW_FixedToInt(left),
  431.         FW_FixedToInt(top),
  432.         FW_FixedToInt(right),
  433.         FW_FixedToInt(bottom));
  434. }
  435.  
  436. //----------------------------------------------------------------------------------------
  437. //    FW_CRect::IsEmpty
  438. //----------------------------------------------------------------------------------------
  439.  
  440. FW_Boolean FW_CRect::IsEmpty() const
  441. {
  442.     return right<=left || bottom<=top;
  443. }
  444.  
  445. //----------------------------------------------------------------------------------------
  446. //    FW_CRect::Contains
  447. //----------------------------------------------------------------------------------------
  448.  
  449. FW_Boolean FW_CRect::Contains(const FW_SPoint &pt) const
  450. {
  451.     return left<=pt.x && pt.x<right
  452.         && top <=pt.y && pt.y<bottom;
  453. }
  454.  
  455. //----------------------------------------------------------------------------------------
  456. //    FW_CRect::Contains
  457. //----------------------------------------------------------------------------------------
  458.  
  459. FW_Boolean FW_CRect::Contains( const FW_SRect &r) const
  460. {
  461.     return left<=r.left && r.right<=right
  462.         && top <=r.top  && r.bottom<=bottom;
  463. }
  464.  
  465. //----------------------------------------------------------------------------------------
  466. //    FW_CRect::operator==
  467. //----------------------------------------------------------------------------------------
  468.  
  469. FW_Boolean FW_CRect::operator==(const FW_SRect &sRect) const
  470. {
  471.     return (left == sRect.left && top == sRect.top  && right == sRect.right  && bottom == sRect.bottom);
  472. }
  473.  
  474. //----------------------------------------------------------------------------------------
  475. //    FW_CRect::IsIntersecting
  476. //----------------------------------------------------------------------------------------
  477.  
  478. FW_Boolean FW_CRect::IsIntersecting(const FW_SRect &r) const
  479. {
  480.     return FW_Maximum(left,r.left) < FW_Minimum(right,r.right)
  481.         && FW_Maximum(top,r.top) < FW_Minimum(bottom,r.bottom);
  482. }
  483.  
  484. static inline void FW_PrivAdjustIfEmpty(FW_CRect &r)
  485. {
  486.     // [BRP] The IsEmpty test below was in Bedrock and ODF R1
  487.     // However, the caller should be responsible for testing
  488.     // the IsEmpty status of the rect.
  489.     // This particular case fixes a bug
  490.     // found in ODFDraw where rectangle selection of
  491.     // vertical and horizontal lines would fail.
  492.     // Here, we allow the case where the intersection has zero-width or height
  493.  
  494.     // if (IsEmpty())
  495.     if(r.left > r.right || r.top > r.bottom)
  496.         r.SetInt(0,0,0,0);
  497. }
  498.  
  499. //----------------------------------------------------------------------------------------
  500. //    FW_CRect::Intersection
  501. //----------------------------------------------------------------------------------------
  502.  
  503. void FW_CRect::Intersection(const FW_SRect &r)
  504. {
  505.     left = FW_Maximum(left, r.left);
  506.     top = FW_Maximum(top, r.top);
  507.     right = FW_Minimum(right, r.right);
  508.     bottom = FW_Minimum(bottom, r.bottom);
  509.         
  510.     FW_PrivAdjustIfEmpty(*this);
  511. }
  512.  
  513. //----------------------------------------------------------------------------------------
  514. //    FW_CRect::Intersection
  515. //----------------------------------------------------------------------------------------
  516.  
  517. void FW_CRect::Intersection(const FW_SRect &r1, const FW_SRect &r2)
  518. {
  519.     left = FW_Maximum(r1.left, r2.left);
  520.     top = FW_Maximum(r1.top, r2.top);
  521.     right = FW_Minimum(r1.right, r2.right);
  522.     bottom = FW_Minimum(r1.bottom, r2.bottom);
  523.     
  524.     FW_PrivAdjustIfEmpty(*this);
  525. }
  526.  
  527. //----------------------------------------------------------------------------------------
  528. //    FW_CRect::Union
  529. //----------------------------------------------------------------------------------------
  530.  
  531. void FW_CRect::Union(const FW_SRect &rect)
  532. {
  533.     left = FW_Minimum(left, rect.left);
  534.     right= FW_Maximum(right, rect.right);
  535.     top  = FW_Minimum(top, rect.top);
  536.     bottom=FW_Maximum(bottom, rect.bottom);
  537.     
  538.     FW_PrivAdjustIfEmpty(*this);
  539. }
  540.  
  541. //----------------------------------------------------------------------------------------
  542. //    FW_CRect::Union
  543. //----------------------------------------------------------------------------------------
  544.  
  545. void FW_CRect::Union(const FW_SRect &r1, const FW_SRect &r2)
  546. {
  547.     left = FW_Minimum(r1.left, r2.left);
  548.     right= FW_Maximum(r1.right, r2.right);
  549.     top  = FW_Minimum(r1.top, r2.top);
  550.     bottom=FW_Maximum(r1.bottom, r2.bottom);
  551.     
  552.     FW_PrivAdjustIfEmpty(*this);
  553. }
  554.  
  555. //----------------------------------------------------------------------------------------
  556. //    FW_CRect::Sort
  557. //----------------------------------------------------------------------------------------
  558.  
  559. void FW_CRect::Sort()
  560. {
  561.     if (left > right)
  562.     {
  563.         FW_Fixed temp = left;
  564.         left = right;
  565.         right = temp;
  566.     }
  567.     if (top > bottom)
  568.     {
  569.         FW_Fixed temp = top;
  570.         top = bottom;
  571.         bottom = temp;
  572.     }
  573. }
  574.  
  575. //----------------------------------------------------------------------------------------
  576. //    FW_CRect::Map
  577. //----------------------------------------------------------------------------------------
  578. //     The result may not be sorted. You might have to call Sort.
  579.  
  580. void FW_CRect::Map(const FW_SRect& srcRect, const FW_SRect& dstRect)
  581. {
  582.     ((FW_CPoint*)&left)->Map(srcRect, dstRect);
  583.     ((FW_CPoint*)&right)->Map(srcRect, dstRect);
  584. }
  585.  
  586. //----------------------------------------------------------------------------------------
  587. //    FW_CRect::TopRight
  588. //----------------------------------------------------------------------------------------
  589.  
  590. FW_CPoint FW_CRect::TopRight() const
  591. {
  592.     FW_CPoint point(right, top);
  593.     return point;
  594. }
  595.  
  596. //----------------------------------------------------------------------------------------
  597. //    FW_CRect::BotLeft
  598. //----------------------------------------------------------------------------------------
  599.  
  600. FW_CPoint FW_CRect::BotLeft() const
  601. {
  602.     FW_CPoint point(left, bottom);
  603.     return point;
  604. }
  605.  
  606. //----------------------------------------------------------------------------------------
  607. //    FW_Transform
  608. //----------------------------------------------------------------------------------------
  609.  
  610. void FW_Transform(Environment* ev, FW_SRect& rect, ODTransform* transform)
  611. {
  612. #if FW_OPENDOC_VERSION < FW_OPENDOC_DR4
  613.     * (((ODPoint*) &rect) + 0) =
  614. #endif
  615.     transform->TransformPoint(ev, ((ODPoint*) &rect) + 0);
  616.     
  617. #if FW_OPENDOC_VERSION < FW_OPENDOC_DR4
  618.     * (((ODPoint*) &rect) + 1) =
  619. #endif
  620.     transform->TransformPoint(ev, ((ODPoint*) &rect) + 1);
  621. }
  622.  
  623. //----------------------------------------------------------------------------------------
  624. //    FW_InverseTransform
  625. //----------------------------------------------------------------------------------------
  626.  
  627. void FW_InverseTransform(Environment* ev, FW_SRect& rect, ODTransform* transform)
  628. {
  629. #if FW_OPENDOC_VERSION < FW_OPENDOC_DR4
  630.     * (((ODPoint*) &rect) + 0) =
  631. #endif
  632.     transform->InvertPoint(ev, ((ODPoint*) &rect) + 0);
  633.  
  634. #if FW_OPENDOC_VERSION < FW_OPENDOC_DR4
  635.     * (((ODPoint*) &rect) + 1) =
  636. #endif
  637.     transform->InvertPoint(ev, ((ODPoint*) &rect) + 1);
  638. }
  639.  
  640. //----------------------------------------------------------------------------------------
  641. //    FW_TransformCopy
  642. //----------------------------------------------------------------------------------------
  643.  
  644. FW_CRect FW_TransformCopy(Environment* ev, const FW_SRect& rect, ODTransform* transform)
  645. {
  646.     FW_CRect r(rect);
  647.  
  648. #if FW_OPENDOC_VERSION < FW_OPENDOC_DR4
  649.     * (((ODPoint*) &r) + 0) =
  650. #endif
  651.     transform->TransformPoint(ev, ((ODPoint*) &r) + 0);
  652.  
  653. #if FW_OPENDOC_VERSION < FW_OPENDOC_DR4
  654.     * (((ODPoint*) &r) + 1) =
  655. #endif
  656.     transform->TransformPoint(ev, ((ODPoint*) &r) + 1);
  657.     
  658.     return r;
  659. }
  660.  
  661. //----------------------------------------------------------------------------------------
  662. //    FW_InverseTransformCopy
  663. //----------------------------------------------------------------------------------------
  664.  
  665. FW_CRect FW_InverseTransformCopy(Environment* ev, const FW_SRect& rect, ODTransform* transform)
  666. {
  667.     FW_CRect r(rect);
  668.  
  669. #if FW_OPENDOC_VERSION < FW_OPENDOC_DR4
  670.     * (((ODPoint*) &r) + 0) =
  671. #endif
  672.     transform->InvertPoint(ev, ((ODPoint*) &r) + 0);
  673.  
  674. #if FW_OPENDOC_VERSION < FW_OPENDOC_DR4
  675.     * (((ODPoint*) &r) + 1) =
  676. #endif
  677.     transform->InvertPoint(ev, ((ODPoint*) &r) + 1);
  678.     
  679.     return r;
  680. }
  681.  
  682. //----------------------------------------------------------------------------------------
  683. //    FW_CRect::operator[]
  684. //----------------------------------------------------------------------------------------
  685.  
  686. FW_CPoint& FW_CRect::operator[](FW_PointSelector sel)
  687. {
  688.     return (sel == FW_kTopLeft) ? *((FW_CPoint *) &left) : *((FW_CPoint *) &right);
  689. }
  690.  
  691. //----------------------------------------------------------------------------------------
  692. //    FW_CRect::operator[]
  693. //----------------------------------------------------------------------------------------
  694.  
  695. const FW_CPoint& FW_CRect::operator[](FW_PointSelector sel) const
  696. {
  697.     return (sel == FW_kTopLeft) ? *((FW_CPoint *) &left) : *((FW_CPoint *) &right);
  698. }
  699.  
  700. //----------------------------------------------------------------------------------------
  701. //    FW_CRect::Size
  702. //----------------------------------------------------------------------------------------
  703.  
  704. FW_CPoint FW_CRect::Size() const
  705. {
  706.     return FW_CPoint(right - left, bottom - top);
  707. }
  708.  
  709. //----------------------------------------------------------------------------------------
  710. //    FW_CRect::Length
  711. //----------------------------------------------------------------------------------------
  712.  
  713. FW_Fixed FW_CRect::Length(FW_XYSelector selector) const
  714. {
  715.     return BotRight()[selector] - TopLeft()[selector];
  716. }
  717.  
  718. //----------------------------------------------------------------------------------------
  719. //    FW_CRect::operator+=
  720. //----------------------------------------------------------------------------------------
  721.  
  722. FW_CRect& FW_CRect::operator+=(const FW_SPoint& pt)
  723. {
  724.     left    +=    pt.x;
  725.     top        +=    pt.y;
  726.     right    +=    pt.x;
  727.     bottom    +=    pt.y;
  728.  
  729.     return *this;
  730. }
  731.  
  732. //----------------------------------------------------------------------------------------
  733. //    FW_CRect::operator+
  734. //----------------------------------------------------------------------------------------
  735.  
  736. FW_CRect FW_CRect::operator+(const FW_SPoint& pt) const
  737. {
  738.     return FW_CRect(
  739.         left    +    pt.x,
  740.         top        +    pt.y,
  741.         right    +    pt.x,
  742.         bottom    +    pt.y);
  743. }
  744.  
  745. //----------------------------------------------------------------------------------------
  746. //    FW_CRect::operator-=
  747. //----------------------------------------------------------------------------------------
  748.  
  749. FW_CRect& FW_CRect::operator-=(const FW_SPoint& pt)
  750. {
  751.     left    -=    pt.x;
  752.     top        -=    pt.y;
  753.     right    -=    pt.x;
  754.     bottom    -=    pt.y;
  755.  
  756.     return *this;
  757. }
  758.  
  759. //----------------------------------------------------------------------------------------
  760. //    FW_CRect::operator-
  761. //----------------------------------------------------------------------------------------
  762.  
  763. FW_CRect FW_CRect::operator-(const FW_SPoint& pt) const
  764. {
  765.     return FW_CRect(
  766.         left    -    pt.x,
  767.         top        -    pt.y,
  768.         right    -    pt.x,
  769.         bottom    -    pt.y);
  770. }
  771.  
  772. //----------------------------------------------------------------------------------------
  773. //    operator<<
  774. //----------------------------------------------------------------------------------------
  775.  
  776. FW_CWritableStream& operator<<(FW_CWritableStream& stream, const FW_SRect& rect)
  777. {
  778.     return stream
  779.         << rect.left
  780.         << rect.top
  781.         << rect.right
  782.         << rect.bottom;
  783. }
  784.  
  785. //----------------------------------------------------------------------------------------
  786. //    operator>>
  787. //----------------------------------------------------------------------------------------
  788.  
  789. FW_CReadableStream& operator>>(FW_CReadableStream& stream, FW_SRect& rect)
  790. {
  791.     return stream
  792.         >> rect.left
  793.         >> rect.top
  794.         >> rect.right
  795.         >> rect.bottom;
  796. }
  797.  
  798.