1///////////////////////////////////////////////////////////////////////////// 2// Name: src/common/rgncmn.cpp 3// Purpose: Methods of wxRegion that have a generic implementation 4// Author: Robin Dunn 5// Modified by: 6// Created: 27-Mar-2003 7// RCS-ID: $Id: rgncmn.cpp 41901 2006-10-10 17:33:49Z PC $ 8// Copyright: (c) Robin Dunn 9// Licence: wxWindows licence 10///////////////////////////////////////////////////////////////////////////// 11 12// ============================================================================ 13// declarations 14// ============================================================================ 15 16// For compilers that support precompilation, includes "wx.h". 17#include "wx/wxprec.h" 18 19#ifdef __BORLANDC__ 20 #pragma hdrstop 21#endif 22 23#include "wx/region.h" 24 25#ifndef WX_PRECOMP 26 #include "wx/dcmemory.h" 27 #include "wx/bitmap.h" 28 #include "wx/image.h" 29#endif //WX_PRECOMP 30 31// ============================================================================ 32// wxRegionBase implementation 33// ============================================================================ 34 35// ---------------------------------------------------------------------------- 36// region comparision 37// ---------------------------------------------------------------------------- 38 39bool wxRegionBase::IsEqual(const wxRegion& region) const 40{ 41 if ( m_refData == region.GetRefData() ) 42 { 43 // regions are identical, hence equal 44 return true; 45 } 46 47 if ( !m_refData || !region.GetRefData() ) 48 { 49 // one, but not both, of the regions is invalid 50 return false; 51 } 52 53 return DoIsEqual(region); 54} 55 56// ---------------------------------------------------------------------------- 57// region to/from bitmap conversions 58// ---------------------------------------------------------------------------- 59 60wxBitmap wxRegionBase::ConvertToBitmap() const 61{ 62 wxRect box = GetBox(); 63 wxBitmap bmp(box.GetRight(), box.GetBottom()); 64 wxMemoryDC dc; 65 dc.SelectObject(bmp); 66 dc.SetBackground(*wxBLACK_BRUSH); 67 dc.Clear(); 68 dc.SetClippingRegion(*wx_static_cast(const wxRegion *, this)); 69 dc.SetBackground(*wxWHITE_BRUSH); 70 dc.Clear(); 71 dc.SelectObject(wxNullBitmap); 72 return bmp; 73} 74 75#if wxUSE_IMAGE 76 77static bool DoRegionUnion(wxRegionBase& region, 78 const wxImage& image, 79 unsigned char loR, 80 unsigned char loG, 81 unsigned char loB, 82 int tolerance) 83{ 84 unsigned char hiR, hiG, hiB; 85 86 hiR = (unsigned char)wxMin(0xFF, loR + tolerance); 87 hiG = (unsigned char)wxMin(0xFF, loG + tolerance); 88 hiB = (unsigned char)wxMin(0xFF, loB + tolerance); 89 90 // Loop through the image row by row, pixel by pixel, building up 91 // rectangles to add to the region. 92 int width = image.GetWidth(); 93 int height = image.GetHeight(); 94 for (int y=0; y < height; y++) 95 { 96 wxRect rect; 97 rect.y = y; 98 rect.height = 1; 99 100 for (int x=0; x < width; x++) 101 { 102 // search for a continuous range of non-transparent pixels 103 int x0 = x; 104 while ( x < width) 105 { 106 unsigned char R = image.GetRed(x,y); 107 unsigned char G = image.GetGreen(x,y); 108 unsigned char B = image.GetBlue(x,y); 109 if (( R >= loR && R <= hiR) && 110 ( G >= loG && G <= hiG) && 111 ( B >= loB && B <= hiB)) // It's transparent 112 break; 113 x++; 114 } 115 116 // Add the run of non-transparent pixels (if any) to the region 117 if (x > x0) { 118 rect.x = x0; 119 rect.width = x - x0; 120 region.Union(rect); 121 } 122 } 123 } 124 125 return true; 126} 127 128 129bool wxRegionBase::Union(const wxBitmap& bmp) 130{ 131 if (bmp.GetMask()) 132 { 133 wxImage image = bmp.ConvertToImage(); 134 wxASSERT_MSG( image.HasMask(), _T("wxBitmap::ConvertToImage doesn't preserve mask?") ); 135 return DoRegionUnion(*this, image, 136 image.GetMaskRed(), 137 image.GetMaskGreen(), 138 image.GetMaskBlue(), 139 0); 140 } 141 else 142 { 143 return Union(0, 0, bmp.GetWidth(), bmp.GetHeight()); 144 } 145} 146 147bool wxRegionBase::Union(const wxBitmap& bmp, 148 const wxColour& transColour, 149 int tolerance) 150{ 151 wxImage image = bmp.ConvertToImage(); 152 return DoRegionUnion(*this, image, 153 transColour.Red(), 154 transColour.Green(), 155 transColour.Blue(), 156 tolerance); 157} 158 159#endif // wxUSE_IMAGE 160 161#ifdef wxHAS_REGION_COMBINE 162// ============================================================================ 163// wxRegionWithCombine 164// ============================================================================ 165 166// implement some wxRegionBase pure virtuals in terms of Combine() 167bool wxRegionWithCombine::DoUnionWithRect(const wxRect& rect) 168{ 169 return Combine(rect, wxRGN_OR); 170} 171 172bool wxRegionWithCombine::DoUnionWithRegion(const wxRegion& region) 173{ 174 return DoCombine(region, wxRGN_OR); 175} 176 177bool wxRegionWithCombine::DoIntersect(const wxRegion& region) 178{ 179 return DoCombine(region, wxRGN_AND); 180} 181 182bool wxRegionWithCombine::DoSubtract(const wxRegion& region) 183{ 184 return DoCombine(region, wxRGN_DIFF); 185} 186 187bool wxRegionWithCombine::DoXor(const wxRegion& region) 188{ 189 return DoCombine(region, wxRGN_XOR); 190} 191 192#endif // wxHAS_REGION_COMBINE 193