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