From 0fb067bbe6ca68e12c4f14d734001c5a9bd6d4a1 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Thu, 31 Jan 2002 16:00:13 +0000
Subject: [PATCH] implemented wxRegion::Offset() for MSW and documented it

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13936 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/region.tex | 45 +++++++++++++++++++-------------
 include/wx/msw/region.h  | 40 +++++++++++++++++++----------
 src/msw/region.cpp       | 55 +++++++++++++++++++++++++++-------------
 3 files changed, 91 insertions(+), 49 deletions(-)

diff --git a/docs/latex/wx/region.tex b/docs/latex/wx/region.tex
index a5c3001478..dbffb94465 100644
--- a/docs/latex/wx/region.tex
+++ b/docs/latex/wx/region.tex
@@ -24,7 +24,7 @@ reference counting, so copying and assignment operations are fast.
 
 Default constructor.
 
-\func{}{wxRegion}{\param{long}{ x}, \param{long}{ y}, \param{long}{ width}, \param{long}{ height}}
+\func{}{wxRegion}{\param{wxCoord}{ x}, \param{wxCoord}{ y}, \param{wxCoord}{ width}, \param{wxCoord}{ height}}
 
 Constructs a rectangular region with the given position and size.
 
@@ -97,7 +97,7 @@ Returns the outer bounds of the region.
 
 \membersection{wxRegion::Intersect}\label{wxregionintersect}
 
-\func{bool}{Intersect}{\param{long}{ x}, \param{long}{ y}, \param{long}{ width}, \param{long}{ height}}
+\func{bool}{Intersect}{\param{wxCoord}{ x}, \param{wxCoord}{ y}, \param{wxCoord}{ width}, \param{wxCoord}{ height}}
 
 Finds the intersection of this region and another, rectangular region, specified using position and size.
 
@@ -111,7 +111,7 @@ Finds the intersection of this region and another region.
 
 \wxheading{Return value}
 
-TRUE if successful, FALSE otherwise.
+{\tt TRUE} if successful, {\tt FALSE} otherwise.
 
 \wxheading{Remarks}
 
@@ -122,7 +122,7 @@ is stored in this region.
 
 \constfunc{bool}{IsEmpty}{\void}
 
-Returns TRUE if the region is empty, FALSE otherwise.
+Returns {\tt TRUE} if the region is empty, {\tt FALSE} otherwise.
 
 \membersection{wxRegion::Subtract}\label{wxregionsubstract}
 
@@ -136,16 +136,27 @@ Subtracts a region from this region.
 
 \wxheading{Return value}
 
-TRUE if successful, FALSE otherwise.
+{\tt TRUE} if successful, {\tt FALSE} otherwise.
 
 \wxheading{Remarks}
 
 This operation combines the parts of 'this' region that are not part of the second region.
 The result is stored in this region.
 
+\membersection{wxRegion::Offset}\label{wxregionoffset}
+
+\func{bool}{Offset}{\param{wxCoord}{ x}, \param{wxCoord}{ y}}
+
+Moves the region by the specified offsets in horizontal and vertical
+directions.
+
+\wxheading{Return value}
+
+{\tt TRUE} if successful, {\tt FALSE} otherwise (the region is unchanged then).
+
 \membersection{wxRegion::Union}\label{wxregionunion}
 
-\func{bool}{Union}{\param{long}{ x}, \param{long}{ y}, \param{long}{ width}, \param{long}{ height}}
+\func{bool}{Union}{\param{wxCoord}{ x}, \param{wxCoord}{ y}, \param{wxCoord}{ width}, \param{wxCoord}{ height}}
 
 Finds the union of this region and another, rectangular region, specified using position and size.
 
@@ -159,7 +170,7 @@ Finds the union of this region and another region.
 
 \wxheading{Return value}
 
-TRUE if successful, FALSE otherwise.
+{\tt TRUE} if successful, {\tt FALSE} otherwise.
 
 \wxheading{Remarks}
 
@@ -168,7 +179,7 @@ The result is stored in this region.
 
 \membersection{wxRegion::Xor}\label{wxregionxor}
 
-\func{bool}{Xor}{\param{long}{ x}, \param{long}{ y}, \param{long}{ width}, \param{long}{ height}}
+\func{bool}{Xor}{\param{wxCoord}{ x}, \param{wxCoord}{ y}, \param{wxCoord}{ width}, \param{wxCoord}{ height}}
 
 Finds the Xor of this region and another, rectangular region, specified using position and size.
 
@@ -182,7 +193,7 @@ Finds the Xor of this region and another region.
 
 \wxheading{Return value}
 
-TRUE if successful, FALSE otherwise.
+{\tt TRUE} if successful, {\tt FALSE} otherwise.
 
 \wxheading{Remarks}
 
