1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/pen.cpp
4 // Author: David Webster
7 // Copyright: (c) David Webster
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
24 #include "wx/os2/private.h"
26 class WXDLLIMPEXP_FWD_CORE wxPen
;
28 // ----------------------------------------------------------------------------
29 // wxPenRefData: contains information about an HPEN and its handle
30 // ----------------------------------------------------------------------------
32 class WXDLLEXPORT wxPenRefData
: public wxGDIRefData
34 friend class WXDLLIMPEXP_FWD_CORE wxPen
;
37 wxPenRefData(const wxPenRefData
& rData
);
38 wxPenRefData(const wxColour
& col
, int width
, wxPenStyle style
);
39 wxPenRefData(const wxBitmap
& stipple
, int width
);
40 virtual ~wxPenRefData();
42 bool operator==(const wxPenRefData
& data
) const
44 // we intentionally don't compare m_hPen fields here
45 return m_nStyle
== data
.m_nStyle
&&
46 m_nWidth
== data
.m_nWidth
&&
47 m_nJoin
== data
.m_nJoin
&&
48 m_nCap
== data
.m_nCap
&&
49 m_vColour
== data
.m_vColour
&&
50 (m_nStyle
!= wxPENSTYLE_STIPPLE
|| m_vStipple
.IsSameAs(data
.m_vStipple
)) &&
51 (m_nStyle
!= wxPENSTYLE_USER_DASH
||
52 (m_dash
== data
.m_dash
&&
53 memcmp(m_dash
, data
.m_dash
, m_nbDash
*sizeof(wxDash
)) == 0));
57 // initialize the fields which have reasonable default values
59 // doesn't initialize m_width and m_style which must be initialize in ctor
62 m_nJoin
= wxJOIN_ROUND
;
77 WXHPEN m_hPen
;// in OS/2 GPI this will be the PS the pen is associated with
79 wxDECLARE_NO_ASSIGN_CLASS(wxPenRefData
);
82 #define M_PENDATA ((wxPenRefData *)m_refData)
84 // ----------------------------------------------------------------------------
85 // wxPenRefData ctors/dtor
86 // ----------------------------------------------------------------------------
88 wxPenRefData::wxPenRefData()
92 m_nStyle
= wxPENSTYLE_SOLID
;
94 } // end of wxPenRefData::wxPenRefData
96 wxPenRefData::wxPenRefData(
97 const wxPenRefData
& rData
100 m_nStyle
= rData
.m_nStyle
;
101 m_nWidth
= rData
.m_nWidth
;
102 m_nJoin
= rData
.m_nJoin
;
103 m_nCap
= rData
.m_nCap
;
104 m_nbDash
= rData
.m_nbDash
;
105 m_dash
= rData
.m_dash
;
106 m_vColour
= rData
.m_vColour
;
108 } // end of wxPenRefData::wxPenRefData
110 wxPenRefData::wxPenRefData(const wxColour
& col
, int width
, wxPenStyle style
)
120 wxPenRefData::wxPenRefData(const wxBitmap
& stipple
, int width
)
124 m_nStyle
= wxPENSTYLE_STIPPLE
;
127 m_vStipple
= stipple
;
130 wxPenRefData::~wxPenRefData()
132 } // end of wxPenRefData::~wxPenRefData
134 // ----------------------------------------------------------------------------
136 // ----------------------------------------------------------------------------
138 IMPLEMENT_DYNAMIC_CLASS(wxPen
, wxGDIObject
)
141 const wxColour
& rColour
146 m_refData
= new wxPenRefData(rColour
, nWidth
, nStyle
);
149 } // end of wxPen::wxPen
151 #if FUTURE_WXWIN_COMPATIBILITY_3_0
152 wxPen::wxPen(const wxColour
& colour
, int width
, int style
)
154 m_refData
= new wxPenRefData(colour
, width
, (wxPenStyle
)style
);
161 const wxBitmap
& rStipple
165 m_refData
= new wxPenRefData (rStipple
, nWidth
);
168 } // end of wxPen::wxPen
170 bool wxPen::operator==(const wxPen
& pen
) const
173 penData
= static_cast<const wxPenRefData
*>(pen
.m_refData
);
175 // an invalid pen is only equal to another invalid pen
176 return m_refData
? penData
&& *M_PENDATA
== *penData
: !penData
;
183 bool wxPen::RealizeResource()
189 if (M_PENDATA
&& M_PENDATA
->m_hPen
== 0L)
191 SIZEL vSize
= {0, 0};
192 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
193 HDC hDC
= ::DevOpenDC( vHabmain
200 M_PENDATA
->m_hPen
= (WXHPEN
)::GpiCreatePS( vHabmain
203 ,PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
209 // Set the color table to RGB mode
211 if (!::GpiCreateLogColorTable( (HPS
)M_PENDATA
->m_hPen
219 vError
= ::WinGetLastError(vHabmain
);
220 sError
= wxPMErrorToStr(vError
);
221 wxLogError(wxT("Unable to set current color table to RGB mode. Error: %s\n"), sError
.c_str());
224 if (M_PENDATA
->m_nStyle
== wxPENSTYLE_TRANSPARENT
)
229 COLORREF vPmColour
= 0L;
230 USHORT uLineType
= (USHORT
)wx2os2PenStyle(M_PENDATA
->m_nStyle
);
232 vPmColour
= M_PENDATA
->m_vColour
.GetPixel();
236 switch(M_PENDATA
->m_nJoin
)
239 uJoin
= LINEJOIN_BEVEL
;
243 uJoin
= LINEJOIN_MITRE
;
247 uJoin
= LINEJOIN_ROUND
;
253 switch(M_PENDATA
->m_nCap
)
255 case wxCAP_PROJECTING
:
256 uCap
= LINEEND_SQUARE
;
264 uCap
= LINEEND_ROUND
;
267 m_vLineBundle
.lColor
= (LONG
)vPmColour
;
268 m_vLineBundle
.usMixMode
= FM_OVERPAINT
;
269 if (M_PENDATA
->m_nWidth
< 1)
270 M_PENDATA
->m_nWidth
= 1;
271 m_vLineBundle
.fxWidth
= M_PENDATA
->m_nWidth
;
272 m_vLineBundle
.lGeomWidth
= M_PENDATA
->m_nWidth
;
273 m_vLineBundle
.usType
= uLineType
;
274 m_vLineBundle
.usEnd
= uCap
;
275 m_vLineBundle
.usJoin
= uJoin
;
277 bOk
= ::GpiSetAttrs( M_PENDATA
->m_hPen
279 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
| LBB_END
| LBB_JOIN
285 vError
= ::WinGetLastError(vHabmain
);
286 sError
= wxPMErrorToStr(vError
);
287 wxLogError(wxT("Can't set Gpi attributes for a LINEBUNDLE. Error: %s\n"), sError
.c_str());
291 ULONG flAttrMask
= 0L;
292 ULONG flDefMask
= 0L;
293 switch(M_PENDATA
->m_nStyle
)
295 case wxPENSTYLE_STIPPLE
:
296 ::GpiSetBitmapId( M_PENDATA
->m_hPen
297 ,(USHORT
)M_PENDATA
->m_vStipple
.GetHBITMAP()
298 ,(USHORT
)M_PENDATA
->m_vStipple
.GetId()
300 ::GpiSetPatternSet( M_PENDATA
->m_hPen
301 ,(USHORT
)M_PENDATA
->m_vStipple
.GetId()
303 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SET
| ABB_SYMBOL
;
304 flDefMask
= ABB_REF_POINT
;
307 case wxPENSTYLE_BDIAGONAL_HATCH
:
308 m_vAreaBundle
.usSymbol
= PATSYM_DIAG3
;
309 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
310 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
311 flDefMask
= ABB_SET
| ABB_REF_POINT
;
314 case wxPENSTYLE_CROSSDIAG_HATCH
:
315 m_vAreaBundle
.usSymbol
= PATSYM_DIAGHATCH
;
316 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
317 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
318 flDefMask
= ABB_SET
| ABB_REF_POINT
;
321 case wxPENSTYLE_FDIAGONAL_HATCH
:
322 m_vAreaBundle
.usSymbol
= PATSYM_DIAG1
;
323 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
324 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
325 flDefMask
= ABB_SET
| ABB_REF_POINT
;
328 case wxPENSTYLE_CROSS_HATCH
:
329 m_vAreaBundle
.usSymbol
= PATSYM_HATCH
;
330 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
331 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
332 flDefMask
= ABB_SET
| ABB_REF_POINT
;
335 case wxPENSTYLE_HORIZONTAL_HATCH
:
336 m_vAreaBundle
.usSymbol
= PATSYM_HORIZ
;
337 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
338 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
339 flDefMask
= ABB_SET
| ABB_REF_POINT
;
342 case wxPENSTYLE_VERTICAL_HATCH
:
343 m_vAreaBundle
.usSymbol
= PATSYM_VERT
;
344 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
345 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
346 flDefMask
= ABB_SET
| ABB_REF_POINT
;
350 m_vAreaBundle
.usSymbol
= PATSYM_SOLID
;
351 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
352 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
353 flDefMask
= ABB_SET
| ABB_REF_POINT
;
357 m_vAreaBundle
.lColor
= vPmColour
;
358 m_vAreaBundle
.lBackColor
= RGB_WHITE
;
359 m_vAreaBundle
.usMixMode
= FM_OVERPAINT
;
360 m_vAreaBundle
.usBackMixMode
= BM_OVERPAINT
;
362 bOk
= ::GpiSetAttrs( M_PENDATA
->m_hPen
370 vError
= ::WinGetLastError(vHabmain
);
371 sError
= wxPMErrorToStr(vError
);
372 wxLogError(wxT("Can't set Gpi attributes for an AREABUNDLE. Error: %s\n"), sError
.c_str());
378 } // end of wxPen::RealizeResource
380 WXHANDLE
wxPen::GetResourceHandle() const
385 return (WXHANDLE
)M_PENDATA
->m_hPen
;
386 } // end of wxPen::GetResourceHandle
388 bool wxPen::FreeResource( bool WXUNUSED(bForce
) )
390 if (M_PENDATA
&& (M_PENDATA
->m_hPen
!= 0))
392 M_PENDATA
->m_hPen
= 0;
396 } // end of wxPen::FreeResource
398 bool wxPen::IsFree() const
400 return (M_PENDATA
&& M_PENDATA
->m_hPen
== 0);
403 wxGDIRefData
* wxPen::CreateGDIRefData() const
405 return new wxPenRefData
;
408 wxGDIRefData
* wxPen::CloneGDIRefData(const wxGDIRefData
* data
) const
410 return new wxPenRefData(*static_cast<const wxPenRefData
*>(data
));
413 void wxPen::SetColour( const wxColour
& rColour
)
416 M_PENDATA
->m_vColour
= rColour
;
418 } // end of wxPen::SetColour
420 void wxPen::SetColour( unsigned char cRed
, unsigned char cGreen
, unsigned char cBlue
)
423 M_PENDATA
->m_vColour
.Set(cRed
, cGreen
, cBlue
);
425 } // end of wxPen::SetColour
427 void wxPen::SetPS( HPS hPS
)
430 if (M_PENDATA
->m_hPen
)
431 ::GpiDestroyPS(M_PENDATA
->m_hPen
);
432 M_PENDATA
->m_hPen
= hPS
;
434 } // end of WxWinGdi_CPen::SetPS
436 void wxPen::SetWidth(
441 M_PENDATA
->m_nWidth
= nWidth
;
443 } // end of wxPen::SetWidth
445 void wxPen::SetStyle(
450 M_PENDATA
->m_nStyle
= nStyle
;
452 } // end of wxPen::SetStyle
454 void wxPen::SetStipple(
455 const wxBitmap
& rStipple
459 M_PENDATA
->m_vStipple
= rStipple
;
460 M_PENDATA
->m_nStyle
= wxPENSTYLE_STIPPLE
;
462 } // end of wxPen::SetStipple
464 void wxPen::SetDashes( int WXUNUSED(nNbDashes
),
465 const wxDash
* WXUNUSED(pDash
) )
468 // Does nothing under OS/2
470 } // end of wxPen::SetDashes
477 M_PENDATA
->m_nJoin
= nJoin
;
479 } // end of wxPen::SetJoin
486 M_PENDATA
->m_nCap
= nCap
;
488 } // end of wxPen::SetCap
490 wxColour
wxPen::GetColour() const
492 wxCHECK_MSG( IsOk(), wxNullColour
, wxT("invalid pen") );
494 return M_PENDATA
->m_vColour
;
497 int wxPen::GetWidth() const
499 wxCHECK_MSG( IsOk(), -1, wxT("invalid pen") );
501 return M_PENDATA
->m_nWidth
;
504 wxPenStyle
wxPen::GetStyle() const
506 wxCHECK_MSG( IsOk(), wxPENSTYLE_INVALID
, wxT("invalid pen") );
508 return M_PENDATA
->m_nStyle
;
511 wxPenJoin
wxPen::GetJoin() const
513 wxCHECK_MSG( IsOk(), wxJOIN_INVALID
, wxT("invalid pen") );
515 return M_PENDATA
->m_nJoin
;
518 wxPenCap
wxPen::GetCap() const
520 wxCHECK_MSG( IsOk(), wxCAP_INVALID
, wxT("invalid pen") );
522 return M_PENDATA
->m_nCap
;
525 int wxPen::GetPS() const
527 wxCHECK_MSG( IsOk(), 0, wxT("invalid pen") );
529 return M_PENDATA
->m_hPen
;
532 int wxPen::GetDashes(wxDash
** ptr
) const
534 wxCHECK_MSG( IsOk(), -1, wxT("invalid pen") );
536 *ptr
= M_PENDATA
->m_dash
;
537 return M_PENDATA
->m_nbDash
;
540 wxDash
* wxPen::GetDash() const
542 wxCHECK_MSG( IsOk(), NULL
, wxT("invalid pen") );
544 return M_PENDATA
->m_dash
;
547 int wxPen::GetDashCount() const
549 wxCHECK_MSG( IsOk(), -1, wxT("invalid pen") );
551 return M_PENDATA
->m_nbDash
;
554 wxBitmap
* wxPen::GetStipple() const
556 wxCHECK_MSG( IsOk(), NULL
, wxT("invalid pen") );
558 return &(M_PENDATA
->m_vStipple
);
570 nPMStyle
= LINETYPE_DOT
;
573 case wxPENSTYLE_DOT_DASH
:
574 nPMStyle
= LINETYPE_DASHDOT
;
577 case wxPENSTYLE_SHORT_DASH
:
578 nPMStyle
= LINETYPE_SHORTDASH
;
581 case wxPENSTYLE_LONG_DASH
:
582 nPMStyle
= LINETYPE_LONGDASH
;
585 case wxPENSTYLE_TRANSPARENT
:
586 nPMStyle
= LINETYPE_INVISIBLE
;
589 case wxPENSTYLE_USER_DASH
:
590 nPMStyle
= LINETYPE_DASHDOUBLEDOT
; // We must make a choice... This is mine!
593 case wxPENSTYLE_SOLID
:
595 nPMStyle
= LINETYPE_SOLID
;
599 } // end of wx2os2PenStyle