X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a724d7892daa5a4eb5e7eb615bfbb4779730f4a6..268766dd1f2a2d4d593d1d65893f62b5753ff20b:/src/motif/region.cpp diff --git a/src/motif/region.cpp b/src/motif/region.cpp index 7121fe63a3..fb3b1e3db2 100644 --- a/src/motif/region.cpp +++ b/src/motif/region.cpp @@ -3,7 +3,7 @@ // Purpose: Region class // Author: Markus Holzem/Julian Smart // Created: Fri Oct 24 10:46:34 MET 1997 -// RCS-ID: $Id$ +// RCS-ID: $Id$ // Copyright: (c) 1997 Markus Holzem/Julian Smart // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -15,13 +15,25 @@ #include "wx/region.h" #include "wx/gdicmn.h" +#ifdef __VMS__ +#pragma message disable nosimpint +#endif #include +#ifdef __VMS__ +#pragma message enable nosimpint +#endif // #include "wx/motif/private.h" -#if !USE_SHARED_LIBRARY - IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject) - IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject) -#endif + IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject) + IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject) + +// ---------------------------------------------------------------------------- +// list types +// ---------------------------------------------------------------------------- + +#include "wx/listimpl.cpp" + +WX_DEFINE_LIST(wxRectList); //----------------------------------------------------------------------------- // wxRegionRefData implementation @@ -29,24 +41,89 @@ class WXDLLEXPORT wxRegionRefData : public wxGDIRefData { public: - wxRegionRefData() - { - m_region = XCreateRegion(); - } - - wxRegionRefData(const wxRegionRefData& data) - { - m_region = XCreateRegion(); - XUnionRegion(m_region, data.m_region, m_region); - } - - ~wxRegionRefData() - { - XDestroyRegion(m_region); - } - Region m_region; + wxRegionRefData() + { + m_region = XCreateRegion(); + m_usingRects = FALSE; + m_rects = (wxRect*) NULL; + m_rectCount = 0; + } + + wxRegionRefData(const wxRegionRefData& data) + { + m_region = XCreateRegion(); + m_rects = (wxRect*) NULL; + m_rectCount = 0; + XUnionRegion(m_region, data.m_region, m_region); + + SetRects(data.m_rectCount, data.m_rects); + } + + ~wxRegionRefData() + { + XDestroyRegion(m_region); + DeleteRects(); + } + + wxRect* GetRects() { return m_rects; }; + void SetRects(const wxRectList& rectList); + void SetRects(int count, const wxRect* rects); + bool UsingRects() const { return m_usingRects; } + int GetRectCount() const { return m_rectCount; } + + void DeleteRects(); + + Region m_region; + wxRect* m_rects; + int m_rectCount; + bool m_usingRects; // TRUE if we're using the above. }; +void wxRegionRefData::SetRects(const wxRectList& rectList) +{ + DeleteRects(); + m_usingRects = (rectList.Number() > 0); + if (m_usingRects) + { + m_rectCount = rectList.Number(); + m_rects = new wxRect[m_rectCount]; + } + + wxRectList::Node* node = rectList.GetFirst(); + int i = 0; + while (node) { + wxRect* rect = node->GetData(); + m_rects[i] = * rect; + node = node->GetNext(); + i ++; + } +} + +void wxRegionRefData::SetRects(int count, const wxRect* rects) +{ + DeleteRects(); + m_usingRects = (count > 0); + if (m_usingRects) + { + m_rectCount = count; + m_rects = new wxRect[m_rectCount]; + int i; + for (i = 0; i < m_rectCount; i++) + m_rects[i] = rects[i]; + } +} + +void wxRegionRefData::DeleteRects() +{ + if (m_rects) + { + delete[] m_rects; + m_rects = (wxRect*) NULL; + } + m_rectCount = 0; + m_usingRects = FALSE; + } + #define M_REGION (((wxRegionRefData*)m_refData)->m_region) //----------------------------------------------------------------------------- @@ -60,28 +137,28 @@ wxRegion::wxRegion() { } -wxRegion::wxRegion(long x, long y, long w, long h) +wxRegion::wxRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h) { m_refData = new wxRegionRefData; - XRectangle rect; - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - XUnionRectWithRegion(&rect, M_REGION, M_REGION); + XRectangle rect; + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + XUnionRectWithRegion(&rect, M_REGION, M_REGION); } wxRegion::wxRegion(const wxPoint& topLeft, const wxPoint& bottomRight) { m_refData = new wxRegionRefData; - XRectangle rect; - rect.x = topLeft.x; - rect.y = topLeft.y; - rect.width = bottomRight.x - topLeft.x; - rect.height = bottomRight.y - topLeft.y; - XUnionRectWithRegion(&rect, M_REGION, M_REGION); + XRectangle rect; + rect.x = topLeft.x; + rect.y = topLeft.y; + rect.width = bottomRight.x - topLeft.x; + rect.height = bottomRight.y - topLeft.y; + XUnionRectWithRegion(&rect, M_REGION, M_REGION); } wxRegion::wxRegion(const wxRect& rect) @@ -89,9 +166,9 @@ wxRegion::wxRegion(const wxRect& rect) m_refData = new wxRegionRefData; XRectangle rect1; - rect1.x = rect.x; - rect1.y = rect.y; - rect1.width = rect.width; + rect1.x = rect.x; + rect1.y = rect.y; + rect1.width = rect.width; rect1.height = rect.height; XUnionRectWithRegion(&rect1, M_REGION, M_REGION); } @@ -105,7 +182,7 @@ wxRegion::~wxRegion() } // Get the internal region handle -WXRegion wxRegion::GetXRegion() +WXRegion wxRegion::GetXRegion() const { wxASSERT( m_refData !=NULL ); @@ -123,35 +200,34 @@ void wxRegion::Clear() } //! Combine rectangle (x, y, w, h) with this. -bool wxRegion::Combine(long x, long y, long width, long 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); - } +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. Region rectRegion = XCreateRegion(); - XRectangle rect; - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - XUnionRectWithRegion(&rect, rectRegion, rectRegion); + XRectangle rect; + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + XUnionRectWithRegion(&rect, rectRegion, rectRegion); - int mode = 0; // TODO platform-specific code switch (op) { case wxRGN_AND: - XIntersectRegion(M_REGION, rectRegion, M_REGION); + XIntersectRegion(M_REGION, rectRegion, M_REGION); break ; case wxRGN_OR: - XUnionRegion(M_REGION, rectRegion, M_REGION); + XUnionRegion(M_REGION, rectRegion, M_REGION); break ; case wxRGN_XOR: // TODO @@ -171,28 +247,27 @@ bool wxRegion::Combine(long x, long y, long width, long height, wxRegionOp op) //! Union /e region with this. 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); - } + 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); + } - int mode = 0; // TODO platform-specific code switch (op) { case wxRGN_AND: - XIntersectRegion(M_REGION, ((wxRegionRefData*)region.m_refData)->m_region, - M_REGION); + XIntersectRegion(M_REGION, ((wxRegionRefData*)region.m_refData)->m_region, + M_REGION); break ; case wxRGN_OR: - XUnionRegion(M_REGION, ((wxRegionRefData*)region.m_refData)->m_region, - M_REGION); + XUnionRegion(M_REGION, ((wxRegionRefData*)region.m_refData)->m_region, + M_REGION); break ; case wxRGN_XOR: // TODO @@ -219,23 +294,23 @@ bool wxRegion::Combine(const wxRect& rect, wxRegionOp op) //----------------------------------------------------------------------------- // Outer bounds of region -void wxRegion::GetBox(long& x, long& y, long&w, long &h) const +void wxRegion::GetBox(wxCoord& x, wxCoord& y, wxCoord&w, wxCoord &h) const { - if (m_refData) { - XRectangle rect; - XClipBox(M_REGION, &rect); - x = rect.x; - y = rect.y; - w = rect.width; - h = rect.height; - } else { - x = y = w = h = 0; - } + if (m_refData) { + XRectangle rect; + XClipBox(M_REGION, &rect); + x = rect.x; + y = rect.y; + w = rect.width; + h = rect.height; + } else { + x = y = w = h = 0; + } } wxRect wxRegion::GetBox() const { - long x, y, w, h; + wxCoord x, y, w, h; GetBox(x, y, w, h); return wxRect(x, y, w, h); } @@ -243,7 +318,7 @@ wxRect wxRegion::GetBox() const // Is region empty? bool wxRegion::Empty() const { - return m_refData ? XEmptyRegion(M_REGION) : TRUE; + return m_refData ? XEmptyRegion(M_REGION) : TRUE; } //----------------------------------------------------------------------------- @@ -251,10 +326,10 @@ bool wxRegion::Empty() const //----------------------------------------------------------------------------- // Does the region contain the point (x,y)? -wxRegionContain wxRegion::Contains(long x, long y) const +wxRegionContain wxRegion::Contains(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y)) const { - if (!m_refData) - return wxOutRegion; + if (!m_refData) + return wxOutRegion; // TODO. Return wxInRegion if within region. if (0) @@ -265,32 +340,32 @@ wxRegionContain wxRegion::Contains(long x, long y) const // Does the region contain the point pt? wxRegionContain wxRegion::Contains(const wxPoint& pt) const { - if (!m_refData) - return wxOutRegion; + if (!m_refData) + return wxOutRegion; - return XPointInRegion(M_REGION, pt.x, pt.y) ? wxInRegion : wxOutRegion; + return XPointInRegion(M_REGION, pt.x, pt.y) ? wxInRegion : wxOutRegion; } // Does the region contain the rectangle (x, y, w, h)? -wxRegionContain wxRegion::Contains(long x, long y, long w, long h) const +wxRegionContain wxRegion::Contains(wxCoord x, wxCoord y, wxCoord w, wxCoord h) const { - if (!m_refData) - return wxOutRegion; + if (!m_refData) + return wxOutRegion; - switch (XRectInRegion(M_REGION, x, y, w, h)) { - case RectangleIn: return wxInRegion; - case RectanglePart: return wxPartRegion; - } - return wxOutRegion; + switch (XRectInRegion(M_REGION, x, y, w, h)) { + case RectangleIn: return wxInRegion; + case RectanglePart: return wxPartRegion; + } + return wxOutRegion; } // Does the region contain the rectangle rect wxRegionContain wxRegion::Contains(const wxRect& rect) const { - if (!m_refData) - return wxOutRegion; + if (!m_refData) + return wxOutRegion; - long x, y, w, h; + wxCoord x, y, w, h; x = rect.x; y = rect.y; w = rect.GetWidth(); @@ -298,10 +373,42 @@ wxRegionContain wxRegion::Contains(const wxRect& rect) const return Contains(x, y, w, h); } +bool wxRegion::UsingRects() const +{ + return ((wxRegionRefData*)m_refData)->UsingRects(); +} + +/* +wxRectList& wxRegion::GetRectList() +{ + return ((wxRegionRefData*)m_refData)->GetRectList(); +} +*/ + +wxRect* wxRegion::GetRects() +{ + return ((wxRegionRefData*)m_refData)->GetRects(); +} + +int wxRegion::GetRectCount() const +{ + return ((wxRegionRefData*)m_refData)->GetRectCount(); +} + +void wxRegion::SetRects(const wxRectList& rectList) +{ + ((wxRegionRefData*)m_refData)->SetRects(rectList); +} + +void wxRegion::SetRects(int count, const wxRect* rects) +{ + ((wxRegionRefData*)m_refData)->SetRects(count, rects); +} + /////////////////////////////////////////////////////////////////////////////// -// // -// wxRegionIterator // -// // +// // +// wxRegionIterator // +// // /////////////////////////////////////////////////////////////////////////////// /*! @@ -324,7 +431,7 @@ wxRegionIterator::wxRegionIterator(const wxRegion& region) { m_rects = NULL; - Reset(region); + Reset(region); } /*! @@ -332,20 +439,50 @@ wxRegionIterator::wxRegionIterator(const wxRegion& region) */ void wxRegionIterator::Reset(const wxRegion& region) { - m_current = 0; - m_region = region; + m_current = 0; + m_region = region; if (m_rects) delete[] m_rects; m_rects = NULL; - if (m_region.Empty()) - m_numRects = 0; - else - { - // TODO create m_rects and fill with rectangles for this region + if (m_region.Empty()) m_numRects = 0; + else + { + // Create m_rects and fill with rectangles for this region. + // Since we can't find the rectangles in a region, we cheat + // by retrieving the rectangles explicitly set in wxPaintDC::wxPaintDC + // (dcclient.cpp). + if (m_region.UsingRects()) + { + wxRect* rects = m_region.GetRects(); + int count = m_region.GetRectCount(); + m_numRects = count; + m_rects = new wxRect[m_numRects]; + + for (size_t i = 0; i < m_numRects; i++) + m_rects[i] = rects[i]; + + /* + int i = 0; + wxRectList::Node* node = rectList.GetFirst(); + while (node) { + wxRect* rect = node->GetData(); + m_rects[i] = * rect; + node = node->GetNext(); + i ++; + } + */ + } + else + { + // For now, fudge by getting the whole bounding box. + m_rects = new wxRect[1]; + m_numRects = 1; + m_rects[0] = m_region.GetBox(); + } } } @@ -355,8 +492,8 @@ void wxRegionIterator::Reset(const wxRegion& region) */ void wxRegionIterator::operator ++ () { - if (m_current < m_numRects) - ++m_current; + if (m_current < m_numRects) + ++m_current; } /*! @@ -365,35 +502,35 @@ void wxRegionIterator::operator ++ () */ void wxRegionIterator::operator ++ (int) { - if (m_current < m_numRects) - ++m_current; + if (m_current < m_numRects) + ++m_current; } -long wxRegionIterator::GetX() const +wxCoord wxRegionIterator::GetX() const { - if (m_current < m_numRects) - return m_rects[m_current].x; - return 0; + if (m_current < m_numRects) + return m_rects[m_current].x; + return 0; } -long wxRegionIterator::GetY() const +wxCoord wxRegionIterator::GetY() const { - if (m_current < m_numRects) - return m_rects[m_current].y; - return 0; + if (m_current < m_numRects) + return m_rects[m_current].y; + return 0; } -long wxRegionIterator::GetW() const +wxCoord wxRegionIterator::GetW() const { - if (m_current < m_numRects) - return m_rects[m_current].width ; - return 0; + if (m_current < m_numRects) + return m_rects[m_current].width ; + return 0; } -long wxRegionIterator::GetH() const +wxCoord wxRegionIterator::GetH() const { - if (m_current < m_numRects) - return m_rects[m_current].height; - return 0; + if (m_current < m_numRects) + return m_rects[m_current].height; + return 0; }