]> git.saurik.com Git - wxWidgets.git/blame - src/msw/pen.cpp
HasGroup/Entry added
[wxWidgets.git] / src / msw / pen.cpp
CommitLineData
2bda0e17
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: 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 and Markus Holzem
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "pen.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include <stdio.h>
25#include "wx/setup.h"
26#include "wx/list.h"
27#include "wx/utils.h"
28#include "wx/app.h"
29#include "wx/pen.h"
30#endif
31
32#include "wx/msw/private.h"
33#include "assert.h"
34
35#if !USE_SHARED_LIBRARIES
36IMPLEMENT_DYNAMIC_CLASS(wxPen, wxGDIObject)
37#endif
38
39wxPenRefData::wxPenRefData(void)
40{
41// m_stipple = NULL ;
42 m_style = wxSOLID;
43 m_width = 1;
44 m_join = wxJOIN_ROUND ;
45 m_cap = wxCAP_ROUND ;
46 m_nbDash = 0 ;
47 m_dash = 0 ;
48 m_hPen = 0;
49}
50
51wxPenRefData::~wxPenRefData(void)
52{
53 if ( m_hPen )
54 ::DeleteObject((HPEN) m_hPen);
55}
56
57// Pens
58
59wxPen::wxPen(void)
60{
61 if ( wxThePenList )
62 wxThePenList->AddPen(this);
63}
64
65wxPen::~wxPen()
66{
67 if (wxThePenList)
68 wxThePenList->RemovePen(this);
69}
70
71// Should implement Create
debe6624 72wxPen::wxPen(const wxColour& col, int Width, int Style)
2bda0e17
KB
73{
74 m_refData = new wxPenRefData;
75
76 M_PENDATA->m_colour = col;
77// M_PENDATA->m_stipple = NULL;
78 M_PENDATA->m_width = Width;
79 M_PENDATA->m_style = Style;
80 M_PENDATA->m_join = wxJOIN_ROUND ;
81 M_PENDATA->m_cap = wxCAP_ROUND ;
82 M_PENDATA->m_nbDash = 0 ;
83 M_PENDATA->m_dash = 0 ;
84 M_PENDATA->m_hPen = 0 ;
85
86#ifndef __WIN32__
87 // In Windows, only a pen of width = 1 can be dotted or dashed!
88 if ((Style == wxDOT) || (Style == wxLONG_DASH) ||
89 (Style == wxSHORT_DASH) || (Style == wxDOT_DASH) ||
90 (Style == wxUSER_DASH))
91 M_PENDATA->m_width = 1;
92#else
93/***
94 DWORD vers = GetVersion() ;
95 WORD high = HIWORD(vers) ; // high bit=0 for NT, 1 for Win32s
96 // Win32s doesn't support wide dashed pens
97
98 if ((high&0x8000)!=0)
99***/
100 if (wxGetOsVersion()==wxWIN32S)
101 {
102 // In Windows, only a pen of width = 1 can be dotted or dashed!
103 if ((Style == wxDOT) || (Style == wxLONG_DASH) ||
104 (Style == wxSHORT_DASH) || (Style == wxDOT_DASH) ||
105 (Style == wxUSER_DASH))
106 M_PENDATA->m_width = 1;
107 }
108#endif
109 RealizeResource();
110
111 if ( wxThePenList )
112 wxThePenList->AddPen(this);
113}
114
debe6624 115wxPen::wxPen(const wxBitmap& stipple, int Width)
2bda0e17
KB
116{
117 m_refData = new wxPenRefData;
118
119// M_PENDATA->m_colour = col;
120 M_PENDATA->m_stipple = stipple;
121 M_PENDATA->m_width = Width;
122 M_PENDATA->m_style = wxSTIPPLE;
123 M_PENDATA->m_join = wxJOIN_ROUND ;
124 M_PENDATA->m_cap = wxCAP_ROUND ;
125 M_PENDATA->m_nbDash = 0 ;
126 M_PENDATA->m_dash = 0 ;
127 M_PENDATA->m_hPen = 0 ;
128
129 RealizeResource();
130
131 if ( wxThePenList )
132 wxThePenList->AddPen(this);
133}
134
debe6624 135wxPen::wxPen(const wxString& col, int Width, int Style)
2bda0e17
KB
136{
137 m_refData = new wxPenRefData;
138
139 M_PENDATA->m_colour = col;
140// M_PENDATA->m_stipple = NULL ;
141 M_PENDATA->m_width = Width;
142 M_PENDATA->m_style = Style;
143 M_PENDATA->m_join = wxJOIN_ROUND ;
144 M_PENDATA->m_cap = wxCAP_ROUND ;
145 M_PENDATA->m_nbDash = 0 ;
146 M_PENDATA->m_dash = 0 ;
147 M_PENDATA->m_hPen = 0 ;
148
2bda0e17
KB
149 RealizeResource();
150
151 if ( wxThePenList )
152 wxThePenList->AddPen(this);
153}
154
155bool wxPen::RealizeResource(void)
156{
157 if (M_PENDATA && (M_PENDATA->m_hPen == 0))
158 {
159 if (M_PENDATA->m_style==wxTRANSPARENT)
160 {
161 M_PENDATA->m_hPen = (WXHPEN) ::GetStockObject(NULL_PEN);
162 return TRUE;
163 }
164
165 COLORREF ms_colour = 0 ;
166 ms_colour = M_PENDATA->m_colour.GetPixel() ;
167
168 // Join style, Cap style, Pen Stippling only on Win32.
169 // Currently no time to find equivalent on Win3.1, sorry
170 // [if such equiv exist!!]
171#ifdef __WIN32__
172 if (M_PENDATA->m_join==wxJOIN_ROUND &&
173 M_PENDATA->m_cap==wxCAP_ROUND &&
174 M_PENDATA->m_style!=wxUSER_DASH &&
6f65e337
JS
175 M_PENDATA->m_style!=wxSTIPPLE &&
176 M_PENDATA->m_width <= 1
2bda0e17
KB
177 )
178 M_PENDATA->m_hPen = (WXHPEN) CreatePen(wx2msPenStyle(M_PENDATA->m_style), M_PENDATA->m_width, ms_colour);
179 else
180 {
181 DWORD ms_style = PS_GEOMETRIC|wx2msPenStyle(M_PENDATA->m_style) ;
182
183 LOGBRUSH logb ;
184
185 switch(M_PENDATA->m_join)
186 {
187 case wxJOIN_BEVEL: ms_style |= PS_JOIN_BEVEL ; break ;
188 case wxJOIN_MITER: ms_style |= PS_JOIN_MITER ; break ;
189 default:
190 case wxJOIN_ROUND: ms_style |= PS_JOIN_ROUND ; break ;
191 }
192
193 switch(M_PENDATA->m_cap)
194 {
195 case wxCAP_PROJECTING: ms_style |= PS_ENDCAP_SQUARE ; break ;
196 case wxCAP_BUTT: ms_style |= PS_ENDCAP_FLAT ; break ;
197 default:
198 case wxCAP_ROUND: ms_style |= PS_ENDCAP_ROUND ; break ;
199 }
200
201 switch(M_PENDATA->m_style)
202 {
203 case wxSTIPPLE:
204 logb.lbStyle = BS_PATTERN ;
205 if (M_PENDATA->m_stipple.Ok())
206 logb.lbHatch = (LONG)M_PENDATA->m_stipple.GetHBITMAP() ;
207 else
208 logb.lbHatch = (LONG)0 ;
209 break ;
210 case wxBDIAGONAL_HATCH:
211 logb.lbStyle = BS_HATCHED ;
212 logb.lbHatch = HS_BDIAGONAL ;
213 break ;
214 case wxCROSSDIAG_HATCH:
215 logb.lbStyle = BS_HATCHED ;
216 logb.lbHatch = HS_DIAGCROSS ;
217 break ;
218 case wxFDIAGONAL_HATCH:
219 logb.lbStyle = BS_HATCHED ;
220 logb.lbHatch = HS_FDIAGONAL ;
221 break ;
222 case wxCROSS_HATCH:
223 logb.lbStyle = BS_HATCHED ;
224 logb.lbHatch = HS_CROSS ;
225 break ;
226 case wxHORIZONTAL_HATCH:
227 logb.lbStyle = BS_HATCHED ;
228 logb.lbHatch = HS_HORIZONTAL ;
229 break ;
230 case wxVERTICAL_HATCH:
231 logb.lbStyle = BS_HATCHED ;
232 logb.lbHatch = HS_VERTICAL ;
233 break ;
234 default:
235 logb.lbStyle = BS_SOLID ;
236 break ;
237 }
238 logb.lbColor = ms_colour ;
239 wxDash *real_dash ;
240 if (M_PENDATA->m_style==wxUSER_DASH && M_PENDATA->m_nbDash && M_PENDATA->m_dash)
241 {
242 real_dash = new wxDash[M_PENDATA->m_nbDash] ;
243 int i;
244 for (i=0;i<M_PENDATA->m_nbDash;i++)
245 real_dash[i] = M_PENDATA->m_dash[i] * M_PENDATA->m_width ;
246 }
247 else
248 real_dash = 0 ;
249
250 // Win32s doesn't have ExtCreatePen function...
251 if (wxGetOsVersion()==wxWINDOWS_NT || wxGetOsVersion()==wxWIN95)
252 M_PENDATA->m_hPen = (WXHPEN) ExtCreatePen(ms_style,M_PENDATA->m_width,&logb,
253 M_PENDATA->m_style==wxUSER_DASH ? M_PENDATA->m_nbDash:0, (const DWORD *)real_dash);
254 else
255 M_PENDATA->m_hPen = (WXHPEN) CreatePen(wx2msPenStyle(M_PENDATA->m_style), M_PENDATA->m_width, ms_colour);
256
257 if (real_dash)
258 delete [] real_dash ;
259 }
260#else
261 M_PENDATA->m_hPen = (WXHPEN) CreatePen(wx2msPenStyle(M_PENDATA->m_style), M_PENDATA->m_width, ms_colour);
262#endif
263#ifdef DEBUG_CREATE
264 if (M_PENDATA->m_hPen==0)
265 wxError("Cannot create pen","Internal error") ;
266#endif
267 return TRUE;
268 }
269 return FALSE;
270}
271
272WXHANDLE wxPen::GetResourceHandle(void)
273{
274 if ( !M_PENDATA )
275 return 0;
276 else
277 return (WXHANDLE)M_PENDATA->m_hPen;
278}
279
280bool wxPen::FreeResource(bool force)
281{
282 if (M_PENDATA && (M_PENDATA->m_hPen != 0))
283 {
284 DeleteObject((HPEN) M_PENDATA->m_hPen);
285 M_PENDATA->m_hPen = 0;
286 return TRUE;
287 }
288 else return FALSE;
289}
290
291/*
292bool wxPen::UseResource(void)
293{
294 IncrementResourceUsage();
295 return TRUE;
296}
297
298bool wxPen::ReleaseResource(void)
299{
300 DecrementResourceUsage();
301 return TRUE;
302}
303*/
304
305bool wxPen::IsFree(void)
306{
307 return (M_PENDATA && M_PENDATA->m_hPen == 0);
308}
309
310void wxPen::SetColour(const wxColour& col)
311{
312 if ( !M_PENDATA )
313 m_refData = new wxPenRefData;
314
315 M_PENDATA->m_colour = col;
316
317 if (FreeResource())
318 RealizeResource();
319}
320
321void wxPen::SetColour(const wxString& col)
322{
323 if ( !M_PENDATA )
324 m_refData = new wxPenRefData;
325
326 M_PENDATA->m_colour = col;
327
328 if (FreeResource())
329 RealizeResource();
330}
331
332void wxPen::SetColour(const unsigned char r, const unsigned char g, const unsigned char b)
333{
334 if ( !M_PENDATA )
335 m_refData = new wxPenRefData;
336
337 M_PENDATA->m_colour.Set(r, g, b);
338
339 if (FreeResource())
340 RealizeResource();
341}
342
debe6624 343void wxPen::SetWidth(int Width)
2bda0e17
KB
344{
345 if ( !M_PENDATA )
346 m_refData = new wxPenRefData;
347
348 M_PENDATA->m_width = Width;
349
350 if (FreeResource())
351 RealizeResource();
352}
353
debe6624 354void wxPen::SetStyle(int Style)
2bda0e17
KB
355{
356 if ( !M_PENDATA )
357 m_refData = new wxPenRefData;
358
359 M_PENDATA->m_style = Style;
360
361 if (FreeResource())
362 RealizeResource();
363}
364
365void wxPen::SetStipple(const wxBitmap& Stipple)
366{
367 if ( !M_PENDATA )
368 m_refData = new wxPenRefData;
369
370 M_PENDATA->m_stipple = Stipple;
371 M_PENDATA->m_style = wxSTIPPLE;
372
373 if (FreeResource())
374 RealizeResource();
375}
376
debe6624 377void wxPen::SetDashes(int nb_dashes, const wxDash *Dash)
2bda0e17
KB
378{
379 if ( !M_PENDATA )
380 m_refData = new wxPenRefData;
381
382 M_PENDATA->m_nbDash = nb_dashes;
383 M_PENDATA->m_dash = (wxDash *)Dash;
384
385 if (FreeResource())
386 RealizeResource();
387}
388
debe6624 389void wxPen::SetJoin(int Join)
2bda0e17
KB
390{
391 if ( !M_PENDATA )
392 m_refData = new wxPenRefData;
393
394 M_PENDATA->m_join = Join;
395
396 if (FreeResource())
397 RealizeResource();
398}
399
debe6624 400void wxPen::SetCap(int Cap)
2bda0e17
KB
401{
402 if ( !M_PENDATA )
403 m_refData = new wxPenRefData;
404
405 M_PENDATA->m_cap = Cap;
406
407 if (FreeResource())
408 RealizeResource();
409}
410
411int wx2msPenStyle(int wx_style)
412{
413 int cstyle;
414/***
415#ifdef __WIN32__
416 DWORD vers = GetVersion() ;
417 WORD high = HIWORD(vers) ; // high bit=0 for NT, 1 for Win32s
418#endif
419***/
420 switch (wx_style)
421 {
422 case wxDOT:
423 cstyle = PS_DOT;
424 break;
425 case wxSHORT_DASH:
426 case wxLONG_DASH:
427 cstyle = PS_DASH;
428 break;
429 case wxTRANSPARENT:
430 cstyle = PS_NULL;
431 break;
432 case wxUSER_DASH:
433 // User dash style not supported on Win3.1, sorry...
434#ifdef __WIN32__
435 // Win32s doesn't have PS_USERSTYLE
436/***
437 if ((high&0x8000)==0)
438***/
439 if (wxGetOsVersion()==wxWINDOWS_NT)
440 cstyle = PS_USERSTYLE ;
441 else
442 cstyle = PS_DOT ; // We must make a choice... This is mine!
443#else
444 cstyle = PS_DASH ;
445#endif
446 break ;
447 case wxSOLID:
448 default:
449 cstyle = PS_SOLID;
450 break;
451 }
452 return cstyle;
453}
454