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"); 
 258                         m_faceName 
=  wxT("Monaco"); 
 262                         m_faceName 
=  wxT("Times"); 
 266                 wxMacStringToPascal( m_faceName 
, qdFontName 
); 
 267                 m_macFontFamily 
= FMGetFontFamilyFromName( qdFontName 
); 
 268                 if ( m_macFontFamily 
== kInvalidFontFamily 
) 
 270                     wxLogDebug( wxT("ATSFontFamilyFindFromName failed for %s"), m_faceName
.c_str() ); 
 271                     m_macFontFamily 
= GetAppFont(); 
 279             if ( m_faceName 
== wxT("systemfont") ) 
 280                 m_macFontFamily 
= GetSysFont(); 
 281             else if ( m_faceName 
== wxT("applicationfont") ) 
 282                 m_macFontFamily 
= GetAppFont(); 
 285             if ( m_faceName 
== wxT("systemfont") ) 
 286                 m_faceName 
=  wxT("Lucida Grande"); 
 287             else if ( m_faceName 
== wxT("applicationfont") ) 
 288                 m_faceName 
=  wxT("Lucida Grande"); 
 291                 wxMacCFStringHolder 
cf( m_faceName
, wxLocale::GetSystemEncoding() ); 
 292                 ATSFontFamilyRef atsfamily 
= ATSFontFamilyFindFromName( cf 
, kATSOptionFlagsDefault 
); 
 294                 // ATSFontFamilyRef is an unsigned type, so check against max 
 295                 // for an invalid value, not -1. 
 296                 if ( atsfamily 
== 0xffffffff  ) 
 298                     wxLogDebug( wxT("ATSFontFamilyFindFromName failed for ") + m_faceName 
); 
 299                     m_macFontFamily 
= GetAppFont(); 
 302                     m_macFontFamily 
= FMGetFontFamilyFromATSFontFamilyRef( atsfamily 
); 
 307         if (m_weight 
== wxBOLD
) 
 308              m_macFontStyle 
|= bold
; 
 309         if (m_style 
== wxITALIC 
|| m_style 
== wxSLANT
) 
 310             m_macFontStyle 
|= italic
; 
 312             m_macFontStyle 
|= underline
; 
 313         m_macFontSize 
= m_pointSize 
; 
 316     // we try to get as much styles as possible into ATSU 
 319     // ATSUFontID and FMFont are equivalent 
 320     FMFontStyle intrinsicStyle 
= 0 ; 
 322     status 
= FMGetFontFromFontFamilyInstance( m_macFontFamily 
, m_macFontStyle 
, &m_macATSUFontID 
, &intrinsicStyle
); 
 323     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't get an ATSUFont from font family") ); 
 325     m_macATSUAdditionalQDStyles 
= m_macFontStyle 
& (~intrinsicStyle 
); 
 327     if ( m_macATSUStyle 
) 
 329         ::ATSUDisposeStyle((ATSUStyle
)m_macATSUStyle
); 
 330         m_macATSUStyle 
= NULL 
; 
 333     status 
= ::ATSUCreateStyle((ATSUStyle 
*)&m_macATSUStyle
); 
 334     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't create ATSU style") ); 
 336     ATSUAttributeTag atsuTags
[] = 
 340         kATSUVerticalCharacterTag
, 
 343         kATSUQDUnderlineTag 
, 
 344         kATSUQDCondensedTag 
, 
 347     ByteCount atsuSizes
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
 349         sizeof( ATSUFontID 
) , 
 351         sizeof( ATSUVerticalCharacterType
), 
 359     Boolean kTrue 
= true ; 
 360     Boolean kFalse 
= false ; 
 362     Fixed atsuSize 
= IntToFixed( m_macFontSize 
); 
 363     ATSUVerticalCharacterType kHorizontal 
= kATSUStronglyHorizontal
; 
 364     ATSUAttributeValuePtr    atsuValues
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] = 
 369             (m_macATSUAdditionalQDStyles 
& bold
) ? &kTrue 
: &kFalse 
, 
 370             (m_macATSUAdditionalQDStyles 
& italic
) ? &kTrue 
: &kFalse 
, 
 371             (m_macATSUAdditionalQDStyles 
& underline
) ? &kTrue 
: &kFalse 
, 
 372             (m_macATSUAdditionalQDStyles 
& condense
) ? &kTrue 
: &kFalse 
, 
 373             (m_macATSUAdditionalQDStyles 
& extend
) ? &kTrue 
: &kFalse 
, 
 376     status 
= ::ATSUSetAttributes( 
 377         (ATSUStyle
)m_macATSUStyle
, 
 378         sizeof(atsuTags
) / sizeof(ATSUAttributeTag
) , 
 379         atsuTags
, atsuSizes
, atsuValues
); 
 381     wxASSERT_MSG( status 
== noErr 
, wxT("couldn't modify ATSU style") ); 
 384 // ---------------------------------------------------------------------------- 
 386 // ---------------------------------------------------------------------------- 
 388 bool wxFont::Create(const wxNativeFontInfo
& info
) 
 391         info
.pointSize
, info
.family
, info
.style
, info
.weight
, 
 392         info
.underlined
, info
.faceName
, info
.encoding 
); 
 395 wxFont::wxFont(const wxString
& fontdesc
) 
 397     wxNativeFontInfo info
; 
 398     if ( info
.FromString(fontdesc
) ) 
 402 bool wxFont::Create(int pointSize
, 
 407     const wxString
& faceName
, 
 408     wxFontEncoding encoding
) 
 412     m_refData 
