]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/font.cpp
patch 1306473
[wxWidgets.git] / src / mac / carbon / font.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: font.cpp
3 // Purpose: wxFont class
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #include "wx/string.h"
15 #include "wx/font.h"
16 #include "wx/fontutil.h"
17 #include "wx/gdicmn.h"
18 #include "wx/utils.h"
19
20 #include "wx/fontutil.h"
21
22 #include "wx/mac/private.h"
23 #ifndef __DARWIN__
24 #include <ATSUnicode.h>
25 #endif
26
27 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
28
29 class WXDLLEXPORT wxFontRefData: public wxGDIRefData
30 {
31 friend class WXDLLEXPORT wxFont;
32 public:
33 wxFontRefData()
34 : m_fontId(0)
35 , m_pointSize(10)
36 , m_family(wxDEFAULT)
37 , m_style(wxNORMAL)
38 , m_weight(wxNORMAL)
39 , m_underlined(FALSE)
40 , m_faceName(wxT("applicationfont"))
41 , m_encoding(wxFONTENCODING_DEFAULT)
42 , m_macFontNum(0)
43 , m_macFontSize(0)
44 , m_macFontStyle(0)
45 , m_macATSUStyle(0)
46 , m_macATSUFontID(0)
47 {
48 Init(m_pointSize, m_family, m_style, m_weight,
49 m_underlined, m_faceName, m_encoding);
50 }
51
52 wxFontRefData(const wxFontRefData& data)
53 : wxGDIRefData()
54 , m_fontId(data.m_fontId)
55 , m_pointSize(data.m_pointSize)
56 , m_family(data.m_family)
57 , m_style(data.m_style)
58 , m_weight(data.m_weight)
59 , m_underlined(data.m_underlined)
60 , m_faceName(data.m_faceName)
61 , m_encoding(data.m_encoding)
62 , m_macFontNum(data.m_macFontNum)
63 , m_macFontSize(data.m_macFontSize)
64 , m_macFontStyle(data.m_macFontStyle)
65 , m_macATSUStyle(0)
66 , m_macATSUFontID(data.m_macATSUFontID)
67 {
68 Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
69 data.m_underlined, data.m_faceName, data.m_encoding);
70 }
71
72 wxFontRefData(int size,
73 int family,
74 int style,
75 int weight,
76 bool underlined,
77 const wxString& faceName,
78 wxFontEncoding encoding)
79 : m_fontId(0)
80 , m_pointSize(size)
81 , m_family(family)
82 , m_style(style)
83 , m_weight(weight)
84 , m_underlined(underlined)
85 , m_faceName(faceName)
86 , m_encoding(encoding)
87 , m_macFontNum(0)
88 , m_macFontSize(0)
89 , m_macFontStyle(0)
90 , m_macATSUStyle(0)
91 , m_macATSUFontID(0)
92 {
93 Init(size, family, style, weight, underlined, faceName, encoding);
94 }
95
96 virtual ~wxFontRefData();
97 void SetNoAntiAliasing( bool no = TRUE ) { m_noAA = no; }
98 bool GetNoAntiAliasing() const { return m_noAA; }
99
100 protected:
101 // common part of all ctors
102 void Init(int size,
103 int family,
104 int style,
105 int weight,
106 bool underlined,
107 const wxString& faceName,
108 wxFontEncoding encoding);
109
110 // font characterstics
111 int m_fontId;
112 int m_pointSize;
113 int m_family;
114 int m_style;
115 int m_weight;
116 bool m_underlined;
117 wxString m_faceName;
118 wxFontEncoding m_encoding;
119 bool m_noAA; // No anti-aliasing
120
121 public:
122 short m_macFontNum;
123 short m_macFontSize;
124 Style m_macFontStyle;
125
126 // ATSU Font Information
127
128 // this is split into an ATSU font id that may
129 // contain some styles (special bold fonts etc) and
130 // these are the additional qd styles that are not
131 // included in the ATSU font id
132 ATSUStyle m_macATSUStyle ;
133 ATSUFontID m_macATSUFontID;
134 Style m_macATSUAdditionalQDStyles ;
135
136 // for true themeing support we must store the correct font
137 // information here, as this speeds up and optimizes rendering
138 ThemeFontID m_macThemeFontID ;
139
140 wxNativeFontInfo m_info;
141
142 public:
143 void MacFindFont() ;
144 };
145 // ============================================================================
146 // implementation
147 // ============================================================================
148
149 // ----------------------------------------------------------------------------
150 // wxFontRefData
151 // ----------------------------------------------------------------------------
152
153 void wxFontRefData::Init(int pointSize,
154 int family,
155 int style,
156 int weight,
157 bool underlined,
158 const wxString& faceName,
159 wxFontEncoding encoding)
160 {
161 m_style = style;
162 m_pointSize = pointSize;
163 m_family = family;
164 m_style = style;
165 m_weight = weight;
166 m_underlined = underlined;
167 m_faceName = faceName;
168 m_encoding = encoding;
169
170 m_macFontNum = 0 ;
171 m_macFontSize = 0;
172 m_macFontStyle = 0;
173 m_macATSUFontID = 0;
174 m_macATSUAdditionalQDStyles = 0 ;
175 m_macATSUStyle = NULL ;
176
177 m_macThemeFontID = kThemeCurrentPortFont ;
178 m_noAA = FALSE;
179 }
180
181 wxFontRefData::~wxFontRefData()
182 {
183 if ( m_macATSUStyle )
184 {
185 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
186 m_macATSUStyle = NULL ;
187 }
188 }
189
190 void wxFontRefData::MacFindFont()
191 {
192 if ( m_macThemeFontID != kThemeCurrentPortFont )
193 {
194 Str255 fontName ;
195 GetThemeFont(m_macThemeFontID , GetApplicationScript() , fontName , &m_macFontSize , &m_macFontStyle ) ;
196 m_faceName = wxMacMakeStringFromPascal( fontName ) ;
197 if ( m_macFontStyle & bold )
198 m_weight = wxBOLD ;
199 else
200 m_weight = wxNORMAL ;
201 if ( m_macFontStyle & italic )
202 m_style = wxITALIC ;
203 if ( m_macFontStyle & underline )
204 m_underlined = true ;
205 ::GetFNum( fontName, &m_macFontNum);
206 m_pointSize = m_macFontSize ;
207 }
208 else
209 {
210 if( m_faceName.Length() == 0 )
211 {
212 switch( m_family )
213 {
214 case wxDEFAULT :
215 m_macFontNum = ::GetAppFont() ;
216 break ;
217 case wxSCRIPT :
218 case wxROMAN :
219 case wxDECORATIVE :
220 #ifdef __WXMAC_OSX__
221 ::GetFNum( "\pTimes" , &m_macFontNum) ;
222 #else
223 ::GetFNum( "\pTimes" , &m_macFontNum) ;
224 #endif
225 break ;
226 case wxSWISS :
227 #ifdef __WXMAC_OSX__
228 ::GetFNum( "\pLucida Grande" , &m_macFontNum) ;
229 #else
230 ::GetFNum( "\pGeneva" , &m_macFontNum) ;
231 #endif
232 break ;
233 case wxMODERN :
234 #ifdef __WXMAC_OSX__
235 ::GetFNum( "\pMonaco" , &m_macFontNum) ;
236 #else
237 ::GetFNum( "\pMonaco" , &m_macFontNum) ;
238 #endif
239 break ;
240 }
241 Str255 name ;
242 ::GetFontName( m_macFontNum , name ) ;
243 m_faceName = wxMacMakeStringFromPascal( name ) ;
244 }
245 else
246 {
247 if ( m_faceName == wxT("systemfont") )
248 m_macFontNum = ::GetSysFont() ;
249 else if ( m_faceName == wxT("applicationfont") )
250 m_macFontNum = ::GetAppFont() ;
251 else
252 {
253 Str255 fontname ;
254 wxMacStringToPascal( m_faceName , fontname ) ;
255 ::GetFNum( fontname, &m_macFontNum);
256 }
257 }
258
259 m_macFontStyle = 0;
260 if (m_weight == wxBOLD)
261 m_macFontStyle |= bold;
262 if (m_style == wxITALIC || m_style == wxSLANT)
263 m_macFontStyle |= italic;
264 if (m_underlined)
265 m_macFontStyle |= underline;
266 m_macFontSize = m_pointSize ;
267 }
268
269 // we try to get as much styles as possible into ATSU
270
271 Fixed atsuSize = IntToFixed( m_macFontSize ) ;
272
273 Style atsuStyle = normal ;
274 verify_noerr(::ATSUFONDtoFontID(m_macFontNum, atsuStyle , (UInt32*)&m_macATSUFontID) );
275 if ( m_macFontStyle & bold )
276 {
277 ATSUFontID test ;
278 if ( ::ATSUFONDtoFontID(m_macFontNum, atsuStyle | bold , &test) == noErr )
279 {
280 atsuStyle |= bold ;
281 m_macATSUFontID = test ;
282 }
283 }
284 if ( m_macFontStyle & italic )
285 {
286 ATSUFontID test ;
287 if ( ::ATSUFONDtoFontID(m_macFontNum, atsuStyle | italic , &test) == noErr )
288 {
289 atsuStyle |= italic ;
290 m_macATSUFontID = test ;
291 }
292 }
293 if ( m_macFontStyle & underline )
294 {
295 ATSUFontID test ;
296 if ( ::ATSUFONDtoFontID(m_macFontNum, atsuStyle | underline , &test) == noErr )
297 {
298 atsuStyle |= underline ;
299 m_macATSUFontID = test ;
300 }
301 }
302
303 m_macATSUAdditionalQDStyles = m_macFontStyle & (~atsuStyle ) ;
304
305 if ( m_macATSUStyle )
306 {
307 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
308 m_macATSUStyle = NULL ;
309 }
310 OSStatus status = ::ATSUCreateStyle((ATSUStyle *)&m_macATSUStyle) ;
311 wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") ) ;
312 ATSUAttributeTag atsuTags[] =
313 {
314 kATSUFontTag ,
315 kATSUSizeTag ,
316 kATSUVerticalCharacterTag,
317 kATSUQDBoldfaceTag ,
318 kATSUQDItalicTag ,
319 kATSUQDUnderlineTag ,
320 kATSUQDCondensedTag ,
321 kATSUQDExtendedTag ,
322 } ;
323 ByteCount atsuSizes[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
324 {
325 sizeof( ATSUFontID ) ,
326 sizeof( Fixed ) ,
327 sizeof( ATSUVerticalCharacterType),
328 sizeof( Boolean ) ,
329 sizeof( Boolean ) ,
330 sizeof( Boolean ) ,
331 sizeof( Boolean ) ,
332 sizeof( Boolean ) ,
333 } ;
334 Boolean kTrue = true ;
335 Boolean kFalse = false ;
336
337 ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
338 ATSUAttributeValuePtr atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
339 {
340 &m_macATSUFontID ,
341 &atsuSize ,
342 &kHorizontal,
343 (m_macATSUAdditionalQDStyles & bold) ? &kTrue : &kFalse ,
344 (m_macATSUAdditionalQDStyles & italic) ? &kTrue : &kFalse ,
345 (m_macATSUAdditionalQDStyles & underline) ? &kTrue : &kFalse ,
346 (m_macATSUAdditionalQDStyles & condense) ? &kTrue : &kFalse ,
347 (m_macATSUAdditionalQDStyles & extend) ? &kTrue : &kFalse ,
348 } ;
349 status = ::ATSUSetAttributes((ATSUStyle)m_macATSUStyle, sizeof(atsuTags)/sizeof(ATSUAttributeTag) ,
350 atsuTags, atsuSizes, atsuValues);
351
352 wxASSERT_MSG( status == noErr , wxT("couldn't Modify ATSU style") ) ;
353 }
354
355 // ----------------------------------------------------------------------------
356 // wxFont
357 // ----------------------------------------------------------------------------
358
359 void wxFont::Init()
360 {
361 }
362
363 bool wxFont::Create(const wxNativeFontInfo& info)
364 {
365 return Create(info.pointSize, info.family, info.style, info.weight,
366 info.underlined, info.faceName, info.encoding);
367 }
368
369 wxFont::wxFont(const wxString& fontdesc)
370 {
371 wxNativeFontInfo info;
372 if ( info.FromString(fontdesc) )
373 (void)Create(info);
374 }
375
376 bool wxFont::Create(int pointSize,
377 int family,
378 int style,
379 int weight,
380 bool underlined,
381 const wxString& faceName,
382 wxFontEncoding encoding)
383 {
384 UnRef();
385 m_refData = new wxFontRefData(pointSize, family, style, weight,
386 underlined, faceName, encoding);
387
388 RealizeResource();
389
390 return TRUE;
391 }
392
393 bool wxFont::MacCreateThemeFont(wxUint16 themeFontID )
394 {
395 UnRef();
396 m_refData = new wxFontRefData(12, wxDEFAULT , wxFONTSTYLE_NORMAL , wxFONTWEIGHT_NORMAL ,false, wxEmptyString, wxFONTENCODING_DEFAULT);
397 M_FONTDATA->m_macThemeFontID = themeFontID ;
398 RealizeResource();
399
400 return TRUE;
401 }
402
403 wxFont::~wxFont()
404 {
405 }
406
407 bool wxFont::RealizeResource()
408 {
409 M_FONTDATA->MacFindFont() ;
410 return TRUE;
411 }
412
413 void wxFont::SetEncoding(wxFontEncoding encoding)
414 {
415 Unshare();
416
417 M_FONTDATA->m_encoding = encoding;
418
419 RealizeResource();
420 }
421
422 void wxFont::Unshare()
423 {
424 // Don't change shared data
425 if (!m_refData)
426 {
427 m_refData = new wxFontRefData();
428 }
429 else
430 {
431 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
432 UnRef();
433 m_refData = ref;
434 }
435 }
436
437 void wxFont::SetPointSize(int pointSize)
438 {
439 Unshare();
440
441 M_FONTDATA->m_pointSize = pointSize;
442
443 RealizeResource();
444 }
445
446 void wxFont::SetFamily(int family)
447 {
448 Unshare();
449
450 M_FONTDATA->m_family = family;
451
452 RealizeResource();
453 }
454
455 void wxFont::SetStyle(int style)
456 {
457 Unshare();
458
459 M_FONTDATA->m_style = style;
460
461 RealizeResource();
462 }
463
464 void wxFont::SetWeight(int weight)
465 {
466 Unshare();
467
468 M_FONTDATA->m_weight = weight;
469
470 RealizeResource();
471 }
472
473 void wxFont::SetFaceName(const wxString& faceName)
474 {
475 Unshare();
476
477 M_FONTDATA->m_faceName = faceName;
478
479 RealizeResource();
480 }
481
482 void wxFont::SetUnderlined(bool underlined)
483 {
484 Unshare();
485
486 M_FONTDATA->m_underlined = underlined;
487
488 RealizeResource();
489 }
490
491 void wxFont::SetNoAntiAliasing( bool no )
492 {
493 Unshare();
494
495 M_FONTDATA->SetNoAntiAliasing( no );
496
497 RealizeResource();
498 }
499
500 // ----------------------------------------------------------------------------
501 // accessors
502 // ----------------------------------------------------------------------------
503
504 // TODO: insert checks everywhere for M_FONTDATA == NULL!
505
506 int wxFont::GetPointSize() const
507 {
508 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
509 return M_FONTDATA->m_pointSize;
510 }
511
512 int wxFont::GetFamily() const
513 {
514 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
515 return M_FONTDATA->m_family;
516 }
517
518 int wxFont::GetStyle() const
519 {
520 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
521 return M_FONTDATA->m_style;
522 }
523
524 int wxFont::GetWeight() const
525 {
526 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
527 return M_FONTDATA->m_weight;
528 }
529
530 bool wxFont::GetUnderlined() const
531 {
532 wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
533 return M_FONTDATA->m_underlined;
534 }
535
536 wxString wxFont::GetFaceName() const
537 {
538 wxCHECK_MSG( M_FONTDATA != NULL , wxEmptyString , wxT("invalid font") );
539 return M_FONTDATA->m_faceName;
540 }
541
542 wxFontEncoding wxFont::GetEncoding() const
543 {
544 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTENCODING_DEFAULT , wxT("invalid font") );
545 return M_FONTDATA->m_encoding;
546 }
547
548 bool wxFont::GetNoAntiAliasing() const
549 {
550 wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
551 return M_FONTDATA->m_noAA;
552 }
553
554 short wxFont::MacGetFontNum() const
555 {
556 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
557 return M_FONTDATA->m_macFontNum;
558 }
559
560 short wxFont::MacGetFontSize() const
561 {
562 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
563 return M_FONTDATA->m_macFontSize;
564 }
565
566 wxByte wxFont::MacGetFontStyle() const
567 {
568 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
569 return M_FONTDATA->m_macFontStyle;
570 }
571
572 wxUint32 wxFont::MacGetATSUFontID() const
573 {
574 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
575 return M_FONTDATA->m_macATSUFontID;
576 }
577
578 void* wxFont::MacGetATSUStyle() const
579 {
580 wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
581 return M_FONTDATA->m_macATSUStyle;
582 }
583
584 wxUint32 wxFont::MacGetATSUAdditionalQDStyles() const
585 {
586 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
587 return M_FONTDATA->m_macATSUAdditionalQDStyles;
588 }
589
590 wxUint16 wxFont::MacGetThemeFontID() const
591 {
592 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
593 return M_FONTDATA->m_macThemeFontID;
594 }
595
596
597 const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
598 {
599 wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
600 wxCHECK_MSG( Ok(), NULL, wxT("invalid font") );
601
602 M_FONTDATA->m_info.InitFromFont(*this);
603
604 return &(M_FONTDATA->m_info);
605 }
606