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 
= 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(*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