X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/debe6624c1e9d4bf3243381153d1e173c849bcd8..b512ed93206f70d502c52df705cad47c3ba2cc7f:/src/msw/pen.cpp diff --git a/src/msw/pen.cpp b/src/msw/pen.cpp index 12197dd801..5daea9b6cd 100644 --- a/src/msw/pen.cpp +++ b/src/msw/pen.cpp @@ -1,454 +1,603 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: pen.cpp +// Name: src/msw/pen.cpp // Purpose: wxPen // Author: Julian Smart -// Modified by: +// Modified by: Vadim Zeitlin: refactored wxPen code to wxPenRefData // Created: 04/01/98 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows license +// Copyright: (c) Julian Smart +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "pen.h" -#endif +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ -#pragma hdrstop + #pragma hdrstop #endif -#ifndef WX_PRECOMP -#include -#include "wx/setup.h" -#include "wx/list.h" -#include "wx/utils.h" -#include "wx/app.h" #include "wx/pen.h" + +#ifndef WX_PRECOMP + #include "wx/bitmap.h" + #include "wx/utils.h" #endif #include "wx/msw/private.h" -#include "assert.h" -#if !USE_SHARED_LIBRARIES -IMPLEMENT_DYNAMIC_CLASS(wxPen, wxGDIObject) +#define M_PENDATA ((wxPenRefData*)m_refData) + +// Win32 has ExtCreatePen() but WinCE doesn't +#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__) + #define wxHAVE_EXT_CREATE_PEN #endif -wxPenRefData::wxPenRefData(void) +// ---------------------------------------------------------------------------- +// wxPenRefData: contains information about an HPEN and its handle +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxPenRefData : public wxGDIRefData { -// m_stipple = NULL ; - m_style = wxSOLID; - m_width = 1; - m_join = wxJOIN_ROUND ; - m_cap = wxCAP_ROUND ; - m_nbDash = 0 ; - m_dash = 0 ; - m_hPen = 0; +public: + // ctors and dtor + // -------------- + + wxPenRefData(); + wxPenRefData(const wxPenRefData& data); + wxPenRefData(const wxColour& col, int width, wxPenStyle style); + wxPenRefData(const wxBitmap& stipple, int width); + virtual ~wxPenRefData(); + + bool operator==(const wxPenRefData& data) const + { + // we intentionally don't compare m_hPen fields here + return m_style == data.m_style && + m_width == data.m_width && + m_join == data.m_join && + m_cap == data.m_cap && + m_colour == data.m_colour && + (m_style != wxPENSTYLE_STIPPLE || m_stipple.IsSameAs(data.m_stipple)) && + (m_style != wxPENSTYLE_USER_DASH || + (m_nbDash == data.m_nbDash && + memcmp(m_dash, data.m_dash, m_nbDash*sizeof(wxDash)) == 0)); + } + + + // accessors and setters + // --------------------- + + wxColour& GetColour() const { return const_cast(m_colour); } + int GetWidth() const { return m_width; } + wxPenStyle GetStyle() const { return m_style; } + wxPenJoin GetJoin() const { return m_join; } + wxPenCap GetCap() const { return m_cap; } + wxDash* GetDash() const { return m_dash; } + int GetDashCount() const { return m_nbDash; } + wxBitmap* GetStipple() const { return const_cast(&m_stipple); } + + void SetColour(const wxColour& col) { Free(); m_colour = col; } + void SetWidth(int width) { Free(); m_width = width; } + void SetStyle(wxPenStyle style) { Free(); m_style = style; } + void SetStipple(const wxBitmap& stipple) + { + Free(); + + m_style = wxPENSTYLE_STIPPLE; + m_stipple = stipple; + } + + void SetDashes(int nb_dashes, const wxDash *dash) + { + Free(); + + m_nbDash = nb_dashes; + m_dash = const_cast(dash); + } + + void SetJoin(wxPenJoin join) { Free(); m_join = join; } + void SetCap(wxPenCap cap) { Free(); m_cap = cap; } + + + // HPEN management + // --------------- + + // create the HPEN if we don't have it yet + bool Alloc(); + + // get the HPEN creating it on demand + WXHPEN GetHPEN() const; + + // return true if we have a valid HPEN + bool HasHPEN() const { return m_hPen != 0; } + + // return true if we had a valid handle before, false otherwise + bool Free(); + +private: + // initialize the fields which have reasonable default values + // + // doesn't initialize m_width and m_style which must be initialize in ctor + void Init() + { + m_join = wxJOIN_ROUND; + m_cap = wxCAP_ROUND; + m_nbDash = 0; + m_dash = NULL; + m_hPen = 0; + } + + int m_width; + wxPenStyle m_style; + wxPenJoin m_join; + wxPenCap m_cap; + wxBitmap m_stipple; + int m_nbDash; + wxDash * m_dash; + wxColour m_colour; + HPEN m_hPen; + + wxDECLARE_NO_ASSIGN_CLASS(wxPenRefData); +}; + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxPenRefData ctors/dtor +// ---------------------------------------------------------------------------- + +wxPenRefData::wxPenRefData() +{ + Init(); + + m_style = wxPENSTYLE_SOLID; + m_width = 1; } -wxPenRefData::~wxPenRefData(void) +wxPenRefData::wxPenRefData(const wxPenRefData& data) + :wxGDIRefData() { - if ( m_hPen ) - ::DeleteObject((HPEN) m_hPen); + m_style = data.m_style; + m_width = data.m_width; + m_join = data.m_join; + m_cap = data.m_cap; + m_nbDash = data.m_nbDash; + m_dash = data.m_dash; + m_colour = data.m_colour; + m_hPen = 0; } -// Pens +wxPenRefData::wxPenRefData(const wxColour& col, int width, wxPenStyle style) +{ + Init(); + + m_style = style; + m_width = width; + + m_colour = col; +} -wxPen::wxPen(void) +wxPenRefData::wxPenRefData(const wxBitmap& stipple, int width) { - if ( wxThePenList ) - wxThePenList->AddPen(this); + Init(); + + m_style = wxPENSTYLE_STIPPLE; + m_width = width; + + m_stipple = stipple; } -wxPen::~wxPen() +wxPenRefData::~wxPenRefData() { - if (wxThePenList) - wxThePenList->RemovePen(this); + if ( m_hPen ) + ::DeleteObject(m_hPen); } -// Should implement Create -wxPen::wxPen(const wxColour& col, int Width, int Style) +// ---------------------------------------------------------------------------- +// wxPenRefData HPEN management +// ---------------------------------------------------------------------------- + +static int ConvertPenStyle(wxPenStyle style) { - m_refData = new wxPenRefData; + switch ( style ) + { + case wxPENSTYLE_SHORT_DASH: + case wxPENSTYLE_LONG_DASH: + return PS_DASH; + + case wxPENSTYLE_TRANSPARENT: + return PS_NULL; + + default: + wxFAIL_MSG( _T("unknown pen style") ); + // fall through + +#ifdef wxHAVE_EXT_CREATE_PEN + case wxPENSTYLE_DOT: + return PS_DOT; + + case wxPENSTYLE_DOT_DASH: + return PS_DASHDOT; + + case wxPENSTYLE_USER_DASH: + return PS_USERSTYLE; + + case wxPENSTYLE_STIPPLE: + case wxPENSTYLE_BDIAGONAL_HATCH: + case wxPENSTYLE_CROSSDIAG_HATCH: + case wxPENSTYLE_FDIAGONAL_HATCH: + case wxPENSTYLE_CROSS_HATCH: + case wxPENSTYLE_HORIZONTAL_HATCH: + case wxPENSTYLE_VERTICAL_HATCH: + case wxPENSTYLE_SOLID: +#endif // wxHAVE_EXT_CREATE_PEN + + return PS_SOLID; + } +} - M_PENDATA->m_colour = col; -// M_PENDATA->m_stipple = NULL; - M_PENDATA->m_width = Width; - M_PENDATA->m_style = Style; - M_PENDATA->m_join = wxJOIN_ROUND ; - M_PENDATA->m_cap = wxCAP_ROUND ; - M_PENDATA->m_nbDash = 0 ; - M_PENDATA->m_dash = 0 ; - M_PENDATA->m_hPen = 0 ; +#ifdef wxHAVE_EXT_CREATE_PEN -#ifndef __WIN32__ - // In Windows, only a pen of width = 1 can be dotted or dashed! - if ((Style == wxDOT) || (Style == wxLONG_DASH) || - (Style == wxSHORT_DASH) || (Style == wxDOT_DASH) || - (Style == wxUSER_DASH)) - M_PENDATA->m_width = 1; -#else -/*** - DWORD vers = GetVersion() ; - WORD high = HIWORD(vers) ; // high bit=0 for NT, 1 for Win32s - // Win32s doesn't support wide dashed pens +static int ConvertJoinStyle(wxPenJoin join) +{ + switch( join ) + { + case wxJOIN_BEVEL: + return PS_JOIN_BEVEL; + + case wxJOIN_MITER: + return PS_JOIN_MITER; - if ((high&0x8000)!=0) -***/ - if (wxGetOsVersion()==wxWIN32S) - { - // In Windows, only a pen of width = 1 can be dotted or dashed! - if ((Style == wxDOT) || (Style == wxLONG_DASH) || - (Style == wxSHORT_DASH) || (Style == wxDOT_DASH) || - (Style == wxUSER_DASH)) - M_PENDATA->m_width = 1; - } -#endif - RealizeResource(); + default: + wxFAIL_MSG( _T("unknown pen join style") ); + // fall through - if ( wxThePenList ) - wxThePenList->AddPen(this); + case wxJOIN_ROUND: + return PS_JOIN_ROUND; + } } -wxPen::wxPen(const wxBitmap& stipple, int Width) +static int ConvertCapStyle(wxPenCap cap) { - m_refData = new wxPenRefData; + switch ( cap ) + { + case wxCAP_PROJECTING: + return PS_ENDCAP_SQUARE; -// M_PENDATA->m_colour = col; - M_PENDATA->m_stipple = stipple; - M_PENDATA->m_width = Width; - M_PENDATA->m_style = wxSTIPPLE; - M_PENDATA->m_join = wxJOIN_ROUND ; - M_PENDATA->m_cap = wxCAP_ROUND ; - M_PENDATA->m_nbDash = 0 ; - M_PENDATA->m_dash = 0 ; - M_PENDATA->m_hPen = 0 ; + case wxCAP_BUTT: + return PS_ENDCAP_FLAT; - RealizeResource(); + default: + wxFAIL_MSG( _T("unknown pen cap style") ); + // fall through - if ( wxThePenList ) - wxThePenList->AddPen(this); + case wxCAP_ROUND: + return PS_ENDCAP_ROUND; + } } -wxPen::wxPen(const wxString& col, int Width, int Style) +#endif // wxHAVE_EXT_CREATE_PEN + +bool wxPenRefData::Alloc() { - m_refData = new wxPenRefData; + if ( m_hPen ) + return false; + + if ( m_style == wxPENSTYLE_TRANSPARENT ) + { + m_hPen = (HPEN)::GetStockObject(NULL_PEN); + return true; + } + + const COLORREF col = m_colour.GetPixel(); + +#ifdef wxHAVE_EXT_CREATE_PEN + // Only NT can display dashed or dotted lines with width > 1 + static const int os = wxGetOsVersion(); + if ( os != wxOS_WINDOWS_NT && + (m_style == wxPENSTYLE_DOT || + m_style == wxPENSTYLE_LONG_DASH || + m_style == wxPENSTYLE_SHORT_DASH || + m_style == wxPENSTYLE_DOT_DASH || + m_style == wxPENSTYLE_USER_DASH) && + m_width > 1 ) + { + m_width = 1; + } + + // check if it's a standard kind of pen which can be created with just + // CreatePen() + if ( m_join == wxJOIN_ROUND && + m_cap == wxCAP_ROUND && + m_style != wxPENSTYLE_USER_DASH && + m_style != wxPENSTYLE_STIPPLE && + (m_width <= 1 || m_style == wxPENSTYLE_SOLID) ) +#endif // !wxHAVE_EXT_CREATE_PEN + { + m_hPen = ::CreatePen(ConvertPenStyle(m_style), m_width, col); + } +#ifdef wxHAVE_EXT_CREATE_PEN + else // need to use ExtCreatePen() + { + DWORD styleMSW = PS_GEOMETRIC | + ConvertPenStyle(m_style) | + ConvertJoinStyle(m_join) | + ConvertCapStyle(m_cap); + + LOGBRUSH lb; + switch( m_style ) + { + case wxPENSTYLE_STIPPLE: + lb.lbStyle = BS_PATTERN; + lb.lbHatch = wxPtrToUInt(m_stipple.GetHBITMAP()); + break; + + case wxPENSTYLE_BDIAGONAL_HATCH: + lb.lbStyle = BS_HATCHED; + lb.lbHatch = HS_BDIAGONAL; + break; + + case wxPENSTYLE_CROSSDIAG_HATCH: + lb.lbStyle = BS_HATCHED; + lb.lbHatch = HS_DIAGCROSS; + break; + + case wxPENSTYLE_FDIAGONAL_HATCH: + lb.lbStyle = BS_HATCHED; + lb.lbHatch = HS_FDIAGONAL; + break; + + case wxPENSTYLE_CROSS_HATCH: + lb.lbStyle = BS_HATCHED; + lb.lbHatch = HS_CROSS; + break; + + case wxPENSTYLE_HORIZONTAL_HATCH: + lb.lbStyle = BS_HATCHED; + lb.lbHatch = HS_HORIZONTAL; + break; + + case wxPENSTYLE_VERTICAL_HATCH: + lb.lbStyle = BS_HATCHED; + lb.lbHatch = HS_VERTICAL; + break; + + default: + lb.lbStyle = BS_SOLID; + // this should be unnecessary (it's unused) but suppresses the + // Purify messages about uninitialized memory read + lb.lbHatch = 0; + break; + } + + lb.lbColor = col; + + DWORD *dash; + if ( m_style == wxPENSTYLE_USER_DASH && m_nbDash && m_dash ) + { + dash = new DWORD[m_nbDash]; + int rw = m_width > 1 ? m_width : 1; + for ( int i = 0; i < m_nbDash; i++ ) + dash[i] = m_dash[i] * rw; + } + else + { + dash = NULL; + } + + m_hPen = ::ExtCreatePen(styleMSW, m_width, &lb, m_nbDash, (LPDWORD)dash); + + delete [] dash; + } +#endif // wxHAVE_EXT_CREATE_PEN + + return m_hPen != 0; +} - M_PENDATA->m_colour = col; -// M_PENDATA->m_stipple = NULL ; - M_PENDATA->m_width = Width; - M_PENDATA->m_style = Style; - M_PENDATA->m_join = wxJOIN_ROUND ; - M_PENDATA->m_cap = wxCAP_ROUND ; - M_PENDATA->m_nbDash = 0 ; - M_PENDATA->m_dash = 0 ; - M_PENDATA->m_hPen = 0 ; +bool wxPenRefData::Free() +{ + if ( !m_hPen ) + return false; - RealizeResource(); + ::DeleteObject(m_hPen); + m_hPen = 0; - if ( wxThePenList ) - wxThePenList->AddPen(this); + return true; } -bool wxPen::RealizeResource(void) +WXHPEN wxPenRefData::GetHPEN() const { - if (M_PENDATA && (M_PENDATA->m_hPen == 0)) - { - if (M_PENDATA->m_style==wxTRANSPARENT) - { - M_PENDATA->m_hPen = (WXHPEN) ::GetStockObject(NULL_PEN); - return TRUE; - } + if ( !m_hPen ) + const_cast(this)->Alloc(); - COLORREF ms_colour = 0 ; - ms_colour = M_PENDATA->m_colour.GetPixel() ; - - // Join style, Cap style, Pen Stippling only on Win32. - // Currently no time to find equivalent on Win3.1, sorry - // [if such equiv exist!!] -#ifdef __WIN32__ - if (M_PENDATA->m_join==wxJOIN_ROUND && - M_PENDATA->m_cap==wxCAP_ROUND && - M_PENDATA->m_style!=wxUSER_DASH && - M_PENDATA->m_style!=wxSTIPPLE && - M_PENDATA->m_width <= 1 - ) - M_PENDATA->m_hPen = (WXHPEN) CreatePen(wx2msPenStyle(M_PENDATA->m_style), M_PENDATA->m_width, ms_colour); - else - { - DWORD ms_style = PS_GEOMETRIC|wx2msPenStyle(M_PENDATA->m_style) ; + return (WXHPEN)m_hPen; +} - LOGBRUSH logb ; +// ---------------------------------------------------------------------------- +// wxPen +// ---------------------------------------------------------------------------- - switch(M_PENDATA->m_join) - { - case wxJOIN_BEVEL: ms_style |= PS_JOIN_BEVEL ; break ; - case wxJOIN_MITER: ms_style |= PS_JOIN_MITER ; break ; - default: - case wxJOIN_ROUND: ms_style |= PS_JOIN_ROUND ; break ; - } +IMPLEMENT_DYNAMIC_CLASS(wxPen, wxGDIObject) - switch(M_PENDATA->m_cap) - { - case wxCAP_PROJECTING: ms_style |= PS_ENDCAP_SQUARE ; break ; - case wxCAP_BUTT: ms_style |= PS_ENDCAP_FLAT ; break ; - default: - case wxCAP_ROUND: ms_style |= PS_ENDCAP_ROUND ; break ; - } - - switch(M_PENDATA->m_style) - { - case wxSTIPPLE: - logb.lbStyle = BS_PATTERN ; - if (M_PENDATA->m_stipple.Ok()) - logb.lbHatch = (LONG)M_PENDATA->m_stipple.GetHBITMAP() ; - else - logb.lbHatch = (LONG)0 ; - break ; - case wxBDIAGONAL_HATCH: - logb.lbStyle = BS_HATCHED ; - logb.lbHatch = HS_BDIAGONAL ; - break ; - case wxCROSSDIAG_HATCH: - logb.lbStyle = BS_HATCHED ; - logb.lbHatch = HS_DIAGCROSS ; - break ; - case wxFDIAGONAL_HATCH: - logb.lbStyle = BS_HATCHED ; - logb.lbHatch = HS_FDIAGONAL ; - break ; - case wxCROSS_HATCH: - logb.lbStyle = BS_HATCHED ; - logb.lbHatch = HS_CROSS ; - break ; - case wxHORIZONTAL_HATCH: - logb.lbStyle = BS_HATCHED ; - logb.lbHatch = HS_HORIZONTAL ; - break ; - case wxVERTICAL_HATCH: - logb.lbStyle = BS_HATCHED ; - logb.lbHatch = HS_VERTICAL ; - break ; - default: - logb.lbStyle = BS_SOLID ; - break ; - } - logb.lbColor = ms_colour ; - wxDash *real_dash ; - if (M_PENDATA->m_style==wxUSER_DASH && M_PENDATA->m_nbDash && M_PENDATA->m_dash) - { - real_dash = new wxDash[M_PENDATA->m_nbDash] ; - int i; - for (i=0;im_nbDash;i++) - real_dash[i] = M_PENDATA->m_dash[i] * M_PENDATA->m_width ; - } - else - real_dash = 0 ; - - // Win32s doesn't have ExtCreatePen function... - if (wxGetOsVersion()==wxWINDOWS_NT || wxGetOsVersion()==wxWIN95) - M_PENDATA->m_hPen = (WXHPEN) ExtCreatePen(ms_style,M_PENDATA->m_width,&logb, - M_PENDATA->m_style==wxUSER_DASH ? M_PENDATA->m_nbDash:0, (const DWORD *)real_dash); - else - M_PENDATA->m_hPen = (WXHPEN) CreatePen(wx2msPenStyle(M_PENDATA->m_style), M_PENDATA->m_width, ms_colour); - - if (real_dash) - delete [] real_dash ; - } -#else - M_PENDATA->m_hPen = (WXHPEN) CreatePen(wx2msPenStyle(M_PENDATA->m_style), M_PENDATA->m_width, ms_colour); -#endif -#ifdef DEBUG_CREATE - if (M_PENDATA->m_hPen==0) - wxError("Cannot create pen","Internal error") ; +wxPen::wxPen(const wxColour& col, int width, wxPenStyle style) +{ + m_refData = new wxPenRefData(col, width, style); +} + +#if FUTURE_WXWIN_COMPATIBILITY_3_0 +wxPen::wxPen(const wxColour& colour, int width, int style) +{ + m_refData = new wxPenRefData(colour, width, (wxPenStyle)style); +} #endif - return TRUE; - } - return FALSE; + +wxPen::wxPen(const wxBitmap& stipple, int width) +{ + m_refData = new wxPenRefData(stipple, width); +} + +bool wxPen::operator==(const wxPen& pen) const +{ + const wxPenRefData * + penData = static_cast(pen.m_refData); + + // an invalid pen is only equal to another invalid pen + return m_refData ? penData && *M_PENDATA == *penData : !penData; } -WXHANDLE wxPen::GetResourceHandle(void) +bool wxPen::RealizeResource() { - if ( !M_PENDATA ) - return 0; - else - return (WXHANDLE)M_PENDATA->m_hPen; + return M_PENDATA && M_PENDATA->Alloc(); } -bool wxPen::FreeResource(bool force) +WXHANDLE wxPen::GetResourceHandle() const { - if (M_PENDATA && (M_PENDATA->m_hPen != 0)) - { - DeleteObject((HPEN) M_PENDATA->m_hPen); - M_PENDATA->m_hPen = 0; - return TRUE; - } - else return FALSE; + return M_PENDATA ? M_PENDATA->GetHPEN() : 0; } -/* -bool wxPen::UseResource(void) +bool wxPen::FreeResource(bool WXUNUSED(force)) { - IncrementResourceUsage(); - return TRUE; + return M_PENDATA && M_PENDATA->Free(); } -bool wxPen::ReleaseResource(void) +bool wxPen::IsFree() const { - DecrementResourceUsage(); - return TRUE; + return M_PENDATA && !M_PENDATA->HasHPEN(); } -*/ -bool wxPen::IsFree(void) +wxGDIRefData* wxPen::CreateGDIRefData() const { - return (M_PENDATA && M_PENDATA->m_hPen == 0); + return new wxPenRefData; +} + +wxGDIRefData* wxPen::CloneGDIRefData(const wxGDIRefData* data) const +{ + return new wxPenRefData(*static_cast(data)); } void wxPen::SetColour(const wxColour& col) { - if ( !M_PENDATA ) - m_refData = new wxPenRefData; + AllocExclusive(); + + M_PENDATA->SetColour(col); +} + +void wxPen::SetColour(unsigned char r, unsigned char g, unsigned char b) +{ + SetColour(wxColour(r, g, b)); +} + +void wxPen::SetWidth(int width) +{ + AllocExclusive(); - M_PENDATA->m_colour = col; - - if (FreeResource()) - RealizeResource(); + M_PENDATA->SetWidth(width); } -void wxPen::SetColour(const wxString& col) +void wxPen::SetStyle(wxPenStyle style) { - if ( !M_PENDATA ) - m_refData = new wxPenRefData; + AllocExclusive(); - M_PENDATA->m_colour = col; - - if (FreeResource()) - RealizeResource(); + M_PENDATA->SetStyle(style); } -void wxPen::SetColour(const unsigned char r, const unsigned char g, const unsigned char b) +void wxPen::SetStipple(const wxBitmap& stipple) { - if ( !M_PENDATA ) - m_refData = new wxPenRefData; + AllocExclusive(); - M_PENDATA->m_colour.Set(r, g, b); - - if (FreeResource()) - RealizeResource(); + M_PENDATA->SetStipple(stipple); } -void wxPen::SetWidth(int Width) +void wxPen::SetDashes(int nb_dashes, const wxDash *dash) { - if ( !M_PENDATA ) - m_refData = new wxPenRefData; + AllocExclusive(); - M_PENDATA->m_width = Width; + M_PENDATA->SetDashes(nb_dashes, dash); +} - if (FreeResource()) - RealizeResource(); +void wxPen::SetJoin(wxPenJoin join) +{ + AllocExclusive(); + + M_PENDATA->SetJoin(join); } -void wxPen::SetStyle(int Style) +void wxPen::SetCap(wxPenCap cap) { - if ( !M_PENDATA ) - m_refData = new wxPenRefData; + AllocExclusive(); + + M_PENDATA->SetCap(cap); +} - M_PENDATA->m_style = Style; +wxColour wxPen::GetColour() const +{ + wxCHECK_MSG( Ok(), wxNullColour, wxT("invalid pen") ); - if (FreeResource()) - RealizeResource(); + return M_PENDATA->GetColour(); } -void wxPen::SetStipple(const wxBitmap& Stipple) +int wxPen::GetWidth() const { - if ( !M_PENDATA ) - m_refData = new wxPenRefData; + wxCHECK_MSG( Ok(), -1, wxT("invalid pen") ); - M_PENDATA->m_stipple = Stipple; - M_PENDATA->m_style = wxSTIPPLE; - - if (FreeResource()) - RealizeResource(); + return M_PENDATA->GetWidth(); } -void wxPen::SetDashes(int nb_dashes, const wxDash *Dash) +wxPenStyle wxPen::GetStyle() const { - if ( !M_PENDATA ) - m_refData = new wxPenRefData; + wxCHECK_MSG( Ok(), wxPENSTYLE_INVALID, wxT("invalid pen") ); - M_PENDATA->m_nbDash = nb_dashes; - M_PENDATA->m_dash = (wxDash *)Dash; - - if (FreeResource()) - RealizeResource(); + return M_PENDATA->GetStyle(); } -void wxPen::SetJoin(int Join) +wxPenJoin wxPen::GetJoin() const { - if ( !M_PENDATA ) - m_refData = new wxPenRefData; + wxCHECK_MSG( Ok(), wxJOIN_INVALID, wxT("invalid pen") ); - M_PENDATA->m_join = Join; + return M_PENDATA->GetJoin(); +} - if (FreeResource()) - RealizeResource(); +wxPenCap wxPen::GetCap() const +{ + wxCHECK_MSG( Ok(), wxCAP_INVALID, wxT("invalid pen") ); + + return M_PENDATA->GetCap(); } -void wxPen::SetCap(int Cap) +int wxPen::GetDashes(wxDash** ptr) const { - if ( !M_PENDATA ) - m_refData = new wxPenRefData; + wxCHECK_MSG( Ok(), -1, wxT("invalid pen") ); + + *ptr = M_PENDATA->GetDash(); + return M_PENDATA->GetDashCount(); +} - M_PENDATA->m_cap = Cap; +wxDash* wxPen::GetDash() const +{ + wxCHECK_MSG( Ok(), NULL, wxT("invalid pen") ); - if (FreeResource()) - RealizeResource(); + return m_refData ? M_PENDATA->GetDash() : NULL; } -int wx2msPenStyle(int wx_style) +int wxPen::GetDashCount() const { - int cstyle; -/*** -#ifdef __WIN32__ - DWORD vers = GetVersion() ; - WORD high = HIWORD(vers) ; // high bit=0 for NT, 1 for Win32s -#endif -***/ - switch (wx_style) - { - case wxDOT: - cstyle = PS_DOT; - break; - case wxSHORT_DASH: - case wxLONG_DASH: - cstyle = PS_DASH; - break; - case wxTRANSPARENT: - cstyle = PS_NULL; - break; - case wxUSER_DASH: - // User dash style not supported on Win3.1, sorry... -#ifdef __WIN32__ - // Win32s doesn't have PS_USERSTYLE -/*** - if ((high&0x8000)==0) -***/ - if (wxGetOsVersion()==wxWINDOWS_NT) - cstyle = PS_USERSTYLE ; - else - cstyle = PS_DOT ; // We must make a choice... This is mine! -#else - cstyle = PS_DASH ; -#endif - break ; - case wxSOLID: - default: - cstyle = PS_SOLID; - break; - } - return cstyle; + wxCHECK_MSG( Ok(), -1, wxT("invalid pen") ); + + return m_refData ? M_PENDATA->GetDashCount() : 0; } +wxBitmap* wxPen::GetStipple() const +{ + wxCHECK_MSG( Ok(), NULL, wxT("invalid pen") ); + + return m_refData ? M_PENDATA->GetStipple() : NULL; +}