= new wxFontRefData( 
 413         pointSize
, family
, style
, weight
, 
 414         underlined
, faceName
, encoding
); 
 421 bool wxFont::MacCreateThemeFont(wxUint16 themeFontID
) 
 425     m_refData 
= new wxFontRefData( 
 426         12, wxDEFAULT
, wxFONTSTYLE_NORMAL
, wxFONTWEIGHT_NORMAL
, 
 427         false, wxEmptyString
, wxFONTENCODING_DEFAULT 
); 
 429     M_FONTDATA
->m_macThemeFontID 
= themeFontID 
; 
 439 bool wxFont::RealizeResource() 
 441     M_FONTDATA
->MacFindFont(); 
 446 void wxFont::SetEncoding(wxFontEncoding encoding
) 
 450     M_FONTDATA
->m_encoding 
= encoding
; 
 455 void wxFont::Unshare() 
 457     // Don't change shared data 
 460         m_refData 
= new wxFontRefData(); 
 464         wxFontRefData
* ref 
= new wxFontRefData(*(wxFontRefData
*)m_refData
); 
 470 void wxFont::SetPointSize(int pointSize
) 
 474     M_FONTDATA
->m_pointSize 
= pointSize
; 
 479 void wxFont::SetFamily(int family
) 
 483     M_FONTDATA
->m_family 
= family
; 
 488 void wxFont::SetStyle(int style
) 
 492     M_FONTDATA
->m_style 
= style
; 
 497 void wxFont::SetWeight(int weight
) 
 501     M_FONTDATA
->m_weight 
= weight
; 
 506 bool wxFont::SetFaceName(const wxString
& faceName
) 
 510     M_FONTDATA
->m_faceName 
= faceName
; 
 514     return wxFontBase::SetFaceName(faceName
); 
 517 void wxFont::SetUnderlined(bool underlined
) 
 521     M_FONTDATA
->m_underlined 
= underlined
; 
 526 void wxFont::SetNoAntiAliasing( bool no 
) 
 530     M_FONTDATA
->SetNoAntiAliasing( no 
); 
 535 // ---------------------------------------------------------------------------- 
 537 // ---------------------------------------------------------------------------- 
 539 // TODO: insert checks everywhere for M_FONTDATA == NULL! 
 541 int wxFont::GetPointSize() const 
 543     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 545     return M_FONTDATA
->m_pointSize
; 
 548 wxSize 
wxFont::GetPixelSize() const 
 550 #if wxUSE_GRAPHICS_CONTEXT 
 551     // TODO: consider caching the value 
 552     wxGraphicsContext
* dc 
= wxGraphicsContext::CreateFromNative((CGContextRef
) NULL
); 
 553     dc
->SetFont(*(wxFont 
*)this,*wxBLACK
); 
 554     wxDouble width
, height 
= 0; 
 555     dc
->GetTextExtent( wxT("g"), &width
, &height
, NULL
, NULL
); 
 556     return wxSize((int)width
, (int)height
); 
 558     return wxFontBase::GetPixelSize(); 
 562 int wxFont::GetFamily() const 
 564     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 566     return M_FONTDATA
->m_family
; 
 569 int wxFont::GetStyle() const 
 571     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 573     return M_FONTDATA
->m_style
; 
 576 int wxFont::GetWeight() const 
 578     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 580     return M_FONTDATA
->m_weight
; 
 583 bool wxFont::GetUnderlined() const 
 585     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, false, wxT("invalid font") ); 
 587     return M_FONTDATA
->m_underlined
; 
 590 wxString 
wxFont::GetFaceName() const 
 592     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, wxEmptyString 
, wxT("invalid font") ); 
 594     return M_FONTDATA
->m_faceName
; 
 597 wxFontEncoding 
wxFont::GetEncoding() const 
 599     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, wxFONTENCODING_DEFAULT 
, wxT("invalid font") ); 
 601     return M_FONTDATA
->m_encoding
; 
 604 bool wxFont::GetNoAntiAliasing() const 
 606     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, false, wxT("invalid font") ); 
 608     return M_FONTDATA
->m_noAA
; 
 611 short wxFont::MacGetFontNum() const 
 613     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 615     return M_FONTDATA
->m_macFontFamily
; 
 618 short wxFont::MacGetFontSize() const 
 620     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 622     return M_FONTDATA
->m_macFontSize
; 
 625 wxByte 
wxFont::MacGetFontStyle() const 
 627     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 629     return M_FONTDATA
->m_macFontStyle
; 
 632 wxUint32 
wxFont::MacGetATSUFontID() const 
 634     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 636     return M_FONTDATA
->m_macATSUFontID
; 
 639 void * wxFont::MacGetATSUStyle() const 
 641     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, NULL
, wxT("invalid font") ); 
 643     return M_FONTDATA
->m_macATSUStyle
; 
 646 wxUint32 
wxFont::MacGetATSUAdditionalQDStyles() const 
 648     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 650     return M_FONTDATA
->m_macATSUAdditionalQDStyles
; 
 653 wxUint16 
wxFont::MacGetThemeFontID() const 
 655     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, 0, wxT("invalid font") ); 
 657     return M_FONTDATA
->m_macThemeFontID
; 
 660 const wxNativeFontInfo 
* wxFont::GetNativeFontInfo() const 
 662     wxCHECK_MSG( M_FONTDATA 
!= NULL 
, NULL
, wxT("invalid font") ); 
 663     wxCHECK_MSG( Ok(), NULL
, wxT("invalid font") ); 
 665     M_FONTDATA
->m_info
.InitFromFont(*this); 
 667     return &(M_FONTDATA
->m_info
);