@@ -231,37 +242,37 @@ Creates an iterator object given a region.
 
 \membersection{wxRegionIterator::GetX}
 
-\constfunc{long}{GetX}{\void}
+\constfunc{wxCoord}{GetX}{\void}
 
 Returns the x value for the current region.
 
 \membersection{wxRegionIterator::GetY}
 
-\constfunc{long}{GetY}{\void}
+\constfunc{wxCoord}{GetY}{\void}
 
 Returns the y value for the current region.
 
 \membersection{wxRegionIterator::GetW}
 
-\constfunc{long}{GetW}{\void}
+\constfunc{wxCoord}{GetW}{\void}
 
 An alias for GetWidth.
 
 \membersection{wxRegionIterator::GetWidth}
 
-\constfunc{long}{GetWidth}{\void}
+\constfunc{wxCoord}{GetWidth}{\void}
 
 Returns the width value for the current region.
 
 \membersection{wxRegionIterator::GetH}
 
-\constfunc{long}{GetH}{\void}
+\constfunc{wxCoord}{GetH}{\void}
 
 An alias for GetHeight.
 
 \membersection{wxRegionIterator::GetHeight}
 
-\constfunc{long}{GetWidth}{\void}
+\constfunc{wxCoord}{GetWidth}{\void}
 
 Returns the width value for the current region.
 
@@ -275,7 +286,7 @@ Returns the current rectangle.
 
 \constfunc{bool}{HaveRects}{\void}
 
-Returns TRUE if there are still some rectangles; otherwise returns FALSE.
+Returns {\tt TRUE} if there are still some rectangles; otherwise returns {\tt FALSE}.
 
 \membersection{wxRegionIterator::Reset}
 
@@ -299,7 +310,7 @@ Increment operator. Increments the iterator to the next region.
 
 \constfunc{}{operator bool}{\void}
 
-Returns TRUE if there are still some rectangles; otherwise returns FALSE.
+Returns {\tt TRUE} if there are still some rectangles; otherwise returns {\tt FALSE}.
 
 You can use this to test the iterator object as if it were of type bool.
 
diff --git a/include/wx/msw/region.h b/include/wx/msw/region.h
index 58c4d94baa..ae99e4a5d6 100644
--- a/include/wx/msw/region.h
+++ b/include/wx/msw/region.h
@@ -59,31 +59,38 @@ public:
         { Ref(r); return (*this); }
 
     // Modify region
+    // -------------
+
     // Clear current region
-    void Clear(void);
+    void Clear();
+
+    // Move the region
+    bool Offset(wxCoord x, wxCoord y);
 
     // Union rectangle or region with this.
-    inline bool Union(wxCoord x, wxCoord y, wxCoord width, wxCoord height) { return Combine(x, y, width, height, wxRGN_OR); }
-    inline bool Union(const wxRect& rect) { return Combine(rect, wxRGN_OR); }
-    inline bool Union(const wxRegion& region) { return Combine(region, wxRGN_OR); }
+    bool Union(wxCoord x, wxCoord y, wxCoord width, wxCoord height) { return Combine(x, y, width, height, wxRGN_OR); }
+    bool Union(const wxRect& rect) { return Combine(rect, wxRGN_OR); }
+    bool Union(const wxRegion& region) { return Combine(region, wxRGN_OR); }
 
     // Intersect rectangle or region with this.
-    inline bool Intersect(wxCoord x, wxCoord y, wxCoord width, wxCoord height) { return Combine(x, y, width, height, wxRGN_AND); }
-    inline bool Intersect(const wxRect& rect)  { return Combine(rect, wxRGN_AND); }
-    inline bool Intersect(const wxRegion& region)  { return Combine(region, wxRGN_AND); }
+    bool Intersect(wxCoord x, wxCoord y, wxCoord width, wxCoord height) { return Combine(x, y, width, height, wxRGN_AND); }
+    bool Intersect(const wxRect& rect)  { return Combine(rect, wxRGN_AND); }
+    bool Intersect(const wxRegion& region)  { return Combine(region, wxRGN_AND); }
 
     // Subtract rectangle or region from this:
     // Combines the parts of 'this' that are not part of the second region.
-    inline bool Subtract(wxCoord x, wxCoord y, wxCoord width, wxCoord height) { return Combine(x, y, width, height, wxRGN_DIFF); }
-    inline bool Subtract(const wxRect& rect)  { return Combine(rect, wxRGN_DIFF); }
-    inline bool Subtract(const wxRegion& region)  { return Combine(region, wxRGN_DIFF); }
+    bool Subtract(wxCoord x, wxCoord y, wxCoord width, wxCoord height) { return Combine(x, y, width, height, wxRGN_DIFF); }
+    bool Subtract(const wxRect& rect)  { return Combine(rect, wxRGN_DIFF); }
+    bool Subtract(const wxRegion& region)  { return Combine(region, wxRGN_DIFF); }
 
     // XOR: the union of two combined regions except for any overlapping areas.
