]> git.saurik.com Git - wxWidgets.git/blob - src/os2/pen.cpp
Include wx/list.h according to precompiled headers of wx/wx.h (with other minor clean...
[wxWidgets.git] / src / os2 / pen.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/pen.cpp
3 // Purpose: wxPen
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/10/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifndef WX_PRECOMP
16 #include <stdio.h>
17 #include "wx/list.h"
18 #include "wx/utils.h"
19 #include "wx/app.h"
20 #include "wx/pen.h"
21 #include "wx/log.h"
22 #endif
23
24 #include "wx/os2/private.h"
25 #include "assert.h"
26
27 IMPLEMENT_DYNAMIC_CLASS(wxPen, wxGDIObject)
28
29 wxPenRefData::wxPenRefData()
30 {
31 m_nStyle = wxSOLID;
32 m_nWidth = 1;
33 m_nJoin = wxJOIN_ROUND ;
34 m_nCap = wxCAP_ROUND ;
35 m_nbDash = 0 ;
36 m_dash = (wxDash*)NULL;
37 m_hPen = 0L;
38 } // end of wxPenRefData::wxPenRefData
39
40 wxPenRefData::wxPenRefData(
41 const wxPenRefData& rData
42 )
43 {
44 m_nStyle = rData.m_nStyle;
45 m_nWidth = rData.m_nWidth;
46 m_nJoin = rData.m_nJoin;
47 m_nCap = rData.m_nCap;
48 m_nbDash = rData.m_nbDash;
49 m_dash = rData.m_dash;
50 m_vColour = rData.m_vColour;
51 m_hPen = 0L;
52 } // end of wxPenRefData::wxPenRefData
53
54 wxPenRefData::~wxPenRefData()
55 {
56 } // end of wxPenRefData::~wxPenRefData
57
58 //
59 // Pens
60 //
61 wxPen::wxPen()
62 {
63 } // end of wxPen::wxPen
64
65 wxPen::~wxPen()
66 {
67 } // end of wxPen::wxPen
68
69 // Should implement Create
70 wxPen::wxPen(
71 const wxColour& rColour
72 , int nWidth
73 , int nStyle
74 )
75 {
76 m_refData = new wxPenRefData;
77
78 M_PENDATA->m_vColour = rColour;
79 M_PENDATA->m_nWidth = nWidth;
80 M_PENDATA->m_nStyle = nStyle;
81 M_PENDATA->m_nJoin = wxJOIN_ROUND ;
82 M_PENDATA->m_nCap = wxCAP_ROUND ;
83 M_PENDATA->m_hPen = 0L;
84
85 RealizeResource();
86 } // end of wxPen::wxPen
87
88 wxPen::wxPen(
89 const wxBitmap& rStipple
90 , int nWidth
91 )
92 {
93 m_refData = new wxPenRefData;
94
95 M_PENDATA->m_vStipple = rStipple;
96 M_PENDATA->m_nWidth = nWidth;
97 M_PENDATA->m_nStyle = wxSTIPPLE;
98 M_PENDATA->m_nJoin = wxJOIN_ROUND ;
99 M_PENDATA->m_nCap = wxCAP_ROUND ;
100 M_PENDATA->m_hPen = 0;
101
102 RealizeResource();
103 } // end of wxPen::wxPen
104
105 int wx2os2PenStyle(
106 int nWxStyle
107 );
108
109 bool wxPen::RealizeResource()
110 {
111 BOOL bOk;
112 ERRORID vError;
113 wxString sError;
114
115 if (M_PENDATA && M_PENDATA->m_hPen == 0L)
116 {
117 SIZEL vSize = {0, 0};
118 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
119 HDC hDC = ::DevOpenDC( vHabmain
120 ,OD_MEMORY
121 ,"*"
122 ,5L
123 ,(PDEVOPENDATA)&vDop
124 ,NULLHANDLE
125 );
126 M_PENDATA->m_hPen = (WXHPEN)::GpiCreatePS( vHabmain
127 ,hDC
128 ,&vSize
129 ,PU_PELS | GPIT_MICRO | GPIA_ASSOC
130 );
131 }
132 if (M_PENDATA)
133 {
134 //
135 // Set the color table to RGB mode
136 //
137 if (!::GpiCreateLogColorTable( (HPS)M_PENDATA->m_hPen
138 ,0L
139 ,LCOLF_RGB
140 ,0L
141 ,0L
142 ,NULL
143 ))
144 {
145 vError = ::WinGetLastError(vHabmain);
146 sError = wxPMErrorToStr(vError);
147 wxLogError(_T("Unable to set current color table to RGB mode. Error: %s\n"), sError.c_str());
148 return false;
149 }
150 if (M_PENDATA->m_nStyle == wxTRANSPARENT)
151 {
152 return true;
153 }
154
155 COLORREF vPmColour = 0L;
156 USHORT uLineType = (USHORT)wx2os2PenStyle(M_PENDATA->m_nStyle);
157
158 vPmColour = M_PENDATA->m_vColour.GetPixel();
159
160 USHORT uJoin = 0L;
161
162 switch(M_PENDATA->m_nJoin)
163 {
164 case wxJOIN_BEVEL:
165 uJoin = LINEJOIN_BEVEL;
166 break;
167
168 case wxJOIN_MITER:
169 uJoin = LINEJOIN_MITRE;
170 break;
171
172 case wxJOIN_ROUND:
173 uJoin = LINEJOIN_ROUND;
174 break;
175 }
176
177 USHORT uCap = 0L;
178
179 switch(M_PENDATA->m_nCap)
180 {
181 case wxCAP_PROJECTING:
182 uCap = LINEEND_SQUARE;
183 break;
184
185 case wxCAP_BUTT:
186 uCap = LINEEND_FLAT;
187 break;
188
189 case wxCAP_ROUND:
190 uCap = LINEEND_ROUND;
191 break;
192 }
193 m_vLineBundle.lColor = (LONG)vPmColour;
194 m_vLineBundle.usMixMode = FM_OVERPAINT;
195 m_vLineBundle.fxWidth = M_PENDATA->m_nWidth;
196 m_vLineBundle.lGeomWidth = M_PENDATA->m_nWidth;
197 m_vLineBundle.usType = uLineType;
198 m_vLineBundle.usEnd = uCap;
199 m_vLineBundle.usJoin = uJoin;
200
201 bOk = ::GpiSetAttrs( M_PENDATA->m_hPen
202 ,PRIM_LINE
203 ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE | LBB_END | LBB_JOIN
204 ,0L
205 ,&m_vLineBundle
206 );
207 if (!bOk)
208 {
209 vError = ::WinGetLastError(vHabmain);
210 sError = wxPMErrorToStr(vError);
211 wxLogError(_T("Can't set Gpi attributes for a LINEBUNDLE. Error: %s\n"), sError.c_str());
212 return false;
213 }
214
215 ULONG flAttrMask = 0L;
216 ULONG flDefMask = 0L;
217 switch(M_PENDATA->m_nStyle)
218 {
219 case wxSTIPPLE:
220 ::GpiSetBitmapId( M_PENDATA->m_hPen
221 ,(USHORT)M_PENDATA->m_vStipple.GetHBITMAP()
222 ,(USHORT)M_PENDATA->m_vStipple.GetId()
223 );
224 ::GpiSetPatternSet( M_PENDATA->m_hPen
225 ,(USHORT)M_PENDATA->m_vStipple.GetId()
226 );
227 flAttrMask = ABB_COLOR | ABB_BACK_COLOR | ABB_MIX_MODE | ABB_BACK_MIX_MODE | ABB_SET | ABB_SYMBOL;
228 flDefMask = ABB_REF_POINT;
229 break;
230
231 case wxBDIAGONAL_HATCH:
232 m_vAreaBundle.usSymbol = PATSYM_DIAG3;
233 m_vAreaBundle.usSet = LCID_DEFAULT;
234 flAttrMask = ABB_COLOR | ABB_BACK_COLOR | ABB_MIX_MODE | ABB_BACK_MIX_MODE | ABB_SYMBOL;
235 flDefMask = ABB_SET | ABB_REF_POINT;
236 break;
237
238 case wxCROSSDIAG_HATCH:
239 m_vAreaBundle.usSymbol = PATSYM_DIAGHATCH;
240 m_vAreaBundle.usSet = LCID_DEFAULT;
241 flAttrMask = ABB_COLOR | ABB_BACK_COLOR | ABB_MIX_MODE | ABB_BACK_MIX_MODE | ABB_SYMBOL;
242 flDefMask = ABB_SET | ABB_REF_POINT;
243 break;
244
245 case wxFDIAGONAL_HATCH:
246 m_vAreaBundle.usSymbol = PATSYM_DIAG1;
247 m_vAreaBundle.usSet = LCID_DEFAULT;
248 flAttrMask = ABB_COLOR | ABB_BACK_COLOR | ABB_MIX_MODE | ABB_BACK_MIX_MODE | ABB_SYMBOL;
249 flDefMask = ABB_SET | ABB_REF_POINT;
250 break;
251
252 case wxCROSS_HATCH:
253 m_vAreaBundle.usSymbol = PATSYM_HATCH;
254 m_vAreaBundle.usSet = LCID_DEFAULT;
255 flAttrMask = ABB_COLOR | ABB_BACK_COLOR | ABB_MIX_MODE | ABB_BACK_MIX_MODE | ABB_SYMBOL;
256 flDefMask = ABB_SET | ABB_REF_POINT;
257 break;
258
259 case wxHORIZONTAL_HATCH:
260 m_vAreaBundle.usSymbol = PATSYM_HORIZ;
261 m_vAreaBundle.usSet = LCID_DEFAULT;
262 flAttrMask = ABB_COLOR | ABB_BACK_COLOR | ABB_MIX_MODE | ABB_BACK_MIX_MODE | ABB_SYMBOL;
263 flDefMask = ABB_SET | ABB_REF_POINT;
264 break;
265
266 case wxVERTICAL_HATCH:
267 m_vAreaBundle.usSymbol = PATSYM_VERT;
268 m_vAreaBundle.usSet = LCID_DEFAULT;
269 flAttrMask = ABB_COLOR | ABB_BACK_COLOR | ABB_MIX_MODE | ABB_BACK_MIX_MODE | ABB_SYMBOL;
270 flDefMask = ABB_SET | ABB_REF_POINT;
271 break;
272
273 default:
274 m_vAreaBundle.usSymbol = PATSYM_SOLID;
275 m_vAreaBundle.usSet = LCID_DEFAULT;
276 flAttrMask = ABB_COLOR | ABB_BACK_COLOR | ABB_MIX_MODE | ABB_BACK_MIX_MODE | ABB_SYMBOL;
277 flDefMask = ABB_SET | ABB_REF_POINT;
278 break;
279 }
280
281 m_vAreaBundle.lColor = vPmColour;
282 m_vAreaBundle.lBackColor = RGB_WHITE;
283 m_vAreaBundle.usMixMode = FM_OVERPAINT;
284 m_vAreaBundle.usBackMixMode = BM_OVERPAINT;
285
286 bOk = ::GpiSetAttrs( M_PENDATA->m_hPen
287 ,PRIM_AREA
288 ,flAttrMask
289 ,flDefMask
290 ,&m_vAreaBundle
291 );
292 if (!bOk)
293 {
294 vError = ::WinGetLastError(vHabmain);
295 sError = wxPMErrorToStr(vError);
296 wxLogError(_T("Can't set Gpi attributes for an AREABUNDLE. Error: %s\n"), sError.c_str());
297 }
298
299 return (bool)bOk;
300 }
301 return false;
302 } // end of wxPen::RealizeResource
303
304 WXHANDLE wxPen::GetResourceHandle()
305 {
306 if (!M_PENDATA)
307 return 0;
308 else
309 return (WXHANDLE)M_PENDATA->m_hPen;
310 } // end of wxPen::GetResourceHandle
311
312 bool wxPen::FreeResource( bool WXUNUSED(bForce) )
313 {
314 if (M_PENDATA && (M_PENDATA->m_hPen != 0))
315 {
316 M_PENDATA->m_hPen = 0;
317 return true;
318 }
319 else return false;
320 } // end of wxPen::FreeResource
321
322 bool wxPen::IsFree() const
323 {
324 return (M_PENDATA && M_PENDATA->m_hPen == 0);
325 }
326
327 void wxPen::Unshare()
328 {
329 // Don't change shared data
330 if (!m_refData)
331 {
332 m_refData = new wxPenRefData();
333 }
334 else
335 {
336 wxPenRefData* ref = new wxPenRefData(*(wxPenRefData*)m_refData);
337 UnRef();
338 m_refData = ref;
339 }
340 } // end of wxPen::Unshare
341
342 void wxPen::SetColour( const wxColour& rColour )
343 {
344 Unshare();
345 M_PENDATA->m_vColour = rColour;
346 RealizeResource();
347 } // end of wxPen::SetColour
348
349 void wxPen::SetColour( unsigned char cRed, unsigned char cGreen, unsigned char cBlue)
350 {
351 Unshare();
352 M_PENDATA->m_vColour.Set(cRed, cGreen, cBlue);
353 RealizeResource();
354 } // end of wxPen::SetColour
355
356 void wxPen::SetPS( HPS hPS )
357 {
358 Unshare();
359 if (M_PENDATA->m_hPen)
360 ::GpiDestroyPS(M_PENDATA->m_hPen);
361 M_PENDATA->m_hPen = hPS;
362 RealizeResource();
363 } // end of WxWinGdi_CPen::SetPS
364
365 void wxPen::SetWidth(
366 int nWidth
367 )
368 {
369 Unshare();
370 M_PENDATA->m_nWidth = nWidth;
371 RealizeResource();
372 } // end of wxPen::SetWidth
373
374 void wxPen::SetStyle(
375 int nStyle
376 )
377 {
378 Unshare();
379 M_PENDATA->m_nStyle = nStyle;
380 RealizeResource();
381 } // end of wxPen::SetStyle
382
383 void wxPen::SetStipple(
384 const wxBitmap& rStipple
385 )
386 {
387 Unshare();
388 M_PENDATA->m_vStipple = rStipple;
389 M_PENDATA->m_nStyle = wxSTIPPLE;
390 RealizeResource();
391 } // end of wxPen::SetStipple
392
393 void wxPen::SetDashes( int WXUNUSED(nNbDashes),
394 const wxDash* WXUNUSED(pDash) )
395 {
396 //
397 // Does nothing under OS/2
398 //
399 } // end of wxPen::SetDashes
400
401 void wxPen::SetJoin(
402 int nJoin
403 )
404 {
405 Unshare();
406 M_PENDATA->m_nJoin = nJoin;
407 RealizeResource();
408 } // end of wxPen::SetJoin
409
410 void wxPen::SetCap(
411 int nCap
412 )
413 {
414 Unshare();
415 M_PENDATA->m_nCap = nCap;
416 RealizeResource();
417 } // end of wxPen::SetCap
418
419 int wx2os2PenStyle(
420 int nWxStyle
421 )
422 {
423 int nPMStyle = 0;
424
425 switch (nWxStyle)
426 {
427 case wxDOT:
428 nPMStyle = LINETYPE_DOT;
429 break;
430
431 case wxDOT_DASH:
432 nPMStyle = LINETYPE_DASHDOT;
433 break;
434
435 case wxSHORT_DASH:
436 nPMStyle = LINETYPE_SHORTDASH;
437 break;
438
439 case wxLONG_DASH:
440 nPMStyle = LINETYPE_LONGDASH;
441 break;
442
443 case wxTRANSPARENT:
444 nPMStyle = LINETYPE_INVISIBLE;
445 break;
446
447 case wxUSER_DASH:
448 nPMStyle = LINETYPE_DASHDOUBLEDOT; // We must make a choice... This is mine!
449 break;
450
451 case wxSOLID:
452 default:
453 nPMStyle = LINETYPE_SOLID;
454 break;
455 }
456 return nPMStyle;
457 } // end of wx2os2PenStyle