]> git.saurik.com Git - wxWidgets.git/blob - src/osx/carbon/font.cpp
c3426f807bb1e0ee6d57f77e1333fa32fcfd90a7
[wxWidgets.git] / src / osx / carbon / font.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/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/font.h"
15
16 #ifndef WX_PRECOMP
17 #include "wx/string.h"
18 #include "wx/utils.h"
19 #include "wx/intl.h"
20 #include "wx/gdicmn.h"
21 #include "wx/log.h"
22 #endif
23
24 #include "wx/fontutil.h"
25 #include "wx/graphics.h"
26 #include "wx/settings.h"
27 #include "wx/tokenzr.h"
28
29 #include "wx/osx/private.h"
30
31 #if wxOSX_USE_ATSU_TEXT && !wxOSX_USE_CARBON
32 // include themeing support
33 #include <Carbon/Carbon.h>
34 #endif
35
36 #include <map>
37 #include <string>
38
39 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
40
41 class WXDLLEXPORT wxFontRefData: public wxGDIRefData
42 {
43 public:
44
45 wxFontRefData()
46 {
47 Init();
48 m_info.Init(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
49 false, wxEmptyString, wxFONTENCODING_DEFAULT);
50 }
51
52 wxFontRefData(const wxFontRefData& data);
53
54 wxFontRefData( const wxNativeFontInfo& info ) : m_info(info)
55 {
56 Init();
57 }
58
59 wxFontRefData(wxOSXSystemFont font, int size);
60
61 #if wxOSX_USE_CORE_TEXT
62 wxFontRefData( wxUint32 coreTextFontType );
63 wxFontRefData( CTFontRef font );
64 wxFontRefData( CTFontDescriptorRef fontdescriptor, int size );
65 #endif
66
67 virtual ~wxFontRefData();
68
69 void SetNoAntiAliasing( bool no = true ) { m_noAA = no; }
70
71 bool GetNoAntiAliasing() const { return m_noAA; }
72
73 void SetPointSize( int size )
74 {
75 if( GetPointSize() != size )
76 {
77 m_info.SetPointSize(size);
78 Free();
79 }
80 }
81
82 int GetPointSize() const { return m_info.GetPointSize(); }
83
84 void SetFamily( wxFontFamily family )
85 {
86 if ( m_info.m_family != family )
87 {
88 m_info.SetFamily( family );
89 Free();
90 }
91 }
92
93 wxFontFamily GetFamily() const { return m_info.GetFamily(); }
94
95 void SetStyle( wxFontStyle style )
96 {
97 if ( m_info.m_style != style )
98 {
99 m_info.SetStyle( style );
100 Free();
101 }
102 }
103
104
105 wxFontStyle GetStyle() const { return m_info.GetStyle(); }
106
107 void SetWeight( wxFontWeight weight )
108 {
109 if ( m_info.m_weight != weight )
110 {
111 m_info.SetWeight( weight );
112 Free();
113 }
114 }
115
116
117 wxFontWeight GetWeight() const { return m_info.GetWeight(); }
118
119 void SetUnderlined( bool u )
120 {
121 if ( m_info.m_underlined != u )
122 {
123 m_info.SetUnderlined( u );
124 Free();
125 }
126 }
127
128 bool GetUnderlined() const { return m_info.GetUnderlined(); }
129
130 void SetFaceName( const wxString& facename )
131 {
132 if ( m_info.m_faceName != facename )
133 {
134 m_info.SetFaceName( facename );
135 Free();
136 }
137 }
138
139 wxString GetFaceName() const { return m_info.GetFaceName(); }
140
141 void SetEncoding( wxFontEncoding encoding )
142 {
143 if ( m_info.m_encoding != encoding )
144 {
145 m_info.SetEncoding( encoding );
146 Free();
147 }
148 }
149
150 wxFontEncoding GetEncoding() const { return m_info.GetEncoding(); }
151
152 void Free();
153
154 void MacFindFont();
155
156 protected:
157 // common part of all ctors
158 void Init();
159 #if wxOSX_USE_CORE_TEXT
160 // void Init( CTFontRef font );
161 #endif
162 bool m_noAA; // No anti-aliasing
163 public:
164 bool m_fontValid;
165 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
166 // for true themeing support we must store the correct font
167 // information here, as this speeds up and optimizes rendering
168 ThemeFontID m_macThemeFontID ;
169 #endif
170 #if wxOSX_USE_CORE_TEXT
171 wxCFRef<CTFontRef> m_ctFont;
172 #endif
173 #if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
174 ATSUStyle m_macATSUStyle ;
175 #endif
176 #if wxOSX_USE_COCOA
177 WX_NSFont m_nsFont;
178 #endif
179 #if wxOSX_USE_IPHONE
180 WX_UIFont m_uiFont;
181 #endif
182 wxNativeFontInfo m_info;
183 };
184
185 #define M_FONTDATA ((wxFontRefData*)m_refData)
186
187 wxFontRefData::wxFontRefData(const wxFontRefData& data)
188 {
189 Init();
190 m_info = data.m_info;
191 m_noAA = data.m_noAA;
192 m_fontValid = data.m_fontValid;
193 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
194 m_macThemeFontID = data.m_macThemeFontID;
195 #endif
196 #if wxOSX_USE_CORE_TEXT
197 m_ctFont = data.m_ctFont;
198 #endif
199 #if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
200 if ( data.m_macATSUStyle != NULL )
201 {
202 ATSUCreateStyle(&m_macATSUStyle) ;
203 ATSUCopyAttributes(data.m_macATSUStyle, m_macATSUStyle);
204 }
205 #endif
206 #if wxOSX_USE_COCOA
207 m_nsFont = (NSFont*) wxMacCocoaRetain(data.m_nsFont);
208 #endif
209 #if wxOSX_USE_IPHONE
210 m_uiFont = wxMacCocoaRetain(data.m_uiFont);
211 #endif
212
213 }
214
215 // ============================================================================
216 // implementation
217 // ============================================================================
218
219 // ----------------------------------------------------------------------------
220 // wxFontRefData
221 // ----------------------------------------------------------------------------
222
223 void wxFontRefData::Init()
224 {
225 m_noAA = false;
226 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
227 m_macThemeFontID = kThemeCurrentPortFont ;
228 #endif
229 #if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
230 m_macATSUStyle = NULL ;
231 #endif
232 #if wxOSX_USE_COCOA
233 m_nsFont = NULL;
234 #endif
235 #if wxOSX_USE_IPHONE
236 m_uiFont = NULL;
237 #endif
238 m_fontValid = false;
239 }
240
241 wxFontRefData::~wxFontRefData()
242 {
243 Free();
244 }
245
246 void wxFontRefData::Free()
247 {
248 #if wxOSX_USE_CORE_TEXT
249 m_ctFont.reset();
250 #endif
251 #if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
252 if ( m_macATSUStyle )
253 {
254 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
255 m_macATSUStyle = NULL ;
256 }
257 #endif
258 #if wxOSX_USE_COCOA
259 if (m_nsFont != NULL)
260 {
261 wxMacCocoaRelease(m_nsFont);
262 m_nsFont = NULL;
263 }
264 #endif
265 #if wxOSX_USE_IPHONE
266 if (m_uiFont != NULL)
267 {
268 wxMacCocoaRelease(m_uiFont);
269 m_uiFont = NULL;
270 }
271 #endif
272 m_fontValid = false;
273 }
274
275 wxFontRefData::wxFontRefData(wxOSXSystemFont font, int size)
276 {
277 wxASSERT( font != wxOSX_SYSTEM_FONT_NONE );
278 Init();
279
280 #if wxOSX_USE_CORE_TEXT
281 if ( UMAGetSystemVersion() >= 0x1050 )
282 {
283 CTFontUIFontType uifont;
284 switch( font )
285 {
286 case wxOSX_SYSTEM_FONT_NORMAL:
287 uifont = kCTFontSystemFontType;
288 break;
289 case wxOSX_SYSTEM_FONT_BOLD:
290 uifont = kCTFontEmphasizedSystemFontType;
291 break;
292 case wxOSX_SYSTEM_FONT_SMALL:
293 uifont = kCTFontSmallSystemFontType;
294 break;
295 case wxOSX_SYSTEM_FONT_SMALL_BOLD:
296 uifont = kCTFontSmallEmphasizedSystemFontType;
297 break;
298 case wxOSX_SYSTEM_FONT_MINI:
299 uifont = kCTFontMiniSystemFontType;
300 break;
301 case wxOSX_SYSTEM_FONT_MINI_BOLD:
302 uifont = kCTFontMiniEmphasizedSystemFontType;
303 break;
304 case wxOSX_SYSTEM_FONT_LABELS:
305 uifont = kCTFontLabelFontType;
306 break;
307 case wxOSX_SYSTEM_FONT_VIEWS:
308 uifont = kCTFontViewsFontType;
309 break;
310 default:
311 break;
312 }
313 m_ctFont.reset(CTFontCreateUIFontForLanguage( uifont, (CGFloat) size, NULL ));
314 wxCFRef<CTFontDescriptorRef> descr;
315 descr.reset( CTFontCopyFontDescriptor( m_ctFont ) );
316 m_info.Init(descr);
317 }
318 #endif
319 #if wxOSX_USE_ATSU_TEXT
320 {
321 #if !wxOSX_USE_CARBON
322 // not needed outside
323 ThemeFontID m_macThemeFontID;
324 #endif
325 switch( font )
326 {
327 case wxOSX_SYSTEM_FONT_NORMAL:
328 m_macThemeFontID = kThemeSystemFont;
329 break;
330 case wxOSX_SYSTEM_FONT_BOLD:
331 m_macThemeFontID = kThemeEmphasizedSystemFont;
332 break;
333 case wxOSX_SYSTEM_FONT_SMALL:
334 m_macThemeFontID = kThemeSmallSystemFont;
335 break;
336 case wxOSX_SYSTEM_FONT_SMALL_BOLD:
337 m_macThemeFontID = kThemeSmallEmphasizedSystemFont;
338 break;
339 case wxOSX_SYSTEM_FONT_MINI:
340 m_macThemeFontID = kThemeMiniSystemFont;
341 break;
342 case wxOSX_SYSTEM_FONT_MINI_BOLD:
343 // bold not available under themeing
344 m_macThemeFontID = kThemeMiniSystemFont;
345 break;
346 case wxOSX_SYSTEM_FONT_LABELS:
347 m_macThemeFontID = kThemeLabelFont;
348 break;
349 case wxOSX_SYSTEM_FONT_VIEWS:
350 m_macThemeFontID = kThemeViewsFont;
351 break;
352 default:
353 break;
354 }
355 if ( m_info.m_faceName.empty() )
356 {
357 Style style ;
358 FMFontSize fontSize;
359 Str255 qdFontName ;
360
361 GetThemeFont( m_macThemeFontID, GetApplicationScript(), qdFontName, &fontSize, &style );
362 if ( size != 0 )
363 fontSize = size;
364
365 wxFontStyle fontstyle = wxFONTSTYLE_NORMAL;
366 wxFontWeight fontweight = wxFONTWEIGHT_NORMAL;
367 bool underlined = false;
368
369 if ( style & bold )
370 fontweight = wxFONTWEIGHT_BOLD ;
371 else
372 fontweight = wxFONTWEIGHT_NORMAL ;
373 if ( style & italic )
374 fontstyle = wxFONTSTYLE_ITALIC ;
375 if ( style & underline )
376 underlined = true ;
377
378 m_info.Init(size,wxFONTFAMILY_DEFAULT,fontstyle,fontweight,underlined,
379 wxMacMakeStringFromPascal( qdFontName ), wxFONTENCODING_DEFAULT);
380 }
381 }
382 #endif
383 #if wxOSX_USE_COCOA
384 m_nsFont = wxFont::CreateNSFont( font, &m_info );
385 #endif
386 #if wxOSX_USE_IPHONE
387 m_uiFont = wxFont::CreateUIFont( font, &m_info );
388 #endif
389 }
390
391 void wxFontRefData::MacFindFont()
392 {
393 if ( m_fontValid )
394 return;
395
396 m_info.EnsureValid();
397
398 #if wxOSX_USE_CORE_TEXT
399 if ( UMAGetSystemVersion() >= 0x1050 )
400 {
401 CTFontSymbolicTraits traits = 0;
402
403 if (m_info.m_weight == wxFONTWEIGHT_BOLD)
404 traits |= kCTFontBoldTrait;
405 if (m_info.m_style == wxFONTSTYLE_ITALIC || m_info.m_style == wxFONTSTYLE_SLANT)
406 traits |= kCTFontItalicTrait;
407
408 // use font caching
409 wxString lookupnameWithSize = wxString::Format( "%s_%ld_%ld", m_info.m_faceName.c_str(), traits, m_info.m_pointSize );
410
411 static std::map< std::wstring , wxCFRef< CTFontRef > > fontcache ;
412 m_ctFont = fontcache[ std::wstring(lookupnameWithSize.wc_str()) ];
413 if ( !m_ctFont )
414 {
415 m_ctFont.reset( CTFontCreateWithFontDescriptor( m_info.m_ctFontDescriptor, 0/*m_pointSize */, NULL ) );
416 }
417 }
418
419 #endif
420 #if wxOSX_USE_ATSU_TEXT
421 {
422 // we try to get as much styles as possible into ATSU
423
424 OSStatus status = ::ATSUCreateStyle(&m_macATSUStyle);
425 wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") );
426
427 ATSUAttributeTag atsuTags[] =
428 {
429 kATSUFontTag ,
430 kATSUSizeTag ,
431 kATSUVerticalCharacterTag,
432 kATSUQDBoldfaceTag ,
433 kATSUQDItalicTag ,
434 kATSUQDUnderlineTag ,
435 kATSUQDCondensedTag ,
436 kATSUQDExtendedTag ,
437 };
438 ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
439 {
440 sizeof( ATSUFontID ) ,
441 sizeof( Fixed ) ,
442 sizeof( ATSUVerticalCharacterType),
443 sizeof( Boolean ) ,
444 sizeof( Boolean ) ,
445 sizeof( Boolean ) ,
446 sizeof( Boolean ) ,
447 sizeof( Boolean ) ,
448 };
449
450 Boolean kTrue = true ;
451 Boolean kFalse = false ;
452
453 Fixed atsuSize = IntToFixed( m_info.m_pointSize );
454 ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
455 FMFontStyle addQDStyle = m_info.m_atsuAdditionalQDStyles;
456 ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
457 {
458 &m_info.m_atsuFontID ,
459 &atsuSize ,
460 &kHorizontal,
461 (addQDStyle & bold) ? &kTrue : &kFalse ,
462 (addQDStyle & italic) ? &kTrue : &kFalse ,
463 (addQDStyle & underline) ? &kTrue : &kFalse ,
464 (addQDStyle & condense) ? &kTrue : &kFalse ,
465 (addQDStyle & extend) ? &kTrue : &kFalse ,
466 };
467
468 status = ::ATSUSetAttributes(
469 (ATSUStyle)m_macATSUStyle,
470 sizeof(atsuTags) / sizeof(ATSUAttributeTag) ,
471 atsuTags, atsuSizes, atsuValues);
472
473 wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") );
474 return;
475 }
476 #endif
477 #if wxOSX_USE_COCOA
478 m_nsFont = wxFont::CreateNSFont( &m_info );
479 #endif
480 #if wxOSX_USE_IPHONE
481 m_uiFont = wxFont::CreateUIFont( &m_info );
482 #endif
483 m_fontValid = true;
484 }
485
486 // ----------------------------------------------------------------------------
487 // wxFont
488 // ----------------------------------------------------------------------------
489
490 bool wxFont::Create(const wxNativeFontInfo& info)
491 {
492 UnRef();
493
494 m_refData = new wxFontRefData( info );
495 RealizeResource();
496
497 return true;
498 }
499
500 wxFont::wxFont(const wxString& fontdesc)
501 {
502 wxNativeFontInfo info;
503 if ( info.FromString(fontdesc) )
504 (void)Create(info);
505 }
506
507 bool wxFont::Create(int pointSize,
508 wxFontFamily family,
509 wxFontStyle style,
510 wxFontWeight weight,
511 bool underlined,
512 const wxString& faceNameParam,
513 wxFontEncoding encoding)
514 {
515 UnRef();
516
517 wxString faceName = faceNameParam;
518
519 if ( faceName.empty() )
520 {
521 switch ( family )
522 {
523 case wxFONTFAMILY_DEFAULT :
524 faceName = wxT("Lucida Grande");
525 break;
526
527 case wxFONTFAMILY_SCRIPT :
528 case wxFONTFAMILY_ROMAN :
529 case wxFONTFAMILY_DECORATIVE :
530 faceName = wxT("Times");
531 break ;
532
533 case wxFONTFAMILY_SWISS :
534 faceName = wxT("Helvetica");
535 break ;
536
537 case wxFONTFAMILY_MODERN :
538 case wxFONTFAMILY_TELETYPE:
539 faceName = wxT("Courier");
540 break ;
541
542 default:
543 faceName = wxT("Times");
544 break ;
545 }
546 }
547
548 wxNativeFontInfo info;
549
550 info.Init(pointSize, family, style, weight,
551 underlined, faceName, encoding);
552
553 m_refData = new wxFontRefData(info);
554
555 return true;
556 }
557
558 bool wxFont::CreateSystemFont(wxOSXSystemFont font)
559 {
560 UnRef();
561
562 m_refData = new wxFontRefData( font, 0 );
563
564 return true;
565 }
566
567 wxFont::~wxFont()
568 {
569 }
570
571 bool wxFont::RealizeResource()
572 {
573 M_FONTDATA->MacFindFont();
574
575 return true;
576 }
577
578 void wxFont::SetEncoding(wxFontEncoding encoding)
579 {
580 AllocExclusive();
581
582 M_FONTDATA->SetEncoding( encoding );
583 }
584
585 wxGDIRefData *wxFont::CreateGDIRefData() const
586 {
587 return new wxFontRefData;
588 }
589
590 wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
591 {
592 return new wxFontRefData(*static_cast<const wxFontRefData *>(data));
593 }
594
595 void wxFont::SetPointSize(int pointSize)
596 {
597 if ( M_FONTDATA->GetPointSize() == pointSize )
598 return;
599
600 AllocExclusive();
601
602 M_FONTDATA->SetPointSize( pointSize );
603 }
604
605 void wxFont::SetFamily(wxFontFamily family)
606 {
607 AllocExclusive();
608
609 M_FONTDATA->SetFamily( family );
610 }
611
612 void wxFont::SetStyle(wxFontStyle style)
613 {
614 AllocExclusive();
615
616 M_FONTDATA->SetStyle( style );
617 }
618
619 void wxFont::SetWeight(wxFontWeight weight)
620 {
621 AllocExclusive();
622
623 M_FONTDATA->SetWeight( weight );
624 }
625
626 bool wxFont::SetFaceName(const wxString& faceName)
627 {
628 AllocExclusive();
629
630 M_FONTDATA->SetFaceName( faceName );
631
632 return wxFontBase::SetFaceName(faceName);
633 }
634
635 void wxFont::SetUnderlined(bool underlined)
636 {
637 AllocExclusive();
638
639 M_FONTDATA->SetUnderlined( underlined );
640 }
641
642 void wxFont::SetNoAntiAliasing( bool no )
643 {
644 AllocExclusive();
645
646 M_FONTDATA->SetNoAntiAliasing( no );
647 }
648
649 // ----------------------------------------------------------------------------
650 // accessors
651 // ----------------------------------------------------------------------------
652
653 // TODO: insert checks everywhere for M_FONTDATA == NULL!
654
655 int wxFont::GetPointSize() const
656 {
657 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
658
659 return M_FONTDATA->GetPointSize();
660 }
661
662 wxSize wxFont::GetPixelSize() const
663 {
664 #if wxUSE_GRAPHICS_CONTEXT
665 // TODO: consider caching the value
666 wxGraphicsContext* dc = wxGraphicsContext::CreateFromNative((CGContextRef) NULL);
667 dc->SetFont(*(wxFont *)this,*wxBLACK);
668 wxDouble width, height = 0;
669 dc->GetTextExtent( wxT("g"), &width, &height, NULL, NULL);
670 delete dc;
671 return wxSize((int)width, (int)height);
672 #else
673 return wxFontBase::GetPixelSize();
674 #endif
675 }
676
677 wxFontFamily wxFont::GetFamily() const
678 {
679 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTFAMILY_MAX, wxT("invalid font") );
680
681 return M_FONTDATA->GetFamily();
682 }
683
684 wxFontStyle wxFont::GetStyle() const
685 {
686 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTSTYLE_MAX, wxT("invalid font") );
687
688 return M_FONTDATA->GetStyle() ;
689 }
690
691 wxFontWeight wxFont::GetWeight() const
692 {
693 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTWEIGHT_MAX, wxT("invalid font") );
694
695 return M_FONTDATA->GetWeight();
696 }
697
698 bool wxFont::GetUnderlined() const
699 {
700 wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
701
702 return M_FONTDATA->GetUnderlined();
703 }
704
705 wxString wxFont::GetFaceName() const
706 {
707 wxCHECK_MSG( M_FONTDATA != NULL , wxEmptyString , wxT("invalid font") );
708
709 return M_FONTDATA->GetFaceName() ;
710 }
711
712 wxFontEncoding wxFont::GetEncoding() const
713 {
714 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTENCODING_DEFAULT , wxT("invalid font") );
715
716 return M_FONTDATA->GetEncoding() ;
717 }
718
719 bool wxFont::GetNoAntiAliasing() const
720 {
721 wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
722
723 return M_FONTDATA->GetNoAntiAliasing();
724 }
725
726 #if wxOSX_USE_ATSU_TEXT && wxOSX_USE_CARBON
727
728 short wxFont::MacGetFontNum() const
729 {
730 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
731
732 // cast away constness otherwise lazy font resolution is not possible
733 const_cast<wxFont *>(this)->RealizeResource();
734
735 return M_FONTDATA->m_info.m_qdFontFamily;
736 }
737
738 wxByte wxFont::MacGetFontStyle() const
739 {
740 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
741
742 // cast away constness otherwise lazy font resolution is not possible
743 const_cast<wxFont *>(this)->RealizeResource();
744
745 return M_FONTDATA->m_info.m_qdFontStyle;
746 }
747
748 wxUint16 wxFont::MacGetThemeFontID() const
749 {
750 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
751
752 return M_FONTDATA->m_macThemeFontID;
753 }
754
755 #endif
756
757 #if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
758 void * wxFont::MacGetATSUStyle() const
759 {
760 wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
761
762 // cast away constness otherwise lazy font resolution is not possible
763 const_cast<wxFont *>(this)->RealizeResource();
764
765 return M_FONTDATA->m_macATSUStyle;
766 }
767 #endif
768
769 #if wxOSX_USE_CORE_TEXT
770
771 CTFontRef wxFont::GetCTFont() const
772 {
773 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
774
775 // cast away constness otherwise lazy font resolution is not possible
776 const_cast<wxFont *>(this)->RealizeResource();
777
778 return (CTFontRef)(M_FONTDATA->m_ctFont);
779 }
780
781 #endif
782
783 #if wxOSX_USE_COCOA
784
785 NSFont* wxFont::GetNSFont() const
786 {
787 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
788
789 // cast away constness otherwise lazy font resolution is not possible
790 const_cast<wxFont *>(this)->RealizeResource();
791
792 return (M_FONTDATA->m_nsFont);
793 }
794
795 #endif
796
797 const wxNativeFontInfo * wxFont::GetNativeFontInfo() const
798 {
799 wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
800 wxCHECK_MSG( Ok(), NULL, wxT("invalid font") );
801
802 // cast away constness otherwise lazy font resolution is not possible
803 const_cast<wxFont *>(this)->RealizeResource();
804
805 // M_FONTDATA->m_info.InitFromFont(*this);
806
807 return &(M_FONTDATA->m_info);
808 }
809
810 // ----------------------------------------------------------------------------
811 // wxNativeFontInfo
812 // ----------------------------------------------------------------------------
813
814 #if wxOSX_USE_CORE_TEXT
815
816 /* from Core Text Manual Common Operations */
817
818 static CTFontDescriptorRef wxMacCreateCTFontDescriptor(CFStringRef iFamilyName, CTFontSymbolicTraits iTraits )
819 {
820 CTFontDescriptorRef descriptor = NULL;
821 CFMutableDictionaryRef attributes;
822
823 assert(iFamilyName != NULL);
824 // Create a mutable dictionary to hold our attributes.
825 attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
826 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
827 check(attributes != NULL);
828
829 if (attributes != NULL) {
830 // Add a family name to our attributes.
831 CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, iFamilyName);
832
833
834 if ( iTraits ) {
835 CFMutableDictionaryRef traits;
836 CFNumberRef symTraits;
837
838 // Create the traits dictionary.
839 symTraits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type,
840 &iTraits);
841 check(symTraits != NULL);
842
843 if (symTraits != NULL) {
844 // Create a dictionary to hold our traits values.
845 traits = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
846 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
847 check(traits != NULL);
848
849 if (traits != NULL) {
850 // Add the symbolic traits value to the traits dictionary.
851 CFDictionaryAddValue(traits, kCTFontSymbolicTrait, symTraits);
852
853 // Add the traits attribute to our attributes.
854 CFDictionaryAddValue(attributes, kCTFontTraitsAttribute, traits);
855 CFRelease(traits);
856 }
857 CFRelease(symTraits);
858 }
859 }
860 // Create the font descriptor with our attributes
861 descriptor = CTFontDescriptorCreateWithAttributes(attributes);
862 check(descriptor != NULL);
863
864 CFRelease(attributes);
865 }
866 // Return our font descriptor.
867 return descriptor ;
868 }
869
870 #endif
871
872 void wxNativeFontInfo::Init()
873 {
874 #if wxOSX_USE_CORE_TEXT
875 m_ctFontDescriptor = NULL;
876 #endif
877 #if wxOSX_USE_ATSU_TEXT
878 m_atsuFontID = 0 ;
879 m_atsuAdditionalQDStyles = 0;
880 m_atsuFontValid = false;
881 #if wxOSX_USE_CARBON
882 m_qdFontStyle = 0;
883 m_qdFontFamily = 0;
884 #endif
885 #endif
886 #if wxOSX_USE_COCOA
887 m_nsFontDescriptor = NULL;
888 #endif
889 #if wxOSX_USE_IPHONE
890 m_uiFontDescriptor = NULL;
891 #endif
892 m_pointSize = 0;
893 m_family = wxFONTFAMILY_DEFAULT;
894 m_style = wxFONTSTYLE_NORMAL;
895 m_weight = wxFONTWEIGHT_NORMAL;
896 m_underlined = false;
897 m_faceName.clear();
898 m_encoding = wxFONTENCODING_DEFAULT;
899 m_descriptorValid = false;
900 }
901
902 #if wxOSX_USE_CORE_TEXT
903 void wxNativeFontInfo::Init(CTFontDescriptorRef descr)
904 {
905 Init();
906 m_ctFontDescriptor = wxCFRetain(descr);
907
908 wxCFRef< CFNumberRef > sizevalue( (CFNumberRef) CTFontDescriptorCopyAttribute( m_ctFontDescriptor, kCTFontSizeAttribute ) );
909 float fsize;
910 if ( CFNumberGetValue( sizevalue , kCFNumberFloatType , &fsize ) )
911 m_pointSize = (int)( fsize + 0.5 );
912
913 wxCFRef< CFDictionaryRef > traitsvalue( (CFDictionaryRef) CTFontDescriptorCopyAttribute( m_ctFontDescriptor, kCTFontTraitsAttribute ) );
914 CTFontSymbolicTraits traits;
915 if ( CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(traitsvalue,kCTFontSymbolicTrait),kCFNumberIntType,&traits) )
916 {
917 if ( traits & kCTFontItalicTrait )
918 m_style = wxFONTSTYLE_ITALIC;
919 if ( traits & kCTFontBoldTrait )
920 m_weight = wxFONTWEIGHT_BOLD ;
921 }
922
923 wxCFStringRef familyName( (CFStringRef) CTFontDescriptorCopyAttribute(m_ctFontDescriptor, kCTFontFamilyNameAttribute));
924 m_faceName = familyName.AsString();
925 }
926 #endif
927
928 void wxNativeFontInfo::EnsureValid()
929 {
930 if ( m_descriptorValid )
931 return;
932
933 #if wxOSX_USE_CORE_TEXT
934 if ( m_ctFontDescriptor == NULL && UMAGetSystemVersion() >= 0x1050 )
935 {
936 CTFontSymbolicTraits traits = 0;
937
938 if (m_weight == wxFONTWEIGHT_BOLD)
939 traits |= kCTFontBoldTrait;
940 if (m_style == wxFONTSTYLE_ITALIC || m_style == wxFONTSTYLE_SLANT)
941 traits |= kCTFontItalicTrait;
942
943 // use font caching
944 wxString lookupnameWithSize = wxString::Format( "%s_%ld_%ld", m_faceName.c_str(), traits, m_pointSize );
945
946 static std::map< std::wstring , wxCFRef< CTFontDescriptorRef > > fontdescriptorcache ;
947 m_ctFontDescriptor = wxCFRetain((CTFontDescriptorRef)fontdescriptorcache[ std::wstring(lookupnameWithSize.wc_str()) ]);
948 if ( !m_ctFontDescriptor )
949 {
950 // QD selection algorithm is the fastest by orders of magnitude on 10.5
951 if ( m_faceName.IsAscii() )
952 {
953 uint8_t qdstyle = 0;
954 if (m_weight == wxFONTWEIGHT_BOLD)
955 qdstyle |= bold;
956 if (m_style == wxFONTSTYLE_ITALIC || m_style == wxFONTSTYLE_SLANT)
957 qdstyle |= italic;
958
959 Str255 qdFontName ;
960 wxMacStringToPascal( m_faceName , qdFontName );
961 wxCFRef< CTFontRef > font;
962 font.reset( CTFontCreateWithQuickdrawInstance(qdFontName, 0 , qdstyle, m_pointSize) );
963 m_ctFontDescriptor = CTFontCopyFontDescriptor(font);
964 }
965 else
966 {
967 m_ctFontDescriptor = wxMacCreateCTFontDescriptor( wxCFStringRef(m_faceName),traits );
968 }
969 fontdescriptorcache[ std::wstring(lookupnameWithSize.wc_str()) ].reset(wxCFRetain(m_ctFontDescriptor));
970 }
971 }
972 #endif
973 #if wxOSX_USE_ATSU_TEXT
974 if ( !m_atsuFontValid )
975 {
976 #if !wxOSX_USE_CARBON
977 // not needed outside
978 wxInt16 m_qdFontFamily;
979 wxInt16 m_qdFontStyle;
980 #endif
981 wxCFStringRef cf( m_faceName, wxLocale::GetSystemEncoding() );
982 ATSFontFamilyRef atsfamily = ATSFontFamilyFindFromName( cf , kATSOptionFlagsDefault );
983 if ( atsfamily == (ATSFontFamilyRef) -1 )
984 {
985 wxLogDebug( wxT("ATSFontFamilyFindFromName failed for ") + m_faceName );
986 m_qdFontFamily = GetAppFont();
987 }
988 else
989 {
990 m_qdFontFamily = FMGetFontFamilyFromATSFontFamilyRef( atsfamily );
991 }
992
993 m_qdFontStyle = 0;
994 if (m_weight == wxFONTWEIGHT_BOLD)
995 m_qdFontStyle |= bold;
996 if (m_style == wxFONTSTYLE_ITALIC || m_style == wxFONTSTYLE_SLANT)
997 m_qdFontStyle |= italic;
998 if (m_underlined)
999 m_qdFontStyle |= underline;
1000
1001
1002 // we try to get as much styles as possible into ATSU
1003
1004 // ATSUFontID and FMFont are equivalent
1005 FMFontStyle intrinsicStyle = 0 ;
1006 OSStatus status = FMGetFontFromFontFamilyInstance( m_qdFontFamily , m_qdFontStyle , (FMFont*)&m_atsuFontID , &intrinsicStyle);
1007 wxASSERT_MSG( status == noErr , wxT("couldn't get an ATSUFont from font family") );
1008 m_atsuAdditionalQDStyles = m_qdFontStyle & (~intrinsicStyle );
1009 m_atsuFontValid = true;
1010 }
1011 #endif
1012 #if wxOSX_USE_COCOA
1013 if ( m_nsFontDescriptor == NULL )
1014 ValidateNSFontDescriptor();
1015 #endif
1016 #if wxOSX_USE_IPHONE
1017 // TODO
1018 #endif
1019 m_descriptorValid = true;
1020 }
1021
1022 void wxNativeFontInfo::Init(const wxNativeFontInfo& info)
1023 {
1024 Init();
1025 #if wxOSX_USE_CORE_TEXT
1026 m_ctFontDescriptor = wxCFRetain(info.m_ctFontDescriptor);
1027 #endif
1028 #if wxOSX_USE_ATSU_TEXT
1029 m_atsuFontValid = info.m_atsuFontValid;
1030 m_atsuFontID = info.m_atsuFontID ;
1031 m_atsuAdditionalQDStyles = info.m_atsuAdditionalQDStyles;
1032 #if wxOSX_USE_CARBON
1033 m_qdFontFamily = info.m_qdFontFamily;
1034 m_qdFontStyle = info.m_qdFontStyle;
1035 #endif
1036 #endif
1037 #if wxOSX_USE_COCOA
1038 m_nsFontDescriptor = (NSFontDescriptor*) wxMacCocoaRetain(info.m_nsFontDescriptor);
1039 #endif
1040 #if wxOSX_USE_IPHONE
1041 m_uiFontDescriptor = wxMacCocoaRetain(info.m_uiFontDescriptor);;
1042 #endif
1043 m_pointSize = info.m_pointSize;
1044 m_family = info.m_family;
1045 m_style = info.m_style;
1046 m_weight = info.m_weight;
1047 m_underlined = info.m_underlined;
1048 m_faceName = info.m_faceName;
1049 m_encoding = info.m_encoding;
1050 m_descriptorValid = info.m_descriptorValid;
1051 }
1052
1053 void wxNativeFontInfo::Init(int size,
1054 wxFontFamily family,
1055 wxFontStyle style,
1056 wxFontWeight weight,
1057 bool underlined,
1058 const wxString& faceName,
1059 wxFontEncoding encoding)
1060 {
1061 Init();
1062 m_pointSize = size;
1063 m_family = family;
1064 m_style = style;
1065 m_weight = weight;
1066 m_underlined = underlined;
1067 m_faceName = faceName;
1068 m_encoding = encoding;
1069
1070 }
1071
1072 void wxNativeFontInfo::Free()
1073 {
1074 #if wxOSX_USE_CORE_TEXT
1075 wxCFRelease(m_ctFontDescriptor);
1076 m_ctFontDescriptor = NULL;
1077 #endif
1078 #if wxOSX_USE_ATSU_TEXT
1079 m_atsuFontID = 0 ;
1080 m_atsuAdditionalQDStyles = 0;
1081 m_atsuFontValid = false;
1082 #endif
1083 #if wxOSX_USE_COCOA
1084 wxMacCocoaRelease(m_nsFontDescriptor);
1085 m_nsFontDescriptor = NULL;
1086 #endif
1087 #if wxOSX_USE_IPHONE
1088 wxMacCocoaRelease(m_uiFontDescriptor);
1089 m_uiFontDescriptor = NULL
1090 #endif
1091 m_descriptorValid = false;
1092 }
1093
1094 bool wxNativeFontInfo::FromString(const wxString& s)
1095 {
1096 long l;
1097
1098 wxStringTokenizer tokenizer(s, _T(";"));
1099
1100 wxString token = tokenizer.GetNextToken();
1101 //
1102 // Ignore the version for now
1103 //
1104
1105 token = tokenizer.GetNextToken();
1106 if ( !token.ToLong(&l) )
1107 return false;
1108 m_pointSize = (int)l;
1109
1110 token = tokenizer.GetNextToken();
1111 if ( !token.ToLong(&l) )
1112 return false;
1113 m_family = (wxFontFamily)l;
1114
1115 token = tokenizer.GetNextToken();
1116 if ( !token.ToLong(&l) )
1117 return false;
1118 m_style = (wxFontStyle)l;
1119
1120 token = tokenizer.GetNextToken();
1121 if ( !token.ToLong(&l) )
1122 return false;
1123 m_weight = (wxFontWeight)l;
1124
1125 token = tokenizer.GetNextToken();
1126 if ( !token.ToLong(&l) )
1127 return false;
1128 m_underlined = l != 0;
1129
1130 m_faceName = tokenizer.GetNextToken();
1131
1132 #ifndef __WXMAC__
1133 if( !faceName )
1134 return false;
1135 #endif
1136
1137 token = tokenizer.GetNextToken();
1138 if ( !token.ToLong(&l) )
1139 return false;
1140 m_encoding = (wxFontEncoding)l;
1141
1142 return true;
1143 }
1144
1145 wxString wxNativeFontInfo::ToString() const
1146 {
1147 wxString s;
1148
1149 s.Printf(_T("%d;%d;%d;%d;%d;%d;%s;%d"),
1150 0, // version
1151 m_pointSize,
1152 m_family,
1153 (int)m_style,
1154 (int)m_weight,
1155 m_underlined,
1156 m_faceName.GetData(),
1157 (int)m_encoding);
1158
1159 return s;
1160 }
1161
1162 int wxNativeFontInfo::GetPointSize() const
1163 {
1164 return m_pointSize;
1165 }
1166
1167 wxFontStyle wxNativeFontInfo::GetStyle() const
1168 {
1169 return m_style;
1170 }
1171
1172 wxFontWeight wxNativeFontInfo::GetWeight() const
1173 {
1174 return m_weight;
1175 }
1176
1177 bool wxNativeFontInfo::GetUnderlined() const
1178 {
1179 return m_underlined;
1180 }
1181
1182 wxString wxNativeFontInfo::GetFaceName() const
1183 {
1184 return m_faceName;
1185 }
1186
1187 wxFontFamily wxNativeFontInfo::GetFamily() const
1188 {
1189 return m_family;
1190 }
1191
1192 wxFontEncoding wxNativeFontInfo::GetEncoding() const
1193 {
1194 return m_encoding;
1195 }
1196
1197 // changing the font descriptor
1198
1199 void wxNativeFontInfo::SetPointSize(int pointsize)
1200 {
1201 if ( m_pointSize != pointsize )
1202 {
1203 m_pointSize = pointsize;
1204 Free();
1205 }
1206 }
1207
1208 void wxNativeFontInfo::SetStyle(wxFontStyle style_)
1209 {
1210 if ( m_style != style_ )
1211 {
1212 m_style = style_;
1213 Free();
1214 }
1215 }
1216
1217 void wxNativeFontInfo::SetWeight(wxFontWeight weight_)
1218 {
1219 if ( m_weight != weight_ )
1220 {
1221 m_weight = weight_;
1222 Free();
1223 }
1224 }
1225
1226 void wxNativeFontInfo::SetUnderlined(bool underlined_)
1227 {
1228 if ( m_underlined != underlined_ )
1229 {
1230 m_underlined = underlined_;
1231 Free();
1232 }
1233 }
1234
1235 bool wxNativeFontInfo::SetFaceName(const wxString& facename_)
1236 {
1237 if ( m_faceName != facename_ )
1238 {
1239 m_faceName = facename_;
1240 Free();
1241 }
1242 return true;
1243 }
1244
1245 void wxNativeFontInfo::SetFamily(wxFontFamily family_)
1246 {
1247 if ( m_family != family_ )
1248 {
1249 m_family = family_;
1250 Free();
1251 }
1252 }
1253
1254 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_)
1255 {
1256 m_encoding = encoding_;
1257 // not reflected in native descriptors
1258 }