]> git.saurik.com Git - wxWidgets.git/blame - src/msw/pen.cpp
call SetHorizontalExtent() from SetString(); also simplified/cleaned up the former...
[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
8ecff181
WS
22 #include <stdio.h>
23 #include "wx/list.h"
24 #include "wx/utils.h"
25 #include "wx/app.h"
2bda0e17
KB
26#endif
27
28#include "wx/msw/private.h"
2bda0e17 29
a6c81161 30static int wx2msPenStyle(int wx_style);
ef59847c 31
2bda0e17 32IMPLEMENT_DYNAMIC_CLASS(wxPen, wxGDIObject)
2bda0e17 33
e4a81a2e 34wxPenRefData::wxPenRefData()
2bda0e17 35{
2bda0e17
KB
36 m_style = wxSOLID;
37 m_width = 1;
38 m_join = wxJOIN_ROUND ;
39 m_cap = wxCAP_ROUND ;
40 m_nbDash = 0 ;
edd97174 41 m_dash = (wxDash*)NULL;
2bda0e17
KB
42 m_hPen = 0;
43}
44
b823f5a1 45wxPenRefData::wxPenRefData(const wxPenRefData& data)
04a18b0d 46 :wxGDIRefData()
b823f5a1
JS
47{
48 m_style = data.m_style;
49 m_width = data.m_width;
50 m_join = data.m_join;
51 m_cap = data.m_cap;
52 m_nbDash = data.m_nbDash;
53 m_dash = data.m_dash;
54 m_colour = data.m_colour;
55 m_hPen = 0;
56}
57
e4a81a2e 58wxPenRefData::~wxPenRefData()
2bda0e17 59{
8b0975a3
VZ
60 if ( m_hPen )
61 ::DeleteObject((HPEN) m_hPen);
2bda0e17
KB
62}
63
64// Pens
65
e4a81a2e 66wxPen::wxPen()
2bda0e17 67{
2bda0e17
KB
68}
69
70wxPen::~wxPen()
71{
2bda0e17
KB
72}
73
74// Should implement Create
debe6624 75wxPen::wxPen(const wxColour& col, int Width, int Style)
2bda0e17
KB
76{
77 m_refData = new wxPenRefData;
78
79 M_PENDATA->m_colour = col;
80// M_PENDATA->m_stipple = NULL;
81 M_PENDATA->m_width = Width;
82 M_PENDATA->m_style = Style;
83 M_PENDATA->m_join = wxJOIN_ROUND ;
84 M_PENDATA->m_cap = wxCAP_ROUND ;
85 M_PENDATA->m_nbDash = 0 ;
edd97174 86 M_PENDATA->m_dash = (wxDash*)NULL;
2bda0e17
KB
87 M_PENDATA->m_hPen = 0 ;
88
2bda0e17 89 RealizeResource();
2bda0e17
KB
90}
91
debe6624 92wxPen::wxPen(const wxBitmap& stipple, int Width)
2bda0e17 93{
c45a644e 94 m_refData = new wxPenRefData;
2bda0e17
KB
95
96// M_PENDATA->m_colour = col;
c45a644e
RR
97 M_PENDATA->m_stipple = stipple;
98 M_PENDATA->m_width = Width;
99 M_PENDATA->m_style = wxSTIPPLE;
100 M_PENDATA->m_join = wxJOIN_ROUND ;
101 M_PENDATA->m_cap = wxCAP_ROUND ;
102 M_PENDATA->m_nbDash = 0 ;
edd97174 103 M_PENDATA->m_dash = (wxDash*)NULL;
c45a644e 104 M_PENDATA->m_hPen = 0 ;
2bda0e17 105
c45a644e 106 RealizeResource();
2bda0e17
KB
107}
108
e4a81a2e 109bool wxPen::RealizeResource()
2bda0e17 110{
8b0975a3
VZ
111 if ( !M_PENDATA || M_PENDATA->m_hPen )
112 return false;
113
114 if (M_PENDATA->m_style==wxTRANSPARENT)
c45a644e 115 {
8b0975a3
VZ
116 M_PENDATA->m_hPen = (WXHPEN) ::GetStockObject(NULL_PEN);
117 return true;
118 }
119
120 static const int os = wxGetOsVersion();
121 COLORREF ms_colour = M_PENDATA->m_colour.GetPixel();
122
123 // Join style, Cap style, Pen Stippling
124#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
125 // Only NT can display dashed or dotted lines with width > 1
126 if ( os != wxWINDOWS_NT &&
f3ebca94
VZ
127 (M_PENDATA->m_style == wxDOT ||
128 M_PENDATA->m_style == wxLONG_DASH ||
129 M_PENDATA->m_style == wxSHORT_DASH ||
130 M_PENDATA->m_style == wxDOT_DASH ||
131 M_PENDATA->m_style == wxUSER_DASH) &&
8b0975a3
VZ
132 M_PENDATA->m_width > 1 )
133 {
134 M_PENDATA->m_width = 1;
135 }
136
137 if (M_PENDATA->m_join==wxJOIN_ROUND &&
138 M_PENDATA->m_cap==wxCAP_ROUND &&
139 M_PENDATA->m_style!=wxUSER_DASH &&
140 M_PENDATA->m_style!=wxSTIPPLE &&
141 M_PENDATA->m_width <= 1)
142 {
143 M_PENDATA->m_hPen =
144 (WXHPEN) CreatePen( wx2msPenStyle(M_PENDATA->m_style),
145 M_PENDATA->m_width,
146 ms_colour );
147 }
148 else
149 {
150 DWORD ms_style = PS_GEOMETRIC | wx2msPenStyle(M_PENDATA->m_style);
151
152 switch(M_PENDATA->m_join)
c45a644e 153 {
8b0975a3
VZ
154 case wxJOIN_BEVEL: ms_style |= PS_JOIN_BEVEL; break;
155 case wxJOIN_MITER: ms_style |= PS_JOIN_MITER; break;
156 default:
157 case wxJOIN_ROUND: ms_style |= PS_JOIN_ROUND; break;
c45a644e
RR
158 }
159
8b0975a3 160 switch(M_PENDATA->m_cap)
c45a644e 161 {
8b0975a3
VZ
162 case wxCAP_PROJECTING: ms_style |= PS_ENDCAP_SQUARE; break;
163 case wxCAP_BUTT: ms_style |= PS_ENDCAP_FLAT; break;
164 default:
165 case wxCAP_ROUND: ms_style |= PS_ENDCAP_ROUND; break;
c45a644e 166 }
8b0975a3
VZ
167
168 LOGBRUSH logb;
169
170 switch(M_PENDATA->m_style)
c45a644e 171 {
8b0975a3
VZ
172 case wxSTIPPLE:
173 logb.lbStyle = BS_PATTERN ;
174 if (M_PENDATA->m_stipple.Ok())
175 logb.lbHatch = (LONG)M_PENDATA->m_stipple.GetHBITMAP();
176 else
177 logb.lbHatch = (LONG)0;
178 break;
179 case wxBDIAGONAL_HATCH:
180 logb.lbStyle = BS_HATCHED;
181 logb.lbHatch = HS_BDIAGONAL;
182 break;
183 case wxCROSSDIAG_HATCH:
184 logb.lbStyle = BS_HATCHED;
185 logb.lbHatch = HS_DIAGCROSS;
186 break;
187 case wxFDIAGONAL_HATCH:
188 logb.lbStyle = BS_HATCHED;
189 logb.lbHatch = HS_FDIAGONAL;
190 break;
191 case wxCROSS_HATCH:
192 logb.lbStyle = BS_HATCHED;
193 logb.lbHatch = HS_CROSS;
194 break;
195 case wxHORIZONTAL_HATCH:
196 logb.lbStyle = BS_HATCHED;
197 logb.lbHatch = HS_HORIZONTAL;
198 break;
199 case wxVERTICAL_HATCH:
200 logb.lbStyle = BS_HATCHED;
201 logb.lbHatch = HS_VERTICAL;
202 break;
203 default:
204 logb.lbStyle = BS_SOLID;
61ba49f2 205#ifdef __WXDEBUG__
8b0975a3
VZ
206 // this should be unnecessary (it's unused) but suppresses the Purify
207 // messages about uninitialized memory read
208 logb.lbHatch = 0;
61ba49f2 209#endif
8b0975a3 210 break;
c45a644e 211 }
8b0975a3
VZ
212
213 logb.lbColor = ms_colour;
214
215 wxMSWDash *real_dash;
216 if (M_PENDATA->m_style==wxUSER_DASH && M_PENDATA->m_nbDash && M_PENDATA->m_dash)
217 {
218 real_dash = new wxMSWDash[M_PENDATA->m_nbDash];
219 int rw = M_PENDATA->m_width > 1 ? M_PENDATA->m_width : 1;
220 for ( int i = 0; i < M_PENDATA->m_nbDash; i++ )
221 real_dash[i] = M_PENDATA->m_dash[i] * rw;
222 }
223 else
224 {
225 real_dash = (wxMSWDash*)NULL;
226 }
227
228 // Win32s doesn't have ExtCreatePen function...
229 if (os==wxWINDOWS_NT || os==wxWIN95)
230 {
231 M_PENDATA->m_hPen =
232 (WXHPEN) ExtCreatePen( ms_style,
233 M_PENDATA->m_width,
234 &logb,
235 M_PENDATA->m_style == wxUSER_DASH
236 ? M_PENDATA->m_nbDash
237 : 0,
238 (LPDWORD)real_dash );
239 }
240 else
241 {
242 M_PENDATA->m_hPen =
243 (WXHPEN) CreatePen( wx2msPenStyle(M_PENDATA->m_style),
244 M_PENDATA->m_width,
245 ms_colour );
246 }
247
248 delete [] real_dash;
249 }
250#else // WinCE
251 M_PENDATA->m_hPen =
252 (WXHPEN) CreatePen( wx2msPenStyle(M_PENDATA->m_style),
253 M_PENDATA->m_width,
254 ms_colour );
255#endif // !WinCE/WinCE
256
257 return true;
2bda0e17
KB
258}
259
2b5f62a0 260WXHANDLE wxPen::GetResourceHandle() const
2bda0e17 261{
92218ce6
WS
262 if ( !M_PENDATA )
263 return 0;
264 else
265 return (WXHANDLE)M_PENDATA->m_hPen;
2bda0e17
KB
266}
267
33ac7e6f 268bool wxPen::FreeResource(bool WXUNUSED(force))
2bda0e17 269{
92218ce6
WS
270 if (M_PENDATA && (M_PENDATA->m_hPen != 0))
271 {
272 DeleteObject((HPEN) M_PENDATA->m_hPen);
273 M_PENDATA->m_hPen = 0;
274 return true;
275 }
276 else return false;
2bda0e17
KB
277}
278
e4a81a2e 279bool wxPen::IsFree() const
2bda0e17 280{
92218ce6 281 return (M_PENDATA && M_PENDATA->m_hPen == 0);
2bda0e17 282}
2bda0e17 283
b823f5a1 284void wxPen::Unshare()
2bda0e17 285{
92218ce6
WS
286 // Don't change shared data
287 if (!m_refData)
b823f5a1 288 {
92218ce6
WS
289 m_refData = new wxPenRefData();
290 }
b823f5a1
JS
291 else
292 {
92218ce6
WS
293 wxPenRefData* ref = new wxPenRefData(*(wxPenRefData*)m_refData);
294 UnRef();
295 m_refData = ref;
296 }
2bda0e17
KB
297}
298
299void wxPen::SetColour(const wxColour& col)
300{
b823f5a1 301 Unshare();
2bda0e17 302
b823f5a1 303 M_PENDATA->m_colour = col;
bbd41262 304
2bda0e17
KB
305 RealizeResource();
306}
307
1a1498c0 308void wxPen::SetColour(unsigned char r, unsigned char g, unsigned char b)
2bda0e17 309{
b823f5a1 310 Unshare();
2bda0e17 311
b823f5a1 312 M_PENDATA->m_colour.Set(r, g, b);
bbd41262 313
2bda0e17
KB
314 RealizeResource();
315}
316
debe6624 317void wxPen::SetWidth(int Width)
2bda0e17 318{
b823f5a1 319 Unshare();
2bda0e17 320
b823f5a1 321 M_PENDATA->m_width = Width;
2bda0e17 322
2bda0e17
KB
323 RealizeResource();
324}
325
debe6624 326void wxPen::SetStyle(int Style)
2bda0e17 327{
b823f5a1 328 Unshare();
2bda0e17 329
b823f5a1 330 M_PENDATA->m_style = Style;
2bda0e17 331
2bda0e17
KB
332 RealizeResource();
333}
334
335void wxPen::SetStipple(const wxBitmap& Stipple)
336{
b823f5a1 337 Unshare();
2bda0e17 338
b823f5a1
JS
339 M_PENDATA->m_stipple = Stipple;
340 M_PENDATA->m_style = wxSTIPPLE;
bbd41262 341
2bda0e17
KB
342 RealizeResource();
343}
344
debe6624 345void wxPen::SetDashes(int nb_dashes, const wxDash *Dash)
2bda0e17 346{
b823f5a1 347 Unshare();
2bda0e17 348
b823f5a1 349 M_PENDATA->m_nbDash = nb_dashes;
edd97174 350 M_PENDATA->m_dash = (wxDash *)Dash;
bbd41262 351
2bda0e17
KB
352 RealizeResource();
353}
354
debe6624 355void wxPen::SetJoin(int Join)
2bda0e17 356{
b823f5a1 357 Unshare();
2bda0e17 358
b823f5a1 359 M_PENDATA->m_join = Join;
2bda0e17 360
2bda0e17
KB
361 RealizeResource();
362}
363
debe6624 364void wxPen::SetCap(int Cap)
2bda0e17 365{
b823f5a1 366 Unshare();
2bda0e17 367
b823f5a1 368 M_PENDATA->m_cap = Cap;
2bda0e17 369
2bda0e17
KB
370 RealizeResource();
371}
372
373int wx2msPenStyle(int wx_style)
374{
07505825 375#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
c45a644e 376 switch (wx_style)
bbd41262 377 {
07505825
WS
378 case wxDOT:
379 return PS_DOT;
c45a644e 380
07505825
WS
381 case wxDOT_DASH:
382 return PS_DASHDOT;
383
384 case wxSHORT_DASH:
385 case wxLONG_DASH:
386 return PS_DASH;
387
388 case wxTRANSPARENT:
389 return PS_NULL;
390
391 case wxUSER_DASH:
392 // if (wxGetOsVersion()==wxWINDOWS_NT || wxGetOsVersion()==wxWIN95)
393 return PS_USERSTYLE;
394 }
2bda0e17 395#else
07505825 396 wxUnusedVar(wx_style);
2bda0e17 397#endif
07505825 398 return PS_SOLID;
2bda0e17 399}