1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/mac/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" 
  27 #include "wx/mac/private.h" 
  30 #include <ATSUnicode.h> 
  34 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
) 
  37 class WXDLLEXPORT wxFontRefData
: public wxGDIRefData
 
  39     friend class WXDLLEXPORT wxFont
; 
  49         , m_faceName(wxT("applicationfont")) 
  50         , m_encoding(wxFONTENCODING_DEFAULT
) 
  57         Init(m_pointSize
, m_family
, m_style
, m_weight
, 
  58              m_underlined
, m_faceName
, m_encoding
); 
  61     wxFontRefData(const wxFontRefData
& data
) 
  63         , m_fontId(data
.m_fontId
) 
  64         , m_pointSize(data
.m_pointSize
) 
  65         , m_family(data
.m_family
) 
  66         , m_style(data
.m_style
) 
  67         , m_weight(data
.m_weight
) 
  68         , m_underlined(data
.m_underlined
) 
  69         , m_faceName(data
.m_faceName
) 
  70         , m_encoding(data
.m_encoding
) 
  71         , m_macFontFamily(data
.m_macFontFamily
) 
  72         , m_macFontSize(data
.m_macFontSize
) 
  73         , m_macFontStyle(data
.m_macFontStyle
) 
  75         , m_macATSUFontID(data
.m_macATSUFontID
) 
  77         Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
, 
  78              data
.m_underlined
, data
.m_faceName
, data
.m_encoding
); 
  81     wxFontRefData(int size
, 
  86                   const wxString
& faceName
, 
  87                   wxFontEncoding encoding
) 
  93         , m_underlined(underlined
) 
  94         , m_faceName(faceName
) 
  95         , m_encoding(encoding
) 
 102         Init(size
, family
, style
, weight
, underlined
, faceName
, encoding
); 
 105     virtual ~wxFontRefData(); 
 107     void SetNoAntiAliasing( bool no 
= true ) 
 110     bool GetNoAntiAliasing() const 
 116     // common part of all ctors 
 122               const wxString
& faceName
, 
 123               wxFontEncoding encoding
); 
 125     // font characterstics 
 133     wxFontEncoding  m_encoding
; 
 134     bool            m_noAA
;      // No anti-aliasing 
 137     FMFontFamily    m_macFontFamily
; 
 138     FMFontSize      m_macFontSize
; 
 139     FMFontStyle     m_macFontStyle
; 
 141     // ATSU Font Information 
 143     // this is split into an ATSU font id that may 
 144     // contain some styles (special bold fonts etc) and 
 145     // these are the additional qd styles that are not 
 146     // included in the ATSU font id 
 147     ATSUStyle       m_macATSUStyle 
; 
 148     ATSUFontID      m_macATSUFontID
; 
 149     FMFontStyle     m_macATSUAdditionalQDStyles 
; 
 151     // for true themeing support we must store the correct font 
 152     // information here, as this speeds up and optimizes rendering 
 153     ThemeFontID     m_macThemeFontID 
; 
 155     wxNativeFontInfo  m_info
; 
 158 #define M_FONTDATA ((wxFontRefData*)m_refData) 
 161 // ============================================================================ 
 163 // ============================================================================ 
 165 // ---------------------------------------------------------------------------- 
 167 // ---------------------------------------------------------------------------- 
 169 void wxFontRefData::Init(int pointSize
, 
 174     const wxString
& faceName
, 
 175     wxFontEncoding encoding
) 
 178     m_pointSize 
= pointSize
; 
 182     m_underlined 
= underlined
; 
 183     m_faceName 
= faceName
; 
 184     m_encoding 
= encoding
; 
 186     m_macFontFamily 
= 0 ; 
 190     m_macATSUAdditionalQDStyles 
= 0 ; 
 191     m_macATSUStyle 
= NULL 
; 
 193     m_macThemeFontID 
= kThemeCurrentPortFont 
; 
 197 wxFontRefData::~wxFontRefData() 
 199     if ( m_macATSUStyle 
) 
 201         ::ATSUDisposeStyle((ATSUStyle
)m_macATSUStyle
); 
 202         m_macATSUStyle 
