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