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_ATSU_TEXT
174 ATSUStyle m_macATSUStyle
;
176 wxCFRef
<CGFontRef
> m_cgFont
;
183 wxNativeFontInfo m_info
;
186 #define M_FONTDATA ((wxFontRefData*)m_refData)
188 wxFontRefData::wxFontRefData(const wxFontRefData
& data
)
191 m_info
= data
.m_info
;
192 m_noAA
= data
.m_noAA
;
193 m_fontValid
= data
.m_fontValid
;
194 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
195 m_macThemeFontID
= data
.m_macThemeFontID
;
197 #if wxOSX_USE_CORE_TEXT
198 m_ctFont
= data
.m_ctFont
;
200 m_cgFont
= data
.m_cgFont
;
201 #if wxOSX_USE_ATSU_TEXT
202 if ( data
.m_macATSUStyle
!= NULL
)
204 ATSUCreateStyle(&m_macATSUStyle
) ;
205 ATSUCopyAttributes(data
.m_macATSUStyle
, m_macATSUStyle
);
209 m_nsFont
= (NSFont
*) wxMacCocoaRetain(data
.m_nsFont
);
212 m_uiFont
= (UIFont
*) wxMacCocoaRetain(data
.m_uiFont
);
217 // ============================================================================
219 // ============================================================================
221 // ----------------------------------------------------------------------------
223 // ----------------------------------------------------------------------------
225 void wxFontRefData::Init()
228 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
229 m_macThemeFontID
= kThemeCurrentPortFont
;
231 #if wxOSX_USE_ATSU_TEXT
232 m_macATSUStyle
= NULL
;
243 wxFontRefData::~wxFontRefData()
248 void wxFontRefData::Free()
250 #if wxOSX_USE_CORE_TEXT
254 #if wxOSX_USE_ATSU_TEXT
256 m_macThemeFontID
= kThemeCurrentPortFont
;
258 if ( m_macATSUStyle
)
260 ::ATSUDisposeStyle((ATSUStyle
)m_macATSUStyle
);
261 m_macATSUStyle
= NULL
;
265 if (m_nsFont
!= NULL
)
267 wxMacCocoaRelease(m_nsFont
);
272 if (m_uiFont
!= NULL
)
274 wxMacCocoaRelease(m_uiFont
);
281 wxFontRefData::wxFontRefData(wxOSXSystemFont font
, int size
)
283 wxASSERT( font
!= wxOSX_SYSTEM_FONT_NONE
);
286 #if wxOSX_USE_CORE_TEXT
287 if ( UMAGetSystemVersion() >= 0x1050 )
289 CTFontUIFontType uifont
= kCTFontSystemFontType
;
292 case wxOSX_SYSTEM_FONT_NORMAL
:
293 uifont
= kCTFontSystemFontType
;
295 case wxOSX_SYSTEM_FONT_BOLD
:
296 uifont
= kCTFontEmphasizedSystemFontType
;
298 case wxOSX_SYSTEM_FONT_SMALL
:
299 uifont
= kCTFontSmallSystemFontType
;
301 case wxOSX_SYSTEM_FONT_SMALL_BOLD
:
302 uifont
= kCTFontSmallEmphasizedSystemFontType
;
304 case wxOSX_SYSTEM_FONT_MINI
:
305 uifont
= kCTFontMiniSystemFontType
;
307 case wxOSX_SYSTEM_FONT_MINI_BOLD
:
308 uifont
= kCTFontMiniEmphasizedSystemFontType
;
310 case wxOSX_SYSTEM_FONT_LABELS
:
311 uifont
= kCTFontLabelFontType
;
313 case wxOSX_SYSTEM_FONT_VIEWS
:
314 uifont
= kCTFontViewsFontType
;
319 m_ctFont
.reset(CTFontCreateUIFontForLanguage( uifont
, (CGFloat
) size
, NULL
));
320 wxCFRef
<CTFontDescriptorRef
> descr
;
321 descr
.reset( CTFontCopyFontDescriptor( m_ctFont
) );
325 #if wxOSX_USE_ATSU_TEXT
327 #if !wxOSX_USE_CARBON
328 // not needed outside
329 ThemeFontID m_macThemeFontID
= kThemeSystemFont
;
333 case wxOSX_SYSTEM_FONT_NORMAL
:
334 m_macThemeFontID
= kThemeSystemFont
;
336 case wxOSX_SYSTEM_FONT_BOLD
:
337 m_macThemeFontID
= kThemeEmphasizedSystemFont
;
339 case wxOSX_SYSTEM_FONT_SMALL
:
340 m_macThemeFontID
= kThemeSmallSystemFont
;
342 case wxOSX_SYSTEM_FONT_SMALL_BOLD
:
343 m_macThemeFontID
= kThemeSmallEmphasizedSystemFont
;
345 case wxOSX_SYSTEM_FONT_MINI
:
346 m_macThemeFontID
= kThemeMiniSystemFont
;
348 case wxOSX_SYSTEM_FONT_MINI_BOLD
:
349 // bold not available under themeing
350 m_macThemeFontID
= kThemeMiniSystemFont
;
352 case wxOSX_SYSTEM_FONT_LABELS
:
353 m_macThemeFontID
= kThemeLabelFont
;
355 case wxOSX_SYSTEM_FONT_VIEWS
:
356 m_macThemeFontID
= kThemeViewsFont
;
361 if ( m_info
.m_faceName
.empty() )
367 GetThemeFont( m_macThemeFontID
, GetApplicationScript(), qdFontName
, &fontSize
, &style
);
371 wxFontStyle fontstyle
= wxFONTSTYLE_NORMAL
;
372 wxFontWeight fontweight
= wxFONTWEIGHT_NORMAL
;
373 bool underlined
= false;
376 fontweight
= wxFONTWEIGHT_BOLD
;
378 fontweight
= wxFONTWEIGHT_NORMAL
;
379 if ( style
& italic
)
380 fontstyle
= wxFONTSTYLE_ITALIC
;
381 if ( style
& underline
)
384 m_info
.Init(fontSize
,wxFONTFAMILY_DEFAULT
,fontstyle
,fontweight
,underlined
,
385 wxMacMakeStringFromPascal( qdFontName
), wxFONTENCODING_DEFAULT
);
390 m_nsFont
= wxFont::OSXCreateNSFont( font
, &m_info
);
393 m_uiFont
= wxFont::OSXCreateUIFont( font
, &m_info
);
397 void wxFontRefData::MacFindFont()
402 m_info
.EnsureValid();
404 #if wxOSX_USE_CORE_TEXT
405 if ( UMAGetSystemVersion() >= 0x1050 )
407 CTFontSymbolicTraits traits
= 0;
409 if (m_info
.m_weight
== wxFONTWEIGHT_BOLD
)
410 traits
|= kCTFontBoldTrait
;
411 if (m_info
.m_style
== wxFONTSTYLE_ITALIC
|| m_info
.m_style
== wxFONTSTYLE_SLANT
)
412 traits
|= kCTFontItalicTrait
;
415 wxString lookupnameWithSize
= wxString::Format( "%s_%ld_%ld", m_info
.m_faceName
.c_str(), traits
, m_info
.m_pointSize
);
417 static std::map
< std::wstring
, wxCFRef
< CTFontRef
> > fontcache
;
418 m_ctFont
= fontcache
[ std::wstring(lookupnameWithSize
.wc_str()) ];
421 m_ctFont
.reset( CTFontCreateWithFontDescriptor( m_info
.m_ctFontDescriptor
, 0/*m_pointSize */, NULL
) );
423 m_cgFont
.reset(CTFontCopyGraphicsFont(m_ctFont
, NULL
));
427 #if wxOSX_USE_ATSU_TEXT
429 // we try to get as much styles as possible into ATSU
431 OSStatus status
= ::ATSUCreateStyle(&m_macATSUStyle
);
432 wxASSERT_MSG( status
== noErr
, wxT("couldn't create ATSU style") );
434 ATSUAttributeTag atsuTags
[] =
438 kATSUVerticalCharacterTag
,
441 kATSUQDUnderlineTag
,
442 kATSUQDCondensedTag
,
445 ByteCount atsuSizes
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] =
447 sizeof( ATSUFontID
) ,
449 sizeof( ATSUVerticalCharacterType
),
457 Boolean kTrue
= true ;
458 Boolean kFalse
= false ;
460 Fixed atsuSize
= IntToFixed( m_info
.m_pointSize
);
461 ATSUVerticalCharacterType kHorizontal
= kATSUStronglyHorizontal
;
462 FMFontStyle addQDStyle
= m_info
.m_atsuAdditionalQDStyles
;
463 ATSUAttributeValuePtr atsuValues
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] =
465 &m_info
.m_atsuFontID
,
468 (addQDStyle
& bold
) ? &kTrue
: &kFalse
,
469 (addQDStyle
& italic
) ? &kTrue
: &kFalse
,
470 (addQDStyle
& underline
) ? &kTrue
: &kFalse
,
471 (addQDStyle
& condense
) ? &kTrue
: &kFalse
,
472 (addQDStyle
& extend
) ? &kTrue
: &kFalse
,
475 status
= ::ATSUSetAttributes(
476 (ATSUStyle
)m_macATSUStyle
,
477 sizeof(atsuTags
) / sizeof(ATSUAttributeTag
) ,
478 atsuTags
, atsuSizes
, atsuValues
);
480 wxASSERT_MSG( status
== noErr
, wxT("couldn't modify ATSU style") );
481 if ( m_cgFont
.get() == NULL
)
483 ATSFontRef fontRef
= FMGetATSFontRefFromFont(m_info
.m_atsuFontID
);
484 m_cgFont
.reset( CGFontCreateWithPlatformFont( &fontRef
) );
489 m_nsFont
= wxFont::OSXCreateNSFont( &m_info
);
492 m_uiFont
= wxFont::OSXCreateUIFont( &m_info
);
497 // ----------------------------------------------------------------------------
499 // ----------------------------------------------------------------------------
501 bool wxFont::Create(const wxNativeFontInfo
& info
)
505 m_refData
= new wxFontRefData( info
);
511 wxFont::wxFont(const wxString
& fontdesc
)
513 wxNativeFontInfo info
;
514 if ( info
.FromString(fontdesc
) )
518 bool wxFont::Create(int pointSize
,
523 const wxString
& faceNameParam
,
524 wxFontEncoding encoding
)
528 wxString faceName
= faceNameParam
;
530 if ( faceName
.empty() )
534 case wxFONTFAMILY_DEFAULT
:
535 faceName
= wxT("Lucida Grande");
538 case wxFONTFAMILY_SCRIPT
:
539 case wxFONTFAMILY_ROMAN
:
540 case wxFONTFAMILY_DECORATIVE
:
541 faceName
= wxT("Times");
544 case wxFONTFAMILY_SWISS
:
545 faceName
= wxT("Helvetica");
548 case wxFONTFAMILY_MODERN
:
549 case wxFONTFAMILY_TELETYPE
:
550 faceName
= wxT("Courier");
554 faceName
= wxT("Times");
559 wxNativeFontInfo info
;
561 info
.Init(pointSize
, family
, style
, weight
,
562 underlined
, faceName
, encoding
);
564 m_refData
= new wxFontRefData(info
);
569 bool wxFont::CreateSystemFont(wxOSXSystemFont font
)
573 m_refData
= new wxFontRefData( font
, 0 );
582 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo
& info
)
586 m_refData
= new wxFontRefData( info
);
590 bool wxFont::RealizeResource()
592 M_FONTDATA
->MacFindFont();
597 void wxFont::SetEncoding(wxFontEncoding encoding
)
601 M_FONTDATA
->SetEncoding( encoding
);
604 wxGDIRefData
*wxFont::CreateGDIRefData() const
606 return new wxFontRefData
;
609 wxGDIRefData
*wxFont::CloneGDIRefData(const wxGDIRefData
*data
) const
611 return new wxFontRefData(*static_cast<const wxFontRefData
*>(data
));
614 void wxFont::SetPointSize(int pointSize
)
616 if ( M_FONTDATA
->GetPointSize() == pointSize
)
621 M_FONTDATA
->SetPointSize( pointSize
);
624 void wxFont::SetFamily(wxFontFamily family
)
628 M_FONTDATA
->SetFamily( family
);
631 void wxFont::SetStyle(wxFontStyle style
)
635 M_FONTDATA
->SetStyle( style
);
638 void wxFont::SetWeight(wxFontWeight weight
)
642 M_FONTDATA
->SetWeight( weight
);
645 bool wxFont::SetFaceName(const wxString
& faceName
)
649 M_FONTDATA
->SetFaceName( faceName
);
651 return wxFontBase::SetFaceName(faceName
);
654 void wxFont::SetUnderlined(bool underlined
)
658 M_FONTDATA
->SetUnderlined( underlined
);
661 void wxFont::SetNoAntiAliasing( bool no
)
665 M_FONTDATA
->SetNoAntiAliasing( no
);
668 // ----------------------------------------------------------------------------
670 // ----------------------------------------------------------------------------
672 // TODO: insert checks everywhere for M_FONTDATA == NULL!
674 int wxFont::GetPointSize() const
676 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
678 return M_FONTDATA
->GetPointSize();
681 wxSize
wxFont::GetPixelSize() const
683 #if wxUSE_GRAPHICS_CONTEXT
684 // TODO: consider caching the value
685 wxGraphicsContext
* dc
= wxGraphicsContext::CreateFromNative((CGContextRef
) NULL
);
686 dc
->SetFont(*(wxFont
*)this,*wxBLACK
);
687 wxDouble width
, height
= 0;
688 dc
->GetTextExtent( wxT("g"), &width
, &height
, NULL
, NULL
);
690 return wxSize((int)width
, (int)height
);
692 return wxFontBase::GetPixelSize();
696 wxFontFamily
wxFont::GetFamily() const
698 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTFAMILY_MAX
, wxT("invalid font") );
700 return M_FONTDATA
->GetFamily();
703 wxFontStyle
wxFont::GetStyle() const
705 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTSTYLE_MAX
, wxT("invalid font") );
707 return M_FONTDATA
->GetStyle() ;
710 wxFontWeight
wxFont::GetWeight() const
712 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTWEIGHT_MAX
, wxT("invalid font") );
714 return M_FONTDATA
->GetWeight();
717 bool wxFont::GetUnderlined() const
719 wxCHECK_MSG( M_FONTDATA
!= NULL
, false, wxT("invalid font") );
721 return M_FONTDATA
->GetUnderlined();
724 wxString
wxFont::GetFaceName() const
726 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxEmptyString
, wxT("invalid font") );
728 return M_FONTDATA
->GetFaceName() ;
731 wxFontEncoding
wxFont::GetEncoding() const
733 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTENCODING_DEFAULT
, wxT("invalid font") );
735 return M_FONTDATA
->GetEncoding() ;
738 bool wxFont::GetNoAntiAliasing() const
740 wxCHECK_MSG( M_FONTDATA
!= NULL
, false, wxT("invalid font") );
742 return M_FONTDATA
->GetNoAntiAliasing();
745 #if wxOSX_USE_ATSU_TEXT && wxOSX_USE_CARBON
747 short wxFont::MacGetFontNum() const
749 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
751 // cast away constness otherwise lazy font resolution is not possible
752 const_cast<wxFont
*>(this)->RealizeResource();
754 return M_FONTDATA
->m_info
.m_qdFontFamily
;
757 wxByte
wxFont::MacGetFontStyle() const
759 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
761 // cast away constness otherwise lazy font resolution is not possible
762 const_cast<wxFont
*>(this)->RealizeResource();
764 return M_FONTDATA
->m_info
.m_qdFontStyle
;
767 wxUint16
wxFont::MacGetThemeFontID() const
769 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
771 return M_FONTDATA
->m_macThemeFontID
;
776 #if wxOSX_USE_ATSU_TEXT
777 void * wxFont::MacGetATSUStyle() const
779 wxCHECK_MSG( M_FONTDATA
!= NULL
, NULL
, wxT("invalid font") );
781 // cast away constness otherwise lazy font resolution is not possible
782 const_cast<wxFont
*>(this)->RealizeResource();
784 return M_FONTDATA
->m_macATSUStyle
;
787 #if WXWIN_COMPATIBILITY_2_8
788 wxUint32
wxFont::MacGetATSUFontID() const
790 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
792 // cast away constness otherwise lazy font resolution is not possible
793 const_cast<wxFont
*>(this)->RealizeResource();
795 return M_FONTDATA
->m_info
.m_atsuFontID
;
798 wxUint32
wxFont::MacGetATSUAdditionalQDStyles() const
800 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
802 // cast away constness otherwise lazy font resolution is not possible
803 const_cast<wxFont
*>(this)->RealizeResource();
805 return M_FONTDATA
->m_info
.m_atsuAdditionalQDStyles
;
811 #if wxOSX_USE_CORE_TEXT
813 CTFontRef
wxFont::OSXGetCTFont() const
815 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
817 // cast away constness otherwise lazy font resolution is not possible
818 const_cast<wxFont
*>(this)->RealizeResource();
820 return (CTFontRef
)(M_FONTDATA
->m_ctFont
);
825 #if wxOSX_USE_COCOA_OR_CARBON
827 CGFontRef
wxFont::OSXGetCGFont() const
829 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
831 // cast away constness otherwise lazy font resolution is not possible
832 const_cast<wxFont
*>(this)->RealizeResource();
834 return (M_FONTDATA
->m_cgFont
);
842 NSFont
* wxFont::OSXGetNSFont() const
844 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
846 // cast away constness otherwise lazy font resolution is not possible
847 const_cast<wxFont
*>(this)->RealizeResource();
849 return (M_FONTDATA
->m_nsFont
);
854 const wxNativeFontInfo
* wxFont::GetNativeFontInfo() const
856 wxCHECK_MSG( M_FONTDATA
!= NULL
, NULL
, wxT("invalid font") );
857 wxCHECK_MSG( Ok(), NULL
, wxT("invalid font") );
859 // cast away constness otherwise lazy font resolution is not possible
860 const_cast<wxFont
*>(this)->RealizeResource();
862 // M_FONTDATA->m_info.InitFromFont(*this);
864 return &(M_FONTDATA
->m_info
);
867 // ----------------------------------------------------------------------------
869 // ----------------------------------------------------------------------------
871 #if wxOSX_USE_CORE_TEXT
873 /* from Core Text Manual Common Operations */
875 static CTFontDescriptorRef
wxMacCreateCTFontDescriptor(CFStringRef iFamilyName
, CTFontSymbolicTraits iTraits
)
877 CTFontDescriptorRef descriptor
= NULL
;
878 CFMutableDictionaryRef attributes
;
880 assert(iFamilyName
!= NULL
);
881 // Create a mutable dictionary to hold our attributes.
882 attributes
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
883 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
884 check(attributes
!= NULL
);
886 if (attributes
!= NULL
) {
887 // Add a family name to our attributes.
888 CFDictionaryAddValue(attributes
, kCTFontFamilyNameAttribute
, iFamilyName
);
892 CFMutableDictionaryRef traits
;
893 CFNumberRef symTraits
;
895 // Create the traits dictionary.
896 symTraits
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
898 check(symTraits
!= NULL
);
900 if (symTraits
!= NULL
) {
901 // Create a dictionary to hold our traits values.
902 traits
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
903 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
904 check(traits
!= NULL
);
906 if (traits
!= NULL
) {
907 // Add the symbolic traits value to the traits dictionary.
908 CFDictionaryAddValue(traits
, kCTFontSymbolicTrait
, symTraits
);
910 // Add the traits attribute to our attributes.
911 CFDictionaryAddValue(attributes
, kCTFontTraitsAttribute
, traits
);
914 CFRelease(symTraits
);
917 // Create the font descriptor with our attributes
918 descriptor
= CTFontDescriptorCreateWithAttributes(attributes
);
919 check(descriptor
!= NULL
);
921 CFRelease(attributes
);
923 // Return our font descriptor.
929 void wxNativeFontInfo::Init()
931 #if wxOSX_USE_CORE_TEXT
932 m_ctFontDescriptor
= NULL
;
934 #if wxOSX_USE_ATSU_TEXT
936 m_atsuAdditionalQDStyles
= 0;
937 m_atsuFontValid
= false;
944 m_nsFontDescriptor
= NULL
;
947 m_family
= wxFONTFAMILY_DEFAULT
;
948 m_style
= wxFONTSTYLE_NORMAL
;
949 m_weight
= wxFONTWEIGHT_NORMAL
;
950 m_underlined
= false;
952 m_encoding
= wxFont::GetDefaultEncoding();
953 m_descriptorValid
= false;
956 #if wxOSX_USE_CORE_TEXT
957 void wxNativeFontInfo::Init(CTFontDescriptorRef descr
)
960 m_ctFontDescriptor
= wxCFRetain(descr
);
962 wxCFRef
< CFNumberRef
> sizevalue( (CFNumberRef
) CTFontDescriptorCopyAttribute( m_ctFontDescriptor
, kCTFontSizeAttribute
) );
964 if ( CFNumberGetValue( sizevalue
, kCFNumberFloatType
, &fsize
) )
965 m_pointSize
= (int)( fsize
+ 0.5 );
967 wxCFRef
< CFDictionaryRef
> traitsvalue( (CFDictionaryRef
) CTFontDescriptorCopyAttribute( m_ctFontDescriptor
, kCTFontTraitsAttribute
) );
968 CTFontSymbolicTraits traits
;
969 if ( CFNumberGetValue((CFNumberRef
) CFDictionaryGetValue(traitsvalue
,kCTFontSymbolicTrait
),kCFNumberIntType
,&traits
) )
971 if ( traits
& kCTFontItalicTrait
)
972 m_style
= wxFONTSTYLE_ITALIC
;
973 if ( traits
& kCTFontBoldTrait
)
974 m_weight
= wxFONTWEIGHT_BOLD
;
977 wxCFStringRef
familyName( (CFStringRef
) CTFontDescriptorCopyAttribute(m_ctFontDescriptor
, kCTFontFamilyNameAttribute
));
978 m_faceName
= familyName
.AsString();
982 void wxNativeFontInfo::EnsureValid()
984 if ( m_descriptorValid
)
987 #if wxOSX_USE_CORE_TEXT
988 if ( m_ctFontDescriptor
== NULL
&& UMAGetSystemVersion() >= 0x1050 )
990 CTFontSymbolicTraits traits
= 0;
992 if (m_weight
== wxFONTWEIGHT_BOLD
)
993 traits
|= kCTFontBoldTrait
;
994 if (m_style
== wxFONTSTYLE_ITALIC
|| m_style
== wxFONTSTYLE_SLANT
)
995 traits
|= kCTFontItalicTrait
;
998 wxString lookupnameWithSize
= wxString::Format( "%s_%ld_%ld", m_faceName
.c_str(), traits
, m_pointSize
);
1000 static std::map
< std::wstring
, wxCFRef
< CTFontDescriptorRef
> > fontdescriptorcache
;
1001 m_ctFontDescriptor
= wxCFRetain((CTFontDescriptorRef
)fontdescriptorcache
[ std::wstring(lookupnameWithSize
.wc_str()) ]);
1002 if ( !m_ctFontDescriptor
)
1004 // QD selection algorithm is the fastest by orders of magnitude on 10.5
1005 if ( m_faceName
.IsAscii() )
1007 uint8_t qdstyle
= 0;
1008 if (m_weight
== wxFONTWEIGHT_BOLD
)
1010 if (m_style
== wxFONTSTYLE_ITALIC
|| m_style
== wxFONTSTYLE_SLANT
)
1014 wxMacStringToPascal( m_faceName
, qdFontName
);
1015 wxCFRef
< CTFontRef
> font
;
1016 font
.reset( CTFontCreateWithQuickdrawInstance(qdFontName
, 0 , qdstyle
, m_pointSize
) );
1017 m_ctFontDescriptor
= CTFontCopyFontDescriptor(font
);
1021 m_ctFontDescriptor
= wxMacCreateCTFontDescriptor( wxCFStringRef(m_faceName
),traits
);
1023 fontdescriptorcache
[ std::wstring(lookupnameWithSize
.wc_str()) ].reset(wxCFRetain(m_ctFontDescriptor
));
1027 #if wxOSX_USE_ATSU_TEXT
1028 if ( !m_atsuFontValid
)
1030 #if !wxOSX_USE_CARBON
1031 // not needed outside
1032 wxInt16 m_qdFontFamily
;
1033 wxInt16 m_qdFontStyle
;
1035 wxCFStringRef
cf( m_faceName
, wxLocale::GetSystemEncoding() );
1036 ATSFontFamilyRef atsfamily
= ATSFontFamilyFindFromName( cf
, kATSOptionFlagsDefault
);
1037 if ( atsfamily
== (ATSFontFamilyRef
) -1 )
1039 wxLogDebug( wxT("ATSFontFamilyFindFromName failed for ") + m_faceName
);
1040 m_qdFontFamily
= GetAppFont();
1044 m_qdFontFamily
= FMGetFontFamilyFromATSFontFamilyRef( atsfamily
);
1048 if (m_weight
== wxFONTWEIGHT_BOLD
)
1049 m_qdFontStyle
|= bold
;
1050 if (m_style
== wxFONTSTYLE_ITALIC
|| m_style
== wxFONTSTYLE_SLANT
)
1051 m_qdFontStyle
|= italic
;
1053 m_qdFontStyle
|= underline
;
1056 // we try to get as much styles as possible into ATSU
1058 // ATSUFontID and FMFont are equivalent
1059 FMFontStyle intrinsicStyle
= 0 ;
1060 OSStatus status
= FMGetFontFromFontFamilyInstance( m_qdFontFamily
, m_qdFontStyle
, (FMFont
*)&m_atsuFontID
, &intrinsicStyle
);
1061 if ( status
!= noErr
)
1063 wxFAIL_MSG( wxT("couldn't get an ATSUFont from font family") );
1065 m_atsuAdditionalQDStyles
= m_qdFontStyle
& (~intrinsicStyle
);
1066 m_atsuFontValid
= true;
1070 if ( m_nsFontDescriptor
== NULL
)
1071 OSXValidateNSFontDescriptor();
1073 #if wxOSX_USE_IPHONE
1076 m_descriptorValid
= true;
1079 void wxNativeFontInfo::Init(const wxNativeFontInfo
& info
)
1082 #if wxOSX_USE_CORE_TEXT
1083 m_ctFontDescriptor
= wxCFRetain(info
.m_ctFontDescriptor
);
1085 #if wxOSX_USE_ATSU_TEXT
1086 m_atsuFontValid
= info
.m_atsuFontValid
;
1087 m_atsuFontID
= info
.m_atsuFontID
;
1088 m_atsuAdditionalQDStyles
= info
.m_atsuAdditionalQDStyles
;
1089 #if wxOSX_USE_CARBON
1090 m_qdFontFamily
= info
.m_qdFontFamily
;
1091 m_qdFontStyle
= info
.m_qdFontStyle
;
1095 m_nsFontDescriptor
= (NSFontDescriptor
*) wxMacCocoaRetain(info
.m_nsFontDescriptor
);
1097 m_pointSize
= info
.m_pointSize
;
1098 m_family
= info
.m_family
;
1099 m_style
= info
.m_style
;
1100 m_weight
= info
.m_weight
;
1101 m_underlined
= info
.m_underlined
;
1102 m_faceName
= info
.m_faceName
;
1103 m_encoding
= info
.m_encoding
;
1104 m_descriptorValid
= info
.m_descriptorValid
;
1107 void wxNativeFontInfo::Init(int size
,
1108 wxFontFamily family
,
1110 wxFontWeight weight
,
1112 const wxString
& faceName
,
1113 wxFontEncoding encoding
)
1120 m_underlined
= underlined
;
1121 m_faceName
= faceName
;
1122 if ( encoding
== wxFONTENCODING_DEFAULT
)
1123 encoding
= wxFont::GetDefaultEncoding();
1124 m_encoding
= encoding
;
1128 void wxNativeFontInfo::Free()
1130 #if wxOSX_USE_CORE_TEXT
1131 wxCFRelease(m_ctFontDescriptor
);
1132 m_ctFontDescriptor
= NULL
;
1134 #if wxOSX_USE_ATSU_TEXT
1136 m_atsuAdditionalQDStyles
= 0;
1137 m_atsuFontValid
= false;
1140 wxMacCocoaRelease(m_nsFontDescriptor
);
1141 m_nsFontDescriptor
= NULL
;
1143 m_descriptorValid
= false;
1146 bool wxNativeFontInfo::FromString(const wxString
& s
)
1150 wxStringTokenizer
tokenizer(s
, _T(";"));
1152 wxString token
= tokenizer
.GetNextToken();
1154 // Ignore the version for now
1157 token
= tokenizer
.GetNextToken();
1158 if ( !token
.ToLong(&l
) )
1160 m_pointSize
= (int)l
;
1162 token
= tokenizer
.GetNextToken();
1163 if ( !token
.ToLong(&l
) )
1165 m_family
= (wxFontFamily
)l
;
1167 token
= tokenizer
.GetNextToken();
1168 if ( !token
.ToLong(&l
) )
1170 m_style
= (wxFontStyle
)l
;
1172 token
= tokenizer
.GetNextToken();
1173 if ( !token
.ToLong(&l
) )
1175 m_weight
= (wxFontWeight
)l
;
1177 token
= tokenizer
.GetNextToken();
1178 if ( !token
.ToLong(&l
) )
1180 m_underlined
= l
!= 0;
1182 m_faceName
= tokenizer
.GetNextToken();
1189 token
= tokenizer
.GetNextToken();
1190 if ( !token
.ToLong(&l
) )
1192 m_encoding
= (wxFontEncoding
)l
;
1197 wxString
wxNativeFontInfo::ToString() const
1201 s
.Printf(_T("%d;%d;%d;%d;%d;%d;%s;%d"),
1208 m_faceName
.GetData(),
1214 int wxNativeFontInfo::GetPointSize() const
1219 wxFontStyle
wxNativeFontInfo::GetStyle() const
1224 wxFontWeight
wxNativeFontInfo::GetWeight() const
1229 bool wxNativeFontInfo::GetUnderlined() const
1231 return m_underlined
;
1234 wxString
wxNativeFontInfo::GetFaceName() const
1239 wxFontFamily
wxNativeFontInfo::GetFamily() const
1244 wxFontEncoding
wxNativeFontInfo::GetEncoding() const
1249 // changing the font descriptor
1251 void wxNativeFontInfo::SetPointSize(int pointsize
)
1253 if ( m_pointSize
!= pointsize
)
1255 m_pointSize
= pointsize
;
1260 void wxNativeFontInfo::SetStyle(wxFontStyle style_
)
1262 if ( m_style
!= style_
)
1269 void wxNativeFontInfo::SetWeight(wxFontWeight weight_
)
1271 if ( m_weight
!= weight_
)
1278 void wxNativeFontInfo::SetUnderlined(bool underlined_
)
1280 if ( m_underlined
!= underlined_
)
1282 m_underlined
= underlined_
;
1287 bool wxNativeFontInfo::SetFaceName(const wxString
& facename_
)
1289 if ( m_faceName
!= facename_
)
1291 m_faceName
= facename_
;
1297 void wxNativeFontInfo::SetFamily(wxFontFamily family_
)
1299 if ( m_family
!= family_
)
1306 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_
)
1308 if ( encoding_
== wxFONTENCODING_DEFAULT
)
1309 encoding_
= wxFont::GetDefaultEncoding();
1310 m_encoding
= encoding_
;
1311 // not reflected in native descriptors