]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/pen.cpp
1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
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"
34 IMPLEMENT_DYNAMIC_CLASS(wxPen
, wxGDIObject
)
36 wxPenRefData::wxPenRefData()
40 m_join
= wxJOIN_ROUND
;
43 m_dash
= (wxDash
*)NULL
;
47 wxPenRefData::wxPenRefData(const wxPenRefData
& data
)
49 m_style
= data
.m_style
;
50 m_width
= data
.m_width
;
53 m_nbDash
= data
.m_nbDash
;
55 m_colour
= data
.m_colour
;
59 wxPenRefData::~wxPenRefData()
62 ::DeleteObject((HPEN
) m_hPen
);
75 // Should implement Create
76 wxPen::wxPen(const wxColour
& col
, int Width
, int Style
)
78 m_refData
= new wxPenRefData
;
80 M_PENDATA
->m_colour
= col
;
81 // M_PENDATA->m_stipple = NULL;
82 M_PENDATA
->m_width
= Width
;
83 M_PENDATA
->m_style
= Style
;
84 M_PENDATA
->m_join
= wxJOIN_ROUND
;
85 M_PENDATA
->m_cap
= wxCAP_ROUND
;
86 M_PENDATA
->m_nbDash
= 0 ;
87 M_PENDATA
->m_dash
= (wxDash
*)NULL
;
88 M_PENDATA
->m_hPen
= 0 ;
91 // In Windows, only a pen of width = 1 can be dotted or dashed!
92 if ((Style
== wxDOT
) || (Style
== wxLONG_DASH
) ||
93 (Style
== wxSHORT_DASH
) || (Style
== wxDOT_DASH
) ||
94 (Style
== wxUSER_DASH
))
95 M_PENDATA
->m_width
= 1;
98 DWORD vers = GetVersion() ;
99 WORD high = HIWORD(vers) ; // high bit=0 for NT, 1 for Win32s
100 // Win32s doesn't support wide dashed pens
102 if ((high&0x8000)!=0)
104 if (wxGetOsVersion()==wxWIN32S
)
106 // In Windows, only a pen of width = 1 can be dotted or dashed!
107 if ((Style
== wxDOT
) || (Style
== wxLONG_DASH
) ||
108 (Style
== wxSHORT_DASH
) || (Style
== wxDOT_DASH
) ||
109 (Style
== wxUSER_DASH
))
110 M_PENDATA
->m_width
= 1;
117 wxPen::wxPen(const wxBitmap
& stipple
, int Width
)
119 m_refData
= new wxPenRefData
;
121 // M_PENDATA->m_colour = col;
122 M_PENDATA
->m_stipple
= stipple
;
123 M_PENDATA
->m_width
= Width
;
124 M_PENDATA
->m_style
= wxSTIPPLE
;
125 M_PENDATA
->m_join
= wxJOIN_ROUND
;
126 M_PENDATA
->m_cap
= wxCAP_ROUND
;
127 M_PENDATA
->m_nbDash
= 0 ;
128 M_PENDATA
->m_dash
= (wxDash
*)NULL
;
129 M_PENDATA
->m_hPen
= 0 ;
135 bool wxPen::RealizeResource()
137 if (M_PENDATA
&& (M_PENDATA
->m_hPen
== 0))
139 if (M_PENDATA
->m_style
==wxTRANSPARENT
)
141 M_PENDATA
->m_hPen
= (WXHPEN
) ::GetStockObject(NULL_PEN
);
145 COLORREF ms_colour
= M_PENDATA
->m_colour
.GetPixel();
147 // Join style, Cap style, Pen Stippling only on Win32.
148 // Currently no time to find equivalent on Win3.1, sorry
149 // [if such equiv exist!!]
150 #if defined(__WIN32__) && !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
151 if (M_PENDATA
->m_join
==wxJOIN_ROUND
&&
152 M_PENDATA
->m_cap
==wxCAP_ROUND
&&
153 M_PENDATA
->m_style
!=wxUSER_DASH
&&
154 M_PENDATA
->m_style
!=wxSTIPPLE
&&
155 M_PENDATA
->m_width
<= 1)
158 (WXHPEN
) CreatePen( wx2msPenStyle(M_PENDATA
->m_style
),
164 DWORD ms_style
= PS_GEOMETRIC
| wx2msPenStyle(M_PENDATA
->m_style
);
166 switch(M_PENDATA
->m_join
)
168 case wxJOIN_BEVEL
: ms_style
|= PS_JOIN_BEVEL
; break;
169 case wxJOIN_MITER
: ms_style
|= PS_JOIN_MITER
; break;
171 case wxJOIN_ROUND
: ms_style
|= PS_JOIN_ROUND
; break;
174 switch(M_PENDATA
->m_cap
)
176 case wxCAP_PROJECTING
: ms_style
|= PS_ENDCAP_SQUARE
; break;
177 case wxCAP_BUTT
: ms_style
|= PS_ENDCAP_FLAT
; break;
179 case wxCAP_ROUND
: ms_style
|= PS_ENDCAP_ROUND
; break;
184 switch(M_PENDATA
->m_style
)
187 logb
.lbStyle
= BS_PATTERN
;
188 if (M_PENDATA
->m_stipple
.Ok())
189 logb
.lbHatch
= (LONG
)M_PENDATA
->m_stipple
.GetHBITMAP();
191 logb
.lbHatch
= (LONG
)0;
193 case wxBDIAGONAL_HATCH
:
194 logb
.lbStyle
= BS_HATCHED
;
195 logb
.lbHatch
= HS_BDIAGONAL
;
197 case wxCROSSDIAG_HATCH
:
198 logb
.lbStyle
= BS_HATCHED
;
199 logb
.lbHatch
= HS_DIAGCROSS
;
201 case wxFDIAGONAL_HATCH
:
202 logb
.lbStyle
= BS_HATCHED
;
203 logb
.lbHatch
= HS_FDIAGONAL
;
206 logb
.lbStyle
= BS_HATCHED
;
207 logb
.lbHatch
= HS_CROSS
;
209 case wxHORIZONTAL_HATCH
:
210 logb
.lbStyle
= BS_HATCHED
;
211 logb
.lbHatch
= HS_HORIZONTAL
;
213 case wxVERTICAL_HATCH
:
214 logb
.lbStyle
= BS_HATCHED
;
215 logb
.lbHatch
= HS_VERTICAL
;
218 logb
.lbStyle
= BS_SOLID
;
220 // this should be unnecessary (it's unused) but suppresses the Purigy
221 // messages about uninitialized memory read
227 logb
.lbColor
= ms_colour
;
229 wxMSWDash
*real_dash
;
230 if (M_PENDATA
->m_style
==wxUSER_DASH
&& M_PENDATA
->m_nbDash
&& M_PENDATA
->m_dash
)
232 real_dash
= new wxMSWDash
[M_PENDATA
->m_nbDash
];
233 int rw
= M_PENDATA
->m_width
> 1 ? M_PENDATA
->m_width
: 1;
234 for ( int i
= 0; i
< M_PENDATA
->m_nbDash
; i
++ )
235 real_dash
[i
] = M_PENDATA
->m_dash
[i
] * rw
;
239 real_dash
= (wxMSWDash
*)NULL
;
242 // Win32s doesn't have ExtCreatePen function...
243 if (wxGetOsVersion()==wxWINDOWS_NT
|| wxGetOsVersion()==wxWIN95
)
246 (WXHPEN
) ExtCreatePen( ms_style
,
249 M_PENDATA
->m_style
== wxUSER_DASH
250 ? M_PENDATA
->m_nbDash
252 (LPDWORD
)real_dash
);
257 (WXHPEN
) CreatePen( wx2msPenStyle(M_PENDATA
->m_style
),
267 (WXHPEN
) CreatePen( wx2msPenStyle(M_PENDATA
->m_style
),
271 #ifdef WXDEBUG_CREATE
272 if (M_PENDATA
->m_hPen
==0)
273 wxError("Cannot create pen","Internal error") ;
280 WXHANDLE
wxPen::GetResourceHandle() const
285 return (WXHANDLE
)M_PENDATA
->m_hPen
;
288 bool wxPen::FreeResource(bool WXUNUSED(force
))
290 if (M_PENDATA
&& (M_PENDATA
->m_hPen
!= 0))
292 DeleteObject((HPEN
) M_PENDATA
->m_hPen
);
293 M_PENDATA
->m_hPen
= 0;
299 bool wxPen::IsFree() const
301 return (M_PENDATA
&& M_PENDATA
->m_hPen
== 0);
304 void wxPen::Unshare()
306 // Don't change shared data
309 m_refData
= new wxPenRefData();
313 wxPenRefData
* ref
= new wxPenRefData(*(wxPenRefData
*)m_refData
);
319 void wxPen::SetColour(const wxColour
& col
)
323 M_PENDATA
->m_colour
= col
;
328 void wxPen::SetColour(unsigned char r
, unsigned char g
, unsigned char b
)
332 M_PENDATA
->m_colour
.Set(r
, g
, b
);
337 void wxPen::SetWidth(int Width
)
341 M_PENDATA
->m_width
= Width
;
346 void wxPen::SetStyle(int Style
)
350 M_PENDATA
->m_style
= Style
;
355 void wxPen::SetStipple(const wxBitmap
& Stipple
)
359 M_PENDATA
->m_stipple
= Stipple
;
360 M_PENDATA
->m_style
= wxSTIPPLE
;
365 void wxPen::SetDashes(int nb_dashes
, const wxDash
*Dash
)
369 M_PENDATA
->m_nbDash
= nb_dashes
;
370 M_PENDATA
->m_dash
= (wxDash
*)Dash
;
375 void wxPen::SetJoin(int Join
)
379 M_PENDATA
->m_join
= Join
;
384 void wxPen::SetCap(int Cap
)
388 M_PENDATA
->m_cap
= Cap
;
393 int wx2msPenStyle(int wx_style
)
398 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
418 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
420 // Win32s doesn't have PS_USERSTYLE
421 if (wxGetOsVersion()==wxWINDOWS_NT
|| wxGetOsVersion()==wxWIN95
)
422 cstyle
= PS_USERSTYLE
;
424 cstyle
= PS_DOT
; // We must make a choice... This is mine!