]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/pen.cpp
1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "pen.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
32 #include "wx/msw/private.h"
35 IMPLEMENT_DYNAMIC_CLASS(wxPen
, wxGDIObject
)
37 wxPenRefData::wxPenRefData()
41 m_join
= wxJOIN_ROUND
;
44 m_dash
= (wxMSWDash
*)NULL
;
48 wxPenRefData::wxPenRefData(const wxPenRefData
& data
)
50 m_style
= data
.m_style
;
51 m_width
= data
.m_width
;
54 m_nbDash
= data
.m_nbDash
;
56 m_colour
= data
.m_colour
;
60 wxPenRefData::~wxPenRefData()
63 ::DeleteObject((HPEN
) m_hPen
);
71 wxThePenList
->AddPen(this);
77 wxThePenList
->RemovePen(this);
80 // Should implement Create
81 wxPen::wxPen(const wxColour
& col
, int Width
, int Style
)
83 m_refData
= new wxPenRefData
;
85 M_PENDATA
->m_colour
= col
;
86 // M_PENDATA->m_stipple = NULL;
87 M_PENDATA
->m_width
= Width
;
88 M_PENDATA
->m_style
= Style
;
89 M_PENDATA
->m_join
= wxJOIN_ROUND
;
90 M_PENDATA
->m_cap
= wxCAP_ROUND
;
91 M_PENDATA
->m_nbDash
= 0 ;
92 M_PENDATA
->m_dash
= (wxMSWDash
*)NULL
;
93 M_PENDATA
->m_hPen
= 0 ;
96 // In Windows, only a pen of width = 1 can be dotted or dashed!
97 if ((Style
== wxDOT
) || (Style
== wxLONG_DASH
) ||
98 (Style
== wxSHORT_DASH
) || (Style
== wxDOT_DASH
) ||
99 (Style
== wxUSER_DASH
))
100 M_PENDATA
->m_width
= 1;
103 DWORD vers = GetVersion() ;
104 WORD high = HIWORD(vers) ; // high bit=0 for NT, 1 for Win32s
105 // Win32s doesn't support wide dashed pens
107 if ((high&0x8000)!=0)
109 if (wxGetOsVersion()==wxWIN32S
)
111 // In Windows, only a pen of width = 1 can be dotted or dashed!
112 if ((Style
== wxDOT
) || (Style
== wxLONG_DASH
) ||
113 (Style
== wxSHORT_DASH
) || (Style
== wxDOT_DASH
) ||
114 (Style
== wxUSER_DASH
))
115 M_PENDATA
->m_width
= 1;
121 wxThePenList
->AddPen(this);
124 wxPen::wxPen(const wxBitmap
& stipple
, int Width
)
126 m_refData
= new wxPenRefData
;
128 // M_PENDATA->m_colour = col;
129 M_PENDATA
->m_stipple
= stipple
;
130 M_PENDATA
->m_width
= Width
;
131 M_PENDATA
->m_style
= wxSTIPPLE
;
132 M_PENDATA
->m_join
= wxJOIN_ROUND
;
133 M_PENDATA
->m_cap
= wxCAP_ROUND
;
134 M_PENDATA
->m_nbDash
= 0 ;
135 M_PENDATA
->m_dash
= (wxMSWDash
*)NULL
;
136 M_PENDATA
->m_hPen
= 0 ;
141 wxThePenList
->AddPen(this);
144 bool wxPen::RealizeResource()
146 if (M_PENDATA
&& (M_PENDATA
->m_hPen
== 0))
148 if (M_PENDATA
->m_style
==wxTRANSPARENT
)
150 M_PENDATA
->m_hPen
= (WXHPEN
) ::GetStockObject(NULL_PEN
);
154 COLORREF ms_colour
= 0;
155 ms_colour
= M_PENDATA
->m_colour
.GetPixel();
157 // Join style, Cap style, Pen Stippling only on Win32.
158 // Currently no time to find equivalent on Win3.1, sorry
159 // [if such equiv exist!!]
161 if (M_PENDATA
->m_join
==wxJOIN_ROUND
&&
162 M_PENDATA
->m_cap
==wxCAP_ROUND
&&
163 M_PENDATA
->m_style
!=wxUSER_DASH
&&
164 M_PENDATA
->m_style
!=wxSTIPPLE
&&
165 M_PENDATA
->m_width
<= 1)
168 (WXHPEN
) CreatePen( wx2msPenStyle(M_PENDATA
->m_style
),
174 DWORD ms_style
= PS_GEOMETRIC
| wx2msPenStyle(M_PENDATA
->m_style
);
176 switch(M_PENDATA
->m_join
)
178 case wxJOIN_BEVEL
: ms_style
|= PS_JOIN_BEVEL
; break;
179 case wxJOIN_MITER
: ms_style
|= PS_JOIN_MITER
; break;
181 case wxJOIN_ROUND
: ms_style
|= PS_JOIN_ROUND
; break;
184 switch(M_PENDATA
->m_cap
)
186 case wxCAP_PROJECTING
: ms_style
|= PS_ENDCAP_SQUARE
; break;
187 case wxCAP_BUTT
: ms_style
|= PS_ENDCAP_FLAT
; break;
189 case wxCAP_ROUND
: ms_style
|= PS_ENDCAP_ROUND
; break;
194 switch(M_PENDATA
->m_style
)
197 logb
.lbStyle
= BS_PATTERN
;
198 if (M_PENDATA
->m_stipple
.Ok())
199 logb
.lbHatch
= (LONG
)M_PENDATA
->m_stipple
.GetHBITMAP();
201 logb
.lbHatch
= (LONG
)0;
203 case wxBDIAGONAL_HATCH
:
204 logb
.lbStyle
= BS_HATCHED
;
205 logb
.lbHatch
= HS_BDIAGONAL
;
207 case wxCROSSDIAG_HATCH
:
208 logb
.lbStyle
= BS_HATCHED
;
209 logb
.lbHatch
= HS_DIAGCROSS
;
211 case wxFDIAGONAL_HATCH
:
212 logb
.lbStyle
= BS_HATCHED
;
213 logb
.lbHatch
= HS_FDIAGONAL
;
216 logb
.lbStyle
= BS_HATCHED
;
217 logb
.lbHatch
= HS_CROSS
;
219 case wxHORIZONTAL_HATCH
:
220 logb
.lbStyle
= BS_HATCHED
;
221 logb
.lbHatch
= HS_HORIZONTAL
;
223 case wxVERTICAL_HATCH
:
224 logb
.lbStyle
= BS_HATCHED
;
225 logb
.lbHatch
= HS_VERTICAL
;
228 logb
.lbStyle
= BS_SOLID
;
230 // this should be unnecessary (it's unused) but suppresses the Purigy
231 // messages about uninitialized memory read
237 logb
.lbColor
= ms_colour
;
239 wxMSWDash
*real_dash
;
240 if (M_PENDATA
->m_style
==wxUSER_DASH
&& M_PENDATA
->m_nbDash
&& M_PENDATA
->m_dash
)
242 real_dash
= new wxMSWDash
[M_PENDATA
->m_nbDash
];
244 for (i
=0; i
<M_PENDATA
->m_nbDash
; i
++)
245 real_dash
[i
] = M_PENDATA
->m_dash
[i
] * M_PENDATA
->m_width
;
249 real_dash
= (wxMSWDash
*)NULL
;
252 // Win32s doesn't have ExtCreatePen function...
253 if (wxGetOsVersion()==wxWINDOWS_NT
|| wxGetOsVersion()==wxWIN95
)
256 (WXHPEN
) ExtCreatePen( ms_style
,
259 M_PENDATA
->m_style
== wxUSER_DASH
260 ? M_PENDATA
->m_nbDash
262 (LPDWORD
)real_dash
);
267 (WXHPEN
) CreatePen( wx2msPenStyle(M_PENDATA
->m_style
),
277 (WXHPEN
) CreatePen( wx2msPenStyle(M_PENDATA
->m_style
),
281 #ifdef WXDEBUG_CREATE
282 if (M_PENDATA
->m_hPen
==0)
283 wxError("Cannot create pen","Internal error") ;
290 WXHANDLE
wxPen::GetResourceHandle()
295 return (WXHANDLE
)M_PENDATA
->m_hPen
;
298 bool wxPen::FreeResource(bool force
)
300 if (M_PENDATA
&& (M_PENDATA
->m_hPen
!= 0))
302 DeleteObject((HPEN
) M_PENDATA
->m_hPen
);
303 M_PENDATA
->m_hPen
= 0;
309 bool wxPen::IsFree() const
311 return (M_PENDATA
&& M_PENDATA
->m_hPen
== 0);
314 void wxPen::Unshare()
316 // Don't change shared data
319 m_refData
= new wxPenRefData();
323 wxPenRefData
* ref
= new wxPenRefData(*(wxPenRefData
*)m_refData
);
329 void wxPen::SetColour(const wxColour
& col
)
333 M_PENDATA
->m_colour
= col
;
338 void wxPen::SetColour(unsigned char r
, unsigned char g
, unsigned char b
)
342 M_PENDATA
->m_colour
.Set(r
, g
, b
);
347 void wxPen::SetWidth(int Width
)
351 M_PENDATA
->m_width
= Width
;
356 void wxPen::SetStyle(int Style
)
360 M_PENDATA
->m_style
= Style
;
365 void wxPen::SetStipple(const wxBitmap
& Stipple
)
369 M_PENDATA
->m_stipple
= Stipple
;
370 M_PENDATA
->m_style
= wxSTIPPLE
;
375 void wxPen::SetDashes(int nb_dashes
, const wxDash
*Dash
)
379 M_PENDATA
->m_nbDash
= nb_dashes
;
380 M_PENDATA
->m_dash
= (wxMSWDash
*)Dash
;
385 void wxPen::SetJoin(int Join
)
389 M_PENDATA
->m_join
= Join
;
394 void wxPen::SetCap(int Cap
)
398 M_PENDATA
->m_cap
= Cap
;
403 int wx2msPenStyle(int wx_style
)
427 // Win32s doesn't have PS_USERSTYLE
428 if (wxGetOsVersion()==wxWINDOWS_NT
|| wxGetOsVersion()==wxWIN95
)
429 cstyle
= PS_USERSTYLE
;
431 cstyle
= PS_DOT
; // We must make a choice... This is mine!