]> git.saurik.com Git - wxWidgets.git/blobdiff - src/cocoa/pen.mm
Fix out of bounds string access in wxMSW wxDirDialog.
[wxWidgets.git] / src / cocoa / pen.mm
index 02fb79cb31926eea512a21ab17e0d87083e642c2..5ff2d91a51f8ec12a44cd0aee77e4a8540fb3420 100644 (file)
@@ -6,13 +6,18 @@
 // Created:     2003/08/02
 // RCS-ID:      $Id$
 // Copyright:   (c) 2003 David Elliott
-// Licence:    wxWindows licence
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#include "wx/setup.h"
-#include "wx/pen.h"
-#include "wx/bitmap.h"
-#include "wx/colour.h"
+#include "wx/wxprec.h"
+
+#ifndef WX_PRECOMP
+    #include "wx/pen.h"
+    #include "wx/bitmap.h"
+    #include "wx/colour.h"
+#endif //WX_PRECOMP
+
+#include "wx/cocoa/ObjcRef.h"
 
 #import <AppKit/NSColor.h>
 
 // ========================================================================
 class WXDLLEXPORT wxPenRefData: public wxGDIRefData
 {
-    friend class WXDLLEXPORT wxPen;
 public:
     wxPenRefData(const wxColour& colour = wxNullColour,
         int width = 1, int style = wxSOLID,
         const wxBitmap& stipple = wxNullBitmap);
     wxPenRefData(const wxPenRefData& data);
-    ~wxPenRefData() { Free(); }
+    ~wxPenRefData() { FreeCocoaNSColor(); FreeCocoaDash(); }
 
     void SetWidth(int Width) { m_width = Width; }
-    void SetStyle(int Style) { m_style = Style; }
+    void SetStyle(int Style)
+    {   FreeCocoaNSColor();
+        FreeCocoaDash();
+        m_style = Style;
+    }
     void SetJoin(int Join) { m_join = Join; }
     void SetCap(int Cap) { m_cap = Cap; }
-    void SetColour(const wxColour& col) { Free(); m_colour = col; }
+    void SetColour(const wxColour& col) { FreeCocoaNSColor(); m_colour = col; }
     void SetDashes(int nb_dashes, const wxDash *Dash)
     {
+        FreeCocoaDash();
         m_nbDash = nb_dashes;
         m_dash = (wxDash *)Dash;
     }
     void SetStipple(const wxBitmap& Stipple)
     {
-        Free();
+        FreeCocoaNSColor();
         m_stipple = Stipple;
         m_style = wxSTIPPLE;
     }
     WX_NSColor GetNSColor();
+    int GetCocoaLineDash(const CGFloat **pattern);
 protected:
-    void Free();
+    void FreeCocoaNSColor();
+    void FreeCocoaDash();
 
     int             m_width;
     int             m_style;
@@ -58,11 +69,45 @@ protected:
     wxDash         *m_dash;
     wxBitmap        m_stipple;
     WX_NSColor      m_cocoaNSColor;
+    CGFloat        *m_cocoaDash;
+
+    // Predefined dash patterns
+    static const int scm_countDot;
+    static const CGFloat scm_patternDot[];
+    static const int scm_countLongDash;
+    static const CGFloat scm_patternLongDash[];
+    static const int scm_countShortDash;
+    static const CGFloat scm_patternShortDash[];
+    static const int scm_countDotDash;
+    static const CGFloat scm_patternDotDash[];
+
+    friend class WXDLLIMPEXP_FWD_CORE wxPen;
+
 private:
     // Don't allow assignment
     wxPenRefData& operator=(const wxPenRefData& data);
 };
 
+const int wxPenRefData::scm_countDot = 1;
+const CGFloat wxPenRefData::scm_patternDot[] = {
+    1.0
+};
+const int wxPenRefData::scm_countLongDash = 1;
+const CGFloat wxPenRefData::scm_patternLongDash[] = {
+    10.0
+};
+const int wxPenRefData::scm_countShortDash = 1;
+const CGFloat wxPenRefData::scm_patternShortDash[] = {
+    5.0
+};
+const int wxPenRefData::scm_countDotDash = 4;
+const CGFloat wxPenRefData::scm_patternDotDash[] = {
+    1.0
+,   1.0
+,   5.0
+,   1.0
+};
+
 #define M_PENDATA ((wxPenRefData *)m_refData)
 
 inline wxPenRefData::wxPenRefData(const wxColour& colour,
@@ -77,6 +122,7 @@ inline wxPenRefData::wxPenRefData(const wxColour& colour,
     m_dash = 0;
     m_stipple = stipple;
     m_cocoaNSColor = nil;
+    m_cocoaDash = NULL;
 }
 
 inline wxPenRefData::wxPenRefData(const wxPenRefData& data)
@@ -89,15 +135,22 @@ inline wxPenRefData::wxPenRefData(const wxPenRefData& data)
     m_nbDash = data.m_nbDash;
     m_dash = data.m_dash;
     m_stipple = data.m_stipple;
-    m_cocoaNSColor = [data.m_cocoaNSColor retain];
+    m_cocoaNSColor = wxGCSafeRetain(data.m_cocoaNSColor);
+    m_cocoaDash = NULL;
 }
 
-inline void wxPenRefData::Free()
+inline void wxPenRefData::FreeCocoaNSColor()
 {
-    [m_cocoaNSColor release];
+    wxGCSafeRelease(m_cocoaNSColor);
     m_cocoaNSColor = nil;
 }
 
