1. fixed bug in wxRegion::Combine() which was modifying all shared regions,

not just the given one
2. added wxRegionIterator copy ctor and assignment operator
3. fixed wxRegionIterator::operators++() to do what they say
4. generic code cleanup


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@17310 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2002-09-20 23:36:23 +00:00
parent b254accad1
commit 6d9a4c4d6f
2 changed files with 135 additions and 114 deletions

View File

@@ -5,7 +5,7 @@
// Modified by: // Modified by:
// Created: 01/02/97 // Created: 01/02/97
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Julian Smart // Copyright: (c) 1997-2002 wxWindows team
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@@ -13,10 +13,9 @@
#define _WX_REGION_H_ #define _WX_REGION_H_
#ifdef __GNUG__ #ifdef __GNUG__
#pragma interface "region.h" #pragma interface "region.h"
#endif #endif
#include "wx/list.h"
#include "wx/gdiobj.h" #include "wx/gdiobj.h"
#include "wx/gdicmn.h" #include "wx/gdicmn.h"
@@ -93,11 +92,11 @@ public:
// Outer bounds of region // Outer bounds of region
void GetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const; void GetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const;
wxRect GetBox(void) const ; wxRect GetBox() const ;
// Is region empty? // Is region empty?
bool Empty(void) const; bool Empty() const;
inline bool IsEmpty(void) const { return Empty(); } inline bool IsEmpty() const { return Empty(); }
// Tests // Tests
// Does the region contain the point (x,y)? // Does the region contain the point (x,y)?
@@ -129,31 +128,39 @@ protected:
class WXDLLEXPORT wxRegionIterator : public wxObject class WXDLLEXPORT wxRegionIterator : public wxObject
{ {
public: public:
wxRegionIterator(void); wxRegionIterator() { Init(); }
wxRegionIterator(const wxRegion& region); wxRegionIterator(const wxRegion& region);
~wxRegionIterator(void); wxRegionIterator(const wxRegionIterator& ri) { Init(); *this = ri; }
void Reset(void) { m_current = 0; } wxRegionIterator& operator=(const wxRegionIterator& ri);
virtual ~wxRegionIterator();
void Reset() { m_current = 0; }
void Reset(const wxRegion& region); void Reset(const wxRegion& region);
bool HaveRects() const { return (m_current < m_numRects); }
#ifndef __SALFORDC__ #ifndef __SALFORDC__
operator bool (void) const { return (m_current < m_numRects); } operator bool () const { return HaveRects(); }
#endif #endif
bool HaveRects(void) const { return (m_current < m_numRects); } wxRegionIterator& operator++();
wxRegionIterator operator++(int);
void operator ++ (void); wxCoord GetX() const;
void operator ++ (int); wxCoord GetY() const;
wxCoord GetW() const;
wxCoord GetWidth() const { return GetW(); }
wxCoord GetH() const;
wxCoord GetHeight() const { return GetH(); }
wxCoord GetX(void) const; wxRect GetRect() const { return wxRect(GetX(), GetY(), GetW(), GetH()); }
wxCoord GetY(void) const;
wxCoord GetW(void) const;
wxCoord GetWidth(void) const { return GetW(); }
wxCoord GetH(void) const;
wxCoord GetHeight(void) const { return GetH(); }
wxRect GetRect() const { return wxRect(GetX(), GetY(), GetWidth(), GetHeight()); }
private: private:
// common part of all ctors
void Init();
long m_current; long m_current;
long m_numRects; long m_numRects;
wxRegion m_region; wxRegion m_region;

View File

@@ -1,16 +1,24 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: msw/region.cpp // Name: msw/region.cpp
// Purpose: Region handling for wxWindows/X11 // Purpose: wxRegion implementation using Win32 API
// Author: Markus Holzem // Author: Markus Holzem, Vadim Zeitlin
// Modified by: // Modified by:
// Created: Fri Oct 24 10:46:34 MET 1997 // Created: Fri Oct 24 10:46:34 MET 1997
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) 1997 Julian Smart and Markus Holzem // Copyright: (c) 1997-2002 wxWindows team
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#ifdef __GNUG__ #ifdef __GNUG__
#pragma implementation "region.h" #pragma implementation "region.h"
#endif #endif
// For compilers that support precompilation, includes "wx.h". // For compilers that support precompilation, includes "wx.h".
@@ -20,18 +28,17 @@
#pragma hdrstop #pragma hdrstop
#endif #endif
#include "wx/msw/region.h" #include "wx/region.h"
#include "wx/gdicmn.h" #include "wx/gdicmn.h"
#include "wx/window.h"
#include "wx/msw/private.h" #include "wx/msw/private.h"
IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject) IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject)
IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject) IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject)
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxRegionRefData implementation // wxRegionRefData implementation
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class WXDLLEXPORT wxRegionRefData : public wxGDIRefData class WXDLLEXPORT wxRegionRefData : public wxGDIRefData
{ {
@@ -56,7 +63,7 @@ public:
#endif #endif
} }
~wxRegionRefData() virtual ~wxRegionRefData()
{ {
::DeleteObject(m_region); ::DeleteObject(m_region);
m_region = 0; m_region = 0;
@@ -68,13 +75,14 @@ public:
#define M_REGION (((wxRegionRefData*)m_refData)->m_region) #define M_REGION (((wxRegionRefData*)m_refData)->m_region)
#define M_REGION_OF(rgn) (((wxRegionRefData*)(rgn.m_refData))->m_region) #define M_REGION_OF(rgn) (((wxRegionRefData*)(rgn.m_refData))->m_region)
//----------------------------------------------------------------------------- // ============================================================================
// wxRegion // wxRegion implementation
//----------------------------------------------------------------------------- // ============================================================================
// ----------------------------------------------------------------------------
// ctors and dtor
// ----------------------------------------------------------------------------
/*
* Create an empty region.
*/
wxRegion::wxRegion() wxRegion::wxRegion()
{ {
m_refData = (wxRegionRefData *)NULL; m_refData = (wxRegionRefData *)NULL;
@@ -135,9 +143,9 @@ wxObjectRefData *wxRegion::CloneRefData(const wxObjectRefData *data) const
return new wxRegionRefData(*(wxRegionRefData *)data); return new wxRegionRefData(*(wxRegionRefData *)data);
} }
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Modify region // wxRegion operations
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Clear current region // Clear current region
void wxRegion::Clear() void wxRegion::Clear()
@@ -195,6 +203,8 @@ bool wxRegion::Combine(const wxRegion& rgn, wxRegionOp op)
} }
else // we have a valid region else // we have a valid region
{ {
AllocExclusive();
int mode; int mode;
switch ( op ) switch ( op )
{ {
@@ -248,9 +258,9 @@ bool wxRegion::Combine(const wxRect& rect, wxRegionOp op)
rect.GetWidth(), rect.GetHeight(), op); rect.GetWidth(), rect.GetHeight(), op);
} }
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Information on region // wxRegion bounding box
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Outer bounds of region // Outer bounds of region
void wxRegion::GetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const void wxRegion::GetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const
@@ -286,9 +296,9 @@ bool wxRegion::Empty() const
return (w == 0) && (h == 0); return (w == 0) && (h == 0);
} }
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Tests // wxRegion hit testing
//----------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Does the region contain the point (x,y)? // Does the region contain the point (x,y)?
wxRegionContain wxRegion::Contains(wxCoord x, wxCoord y) const wxRegionContain wxRegion::Contains(wxCoord x, wxCoord y) const
@@ -296,26 +306,18 @@ wxRegionContain wxRegion::Contains(wxCoord x, wxCoord y) const
if (!m_refData) if (!m_refData)
return wxOutRegion; return wxOutRegion;
if (::PtInRegion(M_REGION, (int) x, (int) y)) return ::PtInRegion(M_REGION, (int) x, (int) y) ? wxInRegion : wxOutRegion;
return wxInRegion;
else
return wxOutRegion;
} }
// Does the region contain the point pt? // Does the region contain the point pt?
wxRegionContain wxRegion::Contains(const wxPoint& pt) const wxRegionContain wxRegion::Contains(const wxPoint& pt) const
{ {
if (!m_refData) return Contains(pt.x, pt.y);
return wxOutRegion;
if (::PtInRegion(M_REGION, (int) pt.x, (int) pt.y))
return wxInRegion;
else
return wxOutRegion;
} }
// Does the region contain the rectangle (x, y, w, h)? // Does the region contain the rectangle (x, y, w, h)?
wxRegionContain wxRegion::Contains(wxCoord x, wxCoord y, wxCoord w, wxCoord h) const wxRegionContain wxRegion::Contains(wxCoord x, wxCoord y,
wxCoord w, wxCoord h) const
{ {
if (!m_refData) if (!m_refData)
return wxOutRegion; return wxOutRegion;
@@ -326,56 +328,43 @@ wxRegionContain wxRegion::Contains(wxCoord x, wxCoord y, wxCoord w, wxCoord h) c
rect.right = x + w; rect.right = x + w;
rect.bottom = y + h; rect.bottom = y + h;
if (::RectInRegion(M_REGION, & rect)) return ::RectInRegion(M_REGION, &rect) ? wxInRegion : wxOutRegion;
return wxInRegion;
else
return wxOutRegion;
} }
// Does the region contain the rectangle rect // Does the region contain the rectangle rect
wxRegionContain wxRegion::Contains(const wxRect& rect) const wxRegionContain wxRegion::Contains(const wxRect& rect) const
{ {
if (!m_refData) return Contains(rect.x, rect.y, rect.width, rect.height);
return wxOutRegion;
wxCoord x, y, w, h;
x = rect.x;
y = rect.y;
w = rect.GetWidth();
h = rect.GetHeight();
return Contains(x, y, w, h);
} }
// Get internal region handle // Get internal region handle
WXHRGN wxRegion::GetHRGN() const WXHRGN wxRegion::GetHRGN() const
{ {
if (!m_refData) return (WXHRGN)(m_refData ? M_REGION : 0);
return (WXHRGN) 0;
return (WXHRGN) M_REGION;
} }
/////////////////////////////////////////////////////////////////////////////// // ============================================================================
// // // wxRegionIterator implementation
// wxRegionIterator // // ============================================================================
// //
///////////////////////////////////////////////////////////////////////////////
/* // ----------------------------------------------------------------------------
* Initialize empty iterator // wxRegionIterator ctors/dtor
*/ // ----------------------------------------------------------------------------
wxRegionIterator::wxRegionIterator() : m_current(0), m_numRects(0), m_rects(NULL)
void wxRegionIterator::Init()
{ {
m_current =
m_numRects = NULL;
m_rects = NULL;
} }
wxRegionIterator::~wxRegionIterator() wxRegionIterator::~wxRegionIterator()
{ {
if (m_rects) delete [] m_rects;
delete[] m_rects;
} }
/* // Initialize iterator for region
* Initialize iterator for region
*/
wxRegionIterator::wxRegionIterator(const wxRegion& region) wxRegionIterator::wxRegionIterator(const wxRegion& region)
{ {
m_rects = NULL; m_rects = NULL;
@@ -383,18 +372,42 @@ wxRegionIterator::wxRegionIterator(const wxRegion& region)
Reset(region); Reset(region);
} }
/* wxRegionIterator& wxRegionIterator::operator=(const wxRegionIterator& ri)
* Reset iterator for a new /e region. {
*/ delete [] m_rects;
m_current = ri.m_current;
m_numRects = ri.m_numRects;
if ( m_numRects )
{
m_rects = new wxRect[m_numRects];
for ( long n = 0; n < m_numRects; n++ )
m_rects[n] = ri.m_rects[n];
}
else
{
m_rects = NULL;
}
return *this;
}
// ----------------------------------------------------------------------------
// wxRegionIterator operations
// ----------------------------------------------------------------------------
// Reset iterator for a new region.
void wxRegionIterator::Reset(const wxRegion& region) void wxRegionIterator::Reset(const wxRegion& region)
{ {
m_current = 0; m_current = 0;
m_region = region; m_region = region;
if (m_rects) if (m_rects)
{
delete[] m_rects; delete[] m_rects;
m_rects = NULL; m_rects = NULL;
}
if (m_region.Empty()) if (m_region.Empty())
m_numRects = 0; m_numRects = 0;
@@ -421,7 +434,7 @@ void wxRegionIterator::Reset(const wxRegion& region)
m_numRects = header->nCount; m_numRects = header->nCount;
delete[] (char*) rgnData; delete[] (char*) rgnData;
#else #else // Win16
RECT rect; RECT rect;
::GetRgnBox(((wxRegionRefData*)region.m_refData)->m_region, &rect); ::GetRgnBox(((wxRegionRefData*)region.m_refData)->m_region, &rect);
m_rects = new wxRect[1]; m_rects = new wxRect[1];
@@ -431,55 +444,56 @@ void wxRegionIterator::Reset(const wxRegion& region)
m_rects[0].height = rect.bottom - rect.top; m_rects[0].height = rect.bottom - rect.top;
m_numRects = 1; m_numRects = 1;
#endif #endif // Win32/16
} }
} }
/* wxRegionIterator& wxRegionIterator::operator++()
* Increment iterator. The rectangle returned is the one after the
* incrementation.
*/
void wxRegionIterator::operator ++ ()
{ {
if (m_current < m_numRects) if (m_current < m_numRects)
++m_current; ++m_current;
return *this;
} }
/* wxRegionIterator wxRegionIterator::operator ++ (int)
* Increment iterator. The rectangle returned is the one before the
* incrementation.
*/
void wxRegionIterator::operator ++ (int)
{ {
wxRegionIterator tmp = *this;
if (m_current < m_numRects) if (m_current < m_numRects)
++m_current; ++m_current;
return tmp;
} }
// ----------------------------------------------------------------------------
// wxRegionIterator accessors
// ----------------------------------------------------------------------------
wxCoord wxRegionIterator::GetX() const wxCoord wxRegionIterator::GetX() const
{ {
if (m_current < m_numRects) wxCHECK_MSG( m_current < m_numRects, 0, _T("invalid wxRegionIterator") );
return m_rects[m_current].x;
return 0; return m_rects[m_current].x;
} }
wxCoord wxRegionIterator::GetY() const wxCoord wxRegionIterator::GetY() const
{ {
if (m_current < m_numRects) wxCHECK_MSG( m_current < m_numRects, 0, _T("invalid wxRegionIterator") );
return m_rects[m_current].y;
return 0; return m_rects[m_current].y;
} }
wxCoord wxRegionIterator::GetW() const wxCoord wxRegionIterator::GetW() const
{ {
if (m_current < m_numRects) wxCHECK_MSG( m_current < m_numRects, 0, _T("invalid wxRegionIterator") );
return m_rects[m_current].width;
return 0; return m_rects[m_current].width;
} }
wxCoord wxRegionIterator::GetH() const wxCoord wxRegionIterator::GetH() const
{ {
if (m_current < m_numRects) wxCHECK_MSG( m_current < m_numRects, 0, _T("invalid wxRegionIterator") );
return m_rects[m_current].height;
return 0; return m_rects[m_current].height;
} }