1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:   Region class 
   4 // Author:    David Webster 
   8 // Copyright: (c) Davdi Webster 
   9 // Licence:   wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  16 #include "wx/os2/region.h" 
  17 #include "wx/gdicmn.h" 
  19 #include "wx/window.h" 
  20 #include "wx/os2/private.h" 
  22     IMPLEMENT_DYNAMIC_CLASS(wxRegion
, wxGDIObject
) 
  23     IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator
, wxObject
) 
  25 //----------------------------------------------------------------------------- 
  26 // wxRegionRefData implementation 
  27 //----------------------------------------------------------------------------- 
  29 class WXDLLEXPORT wxRegionRefData 
: public wxGDIRefData 
{ 
  37     wxRegionRefData(const wxRegionRefData
& rData
) 
  42         if (::GpiQueryRegionRects( rData
.m_hPS      
// Pres space 
  43                                   ,rData
.m_hRegion  
// Handle of region to query 
  44                                   ,NULL             
// Return all RECTs 
  45                                   ,&vRgnData        
// Will contain number or RECTs in region 
  46                                   ,NULL             
// NULL to return number of RECTs 
  49             pRect 
= new RECTL
[vRgnData
.crcReturned
]; 
  50             vRgnData
.crc 
= vRgnData
.crcReturned
; 
  51             vRgnData
.ircStart 
= 1; 
  52             if (::GpiQueryRegionRects( rData
.m_hPS     
// Pres space of source 
  53                                       ,rData
.m_hRegion 
// Handle of source region 
  54                                       ,NULL            
// Return all RECTs 
  55                                       ,&vRgnData       
// Operations set to return rects 
  56                                       ,pRect           
// Will contain the actual RECTS 
  59                 m_hRegion 
= ::GpiCreateRegion( rData
.m_hPS
 
  71         ::GpiDestroyRegion(m_hPS
, m_hRegion
); 
  78 #define M_REGION (((wxRegionRefData*)m_refData)->m_hRegion) 
  79 #define M_REGION_OF(rgn) (((wxRegionRefData*)(rgn.m_refData))->m_hRegion) 
  81 //----------------------------------------------------------------------------- 
  83 //----------------------------------------------------------------------------- 
  86  * Create an empty region. 
  90     m_refData 
= new wxRegionRefData
; 
  91 } // end of wxRegion::wxRegion 
  98     m_refData 
= new wxRegionRefData
; 
  99     M_REGION 
= (HRGN
) hRegion
; 
 100     (((wxRegionRefData
*)m_refData
)->m_hPS
) = hPS
; 
 101 } // end of wxRegion::wxRegion 
 111     SIZEL                           vSize 
= {0, 0}; 
 112     DEVOPENSTRUC                    vDop 
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 113     HDC                             hDC 
= ::DevOpenDC( vHabmain
 
 123     vRect
.xRight  
= x 
+ vWidth
; 
 125     vRect
.yTop    
= y 
+ vHeight
; 
 127     m_refData     
= new wxRegionRefData
; 
 130     // Need a PS to create a Region 
 132     ((wxRegionRefData
*)m_refData
)->m_hPS 
= ::GpiCreatePS( vHabmain
 
 135                                                          ,PU_PELS 
| GPIT_MICRO 
| GPIA_ASSOC
 
 137     M_REGION      
= ::GpiCreateRegion( ((wxRegionRefData
*)m_refData
)->m_hPS
 
 141 } // end of wxRegion::wxRegion 
 144   const wxPoint
&                    rTopLeft
 
 145 , const wxPoint
&                    rBottomRight
 
 149     SIZEL                           vSize 
= {0, 0}; 
 150     DEVOPENSTRUC                    vDop 
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 151     HDC                             hDC 
= ::DevOpenDC( vHabmain
 
 159     vRect
.xLeft   
= rTopLeft
.x
; 
 160     vRect
.xRight  
= rBottomRight
.x
; 
 161     vRect
.yBottom 
= rBottomRight
.y
; 
 162     vRect
.yTop    
= rTopLeft
.y
; 
 164     m_refData     
= new wxRegionRefData
; 
 167     // Need a PS to create a Region 
 169     ((wxRegionRefData
*)m_refData
)->m_hPS 
= ::GpiCreatePS( vHabmain
 
 172                                                          ,PU_PELS 
| GPIT_MICRO 
| GPIA_ASSOC
 
 174     M_REGION      
= ::GpiCreateRegion( ((wxRegionRefData
*)m_refData
)->m_hPS
 
 178 } // end of wxRegion::wxRegion 
 185     SIZEL                           vSize 
= {0, 0}; 
 186     DEVOPENSTRUC                    vDop 
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L}; 
 187     HDC                             hDC 
= ::DevOpenDC( vHabmain
 
 196     vRect
.xLeft   
= rRect
.x
; 
 197     vRect
.xRight  
= rRect
.x 
+ rRect
.width
; 
 198     vRect
.yBottom 
= rRect
.y
; 
 199     vRect
.yTop    
= rRect
.y 
+ rRect
.height
; 
 201     m_refData     
= new wxRegionRefData
; 
 204     // Need a PS to create a Region 
 206     ((wxRegionRefData
*)m_refData
)->m_hPS 
= ::GpiCreatePS( vHabmain
 
 209                                                          ,PU_PELS 
| GPIT_MICRO 
| GPIA_ASSOC
 
 211     M_REGION      
= ::GpiCreateRegion( ((wxRegionRefData
*)m_refData
)->m_hPS
 
 215 } // end of wxRegion::wxRegion 
 218 // Destroy the region. 
 220 wxRegion::~wxRegion() 
 222 } // end of wxRegion::~wxRegion 
 224 wxObjectRefData 
*wxRegion::CreateData() const 
 226     return new wxRegionRefData
; 
 229 wxObjectRefData 
*wxRegion::CloneData(const wxObjectRefData 
*data
) const 
 231     return new wxRegionRefData(*(wxRegionRefData 
*)data
); 
 234 //----------------------------------------------------------------------------- 
 236 //----------------------------------------------------------------------------- 
 238 bool wxRegion::Offset( 
 252     if ( ::OffsetRgn(GetHrgn(), x
, y
) == ERROR 
) 
 254         wxLogLastError(_T("OffsetRgn")); 
 263 // Clear current region 
 265 void wxRegion::Clear() 
 268 } // end of wxRegion::Clear 
 271 // Combine rectangle (x, y, w, h) with this. 
 273 bool wxRegion::Combine( 
 281     return Combine(wxRegion(x
, y
, vWidth
, vHeight
), eOp
); 
 282 } // end of wxRegion::Combine 
 285 // Union region with this. 
 287 bool wxRegion::Combine( 
 288   const wxRegion
&                   rRegion
 
 293     // We can't use the API functions if we don't have a valid region handle 
 297         // combining with an empty/invalid region works differently depending 
 308                 wxFAIL_MSG( _T("unknown region operation") ); 
 313                 // leave empty/invalid 
 317     else // we have a valid region 
 345         return (::GpiCombineRegion( ((wxRegionRefData
*)rRegion
.m_refData
)->m_hPS
 
 348                                    ,((wxRegionRefData
*)rRegion
.m_refData
)->m_hRegion
 
 353 } // end of wxRegion::Combine 
 355 bool wxRegion::Combine( 
 360     return Combine( rRect
.GetLeft() 
 366 } // end of wxRegion::Combine 
 368 //----------------------------------------------------------------------------- 
 369 //# Information on region 
 370 //----------------------------------------------------------------------------- 
 373 // Outer bounds of region 
 375 void wxRegion::GetBox( 
 387         rc 
= ::GpiQueryRegionBox( ((wxRegionRefData
*)m_refData
)->m_hPS
 
 393         vWidth  
= vRect
.xRight 
- vRect
.xLeft
; 
 394         vHeight 
= vRect
.yTop 
- vRect
.yBottom
; 
 398         x 
= y 
= vWidth 
= vHeight 
= 0L; 
 400 } // end of wxRegion::GetBox 
 402 wxRect 
wxRegion::GetBox() const 
 406     return wxRect(x
, y
, w
, h
); 
 412 bool wxRegion::Empty() const 
 427     return ((vWidth 
== 0) && (vHeight 
== 0)); 
 428 } // end of wxRegion::Empty 
 430 //----------------------------------------------------------------------------- 
 432 //----------------------------------------------------------------------------- 
 435 // Does the region contain the point (x,y)? 
 436 wxRegionContain 
wxRegion::Contains( 
 450     LONG                            lInside 
= ::GpiPtInRegion( ((wxRegionRefData
*)m_refData
)->m_hPS
 
 454     if (lInside 
== PRGN_INSIDE
) 
 457 } // end of wxRegion::Contains 
 460 // Does the region contain the point pt? 
 462 wxRegionContain 
wxRegion::Contains( 
 463   const wxPoint
&                    rPoint
 
 466     POINTL                          vPoint 
= { rPoint
.x
, rPoint
.y 
}; 
 471     LONG                            lInside 
= ::GpiPtInRegion( ((wxRegionRefData
*)m_refData
)->m_hPS
 
 475     if (lInside 
== PRGN_INSIDE
) 
 479 } // end of wxRegion::Contains 
 482 // Does the region contain the rectangle (x, y, w, h)? 
 484 wxRegionContain 
wxRegion::Contains( 
 498     vRect
.xRight  
= x 
+ vWidth
; 
 499     vRect
.yBottom 
= y 
+ vHeight
; 
 501     if (PRGN_INSIDE 
== ::GpiRectInRegion( ((wxRegionRefData
*)m_refData
)->m_hPS
 
 508 } // end of wxRegion::Contains 
 511 // Does the region contain the rectangle rect 
 513 wxRegionContain 
wxRegion::Contains( 
 527     vWidth  
= rRect
.GetWidth(); 
 528     vHeight 
= rRect
.GetHeight(); 
 534 } // end of wxRegion::Contains 
 537 // Get internal region handle 
 539 WXHRGN 
wxRegion::GetHRGN() const 
 543     return (WXHRGN
) M_REGION
; 
 547 // Set a new PS, this means we have to recreate the old region in the new 
 550 void wxRegion::SetPS( 
 557     if (::GpiQueryRegionRects( ((wxRegionRefData
*)m_refData
)->m_hPS
 
 558                               ,((wxRegionRefData
*)m_refData
)->m_hRegion
 
 564         pRect 
= new RECTL
[vRgnData
.crcReturned
]; 
 565         vRgnData
.crc 
= vRgnData
.crcReturned
; 
 566         vRgnData
.ircStart 
= 1; 
 567         if (::GpiQueryRegionRects( ((wxRegionRefData
*)m_refData
)->m_hPS
 
 568                                   ,((wxRegionRefData
*)m_refData
)->m_hRegion
 
 575             // First destroy the region out of the old PS 
 576             // and then create it in the new and set the new to current 
 578             ::GpiDestroyRegion( ((wxRegionRefData
*)m_refData
)->m_hPS
 
 581             ((wxRegionRefData
*)m_refData
)->m_hRegion 
= ::GpiCreateRegion( hPS
 
 582                                                                          ,vRgnData
.crcReturned
 
 585             ((wxRegionRefData
*)m_refData
)->m_hPS 
= hPS
; 
 589 } // end of wxRegion::SetPS 
 591 /////////////////////////////////////////////////////////////////////////////// 
 593 //                             wxRegionIterator                              // 
 595 /////////////////////////////////////////////////////////////////////////////// 
 598 // Initialize empty iterator 
 600 wxRegionIterator::wxRegionIterator() 
 605 } // end of wxRegionIterator::wxRegionIterator 
 607 wxRegionIterator::~wxRegionIterator() 
 611 } // end of wxRegionIterator::~wxRegionIterator 
 614 // Initialize iterator for region 
 616 wxRegionIterator::wxRegionIterator( 
 617   const wxRegion
&                   rRegion
 
 622 } // end of wxRegionIterator::wxRegionIterator 
 625 // Reset iterator for a new /e region. 
 627 void wxRegionIterator::Reset( 
 628   const wxRegion
&                   rRegion
 
 639     if (m_vRegion
.Empty()) 
 646         if (::GpiQueryRegionRects( ((wxRegionRefData
*)rRegion
.m_refData
)->m_hPS     
// Pres space 
 647                                   ,((wxRegionRefData
*)rRegion
.m_refData
)->m_hRegion 
// Handle of region to query 
 648                                   ,NULL                                             
// Return all RECTs 
 649                                   ,&vRgnData                                        
// Will contain number or RECTs in region 
 650                                   ,NULL                                             
// NULL to return number of RECTs 
 653             pRect 
= new RECTL
[vRgnData
.crcReturned
]; 
 654             m_pRects 
= new wxRect
[vRgnData
.crcReturned
]; 
 655             vRgnData
.crc 
= vRgnData
.crcReturned
; 
 656             m_lNumRects 
= vRgnData
.crcReturned
; 
 657             vRgnData
.ircStart 
= 1; 
 658             if (::GpiQueryRegionRects( ((wxRegionRefData
*)rRegion
.m_refData
)->m_hPS     
// Pres space of source 
 659                                       ,((wxRegionRefData
*)rRegion
.m_refData
)->m_hRegion 
// Handle of source region 
 660                                       ,NULL                                             
// Return all RECTs 
 661                                       ,&vRgnData                                        
// Operations set to return rects 
 662                                       ,pRect                                            
// Will contain the actual RECTS 
 665                 M_REGION 
= ::GpiCreateRegion( ((wxRegionRefData
*)rRegion
.m_refData
)->m_hPS
 
 666                                              ,vRgnData
.crcReturned
 
 669                 for( LONG i 
= 0; i 
< m_lNumRects
; i
++) 
 671                     m_pRects
[i
].x      
= pRect
[i
].xLeft
; 
 672                     m_pRects
[i
].width  
= pRect
[i
].xRight 
- pRect
[i
].xLeft
; 
 673                     m_pRects
[i
].y      
= pRect
[i
].yBottom
; 
 674                     m_pRects
[i
].height 
= pRect
[i
].yTop 
- pRect
[i
].yBottom
; 
 676                 ((wxRegionRefData
*)m_refData
)->m_hPS 
= ((wxRegionRefData
*)rRegion
.m_refData
)->m_hPS
; 
 680 } // end of wxRegionIterator::Reset 
 683 // Increment iterator. The rectangle returned is the one after the 
 686 void wxRegionIterator::operator++ () 
 688     if (m_lCurrent 
< m_lNumRects
) 
 690 } // end of wxRegionIterator::operator ++ 
 693 // Increment iterator. The rectangle returned is the one before the 
 696 void wxRegionIterator::operator++ (int) 
 698     if (m_lCurrent 
< m_lNumRects
) 
 700 } // end of wxRegionIterator::operator++ 
 702 wxCoord 
wxRegionIterator::GetX() const 
 704     if (m_lCurrent 
< m_lNumRects
) 
 705         return m_pRects
[m_lCurrent
].x
; 
 707 } // end of wxRegionIterator::GetX 
 709 wxCoord 
wxRegionIterator::GetY() const 
 711     if (m_lCurrent 
< m_lNumRects
) 
 712         return m_pRects
[m_lCurrent
].y
; 
 714 } // end of wxRegionIterator::GetY 
 716 wxCoord 
wxRegionIterator::GetW() const 
 718     if (m_lCurrent 
< m_lNumRects
) 
 719         return m_pRects
[m_lCurrent
].width 
; 
 721 } // end of wxRegionIterator::GetW 
 723 wxCoord 
wxRegionIterator::GetH() const 
 725     if (m_lCurrent 
< m_lNumRects
) 
 726         return m_pRects
[m_lCurrent
].height
; 
 728 } // end of wxRegionIterator::GetH