~ubuntu-dev/wxwidgets2.6/upstream-debian

« back to all changes in this revision

Viewing changes to src/msw/pen.cpp

  • Committer: Daniel T Chen
  • Date: 2006-06-26 10:15:11 UTC
  • Revision ID: crimsun@ubuntu.com-20060626101511-a4436cec4c6d9b35
ImportĀ DebianĀ 2.6.3.2.1

Show diffs side-by-side

added added

removed removed

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