]> git.saurik.com Git - wxWidgets.git/blame - src/msw/pen.cpp
derive wxConfig classes from wxObject and add wxRTTI macros to them (patch 1587607)
[wxWidgets.git] / src / msw / pen.cpp
CommitLineData
2bda0e17 1/////////////////////////////////////////////////////////////////////////////
46562151 2// Name: src/msw/pen.cpp
2bda0e17
KB
3// Purpose: wxPen
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
6c9a19aa 8// Copyright: (c) Julian Smart
65571936 9// Licence: wxWindows licence
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
2bda0e17
KB
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
8ecff181 16 #pragma hdrstop
2bda0e17
KB
17#endif
18
f5590243
WS
19#include "wx/pen.h"
20
2bda0e17 21#ifndef WX_PRECOMP
ce3b4b90 22 #include "wx/bitmap.h"
8ecff181 23 #include "wx/utils.h"
2bda0e17
KB
24#endif
25
26#include "wx/msw/private.h"
2bda0e17 27
ce3b4b90
PC
28typedef WXDWORD wxMSWDash;
29
a6c81161 30static int wx2msPenStyle(int wx_style);
ef59847c 31
ce3b4b90
PC
32#define M_PENDATA ((wxPenRefData*)m_refData)
33
34class WXDLLEXPORT wxPenRefData : public wxGDIRefData
35{
36public:
37 wxPenRefData();
38 wxPenRefData(const wxPenRefData& data);
39 virtual ~wxPenRefData();
40
41 bool operator==(const wxPenRefData& data) const
42 {
43 // we intentionally don't compare m_hPen fields here
44 return m_style == data.m_style &&
45 m_width == data.m_width &&
46 m_join == data.m_join &&
47 m_cap == data.m_cap &&
48 m_colour == data.m_colour &&
49 (m_style != wxSTIPPLE || m_stipple.IsSameAs(data.m_stipple)) &&
50 (m_style != wxUSER_DASH ||
51 (m_nbDash == data.m_nbDash &&
52 memcmp(m_dash, data.m_dash, m_nbDash*sizeof(wxDash)) == 0));
53 }
54
55 int m_width;
56 int m_style;
57 int m_join;
58 int m_cap;
59 wxBitmap m_stipple;
60 int m_nbDash;
61 wxDash * m_dash;
62 wxColour m_colour;
63 WXHPEN m_hPen;
64
65 DECLARE_NO_ASSIGN_CLASS(wxPenRefData)
66};
2bda0e17 67
e4a81a2e 68wxPenRefData::wxPenRefData()
2bda0e17 69{
2bda0e17
KB
70 m_style = wxSOLID;
71 m_width = 1;
72 m_join = wxJOIN_ROUND ;
73 m_cap = wxCAP_ROUND ;
74 m_nbDash = 0 ;
edd97174 75 m_dash = (wxDash*)NULL;
2bda0e17
KB
76 m_hPen = 0;
77}
78
b823f5a1 79wxPenRefData::wxPenRefData(const wxPenRefData& data)
04a18b0d 80 :wxGDIRefData()
b823f5a1
JS
81{
82 m_style = data.m_style;
83 m_width = data.m_width;
84 m_join = data.m_join;
85 m_cap = data.m_cap;
86 m_nbDash = data.m_nbDash;
87 m_dash = data.m_dash;
88 m_colour = data.m_colour;
89 m_hPen = 0;
90}
91
e4a81a2e 92wxPenRefData::~wxPenRefData()
2bda0e17 93{
8b0975a3
VZ
94 if ( m_hPen )
95 ::DeleteObject((HPEN) m_hPen);
2bda0e17
KB
96}
97
98// Pens
99
ce3b4b90
PC
100IMPLEMENT_DYNAMIC_CLASS(wxPen, wxGDIObject)
101
e4a81a2e 102wxPen::wxPen()
2bda0e17 103{
2bda0e17
KB
104}
105
106wxPen::~wxPen()
107{
2bda0e17
KB
108}
109
110// Should implement Create
debe6624 111wxPen::wxPen(const wxColour& col, int Width, int Style)
2bda0e17
KB
112{
113 m_refData = new wxPenRefData;
114
115 M_PENDATA->m_colour = col;
116// M_PENDATA->m_stipple = NULL;
117 M_PENDATA->m_width = Width;
118 M_PENDATA->m_style = Style;
119 M_PENDATA->m_join = wxJOIN_ROUND ;
120 M_PENDATA->m_cap = wxCAP_ROUND ;
121 M_PENDATA->m_nbDash = 0 ;
edd97174 122 M_PENDATA->m_dash = (wxDash*)NULL;
2bda0e17
KB
123 M_PENDATA->m_hPen = 0 ;
124
2bda0e17 125 RealizeResource();
2bda0e17
KB
126}
127
debe6624 128wxPen::wxPen(const wxBitmap& stipple, int Width)
2bda0e17 129{
c45a644e 130 m_refData = new wxPenRefData;
2bda0e17
KB
131
132// M_PENDATA->m_colour = col;
c45a644e
RR
133 M_PENDATA->m_stipple = stipple;
134 M_PENDATA->m_width = Width;
135 M_PENDATA->m_style = wxSTIPPLE;
136 M_PENDATA->m_join = wxJOIN_ROUND ;
137 M_PENDATA->m_cap = wxCAP_ROUND ;
138 M_PENDATA->m_nbDash = 0 ;
edd97174 139 M_PENDATA->m_dash = (wxDash*)NULL;
c45a644e 140 M_PENDATA->m_hPen = 0 ;
2bda0e17 141
c45a644e 142 RealizeResource();
2bda0e17
KB
143}
144
ce3b4b90
PC
145bool wxPen::operator==(const wxPen& pen) const
146{
147 const wxPenRefData *penData = wx_static_cast(const wxPenRefData*, pen.m_refData);
148
149 // an invalid pen is only equal to another invalid pen
150 return m_refData ? penData && *M_PENDATA == *penData : !penData;
151}
152
e4a81a2e 153bool wxPen::RealizeResource()
2bda0e17 154{
8b0975a3
VZ
155 if ( !M_PENDATA || M_PENDATA->m_hPen )
156 return false;
157
158 if (M_PENDATA->m_style==wxTRANSPARENT)
c45a644e 159 {
8b0975a3
VZ
160 M_PENDATA->m_hPen = (WXHPEN) ::GetStockObject(NULL_PEN);
161 return true;
162 }
163
164 static const int os = wxGetOsVersion();
165 COLORREF ms_colour = M_PENDATA->m_colour.GetPixel();
166
167 // Join style, Cap style, Pen Stippling
168#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
169 // Only NT can display dashed or dotted lines with width > 1
406d283a 170 if ( os != wxOS_WINDOWS_NT &&
f3ebca94
VZ
171 (M_PENDATA->m_style == wxDOT ||
172 M_PENDATA->m_style == wxLONG_DASH ||
173 M_PENDATA->m_style == wxSHORT_DASH ||
174 M_PENDATA->m_style == wxDOT_DASH ||
175 M_PENDATA->m_style == wxUSER_DASH) &&
8b0975a3
VZ
176 M_PENDATA->m_width > 1 )
177 {
178 M_PENDATA->m_width = 1;
179 }
180
181 if (M_PENDATA->m_join==wxJOIN_ROUND &&
182 M_PENDATA->m_cap==wxCAP_ROUND &&
183 M_PENDATA->m_style!=wxUSER_DASH &&
184 M_PENDATA->m_style!=wxSTIPPLE &&
185 M_PENDATA->m_width <= 1)
186 {
187 M_PENDATA->m_hPen =
188 (WXHPEN) CreatePen( wx2msPenStyle(M_PENDATA->m_style),
189 M_PENDATA->m_width,
190 ms_colour );
191 }
192 else
193 {
194 DWORD ms_style = PS_GEOMETRIC | wx2msPenStyle(M_PENDATA->m_style);
195
196 switch(M_PENDATA->m_join)
c45a644e 197 {
8b0975a3
VZ
198 case wxJOIN_BEVEL: ms_style |= PS_JOIN_BEVEL; break;
199 case wxJOIN_MITER: ms_style |= PS_JOIN_MITER; break;
200 default:
201 case wxJOIN_ROUND: ms_style |= PS_JOIN_ROUND; break;
c45a644e
RR
202 }
203
8b0975a3 204 switch(M_PENDATA->m_cap)
c45a644e 205 {
8b0975a3
VZ
206 case wxCAP_PROJECTING: ms_style |= PS_ENDCAP_SQUARE; break;
207 case wxCAP_BUTT: ms_style |= PS_ENDCAP_FLAT; break;
208 default:
209 case wxCAP_ROUND: ms_style |= PS_ENDCAP_ROUND; break;
c45a644e 210 }
8b0975a3
VZ
211
212 LOGBRUSH logb;
213
214 switch(M_PENDATA->m_style)
c45a644e 215 {
8b0975a3
VZ
216 case wxSTIPPLE:
217 logb.lbStyle = BS_PATTERN ;
218 if (M_PENDATA->m_stipple.Ok())
219 logb.lbHatch = (LONG)M_PENDATA->m_stipple.GetHBITMAP();
220 else
221 logb.lbHatch = (LONG)0;
222 break;
223 case wxBDIAGONAL_HATCH:
224 logb.lbStyle = BS_HATCHED;
225 logb.lbHatch = HS_BDIAGONAL;
226 break;
227 case wxCROSSDIAG_HATCH:
228 logb.lbStyle = BS_HATCHED;
229 logb.lbHatch = HS_DIAGCROSS;
230 break;
231 case wxFDIAGONAL_HATCH:
232 logb.lbStyle = BS_HATCHED;
233 logb.lbHatch = HS_FDIAGONAL;
234 break;
235 case wxCROSS_HATCH:
236 logb.lbStyle = BS_HATCHED;
237 logb.lbHatch = HS_CROSS;
238 break;
239 case wxHORIZONTAL_HATCH:
240 logb.lbStyle = BS_HATCHED;
241 logb.lbHatch = HS_HORIZONTAL;
242 break;
243 case wxVERTICAL_HATCH:
244 logb.lbStyle = BS_HATCHED;
245 logb.lbHatch = HS_VERTICAL;
246 break;
247 default:
248 logb.lbStyle = BS_SOLID;
61ba49f2 249#ifdef __WXDEBUG__
8b0975a3
VZ
250 // this should be unnecessary (it's unused) but suppresses the Purify
251 // messages about uninitialized memory read
252 logb.lbHatch = 0;
61ba49f2 253#endif
8b0975a3 254 break;
c45a644e 255 }
8b0975a3
VZ
256
257 logb.lbColor = ms_colour;
258
259 wxMSWDash *real_dash;
260 if (M_PENDATA->m_style==wxUSER_DASH && M_PENDATA->m_nbDash && M_PENDATA->m_dash)
261 {
262 real_dash = new wxMSWDash[M_PENDATA->m_nbDash];
263 int rw = M_PENDATA->m_width > 1 ? M_PENDATA->m_width : 1;
264 for ( int i = 0; i < M_PENDATA->m_nbDash; i++ )
265 real_dash[i] = M_PENDATA->m_dash[i] * rw;
266 }
267 else
268 {
269 real_dash = (wxMSWDash*)NULL;
270 }
271
286b8de5
PC
272 M_PENDATA->m_hPen =
273 (WXHPEN) ExtCreatePen( ms_style,
274 M_PENDATA->m_width,
275 &logb,
276 M_PENDATA->m_style == wxUSER_DASH
277 ? M_PENDATA->m_nbDash
278 : 0,
279 (LPDWORD)real_dash );
8b0975a3
VZ
280
281 delete [] real_dash;
282 }
283#else // WinCE
284 M_PENDATA->m_hPen =
285 (WXHPEN) CreatePen( wx2msPenStyle(M_PENDATA->m_style),
286 M_PENDATA->m_width,
287 ms_colour );
288#endif // !WinCE/WinCE
289
290 return true;
2bda0e17
KB
291}
292
2b5f62a0 293WXHANDLE wxPen::GetResourceHandle() const
2bda0e17 294{
92218ce6
WS
295 if ( !M_PENDATA )
296 return 0;
297 else
298 return (WXHANDLE)M_PENDATA->m_hPen;
2bda0e17
KB
299}
300
33ac7e6f 301bool wxPen::FreeResource(bool WXUNUSED(force))
2bda0e17 302{
92218ce6
WS
303 if (M_PENDATA && (M_PENDATA->m_hPen != 0))
304 {
305 DeleteObject((HPEN) M_PENDATA->m_hPen);
306 M_PENDATA->m_hPen = 0;
307 return true;
308 }
309 else return false;
2bda0e17
KB
310}
311
e4a81a2e 312bool wxPen::IsFree() const
2bda0e17 313{
92218ce6 314 return (M_PENDATA && M_PENDATA->m_hPen == 0);
2bda0e17 315}
2bda0e17 316
7c310bc8 317wxObjectRefData* wxPen::CreateRefData() const
2bda0e17 318{
7c310bc8
PC
319 return new wxFontRefData;
320}
321
322wxObjectRefData* wxPen::CloneRefData(const wxObjectRefData* data) const
323{
324 return new wxFontRefData(*wx_static_cast(const wxPenRefData*, data));
2bda0e17
KB
325}
326
327void wxPen::SetColour(const wxColour& col)
328{
7c310bc8 329 AllocExclusive();
2bda0e17 330
b823f5a1 331 M_PENDATA->m_colour = col;
bbd41262 332
2bda0e17
KB
333 RealizeResource();
334}
335
1a1498c0 336void wxPen::SetColour(unsigned char r, unsigned char g, unsigned char b)
2bda0e17 337{
7c310bc8 338 AllocExclusive();
2bda0e17 339
b823f5a1 340 M_PENDATA->m_colour.Set(r, g, b);
bbd41262 341
2bda0e17
KB
342 RealizeResource();
343}
344
debe6624 345void wxPen::SetWidth(int Width)
2bda0e17 346{
7c310bc8 347 AllocExclusive();
2bda0e17 348
b823f5a1 349 M_PENDATA->m_width = Width;
2bda0e17 350
2bda0e17
KB
351 RealizeResource();
352}
353
debe6624 354void wxPen::SetStyle(int Style)
2bda0e17 355{
7c310bc8 356 AllocExclusive();
2bda0e17 357
b823f5a1 358 M_PENDATA->m_style = Style;
2bda0e17 359
2bda0e17
KB
360 RealizeResource();
361}
362
363void wxPen::SetStipple(const wxBitmap& Stipple)
364{
7c310bc8 365 AllocExclusive();
2bda0e17 366
b823f5a1
JS
367 M_PENDATA->m_stipple = Stipple;
368 M_PENDATA->m_style = wxSTIPPLE;
bbd41262 369
2bda0e17
KB
370 RealizeResource();
371}
372
debe6624 373void wxPen::SetDashes(int nb_dashes, const wxDash *Dash)
2bda0e17 374{
7c310bc8 375 AllocExclusive();
2bda0e17 376
b823f5a1 377 M_PENDATA->m_nbDash = nb_dashes;
edd97174 378 M_PENDATA->m_dash = (wxDash *)Dash;
bbd41262 379
2bda0e17
KB
380 RealizeResource();
381}
382
debe6624 383void wxPen::SetJoin(int Join)
2bda0e17 384{
7c310bc8 385 AllocExclusive();
2bda0e17 386
b823f5a1 387 M_PENDATA->m_join = Join;
2bda0e17 388
2bda0e17
KB
389 RealizeResource();
390}
391
debe6624 392void wxPen::SetCap(int Cap)
2bda0e17 393{
7c310bc8 394 AllocExclusive();
2bda0e17 395
b823f5a1 396 M_PENDATA->m_cap = Cap;
2bda0e17 397
2bda0e17
KB
398 RealizeResource();
399}
400
ce3b4b90
PC
401wxColour& wxPen::GetColour() const
402{
403 return m_refData ? M_PENDATA->m_colour : wxNullColour;
404}
405
406int wxPen::GetWidth() const
407{
408 return m_refData ? M_PENDATA->m_width : 0;
409}
410
411int wxPen::GetStyle() const
412{
413 return m_refData ? M_PENDATA->m_style : 0;
414}
415
416int wxPen::GetJoin() const
417{
418 return m_refData ? M_PENDATA->m_join : 0;
419}
420
421int wxPen::GetCap() const
422{
423 return m_refData ? M_PENDATA->m_cap : 0;
424}
425
426int wxPen::GetDashes(wxDash** ptr) const
427{
428 *ptr = NULL;
429 int count = 0;
430 if (m_refData)
431 {
432 *ptr = M_PENDATA->m_dash;
433 count = M_PENDATA->m_nbDash;
434 }
435 return count;
436}
437
438wxDash* wxPen::GetDash() const
439{
440 wxDash* dash = NULL;
441 if (m_refData)
442 dash = M_PENDATA->m_dash;
443 return dash;
444}
445
446int wxPen::GetDashCount() const
447{
448 return m_refData ? M_PENDATA->m_nbDash : 0;
449}
450
451wxBitmap* wxPen::GetStipple() const
452{
453 wxBitmap* bitmap = NULL;
454 if (m_refData)
455 bitmap = &M_PENDATA->m_stipple;
456 return bitmap;
457}
458
2bda0e17
KB
459int wx2msPenStyle(int wx_style)
460{
07505825 461#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
c45a644e 462 switch (wx_style)
bbd41262 463 {
07505825
WS
464 case wxDOT:
465 return PS_DOT;
c45a644e 466
07505825
WS
467 case wxDOT_DASH:
468 return PS_DASHDOT;
469
470 case wxSHORT_DASH:
471 case wxLONG_DASH:
472 return PS_DASH;
473
474 case wxTRANSPARENT:
475 return PS_NULL;
476
477 case wxUSER_DASH:
286b8de5 478 return PS_USERSTYLE;
07505825 479 }
2bda0e17 480#else
07505825 481 wxUnusedVar(wx_style);
2bda0e17 482#endif
07505825 483 return PS_SOLID;
2bda0e17 484}