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 SetPointSize( int size
)
66 if( GetPointSize() != size
)
68 m_info
.SetPointSize(size
);
73 int GetPointSize() const { return m_info
.GetPointSize(); }
75 void SetFamily( wxFontFamily family
)
77 if ( m_info
.m_family
!= family
)
79 m_info
.SetFamily( family
);
84 wxFontFamily
GetFamily() const { return m_info
.GetFamily(); }
86 void SetStyle( wxFontStyle style
)
88 if ( m_info
.m_style
!= style
)
90 m_info
.SetStyle( style
);
96 wxFontStyle
GetStyle() const { return m_info
.GetStyle(); }
98 void SetWeight( wxFontWeight weight
)
100 if ( m_info
.m_weight
!= weight
)
102 m_info
.SetWeight( weight
);
108 wxFontWeight
GetWeight() const { return m_info
.GetWeight(); }
110 void SetUnderlined( bool u
)
112 if ( m_info
.m_underlined
!= u
)
114 m_info
.SetUnderlined( u
);
119 bool GetUnderlined() const { return m_info
.GetUnderlined(); }
121 void SetFaceName( const wxString
& facename
)
123 if ( m_info
.m_faceName
!= facename
)
125 m_info
.SetFaceName( facename
);
130 wxString
GetFaceName() const { return m_info
.GetFaceName(); }
132 void SetEncoding( wxFontEncoding encoding
)
134 if ( m_info
.m_encoding
!= encoding
)
136 m_info
.SetEncoding( encoding
);
141 wxFontEncoding
GetEncoding() const { return m_info
.GetEncoding(); }
148 // common part of all ctors
150 #if wxOSX_USE_CORE_TEXT
151 // void Init( CTFontRef font );
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
;
160 #if wxOSX_USE_CORE_TEXT
161 wxCFRef
<CTFontRef
> m_ctFont
;
163 #if wxOSX_USE_ATSU_TEXT
164 ATSUStyle m_macATSUStyle
;
166 wxCFRef
<CGFontRef
> m_cgFont
;
173 wxNativeFontInfo m_info
;
176 #define M_FONTDATA ((wxFontRefData*)m_refData)
178 wxFontRefData::wxFontRefData(const wxFontRefData
& data
)
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
;
186 #if wxOSX_USE_CORE_TEXT
187 m_ctFont
= data
.m_ctFont
;
189 m_cgFont
= data
.m_cgFont
;
190 #if wxOSX_USE_ATSU_TEXT
191 if ( data
.m_macATSUStyle
!= NULL
)
193 ATSUCreateStyle(&m_macATSUStyle
) ;
194 ATSUCopyAttributes(data
.m_macATSUStyle
, m_macATSUStyle
);
198 m_nsFont
= (NSFont
*) wxMacCocoaRetain(data
.m_nsFont
);
201 m_uiFont
= (UIFont
*) wxMacCocoaRetain(data
.m_uiFont
);
206 // ============================================================================
208 // ============================================================================
210 // ----------------------------------------------------------------------------
212 // ----------------------------------------------------------------------------
214 void wxFontRefData::Init()
216 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
217 m_macThemeFontID
= kThemeCurrentPortFont
;
219 #if wxOSX_USE_ATSU_TEXT
220 m_macATSUStyle
= NULL
;
231 wxFontRefData::~wxFontRefData()
236 void wxFontRefData::Free()
238 #if wxOSX_USE_CORE_TEXT
242 #if wxOSX_USE_ATSU_TEXT
244 m_macThemeFontID
= kThemeCurrentPortFont
;
246 if ( m_macATSUStyle
)
248 ::ATSUDisposeStyle((ATSUStyle
)m_macATSUStyle
);
249 m_macATSUStyle
= NULL
;
253 if (m_nsFont
!= NULL
)
255 wxMacCocoaRelease(m_nsFont
);
260 if (m_uiFont
!= NULL
)
262 wxMacCocoaRelease(m_uiFont
);
269 wxFontRefData::wxFontRefData(wxOSXSystemFont font
, int size
)
271 wxASSERT( font
!= wxOSX_SYSTEM_FONT_NONE
);
274 #if wxOSX_USE_CORE_TEXT
275 if ( UMAGetSystemVersion() >= 0x1050 )
277 CTFontUIFontType uifont
= kCTFontSystemFontType
;
280 case wxOSX_SYSTEM_FONT_NORMAL
:
281 uifont
= kCTFontSystemFontType
;
283 case wxOSX_SYSTEM_FONT_BOLD
:
284 uifont
= kCTFontEmphasizedSystemFontType
;
286 case wxOSX_SYSTEM_FONT_SMALL
:
287 uifont
= kCTFontSmallSystemFontType
;
289 case wxOSX_SYSTEM_FONT_SMALL_BOLD
:
290 uifont
= kCTFontSmallEmphasizedSystemFontType
;
292 case wxOSX_SYSTEM_FONT_MINI
:
293 uifont
= kCTFontMiniSystemFontType
;
295 case wxOSX_SYSTEM_FONT_MINI_BOLD
:
296 uifont
= kCTFontMiniEmphasizedSystemFontType
;
298 case wxOSX_SYSTEM_FONT_LABELS
:
299 uifont
= kCTFontLabelFontType
;
301 case wxOSX_SYSTEM_FONT_VIEWS
:
302 uifont
= kCTFontViewsFontType
;
307 m_ctFont
.reset(CTFontCreateUIFontForLanguage( uifont
, (CGFloat
) size
, NULL
));
308 wxCFRef
<CTFontDescriptorRef
> descr
;
309 descr
.reset( CTFontCopyFontDescriptor( m_ctFont
) );
313 #if wxOSX_USE_ATSU_TEXT
315 #if !wxOSX_USE_CARBON
316 // not needed outside
317 ThemeFontID m_macThemeFontID
= kThemeSystemFont
;
321 case wxOSX_SYSTEM_FONT_NORMAL
:
322 m_macThemeFontID
= kThemeSystemFont
;
324 case wxOSX_SYSTEM_FONT_BOLD
:
325 m_macThemeFontID
= kThemeEmphasizedSystemFont
;
327 case wxOSX_SYSTEM_FONT_SMALL
:
328 m_macThemeFontID
= kThemeSmallSystemFont
;
330 case wxOSX_SYSTEM_FONT_SMALL_BOLD
:
331 m_macThemeFontID
= kThemeSmallEmphasizedSystemFont
;
333 case wxOSX_SYSTEM_FONT_MINI
:
334 m_macThemeFontID
= kThemeMiniSystemFont
;
336 case wxOSX_SYSTEM_FONT_MINI_BOLD
:
337 // bold not available under theming
338 m_macThemeFontID
= kThemeMiniSystemFont
;
340 case wxOSX_SYSTEM_FONT_LABELS
:
341 m_macThemeFontID
= kThemeLabelFont
;
343 case wxOSX_SYSTEM_FONT_VIEWS
:
344 m_macThemeFontID
= kThemeViewsFont
;
349 if ( m_info
.m_faceName
.empty() )
355 GetThemeFont( m_macThemeFontID
, GetApplicationScript(), qdFontName
, &fontSize
, &style
);
359 wxFontStyle fontstyle
= wxFONTSTYLE_NORMAL
;
360 wxFontWeight fontweight
= wxFONTWEIGHT_NORMAL
;
361 bool underlined
= false;
364 fontweight
= wxFONTWEIGHT_BOLD
;
366 fontweight
= wxFONTWEIGHT_NORMAL
;
367 if ( style
& italic
)
368 fontstyle
= wxFONTSTYLE_ITALIC
;
369 if ( style
& underline
)
372 m_info
.Init(fontSize
,wxFONTFAMILY_DEFAULT
,fontstyle
,fontweight
,underlined
,
373 wxMacMakeStringFromPascal( qdFontName
), wxFONTENCODING_DEFAULT
);
378 m_nsFont
= wxFont::OSXCreateNSFont( font
, &m_info
);
381 m_uiFont
= wxFont::OSXCreateUIFont( font
, &m_info
);
385 void wxFontRefData::MacFindFont()
390 wxCHECK_RET( m_info
.m_pointSize
> 0, wxT("Point size should not be zero.") );
392 m_info
.EnsureValid();
394 #if wxOSX_USE_CORE_TEXT
395 if ( UMAGetSystemVersion() >= 0x1050 )
397 CTFontSymbolicTraits traits
= 0;
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
;
405 wxString lookupnameWithSize
= wxString::Format( "%s_%ld_%ld", m_info
.m_faceName
.c_str(), traits
, m_info
.m_pointSize
);
407 static std::map
< std::wstring
, wxCFRef
< CTFontRef
> > fontcache
;
408 m_ctFont
= fontcache
[ std::wstring(lookupnameWithSize
.wc_str()) ];
411 m_ctFont
.reset( CTFontCreateWithFontDescriptor( m_info
.m_ctFontDescriptor
, 0/*m_pointSize */, NULL
) );
413 m_cgFont
.reset(CTFontCopyGraphicsFont(m_ctFont
, NULL
));
417 #if wxOSX_USE_ATSU_TEXT
419 // we try to get as much styles as possible into ATSU
421 OSStatus status
= ::ATSUCreateStyle(&m_macATSUStyle
);
422 wxASSERT_MSG( status
== noErr
, wxT("couldn't create ATSU style") );
424 ATSUAttributeTag atsuTags
[] =
428 kATSUVerticalCharacterTag
,
431 kATSUQDUnderlineTag
,
432 kATSUQDCondensedTag
,
435 ByteCount atsuSizes
[WXSIZEOF(atsuTags
)] =
437 sizeof( ATSUFontID
) ,
439 sizeof( ATSUVerticalCharacterType
),
447 Boolean kTrue
= true ;
448 Boolean kFalse
= false ;
450 Fixed atsuSize
= IntToFixed( m_info
.m_pointSize
);
451 ATSUVerticalCharacterType kHorizontal
= kATSUStronglyHorizontal
;
452 FMFontStyle addQDStyle
= m_info
.m_atsuAdditionalQDStyles
;
453 ATSUAttributeValuePtr atsuValues
[WXSIZEOF(atsuTags
)] =
455 &m_info
.m_atsuFontID
,
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
,
465 status
= ::ATSUSetAttributes(
466 (ATSUStyle
)m_macATSUStyle
,
468 atsuTags
, atsuSizes
, atsuValues
);
470 wxASSERT_MSG( status
== noErr
, wxString::Format(wxT("couldn't modify ATSU style. Status was %d"), (int) status
).c_str() );
472 if ( m_cgFont
.get() == NULL
)
474 ATSFontRef fontRef
= FMGetATSFontRefFromFont(m_info
.m_atsuFontID
);
475 m_cgFont
.reset( CGFontCreateWithPlatformFont( &fontRef
) );
480 m_nsFont
= wxFont::OSXCreateNSFont( &m_info
);
483 m_uiFont
= wxFont::OSXCreateUIFont( &m_info
);
488 // ----------------------------------------------------------------------------
490 // ----------------------------------------------------------------------------
492 bool wxFont::Create(const wxNativeFontInfo
& info
)
496 m_refData
= new wxFontRefData( info
);
502 wxFont::wxFont(const wxString
& fontdesc
)
504 wxNativeFontInfo info
;
505 if ( info
.FromString(fontdesc
) )
509 bool wxFont::Create(int pointSize
,
514 const wxString
& faceNameParam
,
515 wxFontEncoding encoding
)
519 wxString faceName
= faceNameParam
;
521 if ( faceName
.empty() )
525 case wxFONTFAMILY_DEFAULT
:
526 faceName
= wxT("Lucida Grande");
529 case wxFONTFAMILY_SCRIPT
:
530 case wxFONTFAMILY_ROMAN
:
531 case wxFONTFAMILY_DECORATIVE
:
532 faceName
= wxT("Times");
535 case wxFONTFAMILY_SWISS
:
536 faceName
= wxT("Helvetica");
539 case wxFONTFAMILY_MODERN
:
540 case wxFONTFAMILY_TELETYPE
:
541 faceName
= wxT("Courier");
545 faceName
= wxT("Times");
550 wxNativeFontInfo info
;
552 info
.Init(pointSize
, family
, style
, weight
,
553 underlined
, faceName
, encoding
);
555 m_refData
= new wxFontRefData(info
);
560 bool wxFont::CreateSystemFont(wxOSXSystemFont font
)
564 m_refData
= new wxFontRefData( font
, 0 );
573 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo
& info
)
577 m_refData
= new wxFontRefData( info
);
581 bool wxFont::RealizeResource()
583 M_FONTDATA
->MacFindFont();
588 void wxFont::SetEncoding(wxFontEncoding encoding
)
592 M_FONTDATA
->SetEncoding( encoding
);
595 wxGDIRefData
*wxFont::CreateGDIRefData() const
597 return new wxFontRefData
;
600 wxGDIRefData
*wxFont::CloneGDIRefData(const wxGDIRefData
*data
) const
602 return new wxFontRefData(*static_cast<const wxFontRefData
*>(data
));
605 void wxFont::SetPointSize(int pointSize
)
607 if ( M_FONTDATA
->GetPointSize() == pointSize
)
612 M_FONTDATA
->SetPointSize( pointSize
);
615 void wxFont::SetFamily(wxFontFamily family
)
619 M_FONTDATA
->SetFamily( family
);
622 void wxFont::SetStyle(wxFontStyle style
)
626 M_FONTDATA
->SetStyle( style
);
629 void wxFont::SetWeight(wxFontWeight weight
)
633 M_FONTDATA
->SetWeight( weight
);
636 bool wxFont::SetFaceName(const wxString
& faceName
)
640 M_FONTDATA
->SetFaceName( faceName
);
642 return wxFontBase::SetFaceName(faceName
);
645 void wxFont::SetUnderlined(bool underlined
)
649 M_FONTDATA
->SetUnderlined( underlined
);
652 // ----------------------------------------------------------------------------
654 // ----------------------------------------------------------------------------
656 // TODO: insert checks everywhere for M_FONTDATA == NULL!
658 int wxFont::GetPointSize() const
660 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
662 return M_FONTDATA
->GetPointSize();
665 wxSize
wxFont::GetPixelSize() const
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
);
674 return wxSize((int)width
, (int)height
);
676 return wxFontBase::GetPixelSize();
680 wxFontFamily
wxFont::GetFamily() const
682 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTFAMILY_MAX
, wxT("invalid font") );
684 return M_FONTDATA
->GetFamily();
687 wxFontStyle
wxFont::GetStyle() const
689 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTSTYLE_MAX
, wxT("invalid font") );
691 return M_FONTDATA
->GetStyle() ;
694 wxFontWeight
wxFont::GetWeight() const
696 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTWEIGHT_MAX
, wxT("invalid font") );
698 return M_FONTDATA
->GetWeight();
701 bool wxFont::GetUnderlined() const
703 wxCHECK_MSG( M_FONTDATA
!= NULL
, false, wxT("invalid font") );
705 return M_FONTDATA
->GetUnderlined();
708 wxString
wxFont::GetFaceName() const
710 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxEmptyString
, wxT("invalid font") );
712 return M_FONTDATA
->GetFaceName() ;
715 wxFontEncoding
wxFont::GetEncoding() const
717 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTENCODING_DEFAULT
, wxT("invalid font") );
719 return M_FONTDATA
->GetEncoding() ;
722 #if wxOSX_USE_ATSU_TEXT && wxOSX_USE_CARBON
724 short wxFont::MacGetFontNum() const
726 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
728 // cast away constness otherwise lazy font resolution is not possible
729 const_cast<wxFont
*>(this)->RealizeResource();
731 return M_FONTDATA
->m_info
.m_qdFontFamily
;
734 wxByte
wxFont::MacGetFontStyle() const
736 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
738 // cast away constness otherwise lazy font resolution is not possible
739 const_cast<wxFont
*>(this)->RealizeResource();
741 return M_FONTDATA
->m_info
.m_qdFontStyle
;
744 wxUint16
wxFont::MacGetThemeFontID() const
746 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
748 return M_FONTDATA
->m_macThemeFontID
;
753 #if wxOSX_USE_ATSU_TEXT
754 void * wxFont::MacGetATSUStyle() const
756 wxCHECK_MSG( M_FONTDATA
!= NULL
, NULL
, wxT("invalid font") );
758 // cast away constness otherwise lazy font resolution is not possible
759 const_cast<wxFont
*>(this)->RealizeResource();
761 return M_FONTDATA
->m_macATSUStyle
;
764 #if WXWIN_COMPATIBILITY_2_8
765 wxUint32
wxFont::MacGetATSUFontID() const
767 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
769 // cast away constness otherwise lazy font resolution is not possible
770 const_cast<wxFont
*>(this)->RealizeResource();
772 return M_FONTDATA
->m_info
.m_atsuFontID
;
775 wxUint32
wxFont::MacGetATSUAdditionalQDStyles() const
777 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, 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_info
.m_atsuAdditionalQDStyles
;
788 #if wxOSX_USE_CORE_TEXT
790 CTFontRef
wxFont::OSXGetCTFont() const
792 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
794 // cast away constness otherwise lazy font resolution is not possible
795 const_cast<wxFont
*>(this)->RealizeResource();
797 return (CTFontRef
)(M_FONTDATA
->m_ctFont
);
802 #if wxOSX_USE_COCOA_OR_CARBON
804 CGFontRef
wxFont::OSXGetCGFont() const
806 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
808 // cast away constness otherwise lazy font resolution is not possible
809 const_cast<wxFont
*>(this)->RealizeResource();
811 return (M_FONTDATA
->m_cgFont
);
819 NSFont
* wxFont::OSXGetNSFont() const
821 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
823 // cast away constness otherwise lazy font resolution is not possible
824 const_cast<wxFont
*>(this)->RealizeResource();
826 return (M_FONTDATA
->m_nsFont
);
831 const wxNativeFontInfo
* wxFont::GetNativeFontInfo() const
833 wxCHECK_MSG( M_FONTDATA
!= NULL
, NULL
, wxT("invalid font") );
834 wxCHECK_MSG( Ok(), NULL
, wxT("invalid font") );
836 // cast away constness otherwise lazy font resolution is not possible
837 const_cast<wxFont
*>(this)->RealizeResource();
839 // M_FONTDATA->m_info.InitFromFont(*this);
841 return &(M_FONTDATA
->m_info
);
844 // ----------------------------------------------------------------------------
846 // ----------------------------------------------------------------------------
848 #if wxOSX_USE_CORE_TEXT
850 /* from Core Text Manual Common Operations */
852 static CTFontDescriptorRef
wxMacCreateCTFontDescriptor(CFStringRef iFamilyName
, CTFontSymbolicTraits iTraits
)
854 CTFontDescriptorRef descriptor
= NULL
;
855 CFMutableDictionaryRef attributes
;
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
);
863 if (attributes
!= NULL
) {
864 // Add a family name to our attributes.
865 CFDictionaryAddValue(attributes
, kCTFontFamilyNameAttribute
, iFamilyName
);
869 CFMutableDictionaryRef traits
;
870 CFNumberRef symTraits
;
872 // Create the traits dictionary.
873 symTraits
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
875 wxASSERT(symTraits
!= NULL
);
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
);
883 if (traits
!= NULL
) {
884 // Add the symbolic traits value to the traits dictionary.
885 CFDictionaryAddValue(traits
, kCTFontSymbolicTrait
, symTraits
);
887 // Add the traits attribute to our attributes.
888 CFDictionaryAddValue(attributes
, kCTFontTraitsAttribute
, traits
);
891 CFRelease(symTraits
);
894 // Create the font descriptor with our attributes
895 descriptor
= CTFontDescriptorCreateWithAttributes(attributes
);
896 wxASSERT(descriptor
!= NULL
);
898 CFRelease(attributes
);
900 // Return our font descriptor.
906 void wxNativeFontInfo::Init()
908 #if wxOSX_USE_CORE_TEXT
909 m_ctFontDescriptor
= NULL
;
911 #if wxOSX_USE_ATSU_TEXT
913 m_atsuAdditionalQDStyles
= 0;
914 m_atsuFontValid
= false;
921 m_nsFontDescriptor
= NULL
;
924 m_family
= wxFONTFAMILY_DEFAULT
;
925 m_style
= wxFONTSTYLE_NORMAL
;
926 m_weight
= wxFONTWEIGHT_NORMAL
;
927 m_underlined
= false;
929 m_encoding
= wxFont::GetDefaultEncoding();
930 m_descriptorValid
= false;
933 #if wxOSX_USE_CORE_TEXT
934 void wxNativeFontInfo::Init(CTFontDescriptorRef descr
)
937 m_ctFontDescriptor
= wxCFRetain(descr
);
939 wxCFRef
< CFNumberRef
> sizevalue( (CFNumberRef
) CTFontDescriptorCopyAttribute( m_ctFontDescriptor
, kCTFontSizeAttribute
) );
941 if ( CFNumberGetValue( sizevalue
, kCFNumberFloatType
, &fsize
) )
942 m_pointSize
= (int)( fsize
+ 0.5 );
944 wxCFRef
< CFDictionaryRef
> traitsvalue( (CFDictionaryRef
) CTFontDescriptorCopyAttribute( m_ctFontDescriptor
, kCTFontTraitsAttribute
) );
945 CTFontSymbolicTraits traits
;
946 if ( CFNumberGetValue((CFNumberRef
) CFDictionaryGetValue(traitsvalue
,kCTFontSymbolicTrait
),kCFNumberIntType
,&traits
) )
948 if ( traits
& kCTFontItalicTrait
)
949 m_style
= wxFONTSTYLE_ITALIC
;
950 if ( traits
& kCTFontBoldTrait
)
951 m_weight
= wxFONTWEIGHT_BOLD
;
954 wxCFStringRef
familyName( (CFStringRef
) CTFontDescriptorCopyAttribute(m_ctFontDescriptor
, kCTFontFamilyNameAttribute
));
955 m_faceName
= familyName
.AsString();
959 void wxNativeFontInfo::EnsureValid()
961 if ( m_descriptorValid
)
964 #if wxOSX_USE_CORE_TEXT
965 if ( m_ctFontDescriptor
== NULL
&& UMAGetSystemVersion() >= 0x1050 )
967 CTFontSymbolicTraits traits
= 0;
969 if (m_weight
== wxFONTWEIGHT_BOLD
)
970 traits
|= kCTFontBoldTrait
;
971 if (m_style
== wxFONTSTYLE_ITALIC
|| m_style
== wxFONTSTYLE_SLANT
)
972 traits
|= kCTFontItalicTrait
;
975 wxString lookupnameWithSize
= wxString::Format( "%s_%ld_%ld", m_faceName
.c_str(), traits
, m_pointSize
);
977 static std::map
< std::wstring
, wxCFRef
< CTFontDescriptorRef
> > fontdescriptorcache
;
978 m_ctFontDescriptor
= wxCFRetain((CTFontDescriptorRef
)fontdescriptorcache
[ std::wstring(lookupnameWithSize
.wc_str()) ]);
979 if ( !m_ctFontDescriptor
)
981 // QD selection algorithm is the fastest by orders of magnitude on 10.5
982 if ( m_faceName
.IsAscii() )
985 if (m_weight
== wxFONTWEIGHT_BOLD
)
987 if (m_style
== wxFONTSTYLE_ITALIC
|| m_style
== wxFONTSTYLE_SLANT
)
991 wxMacStringToPascal( m_faceName
, qdFontName
);
992 wxCFRef
< CTFontRef
> font
;
993 font
.reset( CTFontCreateWithQuickdrawInstance(qdFontName
, 0 , qdstyle
, m_pointSize
) );
994 m_ctFontDescriptor
= CTFontCopyFontDescriptor(font
);
998 m_ctFontDescriptor
= wxMacCreateCTFontDescriptor( wxCFStringRef(m_faceName
),traits
);
1000 fontdescriptorcache
[ std::wstring(lookupnameWithSize
.wc_str()) ].reset(wxCFRetain(m_ctFontDescriptor
));
1004 #if wxOSX_USE_ATSU_TEXT
1005 if ( !m_atsuFontValid
)
1007 #if !wxOSX_USE_CARBON
1008 // not needed outside
1009 wxInt16 m_qdFontFamily
;
1010 wxInt16 m_qdFontStyle
;
1012 wxCFStringRef
cf( m_faceName
, wxLocale::GetSystemEncoding() );
1013 ATSFontFamilyRef atsfamily
= ATSFontFamilyFindFromName( cf
, kATSOptionFlagsDefault
);
1014 if ( atsfamily
== (ATSFontFamilyRef
) -1 )
1016 wxLogDebug( wxT("ATSFontFamilyFindFromName failed for ") + m_faceName
);
1017 m_qdFontFamily
= GetAppFont();
1021 m_qdFontFamily
= FMGetFontFamilyFromATSFontFamilyRef( atsfamily
);
1025 if (m_weight
== wxFONTWEIGHT_BOLD
)
1026 m_qdFontStyle
|= bold
;
1027 if (m_style
== wxFONTSTYLE_ITALIC
|| m_style
== wxFONTSTYLE_SLANT
)
1028 m_qdFontStyle
|= italic
;
1030 m_qdFontStyle
|= underline
;
1033 // we try to get as much styles as possible into ATSU
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
)
1040 wxFAIL_MSG( wxT("couldn't get an ATSUFont from font family") );
1042 m_atsuAdditionalQDStyles
= m_qdFontStyle
& (~intrinsicStyle
);
1043 m_atsuFontValid
= true;
1047 if ( m_nsFontDescriptor
== NULL
)
1048 OSXValidateNSFontDescriptor();
1050 #if wxOSX_USE_IPHONE
1053 m_descriptorValid
= true;
1056 void wxNativeFontInfo::Init(const wxNativeFontInfo
& info
)
1059 #if wxOSX_USE_CORE_TEXT
1060 m_ctFontDescriptor
= wxCFRetain(info
.m_ctFontDescriptor
);
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
;
1072 m_nsFontDescriptor
= (NSFontDescriptor
*) wxMacCocoaRetain(info
.m_nsFontDescriptor
);
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
;
1084 void wxNativeFontInfo::Init(int size
,
1085 wxFontFamily family
,
1087 wxFontWeight weight
,
1089 const wxString
& faceName
,
1090 wxFontEncoding encoding
)
1097 m_underlined
= underlined
;
1098 m_faceName
= faceName
;
1099 if ( encoding
== wxFONTENCODING_DEFAULT
)
1100 encoding
= wxFont::GetDefaultEncoding();
1101 m_encoding
= encoding
;
1105 void wxNativeFontInfo::Free()
1107 #if wxOSX_USE_CORE_TEXT
1108 wxCFRelease(m_ctFontDescriptor
);
1109 m_ctFontDescriptor
= NULL
;
1111 #if wxOSX_USE_ATSU_TEXT
1113 m_atsuAdditionalQDStyles
= 0;
1114 m_atsuFontValid
= false;
1117 wxMacCocoaRelease(m_nsFontDescriptor
);
1118 m_nsFontDescriptor
= NULL
;
1120 m_descriptorValid
= false;
1123 bool wxNativeFontInfo::FromString(const wxString
& s
)
1127 wxStringTokenizer
tokenizer(s
, wxT(";"));
1129 wxString token
= tokenizer
.GetNextToken();
1131 // Ignore the version for now
1134 token
= tokenizer
.GetNextToken();
1135 if ( !token
.ToLong(&l
) )
1137 m_pointSize
= (int)l
;
1139 token
= tokenizer
.GetNextToken();
1140 if ( !token
.ToLong(&l
) )
1142 m_family
= (wxFontFamily
)l
;
1144 token
= tokenizer
.GetNextToken();
1145 if ( !token
.ToLong(&l
) )
1147 m_style
= (wxFontStyle
)l
;
1149 token
= tokenizer
.GetNextToken();
1150 if ( !token
.ToLong(&l
) )
1152 m_weight
= (wxFontWeight
)l
;
1154 token
= tokenizer
.GetNextToken();
1155 if ( !token
.ToLong(&l
) )
1157 m_underlined
= l
!= 0;
1159 m_faceName
= tokenizer
.GetNextToken();
1166 token
= tokenizer
.GetNextToken();
1167 if ( !token
.ToLong(&l
) )
1169 m_encoding
= (wxFontEncoding
)l
;
1174 wxString
wxNativeFontInfo::ToString() const
1178 s
.Printf(wxT("%d;%d;%d;%d;%d;%d;%s;%d"),
1185 m_faceName
.GetData(),
1191 int wxNativeFontInfo::GetPointSize() const
1196 wxFontStyle
wxNativeFontInfo::GetStyle() const
1201 wxFontWeight
wxNativeFontInfo::GetWeight() const
1206 bool wxNativeFontInfo::GetUnderlined() const
1208 return m_underlined
;
1211 wxString
wxNativeFontInfo::GetFaceName() const
1216 wxFontFamily
wxNativeFontInfo::GetFamily() const
1221 wxFontEncoding
wxNativeFontInfo::GetEncoding() const
1226 // changing the font descriptor
1228 void wxNativeFontInfo::SetPointSize(int pointsize
)
1230 if ( m_pointSize
!= pointsize
)
1232 m_pointSize
= pointsize
;
1237 void wxNativeFontInfo::SetStyle(wxFontStyle style_
)
1239 if ( m_style
!= style_
)
1246 void wxNativeFontInfo::SetWeight(wxFontWeight weight_
)
1248 if ( m_weight
!= weight_
)
1255 void wxNativeFontInfo::SetUnderlined(bool underlined_
)
1257 if ( m_underlined
!= underlined_
)
1259 m_underlined
= underlined_
;
1264 bool wxNativeFontInfo::SetFaceName(const wxString
& facename_
)
1266 if ( m_faceName
!= facename_
)
1268 m_faceName
= facename_
;
1274 void wxNativeFontInfo::SetFamily(wxFontFamily family_
)
1276 if ( m_family
!= family_
)
1283 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_
)
1285 if ( encoding_
== wxFONTENCODING_DEFAULT
)
1286 encoding_
= wxFont::GetDefaultEncoding();
1287 m_encoding
= encoding_
;
1288 // not reflected in native descriptors