]>
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 #if !USE_SHARED_LIBRARIES
36 IMPLEMENT_DYNAMIC_CLASS(wxPen
, wxGDIObject
)
39 wxPenRefData::wxPenRefData(void)
43 m_join
= wxJOIN_ROUND
;
50 wxPenRefData::wxPenRefData(const wxPenRefData
& data
)
52 m_style
= data
.m_style
;
53 m_width
= data
.m_width
;
56 m_nbDash
= data
.m_nbDash
;
58 m_colour
= data
.m_colour
;
62 wxPenRefData::~wxPenRefData(void)
65 ::DeleteObject((HPEN
) m_hPen
);
73 wxThePenList
->AddPen(this);
79 wxThePenList
->RemovePen(this);
82 // Should implement Create
83 wxPen::wxPen(const wxColour
& col
, int Width
, int Style
)
85 m_refData
= new wxPenRefData
;
87 M_PENDATA
->m_colour
= col
;
88 // M_PENDATA->m_stipple = NULL;
89 M_PENDATA
->m_width
= Width
;
90 M_PENDATA
->m_style
= Style
;
91 M_PENDATA
->m_join
= wxJOIN_ROUND
;
92 M_PENDATA
->m_cap
= wxCAP_ROUND
;
93 M_PENDATA
->m_nbDash
= 0 ;
94 M_PENDATA
->m_dash
= 0 ;
95 M_PENDATA
->m_hPen
= 0 ;
98 // In Windows, only a pen of width = 1 can be dotted or dashed!
99 if ((Style
== wxDOT
) || (Style
== wxLONG_DASH
) ||
100 (Style
== wxSHORT_DASH
) || (Style
== wxDOT_DASH
) ||
101 (Style
== wxUSER_DASH
))
102 M_PENDATA
->m_width
= 1;
105 DWORD vers = GetVersion() ;
106 WORD high = HIWORD(vers) ; // high bit=0 for NT, 1 for Win32s
107 // Win32s doesn't support wide dashed pens
109 if ((high&0x8000)!=0)
111 if (wxGetOsVersion()==wxWIN32S
)
113 // In Windows, only a pen of width = 1 can be dotted or dashed!
114 if ((Style
== wxDOT
) || (Style
== wxLONG_DASH
) ||
115 (Style
== wxSHORT_DASH
) || (Style
== wxDOT_DASH
) ||
116 (Style
== wxUSER_DASH
))
117 M_PENDATA
->m_width
= 1;
123 wxThePenList
->AddPen(this);
126 wxPen::wxPen(const wxBitmap
& stipple
, int Width
)
128 m_refData
= new wxPenRefData
;
130 // M_PENDATA->m_colour = col;
131 M_PENDATA
->m_stipple
= stipple
;
132 M_PENDATA
->m_width
= Width
;
133 M_PENDATA
->m_style
= wxSTIPPLE
;
134 M_PENDATA
->m_join
= wxJOIN_ROUND
;
135 M_PENDATA
->m_cap
= wxCAP_ROUND
;
136 M_PENDATA
->m_nbDash
= 0 ;
137 M_PENDATA
->m_dash
= 0 ;
138 M_PENDATA
->m_hPen
= 0 ;
143 wxThePenList
->AddPen(this);
146 wxPen::wxPen(const wxString
& col
, int Width
, int Style
)
148 m_refData
= new wxPenRefData
;
150 M_PENDATA
->m_colour
= col
;
151 // M_PENDATA->m_stipple = NULL ;
152 M_PENDATA
->m_width
= Width
;
153 M_PENDATA
->m_style
= Style
;
154 M_PENDATA
->m_join
= wxJOIN_ROUND
;
155 M_PENDATA
->m_cap
= wxCAP_ROUND
;
156 M_PENDATA
->m_nbDash
= 0 ;
157 M_PENDATA
->m_dash
= 0 ;
158 M_PENDATA
->m_hPen
= 0 ;
163 wxThePenList
->AddPen(this);
166 bool wxPen::RealizeResource(void)
168 if (M_PENDATA
&& (M_PENDATA
->m_hPen
== 0))
170 if (M_PENDATA
->m_style
==wxTRANSPARENT
)
172 M_PENDATA
->m_hPen
= (WXHPEN
) ::GetStockObject(NULL_PEN
);
176 COLORREF ms_colour
= 0 ;
177 ms_colour
= M_PENDATA
->m_colour
.GetPixel() ;
179 // Join style, Cap style, Pen Stippling only on Win32.
180 // Currently no time to find equivalent on Win3.1, sorry
181 // [if such equiv exist!!]
183 if (M_PENDATA
->m_join
==wxJOIN_ROUND
&&
184 M_PENDATA
->m_cap
==wxCAP_ROUND
&&
185 M_PENDATA
->m_style
!=wxUSER_DASH
&&
186 M_PENDATA
->m_style
!=wxSTIPPLE
&&
187 M_PENDATA
->m_width
<= 1
189 M_PENDATA
->m_hPen
= (WXHPEN
) CreatePen(wx2msPenStyle(M_PENDATA
->m_style
), M_PENDATA
->m_width
, ms_colour
);
192 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 ;
212 switch(M_PENDATA
->m_style
)
215 logb
.lbStyle
= BS_PATTERN
;
216 if (M_PENDATA
->m_stipple
.Ok())
217 logb
.lbHatch
= (LONG
)M_PENDATA
->m_stipple
.GetHBITMAP() ;
219 logb
.lbHatch
= (LONG
)0 ;
221 case wxBDIAGONAL_HATCH
:
222 logb
.lbStyle
= BS_HATCHED
;
223 logb
.lbHatch
= HS_BDIAGONAL
;
225 case wxCROSSDIAG_HATCH
:
226 logb
.lbStyle
= BS_HATCHED
;
227 logb
.lbHatch
= HS_DIAGCROSS
;
229 case wxFDIAGONAL_HATCH
:
230 logb
.lbStyle
= BS_HATCHED
;
231 logb
.lbHatch
= HS_FDIAGONAL
;
234 logb
.lbStyle
= BS_HATCHED
;
235 logb
.lbHatch
= HS_CROSS
;
237 case wxHORIZONTAL_HATCH
:
238 logb
.lbStyle
= BS_HATCHED
;
239 logb
.lbHatch
= HS_HORIZONTAL
;
241 case wxVERTICAL_HATCH
:
242 logb
.lbStyle
= BS_HATCHED
;
243 logb
.lbHatch
= HS_VERTICAL
;
246 logb
.lbStyle
= BS_SOLID
;
249 logb
.lbColor
= ms_colour
;
251 if (M_PENDATA
->m_style
==wxUSER_DASH
&& M_PENDATA
->m_nbDash
&& M_PENDATA
->m_dash
)
253 real_dash
= new wxDash
[M_PENDATA
->m_nbDash
] ;
255 for (i
=0;i
<M_PENDATA
->m_nbDash
;i
++)
256 real_dash
[i
] = M_PENDATA
->m_dash
[i
] * M_PENDATA
->m_width
;
261 // Win32s doesn't have ExtCreatePen function...
262 if (wxGetOsVersion()==wxWINDOWS_NT
|| wxGetOsVersion()==wxWIN95
)
263 M_PENDATA
->m_hPen
= (WXHPEN
) ExtCreatePen(ms_style
,M_PENDATA
->m_width
,&logb
,
264 M_PENDATA
->m_style
==wxUSER_DASH
? M_PENDATA
->m_nbDash
:0, (const DWORD
*)real_dash
);
266 M_PENDATA
->m_hPen
= (WXHPEN
) CreatePen(wx2msPenStyle(M_PENDATA
->m_style
), M_PENDATA
->m_width
, ms_colour
);
269 delete [] real_dash
;
272 M_PENDATA
->m_hPen
= (WXHPEN
) CreatePen(wx2msPenStyle(M_PENDATA
->m_style
), M_PENDATA
->m_width
, ms_colour
);
274 #ifdef WXDEBUG_CREATE
275 if (M_PENDATA
->m_hPen
==0)
276 wxError("Cannot create pen","Internal error") ;
283 WXHANDLE
wxPen::GetResourceHandle(void)
288 return (WXHANDLE
)M_PENDATA
->m_hPen
;
291 bool wxPen::FreeResource(bool force
)
293 if (M_PENDATA
&& (M_PENDATA
->m_hPen
!= 0))
295 DeleteObject((HPEN
) M_PENDATA
->m_hPen
);
296 M_PENDATA
->m_hPen
= 0;
302 bool wxPen::IsFree(void)
304 return (M_PENDATA
&& M_PENDATA
->m_hPen
== 0);
307 void wxPen::Unshare()
309 // Don't change shared data
312 m_refData
= new wxPenRefData();
316 wxPenRefData
* ref
= new wxPenRefData(*(wxPenRefData
*)m_refData
);
322 void wxPen::SetColour(const wxColour
& col
)
326 M_PENDATA
->m_colour
= col
;
331 void wxPen::SetColour(const wxString
& col
)
335 M_PENDATA
->m_colour
= col
;
340 void wxPen::SetColour(const unsigned char r
, const unsigned char g
, const unsigned char b
)
344 M_PENDATA
->m_colour
.Set(r
, g
, b
);
349 void wxPen::SetWidth(int Width
)
353 M_PENDATA
->m_width
= Width
;
358 void wxPen::SetStyle(int Style
)
362 M_PENDATA
->m_style
= Style
;
367 void wxPen::SetStipple(const wxBitmap
& Stipple
)
371 M_PENDATA
->m_stipple
= Stipple
;
372 M_PENDATA
->m_style
= wxSTIPPLE
;
377 void wxPen::SetDashes(int nb_dashes
, const wxDash
*Dash
)
381 M_PENDATA
->m_nbDash
= nb_dashes
;
382 M_PENDATA
->m_dash
= (wxDash
*)Dash
;
387 void wxPen::SetJoin(int Join
)
391 M_PENDATA
->m_join
= Join
;
396 void wxPen::SetCap(int Cap
)
400 M_PENDATA
->m_cap
= Cap
;
405 int wx2msPenStyle(int wx_style
)
410 DWORD vers = GetVersion() ;
411 WORD high = HIWORD(vers) ; // high bit=0 for NT, 1 for Win32s
427 // User dash style not supported on Win3.1, sorry...
429 // Win32s doesn't have PS_USERSTYLE
431 if ((high&0x8000)==0)
433 if (wxGetOsVersion()==wxWINDOWS_NT
)
434 cstyle
= PS_USERSTYLE
;
436 cstyle
= PS_DOT
; // We must make a choice... This is mine!