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
175 bool wxPen::RealizeResource()
181 if (M_PENDATA
&& M_PENDATA
->m_hPen
== 0L)
183 SIZEL vSize
= {0, 0};
184 DEVOPENSTRUC vDop
= {0L, "DISPLAY", NULL
, 0L, 0L, 0L, 0L, 0L, 0L};
185 HDC hDC
= ::DevOpenDC( vHabmain
192 M_PENDATA
->m_hPen
= (WXHPEN
)::GpiCreatePS( vHabmain
195 ,PU_PELS
| GPIT_MICRO
| GPIA_ASSOC
201 // Set the color table to RGB mode
203 if (!::GpiCreateLogColorTable( (HPS
)M_PENDATA
->m_hPen
211 vError
= ::WinGetLastError(vHabmain
);
212 sError
= wxPMErrorToStr(vError
);
213 wxLogError(_T("Unable to set current color table to RGB mode. Error: %s\n"), sError
.c_str());
216 if (M_PENDATA
->m_nStyle
== wxPENSTYLE_TRANSPARENT
)
221 COLORREF vPmColour
= 0L;
222 USHORT uLineType
= (USHORT
)wx2os2PenStyle(M_PENDATA
->m_nStyle
);
224 vPmColour
= M_PENDATA
->m_vColour
.GetPixel();
228 switch(M_PENDATA
->m_nJoin
)
231 uJoin
= LINEJOIN_BEVEL
;
235 uJoin
= LINEJOIN_MITRE
;
239 uJoin
= LINEJOIN_ROUND
;
245 switch(M_PENDATA
->m_nCap
)
247 case wxCAP_PROJECTING
:
248 uCap
= LINEEND_SQUARE
;
256 uCap
= LINEEND_ROUND
;
259 m_vLineBundle
.lColor
= (LONG
)vPmColour
;
260 m_vLineBundle
.usMixMode
= FM_OVERPAINT
;
261 if (M_PENDATA
->m_nWidth
< 1)
262 M_PENDATA
->m_nWidth
= 1;
263 m_vLineBundle
.fxWidth
= M_PENDATA
->m_nWidth
;
264 m_vLineBundle
.lGeomWidth
= M_PENDATA
->m_nWidth
;
265 m_vLineBundle
.usType
= uLineType
;
266 m_vLineBundle
.usEnd
= uCap
;
267 m_vLineBundle
.usJoin
= uJoin
;
269 bOk
= ::GpiSetAttrs( M_PENDATA
->m_hPen
271 ,LBB_COLOR
| LBB_MIX_MODE
| LBB_WIDTH
| LBB_GEOM_WIDTH
| LBB_TYPE
| LBB_END
| LBB_JOIN
277 vError
= ::WinGetLastError(vHabmain
);
278 sError
= wxPMErrorToStr(vError
);
279 wxLogError(_T("Can't set Gpi attributes for a LINEBUNDLE. Error: %s\n"), sError
.c_str());
283 ULONG flAttrMask
= 0L;
284 ULONG flDefMask
= 0L;
285 switch(M_PENDATA
->m_nStyle
)
287 case wxPENSTYLE_STIPPLE
:
288 ::GpiSetBitmapId( M_PENDATA
->m_hPen
289 ,(USHORT
)M_PENDATA
->m_vStipple
.GetHBITMAP()
290 ,(USHORT
)M_PENDATA
->m_vStipple
.GetId()
292 ::GpiSetPatternSet( M_PENDATA
->m_hPen
293 ,(USHORT
)M_PENDATA
->m_vStipple
.GetId()
295 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SET
| ABB_SYMBOL
;
296 flDefMask
= ABB_REF_POINT
;
299 case wxPENSTYLE_BDIAGONAL_HATCH
:
300 m_vAreaBundle
.usSymbol
= PATSYM_DIAG3
;
301 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
302 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
303 flDefMask
= ABB_SET
| ABB_REF_POINT
;
306 case wxPENSTYLE_CROSSDIAG_HATCH
:
307 m_vAreaBundle
.usSymbol
= PATSYM_DIAGHATCH
;
308 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
309 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
310 flDefMask
= ABB_SET
| ABB_REF_POINT
;
313 case wxPENSTYLE_FDIAGONAL_HATCH
:
314 m_vAreaBundle
.usSymbol
= PATSYM_DIAG1
;
315 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
316 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
317 flDefMask
= ABB_SET
| ABB_REF_POINT
;
320 case wxPENSTYLE_CROSS_HATCH
:
321 m_vAreaBundle
.usSymbol
= PATSYM_HATCH
;
322 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
323 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
324 flDefMask
= ABB_SET
| ABB_REF_POINT
;
327 case wxPENSTYLE_HORIZONTAL_HATCH
:
328 m_vAreaBundle
.usSymbol
= PATSYM_HORIZ
;
329 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
330 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
331 flDefMask
= ABB_SET
| ABB_REF_POINT
;
334 case wxPENSTYLE_VERTICAL_HATCH
:
335 m_vAreaBundle
.usSymbol
= PATSYM_VERT
;
336 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
337 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
338 flDefMask
= ABB_SET
| ABB_REF_POINT
;
342 m_vAreaBundle
.usSymbol
= PATSYM_SOLID
;
343 m_vAreaBundle
.usSet
= LCID_DEFAULT
;
344 flAttrMask
= ABB_COLOR
| ABB_BACK_COLOR
| ABB_MIX_MODE
| ABB_BACK_MIX_MODE
| ABB_SYMBOL
;
345 flDefMask
= ABB_SET
| ABB_REF_POINT
;
349 m_vAreaBundle
.lColor
= vPmColour
;
350 m_vAreaBundle
.lBackColor
= RGB_WHITE
;
351 m_vAreaBundle
.usMixMode
= FM_OVERPAINT
;
352 m_vAreaBundle
.usBackMixMode
= BM_OVERPAINT
;
354 bOk
= ::GpiSetAttrs( M_PENDATA
->m_hPen
362 vError
= ::WinGetLastError(vHabmain
);
363 sError
= wxPMErrorToStr(vError
);
364 wxLogError(_T("Can't set Gpi attributes for an AREABUNDLE. Error: %s\n"), sError
.c_str());
370 } // end of wxPen::RealizeResource
372 WXHANDLE
wxPen::GetResourceHandle() const
377 return (WXHANDLE
)M_PENDATA
->m_hPen
;
378 } // end of wxPen::GetResourceHandle
380 bool wxPen::FreeResource( bool WXUNUSED(bForce
) )
382 if (M_PENDATA
&& (M_PENDATA
->m_hPen
!= 0))
384 M_PENDATA
->m_hPen
= 0;
388 } // end of wxPen::FreeResource
390 bool wxPen::IsFree() const
392 return (M_PENDATA
&& M_PENDATA
->m_hPen
== 0);
395 wxGDIRefData
* wxPen::CreateGDIRefData() const
397 return new wxPenRefData
;
400 wxGDIRefData
* wxPen::CloneGDIRefData(const wxGDIRefData
* data
) const
402 return new wxPenRefData(*wx_static_cast(const wxPenRefData
*, data
));
405 void wxPen::SetColour( const wxColour
& rColour
)
408 M_PENDATA
->m_vColour
= rColour
;
410 } // end of wxPen::SetColour
412 void wxPen::SetColour( unsigned char cRed
, unsigned char cGreen
, unsigned char cBlue
)
415 M_PENDATA
->m_vColour
.Set(cRed
, cGreen
, cBlue
);
417 } // end of wxPen::SetColour
419 void wxPen::SetPS( HPS hPS
)
422 if (M_PENDATA
->m_hPen
)
423 ::GpiDestroyPS(M_PENDATA
->m_hPen
);
424 M_PENDATA
->m_hPen
= hPS
;
426 } // end of WxWinGdi_CPen::SetPS
428 void wxPen::SetWidth(
433 M_PENDATA
->m_nWidth
= nWidth
;
435 } // end of wxPen::SetWidth
437 void wxPen::SetStyle(
442 M_PENDATA
->m_nStyle
= nStyle
;
444 } // end of wxPen::SetStyle
446 void wxPen::SetStipple(
447 const wxBitmap
& rStipple
451 M_PENDATA
->m_vStipple
= rStipple
;
452 M_PENDATA
->m_nStyle
= wxPENSTYLE_STIPPLE
;
454 } // end of wxPen::SetStipple
456 void wxPen::SetDashes( int WXUNUSED(nNbDashes
),
457 const wxDash
* WXUNUSED(pDash
) )
460 // Does nothing under OS/2
462 } // end of wxPen::SetDashes
469 M_PENDATA
->m_nJoin
= nJoin
;
471 } // end of wxPen::SetJoin
478 M_PENDATA
->m_nCap
= nCap
;
480 } // end of wxPen::SetCap
482 wxColour
& wxPen::GetColour() const
484 wxCHECK_MSG( Ok(), wxNullColour
, wxT("invalid pen") );
486 return M_PENDATA
->m_vColour
;
489 int wxPen::GetWidth() const
491 wxCHECK_MSG( Ok(), -1, wxT("invalid pen") );
493 return M_PENDATA
->m_nWidth
;
496 wxPenStyle
wxPen::GetStyle() const
498 wxCHECK_MSG( Ok(), wxPENSTYLE_INVALID
, wxT("invalid pen") );
500 return M_PENDATA
->m_nStyle
;
503 wxPenJoin
wxPen::GetJoin() const
505 wxCHECK_MSG( Ok(), wxJOIN_INVALID
, wxT("invalid pen") );
507 return M_PENDATA
->m_nJoin
;
510 wxPenCap
wxPen::GetCap() const
512 wxCHECK_MSG( Ok(), wxCAP_INVALID
, wxT("invalid pen") );
514 return M_PENDATA
->m_nCap
;
517 int wxPen::GetPS() const
519 wxCHECK_MSG( Ok(), 0, wxT("invalid pen") );
521 return M_PENDATA
->m_hPen
;
524 int wxPen::GetDashes(wxDash
** ptr
) const
526 wxCHECK_MSG( Ok(), -1, wxT("invalid pen") );
528 *ptr
= M_PENDATA
->m_dash
;
529 return M_PENDATA
->m_nbDash
;
532 wxDash
* wxPen::GetDash() const
534 wxCHECK_MSG( Ok(), NULL
, wxT("invalid pen") );
536 return M_PENDATA
->m_dash
;
539 int wxPen::GetDashCount() const
541 wxCHECK_MSG( Ok(), -1, wxT("invalid pen") );
543 return M_PENDATA
->m_nbDash
;
546 wxBitmap
* wxPen::GetStipple() const
548 wxCHECK_MSG( Ok(), NULL
, wxT("invalid pen") );
550 return &(M_PENDATA
->m_vStipple
);
562 nPMStyle
= LINETYPE_DOT
;
565 case wxPENSTYLE_DOT_DASH
:
566 nPMStyle
= LINETYPE_DASHDOT
;
569 case wxPENSTYLE_SHORT_DASH
:
570 nPMStyle
= LINETYPE_SHORTDASH
;
573 case wxPENSTYLE_LONG_DASH
:
574 nPMStyle
= LINETYPE_LONGDASH
;
577 case wxPENSTYLE_TRANSPARENT
:
578 nPMStyle
= LINETYPE_INVISIBLE
;
581 case wxPENSTYLE_USER_DASH
:
582 nPMStyle
= LINETYPE_DASHDOUBLEDOT
; // We must make a choice... This is mine!
585 case wxPENSTYLE_SOLID
:
587 nPMStyle
= LINETYPE_SOLID
;
591 } // end of wx2os2PenStyle