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 class WXDLLEXPORT wxFontRefData
: public wxGDIRefData
41 m_info
.Init(10, wxFONTFAMILY_DEFAULT
, wxFONTSTYLE_NORMAL
, wxFONTWEIGHT_NORMAL
,
42 false, wxEmptyString
, wxFONTENCODING_DEFAULT
);
45 wxFontRefData(const wxFontRefData
& data
);
47 wxFontRefData( const wxNativeFontInfo
& info
) : m_info(info
)
52 wxFontRefData(wxOSXSystemFont font
, int size
);
54 #if wxOSX_USE_CORE_TEXT
55 wxFontRefData( wxUint32 coreTextFontType
);
56 wxFontRefData( CTFontRef font
);
57 wxFontRefData( CTFontDescriptorRef fontdescriptor
, int size
);
60 virtual ~wxFontRefData();
62 void SetPointSize( int size
)
64 if( GetPointSize() != size
)
66 m_info
.SetPointSize(size
);
71 int GetPointSize() const { return m_info
.GetPointSize(); }
73 void SetFamily( wxFontFamily family
)
75 if ( m_info
.m_family
!= family
)
77 m_info
.SetFamily( family
);
82 wxFontFamily
GetFamily() const { return m_info
.GetFamily(); }
84 void SetStyle( wxFontStyle style
)
86 if ( m_info
.m_style
!= style
)
88 m_info
.SetStyle( style
);
94 wxFontStyle
GetStyle() const { return m_info
.GetStyle(); }
96 void SetWeight( wxFontWeight weight
)
98 if ( m_info
.m_weight
!= weight
)
100 m_info
.SetWeight( weight
);
106 wxFontWeight
GetWeight() const { return m_info
.GetWeight(); }
108 void SetUnderlined( bool u
)
110 if ( m_info
.m_underlined
!= u
)
112 m_info
.SetUnderlined( u
);
117 bool GetUnderlined() const { return m_info
.GetUnderlined(); }
119 void SetFaceName( const wxString
& facename
)
121 if ( m_info
.m_faceName
!= facename
)
123 m_info
.SetFaceName( facename
);
128 wxString
GetFaceName() const { return m_info
.GetFaceName(); }
130 void SetEncoding( wxFontEncoding encoding
)
132 if ( m_info
.m_encoding
!= encoding
)
134 m_info
.SetEncoding( encoding
);
139 wxFontEncoding
GetEncoding() const { return m_info
.GetEncoding(); }
141 bool IsFixedWidth() const;
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 void CreateATSUFont();
166 ATSUStyle m_macATSUStyle
;
168 wxCFRef
<CGFontRef
> m_cgFont
;
175 wxNativeFontInfo m_info
;
178 #define M_FONTDATA ((wxFontRefData*)m_refData)
180 wxFontRefData::wxFontRefData(const wxFontRefData
& data
) : wxGDIRefData()
183 m_info
= data
.m_info
;
184 m_fontValid
= data
.m_fontValid
;
185 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
186 m_macThemeFontID
= data
.m_macThemeFontID
;
188 #if wxOSX_USE_CORE_TEXT
189 m_ctFont
= data
.m_ctFont
;
191 m_cgFont
= data
.m_cgFont
;
192 #if wxOSX_USE_ATSU_TEXT
193 if ( data
.m_macATSUStyle
!= NULL
)
195 ATSUCreateStyle(&m_macATSUStyle
) ;
196 ATSUCopyAttributes(data
.m_macATSUStyle
, m_macATSUStyle
);
200 m_nsFont
= (NSFont
*) wxMacCocoaRetain(data
.m_nsFont
);
203 m_uiFont
= (UIFont
*) wxMacCocoaRetain(data
.m_uiFont
);
208 // ============================================================================
210 // ============================================================================
212 // ----------------------------------------------------------------------------
214 // ----------------------------------------------------------------------------
216 void wxFontRefData::Init()
218 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
219 m_macThemeFontID
= kThemeCurrentPortFont
;
221 #if wxOSX_USE_ATSU_TEXT
222 m_macATSUStyle
= NULL
;
233 wxFontRefData::~wxFontRefData()
238 void wxFontRefData::Free()
240 #if wxOSX_USE_CORE_TEXT
244 #if wxOSX_USE_ATSU_TEXT
246 m_macThemeFontID
= kThemeCurrentPortFont
;
248 if ( m_macATSUStyle
)
250 ::ATSUDisposeStyle((ATSUStyle
)m_macATSUStyle
);
251 m_macATSUStyle
= NULL
;
255 if (m_nsFont
!= NULL
)
257 wxMacCocoaRelease(m_nsFont
);
262 if (m_uiFont
!= NULL
)
264 wxMacCocoaRelease(m_uiFont
);
271 wxFontRefData::wxFontRefData(wxOSXSystemFont font
, int size
)
273 wxASSERT( font
!= wxOSX_SYSTEM_FONT_NONE
);
276 #if wxOSX_USE_CORE_TEXT
278 CTFontUIFontType uifont
= kCTFontSystemFontType
;
281 case wxOSX_SYSTEM_FONT_NORMAL
:
282 uifont
= kCTFontSystemFontType
;
284 case wxOSX_SYSTEM_FONT_BOLD
:
285 uifont
= kCTFontEmphasizedSystemFontType
;
287 case wxOSX_SYSTEM_FONT_SMALL
:
288 uifont
= kCTFontSmallSystemFontType
;
290 case wxOSX_SYSTEM_FONT_SMALL_BOLD
:
291 uifont
= kCTFontSmallEmphasizedSystemFontType
;
293 case wxOSX_SYSTEM_FONT_MINI
:
294 uifont
= kCTFontMiniSystemFontType
;
296 case wxOSX_SYSTEM_FONT_MINI_BOLD
:
297 uifont
= kCTFontMiniEmphasizedSystemFontType
;
299 case wxOSX_SYSTEM_FONT_LABELS
:
300 uifont
= kCTFontLabelFontType
;
302 case wxOSX_SYSTEM_FONT_VIEWS
:
303 uifont
= kCTFontViewsFontType
;
308 m_ctFont
.reset(CTFontCreateUIFontForLanguage( uifont
, (CGFloat
) size
, NULL
));
309 wxCFRef
<CTFontDescriptorRef
> descr
;
310 descr
.reset( CTFontCopyFontDescriptor( m_ctFont
) );
314 #if wxOSX_USE_ATSU_TEXT
316 #if !wxOSX_USE_CARBON
317 // not needed outside
318 ThemeFontID m_macThemeFontID
= kThemeSystemFont
;
322 case wxOSX_SYSTEM_FONT_NORMAL
:
323 m_macThemeFontID
= kThemeSystemFont
;
325 case wxOSX_SYSTEM_FONT_BOLD
:
326 m_macThemeFontID
= kThemeEmphasizedSystemFont
;
328 case wxOSX_SYSTEM_FONT_SMALL
:
329 m_macThemeFontID
= kThemeSmallSystemFont
;
331 case wxOSX_SYSTEM_FONT_SMALL_BOLD
:
332 m_macThemeFontID
= kThemeSmallEmphasizedSystemFont
;
334 case wxOSX_SYSTEM_FONT_MINI
:
335 m_macThemeFontID
= kThemeMiniSystemFont
;
337 case wxOSX_SYSTEM_FONT_MINI_BOLD
:
338 // bold not available under theming
339 m_macThemeFontID
= kThemeMiniSystemFont
;
341 case wxOSX_SYSTEM_FONT_LABELS
:
342 m_macThemeFontID
= kThemeLabelFont
;
344 case wxOSX_SYSTEM_FONT_VIEWS
:
345 m_macThemeFontID
= kThemeViewsFont
;
350 if ( m_info
.m_faceName
.empty() )
356 GetThemeFont( m_macThemeFontID
, GetApplicationScript(), qdFontName
, &fontSize
, &style
);
360 wxFontStyle fontstyle
= wxFONTSTYLE_NORMAL
;
361 wxFontWeight fontweight
= wxFONTWEIGHT_NORMAL
;
362 bool underlined
= false;
365 fontweight
= wxFONTWEIGHT_BOLD
;
367 fontweight
= wxFONTWEIGHT_NORMAL
;
368 if ( style
& italic
)
369 fontstyle
= wxFONTSTYLE_ITALIC
;
370 if ( style
& underline
)
373 m_info
.Init(fontSize
,wxFONTFAMILY_DEFAULT
,fontstyle
,fontweight
,underlined
,
374 wxMacMakeStringFromPascal( qdFontName
), wxFONTENCODING_DEFAULT
);
379 m_nsFont
= wxFont::OSXCreateNSFont( font
, &m_info
);
382 m_uiFont
= wxFont::OSXCreateUIFont( font
, &m_info
);
384 m_info
.EnsureValid();
385 #if wxOSX_USE_ATSU_TEXT
392 #if wxOSX_USE_ATSU_TEXT
393 void wxFontRefData::CreateATSUFont()
395 // we try to get as much styles as possible into ATSU
397 OSStatus status
= ::ATSUCreateStyle(&m_macATSUStyle
);
398 wxASSERT_MSG( status
== noErr
, wxT("couldn't create ATSU style") );
400 ATSUAttributeTag atsuTags
[] =
404 kATSUVerticalCharacterTag
,
407 kATSUQDUnderlineTag
,
408 kATSUQDCondensedTag
,
411 ByteCount atsuSizes
[WXSIZEOF(atsuTags
)] =
413 sizeof( ATSUFontID
) ,
415 sizeof( ATSUVerticalCharacterType
),
423 Boolean kTrue
= true ;
424 Boolean kFalse
= false ;
426 Fixed atsuSize
= IntToFixed( m_info
.m_pointSize
);
427 ATSUVerticalCharacterType kHorizontal
= kATSUStronglyHorizontal
;
428 FMFontStyle addQDStyle
= m_info
.m_atsuAdditionalQDStyles
;
429 ATSUAttributeValuePtr atsuValues
[WXSIZEOF(atsuTags
)] =
431 &m_info
.m_atsuFontID
,
434 (addQDStyle
& bold
) ? &kTrue
: &kFalse
,
435 (addQDStyle
& italic
) ? &kTrue
: &kFalse
,
436 (addQDStyle
& underline
) ? &kTrue
: &kFalse
,
437 (addQDStyle
& condense
) ? &kTrue
: &kFalse
,
438 (addQDStyle
& extend
) ? &kTrue
: &kFalse
,
441 status
= ::ATSUSetAttributes(
442 (ATSUStyle
)m_macATSUStyle
,
444 atsuTags
, atsuSizes
, atsuValues
);
446 wxASSERT_MSG( status
== noErr
, wxString::Format(wxT("couldn't modify ATSU style. Status was %d"), (int) status
).c_str() );
448 if ( m_cgFont
.get() == NULL
)
450 ATSFontRef fontRef
= FMGetATSFontRefFromFont(m_info
.m_atsuFontID
);
451 m_cgFont
.reset( CGFontCreateWithPlatformFont( &fontRef
) );
456 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
457 static const CGAffineTransform kSlantTransform
= CGAffineTransformMake( 1, 0, tan(DegToRad(11)), 1, 0, 0 );
459 void wxFontRefData::MacFindFont()
464 wxCHECK_RET( m_info
.m_pointSize
> 0, wxT("Point size should not be zero.") );
466 m_info
.EnsureValid();
468 #if wxOSX_USE_CORE_TEXT
470 CTFontSymbolicTraits traits
= 0;
472 if (m_info
.m_weight
== wxFONTWEIGHT_BOLD
)
473 traits
|= kCTFontBoldTrait
;
474 if (m_info
.m_style
== wxFONTSTYLE_ITALIC
|| m_info
.m_style
== wxFONTSTYLE_SLANT
)
475 traits
|= kCTFontItalicTrait
;
478 wxString lookupnameWithSize
= wxString::Format( "%s_%u_%d", m_info
.m_faceName
, traits
, m_info
.m_pointSize
);
480 static std::map
< std::wstring
, wxCFRef
< CTFontRef
> > fontcache
;
481 m_ctFont
= fontcache
[ std::wstring(lookupnameWithSize
.wc_str()) ];
484 m_ctFont
.reset(CTFontCreateWithName( wxCFStringRef(m_info
.m_faceName
), m_info
.m_pointSize
, NULL
));
485 if ( m_ctFont
.get() == NULL
)
487 // TODO try fallbacks according to font type
488 m_ctFont
.reset(CTFontCreateUIFontForLanguage( kCTFontSystemFontType
, m_info
.m_pointSize
, NULL
));
494 // attempt native font variant, if not available, fallback to italic emulation mode and remove bold
495 CTFontRef fontWithTraits
= CTFontCreateCopyWithSymbolicTraits( m_ctFont
, 0, NULL
, traits
, traits
);
496 if ( fontWithTraits
== NULL
)
498 CTFontSymbolicTraits remainingTraits
= traits
;
499 const CGAffineTransform
* remainingTransform
= NULL
;
501 if( remainingTraits
& kCTFontItalicTrait
)
503 remainingTraits
&= ~kCTFontItalicTrait
;
504 remainingTransform
= &kSlantTransform
;
505 if ( remainingTraits
& kCTFontBoldTrait
)
507 // first try an emulated oblique with an existing bold font
508 fontWithTraits
= CTFontCreateCopyWithSymbolicTraits( m_ctFont
, 0, remainingTransform
, remainingTraits
, remainingTraits
);
509 if ( fontWithTraits
== NULL
)
511 // give in on the bold, try native oblique
512 fontWithTraits
= CTFontCreateCopyWithSymbolicTraits( m_ctFont
, 0, NULL
, kCTFontItalicTrait
, kCTFontItalicTrait
);
517 if ( fontWithTraits
== NULL
)
519 fontWithTraits
= CTFontCreateWithName( wxCFStringRef(m_info
.m_faceName
), m_info
.m_pointSize
, remainingTransform
);
523 if ( fontWithTraits
!= NULL
)
524 m_ctFont
.reset(fontWithTraits
);
529 m_cgFont
.reset(CTFontCopyGraphicsFont(m_ctFont
, NULL
));
533 #if wxOSX_USE_ATSU_TEXT
537 m_nsFont
= wxFont::OSXCreateNSFont( &m_info
);
540 m_uiFont
= wxFont::OSXCreateUIFont( &m_info
);
545 bool wxFontRefData::IsFixedWidth() const
547 #if wxOSX_USE_CORE_TEXT
548 CTFontSymbolicTraits traits
= CTFontGetSymbolicTraits(m_ctFont
);
549 return (traits
& kCTFontMonoSpaceTrait
) != 0;
555 // ----------------------------------------------------------------------------
557 // ----------------------------------------------------------------------------
559 bool wxFont::Create(const wxNativeFontInfo
& info
)
563 m_refData
= new wxFontRefData( info
);
569 wxFont::wxFont(wxOSXSystemFont font
)
571 m_refData
= new wxFontRefData( font
, 0 );
574 wxFont::wxFont(const wxString
& fontdesc
)
576 wxNativeFontInfo info
;
577 if ( info
.FromString(fontdesc
) )
581 bool wxFont::Create(int pointSize
,
586 const wxString
& faceNameParam
,
587 wxFontEncoding encoding
)
591 wxString faceName
= faceNameParam
;
593 if ( faceName
.empty() )
597 case wxFONTFAMILY_DEFAULT
:
598 faceName
= wxT("Lucida Grande");
601 case wxFONTFAMILY_SCRIPT
:
602 case wxFONTFAMILY_ROMAN
:
603 case wxFONTFAMILY_DECORATIVE
:
604 faceName
= wxT("Times");
607 case wxFONTFAMILY_SWISS
:
608 faceName
= wxT("Helvetica");
611 case wxFONTFAMILY_MODERN
:
612 case wxFONTFAMILY_TELETYPE
:
613 faceName
= wxT("Courier");
617 faceName
= wxT("Times");
622 wxNativeFontInfo info
;
624 info
.Init(pointSize
, family
, style
, weight
,
625 underlined
, faceName
, encoding
);
627 m_refData
= new wxFontRefData(info
);
636 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo
& info
)
640 m_refData
= new wxFontRefData( info
);
644 bool wxFont::RealizeResource()
646 M_FONTDATA
->MacFindFont();
651 void wxFont::SetEncoding(wxFontEncoding encoding
)
655 M_FONTDATA
->SetEncoding( encoding
);
658 wxGDIRefData
*wxFont::CreateGDIRefData() const
660 return new wxFontRefData
;
663 wxGDIRefData
*wxFont::CloneGDIRefData(const wxGDIRefData
*data
) const
665 return new wxFontRefData(*static_cast<const wxFontRefData
*>(data
));
668 void wxFont::SetPointSize(int pointSize
)
670 if ( M_FONTDATA
!= NULL
&& M_FONTDATA
->GetPointSize() == pointSize
)
675 M_FONTDATA
->SetPointSize( pointSize
);
678 void wxFont::SetFamily(wxFontFamily family
)
682 M_FONTDATA
->SetFamily( family
);
685 void wxFont::SetStyle(wxFontStyle style
)
689 M_FONTDATA
->SetStyle( style
);
692 void wxFont::SetWeight(wxFontWeight weight
)
696 M_FONTDATA
->SetWeight( weight
);
699 bool wxFont::SetFaceName(const wxString
& faceName
)
703 M_FONTDATA
->SetFaceName( faceName
);
705 return wxFontBase::SetFaceName(faceName
);
708 void wxFont::SetUnderlined(bool underlined
)
712 M_FONTDATA
->SetUnderlined( underlined
);
715 // ----------------------------------------------------------------------------
717 // ----------------------------------------------------------------------------
719 // TODO: insert checks everywhere for M_FONTDATA == NULL!
721 int wxFont::GetPointSize() const
723 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
725 return M_FONTDATA
->GetPointSize();
728 wxSize
wxFont::GetPixelSize() const
730 #if wxUSE_GRAPHICS_CONTEXT
731 // TODO: consider caching the value
732 wxGraphicsContext
* dc
= wxGraphicsContext::CreateFromNative((CGContextRef
) NULL
);
733 dc
->SetFont(*(wxFont
*)this,*wxBLACK
);
734 wxDouble width
, height
= 0;
735 dc
->GetTextExtent( wxT("g"), &width
, &height
, NULL
, NULL
);
737 return wxSize((int)width
, (int)height
);
739 return wxFontBase::GetPixelSize();
743 bool wxFont::IsFixedWidth() const
745 wxCHECK_MSG( M_FONTDATA
!= NULL
, false, wxT("invalid font") );
747 // cast away constness otherwise lazy font resolution is not possible
748 const_cast<wxFont
*>(this)->RealizeResource();
750 return M_FONTDATA
->IsFixedWidth();
753 wxFontFamily
wxFont::DoGetFamily() const
755 return M_FONTDATA
->GetFamily();
758 wxFontStyle
wxFont::GetStyle() const
760 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTSTYLE_MAX
, wxT("invalid font") );
762 return M_FONTDATA
->GetStyle() ;
765 wxFontWeight
wxFont::GetWeight() const
767 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTWEIGHT_MAX
, wxT("invalid font") );
769 return M_FONTDATA
->GetWeight();
772 bool wxFont::GetUnderlined() const
774 wxCHECK_MSG( M_FONTDATA
!= NULL
, false, wxT("invalid font") );
776 return M_FONTDATA
->GetUnderlined();
779 wxString
wxFont::GetFaceName() const
781 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxEmptyString
, wxT("invalid font") );
783 return M_FONTDATA
->GetFaceName() ;
786 wxFontEncoding
wxFont::GetEncoding() const
788 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTENCODING_DEFAULT
, wxT("invalid font") );
790 return M_FONTDATA
->GetEncoding() ;
793 #if wxOSX_USE_ATSU_TEXT && wxOSX_USE_CARBON
795 short wxFont::MacGetFontNum() const
797 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
799 // cast away constness otherwise lazy font resolution is not possible
800 const_cast<wxFont
*>(this)->RealizeResource();
802 return M_FONTDATA
->m_info
.m_qdFontFamily
;
805 wxByte
wxFont::MacGetFontStyle() const
807 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
809 // cast away constness otherwise lazy font resolution is not possible
810 const_cast<wxFont
*>(this)->RealizeResource();
812 return M_FONTDATA
->m_info
.m_qdFontStyle
;
815 wxUint16
wxFont::MacGetThemeFontID() const
817 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
819 return M_FONTDATA
->m_macThemeFontID
;
824 #if wxOSX_USE_ATSU_TEXT
825 void * wxFont::MacGetATSUStyle() const
827 wxCHECK_MSG( M_FONTDATA
!= NULL
, NULL
, 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_macATSUStyle
;
835 wxUint32
wxFont::MacGetATSUFontID() const
837 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
839 // cast away constness otherwise lazy font resolution is not possible
840 const_cast<wxFont
*>(this)->RealizeResource();
842 return M_FONTDATA
->m_info
.m_atsuFontID
;
845 wxUint32
wxFont::MacGetATSUAdditionalQDStyles() const
847 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
849 // cast away constness otherwise lazy font resolution is not possible
850 const_cast<wxFont
*>(this)->RealizeResource();
852 return M_FONTDATA
->m_info
.m_atsuAdditionalQDStyles
;
856 #if wxOSX_USE_CORE_TEXT
858 CTFontRef
wxFont::OSXGetCTFont() const
860 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
862 // cast away constness otherwise lazy font resolution is not possible
863 const_cast<wxFont
*>(this)->RealizeResource();
865 return (CTFontRef
)(M_FONTDATA
->m_ctFont
);
870 #if wxOSX_USE_COCOA_OR_CARBON
872 CGFontRef
wxFont::OSXGetCGFont() const
874 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
876 // cast away constness otherwise lazy font resolution is not possible
877 const_cast<wxFont
*>(this)->RealizeResource();
879 return (M_FONTDATA
->m_cgFont
);
887 NSFont
* wxFont::OSXGetNSFont() const
889 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
891 // cast away constness otherwise lazy font resolution is not possible
892 const_cast<wxFont
*>(this)->RealizeResource();
894 return (M_FONTDATA
->m_nsFont
);
901 UIFont
* wxFont::OSXGetUIFont() const
903 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
905 // cast away constness otherwise lazy font resolution is not possible
906 const_cast<wxFont
*>(this)->RealizeResource();
908 return (M_FONTDATA
->m_uiFont
);
913 const wxNativeFontInfo
* wxFont::GetNativeFontInfo() const
915 wxCHECK_MSG( M_FONTDATA
!= NULL
, NULL
, wxT("invalid font") );
916 wxCHECK_MSG( IsOk(), NULL
, wxT("invalid font") );
918 // cast away constness otherwise lazy font resolution is not possible
919 const_cast<wxFont
*>(this)->RealizeResource();
921 // M_FONTDATA->m_info.InitFromFont(*this);
923 return &(M_FONTDATA
->m_info
);
926 // ----------------------------------------------------------------------------
928 // ----------------------------------------------------------------------------
930 #if 0 // wxOSX_USE_CORE_TEXT
932 /* from Core Text Manual Common Operations */
934 static CTFontDescriptorRef
wxMacCreateCTFontDescriptor(CFStringRef iFamilyName
, CTFontSymbolicTraits iTraits
)
936 CTFontDescriptorRef descriptor
= NULL
;
937 CFMutableDictionaryRef attributes
;
939 wxASSERT(iFamilyName
!= NULL
);
940 // Create a mutable dictionary to hold our attributes.
941 attributes
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
942 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
943 wxASSERT(attributes
!= NULL
);
945 if (attributes
!= NULL
) {
946 // Add a family name to our attributes.
947 CFDictionaryAddValue(attributes
, kCTFontFamilyNameAttribute
, iFamilyName
);
951 CFMutableDictionaryRef traits
;
952 CFNumberRef symTraits
;
954 // Create the traits dictionary.
955 symTraits
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
957 wxASSERT(symTraits
!= NULL
);
959 if (symTraits
!= NULL
) {
960 // Create a dictionary to hold our traits values.
961 traits
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
962 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
963 wxASSERT(traits
!= NULL
);
965 if (traits
!= NULL
) {
966 // Add the symbolic traits value to the traits dictionary.
967 CFDictionaryAddValue(traits
, kCTFontSymbolicTrait
, symTraits
);
969 // Add the traits attribute to our attributes.
970 CFDictionaryAddValue(attributes
, kCTFontTraitsAttribute
, traits
);
973 CFRelease(symTraits
);
976 // Create the font descriptor with our attributes
977 descriptor
= CTFontDescriptorCreateWithAttributes(attributes
);
978 wxASSERT(descriptor
!= NULL
);
980 CFRelease(attributes
);
982 // Return our font descriptor.
988 void wxNativeFontInfo::Init()
990 #if wxOSX_USE_ATSU_TEXT
992 m_atsuAdditionalQDStyles
= 0;
993 m_atsuFontValid
= false;
1000 m_family
= wxFONTFAMILY_DEFAULT
;
1001 m_style
= wxFONTSTYLE_NORMAL
;
1002 m_weight
= wxFONTWEIGHT_NORMAL
;
1003 m_underlined
= false;
1005 m_encoding
= wxFont::GetDefaultEncoding();
1006 m_descriptorValid
= false;
1009 #if wxOSX_USE_CORE_TEXT
1010 void wxNativeFontInfo::Init(CTFontDescriptorRef descr
)
1014 wxCFRef
< CFNumberRef
> sizevalue( (CFNumberRef
) CTFontDescriptorCopyAttribute( descr
, kCTFontSizeAttribute
) );
1016 if ( CFNumberGetValue( sizevalue
, kCFNumberFloatType
, &fsize
) )
1017 m_pointSize
= (int)( fsize
+ 0.5 );
1019 wxCFRef
< CFDictionaryRef
> traitsvalue( (CFDictionaryRef
) CTFontDescriptorCopyAttribute( descr
, kCTFontTraitsAttribute
) );
1020 CTFontSymbolicTraits traits
;
1021 if ( CFNumberGetValue((CFNumberRef
) CFDictionaryGetValue(traitsvalue
,kCTFontSymbolicTrait
),kCFNumberIntType
,&traits
) )
1023 if ( traits
& kCTFontItalicTrait
)
1024 m_style
= wxFONTSTYLE_ITALIC
;
1025 if ( traits
& kCTFontBoldTrait
)
1026 m_weight
= wxFONTWEIGHT_BOLD
;
1029 wxCFStringRef
familyName( (CFStringRef
) CTFontDescriptorCopyAttribute(descr
, kCTFontFamilyNameAttribute
));
1030 m_faceName
= familyName
.AsString();
1034 void wxNativeFontInfo::EnsureValid()
1036 if ( m_descriptorValid
)
1039 #if wxOSX_USE_ATSU_TEXT
1040 if ( !m_atsuFontValid
)
1042 #if !wxOSX_USE_CARBON
1043 // not needed outside
1044 wxInt16 m_qdFontFamily
;
1045 wxInt16 m_qdFontStyle
;
1047 wxCFStringRef
cf( m_faceName
, wxLocale::GetSystemEncoding() );
1048 ATSFontFamilyRef atsfamily
= ATSFontFamilyFindFromName( cf
, kATSOptionFlagsDefault
);
1049 if ( atsfamily
== (ATSFontFamilyRef
) -1 )
1051 wxLogDebug( wxT("ATSFontFamilyFindFromName failed for ") + m_faceName
);
1052 m_qdFontFamily
= GetAppFont();
1056 m_qdFontFamily
= FMGetFontFamilyFromATSFontFamilyRef( atsfamily
);
1060 if (m_weight
== wxFONTWEIGHT_BOLD
)
1061 m_qdFontStyle
|= bold
;
1062 if (m_style
== wxFONTSTYLE_ITALIC
|| m_style
== wxFONTSTYLE_SLANT
)
1063 m_qdFontStyle
|= italic
;
1065 m_qdFontStyle
|= underline
;
1068 // we try to get as much styles as possible into ATSU
1070 // ATSUFontID and FMFont are equivalent
1071 FMFontStyle intrinsicStyle
= 0 ;
1072 OSStatus status
= FMGetFontFromFontFamilyInstance( m_qdFontFamily
, m_qdFontStyle
, (FMFont
*)&m_atsuFontID
, &intrinsicStyle
);
1073 if ( status
!= noErr
)
1075 wxFAIL_MSG( wxT("couldn't get an ATSUFont from font family") );
1077 m_atsuAdditionalQDStyles
= m_qdFontStyle
& (~intrinsicStyle
);
1078 m_atsuFontValid
= true;
1081 m_descriptorValid
= true;
1084 void wxNativeFontInfo::Init(const wxNativeFontInfo
& info
)
1087 #if wxOSX_USE_ATSU_TEXT
1088 m_atsuFontValid
= info
.m_atsuFontValid
;
1089 m_atsuFontID
= info
.m_atsuFontID
;
1090 m_atsuAdditionalQDStyles
= info
.m_atsuAdditionalQDStyles
;
1091 #if wxOSX_USE_CARBON
1092 m_qdFontFamily
= info
.m_qdFontFamily
;
1093 m_qdFontStyle
= info
.m_qdFontStyle
;
1096 m_pointSize
= info
.m_pointSize
;
1097 m_family
= info
.m_family
;
1098 m_style
= info
.m_style
;
1099 m_weight
= info
.m_weight
;
1100 m_underlined
= info
.m_underlined
;
1101 m_faceName
= info
.m_faceName
;
1102 m_encoding
= info
.m_encoding
;
1103 m_descriptorValid
= info
.m_descriptorValid
;
1106 void wxNativeFontInfo::Init(int size
,
1107 wxFontFamily family
,
1109 wxFontWeight weight
,
1111 const wxString
& faceName
,
1112 wxFontEncoding encoding
)
1116 // We should use the default font size if the special value wxDEFAULT is
1117 // specified and we also handle -1 as a synonym for wxDEFAULT for
1118 // compatibility with wxGTK (see #12541).
1120 // Notice that we rely on the fact that wxNORMAL_FONT itself is not
1121 // initialized using this ctor, but from native font info.
1122 m_pointSize
= size
== -1 || size
== wxDEFAULT
1123 ? wxNORMAL_FONT
->GetPointSize()
1128 m_underlined
= underlined
;
1129 m_faceName
= faceName
;
1130 if ( encoding
== wxFONTENCODING_DEFAULT
)
1131 encoding
= wxFont::GetDefaultEncoding();
1132 m_encoding
= encoding
;
1136 void wxNativeFontInfo::Free()
1138 #if wxOSX_USE_ATSU_TEXT
1140 m_atsuAdditionalQDStyles
= 0;
1141 m_atsuFontValid
= false;
1143 m_descriptorValid
= false;
1146 bool wxNativeFontInfo::FromString(const wxString
& s
)
1150 wxStringTokenizer
tokenizer(s
, wxT(";"));
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(wxT("%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 bool wxNativeFontInfo::GetStrikethrough() const
1255 // changing the font descriptor
1257 void wxNativeFontInfo::SetPointSize(int pointsize
)
1259 if ( m_pointSize
!= pointsize
)
1261 m_pointSize
= pointsize
;
1266 void wxNativeFontInfo::SetStyle(wxFontStyle style_
)
1268 if ( m_style
!= style_
)
1275 void wxNativeFontInfo::SetWeight(wxFontWeight weight_
)
1277 if ( m_weight
!= weight_
)
1284 void wxNativeFontInfo::SetUnderlined(bool underlined_
)
1286 if ( m_underlined
!= underlined_
)
1288 m_underlined
= underlined_
;
1293 bool wxNativeFontInfo::SetFaceName(const wxString
& facename_
)
1295 if ( m_faceName
!= facename_
)
1297 m_faceName
= facename_
;
1303 void wxNativeFontInfo::SetFamily(wxFontFamily family_
)
1305 if ( m_family
!= family_
)
1312 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_
)
1314 if ( encoding_
== wxFONTENCODING_DEFAULT
)
1315 encoding_
= wxFont::GetDefaultEncoding();
1316 m_encoding
= encoding_
;
1317 // not reflected in native descriptors
1320 void wxNativeFontInfo::SetStrikethrough(bool WXUNUSED(strikethrough
))