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