]> git.saurik.com Git - wxWidgets.git/blob - src/msw/brush.cpp
fixed tests for dashed/dotted pens under OS != NT (bug 1182319)
[wxWidgets.git] / src / msw / brush.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/brush.cpp
3 // Purpose: wxBrush
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
17 #pragma implementation "brush.h"
18 #endif
19
20 // ----------------------------------------------------------------------------
21 // headers
22 // ----------------------------------------------------------------------------
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/list.h"
33 #include "wx/utils.h"
34 #include "wx/app.h"
35 #include "wx/brush.h"
36 #endif // WX_PRECOMP
37
38 #include "wx/msw/private.h"
39
40 // ----------------------------------------------------------------------------
41 // private classes
42 // ----------------------------------------------------------------------------
43
44 class WXDLLEXPORT wxBrushRefData: public wxGDIRefData
45 {
46 public:
47 wxBrushRefData(const wxColour& colour = wxNullColour, int style = wxSOLID);
48 wxBrushRefData(const wxBitmap& stipple);
49 wxBrushRefData(const wxBrushRefData& data);
50 virtual ~wxBrushRefData();
51
52 bool operator==(const wxBrushRefData& data) const;
53
54 HBRUSH GetHBRUSH();
55 void Free();
56
57 const wxColour& GetColour() const { return m_colour; }
58 int GetStyle() const { return m_style; }
59 wxBitmap *GetStipple() { return &m_stipple; }
60
61 void SetColour(const wxColour& colour) { Free(); m_colour = colour; }
62 void SetStyle(int style) { Free(); m_style = style; }
63 void SetStipple(const wxBitmap& stipple) { Free(); DoSetStipple(stipple); }
64
65 private:
66 void DoSetStipple(const wxBitmap& stipple);
67
68 int m_style;
69 wxBitmap m_stipple;
70 wxColour m_colour;
71 HBRUSH m_hBrush;
72
73 // no assignment operator, the objects of this class are shared and never
74 // assigned after being created once
75 wxBrushRefData& operator=(const wxBrushRefData&);
76 };
77
78 #define M_BRUSHDATA ((wxBrushRefData *)m_refData)
79
80 // ============================================================================
81 // wxBrushRefData implementation
82 // ============================================================================
83
84 IMPLEMENT_DYNAMIC_CLASS(wxBrush, wxGDIObject)
85
86 // ----------------------------------------------------------------------------
87 // wxBrushRefData ctors/dtor
88 // ----------------------------------------------------------------------------
89
90 wxBrushRefData::wxBrushRefData(const wxColour& colour, int style)
91 : m_colour(colour)
92 {
93 m_style = style;
94
95 m_hBrush = NULL;
96 }
97
98 wxBrushRefData::wxBrushRefData(const wxBitmap& stipple)
99 {
100 DoSetStipple(stipple);
101
102 m_hBrush = NULL;
103 }
104
105 wxBrushRefData::wxBrushRefData(const wxBrushRefData& data)
106 : wxGDIRefData(),
107 m_stipple(data.m_stipple),
108 m_colour(data.m_colour)
109 {
110 m_style = data.m_style;
111
112 // we can't share HBRUSH, we'd need to create another one ourselves
113 m_hBrush = NULL;
114 }
115
116 wxBrushRefData::~wxBrushRefData()
117 {
118 Free();
119 }
120
121 // ----------------------------------------------------------------------------
122 // wxBrushRefData accesors
123 // ----------------------------------------------------------------------------
124
125 bool wxBrushRefData::operator==(const wxBrushRefData& data) const
126 {
127 // don't compare HBRUSHes
128 return m_style == data.m_style &&
129 m_colour == data.m_colour &&
130 m_stipple == data.m_stipple;
131 }
132
133 void wxBrushRefData::DoSetStipple(const wxBitmap& stipple)
134 {
135 m_stipple = stipple;
136 m_style = stipple.GetMask() ? wxSTIPPLE_MASK_OPAQUE : wxSTIPPLE;
137 }
138
139 // ----------------------------------------------------------------------------
140 // wxBrushRefData resource handling
141 // ----------------------------------------------------------------------------
142
143 void wxBrushRefData::Free()
144 {
145 if ( m_hBrush )
146 {
147 ::DeleteObject(m_hBrush);
148
149 m_hBrush = NULL;
150 }
151 }
152
153 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
154
155 static int TranslateHatchStyle(int style)
156 {
157 switch ( style )
158 {
159 case wxBDIAGONAL_HATCH: return HS_BDIAGONAL;
160 case wxCROSSDIAG_HATCH: return HS_DIAGCROSS;
161 case wxFDIAGONAL_HATCH: return HS_FDIAGONAL;
162 case wxCROSS_HATCH: return HS_CROSS;
163 case wxHORIZONTAL_HATCH:return HS_HORIZONTAL;
164 case wxVERTICAL_HATCH: return HS_VERTICAL;
165 default: return -1;
166 }
167 }
168
169 #endif // !__WXMICROWIN__ && !__WXWINCE__
170
171 HBRUSH wxBrushRefData::GetHBRUSH()
172 {
173 if ( !m_hBrush )
174 {
175 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
176 int hatchStyle = TranslateHatchStyle(m_style);
177 if ( hatchStyle == -1 )
178 #endif // !__WXMICROWIN__ && !__WXWINCE__
179 {
180 switch ( m_style )
181 {
182 case wxTRANSPARENT:
183 m_hBrush = (HBRUSH)::GetStockObject(NULL_BRUSH);
184 break;
185
186 case wxSTIPPLE:
187 m_hBrush = ::CreatePatternBrush(GetHbitmapOf(m_stipple));
188 break;
189
190 case wxSTIPPLE_MASK_OPAQUE:
191 m_hBrush = ::CreatePatternBrush((HBITMAP)m_stipple.GetMask()
192 ->GetMaskBitmap());
193 break;
194
195 default:
196 wxFAIL_MSG( _T("unknown brush style") );
197 // fall through
198
199 case wxSOLID:
200 m_hBrush = ::CreateSolidBrush(m_colour.GetPixel());
201 break;
202 }
203 }
204 #ifndef __WXWINCE__
205 else // create a hatched brush
206 {
207 m_hBrush = ::CreateHatchBrush(hatchStyle, m_colour.GetPixel());
208 }
209 #endif
210
211 if ( !m_hBrush )
212 {
213 wxLogLastError(_T("CreateXXXBrush()"));
214 }
215 }
216
217 return m_hBrush;
218 }
219
220 // ============================================================================
221 // wxBrush implementation
222 // ============================================================================
223
224 // ----------------------------------------------------------------------------
225 // wxBrush ctors/dtor
226 // ----------------------------------------------------------------------------
227
228 wxBrush::wxBrush()
229 {
230 }
231
232 wxBrush::wxBrush(const wxColour& col, int style)
233 {
234 m_refData = new wxBrushRefData(col, style);
235 }
236
237 wxBrush::wxBrush(const wxBitmap& stipple)
238 {
239 m_refData = new wxBrushRefData(stipple);
240 }
241
242 wxBrush::~wxBrush()
243 {
244 }
245
246 // ----------------------------------------------------------------------------
247 // wxBrush house keeping stuff
248 // ----------------------------------------------------------------------------
249
250 wxBrush& wxBrush::operator=(const wxBrush& brush)
251 {
252 if ( this != &brush )
253 {
254 Ref(brush);
255 }
256
257 return *this;
258 }
259
260 bool wxBrush::operator==(const wxBrush& brush) const
261 {
262 const wxBrushRefData *brushData = (wxBrushRefData *)brush.m_refData;
263
264 // an invalid brush is considered to be only equal to another invalid brush
265 return m_refData ? (brushData && *M_BRUSHDATA == *brushData) : !brushData;
266 }
267
268 wxObjectRefData *wxBrush::CreateRefData() const
269 {
270 return new wxBrushRefData;
271 }
272
273 wxObjectRefData *wxBrush::CloneRefData(const wxObjectRefData *data) const
274 {
275 return new wxBrushRefData(*(const wxBrushRefData *)data);
276 }
277
278 // ----------------------------------------------------------------------------
279 // wxBrush accessors
280 // ----------------------------------------------------------------------------
281
282 wxColour wxBrush::GetColour() const
283 {
284 wxCHECK_MSG( Ok(), wxNullColour, _T("invalid brush") );
285
286 return M_BRUSHDATA->GetColour();
287 }
288
289 int wxBrush::GetStyle() const
290 {
291 wxCHECK_MSG( Ok(), 0, _T("invalid brush") );
292
293 return M_BRUSHDATA->GetStyle();
294 }
295
296 wxBitmap *wxBrush::GetStipple() const
297 {
298 wxCHECK_MSG( Ok(), NULL, _T("invalid brush") );
299
300 return M_BRUSHDATA->GetStipple();
301 }
302
303 WXHANDLE wxBrush::GetResourceHandle() const
304 {
305 wxCHECK_MSG( Ok(), FALSE, _T("invalid brush") );
306
307 return (WXHANDLE)M_BRUSHDATA->GetHBRUSH();
308 }
309
310 // ----------------------------------------------------------------------------
311 // wxBrush setters
312 // ----------------------------------------------------------------------------
313
314 void wxBrush::SetColour(const wxColour& col)
315 {
316 AllocExclusive();
317
318 M_BRUSHDATA->SetColour(col);
319 }
320
321 void wxBrush::SetColour(unsigned char r, unsigned char g, unsigned char b)
322 {
323 AllocExclusive();
324
325 M_BRUSHDATA->SetColour(wxColour(r, g, b));
326 }
327
328 void wxBrush::SetStyle(int style)
329 {
330 AllocExclusive();
331
332 M_BRUSHDATA->SetStyle(style);
333 }
334
335 void wxBrush::SetStipple(const wxBitmap& stipple)
336 {
337 AllocExclusive();
338
339 M_BRUSHDATA->SetStipple(stipple);
340 }
341
342