-    inline bool Xor(wxCoord x, wxCoord y, wxCoord width, wxCoord height) { return Combine(x, y, width, height, wxRGN_XOR); }
-    inline bool Xor(const wxRect& rect)  { return Combine(rect, wxRGN_XOR); }
-    inline bool Xor(const wxRegion& region)  { return Combine(region, wxRGN_XOR); }
+    bool Xor(wxCoord x, wxCoord y, wxCoord width, wxCoord height) { return Combine(x, y, width, height, wxRGN_XOR); }
+    bool Xor(const wxRect& rect)  { return Combine(rect, wxRGN_XOR); }
+    bool Xor(const wxRegion& region)  { return Combine(region, wxRGN_XOR); }
 
     // Information on region
+    // ---------------------
+
     // Outer bounds of region
     void GetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const;
     wxRect GetBox(void) const ;
@@ -110,8 +117,13 @@ public:
     // Get internal region handle
     WXHRGN GetHRGN() const;
 
-    DECLARE_DYNAMIC_CLASS(wxRegion);
+protected:
+    virtual wxObjectRefData *CreateData() const;
+    virtual wxObjectRefData *CloneData(wxObjectRefData *data) const;
+
     friend class WXDLLEXPORT wxRegionIterator;
+
+    DECLARE_DYNAMIC_CLASS(wxRegion)
 };
 
 class WXDLLEXPORT wxRegionIterator : public wxObject
diff --git a/src/msw/region.cpp b/src/msw/region.cpp
index c91f276350..d0336daaff 100644
--- a/src/msw/region.cpp
+++ b/src/msw/region.cpp
@@ -127,6 +127,16 @@ wxRegion::~wxRegion()
     // m_refData unrefed in ~wxObject
 }
 
+wxObjectRefData *wxRegion::CreateData() const
+{
+    return new wxRegionRefData;
+}
+
+wxObjectRefData *wxRegion::CloneData(wxObjectRefData *data) const
+{
+    return new wxRegionRefData(*(wxRegionRefData *)data);
+}
+
 //-----------------------------------------------------------------------------
 // Modify region
 //-----------------------------------------------------------------------------
@@ -137,18 +147,30 @@ void wxRegion::Clear()
     UnRef();
 }
 
+bool wxRegion::Offset(wxCoord x, wxCoord y)
+{
+    if ( !x && !y )
+    {
+        // nothing to do
+        return TRUE;
+    }
+
+    AllocExclusive();
+
+    if ( ::OffsetRgn(GetHrgn(), x, y) == ERROR )
+    {
+        wxLogLastError(_T("OffsetRgn"));
+
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
 // Combine rectangle (x, y, w, h) with this.
 bool wxRegion::Combine(wxCoord x, wxCoord y, wxCoord width, wxCoord height, wxRegionOp op)
 {
-    // Don't change shared data
-    if (!m_refData) {
-        m_refData = new wxRegionRefData();
-    } else if (m_refData->GetRefCount() > 1) {
-        wxRegionRefData* ref = (wxRegionRefData*)m_refData;
-        UnRef();
-        m_refData = new wxRegionRefData(*ref);
-    }
-    // If ref count is 1, that means it's 'ours' anyway so no action.
+    AllocExclusive();
 
     HRGN rectRegion = ::CreateRectRgn(x, y, x + width, y + height);
 
@@ -164,7 +186,11 @@ bool wxRegion::Combine(wxCoord x, wxCoord y, wxCoord width, wxCoord height, wxRe
             mode = RGN_COPY; break ;
     }
 
-    bool success = (ERROR != ::CombineRgn(M_REGION, M_REGION, rectRegion, mode));
+    bool success = ::CombineRgn(M_REGION, M_REGION, rectRegion, mode) != ERROR;
+    if ( !success )
+    {
+        wxLogLastError(_T("CombineRgn"));
+    }
 
     ::DeleteObject(rectRegion);
 
@@ -177,14 +203,7 @@ bool wxRegion::Combine(const wxRegion& region, wxRegionOp op)
     if (region.Empty())
         return FALSE;
 
-    // Don't change shared data
-    if (!m_refData) {
-        m_refData = new wxRegionRefData();
-    } else    if (m_refData->GetRefCount() > 1) {
-        wxRegionRefData* ref = (wxRegionRefData*)m_refData;
-        UnRef();
-        m_refData = new wxRegionRefData(*ref);
-    }
+    AllocExclusive();
 
     int mode = 0;
     switch (op)
-- 
2.50.0

