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"
31 #if wxOSX_USE_ATSU_TEXT && !wxOSX_USE_CARBON
32 // include themeing support
33 #include <Carbon/Carbon.h>
39 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
)
41 class WXDLLEXPORT wxFontRefData
: public wxGDIRefData
48 m_info
.Init(10, wxFONTFAMILY_DEFAULT
, wxFONTSTYLE_NORMAL
, wxFONTWEIGHT_NORMAL
,
49 false, wxEmptyString
, wxFONTENCODING_DEFAULT
);
52 wxFontRefData(const wxFontRefData
& data
);
54 wxFontRefData( const wxNativeFontInfo
& info
) : m_info(info
)
59 wxFontRefData(wxOSXSystemFont font
, int size
);
61 #if wxOSX_USE_CORE_TEXT
62 wxFontRefData( wxUint32 coreTextFontType
);
63 wxFontRefData( CTFontRef font
);
64 wxFontRefData( CTFontDescriptorRef fontdescriptor
, int size
);
67 virtual ~wxFontRefData();
69 void SetNoAntiAliasing( bool no
= true ) { m_noAA
= no
; }
71 bool GetNoAntiAliasing() const { return m_noAA
; }
73 void SetPointSize( int size
)
75 if( GetPointSize() != size
)
77 m_info
.SetPointSize(size
);
82 int GetPointSize() const { return m_info
.GetPointSize(); }
84 void SetFamily( wxFontFamily family
)
86 if ( m_info
.m_family
!= family
)
88 m_info
.SetFamily( family
);
93 wxFontFamily
GetFamily() const { return m_info
.GetFamily(); }
95 void SetStyle( wxFontStyle style
)
97 if ( m_info
.m_style
!= style
)
99 m_info
.SetStyle( style
);
105 wxFontStyle
GetStyle() const { return m_info
.GetStyle(); }
107 void SetWeight( wxFontWeight weight
)
109 if ( m_info
.m_weight
!= weight
)
111 m_info
.SetWeight( weight
);
117 wxFontWeight
GetWeight() const { return m_info
.GetWeight(); }
119 void SetUnderlined( bool u
)
121 if ( m_info
.m_underlined
!= u
)
123 m_info
.SetUnderlined( u
);
128 bool GetUnderlined() const { return m_info
.GetUnderlined(); }
130 void SetFaceName( const wxString
& facename
)
132 if ( m_info
.m_faceName
!= facename
)
134 m_info
.SetFaceName( facename
);
139 wxString
GetFaceName() const { return m_info
.GetFaceName(); }
141 void SetEncoding( wxFontEncoding encoding
)
143 if ( m_info
.m_encoding
!= encoding
)
145 m_info
.SetEncoding( encoding
);
150 wxFontEncoding
GetEncoding() const { return m_info
.GetEncoding(); }
157 // common part of all ctors
159 #if wxOSX_USE_CORE_TEXT
160 // void Init( CTFontRef font );
162 bool m_noAA
; // No anti-aliasing
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
;
170 #if wxOSX_USE_CORE_TEXT
171 wxCFRef
<CTFontRef
> m_ctFont
;
173 #if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
174 ATSUStyle m_macATSUStyle
;
182 wxNativeFontInfo m_info
;
185 #define M_FONTDATA ((wxFontRefData*)m_refData)
187 wxFontRefData::wxFontRefData(const wxFontRefData
& data
)
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
;
196 #if wxOSX_USE_CORE_TEXT
197 m_ctFont
= data
.m_ctFont
;
199 #if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
200 if ( data
.m_macATSUStyle
!= NULL
)
202 ATSUCreateStyle(&m_macATSUStyle
) ;
203 ATSUCopyAttributes(data
.m_macATSUStyle
, m_macATSUStyle
);
207 m_nsFont
= (NSFont
*) wxMacCocoaRetain(data
.m_nsFont
);
210 m_uiFont
= wxMacCocoaRetain(data
.m_uiFont
);
215 // ============================================================================
217 // ============================================================================
219 // ----------------------------------------------------------------------------
221 // ----------------------------------------------------------------------------
223 void wxFontRefData::Init()
226 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
227 m_macThemeFontID
= kThemeCurrentPortFont
;
229 #if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
230 m_macATSUStyle
= NULL
;
241 wxFontRefData::~wxFontRefData()
246 void wxFontRefData::Free()
248 #if wxOSX_USE_CORE_TEXT
251 #if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
252 if ( m_macATSUStyle
)
254 ::ATSUDisposeStyle((ATSUStyle
)m_macATSUStyle
);
255 m_macATSUStyle
= NULL
;
259 if (m_nsFont
!= NULL
)
261 wxMacCocoaRelease(m_nsFont
);
266 if (m_uiFont
!= NULL
)
268 wxMacCocoaRelease(m_uiFont
);
275 wxFontRefData::wxFontRefData(wxOSXSystemFont font
, int size
)
277 wxASSERT( font
!= wxOSX_SYSTEM_FONT_NONE
);
280 #if wxOSX_USE_CORE_TEXT
281 if ( UMAGetSystemVersion() >= 0x1050 )
283 CTFontUIFontType uifont
;
286 case wxOSX_SYSTEM_FONT_NORMAL
:
287 uifont
= kCTFontSystemFontType
;
289 case wxOSX_SYSTEM_FONT_BOLD
:
290 uifont
= kCTFontEmphasizedSystemFontType
;
292 case wxOSX_SYSTEM_FONT_SMALL
:
293 uifont
= kCTFontSmallSystemFontType
;
295 case wxOSX_SYSTEM_FONT_SMALL_BOLD
:
296 uifont
= kCTFontSmallEmphasizedSystemFontType
;
298 case wxOSX_SYSTEM_FONT_MINI
:
299 uifont
= kCTFontMiniSystemFontType
;
301 case wxOSX_SYSTEM_FONT_MINI_BOLD
:
302 uifont
= kCTFontMiniEmphasizedSystemFontType
;
304 case wxOSX_SYSTEM_FONT_LABELS
:
305 uifont
= kCTFontLabelFontType
;
307 case wxOSX_SYSTEM_FONT_VIEWS
:
308 uifont
= kCTFontViewsFontType
;
313 m_ctFont
.reset(CTFontCreateUIFontForLanguage( uifont
, (CGFloat
) size
, NULL
));
314 wxCFRef
<CTFontDescriptorRef
> descr
;
315 descr
.reset( CTFontCopyFontDescriptor( m_ctFont
) );
319 #if wxOSX_USE_ATSU_TEXT
321 #if !wxOSX_USE_CARBON
322 // not needed outside
323 ThemeFontID m_macThemeFontID
;
327 case wxOSX_SYSTEM_FONT_NORMAL
:
328 m_macThemeFontID
= kThemeSystemFont
;
330 case wxOSX_SYSTEM_FONT_BOLD
:
331 m_macThemeFontID
= kThemeEmphasizedSystemFont
;
333 case wxOSX_SYSTEM_FONT_SMALL
:
334 m_macThemeFontID
= kThemeSmallSystemFont
;
336 case wxOSX_SYSTEM_FONT_SMALL_BOLD
:
337 m_macThemeFontID
= kThemeSmallEmphasizedSystemFont
;
339 case wxOSX_SYSTEM_FONT_MINI
:
340 m_macThemeFontID
= kThemeMiniSystemFont
;
342 case wxOSX_SYSTEM_FONT_MINI_BOLD
:
343 // bold not available under themeing
344 m_macThemeFontID
= kThemeMiniSystemFont
;
346 case wxOSX_SYSTEM_FONT_LABELS
:
347 m_macThemeFontID
= kThemeLabelFont
;
349 case wxOSX_SYSTEM_FONT_VIEWS
:
350 m_macThemeFontID
= kThemeViewsFont
;
355 if ( m_info
.m_faceName
.empty() )
361 GetThemeFont( m_macThemeFontID
, GetApplicationScript(), qdFontName
, &fontSize
, &style
);
365 wxFontStyle fontstyle
= wxFONTSTYLE_NORMAL
;
366 wxFontWeight fontweight
= wxFONTWEIGHT_NORMAL
;
367 bool underlined
= false;
370 fontweight
= wxFONTWEIGHT_BOLD
;
372 fontweight
= wxFONTWEIGHT_NORMAL
;
373 if ( style
& italic
)
374 fontstyle
= wxFONTSTYLE_ITALIC
;
375 if ( style
& underline
)
378 m_info
.Init(size
,wxFONTFAMILY_DEFAULT
,fontstyle
,fontweight
,underlined
,
379 wxMacMakeStringFromPascal( qdFontName
), wxFONTENCODING_DEFAULT
);
384 m_nsFont
= wxFont::CreateNSFont( font
, &m_info
);
387 m_uiFont
= wxFont::CreateUIFont( font
, &m_info
);
391 void wxFontRefData::MacFindFont()
396 m_info
.EnsureValid();
398 #if wxOSX_USE_CORE_TEXT
399 if ( UMAGetSystemVersion() >= 0x1050 )
401 CTFontSymbolicTraits traits
= 0;
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
;
409 wxString lookupnameWithSize
= wxString::Format( "%s_%ld_%ld", m_info
.m_faceName
.c_str(), traits
, m_info
.m_pointSize
);
411 static std::map
< std::wstring
, wxCFRef
< CTFontRef
> > fontcache
;
412 m_ctFont
= fontcache
[ std::wstring(lookupnameWithSize
.wc_str()) ];
415 m_ctFont
.reset( CTFontCreateWithFontDescriptor( m_info
.m_ctFontDescriptor
, 0/*m_pointSize */, NULL
) );
420 #if wxOSX_USE_ATSU_TEXT
422 // we try to get as much styles as possible into ATSU
424 OSStatus status
= ::ATSUCreateStyle(&m_macATSUStyle
);
425 wxASSERT_MSG( status
== noErr
, wxT("couldn't create ATSU style") );
427 ATSUAttributeTag atsuTags
[] =
431 kATSUVerticalCharacterTag
,
434 kATSUQDUnderlineTag
,
435 kATSUQDCondensedTag
,
438 ByteCount atsuSizes
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] =
440 sizeof( ATSUFontID
) ,
442 sizeof( ATSUVerticalCharacterType
),
450 Boolean kTrue
= true ;
451 Boolean kFalse
= false ;
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
)] =
458 &m_info
.m_atsuFontID
,
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
,
468 status
= ::ATSUSetAttributes(
469 (ATSUStyle
)m_macATSUStyle
,
470 sizeof(atsuTags
) / sizeof(ATSUAttributeTag
) ,
471 atsuTags
, atsuSizes
, atsuValues
);
473 wxASSERT_MSG( status
== noErr
, wxT("couldn't modify ATSU style") );
478 m_nsFont
= wxFont::CreateNSFont( &m_info
);
481 m_uiFont
= wxFont::CreateUIFont( &m_info
);
486 // ----------------------------------------------------------------------------
488 // ----------------------------------------------------------------------------
490 bool wxFont::Create(const wxNativeFontInfo
& info
)
494 m_refData
= new wxFontRefData( info
);
500 wxFont::wxFont(const wxString
& fontdesc
)
502 wxNativeFontInfo info
;
503 if ( info
.FromString(fontdesc
) )
507 bool wxFont::Create(int pointSize
,
512 const wxString
& faceNameParam
,
513 wxFontEncoding encoding
)
517 wxString faceName
= faceNameParam
;
519 if ( faceName
.empty() )
523 case wxFONTFAMILY_DEFAULT
:
524 faceName
= wxT("Lucida Grande");
527 case wxFONTFAMILY_SCRIPT
:
528 case wxFONTFAMILY_ROMAN
:
529 case wxFONTFAMILY_DECORATIVE
:
530 faceName
= wxT("Times");
533 case wxFONTFAMILY_SWISS
:
534 faceName
= wxT("Helvetica");
537 case wxFONTFAMILY_MODERN
:
538 case wxFONTFAMILY_TELETYPE
:
539 faceName
= wxT("Courier");
543 faceName
= wxT("Times");
548 wxNativeFontInfo info
;
550 info
.Init(pointSize
, family
, style
, weight
,
551 underlined
, faceName
, encoding
);
553 m_refData
= new wxFontRefData(info
);
558 bool wxFont::CreateSystemFont(wxOSXSystemFont font
)
562 m_refData
= new wxFontRefData( font
, 0 );
571 bool wxFont::RealizeResource()
573 M_FONTDATA
->MacFindFont();
578 void wxFont::SetEncoding(wxFontEncoding encoding
)
582 M_FONTDATA
->SetEncoding( encoding
);
585 wxGDIRefData
*wxFont::CreateGDIRefData() const
587 return new wxFontRefData
;
590 wxGDIRefData
*wxFont::CloneGDIRefData(const wxGDIRefData
*data
) const
592 return new wxFontRefData(*static_cast<const wxFontRefData
*>(data
));
595 void wxFont::SetPointSize(int pointSize
)
597 if ( M_FONTDATA
->GetPointSize() == pointSize
)
602 M_FONTDATA
->SetPointSize( pointSize
);
605 void wxFont::SetFamily(wxFontFamily family
)
609 M_FONTDATA
->SetFamily( family
);
612 void wxFont::SetStyle(wxFontStyle style
)
616 M_FONTDATA
->SetStyle( style
);
619 void wxFont::SetWeight(wxFontWeight weight
)
623 M_FONTDATA
->SetWeight( weight
);
626 bool wxFont::SetFaceName(const wxString
& faceName
)
630 M_FONTDATA
->SetFaceName( faceName
);
632 return wxFontBase::SetFaceName(faceName
);
635 void wxFont::SetUnderlined(bool underlined
)
639 M_FONTDATA
->SetUnderlined( underlined
);
642 void wxFont::SetNoAntiAliasing( bool no
)
646 M_FONTDATA
->SetNoAntiAliasing( no
);
649 // ----------------------------------------------------------------------------
651 // ----------------------------------------------------------------------------
653 // TODO: insert checks everywhere for M_FONTDATA == NULL!
655 int wxFont::GetPointSize() const
657 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
659 return M_FONTDATA
->GetPointSize();
662 wxSize
wxFont::GetPixelSize() const
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
);
671 return wxSize((int)width
, (int)height
);
673 return wxFontBase::GetPixelSize();
677 wxFontFamily
wxFont::GetFamily() const
679 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTFAMILY_MAX
, wxT("invalid font") );
681 return M_FONTDATA
->GetFamily();
684 wxFontStyle
wxFont::GetStyle() const
686 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTSTYLE_MAX
, wxT("invalid font") );
688 return M_FONTDATA
->GetStyle() ;
691 wxFontWeight
wxFont::GetWeight() const
693 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTWEIGHT_MAX
, wxT("invalid font") );
695 return M_FONTDATA
->GetWeight();
698 bool wxFont::GetUnderlined() const
700 wxCHECK_MSG( M_FONTDATA
!= NULL
, false, wxT("invalid font") );
702 return M_FONTDATA
->GetUnderlined();
705 wxString
wxFont::GetFaceName() const
707 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxEmptyString
, wxT("invalid font") );
709 return M_FONTDATA
->GetFaceName() ;
712 wxFontEncoding
wxFont::GetEncoding() const
714 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTENCODING_DEFAULT
, wxT("invalid font") );
716 return M_FONTDATA
->GetEncoding() ;
719 bool wxFont::GetNoAntiAliasing() const
721 wxCHECK_MSG( M_FONTDATA
!= NULL
, false, wxT("invalid font") );
723 return M_FONTDATA
->GetNoAntiAliasing();
726 #if wxOSX_USE_ATSU_TEXT && wxOSX_USE_CARBON
728 short wxFont::MacGetFontNum() const
730 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
732 // cast away constness otherwise lazy font resolution is not possible
733 const_cast<wxFont
*>(this)->RealizeResource();
735 return M_FONTDATA
->m_info
.m_qdFontFamily
;
738 wxByte
wxFont::MacGetFontStyle() const
740 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
742 // cast away constness otherwise lazy font resolution is not possible
743 const_cast<wxFont
*>(this)->RealizeResource();
745 return M_FONTDATA
->m_info
.m_qdFontStyle
;
748 wxUint16
wxFont::MacGetThemeFontID() const
750 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
752 return M_FONTDATA
->m_macThemeFontID
;
757 #if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
758 void * wxFont::MacGetATSUStyle() const
760 wxCHECK_MSG( M_FONTDATA
!= NULL
, NULL
, wxT("invalid font") );
762 // cast away constness otherwise lazy font resolution is not possible
763 const_cast<wxFont
*>(this)->RealizeResource();
765 return M_FONTDATA
->m_macATSUStyle
;
769 #if wxOSX_USE_CORE_TEXT
771 CTFontRef
wxFont::GetCTFont() const
773 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
775 // cast away constness otherwise lazy font resolution is not possible
776 const_cast<wxFont
*>(this)->RealizeResource();
778 return (CTFontRef
)(M_FONTDATA
->m_ctFont
);
785 NSFont
* wxFont::GetNSFont() const
787 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
789 // cast away constness otherwise lazy font resolution is not possible
790 const_cast<wxFont
*>(this)->RealizeResource();
792 return (M_FONTDATA
->m_nsFont
);
797 const wxNativeFontInfo
* wxFont::GetNativeFontInfo() const
799 wxCHECK_MSG( M_FONTDATA
!= NULL
, NULL
, wxT("invalid font") );
800 wxCHECK_MSG( Ok(), NULL
, wxT("invalid font") );
802 // cast away constness otherwise lazy font resolution is not possible
803 const_cast<wxFont
*>(this)->RealizeResource();
805 // M_FONTDATA->m_info.InitFromFont(*this);
807 return &(M_FONTDATA
->m_info
);
810 // ----------------------------------------------------------------------------
812 // ----------------------------------------------------------------------------
814 #if wxOSX_USE_CORE_TEXT
816 /* from Core Text Manual Common Operations */
818 static CTFontDescriptorRef
wxMacCreateCTFontDescriptor(CFStringRef iFamilyName
, CTFontSymbolicTraits iTraits
)
820 CTFontDescriptorRef descriptor
= NULL
;
821 CFMutableDictionaryRef attributes
;
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
);
829 if (attributes
!= NULL
) {
830 // Add a family name to our attributes.
831 CFDictionaryAddValue(attributes
, kCTFontFamilyNameAttribute
, iFamilyName
);
835 CFMutableDictionaryRef traits
;
836 CFNumberRef symTraits
;
838 // Create the traits dictionary.
839 symTraits
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
841 check(symTraits
!= NULL
);
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
);
849 if (traits
!= NULL
) {
850 // Add the symbolic traits value to the traits dictionary.
851 CFDictionaryAddValue(traits
, kCTFontSymbolicTrait
, symTraits
);
853 // Add the traits attribute to our attributes.
854 CFDictionaryAddValue(attributes
, kCTFontTraitsAttribute
, traits
);
857 CFRelease(symTraits
);
860 // Create the font descriptor with our attributes
861 descriptor
= CTFontDescriptorCreateWithAttributes(attributes
);
862 check(descriptor
!= NULL
);
864 CFRelease(attributes
);
866 // Return our font descriptor.
872 void wxNativeFontInfo::Init()
874 #if wxOSX_USE_CORE_TEXT
875 m_ctFontDescriptor
= NULL
;
877 #if wxOSX_USE_ATSU_TEXT
879 m_atsuAdditionalQDStyles
= 0;
880 m_atsuFontValid
= false;
887 m_nsFontDescriptor
= NULL
;
890 m_uiFontDescriptor
= NULL
;
893 m_family
= wxFONTFAMILY_DEFAULT
;
894 m_style
= wxFONTSTYLE_NORMAL
;
895 m_weight
= wxFONTWEIGHT_NORMAL
;
896 m_underlined
= false;
898 m_encoding
= wxFONTENCODING_DEFAULT
;
899 m_descriptorValid
= false;
902 #if wxOSX_USE_CORE_TEXT
903 void wxNativeFontInfo::Init(CTFontDescriptorRef descr
)
906 m_ctFontDescriptor
= wxCFRetain(descr
);
908 wxCFRef
< CFNumberRef
> sizevalue( (CFNumberRef
) CTFontDescriptorCopyAttribute( m_ctFontDescriptor
, kCTFontSizeAttribute
) );
910 if ( CFNumberGetValue( sizevalue
, kCFNumberFloatType
, &fsize
) )
911 m_pointSize
= (int)( fsize
+ 0.5 );
913 wxCFRef
< CFDictionaryRef
> traitsvalue( (CFDictionaryRef
) CTFontDescriptorCopyAttribute( m_ctFontDescriptor
, kCTFontTraitsAttribute
) );
914 CTFontSymbolicTraits traits
;
915 if ( CFNumberGetValue((CFNumberRef
) CFDictionaryGetValue(traitsvalue
,kCTFontSymbolicTrait
),kCFNumberIntType
,&traits
) )
917 if ( traits
& kCTFontItalicTrait
)
918 m_style
= wxFONTSTYLE_ITALIC
;
919 if ( traits
& kCTFontBoldTrait
)
920 m_weight
= wxFONTWEIGHT_BOLD
;
923 wxCFStringRef
familyName( (CFStringRef
) CTFontDescriptorCopyAttribute(m_ctFontDescriptor
, kCTFontFamilyNameAttribute
));
924 m_faceName
= familyName
.AsString();
928 void wxNativeFontInfo::EnsureValid()
930 if ( m_descriptorValid
)
933 #if wxOSX_USE_CORE_TEXT
934 if ( m_ctFontDescriptor
== NULL
&& UMAGetSystemVersion() >= 0x1050 )
936 CTFontSymbolicTraits traits
= 0;
938 if (m_weight
== wxFONTWEIGHT_BOLD
)
939 traits
|= kCTFontBoldTrait
;
940 if (m_style
== wxFONTSTYLE_ITALIC
|| m_style
== wxFONTSTYLE_SLANT
)
941 traits
|= kCTFontItalicTrait
;
944 wxString lookupnameWithSize
= wxString::Format( "%s_%ld_%ld", m_faceName
.c_str(), traits
, m_pointSize
);
946 static std::map
< std::wstring
, wxCFRef
< CTFontDescriptorRef
> > fontdescriptorcache
;
947 m_ctFontDescriptor
= wxCFRetain((CTFontDescriptorRef
)fontdescriptorcache
[ std::wstring(lookupnameWithSize
.wc_str()) ]);
948 if ( !m_ctFontDescriptor
)
950 // QD selection algorithm is the fastest by orders of magnitude on 10.5
951 if ( m_faceName
.IsAscii() )
954 if (m_weight
== wxFONTWEIGHT_BOLD
)
956 if (m_style
== wxFONTSTYLE_ITALIC
|| m_style
== wxFONTSTYLE_SLANT
)
960 wxMacStringToPascal( m_faceName
, qdFontName
);
961 wxCFRef
< CTFontRef
> font
;
962 font
.reset( CTFontCreateWithQuickdrawInstance(qdFontName
, 0 , qdstyle
, m_pointSize
) );
963 m_ctFontDescriptor
= CTFontCopyFontDescriptor(font
);
967 m_ctFontDescriptor
= wxMacCreateCTFontDescriptor( wxCFStringRef(m_faceName
),traits
);
969 fontdescriptorcache
[ std::wstring(lookupnameWithSize
.wc_str()) ].reset(wxCFRetain(m_ctFontDescriptor
));
973 #if wxOSX_USE_ATSU_TEXT
974 if ( !m_atsuFontValid
)
976 #if !wxOSX_USE_CARBON
977 // not needed outside
978 wxInt16 m_qdFontFamily
;
979 wxInt16 m_qdFontStyle
;
981 wxCFStringRef
cf( m_faceName
, wxLocale::GetSystemEncoding() );
982 ATSFontFamilyRef atsfamily
= ATSFontFamilyFindFromName( cf
, kATSOptionFlagsDefault
);
983 if ( atsfamily
== (ATSFontFamilyRef
) -1 )
985 wxLogDebug( wxT("ATSFontFamilyFindFromName failed for ") + m_faceName
);
986 m_qdFontFamily
= GetAppFont();
990 m_qdFontFamily
= FMGetFontFamilyFromATSFontFamilyRef( atsfamily
);
994 if (m_weight
== wxFONTWEIGHT_BOLD
)
995 m_qdFontStyle
|= bold
;
996 if (m_style
== wxFONTSTYLE_ITALIC
|| m_style
== wxFONTSTYLE_SLANT
)
997 m_qdFontStyle
|= italic
;
999 m_qdFontStyle
|= underline
;
1002 // we try to get as much styles as possible into ATSU
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;
1013 if ( m_nsFontDescriptor
== NULL
)
1014 ValidateNSFontDescriptor();
1016 #if wxOSX_USE_IPHONE
1019 m_descriptorValid
= true;
1022 void wxNativeFontInfo::Init(const wxNativeFontInfo
& info
)
1025 #if wxOSX_USE_CORE_TEXT
1026 m_ctFontDescriptor
= wxCFRetain(info
.m_ctFontDescriptor
);
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
;
1038 m_nsFontDescriptor
= (NSFontDescriptor
*) wxMacCocoaRetain(info
.m_nsFontDescriptor
);
1040 #if wxOSX_USE_IPHONE
1041 m_uiFontDescriptor
= wxMacCocoaRetain(info
.m_uiFontDescriptor
);;
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
;
1053 void wxNativeFontInfo::Init(int size
,
1054 wxFontFamily family
,
1056 wxFontWeight weight
,
1058 const wxString
& faceName
,
1059 wxFontEncoding encoding
)
1066 m_underlined
= underlined
;
1067 m_faceName
= faceName
;
1068 m_encoding
= encoding
;
1072 void wxNativeFontInfo::Free()
1074 #if wxOSX_USE_CORE_TEXT
1075 wxCFRelease(m_ctFontDescriptor
);
1076 m_ctFontDescriptor
= NULL
;
1078 #if wxOSX_USE_ATSU_TEXT
1080 m_atsuAdditionalQDStyles
= 0;
1081 m_atsuFontValid
= false;
1084 wxMacCocoaRelease(m_nsFontDescriptor
);
1085 m_nsFontDescriptor
= NULL
;
1087 #if wxOSX_USE_IPHONE
1088 wxMacCocoaRelease(m_uiFontDescriptor
);
1089 m_uiFontDescriptor
= NULL
1091 m_descriptorValid
= false;
1094 bool wxNativeFontInfo::FromString(const wxString
& s
)
1098 wxStringTokenizer
tokenizer(s
, _T(";"));
1100 wxString token
= tokenizer
.GetNextToken();
1102 // Ignore the version for now
1105 token
= tokenizer
.GetNextToken();
1106 if ( !token
.ToLong(&l
) )
1108 m_pointSize
= (int)l
;
1110 token
= tokenizer
.GetNextToken();
1111 if ( !token
.ToLong(&l
) )
1113 m_family
= (wxFontFamily
)l
;
1115 token
= tokenizer
.GetNextToken();
1116 if ( !token
.ToLong(&l
) )
1118 m_style
= (wxFontStyle
)l
;
1120 token
= tokenizer
.GetNextToken();
1121 if ( !token
.ToLong(&l
) )
1123 m_weight
= (wxFontWeight
)l
;
1125 token
= tokenizer
.GetNextToken();
1126 if ( !token
.ToLong(&l
) )
1128 m_underlined
= l
!= 0;
1130 m_faceName
= tokenizer
.GetNextToken();
1137 token
= tokenizer
.GetNextToken();
1138 if ( !token
.ToLong(&l
) )
1140 m_encoding
= (wxFontEncoding
)l
;
1145 wxString
wxNativeFontInfo::ToString() const
1149 s
.Printf(_T("%d;%d;%d;%d;%d;%d;%s;%d"),
1156 m_faceName
.GetData(),
1162 int wxNativeFontInfo::GetPointSize() const
1167 wxFontStyle
wxNativeFontInfo::GetStyle() const
1172 wxFontWeight
wxNativeFontInfo::GetWeight() const
1177 bool wxNativeFontInfo::GetUnderlined() const
1179 return m_underlined
;
1182 wxString
wxNativeFontInfo::GetFaceName() const
1187 wxFontFamily
wxNativeFontInfo::GetFamily() const
1192 wxFontEncoding
wxNativeFontInfo::GetEncoding() const
1197 // changing the font descriptor
1199 void wxNativeFontInfo::SetPointSize(int pointsize
)
1201 if ( m_pointSize
!= pointsize
)
1203 m_pointSize
= pointsize
;
1208 void wxNativeFontInfo::SetStyle(wxFontStyle style_
)
1210 if ( m_style
!= style_
)
1217 void wxNativeFontInfo::SetWeight(wxFontWeight weight_
)
1219 if ( m_weight
!= weight_
)
1226 void wxNativeFontInfo::SetUnderlined(bool underlined_
)
1228 if ( m_underlined
!= underlined_
)
1230 m_underlined
= underlined_
;
1235 bool wxNativeFontInfo::SetFaceName(const wxString
& facename_
)
1237 if ( m_faceName
!= facename_
)
1239 m_faceName
= facename_
;
1245 void wxNativeFontInfo::SetFamily(wxFontFamily family_
)
1247 if ( m_family
!= family_
)
1254 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_
)
1256 m_encoding
= encoding_
;
1257 // not reflected in native descriptors