= NULL 
; 
 206 void wxFontRefData::MacFindFont() 
 211     if ( m_macThemeFontID 
!= kThemeCurrentPortFont 
) 
 214         GetThemeFont( m_macThemeFontID
, GetApplicationScript(), qdFontName
, &m_macFontSize
, &style 
); 
 215         m_macFontStyle 
= style 
; 
 216         m_faceName 
= wxMacMakeStringFromPascal( qdFontName 
); 
 217         if ( m_macFontStyle 
& bold 
) 
 220             m_weight 
= wxNORMAL 
; 
 221         if ( m_macFontStyle 
& italic 
) 
 223         if ( m_macFontStyle 
& underline 
) 
 224             m_underlined 
= true ; 
 225         m_pointSize 
= m_macFontSize 
; 
 227         m_macFontFamily 
= FMGetFontFamilyFromName( qdFontName 
); 
 232         if ( m_faceName
.empty() ) 
 234             if ( m_family 
== wxDEFAULT 
) 
 237                 m_macFontFamily 
= GetAppFont(); 
 238                 FMGetFontFamilyName(m_macFontFamily
,qdFontName
); 
 239                 m_faceName 
= wxMacMakeStringFromPascal( qdFontName 
); 
 249                         m_faceName 
= wxT("Times"); 
 253                         m_faceName 
=  wxT("Lucida Grande"); 
 257                         m_faceName 
=  wxT("Monaco"); 
 261                         m_faceName 
=  wxT("Times"); 
 265                 wxMacStringToPascal( m_faceName 
, qdFontName 
); 
 266                 m_macFontFamily 
= FMGetFontFamilyFromName( qdFontName 
); 
 267                 if ( m_macFontFamily 
== kInvalidFontFamily 
) 
 269                     wxLogDebug( wxT("ATSFontFamilyFindFromName failed for %s"), m_faceName
.c_str() ); 
 270                     m_macFontFamily 
= GetAppFont(); 
 278             if ( m_faceName 
== wxT("systemfont") ) 
 279                 m_macFontFamily 
= GetSysFont(); 
 280             else if ( m_faceName 
== wxT("applicationfont") ) 
 281                 m_macFontFamily 
= GetAppFont(); 
 284             if ( m_faceName 
== wxT("systemfont") ) 
 285                 m_faceName 
=  wxT("Lucida Grande"); 
 286             else if ( m_faceName 
== wxT("applicationfont") ) 
 287                 m_faceName 
=  wxT("Lucida Grande"); 
 290                 wxMacCFStringHolder 
cf( m_faceName
, wxLocale::GetSystemEncoding() ); 
 291                 ATSFontFamilyRef atsfamily 
= ATSFontFamilyFindFromName( cf 
, kATSOptionFlagsDefault 
); 
 293                 // ATSFontFamilyRef is an unsigned type, so check against max 
 294                 // for an invalid value, not -1. 
 295                 if ( atsfamily 
== 0xffffffff  ) 
 297                     wxLogDebug( wxT("ATSFontFamilyFindFromName failed for ") + m_faceName 
); 
 298                     m_macFontFamily 
= GetAppFont(); 
 301                     m_macFontFamily 
= FMGetFontFamilyFromATSFontFamilyRef( atsfamily 
); 
 306         if (m_weight 
== wxBOLD
) 
 307              m_macFontStyle 
|= bold
; 
 308         if (m_style 
== wxITALIC 
|| m_style 
== wxSLANT
) 
 309             m_macFontStyle 
|= italic
; 
 311             m_macFontStyle 
|= underline
; 
 312         m_macFontSize 
= m_pointSize 
; 
 315     // we try to get as much styles as possible into ATSU 
 318     // ATSUFontID and FMFont are equivalent 
 319     FMFontStyle intrinsicStyle 
= 0 ; 
 321     status 
= FMGetFontFromFontFamilyInstance( m_macFontFamily 
, m_macFontStyle 
, &m_macATSUFontID 
, &intrinsicStyle
); 
 322     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't get an ATSUFont from font family") ); 
 324     m_macATSUAdditionalQDStyles 