+inline void wxPenRefData::FreeCocoaDash()
+{
+    delete m_cocoaDash;
+    m_cocoaDash = NULL;
+}
+
 inline WX_NSColor wxPenRefData::GetNSColor()
 {
     if(!m_cocoaNSColor)
@@ -105,7 +158,7 @@ inline WX_NSColor wxPenRefData::GetNSColor()
         switch( m_style )
         {
         case wxTRANSPARENT:
-            m_cocoaNSColor = [[NSColor clearColor] retain];
+            m_cocoaNSColor = wxGCSafeRetain([NSColor clearColor]);
             break;
         case wxSTIPPLE:
 //  wxBitmap isn't implemented yet
@@ -130,12 +183,68 @@ inline WX_NSColor wxPenRefData::GetNSColor()
             if(!colour_NSColor)
                 colour_NSColor = [NSColor clearColor];
             m_cocoaNSColor = [colour_NSColor copyWithZone:nil];
+            [wxGCSafeRetain(m_cocoaNSColor) release]; // retain in GC. no change in RR.
             break;
         }
     }
     return m_cocoaNSColor;
 }
 
+int wxPenRefData::GetCocoaLineDash(const CGFloat **pattern)
+{
+    int count;
+    switch( m_style )
+    {
+    case wxDOT:
+        count = scm_countDot;
+        if(pattern)
+            *pattern = scm_patternDot;
+        break;
+    case wxLONG_DASH:
+        count = scm_countLongDash;
+        if(pattern)
+            *pattern = scm_patternLongDash;
+        break;
+    case wxSHORT_DASH:
+        count = scm_countShortDash;
+        if(pattern)
+            *pattern = scm_patternShortDash;
+        break;
+    case wxDOT_DASH:
+        count = scm_countDotDash;
+        if(pattern)
+            *pattern = scm_patternDotDash;
+        break;
+    case wxUSER_DASH:
+        count = m_nbDash;
+        if(pattern)
+        {
+            if(!m_cocoaDash)
+            {
+                m_cocoaDash = new CGFloat[count];
+                for(int i=0; i<count; i++)
+                    m_cocoaDash[i] = m_dash[i];
+            }
+            *pattern = m_cocoaDash;
+        }
+        break;
+    case wxTRANSPARENT:
+    case wxSTIPPLE:
+    case wxBDIAGONAL_HATCH:
+    case wxCROSSDIAG_HATCH:
+    case wxFDIAGONAL_HATCH:
+    case wxCROSS_HATCH:
+    case wxHORIZONTAL_HATCH:
+    case wxVERTICAL_HATCH:
+    case wxSOLID:
+    default:
+        count = 0;
+        if(pattern)
+            *pattern = NULL;
+    }
+    return count;
+}
+
 // ========================================================================
 // wxPen
 // ========================================================================
@@ -160,12 +269,12 @@ wxPen::wxPen(const wxBitmap& stipple, int width)
     m_refData = new wxPenRefData(wxNullColour,width,wxSTIPPLE,stipple);
 }
 
-wxObjectRefData *wxPen::CreateRefData() const
+wxGDIRefData *wxPen::CreateGDIRefData() const
 {
     return new wxPenRefData;
 }
 
-wxObjectRefData *wxPen::CloneRefData(const wxObjectRefData *data) const
+wxGDIRefData *wxPen::CloneGDIRefData(const wxGDIRefData *data) const
 {
     return new wxPenRefData(*(wxPenRefData *)data);
 }
@@ -218,29 +327,29 @@ void wxPen::SetStipple(const wxBitmap& Stipple)
     M_PENDATA->SetStipple(Stipple);
 }
 
-wxColour& wxPen::GetColour() const
+wxColour wxPen::GetColour() const
 {
-    return (M_PENDATA ? M_PENDATA->m_colour : wxNullColour); 
+    return (M_PENDATA ? M_PENDATA->m_colour : wxNullColour);
 }
 
 int wxPen::GetWidth() const
 {
-    return (M_PENDATA ? M_PENDATA->m_width : 0); 
+    return (M_PENDATA ? M_PENDATA->m_width : 0);
 }
 
 int wxPen::GetStyle() const
 {
-    return (M_PENDATA ? M_PENDATA->m_style : 0); 
+    return (M_PENDATA ? M_PENDATA->m_style : 0);
 }
 
 int wxPen::GetJoin() const
 {
-    return (M_PENDATA ? M_PENDATA->m_join : 0); 
+    return (M_PENDATA ? M_PENDATA->m_join : 0);
 }
 
 int wxPen::GetCap() const
 {
-    return (M_PENDATA ? M_PENDATA->m_cap : 0); 
+    return (M_PENDATA ? M_PENDATA->m_cap : 0);
 }
 
 int wxPen::GetDashes(wxDash **ptr) const
@@ -250,7 +359,7 @@ int wxPen::GetDashes(wxDash **ptr) const
 
 wxBitmap *wxPen::GetStipple() const
 {
-    return (M_PENDATA ? (& M_PENDATA->m_stipple) : (wxBitmap*) NULL); 
+    return (M_PENDATA ? (& M_PENDATA->m_stipple) : (wxBitmap*) NULL);
 }
 
 WX_NSColor wxPen::GetNSColor()
@@ -258,3 +367,11 @@ WX_NSColor wxPen::GetNSColor()
     return (M_PENDATA ? M_PENDATA->GetNSColor() : nil);
 }
 
+int wxPen::GetCocoaLineDash(const CGFloat **pattern)
+{
+    if(M_PENDATA)
+        return M_PENDATA->GetCocoaLineDash(pattern);
+    if(pattern)
+        *pattern = NULL;
+    return 0;
+}