]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/pen.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/pen.cpp
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
22 #include "wx/bitmap.h"
26 #include "wx/msw/private.h"
28 typedef WXDWORD wxMSWDash
;
30 static int wx2msPenStyle(int wx_style
);
32 #define M_PENDATA ((wxPenRefData*)m_refData)
34 class WXDLLEXPORT wxPenRefData
: public wxGDIRefData
38 wxPenRefData(const wxPenRefData
& data
);
39 virtual ~wxPenRefData();
41 bool operator==(const wxPenRefData
& data
) const
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));
65 DECLARE_NO_ASSIGN_CLASS(wxPenRefData
)
68 wxPenRefData::wxPenRefData()
72 m_join
= wxJOIN_ROUND
;
75 m_dash
= (wxDash
*)NULL
;
79 wxPenRefData::wxPenRefData(const wxPenRefData
& data
)
82 m_style
= data
.m_style
;
83 m_width
= data
.m_width
;
86 m_nbDash
= data
.m_nbDash
;
88 m_colour
= data
.m_colour
;
92 wxPenRefData::~wxPenRefData()
95 ::DeleteObject((HPEN
) m_hPen
);
100 IMPLEMENT_DYNAMIC_CLASS(wxPen
, wxGDIObject
)
110 // Should implement Create
111 wxPen::wxPen(const wxColour
& col
, int Width
, int Style
)
113 m_refData
= new wxPenRefData
;
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 ;
122 M_PENDATA
->m_dash
= (wxDash
*)NULL
;
123 M_PENDATA
->m_hPen
= 0 ;
128 wxPen::wxPen(const wxBitmap
& stipple
, int Width
)
130 m_refData
= new wxPenRefData
;
132 // M_PENDATA->m_colour = col;
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 ;
139 M_PENDATA
->m_dash
= (wxDash
*)NULL
;
140 M_PENDATA
->m_hPen
= 0 ;
145 bool wxPen::operator==(const wxPen
& pen
) const
147 const wxPenRefData
*penData
= wx_static_cast(const wxPenRefData
*, pen
.m_refData
);
149 // an invalid pen is only equal to another invalid pen
150 return m_refData
? penData
&& *M_PENDATA
== *penData
: !penData
;
153 bool wxPen::RealizeResource()
155 if ( !M_PENDATA
|| M_PENDATA
->m_hPen
)
158 if (M_PENDATA
->m_style
==wxTRANSPARENT
)
160 M_PENDATA
->m_hPen
= (WXHPEN
) ::GetStockObject(NULL_PEN
);
164 static const int os
= wxGetOsVersion();
165 COLORREF ms_colour
= M_PENDATA
->m_colour
.GetPixel();
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
170 if ( os
!= wxOS_WINDOWS_NT
&&
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
) &&
176 M_PENDATA
->m_width
> 1 )
178 M_PENDATA
->m_width
= 1;
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)
188 (WXHPEN
) CreatePen( wx2msPenStyle(M_PENDATA
->m_style
),
194 DWORD ms_style
= PS_GEOMETRIC
| wx2msPenStyle(M_PENDATA
->m_style
);
196 switch(M_PENDATA
->m_join
)
198 case wxJOIN_BEVEL
: ms_style
|= PS_JOIN_BEVEL
; break;
199 case wxJOIN_MITER
: ms_style
|= PS_JOIN_MITER
; break;
201 case wxJOIN_ROUND
: ms_style
|= PS_JOIN_ROUND
; break;
204 switch(M_PENDATA
->m_cap
)
206 case wxCAP_PROJECTING
: ms_style
|= PS_ENDCAP_SQUARE
; break;
207 case wxCAP_BUTT
: ms_style
|= PS_ENDCAP_FLAT
; break;
209 case wxCAP_ROUND
: ms_style
|= PS_ENDCAP_ROUND
; break;
214 switch(M_PENDATA
->m_style
)
217 logb
.lbStyle
= BS_PATTERN
;
218 if (M_PENDATA
->m_stipple
.Ok())
219 logb
.lbHatch
= (LONG
)M_PENDATA
->m_stipple
.GetHBITMAP();
221 logb
.lbHatch
= (LONG
)0;
223 case wxBDIAGONAL_HATCH
:
224 logb
.lbStyle
= BS_HATCHED
;
225 logb
.lbHatch
= HS_BDIAGONAL
;
227 case wxCROSSDIAG_HATCH
:
228 logb
.lbStyle
= BS_HATCHED
;
229 logb
.lbHatch
= HS_DIAGCROSS
;
231 case wxFDIAGONAL_HATCH
:
232 logb
.lbStyle
= BS_HATCHED
;
233 logb
.lbHatch
= HS_FDIAGONAL
;
236 logb
.lbStyle
= BS_HATCHED
;
237 logb
.lbHatch
= HS_CROSS
;
239 case wxHORIZONTAL_HATCH
:
240 logb
.lbStyle
= BS_HATCHED
;
241 logb
.lbHatch
= HS_HORIZONTAL
;
243 case wxVERTICAL_HATCH
:
244 logb
.lbStyle
= BS_HATCHED
;
245 logb
.lbHatch
= HS_VERTICAL
;
248 logb
.lbStyle
= BS_SOLID
;
250 // this should be unnecessary (it's unused) but suppresses the Purify
251 // messages about uninitialized memory read
257 logb
.lbColor
= ms_colour
;
259 wxMSWDash
*real_dash
;
260 if (M_PENDATA
->m_style
==wxUSER_DASH
&& M_PENDATA
->m_nbDash
&& M_PENDATA
->m_dash
)
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
;
269 real_dash
= (wxMSWDash
*)NULL
;
273 (WXHPEN
) ExtCreatePen( ms_style
,
276 M_PENDATA
->m_style
== wxUSER_DASH
277 ? M_PENDATA
->m_nbDash
279 (LPDWORD
)real_dash
);
285 (WXHPEN
) CreatePen( wx2msPenStyle(M_PENDATA
->m_style
),
288 #endif // !WinCE/WinCE
293 WXHANDLE
wxPen::GetResourceHandle() const
298 return (WXHANDLE
)M_PENDATA
->m_hPen
;
301 bool wxPen::FreeResource(bool WXUNUSED(force
))
303 if (M_PENDATA
&& (M_PENDATA
->m_hPen
!= 0))
305 DeleteObject((HPEN
) M_PENDATA
->m_hPen
);
306 M_PENDATA
->m_hPen
= 0;
312 bool wxPen::IsFree() const
314 return (M_PENDATA
&& M_PENDATA
->m_hPen
== 0);
317 wxObjectRefData
* wxPen::CreateRefData() const
319 return new wxFontRefData
;
322 wxObjectRefData
* wxPen::CloneRefData(const wxObjectRefData
* data
) const
324 return new wxFontRefData(*wx_static_cast(const wxPenRefData
*, data
));
327 void wxPen::SetColour(const wxColour
& col
)
331 M_PENDATA
->m_colour
= col
;
336 void wxPen::SetColour(unsigned char r
, unsigned char g
, unsigned char b
)
340 M_PENDATA
->m_colour
.Set(r
, g
, b
);
345 void wxPen::SetWidth(int Width
)
349 M_PENDATA
->m_width
= Width
;
354 void wxPen::SetStyle(int Style
)
358 M_PENDATA
->m_style
= Style
;
363 void wxPen::SetStipple(const wxBitmap
& Stipple
)
367 M_PENDATA
->m_stipple
= Stipple
;
368 M_PENDATA
->m_style
= wxSTIPPLE
;
373 void wxPen::SetDashes(int nb_dashes
, const wxDash
*Dash
)
377 M_PENDATA
->m_nbDash
= nb_dashes
;
378 M_PENDATA
->m_dash
= (wxDash
*)Dash
;
383 void wxPen::SetJoin(int Join
)
387 M_PENDATA
->m_join
= Join
;
392 void wxPen::SetCap(int Cap
)
396 M_PENDATA
->m_cap
= Cap
;
401 wxColour
& wxPen::GetColour() const
403 return m_refData
? M_PENDATA
->m_colour
: wxNullColour
;
406 int wxPen::GetWidth() const
408 return m_refData
? M_PENDATA
->m_width
: 0;
411 int wxPen::GetStyle() const
413 return m_refData
? M_PENDATA
->m_style
: 0;
416 int wxPen::GetJoin() const
418 return m_refData
? M_PENDATA
->m_join
: 0;
421 int wxPen::GetCap() const
423 return m_refData
? M_PENDATA
->m_cap
: 0;
426 int wxPen::GetDashes(wxDash
** ptr
) const
432 *ptr
= M_PENDATA
->m_dash
;
433 count
= M_PENDATA
->m_nbDash
;
438 wxDash
* wxPen::GetDash() const
442 dash
= M_PENDATA
->m_dash
;
446 int wxPen::GetDashCount() const
448 return m_refData
? M_PENDATA
->m_nbDash
: 0;
451 wxBitmap
* wxPen::GetStipple() const
453 wxBitmap
* bitmap
= NULL
;
455 bitmap
= &M_PENDATA
->m_stipple
;
459 int wx2msPenStyle(int wx_style
)
461 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
481 wxUnusedVar(wx_style
);