= m_macFontStyle 
& (~intrinsicStyle 
); 
 326     if ( m_macATSUStyle 
) 
 328         ::ATSUDisposeStyle((ATSUStyle
)m_macATSUStyle
); 
 329         m_macATSUStyle 
= NULL 
; 
 332     status 
= ::ATSUCreateStyle((ATSUStyle 
*)&m_macATSUStyle
); 
 333     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't create ATSU style") ); 
 335     ATSUAttributeTag atsuTags
[] = 
 339         kATSUVerticalCharacterTag
, 
 342         kATSUQDUnderlineTag 
, 
 343         kATSUQDCondensedTag 
, 
 346     ByteCount atsuSizes
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
 348         sizeof( ATSUFontID 
) , 
 350         sizeof( ATSUVerticalCharacterType
), 
 358     Boolean kTrue 
= true ; 
 359     Boolean kFalse 
= false ; 
 361     Fixed atsuSize 
= IntToFixed( m_macFontSize 
); 
 362     ATSUVerticalCharacterType kHorizontal 
= kATSUStronglyHorizontal
; 
 363     ATSUAttributeValuePtr    atsuValues
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
 368             (m_macATSUAdditionalQDStyles 
& bold
) ? &kTrue 
: &kFalse 
, 
 369             (m_macATSUAdditionalQDStyles 
& italic
) ? &kTrue 
: &kFalse 
, 
 370             (m_macATSUAdditionalQDStyles 
& underline
) ? &kTrue 
: &kFalse 
, 
 371             (m_macATSUAdditionalQDStyles 
& condense
) ? &kTrue 
: &kFalse 
, 
 372             (m_macATSUAdditionalQDStyles 
& extend
) ? &kTrue 
: &kFalse 
, 
 375     status 
= ::ATSUSetAttributes( 
 376         (ATSUStyle
)m_macATSUStyle
, 
 377         sizeof(atsuTags
) / sizeof(ATSUAttributeTag
) , 
 378         atsuTags
, atsuSizes
, atsuValues
); 
 380     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't modify ATSU style") ); 
 383 // ---------------------------------------------------------------------------- 
 385 // ---------------------------------------------------------------------------- 
 387 bool wxFont::Create(const wxNativeFontInfo
& info
) 
 390         info
.pointSize
, info
.family
, info
.style
, info
.weight
, 
 391         info
.underlined
, info
.faceName
, info
.encoding 
); 
 394 wxFont::wxFont(const wxString
& fontdesc
) 
 396     wxNativeFontInfo info
; 
 397     if ( info
.FromString(fontdesc
) ) 
 401 bool wxFont::Create(int pointSize
, 
 406     const wxString
& faceName
, 
 407     wxFontEncoding encoding
) 
 411     m_refData 
= new wxFontRefData( 
 412         pointSize
, family
, style
, weight
, 
 413         underlined
, faceName
, encoding
); 
 420 bool wxFont::MacCreateThemeFont(wxUint16 themeFontID
) 
 424     m_refData 
= new wxFontRefData( 
 425         12, wxDEFAULT
, wxFONTSTYLE_NORMAL
, wxFONTWEIGHT_NORMAL
, 
 426         false, wxEmptyString
, wxFONTENCODING_DEFAULT 
); 
 428     M_FONTDATA
->m_macThemeFontID 
= themeFontID 
; 
 438 bool wxFont::RealizeResource() 
 440     M_FONTDATA
->MacFindFont(); 
 445 void wxFont::SetEncoding(wxFontEncoding encoding
) 
 449     M_FONTDATA
->m_encoding 
= encoding
; 
 454 wxObjectRefData
* wxFont::CreateRefData() const 
 456     return new wxFontRefData
; 
 459 wxObjectRefData
* wxFont::CloneRefData(const wxObjectRefData
* data
) const 
 461     return new wxFontRefData(*wx_static_cast(const wxFontRefData
*, data
)); 
 464 void wxFont::SetPointSize(int pointSize
) 
 468     M_FONTDATA
->m_pointSize 
= pointSize
; 
 473 void wxFont::SetFamily(int family
) 
 477     M_FONTDATA
->m_family 
= family
; 
 482 void wxFont::SetStyle(int style
) 
 486     M_FONTDATA
