1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/font.cpp
3 // Purpose: wxFont class
4 // Author: Stefan Csomor
7 // Copyright: (c) Stefan Csomor
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 #include "wx/wxprec.h"
16 #include "wx/string.h"
19 #include "wx/gdicmn.h"
23 #include "wx/fontutil.h"
24 #include "wx/graphics.h"
25 #include "wx/settings.h"
26 #include "wx/tokenzr.h"
28 #include "wx/osx/private.h"
33 class WXDLLEXPORT wxFontRefData
: public wxGDIRefData
40 m_info
.Init(10, wxFONTFAMILY_DEFAULT
, wxFONTSTYLE_NORMAL
, wxFONTWEIGHT_NORMAL
,
41 false, wxEmptyString
, wxFONTENCODING_DEFAULT
);
44 wxFontRefData(const wxFontRefData
& data
);
46 wxFontRefData( const wxNativeFontInfo
& info
) : m_info(info
)
51 wxFontRefData(wxOSXSystemFont font
, int size
);
53 #if wxOSX_USE_CORE_TEXT
54 wxFontRefData( wxUint32 coreTextFontType
);
55 wxFontRefData( CTFontRef font
);
56 wxFontRefData( CTFontDescriptorRef fontdescriptor
, int size
);
59 virtual ~wxFontRefData();
61 void SetPointSize( int size
)
63 if( GetPointSize() != size
)
65 m_info
.SetPointSize(size
);
70 int GetPointSize() const { return m_info
.GetPointSize(); }
72 void SetFamily( wxFontFamily family
)
74 if ( m_info
.m_family
!= family
)
76 m_info
.SetFamily( family
);
81 wxFontFamily
GetFamily() const { return m_info
.GetFamily(); }
83 void SetStyle( wxFontStyle style
)
85 if ( m_info
.m_style
!= style
)
87 m_info
.SetStyle( style
);
93 wxFontStyle
GetStyle() const { return m_info
.GetStyle(); }
95 void SetWeight( wxFontWeight weight
)
97 if ( m_info
.m_weight
!= weight
)
99 m_info
.SetWeight( weight
);
105 wxFontWeight
GetWeight() const { return m_info
.GetWeight(); }
107 void SetUnderlined( bool u
)
109 if ( m_info
.m_underlined
!= u
)
111 m_info
.SetUnderlined( u
);
116 bool GetUnderlined() const { return m_info
.GetUnderlined(); }
118 void SetFaceName( const wxString
& facename
)
120 if ( m_info
.m_faceName
!= facename
)
122 m_info
.SetFaceName( facename
);
127 wxString
GetFaceName() const { return m_info
.GetFaceName(); }
129 void SetEncoding( wxFontEncoding encoding
)
131 if ( m_info
.m_encoding
!= encoding
)
133 m_info
.SetEncoding( encoding
);
138 wxFontEncoding
GetEncoding() const { return m_info
.GetEncoding(); }
140 bool IsFixedWidth() const;
147 // common part of all ctors
149 #if wxOSX_USE_CORE_TEXT
150 // void Init( CTFontRef font );
154 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
155 // for true theming support we must store the correct font
156 // information here, as this speeds up and optimizes rendering
157 ThemeFontID m_macThemeFontID
;
159 #if wxOSX_USE_CORE_TEXT
160 wxCFRef
<CTFontRef
> m_ctFont
;
162 #if wxOSX_USE_ATSU_TEXT
163 void CreateATSUFont();
165 ATSUStyle m_macATSUStyle
;
167 wxCFRef
<CGFontRef
> m_cgFont
;
174 wxNativeFontInfo m_info
;
177 #define M_FONTDATA ((wxFontRefData*)m_refData)
179 wxFontRefData::wxFontRefData(const wxFontRefData
& data
) : wxGDIRefData()
182 m_info
= data
.m_info
;
183 m_fontValid
= data
.m_fontValid
;
184 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
185 m_macThemeFontID
= data
.m_macThemeFontID
;
187 #if wxOSX_USE_CORE_TEXT
188 m_ctFont
= data
.m_ctFont
;
190 m_cgFont
= data
.m_cgFont
;
191 #if wxOSX_USE_ATSU_TEXT
192 if ( data
.m_macATSUStyle
!= NULL
)
194 ATSUCreateStyle(&m_macATSUStyle
) ;
195 ATSUCopyAttributes(data
.m_macATSUStyle
, m_macATSUStyle
);
199 m_nsFont
= (NSFont
*) wxMacCocoaRetain(data
.m_nsFont
);
202 m_uiFont
= (UIFont
*) wxMacCocoaRetain(data
.m_uiFont
);
207 // ============================================================================
209 // ============================================================================
211 // ----------------------------------------------------------------------------
213 // ----------------------------------------------------------------------------
215 void wxFontRefData::Init()
217 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
218 m_macThemeFontID
= kThemeCurrentPortFont
;
220 #if wxOSX_USE_ATSU_TEXT
221 m_macATSUStyle
= NULL
;
232 wxFontRefData::~wxFontRefData()
237 void wxFontRefData::Free()
239 #if wxOSX_USE_CORE_TEXT
243 #if wxOSX_USE_ATSU_TEXT
245 m_macThemeFontID
= kThemeCurrentPortFont
;
247 if ( m_macATSUStyle
)
249 ::ATSUDisposeStyle((ATSUStyle
)m_macATSUStyle
);
250 m_macATSUStyle
= NULL
;
254 if (m_nsFont
!= NULL
)
256 wxMacCocoaRelease(m_nsFont
);
261 if (m_uiFont
!= NULL
)
263 wxMacCocoaRelease(m_uiFont
);
270 wxFontRefData::wxFontRefData(wxOSXSystemFont font
, int size
)
272 wxASSERT( font
!= wxOSX_SYSTEM_FONT_NONE
);
275 #if wxOSX_USE_CORE_TEXT
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
);
383 m_info
.EnsureValid();
384 #if wxOSX_USE_ATSU_TEXT
391 #if wxOSX_USE_ATSU_TEXT
392 void wxFontRefData::CreateATSUFont()
394 // we try to get as much styles as possible into ATSU
396 OSStatus status
= ::ATSUCreateStyle(&m_macATSUStyle
);
397 wxASSERT_MSG( status
== noErr
, wxT("couldn't create ATSU style") );
399 ATSUAttributeTag atsuTags
[] =
403 kATSUVerticalCharacterTag
,
406 kATSUQDUnderlineTag
,
407 kATSUQDCondensedTag
,
410 ByteCount atsuSizes
[WXSIZEOF(atsuTags
)] =
412 sizeof( ATSUFontID
) ,
414 sizeof( ATSUVerticalCharacterType
),
422 Boolean kTrue
= true ;
423 Boolean kFalse
= false ;
425 Fixed atsuSize
= IntToFixed( m_info
.m_pointSize
);
426 ATSUVerticalCharacterType kHorizontal
= kATSUStronglyHorizontal
;
427 FMFontStyle addQDStyle
= m_info
.m_atsuAdditionalQDStyles
;
428 ATSUAttributeValuePtr atsuValues
[WXSIZEOF(atsuTags
)] =
430 &m_info
.m_atsuFontID
,
433 (addQDStyle
& bold
) ? &kTrue
: &kFalse
,
434 (addQDStyle
& italic
) ? &kTrue
: &kFalse
,
435 (addQDStyle
& underline
) ? &kTrue
: &kFalse
,
436 (addQDStyle
& condense
) ? &kTrue
: &kFalse
,
437 (addQDStyle
& extend
) ? &kTrue
: &kFalse
,
440 status
= ::ATSUSetAttributes(
441 (ATSUStyle
)m_macATSUStyle
,
443 atsuTags
, atsuSizes
, atsuValues
);
445 wxASSERT_MSG( status
== noErr
, wxString::Format(wxT("couldn't modify ATSU style. Status was %d"), (int) status
).c_str() );
447 if ( m_cgFont
.get() == NULL
)
449 ATSFontRef fontRef
= FMGetATSFontRefFromFont(m_info
.m_atsuFontID
);
450 m_cgFont
.reset( CGFontCreateWithPlatformFont( &fontRef
) );
455 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
456 static const CGAffineTransform kSlantTransform
= CGAffineTransformMake( 1, 0, tan(DegToRad(11)), 1, 0, 0 );
458 void wxFontRefData::MacFindFont()
463 wxCHECK_RET( m_info
.m_pointSize
> 0, wxT("Point size should not be zero.") );
465 m_info
.EnsureValid();
467 #if wxOSX_USE_CORE_TEXT
469 CTFontSymbolicTraits traits
= 0;
471 if (m_info
.m_weight
== wxFONTWEIGHT_BOLD
)
472 traits
|= kCTFontBoldTrait
;
473 if (m_info
.m_style
== wxFONTSTYLE_ITALIC
|| m_info
.m_style
== wxFONTSTYLE_SLANT
)
474 traits
|= kCTFontItalicTrait
;
477 wxString lookupnameWithSize
= wxString::Format( "%s_%u_%d", m_info
.m_faceName
, traits
, m_info
.m_pointSize
);
479 static std::map
< std::wstring
, wxCFRef
< CTFontRef
> > fontcache
;
480 m_ctFont
= fontcache
[ std::wstring(lookupnameWithSize
.wc_str()) ];
483 m_ctFont
.reset(CTFontCreateWithName( wxCFStringRef(m_info
.m_faceName
), m_info
.m_pointSize
, NULL
));
484 if ( m_ctFont
.get() == NULL
)
486 // TODO try fallbacks according to font type
487 m_ctFont
.reset(CTFontCreateUIFontForLanguage( kCTFontSystemFontType
, m_info
.m_pointSize
, NULL
));
493 // attempt native font variant, if not available, fallback to italic emulation mode and remove bold
494 CTFontRef fontWithTraits
= CTFontCreateCopyWithSymbolicTraits( m_ctFont
, 0, NULL
, traits
, traits
);
495 if ( fontWithTraits
== NULL
)
497 CTFontSymbolicTraits remainingTraits
= traits
;
498 const CGAffineTransform
* remainingTransform
= NULL
;
500 if( remainingTraits
& kCTFontItalicTrait
)
502 remainingTraits
&= ~kCTFontItalicTrait
;
503 remainingTransform
= &kSlantTransform
;
504 if ( remainingTraits
& kCTFontBoldTrait
)
506 // first try an emulated oblique with an existing bold font
507 fontWithTraits
= CTFontCreateCopyWithSymbolicTraits( m_ctFont
, 0, remainingTransform
, remainingTraits
, remainingTraits
);
508 if ( fontWithTraits
== NULL
)
510 // give in on the bold, try native oblique
511 fontWithTraits
= CTFontCreateCopyWithSymbolicTraits( m_ctFont
, 0, NULL
, kCTFontItalicTrait
, kCTFontItalicTrait
);
516 if ( fontWithTraits
== NULL
)
518 fontWithTraits
= CTFontCreateWithName( wxCFStringRef(m_info
.m_faceName
), m_info
.m_pointSize
, remainingTransform
);
522 if ( fontWithTraits
!= NULL
)
523 m_ctFont
.reset(fontWithTraits
);
528 m_cgFont
.reset(CTFontCopyGraphicsFont(m_ctFont
, NULL
));
532 #if wxOSX_USE_ATSU_TEXT
536 m_nsFont
= wxFont::OSXCreateNSFont( &m_info
);
539 m_uiFont
= wxFont::OSXCreateUIFont( &m_info
);
544 bool wxFontRefData::IsFixedWidth() const
546 #if wxOSX_USE_CORE_TEXT
547 CTFontSymbolicTraits traits
= CTFontGetSymbolicTraits(m_ctFont
);
548 return (traits
& kCTFontMonoSpaceTrait
) != 0;
554 // ----------------------------------------------------------------------------
556 // ----------------------------------------------------------------------------
558 bool wxFont::Create(const wxNativeFontInfo
& info
)
562 m_refData
= new wxFontRefData( info
);
568 wxFont::wxFont(wxOSXSystemFont font
)
570 m_refData
= new wxFontRefData( font
, 0 );
573 wxFont::wxFont(const wxString
& fontdesc
)
575 wxNativeFontInfo info
;
576 if ( info
.FromString(fontdesc
) )
580 bool wxFont::Create(int pointSize
,
585 const wxString
& faceNameParam
,
586 wxFontEncoding encoding
)
590 wxString faceName
= faceNameParam
;
592 if ( faceName
.empty() )
596 case wxFONTFAMILY_DEFAULT
:
597 faceName
= wxT("Lucida Grande");
600 case wxFONTFAMILY_SCRIPT
:
601 case wxFONTFAMILY_ROMAN
:
602 case wxFONTFAMILY_DECORATIVE
:
603 faceName
= wxT("Times");
606 case wxFONTFAMILY_SWISS
:
607 faceName
= wxT("Helvetica");
610 case wxFONTFAMILY_MODERN
:
611 case wxFONTFAMILY_TELETYPE
:
612 faceName
= wxT("Courier");
616 faceName
= wxT("Times");
621 wxNativeFontInfo info
;
623 info
.Init(pointSize
, family
, style
, weight
,
624 underlined
, faceName
, encoding
);
626 m_refData
= new wxFontRefData(info
);
635 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo
& info
)
639 m_refData
= new wxFontRefData( info
);
643 bool wxFont::RealizeResource()
645 M_FONTDATA
->MacFindFont();
650 void wxFont::SetEncoding(wxFontEncoding encoding
)
654 M_FONTDATA
->SetEncoding( encoding
);
657 wxGDIRefData
*wxFont::CreateGDIRefData() const
659 return new wxFontRefData
;
662 wxGDIRefData
*wxFont::CloneGDIRefData(const wxGDIRefData
*data
) const
664 return new wxFontRefData(*static_cast<const wxFontRefData
*>(data
));
667 void wxFont::SetPointSize(int pointSize
)
669 if ( M_FONTDATA
!= NULL
&& M_FONTDATA
->GetPointSize() == pointSize
)
674 M_FONTDATA
->SetPointSize( pointSize
);
677 void wxFont::SetFamily(wxFontFamily family
)
681 M_FONTDATA
->SetFamily( family
);
684 void wxFont::SetStyle(wxFontStyle style
)
688 M_FONTDATA
->SetStyle( style
);
691 void wxFont::SetWeight(wxFontWeight weight
)
695 M_FONTDATA
->SetWeight( weight
);
698 bool wxFont::SetFaceName(const wxString
& faceName
)
702 M_FONTDATA
->SetFaceName( faceName
);
704 return wxFontBase::SetFaceName(faceName
);
707 void wxFont::SetUnderlined(bool underlined
)
711 M_FONTDATA
->SetUnderlined( underlined
);
714 // ----------------------------------------------------------------------------
716 // ----------------------------------------------------------------------------
718 // TODO: insert checks everywhere for M_FONTDATA == NULL!
720 int wxFont::GetPointSize() const
722 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
724 return M_FONTDATA
->GetPointSize();
727 wxSize
wxFont::GetPixelSize() const
729 #if wxUSE_GRAPHICS_CONTEXT
730 // TODO: consider caching the value
731 wxGraphicsContext
* dc
= wxGraphicsContext::CreateFromNative((CGContextRef
) NULL
);
732 dc
->SetFont(*(wxFont
*)this,*wxBLACK
);
733 wxDouble width
, height
= 0;
734 dc
->GetTextExtent( wxT("g"), &width
, &height
, NULL
, NULL
);
736 return wxSize((int)width
, (int)height
);
738 return wxFontBase::GetPixelSize();
742 bool wxFont::IsFixedWidth() const
744 wxCHECK_MSG( M_FONTDATA
!= NULL
, false, wxT("invalid font") );
746 // cast away constness otherwise lazy font resolution is not possible
747 const_cast<wxFont
*>(this)->RealizeResource();
749 return M_FONTDATA
->IsFixedWidth();
752 wxFontFamily
wxFont::DoGetFamily() const
754 return M_FONTDATA
->GetFamily();
757 wxFontStyle
wxFont::GetStyle() const
759 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTSTYLE_MAX
, wxT("invalid font") );
761 return M_FONTDATA
->GetStyle() ;
764 wxFontWeight
wxFont::GetWeight() const
766 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTWEIGHT_MAX
, wxT("invalid font") );
768 return M_FONTDATA
->GetWeight();
771 bool wxFont::GetUnderlined() const
773 wxCHECK_MSG( M_FONTDATA
!= NULL
, false, wxT("invalid font") );
775 return M_FONTDATA
->GetUnderlined();
778 wxString
wxFont::GetFaceName() const
780 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxEmptyString
, wxT("invalid font") );
782 return M_FONTDATA
->GetFaceName() ;
785 wxFontEncoding
wxFont::GetEncoding() const
787 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTENCODING_DEFAULT
, wxT("invalid font") );
789 return M_FONTDATA
->GetEncoding() ;
792 #if wxOSX_USE_ATSU_TEXT && wxOSX_USE_CARBON
794 short wxFont::MacGetFontNum() const
796 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
798 // cast away constness otherwise lazy font resolution is not possible
799 const_cast<wxFont
*>(this)->RealizeResource();
801 return M_FONTDATA
->m_info
.m_qdFontFamily
;
804 wxByte
wxFont::MacGetFontStyle() 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_info
.m_qdFontStyle
;
814 wxUint16
wxFont::MacGetThemeFontID() const
816 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
818 return M_FONTDATA
->m_macThemeFontID
;
823 #if wxOSX_USE_ATSU_TEXT
824 void * wxFont::MacGetATSUStyle() const
826 wxCHECK_MSG( M_FONTDATA
!= NULL
, NULL
, wxT("invalid font") );
828 // cast away constness otherwise lazy font resolution is not possible
829 const_cast<wxFont
*>(this)->RealizeResource();
831 return M_FONTDATA
->m_macATSUStyle
;
834 wxUint32
wxFont::MacGetATSUFontID() const
836 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
838 // cast away constness otherwise lazy font resolution is not possible
839 const_cast<wxFont
*>(this)->RealizeResource();
841 return M_FONTDATA
->m_info
.m_atsuFontID
;
844 wxUint32
wxFont::MacGetATSUAdditionalQDStyles() const
846 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
848 // cast away constness otherwise lazy font resolution is not possible
849 const_cast<wxFont
*>(this)->RealizeResource();
851 return M_FONTDATA
->m_info
.m_atsuAdditionalQDStyles
;
855 #if wxOSX_USE_CORE_TEXT
857 CTFontRef
wxFont::OSXGetCTFont() const
859 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
861 // cast away constness otherwise lazy font resolution is not possible
862 const_cast<wxFont
*>(this)->RealizeResource();
864 return (CTFontRef
)(M_FONTDATA
->m_ctFont
);
869 #if wxOSX_USE_COCOA_OR_CARBON
871 CGFontRef
wxFont::OSXGetCGFont() const
873 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
875 // cast away constness otherwise lazy font resolution is not possible
876 const_cast<wxFont
*>(this)->RealizeResource();
878 return (M_FONTDATA
->m_cgFont
);
886 NSFont
* wxFont::OSXGetNSFont() const
888 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
890 // cast away constness otherwise lazy font resolution is not possible
891 const_cast<wxFont
*>(this)->RealizeResource();
893 return (M_FONTDATA
->m_nsFont
);
900 UIFont
* wxFont::OSXGetUIFont() const
902 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
904 // cast away constness otherwise lazy font resolution is not possible
905 const_cast<wxFont
*>(this)->RealizeResource();
907 return (M_FONTDATA
->m_uiFont
);
912 const wxNativeFontInfo
* wxFont::GetNativeFontInfo() const
914 wxCHECK_MSG( M_FONTDATA
!= NULL
, NULL
, wxT("invalid font") );
915 wxCHECK_MSG( IsOk(), NULL
, wxT("invalid font") );
917 // cast away constness otherwise lazy font resolution is not possible
918 const_cast<wxFont
*>(this)->RealizeResource();
920 // M_FONTDATA->m_info.InitFromFont(*this);
922 return &(M_FONTDATA
->m_info
);
925 // ----------------------------------------------------------------------------
927 // ----------------------------------------------------------------------------
929 #if 0 // wxOSX_USE_CORE_TEXT
931 /* from Core Text Manual Common Operations */
933 static CTFontDescriptorRef
wxMacCreateCTFontDescriptor(CFStringRef iFamilyName
, CTFontSymbolicTraits iTraits
)
935 CTFontDescriptorRef descriptor
= NULL
;
936 CFMutableDictionaryRef attributes
;
938 wxASSERT(iFamilyName
!= NULL
);
939 // Create a mutable dictionary to hold our attributes.
940 attributes
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
941 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
942 wxASSERT(attributes
!= NULL
);
944 if (attributes
!= NULL
) {
945 // Add a family name to our attributes.
946 CFDictionaryAddValue(attributes
, kCTFontFamilyNameAttribute
, iFamilyName
);
950 CFMutableDictionaryRef traits
;
951 CFNumberRef symTraits
;
953 // Create the traits dictionary.
954 symTraits
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt32Type
,
956 wxASSERT(symTraits
!= NULL
);
958 if (symTraits
!= NULL
) {
959 // Create a dictionary to hold our traits values.
960 traits
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0,
961 &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
962 wxASSERT(traits
!= NULL
);
964 if (traits
!= NULL
) {
965 // Add the symbolic traits value to the traits dictionary.
966 CFDictionaryAddValue(traits
, kCTFontSymbolicTrait
, symTraits
);
968 // Add the traits attribute to our attributes.
969 CFDictionaryAddValue(attributes
, kCTFontTraitsAttribute
, traits
);
972 CFRelease(symTraits
);
975 // Create the font descriptor with our attributes
976 descriptor
= CTFontDescriptorCreateWithAttributes(attributes
);
977 wxASSERT(descriptor
!= NULL
);
979 CFRelease(attributes
);
981 // Return our font descriptor.
987 void wxNativeFontInfo::Init()
989 #if wxOSX_USE_ATSU_TEXT
991 m_atsuAdditionalQDStyles
= 0;
992 m_atsuFontValid
= false;
999 m_family
= wxFONTFAMILY_DEFAULT
;
1000 m_style
= wxFONTSTYLE_NORMAL
;
1001 m_weight
= wxFONTWEIGHT_NORMAL
;
1002 m_underlined
= false;
1004 m_encoding
= wxFont::GetDefaultEncoding();
1005 m_descriptorValid
= false;
1008 #if wxOSX_USE_CORE_TEXT
1009 void wxNativeFontInfo::Init(CTFontDescriptorRef descr
)
1013 wxCFRef
< CFNumberRef
> sizevalue( (CFNumberRef
) CTFontDescriptorCopyAttribute( descr
, kCTFontSizeAttribute
) );
1015 if ( CFNumberGetValue( sizevalue
, kCFNumberFloatType
, &fsize
) )
1016 m_pointSize
= (int)( fsize
+ 0.5 );
1018 wxCFRef
< CFDictionaryRef
> traitsvalue( (CFDictionaryRef
) CTFontDescriptorCopyAttribute( descr
, kCTFontTraitsAttribute
) );
1019 CTFontSymbolicTraits traits
;
1020 if ( CFNumberGetValue((CFNumberRef
) CFDictionaryGetValue(traitsvalue
,kCTFontSymbolicTrait
),kCFNumberIntType
,&traits
) )
1022 if ( traits
& kCTFontItalicTrait
)
1023 m_style
= wxFONTSTYLE_ITALIC
;
1024 if ( traits
& kCTFontBoldTrait
)
1025 m_weight
= wxFONTWEIGHT_BOLD
;
1028 wxCFStringRef
familyName( (CFStringRef
) CTFontDescriptorCopyAttribute(descr
, kCTFontFamilyNameAttribute
));
1029 m_faceName
= familyName
.AsString();
1033 void wxNativeFontInfo::EnsureValid()
1035 if ( m_descriptorValid
)
1038 #if wxOSX_USE_ATSU_TEXT
1039 if ( !m_atsuFontValid
)
1041 #if !wxOSX_USE_CARBON
1042 // not needed outside
1043 wxInt16 m_qdFontFamily
;
1044 wxInt16 m_qdFontStyle
;
1046 wxCFStringRef
cf( m_faceName
, wxLocale::GetSystemEncoding() );
1047 ATSFontFamilyRef atsfamily
= ATSFontFamilyFindFromName( cf
, kATSOptionFlagsDefault
);
1048 if ( atsfamily
== (ATSFontFamilyRef
) -1 )
1050 wxLogDebug( wxT("ATSFontFamilyFindFromName failed for ") + m_faceName
);
1051 m_qdFontFamily
= GetAppFont();
1055 m_qdFontFamily
= FMGetFontFamilyFromATSFontFamilyRef( atsfamily
);
1059 if (m_weight
== wxFONTWEIGHT_BOLD
)
1060 m_qdFontStyle
|= bold
;
1061 if (m_style
== wxFONTSTYLE_ITALIC
|| m_style
== wxFONTSTYLE_SLANT
)
1062 m_qdFontStyle
|= italic
;
1064 m_qdFontStyle
|= underline
;
1067 // we try to get as much styles as possible into ATSU
1069 // ATSUFontID and FMFont are equivalent
1070 FMFontStyle intrinsicStyle
= 0 ;
1071 OSStatus status
= FMGetFontFromFontFamilyInstance( m_qdFontFamily
, m_qdFontStyle
, (FMFont
*)&m_atsuFontID
, &intrinsicStyle
);
1072 if ( status
!= noErr
)
1074 wxFAIL_MSG( wxT("couldn't get an ATSUFont from font family") );
1076 m_atsuAdditionalQDStyles
= m_qdFontStyle
& (~intrinsicStyle
);
1077 m_atsuFontValid
= true;
1080 m_descriptorValid
= true;
1083 void wxNativeFontInfo::Init(const wxNativeFontInfo
& info
)
1086 #if wxOSX_USE_ATSU_TEXT
1087 m_atsuFontValid
= info
.m_atsuFontValid
;
1088 m_atsuFontID
= info
.m_atsuFontID
;
1089 m_atsuAdditionalQDStyles
= info
.m_atsuAdditionalQDStyles
;
1090 #if wxOSX_USE_CARBON
1091 m_qdFontFamily
= info
.m_qdFontFamily
;
1092 m_qdFontStyle
= info
.m_qdFontStyle
;
1095 m_pointSize
= info
.m_pointSize
;
1096 m_family
= info
.m_family
;
1097 m_style
= info
.m_style
;
1098 m_weight
= info
.m_weight
;
1099 m_underlined
= info
.m_underlined
;
1100 m_faceName
= info
.m_faceName
;
1101 m_encoding
= info
.m_encoding
;
1102 m_descriptorValid
= info
.m_descriptorValid
;
1105 void wxNativeFontInfo::Init(int size
,
1106 wxFontFamily family
,
1108 wxFontWeight weight
,
1110 const wxString
& faceName
,
1111 wxFontEncoding encoding
)
1115 // We should use the default font size if the special value wxDEFAULT is
1116 // specified and we also handle -1 as a synonym for wxDEFAULT for
1117 // compatibility with wxGTK (see #12541).
1119 // Notice that we rely on the fact that wxNORMAL_FONT itself is not
1120 // initialized using this ctor, but from native font info.
1121 m_pointSize
= size
== -1 || size
== wxDEFAULT
1122 ? wxNORMAL_FONT
->GetPointSize()
1127 m_underlined
= underlined
;
1128 m_faceName
= faceName
;
1129 if ( encoding
== wxFONTENCODING_DEFAULT
)
1130 encoding
= wxFont::GetDefaultEncoding();
1131 m_encoding
= encoding
;
1135 void wxNativeFontInfo::Free()
1137 #if wxOSX_USE_ATSU_TEXT
1139 m_atsuAdditionalQDStyles
= 0;
1140 m_atsuFontValid
= false;
1142 m_descriptorValid
= false;
1145 bool wxNativeFontInfo::FromString(const wxString
& s
)
1149 wxStringTokenizer
tokenizer(s
, wxT(";"));
1151 wxString token
= tokenizer
.GetNextToken();
1153 // Ignore the version for now
1156 token
= tokenizer
.GetNextToken();
1157 if ( !token
.ToLong(&l
) )
1159 m_pointSize
= (int)l
;
1161 token
= tokenizer
.GetNextToken();
1162 if ( !token
.ToLong(&l
) )
1164 m_family
= (wxFontFamily
)l
;
1166 token
= tokenizer
.GetNextToken();
1167 if ( !token
.ToLong(&l
) )
1169 m_style
= (wxFontStyle
)l
;
1171 token
= tokenizer
.GetNextToken();
1172 if ( !token
.ToLong(&l
) )
1174 m_weight
= (wxFontWeight
)l
;
1176 token
= tokenizer
.GetNextToken();
1177 if ( !token
.ToLong(&l
) )
1179 m_underlined
= l
!= 0;
1181 m_faceName
= tokenizer
.GetNextToken();
1188 token
= tokenizer
.GetNextToken();
1189 if ( !token
.ToLong(&l
) )
1191 m_encoding
= (wxFontEncoding
)l
;
1196 wxString
wxNativeFontInfo::ToString() const
1200 s
.Printf(wxT("%d;%d;%d;%d;%d;%d;%s;%d"),
1207 m_faceName
.GetData(),
1213 int wxNativeFontInfo::GetPointSize() const
1218 wxFontStyle
wxNativeFontInfo::GetStyle() const
1223 wxFontWeight
wxNativeFontInfo::GetWeight() const
1228 bool wxNativeFontInfo::GetUnderlined() const
1230 return m_underlined
;
1233 wxString
wxNativeFontInfo::GetFaceName() const
1238 wxFontFamily
wxNativeFontInfo::GetFamily() const
1243 wxFontEncoding
wxNativeFontInfo::GetEncoding() const
1248 bool wxNativeFontInfo::GetStrikethrough() const
1254 // changing the font descriptor
1256 void wxNativeFontInfo::SetPointSize(int pointsize
)
1258 if ( m_pointSize
!= pointsize
)
1260 m_pointSize
= pointsize
;
1265 void wxNativeFontInfo::SetStyle(wxFontStyle style_
)
1267 if ( m_style
!= style_
)
1274 void wxNativeFontInfo::SetWeight(wxFontWeight weight_
)
1276 if ( m_weight
!= weight_
)
1283 void wxNativeFontInfo::SetUnderlined(bool underlined_
)
1285 if ( m_underlined
!= underlined_
)
1287 m_underlined
= underlined_
;
1292 bool wxNativeFontInfo::SetFaceName(const wxString
& facename_
)
1294 if ( m_faceName
!= facename_
)
1296 m_faceName
= facename_
;
1302 void wxNativeFontInfo::SetFamily(wxFontFamily family_
)
1304 if ( m_family
!= family_
)
1311 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_
)
1313 if ( encoding_
== wxFONTENCODING_DEFAULT
)
1314 encoding_
= wxFont::GetDefaultEncoding();
1315 m_encoding
= encoding_
;
1316 // not reflected in native descriptors
1319 void wxNativeFontInfo::SetStrikethrough(bool WXUNUSED(strikethrough
))