1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/font.cpp
3 // Purpose: wxFont class
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
17 #include "wx/string.h"
20 #include "wx/gdicmn.h"
24 #include "wx/fontutil.h"
25 #include "wx/graphics.h"
26 #include "wx/settings.h"
27 #include "wx/tokenzr.h"
29 #include "wx/osx/private.h"
34 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
)
36 class WXDLLEXPORT wxFontRefData
: public wxGDIRefData
43 m_info
.Init(10, wxFONTFAMILY_DEFAULT
, wxFONTSTYLE_NORMAL
, wxFONTWEIGHT_NORMAL
,
44 false, wxEmptyString
, wxFONTENCODING_DEFAULT
);
47 wxFontRefData(const wxFontRefData
& data
);
49 wxFontRefData( const wxNativeFontInfo
& info
) : m_info(info
)
54 wxFontRefData(wxOSXSystemFont font
, int size
);
56 #if wxOSX_USE_CORE_TEXT
57 wxFontRefData( wxUint32 coreTextFontType
);
58 wxFontRefData( CTFontRef font
);
59 wxFontRefData( CTFontDescriptorRef fontdescriptor
, int size
);
62 virtual ~wxFontRefData();
64 void SetNoAntiAliasing( bool no
= true ) { m_noAA
= no
; }
66 bool GetNoAntiAliasing() const { return m_noAA
; }
68 void SetPointSize( int size
)
70 if( GetPointSize() != size
)
72 m_info
.SetPointSize(size
);
77 int GetPointSize() const { return m_info
.GetPointSize(); }
79 void SetFamily( wxFontFamily family
)
81 if ( m_info
.m_family
!= family
)
83 m_info
.SetFamily( family
);
88 wxFontFamily
GetFamily() const { return m_info
.GetFamily(); }
90 void SetStyle( wxFontStyle style
)
92 if ( m_info
.m_style
!= style
)
94 m_info
.SetStyle( style
);
100 wxFontStyle
GetStyle() const { return m_info
.GetStyle(); }
102 void SetWeight( wxFontWeight weight
)
104 if ( m_info
.m_weight
!= weight
)
106 m_info
.SetWeight( weight
);
112 wxFontWeight
GetWeight() const { return m_info
.GetWeight(); }
114 void SetUnderlined( bool u
)
116 if ( m_info
.m_underlined
!= u
)
118 m_info
.SetUnderlined( u
);
123 bool GetUnderlined() const { return m_info
.GetUnderlined(); }
125 void SetFaceName( const wxString
& facename
)
127 if ( m_info
.m_faceName
!= facename
)
129 m_info
.SetFaceName( facename
);
134 wxString
GetFaceName() const { return m_info
.GetFaceName(); }
136 void SetEncoding( wxFontEncoding encoding
)
138 if ( m_info
.m_encoding
!= encoding
)
140 m_info
.SetEncoding( encoding
);
145 wxFontEncoding
GetEncoding() const { return m_info
.GetEncoding(); }
152 // common part of all ctors
154 #if wxOSX_USE_CORE_TEXT
155 // void Init( CTFontRef font );
157 bool m_noAA
; // No anti-aliasing
160 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
161 // for true theming support we must store the correct font
162 // information here, as this speeds up and optimizes rendering
163 ThemeFontID m_macThemeFontID
;
165 #if wxOSX_USE_CORE_TEXT
166 wxCFRef
<CTFontRef
> m_ctFont
;
168 #if wxOSX_USE_ATSU_TEXT
169 ATSUStyle m_macATSUStyle
;
171 wxCFRef
<CGFontRef
> m_cgFont
;
178 wxNativeFontInfo m_info
;
181 #define M_FONTDATA ((wxFontRefData*)m_refData)
183 wxFontRefData::wxFontRefData(const wxFontRefData
& data
)
186 m_info
= data
.m_info
;
187 m_noAA
= data
.m_noAA
;
188 m_fontValid
= data
.m_fontValid
;
189 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
190 m_macThemeFontID
= data
.m_macThemeFontID
;
192 #if wxOSX_USE_CORE_TEXT
193 m_ctFont
= data
.m_ctFont
;
195 m_cgFont
= data
.m_cgFont
;
196 #if wxOSX_USE_ATSU_TEXT
197 if ( data
.m_macATSUStyle
!= NULL
)
199 ATSUCreateStyle(&m_macATSUStyle
) ;
200 ATSUCopyAttributes(data
.m_macATSUStyle
, m_macATSUStyle
);
204 m_nsFont
= (NSFont
*) wxMacCocoaRetain(data
.m_nsFont
);
207 m_uiFont
= (UIFont
*) wxMacCocoaRetain(data
.m_uiFont
);
212 // ============================================================================
214 // ============================================================================
216 // ----------------------------------------------------------------------------
218 // ----------------------------------------------------------------------------
220 void wxFontRefData::Init()
223 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
224 m_macThemeFontID
= kThemeCurrentPortFont
;
226 #if wxOSX_USE_ATSU_TEXT
227 m_macATSUStyle
= NULL
;
238 wxFontRefData::~wxFontRefData()
243 void wxFontRefData::Free()
245 #if wxOSX_USE_CORE_TEXT
249 #if wxOSX_USE_ATSU_TEXT
251 m_macThemeFontID
= kThemeCurrentPortFont
;
253 if ( m_macATSUStyle
)
255 ::ATSUDisposeStyle((ATSUStyle
)m_macATSUStyle
);
256 m_macATSUStyle
= NULL
;
260 if (m_nsFont
!= NULL
)
262 wxMacCocoaRelease(m_nsFont
);
267 if (m_uiFont
!= NULL
)
269 wxMacCocoaRelease(m_uiFont
);
276 wxFontRefData::wxFontRefData(wxOSXSystemFont font
, int size
)
278 wxASSERT( font
!= wxOSX_SYSTEM_FONT_NONE
);
281 #if wxOSX_USE_CORE_TEXT
282 if ( UMAGetSystemVersion() >= 0x1050 )
284 CTFontUIFontType uifont
= kCTFontSystemFontType
;
287 case wxOSX_SYSTEM_FONT_NORMAL
:
288 uifont
= kCTFontSystemFontType
;
290 case wxOSX_SYSTEM_FONT_BOLD
:
291 uifont
= kCTFontEmphasizedSystemFontType
;
293 case wxOSX_SYSTEM_FONT_SMALL
:
294 uifont
= kCTFontSmallSystemFontType
;
296 case wxOSX_SYSTEM_FONT_SMALL_BOLD
:
297 uifont
= kCTFontSmallEmphasizedSystemFontType
;
299 case wxOSX_SYSTEM_FONT_MINI
:
300 uifont
= kCTFontMiniSystemFontType
;
302 case wxOSX_SYSTEM_FONT_MINI_BOLD
:
303 uifont
= kCTFontMiniEmphasizedSystemFontType
;
305 case wxOSX_SYSTEM_FONT_LABELS
:
306 uifont
= kCTFontLabelFontType
;
308 case wxOSX_SYSTEM_FONT_VIEWS
:
309 uifont
= kCTFontViewsFontType
;
314 m_ctFont
.reset(CTFontCreateUIFontForLanguage( uifont
, (CGFloat
) size
, NULL
));
315 wxCFRef
<CTFontDescriptorRef
> descr
;
316 descr
.reset( CTFontCopyFontDescriptor( m_ctFont
) );
320 #if wxOSX_USE_ATSU_TEXT
322 #if !wxOSX_USE_CARBON
323 // not needed outside
324 ThemeFontID m_macThemeFontID
= kThemeSystemFont
;
328 case wxOSX_SYSTEM_FONT_NORMAL
:
329 m_macThemeFontID
= kThemeSystemFont
;
331 case wxOSX_SYSTEM_FONT_BOLD
:
332 m_macThemeFontID
= kThemeEmphasizedSystemFont
;
334 case wxOSX_SYSTEM_FONT_SMALL
:
335 m_macThemeFontID
= kThemeSmallSystemFont
;
337 case wxOSX_SYSTEM_FONT_SMALL_BOLD
:
338 m_macThemeFontID
= kThemeSmallEmphasizedSystemFont
;
340 case wxOSX_SYSTEM_FONT_MINI
:
341 m_macThemeFontID
= kThemeMiniSystemFont
;
343 case wxOSX_SYSTEM_FONT_MINI_BOLD
:
344 // bold not available under theming
345 m_macThemeFontID
= kThemeMiniSystemFont
;
347 case wxOSX_SYSTEM_FONT_LABELS
:
348 m_macThemeFontID
= kThemeLabelFont
;
350 case wxOSX_SYSTEM_FONT_VIEWS
:
351 m_macThemeFontID
= kThemeViewsFont
;
356 if ( m_info
.m_faceName
.empty() )
362 GetThemeFont( m_macThemeFontID
, GetApplicationScript(), qdFontName
, &fontSize
, &style
);
366 wxFontStyle fontstyle
= wxFONTSTYLE_NORMAL
;
367 wxFontWeight fontweight
= wxFONTWEIGHT_NORMAL
;
368 bool underlined
= false;
371 fontweight
= wxFONTWEIGHT_BOLD
;
373 fontweight
= wxFONTWEIGHT_NORMAL
;
374 if ( style
& italic
)
375 fontstyle
= wxFONTSTYLE_ITALIC
;
376 if ( style
& underline
)
379 m_info
.Init(fontSize
,wxFONTFAMILY_DEFAULT
,fontstyle
,fontweight
,underlined
,
380 wxMacMakeStringFromPascal( qdFontName
), wxFONTENCODING_DEFAULT
);
385 m_nsFont
= wxFont::OSXCreateNSFont( font
, &m_info
);
388 m_uiFont
= wxFont::OSXCreateUIFont( font
, &m_info
);
392 void wxFontRefData::MacFindFont()
397 wxCHECK_RET( m_info
.m_pointSize
> 0, wxT("Point size should not be zero.") );
399 m_info
.EnsureValid();
401 #if wxOSX_USE_CORE_TEXT
402 if ( UMAGetSystemVersion() >= 0x1050 )
404 CTFontSymbolicTraits traits
= 0;
406 if (m_info
.m_weight
== wxFONTWEIGHT_BOLD
)
407 traits
|= kCTFontBoldTrait
;
408 if (m_info
.m_style
== wxFONTSTYLE_ITALIC
|| m_info
.m_style
== wxFONTSTYLE_SLANT
)
409 traits
|= kCTFontItalicTrait
;
412 wxString lookupnameWithSize
= wxString::Format( "%s_%ld_%ld", m_info
.m_faceName
.c_str(), traits
, m_info
.m_pointSize
);
414 static std::map
< std::wstring
, wxCFRef
< CTFontRef
> > fontcache
;
415 m_ctFont
= fontcache
[ std::wstring(lookupnameWithSize
.wc_str()) ];
418 m_ctFont
.reset( CTFontCreateWithFontDescriptor( m_info
.m_ctFontDescriptor
, 0/*m_pointSize */, NULL
) );
420 m_cgFont
.reset(CTFontCopyGraphicsFont(m_ctFont
, NULL
));
424 #if wxOSX_USE_ATSU_TEXT
426 // we try to get as much styles as possible into ATSU
428 OSStatus status
= ::ATSUCreateStyle(&m_macATSUStyle
);
429 wxASSERT_MSG( status
== noErr
, wxT("couldn't create ATSU style") );
431 ATSUAttributeTag atsuTags
[] =
435 kATSUVerticalCharacterTag
,
438 kATSUQDUnderlineTag
,
439 kATSUQDCondensedTag
,
442 ByteCount atsuSizes
[WXSIZEOF(atsuTags
)] =
444 sizeof( ATSUFontID
) ,
446 sizeof( ATSUVerticalCharacterType
),
454 Boolean kTrue
= true ;
455 Boolean kFalse
= false ;
457 Fixed atsuSize
= IntToFixed( m_info
.m_pointSize
);
458 ATSUVerticalCharacterType kHorizontal
= kATSUStronglyHorizontal
;
459 FMFontStyle addQDStyle
= m_info
.m_atsuAdditionalQDStyles
;
460 ATSUAttributeValuePtr atsuValues
[WXSIZEOF(atsuTags
)] =
462 &m_info
.m_atsuFontID
,
465 (addQDStyle
& bold
) ? &kTrue
: &kFalse
,
466 (addQDStyle
& italic
) ? &kTrue
: &kFalse
,
467 (addQDStyle
& underline
) ? &kTrue
: &kFalse
,
468 (addQDStyle
& condense
) ? &kTrue
: &kFalse
,
469 (addQDStyle
& extend
) ? &kTrue
: &kFalse
,
472 status
= ::ATSUSetAttributes(
473 (ATSUStyle
)m_macATSUStyle
,
475 atsuTags
, atsuSizes
, atsuValues
);
477 wxASSERT_MSG( status
== noErr
, wxString::Format(wxT("couldn't modify ATSU style. Status was %d"), (int) status
).c_str() );
479 if ( m_cgFont
.get() == NULL
)
481 ATSFontRef fontRef
= FMGetATSFontRefFromFont(m_info
.m_atsuFontID
);
482 m_cgFont
.reset( CGFontCreateWithPlatformFont( &fontRef
) );
487 m_nsFont
= wxFont::OSXCreateNSFont( &m_info
);
490 m_uiFont
= wxFont::OSXCreateUIFont( &m_info
);
495 // ----------------------------------------------------------------------------
497 // ----------------------------------------------------------------------------
499 bool wxFont::Create(const wxNativeFontInfo
& info
)
503 m_refData
= new wxFontRefData( info
);
509 wxFont::wxFont(const wxString
& fontdesc
)
511 wxNativeFontInfo info
;
512 if ( info
.FromString(fontdesc
) )
516 bool wxFont::Create(int pointSize
,
521 const wxString
& faceNameParam
,
522 wxFontEncoding encoding
)
526 wxString faceName
= faceNameParam
;
528 if ( faceName
.empty() )
532 case wxFONTFAMILY_DEFAULT
:
533 faceName
= wxT("Lucida Grande");
536 case wxFONTFAMILY_SCRIPT
:
537 case wxFONTFAMILY_ROMAN
:
538 case wxFONTFAMILY_DECORATIVE
:
539 faceName
= wxT("Times");
542 case wxFONTFAMILY_SWISS
:
543 faceName
= wxT("Helvetica");
546 case wxFONTFAMILY_MODERN
:
547 case wxFONTFAMILY_TELETYPE
:
548 faceName
= wxT("Courier");
552 faceName
= wxT("Times");
557 wxNativeFontInfo info
;
559 info
.Init(pointSize
, family
, style
, weight
,
560 underlined
, faceName
, encoding
);
562 m_refData
= new wxFontRefData(info
);
567 bool wxFont::CreateSystemFont(wxOSXSystemFont font
)
571 m_refData
= new wxFontRefData( font
, 0 );
580 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo
& info
)
584 m_refData
= new wxFontRefData( info
);
588 bool wxFont::RealizeResource()
590 M_FONTDATA
->MacFindFont();
595 void wxFont::SetEncoding(wxFontEncoding encoding
)
599 M_FONTDATA
->SetEncoding( encoding
);
602 wxGDIRefData
*wxFont::CreateGDIRefData() const
604 return new wxFontRefData
;
607 wxGDIRefData
*wxFont::CloneGDIRefData(const wxGDIRefData
*data
) const
609 return new wxFontRefData(*static_cast<const wxFontRefData
*>(data
));
612 void wxFont::SetPointSize(int pointSize
)
614 if ( M_FONTDATA
->GetPointSize() == pointSize
)
619 M_FONTDATA
->SetPointSize( pointSize
);
622 void wxFont::SetFamily(wxFontFamily family
)
626 M_FONTDATA
->SetFamily( family
);
629 void wxFont::SetStyle(wxFontStyle style
)
633 M_FONTDATA
->SetStyle( style
);
636 void wxFont::SetWeight(wxFontWeight weight
)
640 M_FONTDATA
->SetWeight( weight
);
643 bool wxFont::SetFaceName(const wxString
& faceName
)
647 M_FONTDATA
->SetFaceName( faceName
);
649 return wxFontBase::SetFaceName(faceName
);
652 void wxFont::SetUnderlined(bool underlined
)
656 M_FONTDATA
->SetUnderlined( underlined
);
659 void wxFont::SetNoAntiAliasing( bool no
)
663 M_FONTDATA
->SetNoAntiAliasing( no
);
666 // ----------------------------------------------------------------------------
668 // ----------------------------------------------------------------------------
670 // TODO: insert checks everywhere for M_FONTDATA == NULL!
672 int wxFont::GetPointSize() const
674 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
676 return M_FONTDATA
->GetPointSize();
679 wxSize
wxFont::GetPixelSize() const
681 #if wxUSE_GRAPHICS_CONTEXT
682 // TODO: consider caching the value
683 wxGraphicsContext
* dc
= wxGraphicsContext::CreateFromNative((CGContextRef
) NULL
);
684 dc
->SetFont(*(wxFont
*)this,*wxBLACK
);
685 wxDouble width
, height
= 0;
686 dc
->GetTextExtent( wxT("g"), &width
, &height
, NULL
, NULL
);
688 return wxSize((int)width
, (int)height
);
690 return wxFontBase::GetPixelSize();
694 wxFontFamily
wxFont::GetFamily() const
696 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTFAMILY_MAX
, wxT("invalid font") );
698 return M_FONTDATA
->GetFamily();
701 wxFontStyle
wxFont::GetStyle() const
703 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTSTYLE_MAX
, wxT("invalid font") );
705 return M_FONTDATA
->GetStyle() ;
708 wxFontWeight
wxFont::GetWeight() const
710 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTWEIGHT_MAX
, wxT("invalid font") );
712 return M_FONTDATA
->GetWeight();
715 bool wxFont::GetUnderlined() const
717 wxCHECK_MSG( M_FONTDATA
!= NULL
, false, wxT("invalid font") );
719 return M_FONTDATA
->GetUnderlined();
722 wxString
wxFont::GetFaceName() const
724 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxEmptyString
, wxT("invalid font") );
726 return M_FONTDATA
->GetFaceName() ;
729 wxFontEncoding
wxFont::GetEncoding() const
731 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTENCODING_DEFAULT
, wxT("invalid font") );
733 return M_FONTDATA
->GetEncoding() ;
736 bool wxFont::GetNoAntiAliasing() const
738 wxCHECK_MSG( M_FONTDATA
!= NULL
, false, wxT("invalid font") );
740 return M_FONTDATA
->GetNoAntiAliasing();
743 #if wxOSX_USE_ATSU_TEXT && wxOSX_USE_CARBON
745 short wxFont::MacGetFontNum() const
747 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
749 // cast away constness otherwise lazy font resolution is not possible
750 const_cast<wxFont
*>(this)->RealizeResource();
752 return M_FONTDATA
->m_info
.m_qdFontFamily
;
755 wxByte
wxFont::MacGetFontStyle() const
757 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
759 // cast away constness otherwise lazy font resolution is not possible
760 const_cast<wxFont
*>(this)->RealizeResource();
762 return M_FONTDATA
->m_info
.m_qdFontStyle
;
765 wxUint16
wxFont::MacGetThemeFontID() const
767 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
769 return M_FONTDATA
->m_macThemeFontID
;
774 #if wxOSX_USE_ATSU_TEXT
775 void * wxFont::MacGetATSUStyle() const
777 wxCHECK_MSG( M_FONTDATA
!= NULL
, NULL
, wxT("invalid font") );
779 // cast away constness otherwise lazy font resolution is not possible
780 const_cast<wxFont
*>(this)->RealizeResource();
782 return M_FONTDATA
->m_macATSUStyle
;
785 #if WXWIN_COMPATIBILITY_2_8
786 wxUint32
wxFont::MacGetATSUFontID() const
788 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
790 // cast away constness otherwise lazy font resolution is not possible
791 const_cast<wxFont
*>(this)->RealizeResource();
793 return M_FONTDATA
->m_info
.m_atsuFontID
;
796 wxUint32
wxFont::MacGetATSUAdditionalQDStyles() const
798 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
800 // cast away constness otherwise lazy font resolution is not possible
801 const_cast<wxFont
*>(this)->RealizeResource();
803 return M_FONTDATA
->m_info
.m_atsuAdditionalQDStyles
;
809 #if wxOSX_USE_CORE_TEXT
811 CTFontRef
wxFont::OSXGetCTFont() const
813 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
815 // cast away constness otherwise lazy font resolution is not possible
816 const_cast<wxFont
*>(this)->RealizeResource();
818 return (CTFontRef
)(M_FONTDATA
->m_ctFont
);
823 #if wxOSX_USE_COCOA_OR_CARBON
825 CGFontRef
wxFont::OSXGetCGFont() const
827 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
829 // cast away constness otherwise lazy font resolution is not possible
830 const_cast<wxFont
*>(this)->RealizeResource();
832 return (M_FONTDATA
->m_cgFont
);
840 NSFont
* wxFont::OSXGetNSFont() const
842 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
844 // cast away constness otherwise lazy font resolution is not possible
845 const_cast<wxFont
*>(this)->RealizeResource();
847 return (M_FONTDATA
->m_nsFont
);
852 const wxNativeFontInfo
* wxFont::GetNativeFontInfo() const
854 wxCHECK_MSG( M_FONTDATA
!= NULL
, NULL
, wxT("invalid font") );
855 wxCHECK_MSG( Ok(), NULL
, wxT("invalid font") );
857 // cast away constness otherwise lazy font resolution is not possible
858 const_cast<wxFont
*>(this)->RealizeResource();
860 // M_FONTDATA->m_info.InitFromFont(*this);
862 return &(M_FONTDATA
->m_info
);
865 // ----------------------------------------------------------------------------
867 // ----------------------------------------------------------------------------
869 #if wxOSX_USE_CORE_TEXT
871 /* from Core Text Manual Common Operations */
873 static CTFontDescriptorRef
wxMacCreateCTFontDescriptor(CFStringRef iFamilyName
, CTFontSymbolicTraits iTraits
)
875 CTFontDescriptorRef descriptor
= NULL
;
876 CFMutableDictionaryRef attributes
;
878 wxASSERT(iFamilyName
!= NULL
);
879 // Create a mutable dictionary to hold our attributes.
880 attributes
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
881 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
882 wxASSERT(attributes
!= NULL
);
884 if (attributes
!= NULL
) {
885 // Add a family name to our attributes.
886 CFDictionaryAddValue(attributes
, kCTFontFamilyNameAttribute
, iFamilyName
);
890 CFMutableDictionaryRef traits
;
891 CFNumberRef symTraits
;
893 // Create the traits dictionary.
894 symTraits
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
896 wxASSERT(symTraits
!= NULL
);
898 if (symTraits
!= NULL
) {
899 // Create a dictionary to hold our traits values.
900 traits
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
901 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
902 wxASSERT(traits
!= NULL
);
904 if (traits
!= NULL
) {
905 // Add the symbolic traits value to the traits dictionary.
906 CFDictionaryAddValue(traits
, kCTFontSymbolicTrait
, symTraits
);
908 // Add the traits attribute to our attributes.
909 CFDictionaryAddValue(attributes
, kCTFontTraitsAttribute
, traits
);
912 CFRelease(symTraits
);
915 // Create the font descriptor with our attributes
916 descriptor
= CTFontDescriptorCreateWithAttributes(attributes
);
917 wxASSERT(descriptor
!= NULL
);
919 CFRelease(attributes
);
921 // Return our font descriptor.
927 void wxNativeFontInfo::Init()
929 #if wxOSX_USE_CORE_TEXT
930 m_ctFontDescriptor
= NULL
;
932 #if wxOSX_USE_ATSU_TEXT
934 m_atsuAdditionalQDStyles
= 0;
935 m_atsuFontValid
= false;
942 m_nsFontDescriptor
= NULL
;
945 m_family
= wxFONTFAMILY_DEFAULT
;
946 m_style
= wxFONTSTYLE_NORMAL
;
947 m_weight
= wxFONTWEIGHT_NORMAL
;
948 m_underlined
= false;
950 m_encoding
= wxFont::GetDefaultEncoding();
951 m_descriptorValid
= false;
954 #if wxOSX_USE_CORE_TEXT
955 void wxNativeFontInfo::Init(CTFontDescriptorRef descr
)
958 m_ctFontDescriptor
= wxCFRetain(descr
);
960 wxCFRef
< CFNumberRef
> sizevalue( (CFNumberRef
) CTFontDescriptorCopyAttribute( m_ctFontDescriptor
, kCTFontSizeAttribute
) );
962 if ( CFNumberGetValue( sizevalue
, kCFNumberFloatType
, &fsize
) )
963 m_pointSize
= (int)( fsize
+ 0.5 );
965 wxCFRef
< CFDictionaryRef
> traitsvalue( (CFDictionaryRef
) CTFontDescriptorCopyAttribute( m_ctFontDescriptor
, kCTFontTraitsAttribute
) );
966 CTFontSymbolicTraits traits
;
967 if ( CFNumberGetValue((CFNumberRef
) CFDictionaryGetValue(traitsvalue
,kCTFontSymbolicTrait
),kCFNumberIntType
,&traits
) )
969 if ( traits
& kCTFontItalicTrait
)
970 m_style
= wxFONTSTYLE_ITALIC
;
971 if ( traits
& kCTFontBoldTrait
)
972 m_weight
= wxFONTWEIGHT_BOLD
;
975 wxCFStringRef
familyName( (CFStringRef
) CTFontDescriptorCopyAttribute(m_ctFontDescriptor
, kCTFontFamilyNameAttribute
));
976 m_faceName
= familyName
.AsString();
980 void wxNativeFontInfo::EnsureValid()
982 if ( m_descriptorValid
)
985 #if wxOSX_USE_CORE_TEXT
986 if ( m_ctFontDescriptor
== NULL
&& UMAGetSystemVersion() >= 0x1050 )
988 CTFontSymbolicTraits traits
= 0;
990 if (m_weight
== wxFONTWEIGHT_BOLD
)
991 traits
|= kCTFontBoldTrait
;
992 if (m_style
== wxFONTSTYLE_ITALIC
|| m_style
== wxFONTSTYLE_SLANT
)
993 traits
|= kCTFontItalicTrait
;
996 wxString lookupnameWithSize
= wxString::Format( "%s_%ld_%ld", m_faceName
.c_str(), traits
, m_pointSize
);
998 static std::map
< std::wstring
, wxCFRef
< CTFontDescriptorRef
> > fontdescriptorcache
;
999 m_ctFontDescriptor
= wxCFRetain((CTFontDescriptorRef
)fontdescriptorcache
[ std::wstring(lookupnameWithSize
.wc_str()) ]);
1000 if ( !m_ctFontDescriptor
)
1002 // QD selection algorithm is the fastest by orders of magnitude on 10.5
1003 if ( m_faceName
.IsAscii() )
1005 uint8_t qdstyle
= 0;
1006 if (m_weight
== wxFONTWEIGHT_BOLD
)
1008 if (m_style
== wxFONTSTYLE_ITALIC
|| m_style
== wxFONTSTYLE_SLANT
)
1012 wxMacStringToPascal( m_faceName
, qdFontName
);
1013 wxCFRef
< CTFontRef
> font
;
1014 font
.reset( CTFontCreateWithQuickdrawInstance(qdFontName
, 0 , qdstyle
, m_pointSize
) );
1015 m_ctFontDescriptor
= CTFontCopyFontDescriptor(font
);
1019 m_ctFontDescriptor
= wxMacCreateCTFontDescriptor( wxCFStringRef(m_faceName
),traits
);
1021 fontdescriptorcache
[ std::wstring(lookupnameWithSize
.wc_str()) ].reset(wxCFRetain(m_ctFontDescriptor
));
1025 #if wxOSX_USE_ATSU_TEXT
1026 if ( !m_atsuFontValid
)
1028 #if !wxOSX_USE_CARBON
1029 // not needed outside
1030 wxInt16 m_qdFontFamily
;
1031 wxInt16 m_qdFontStyle
;
1033 wxCFStringRef
cf( m_faceName
, wxLocale::GetSystemEncoding() );
1034 ATSFontFamilyRef atsfamily
= ATSFontFamilyFindFromName( cf
, kATSOptionFlagsDefault
);
1035 if ( atsfamily
== (ATSFontFamilyRef
) -1 )
1037 wxLogDebug( wxT("ATSFontFamilyFindFromName failed for ") + m_faceName
);
1038 m_qdFontFamily
= GetAppFont();
1042 m_qdFontFamily
= FMGetFontFamilyFromATSFontFamilyRef( atsfamily
);
1046 if (m_weight
== wxFONTWEIGHT_BOLD
)
1047 m_qdFontStyle
|= bold
;
1048 if (m_style
== wxFONTSTYLE_ITALIC
|| m_style
== wxFONTSTYLE_SLANT
)
1049 m_qdFontStyle
|= italic
;
1051 m_qdFontStyle
|= underline
;
1054 // we try to get as much styles as possible into ATSU
1056 // ATSUFontID and FMFont are equivalent
1057 FMFontStyle intrinsicStyle
= 0 ;
1058 OSStatus status
= FMGetFontFromFontFamilyInstance( m_qdFontFamily
, m_qdFontStyle
, (FMFont
*)&m_atsuFontID
, &intrinsicStyle
);
1059 if ( status
!= noErr
)
1061 wxFAIL_MSG( wxT("couldn't get an ATSUFont from font family") );
1063 m_atsuAdditionalQDStyles
= m_qdFontStyle
& (~intrinsicStyle
);
1064 m_atsuFontValid
= true;
1068 if ( m_nsFontDescriptor
== NULL
)
1069 OSXValidateNSFontDescriptor();
1071 #if wxOSX_USE_IPHONE
1074 m_descriptorValid
= true;
1077 void wxNativeFontInfo::Init(const wxNativeFontInfo
& info
)
1080 #if wxOSX_USE_CORE_TEXT
1081 m_ctFontDescriptor
= wxCFRetain(info
.m_ctFontDescriptor
);
1083 #if wxOSX_USE_ATSU_TEXT
1084 m_atsuFontValid
= info
.m_atsuFontValid
;
1085 m_atsuFontID
= info
.m_atsuFontID
;
1086 m_atsuAdditionalQDStyles
= info
.m_atsuAdditionalQDStyles
;
1087 #if wxOSX_USE_CARBON
1088 m_qdFontFamily
= info
.m_qdFontFamily
;
1089 m_qdFontStyle
= info
.m_qdFontStyle
;
1093 m_nsFontDescriptor
= (NSFontDescriptor
*) wxMacCocoaRetain(info
.m_nsFontDescriptor
);
1095 m_pointSize
= info
.m_pointSize
;
1096 m_family
= info
.m_family
;
1097 m_style
= info
.m_style
;
1098 m_weight
= info
.m_weight
;
1099 m_underlined
= info
.m_underlined
;
1100 m_faceName
= info
.m_faceName
;
1101 m_encoding
= info
.m_encoding
;
1102 m_descriptorValid
= info
.m_descriptorValid
;
1105 void wxNativeFontInfo::Init(int size
,
1106 wxFontFamily family
,
1108 wxFontWeight weight
,
1110 const wxString
& faceName
,
1111 wxFontEncoding encoding
)
1118 m_underlined
= underlined
;
1119 m_faceName
= faceName
;
1120 if ( encoding
== wxFONTENCODING_DEFAULT
)
1121 encoding
= wxFont::GetDefaultEncoding();
1122 m_encoding
= encoding
;
1126 void wxNativeFontInfo::Free()
1128 #if wxOSX_USE_CORE_TEXT
1129 wxCFRelease(m_ctFontDescriptor
);
1130 m_ctFontDescriptor
= NULL
;
1132 #if wxOSX_USE_ATSU_TEXT
1134 m_atsuAdditionalQDStyles
= 0;
1135 m_atsuFontValid
= false;
1138 wxMacCocoaRelease(m_nsFontDescriptor
);
1139 m_nsFontDescriptor
= NULL
;
1141 m_descriptorValid
= false;
1144 bool wxNativeFontInfo::FromString(const wxString
& s
)
1148 wxStringTokenizer
tokenizer(s
, wxT(";"));
1150 wxString token
= tokenizer
.GetNextToken();
1152 // Ignore the version for now
1155 token
= tokenizer
.GetNextToken();
1156 if ( !token
.ToLong(&l
) )
1158 m_pointSize
= (int)l
;
1160 token
= tokenizer
.GetNextToken();
1161 if ( !token
.ToLong(&l
) )
1163 m_family
= (wxFontFamily
)l
;
1165 token
= tokenizer
.GetNextToken();
1166 if ( !token
.ToLong(&l
) )
1168 m_style
= (wxFontStyle
)l
;
1170 token
= tokenizer
.GetNextToken();
1171 if ( !token
.ToLong(&l
) )
1173 m_weight
= (wxFontWeight
)l
;
1175 token
= tokenizer
.GetNextToken();
1176 if ( !token
.ToLong(&l
) )
1178 m_underlined
= l
!= 0;
1180 m_faceName
= tokenizer
.GetNextToken();
1187 token
= tokenizer
.GetNextToken();
1188 if ( !token
.ToLong(&l
) )
1190 m_encoding
= (wxFontEncoding
)l
;
1195 wxString
wxNativeFontInfo::ToString() const
1199 s
.Printf(wxT("%d;%d;%d;%d;%d;%d;%s;%d"),
1206 m_faceName
.GetData(),
1212 int wxNativeFontInfo::GetPointSize() const
1217 wxFontStyle
wxNativeFontInfo::GetStyle() const
1222 wxFontWeight
wxNativeFontInfo::GetWeight() const
1227 bool wxNativeFontInfo::GetUnderlined() const
1229 return m_underlined
;
1232 wxString
wxNativeFontInfo::GetFaceName() const
1237 wxFontFamily
wxNativeFontInfo::GetFamily() const
1242 wxFontEncoding
wxNativeFontInfo::GetEncoding() const
1247 // changing the font descriptor
1249 void wxNativeFontInfo::SetPointSize(int pointsize
)
1251 if ( m_pointSize
!= pointsize
)
1253 m_pointSize
= pointsize
;
1258 void wxNativeFontInfo::SetStyle(wxFontStyle style_
)
1260 if ( m_style
!= style_
)
1267 void wxNativeFontInfo::SetWeight(wxFontWeight weight_
)
1269 if ( m_weight
!= weight_
)
1276 void wxNativeFontInfo::SetUnderlined(bool underlined_
)
1278 if ( m_underlined
!= underlined_
)
1280 m_underlined
= underlined_
;
1285 bool wxNativeFontInfo::SetFaceName(const wxString
& facename_
)
1287 if ( m_faceName
!= facename_
)
1289 m_faceName
= facename_
;
1295 void wxNativeFontInfo::SetFamily(wxFontFamily family_
)
1297 if ( m_family
!= family_
)
1304 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_
)
1306 if ( encoding_
== wxFONTENCODING_DEFAULT
)
1307 encoding_
= wxFont::GetDefaultEncoding();
1308 m_encoding
= encoding_
;
1309 // not reflected in native descriptors