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