->m_style 
= style
; 
 491 void wxFont::SetWeight(int weight
) 
 495     M_FONTDATA
->m_weight 
= weight
; 
 500 bool wxFont::SetFaceName(const wxString
& faceName
) 
 504     M_FONTDATA
->m_faceName 
= faceName
; 
 508     return wxFontBase::SetFaceName(faceName
); 
 511 void wxFont::SetUnderlined(bool underlined
) 
 515     M_FONTDATA
->m_underlined 
= underlined
; 
 520 void wxFont::SetNoAntiAliasing( bool no 
) 
 524     M_FONTDATA
->SetNoAntiAliasing( no 
); 
 529 // ---------------------------------------------------------------------------- 
 531 // ---------------------------------------------------------------------------- 
 533 // TODO: insert checks everywhere for M_FONTDATA == NULL! 
 535 int wxFont::GetPointSize() const 
 537     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 539     return M_FONTDATA
->m_pointSize
; 
 542 wxSize 
wxFont::GetPixelSize() const 
 544 #if wxUSE_GRAPHICS_CONTEXT 
 545     // TODO: consider caching the value 
 546     wxGraphicsContext
* dc 
= wxGraphicsContext::CreateFromNative((CGContextRef
) NULL
); 
 547     dc
->SetFont(*(wxFont 
*)this,*wxBLACK
); 
 548     wxDouble width
, height 
= 0; 
 549     dc
->GetTextExtent( wxT("g"), &width
, &height
, NULL
, NULL
); 
 550     return wxSize((int)width
, (int)height
); 
 552     wxFontBase::GetPixelSize(); 
 556 int wxFont::GetFamily() const 
 558     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 560     return M_FONTDATA
->m_family
; 
 563 int wxFont::GetStyle() const 
 565     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 567     return M_FONTDATA
->m_style
; 
 570 int wxFont::GetWeight() const 
 572     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 574     return M_FONTDATA
->m_weight
; 
 577 bool wxFont::GetUnderlined() const 
 579     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, false, wxT("invalid font") ); 
 581     return M_FONTDATA
->m_underlined
; 
 584 wxString 
wxFont::GetFaceName() const 
 586     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, wxEmptyString 
, wxT("invalid font") ); 
 588     return M_FONTDATA
->m_faceName
; 
 591 wxFontEncoding 
wxFont::GetEncoding() const 
 593     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, wxFONTENCODING_DEFAULT 
, wxT("invalid font") ); 
 595     return M_FONTDATA
->m_encoding
; 
 598 bool wxFont::GetNoAntiAliasing() const 
 600     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, false, wxT("invalid font") ); 
 602     return M_FONTDATA
->m_noAA
; 
 605 short wxFont::MacGetFontNum() const 
 607     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 609     return M_FONTDATA
->m_macFontFamily
; 
 612 short wxFont::MacGetFontSize() const 
 614     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 616     return M_FONTDATA
->m_macFontSize
; 
 619 wxByte 
wxFont::MacGetFontStyle() const 
 621     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 623     return M_FONTDATA
->m_macFontStyle
; 
 626 wxUint32 
wxFont::MacGetATSUFontID() const 
 628     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 630     return M_FONTDATA
->m_macATSUFontID
; 
 633 void * wxFont::MacGetATSUStyle() const 
 635     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, NULL
, wxT("invalid font") ); 
 637     return M_FONTDATA
->m_macATSUStyle
; 
 640 wxUint32 
wxFont::MacGetATSUAdditionalQDStyles() const 
 642     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 644     return M_FONTDATA
->m_macATSUAdditionalQDStyles
; 
 647 wxUint16 
wxFont::MacGetThemeFontID() const 
 649     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 651     return M_FONTDATA
->m_macThemeFontID
; 
 654 const wxNativeFontInfo 
* wxFont::GetNativeFontInfo() const 
 656     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, NULL
, wxT("invalid font") ); 
 657     wxCHECK_MSG( Ok(), NULL
, wxT("invalid font") ); 
 659     M_FONTDATA
->m_info
.InitFromFont(*this); 
 661     return &(M_FONTDATA
->m_info
);