1///////////////////////////////////////////////////////////////////////////// 2// Name: src/cocoa/pen.mm 3// Purpose: wxPen 4// Author: David Elliott 5// Modified by: 6// Created: 2003/08/02 7// Copyright: (c) 2003 David Elliott 8// Licence: wxWindows licence 9///////////////////////////////////////////////////////////////////////////// 10 11#include "wx/wxprec.h" 12 13#ifndef WX_PRECOMP 14 #include "wx/pen.h" 15 #include "wx/bitmap.h" 16 #include "wx/colour.h" 17#endif //WX_PRECOMP 18 19#include "wx/cocoa/ObjcRef.h" 20 21#import <AppKit/NSColor.h> 22 23// ======================================================================== 24// wxPenRefData 25// ======================================================================== 26class WXDLLEXPORT wxPenRefData: public wxGDIRefData 27{ 28public: 29 wxPenRefData(const wxColour& colour = wxNullColour, 30 int width = 1, int style = wxSOLID, 31 const wxBitmap& stipple = wxNullBitmap); 32 wxPenRefData(const wxPenRefData& data); 33 ~wxPenRefData() { FreeCocoaNSColor(); FreeCocoaDash(); } 34 35 void SetWidth(int Width) { m_width = Width; } 36 void SetStyle(int Style) 37 { FreeCocoaNSColor(); 38 FreeCocoaDash(); 39 m_style = Style; 40 } 41 void SetJoin(int Join) { m_join = Join; } 42 void SetCap(int Cap) { m_cap = Cap; } 43 void SetColour(const wxColour& col) { FreeCocoaNSColor(); m_colour = col; } 44 void SetDashes(int nb_dashes, const wxDash *Dash) 45 { 46 FreeCocoaDash(); 47 m_nbDash = nb_dashes; 48 m_dash = (wxDash *)Dash; 49 } 50 void SetStipple(const wxBitmap& Stipple) 51 { 52 FreeCocoaNSColor(); 53 m_stipple = Stipple; 54 m_style = wxSTIPPLE; 55 } 56 WX_NSColor GetNSColor(); 57 int GetCocoaLineDash(const CGFloat **pattern); 58protected: 59 void FreeCocoaNSColor(); 60 void FreeCocoaDash(); 61 62 int m_width; 63 int m_style; 64 int m_join; 65 int m_cap; 66 wxColour m_colour; 67 int m_nbDash; 68 wxDash *m_dash; 69 wxBitmap m_stipple; 70 WX_NSColor m_cocoaNSColor; 71 CGFloat *m_cocoaDash; 72 73 // Predefined dash patterns 74 static const int scm_countDot; 75 static const CGFloat scm_patternDot[]; 76 static const int scm_countLongDash; 77 static const CGFloat scm_patternLongDash[]; 78 static const int scm_countShortDash; 79 static const CGFloat scm_patternShortDash[]; 80 static const int scm_countDotDash; 81 static const CGFloat scm_patternDotDash[]; 82 83 friend class WXDLLIMPEXP_FWD_CORE wxPen; 84 85private: 86 // Don't allow assignment 87 wxPenRefData& operator=(const wxPenRefData& data); 88}; 89 90const int wxPenRefData::scm_countDot = 1; 91const CGFloat wxPenRefData::scm_patternDot[] = { 92 1.0 93}; 94const int wxPenRefData::scm_countLongDash = 1; 95const CGFloat wxPenRefData::scm_patternLongDash[] = { 96 10.0 97}; 98const int wxPenRefData::scm_countShortDash = 1; 99const CGFloat wxPenRefData::scm_patternShortDash[] = { 100 5.0 101}; 102const int wxPenRefData::scm_countDotDash = 4; 103const CGFloat wxPenRefData::scm_patternDotDash[] = { 104 1.0 105, 1.0 106, 5.0 107, 1.0 108}; 109 110#define M_PENDATA ((wxPenRefData *)m_refData) 111 112inline wxPenRefData::wxPenRefData(const wxColour& colour, 113 int width, int style, const wxBitmap& stipple) 114{ 115 m_width = width; 116 m_style = style; 117 m_join = wxJOIN_ROUND; 118 m_cap = wxCAP_ROUND; 119 m_colour = colour; 120 m_nbDash = 0; 121 m_dash = 0; 122 m_stipple = stipple; 123 m_cocoaNSColor = nil; 124 m_cocoaDash = NULL; 125} 126 127inline wxPenRefData::wxPenRefData(const wxPenRefData& data) 128{ 129 m_width = data.m_width; 130 m_style = data.m_style; 131 m_join = data.m_join; 132 m_cap = data.m_cap; 133 m_colour = data.m_colour; 134 m_nbDash = data.m_nbDash; 135 m_dash = data.m_dash; 136 m_stipple = data.m_stipple; 137 m_cocoaNSColor = wxGCSafeRetain(data.m_cocoaNSColor); 138 m_cocoaDash = NULL; 139} 140 141inline void wxPenRefData::FreeCocoaNSColor() 142{ 143 wxGCSafeRelease(m_cocoaNSColor); 144 m_cocoaNSColor = nil; 145} 146 147inline void wxPenRefData::FreeCocoaDash() 148{ 149 delete m_cocoaDash; 150 m_cocoaDash = NULL; 151} 152 153inline WX_NSColor wxPenRefData::GetNSColor() 154{ 155 if(!m_cocoaNSColor) 156 { 157 switch( m_style ) 158 { 159 case wxTRANSPARENT: 160 m_cocoaNSColor = wxGCSafeRetain([NSColor clearColor]); 161 break; 162 case wxSTIPPLE: 163// wxBitmap isn't implemented yet 164// m_cocoaNSColor = [[NSColor colorWithPatternImage: m_stipple.GetNSImage()] retain]; 165// break; 166 // The hatch brushes are going to be tricky 167 case wxBDIAGONAL_HATCH: 168 case wxCROSSDIAG_HATCH: 169 case wxFDIAGONAL_HATCH: 170 case wxCROSS_HATCH: 171 case wxHORIZONTAL_HATCH: 172 case wxVERTICAL_HATCH: 173 default: 174 // Dot/dashed pens use solid colors 175 case wxDOT: 176 case wxLONG_DASH: 177 case wxSHORT_DASH: 178 case wxDOT_DASH: 179 case wxUSER_DASH: 180 case wxSOLID: 181 NSColor *colour_NSColor = m_colour.GetNSColor(); 182 if(!colour_NSColor) 183 colour_NSColor = [NSColor clearColor]; 184 m_cocoaNSColor = [colour_NSColor copyWithZone:nil]; 185 [wxGCSafeRetain(m_cocoaNSColor) release]; // retain in GC. no change in RR. 186 break; 187 } 188 } 189 return m_cocoaNSColor; 190} 191 192int wxPenRefData::GetCocoaLineDash(const CGFloat **pattern) 193{ 194 int count; 195 switch( m_style ) 196 { 197 case wxDOT: 198 count = scm_countDot; 199 if(pattern) 200 *pattern = scm_patternDot; 201 break; 202 case wxLONG_DASH: 203 count = scm_countLongDash; 204 if(pattern) 205 *pattern = scm_patternLongDash; 206 break; 207 case wxSHORT_DASH: 208 count = scm_countShortDash; 209 if(pattern) 210 *pattern = scm_patternShortDash; 211 break; 212 case wxDOT_DASH: 213 count = scm_countDotDash; 214 if(pattern) 215 *pattern = scm_patternDotDash; 216 break; 217 case wxUSER_DASH: 218 count = m_nbDash; 219 if(pattern) 220 { 221 if(!m_cocoaDash) 222 { 223 m_cocoaDash = new CGFloat[count]; 224 for(int i=0; i<count; i++) 225 m_cocoaDash[i] = m_dash[i]; 226 } 227 *pattern = m_cocoaDash; 228 } 229 break; 230 case wxTRANSPARENT: 231 case wxSTIPPLE: 232 case wxBDIAGONAL_HATCH: 233 case wxCROSSDIAG_HATCH: 234 case wxFDIAGONAL_HATCH: 235 case wxCROSS_HATCH: 236 case wxHORIZONTAL_HATCH: 237 case wxVERTICAL_HATCH: 238 case wxSOLID: 239 default: 240 count = 0; 241 if(pattern) 242 *pattern = NULL; 243 } 244 return count; 245} 246 247// ======================================================================== 248// wxPen 249// ======================================================================== 250IMPLEMENT_DYNAMIC_CLASS(wxPen, wxGDIObject) 251 252wxPen::wxPen() 253{ 254} 255 256wxPen::~wxPen() 257{ 258} 259 260// Should implement Create 261wxPen::wxPen(const wxColour& colour, int width, int style) 262{ 263 m_refData = new wxPenRefData(colour,width,style); 264} 265 266wxPen::wxPen(const wxBitmap& stipple, int width) 267{ 268 m_refData = new wxPenRefData(wxNullColour,width,wxSTIPPLE,stipple); 269} 270 271wxGDIRefData *wxPen::CreateGDIRefData() const 272{ 273 return new wxPenRefData; 274} 275 276wxGDIRefData *wxPen::CloneGDIRefData(const wxGDIRefData *data) const 277{ 278 return new wxPenRefData(*(wxPenRefData *)data); 279} 280 281void wxPen::SetWidth(int Width) 282{ 283 AllocExclusive(); 284 M_PENDATA->SetWidth(Width); 285} 286 287void wxPen::SetStyle(int Style) 288{ 289 AllocExclusive(); 290 M_PENDATA->SetStyle(Style); 291} 292 293void wxPen::SetJoin(int Join) 294{ 295 AllocExclusive(); 296 M_PENDATA->SetJoin(Join); 297} 298 299void wxPen::SetCap(int Cap) 300{ 301 AllocExclusive(); 302 M_PENDATA->SetCap(Cap); 303} 304 305void wxPen::SetColour(const wxColour& col) 306{ 307 AllocExclusive(); 308 M_PENDATA->SetColour(col); 309} 310 311void wxPen::SetColour(unsigned char r, unsigned char g, unsigned char b) 312{ 313 AllocExclusive(); 314 M_PENDATA->SetColour(wxColour(r, g, b)); 315} 316 317void wxPen::SetDashes(int nb_dashes, const wxDash *Dash) 318{ 319 AllocExclusive(); 320 M_PENDATA->SetDashes(nb_dashes, Dash); 321} 322 323void wxPen::SetStipple(const wxBitmap& Stipple) 324{ 325 AllocExclusive(); 326 M_PENDATA->SetStipple(Stipple); 327} 328 329wxColour wxPen::GetColour() const 330{ 331 return (M_PENDATA ? M_PENDATA->m_colour : wxNullColour); 332} 333 334int wxPen::GetWidth() const 335{ 336 return (M_PENDATA ? M_PENDATA->m_width : 0); 337} 338 339int wxPen::GetStyle() const 340{ 341 return (M_PENDATA ? M_PENDATA->m_style : 0); 342} 343 344int wxPen::GetJoin() const 345{ 346 return (M_PENDATA ? M_PENDATA->m_join : 0); 347} 348 349int wxPen::GetCap() const 350{ 351 return (M_PENDATA ? M_PENDATA->m_cap : 0); 352} 353 354int wxPen::GetDashes(wxDash **ptr) const 355{ 356 *ptr = (M_PENDATA ? M_PENDATA->m_dash : (wxDash*) NULL); return (M_PENDATA ? M_PENDATA->m_nbDash : 0); 357} 358 359wxBitmap *wxPen::GetStipple() const 360{ 361 return (M_PENDATA ? (& M_PENDATA->m_stipple) : (wxBitmap*) NULL); 362} 363 364WX_NSColor wxPen::GetNSColor() 365{ 366 return (M_PENDATA ? M_PENDATA->GetNSColor() : nil); 367} 368 369int wxPen::GetCocoaLineDash(const CGFloat **pattern) 370{ 371 if(M_PENDATA) 372 return M_PENDATA->GetCocoaLineDash(pattern); 373 if(pattern) 374 *pattern = NULL; 375 return 0; 376} 377