1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/pen.cpp
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
25 #include "wx/os2/private.h"
27 class WXDLLIMPEXP_FWD_CORE wxPen
;
29 // ----------------------------------------------------------------------------
30 // wxPenRefData: contains information about an HPEN and its handle
31 // ----------------------------------------------------------------------------
33 class WXDLLEXPORT wxPenRefData
: public wxGDIRefData
35 friend class WXDLLIMPEXP_FWD_CORE wxPen
;
38 wxPenRefData(const wxPenRefData
& rData
);
39 wxPenRefData(const wxColour
& col
, int width
, wxPenStyle style
);
40 wxPenRefData(const wxBitmap
& stipple
, int width
);
41 virtual ~wxPenRefData();
43 bool operator==(const wxPenRefData
& data
) const
45 // we intentionally don't compare m_hPen fields here
46 return m_nStyle
== data
.m_nStyle
&&
47 m_nWidth
== data
.m_nWidth
&&
48 m_nJoin
== data
.m_nJoin
&&
49 m_nCap
== data
.m_nCap
&&
50 m_vColour
== data
.m_vColour
&&
51 (m_nStyle
!= wxPENSTYLE_STIPPLE
|| m_vStipple
.IsSameAs(data
.m_vStipple
)) &&
52 (m_nStyle
!= wxPENSTYLE_USER_DASH
||
53 (m_dash
== data
.m_dash
&&
54 memcmp(m_dash
, data
.m_dash
, m_nbDash
*sizeof(wxDash
)) == 0));
58 // initialize the fields which have reasonable default values
60 // doesn't initialize m_width and m_style which must be initialize in ctor
63 m_nJoin
= wxJOIN_ROUND
;
78 WXHPEN m_hPen
;// in OS/2 GPI this will be the PS the pen is associated with
80 DECLARE_NO_ASSIGN_CLASS(wxPenRefData
)
83 #define M_PENDATA ((wxPenRefData *)m_refData)
85 // ----------------------------------------------------------------------------
86 // wxPenRefData ctors/dtor
87 // ----------------------------------------------------------------------------
89 wxPenRefData::wxPenRefData()
93 m_nStyle
= wxPENSTYLE_SOLID
;
95 } // end of wxPenRefData::wxPenRefData
97 wxPenRefData::wxPenRefData(
98 const wxPenRefData
& rData
101 m_nStyle
= rData
.m_nStyle
;
102 m_nWidth
= rData
.m_nWidth
;
103 m_nJoin
= rData
.m_nJoin
;
104 m_nCap
= rData
.m_nCap
;
105 m_nbDash
= rData
.m_nbDash
;
106 m_dash
= rData
.m_dash
;
107 m_vColour
= rData
.m_vColour
;
109 } // end of wxPenRefData::wxPenRefData
111 wxPenRefData::wxPenRefData(const wxColour
& col
, int width
, wxPenStyle style
)
121 wxPenRefData::wxPenRefData(const wxBitmap
& stipple
, int width
)
125 m_nStyle
= wxPENSTYLE_STIPPLE
;
128 m_vStipple
= stipple
;
131 wxPenRefData::~wxPenRefData()
133 } // end of wxPenRefData::~wxPenRefData
135 // ----------------------------------------------------------------------------
137 // ----------------------------------------------------------------------------
139 IMPLEMENT_DYNAMIC_CLASS(wxPen
, wxGDIObject
)
142 const wxColour
& rColour
147 m_refData
= new wxPenRefData(rColour
, nWidth
, nStyle
);
150 } // end of wxPen::wxPen
152 #if FUTURE_WXWIN_COMPATIBILITY_3_0
153 wxPen::wxPen(const wxColour
& colour
, int width
, int style
)
155 m_refData
= new wxPenRefData(colour
, width
, (wxPenStyle
)style
);
162 const wxBitmap
& rStipple
166 m_refData
= new wxPenRefData (rStipple
, nWidth
);
169 } // end of wxPen::wxPen
171 bool wxPen::operator==(const wxPen
& pen
) const
174 penData
= wx_static_cast(const wxPenRefData
*, pen
.m_refData
);
176 // an invalid pen is only equal to another invalid pen
177 return m_refData
? penData
&& *M_PENDATA
== *penData
: !penData
;
184 bool wxPen::RealizeResource()
190 if (M_PENDATA
&& M_PENDATA
->m_hPen
== 0L)
192 SIZEL vSize
= {0, 0};
193 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
194 HDC hDC
= ::DevOpenDC( vHabmain
201 M_PENDATA
->m_hPen
= (WXHPEN
)::GpiCreatePS( vHabmain
204 ,PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
210 // Set the color table to RGB mode
212 if (!::GpiCreateLogColorTable( (HPS
)M_PENDATA
->m_hPen
220 vError
= ::WinGetLastError(vHabmain
);
221 sError
= wxPMErrorToStr(vError
);
222 wxLogError(_T("Unable to set current color table to RGB mode. Error: %s\n"), sError
.c_str());
225 if (M_PENDATA
->m_nStyle
== wxPENSTYLE_TRANSPARENT
)
230 COLORREF vPmColour
= 0L;
231 USHORT uLineType
= (USHORT
)wx2os2PenStyle(M_PENDATA
->m_nStyle
);
233 vPmColour
= M_PENDATA
->m_vColour
.GetPixel();
237 switch(M_PENDATA
->m_nJoin
)
240 uJoin
= LINEJOIN_BEVEL
;
244 uJoin
= LINEJOIN_MITRE
;
248 uJoin
= LINEJOIN_ROUND
;
254 switch(M_PENDATA
->m_nCap
)
256 case wxCAP_PROJECTING
:
257 uCap
= LINEEND_SQUARE
;
265 uCap
= LINEEND_ROUND
;
268 m_vLineBundle
.lColor
= (LONG
)vPmColour
;
269 m_vLineBundle
.usMixMode
= FM_OVERPAINT
;
270 if (M_PENDATA
->m_nWidth
< 1)
271 M_PENDATA
->m_nWidth
= 1;
272 m_vLineBundle
.fxWidth
= M_PENDATA
->m_nWidth
;
273 m_vLineBundle
.lGeomWidth
= M_PENDATA
->m_nWidth
;
274 m_vLineBundle
.usType
= uLineType
;
275 m_vLineBundle
.usEnd
= uCap
;
276 m_vLineBundle
.usJoin
= uJoin
;
278 bOk
= ::GpiSetAttrs( M_PENDATA
->m_hPen
280 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
| LBB_END
| LBB_JOIN
286 vError
= ::WinGetLastError(vHabmain
);
287 sError
= wxPMErrorToStr(vError
);
288 wxLogError(_T("Can't set Gpi attributes for a LINEBUNDLE. Error: %s\n"), sError
.c_str());
292 ULONG flAttrMask
= 0L;
293 ULONG flDefMask
= 0L;
294 switch(M_PENDATA
->m_nStyle
)
296 case wxPENSTYLE_STIPPLE
:
297 ::GpiSetBitmapId( M_PENDATA
->m_hPen
298 ,(USHORT
)M_PENDATA
->m_vStipple
.GetHBITMAP()
299 ,(USHORT
)M_PENDATA
->m_vStipple
.GetId()
301 ::GpiSetPatternSet( M_PENDATA
->m_hPen
302 ,(USHORT
)M_PENDATA
->m_vStipple
.GetId()
304 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SET
| ABB_SYMBOL
;
305 flDefMask
= ABB_REF_POINT
;
308 case wxPENSTYLE_BDIAGONAL_HATCH
:
309 m_vAreaBundle
.usSymbol
= PATSYM_DIAG3
;
310 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
311 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
312 flDefMask
= ABB_SET
| ABB_REF_POINT
;
315 case wxPENSTYLE_CROSSDIAG_HATCH
:
316 m_vAreaBundle
.usSymbol
= PATSYM_DIAGHATCH
;
317 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
318 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
319 flDefMask
= ABB_SET
| ABB_REF_POINT
;
322 case wxPENSTYLE_FDIAGONAL_HATCH
:
323 m_vAreaBundle
.usSymbol
= PATSYM_DIAG1
;
324 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
325 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
326 flDefMask
= ABB_SET
| ABB_REF_POINT
;
329 case wxPENSTYLE_CROSS_HATCH
:
330 m_vAreaBundle
.usSymbol
= PATSYM_HATCH
;
331 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
332 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
333 flDefMask
= ABB_SET
| ABB_REF_POINT
;
336 case wxPENSTYLE_HORIZONTAL_HATCH
:
337 m_vAreaBundle
.usSymbol
= PATSYM_HORIZ
;
338 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
339 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
340 flDefMask
= ABB_SET
| ABB_REF_POINT
;
343 case wxPENSTYLE_VERTICAL_HATCH
:
344 m_vAreaBundle
.usSymbol
= PATSYM_VERT
;
345 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
346 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
347 flDefMask
= ABB_SET
| ABB_REF_POINT
;
351 m_vAreaBundle
.usSymbol
= PATSYM_SOLID
;
352 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
353 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
354 flDefMask
= ABB_SET
| ABB_REF_POINT
;
358 m_vAreaBundle
.lColor
= vPmColour
;
359 m_vAreaBundle
.lBackColor
= RGB_WHITE
;
360 m_vAreaBundle
.usMixMode
= FM_OVERPAINT
;
361 m_vAreaBundle
.usBackMixMode
= BM_OVERPAINT
;
363 bOk
= ::GpiSetAttrs( M_PENDATA
->m_hPen
371 vError
= ::WinGetLastError(vHabmain
);
372 sError
= wxPMErrorToStr(vError
);
373 wxLogError(_T("Can't set Gpi attributes for an AREABUNDLE. Error: %s\n"), sError
.c_str());
379 } // end of wxPen::RealizeResource
381 WXHANDLE
wxPen::GetResourceHandle() const
386 return (WXHANDLE
)M_PENDATA
->m_hPen
;
387 } // end of wxPen::GetResourceHandle
389 bool wxPen::FreeResource( bool WXUNUSED(bForce
) )
391 if (M_PENDATA
&& (M_PENDATA
->m_hPen
!= 0))
393 M_PENDATA
->m_hPen
= 0;
397 } // end of wxPen::FreeResource
399 bool wxPen::IsFree() const
401 return (M_PENDATA
&& M_PENDATA
->m_hPen
== 0);
404 wxGDIRefData
* wxPen::CreateGDIRefData() const
406 return new wxPenRefData
;
409 wxGDIRefData
* wxPen::CloneGDIRefData(const wxGDIRefData
* data
) const
411 return new wxPenRefData(*wx_static_cast(const wxPenRefData
*, data
));
414 void wxPen::SetColour( const wxColour
& rColour
)
417 M_PENDATA
->m_vColour
= rColour
;
419 } // end of wxPen::SetColour
421 void wxPen::SetColour( unsigned char cRed
, unsigned char cGreen
, unsigned char cBlue
)
424 M_PENDATA
->m_vColour
.Set(cRed
, cGreen
, cBlue
);
426 } // end of wxPen::SetColour
428 void wxPen::SetPS( HPS hPS
)
431 if (M_PENDATA
->m_hPen
)
432 ::GpiDestroyPS(M_PENDATA
->m_hPen
);
433 M_PENDATA
->m_hPen
= hPS
;
435 } // end of WxWinGdi_CPen::SetPS
437 void wxPen::SetWidth(
442 M_PENDATA
->m_nWidth
= nWidth
;
444 } // end of wxPen::SetWidth
446 void wxPen::SetStyle(
451 M_PENDATA
->m_nStyle
= nStyle
;
453 } // end of wxPen::SetStyle
455 void wxPen::SetStipple(
456 const wxBitmap
& rStipple
460 M_PENDATA
->m_vStipple
= rStipple
;
461 M_PENDATA
->m_nStyle
= wxPENSTYLE_STIPPLE
;
463 } // end of wxPen::SetStipple
465 void wxPen::SetDashes( int WXUNUSED(nNbDashes
),
466 const wxDash
* WXUNUSED(pDash
) )
469 // Does nothing under OS/2
471 } // end of wxPen::SetDashes
478 M_PENDATA
->m_nJoin
= nJoin
;
480 } // end of wxPen::SetJoin
487 M_PENDATA
->m_nCap
= nCap
;
489 } // end of wxPen::SetCap
491 wxColour
wxPen::GetColour() const
493 wxCHECK_MSG( Ok(), wxNullColour
, wxT("invalid pen") );
495 return M_PENDATA
->m_vColour
;
498 int wxPen::GetWidth() const
500 wxCHECK_MSG( Ok(), -1, wxT("invalid pen") );
502 return M_PENDATA
->m_nWidth
;
505 wxPenStyle
wxPen::GetStyle() const
507 wxCHECK_MSG( Ok(), wxPENSTYLE_INVALID
, wxT("invalid pen") );
509 return M_PENDATA
->m_nStyle
;
512 wxPenJoin
wxPen::GetJoin() const
514 wxCHECK_MSG( Ok(), wxJOIN_INVALID
, wxT("invalid pen") );
516 return M_PENDATA
->m_nJoin
;
519 wxPenCap
wxPen::GetCap() const
521 wxCHECK_MSG( Ok(), wxCAP_INVALID
, wxT("invalid pen") );
523 return M_PENDATA
->m_nCap
;
526 int wxPen::GetPS() const
528 wxCHECK_MSG( Ok(), 0, wxT("invalid pen") );
530 return M_PENDATA
->m_hPen
;
533 int wxPen::GetDashes(wxDash
** ptr
) const
535 wxCHECK_MSG( Ok(), -1, wxT("invalid pen") );
537 *ptr
= M_PENDATA
->m_dash
;
538 return M_PENDATA
->m_nbDash
;
541 wxDash
* wxPen::GetDash() const
543 wxCHECK_MSG( Ok(), NULL
, wxT("invalid pen") );
545 return M_PENDATA
->m_dash
;
548 int wxPen::GetDashCount() const
550 wxCHECK_MSG( Ok(), -1, wxT("invalid pen") );
552 return M_PENDATA
->m_nbDash
;
555 wxBitmap
* wxPen::GetStipple() const
557 wxCHECK_MSG( Ok(), NULL
, wxT("invalid pen") );
559 return &(M_PENDATA
->m_vStipple
);
571 nPMStyle
= LINETYPE_DOT
;
574 case wxPENSTYLE_DOT_DASH
:
575 nPMStyle
= LINETYPE_DASHDOT
;
578 case wxPENSTYLE_SHORT_DASH
:
579 nPMStyle
= LINETYPE_SHORTDASH
;
582 case wxPENSTYLE_LONG_DASH
:
583 nPMStyle
= LINETYPE_LONGDASH
;
586 case wxPENSTYLE_TRANSPARENT
:
587 nPMStyle
= LINETYPE_INVISIBLE
;
590 case wxPENSTYLE_USER_DASH
:
591 nPMStyle
= LINETYPE_DASHDOUBLEDOT
; // We must make a choice... This is mine!
594 case wxPENSTYLE_SOLID
:
596 nPMStyle
= LINETYPE_SOLID
;
600 } // end of wx2os2PenStyle