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"
23 #include "wx/fontutil.h"
24 #include "wx/graphics.h"
26 #include "wx/mac/private.h"
29 #include <ATSUnicode.h>
33 IMPLEMENT_DYNAMIC_CLASS(wxFont
, wxGDIObject
)
36 class WXDLLEXPORT wxFontRefData
: public wxGDIRefData
38 friend class WXDLLEXPORT wxFont
;
48 , m_faceName(wxT("applicationfont"))
49 , m_encoding(wxFONTENCODING_DEFAULT
)
56 Init(m_pointSize
, m_family
, m_style
, m_weight
,
57 m_underlined
, m_faceName
, m_encoding
);
60 wxFontRefData(const wxFontRefData
& data
)
62 , m_fontId(data
.m_fontId
)
63 , m_pointSize(data
.m_pointSize
)
64 , m_family(data
.m_family
)
65 , m_style(data
.m_style
)
66 , m_weight(data
.m_weight
)
67 , m_underlined(data
.m_underlined
)
68 , m_faceName(data
.m_faceName
)
69 , m_encoding(data
.m_encoding
)
70 , m_macFontFamily(data
.m_macFontFamily
)
71 , m_macFontSize(data
.m_macFontSize
)
72 , m_macFontStyle(data
.m_macFontStyle
)
74 , m_macATSUFontID(data
.m_macATSUFontID
)
76 Init(data
.m_pointSize
, data
.m_family
, data
.m_style
, data
.m_weight
,
77 data
.m_underlined
, data
.m_faceName
, data
.m_encoding
);
80 wxFontRefData(int size
,
85 const wxString
& faceName
,
86 wxFontEncoding encoding
)
92 , m_underlined(underlined
)
93 , m_faceName(faceName
)
94 , m_encoding(encoding
)
101 Init(size
, family
, style
, weight
, underlined
, faceName
, encoding
);
104 virtual ~wxFontRefData();
106 void SetNoAntiAliasing( bool no
= true )
109 bool GetNoAntiAliasing() const
115 // common part of all ctors
121 const wxString
& faceName
,
122 wxFontEncoding encoding
);
124 // font characterstics
132 wxFontEncoding m_encoding
;
133 bool m_noAA
; // No anti-aliasing
136 FMFontFamily m_macFontFamily
;
137 FMFontSize m_macFontSize
;
138 FMFontStyle m_macFontStyle
;
140 // ATSU Font Information
142 // this is split into an ATSU font id that may
143 // contain some styles (special bold fonts etc) and
144 // these are the additional qd styles that are not
145 // included in the ATSU font id
146 ATSUStyle m_macATSUStyle
;
147 ATSUFontID m_macATSUFontID
;
148 FMFontStyle m_macATSUAdditionalQDStyles
;
150 // for true themeing support we must store the correct font
151 // information here, as this speeds up and optimizes rendering
152 ThemeFontID m_macThemeFontID
;
154 wxNativeFontInfo m_info
;
157 #define M_FONTDATA ((wxFontRefData*)m_refData)
160 // ============================================================================
162 // ============================================================================
164 // ----------------------------------------------------------------------------
166 // ----------------------------------------------------------------------------
168 void wxFontRefData::Init(int pointSize
,
173 const wxString
& faceName
,
174 wxFontEncoding encoding
)
177 m_pointSize
= pointSize
;
181 m_underlined
= underlined
;
182 m_faceName
= faceName
;
183 m_encoding
= encoding
;
185 m_macFontFamily
= 0 ;
189 m_macATSUAdditionalQDStyles
= 0 ;
190 m_macATSUStyle
= NULL
;
192 m_macThemeFontID
= kThemeCurrentPortFont
;
196 wxFontRefData::~wxFontRefData()
198 if ( m_macATSUStyle
)
200 ::ATSUDisposeStyle((ATSUStyle
)m_macATSUStyle
);
201 m_macATSUStyle
= NULL
;
205 void wxFontRefData::MacFindFont()
210 if ( m_macThemeFontID
!= kThemeCurrentPortFont
)
213 GetThemeFont( m_macThemeFontID
, GetApplicationScript(), qdFontName
, &m_macFontSize
, &style
);
214 m_macFontStyle
= style
;
215 m_faceName
= wxMacMakeStringFromPascal( qdFontName
);
216 if ( m_macFontStyle
& bold
)
219 m_weight
= wxNORMAL
;
220 if ( m_macFontStyle
& italic
)
222 if ( m_macFontStyle
& underline
)
223 m_underlined
= true ;
224 m_pointSize
= m_macFontSize
;
226 m_macFontFamily
= FMGetFontFamilyFromName( qdFontName
);
231 if ( m_faceName
.empty() )
233 if ( m_family
== wxDEFAULT
)
236 m_macFontFamily
= GetAppFont();
237 FMGetFontFamilyName(m_macFontFamily
,qdFontName
);
238 m_faceName
= wxMacMakeStringFromPascal( qdFontName
);
248 m_faceName
= wxT("Times");
252 m_faceName
= wxT("Lucida Grande");
256 m_faceName
= wxT("Monaco");
260 m_faceName
= wxT("Times");
264 wxMacStringToPascal( m_faceName
, qdFontName
);
265 m_macFontFamily
= FMGetFontFamilyFromName( qdFontName
);
266 if ( m_macFontFamily
== kInvalidFontFamily
)
268 wxLogDebug( wxT("ATSFontFamilyFindFromName failed for %s"), m_faceName
);
269 m_macFontFamily
= GetAppFont();
277 if ( m_faceName
== wxT("systemfont") )
278 m_macFontFamily
= GetSysFont();
279 else if ( m_faceName
== wxT("applicationfont") )
280 m_macFontFamily
= GetAppFont();
283 if ( m_faceName
== wxT("systemfont") )
284 m_faceName
= wxT("Lucida Grande");
285 else if ( m_faceName
== wxT("applicationfont") )
286 m_faceName
= wxT("Lucida Grande");
289 wxMacCFStringHolder
cf( m_faceName
, wxLocale::GetSystemEncoding() );
290 ATSFontFamilyRef atsfamily
= ATSFontFamilyFindFromName( cf
, kATSOptionFlagsDefault
);
291 if ( atsfamily
== (ATSFontFamilyRef
) -1 )
293 wxLogDebug( wxT("ATSFontFamilyFindFromName failed for %s"), m_faceName
);
294 m_macFontFamily
= GetAppFont();
297 m_macFontFamily
= FMGetFontFamilyFromATSFontFamilyRef( atsfamily
);
302 if (m_weight
== wxBOLD
)
303 m_macFontStyle
|= bold
;
304 if (m_style
== wxITALIC
|| m_style
== wxSLANT
)
305 m_macFontStyle
|= italic
;
307 m_macFontStyle
|= underline
;
308 m_macFontSize
= m_pointSize
;
311 // we try to get as much styles as possible into ATSU
314 // ATSUFontID and FMFont are equivalent
315 FMFontStyle intrinsicStyle
= 0 ;
317 status
= FMGetFontFromFontFamilyInstance( m_macFontFamily
, m_macFontStyle
, &m_macATSUFontID
, &intrinsicStyle
);
318 wxASSERT_MSG( status
== noErr
, wxT("couldn't get an ATSUFont from font family") );
320 m_macATSUAdditionalQDStyles
= m_macFontStyle
& (~intrinsicStyle
);
322 if ( m_macATSUStyle
)
324 ::ATSUDisposeStyle((ATSUStyle
)m_macATSUStyle
);
325 m_macATSUStyle
= NULL
;
328 status
= ::ATSUCreateStyle((ATSUStyle
*)&m_macATSUStyle
);
329 wxASSERT_MSG( status
== noErr
, wxT("couldn't create ATSU style") );
331 ATSUAttributeTag atsuTags
[] =
335 kATSUVerticalCharacterTag
,
338 kATSUQDUnderlineTag
,
339 kATSUQDCondensedTag
,
342 ByteCount atsuSizes
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] =
344 sizeof( ATSUFontID
) ,
346 sizeof( ATSUVerticalCharacterType
),
354 Boolean kTrue
= true ;
355 Boolean kFalse
= false ;
357 Fixed atsuSize
= IntToFixed( m_macFontSize
);
358 ATSUVerticalCharacterType kHorizontal
= kATSUStronglyHorizontal
;
359 ATSUAttributeValuePtr atsuValues
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] =
364 (m_macATSUAdditionalQDStyles
& bold
) ? &kTrue
: &kFalse
,
365 (m_macATSUAdditionalQDStyles
& italic
) ? &kTrue
: &kFalse
,
366 (m_macATSUAdditionalQDStyles
& underline
) ? &kTrue
: &kFalse
,
367 (m_macATSUAdditionalQDStyles
& condense
) ? &kTrue
: &kFalse
,
368 (m_macATSUAdditionalQDStyles
& extend
) ? &kTrue
: &kFalse
,
371 status
= ::ATSUSetAttributes(
372 (ATSUStyle
)m_macATSUStyle
,
373 sizeof(atsuTags
) / sizeof(ATSUAttributeTag
) ,
374 atsuTags
, atsuSizes
, atsuValues
);
376 wxASSERT_MSG( status
== noErr
, wxT("couldn't modify ATSU style") );
379 // ----------------------------------------------------------------------------
381 // ----------------------------------------------------------------------------
383 bool wxFont::Create(const wxNativeFontInfo
& info
)
386 info
.pointSize
, info
.family
, info
.style
, info
.weight
,
387 info
.underlined
, info
.faceName
, info
.encoding
);
390 wxFont::wxFont(const wxString
& fontdesc
)
392 wxNativeFontInfo info
;
393 if ( info
.FromString(fontdesc
) )
397 bool wxFont::Create(int pointSize
,
402 const wxString
& faceName
,
403 wxFontEncoding encoding
)
407 m_refData
= new wxFontRefData(
408 pointSize
, family
, style
, weight
,
409 underlined
, faceName
, encoding
);
416 bool wxFont::MacCreateThemeFont(wxUint16 themeFontID
)
420 m_refData
= new wxFontRefData(
421 12, wxDEFAULT
, wxFONTSTYLE_NORMAL
, wxFONTWEIGHT_NORMAL
,
422 false, wxEmptyString
, wxFONTENCODING_DEFAULT
);
424 M_FONTDATA
->m_macThemeFontID
= themeFontID
;
434 bool wxFont::RealizeResource()
436 M_FONTDATA
->MacFindFont();
441 void wxFont::SetEncoding(wxFontEncoding encoding
)
445 M_FONTDATA
->m_encoding
= encoding
;
450 void wxFont::Unshare()
452 // Don't change shared data
455 m_refData
= new wxFontRefData();
459 wxFontRefData
* ref
= new wxFontRefData(*(wxFontRefData
*)m_refData
);
465 void wxFont::SetPointSize(int pointSize
)
469 M_FONTDATA
->m_pointSize
= pointSize
;
474 void wxFont::SetFamily(int family
)
478 M_FONTDATA
->m_family
= family
;
483 void wxFont::SetStyle(int style
)
487 M_FONTDATA
->m_style
= style
;
492 void wxFont::SetWeight(int weight
)
496 M_FONTDATA
->m_weight
= weight
;
501 bool wxFont::SetFaceName(const wxString
& faceName
)
505 M_FONTDATA
->m_faceName
= faceName
;
509 return wxFontBase::SetFaceName(faceName
);
512 void wxFont::SetUnderlined(bool underlined
)
516 M_FONTDATA
->m_underlined
= underlined
;
521 void wxFont::SetNoAntiAliasing( bool no
)
525 M_FONTDATA
->SetNoAntiAliasing( no
);
530 // ----------------------------------------------------------------------------
532 // ----------------------------------------------------------------------------
534 // TODO: insert checks everywhere for M_FONTDATA == NULL!
536 int wxFont::GetPointSize() const
538 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
540 return M_FONTDATA
->m_pointSize
;
543 wxSize
wxFont::GetPixelSize() const
545 #if wxUSE_GRAPHICS_CONTEXT
546 // TODO: consider caching the value
547 wxGraphicsContext
* dc
= wxGraphicsContext::CreateFromNative((CGContextRef
) NULL
);
548 dc
->SetFont(*(wxFont
*)this,*wxBLACK
);
549 wxDouble width
, height
= 0;
550 dc
->GetTextExtent( wxT("g"), &width
, &height
, NULL
, NULL
);
551 return wxSize((int)width
, (int)height
);
553 wxFontBase::GetPixelSize();
557 int wxFont::GetFamily() const
559 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
561 return M_FONTDATA
->m_family
;
564 int wxFont::GetStyle() const
566 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
568 return M_FONTDATA
->m_style
;
571 int wxFont::GetWeight() const
573 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
575 return M_FONTDATA
->m_weight
;
578 bool wxFont::GetUnderlined() const
580 wxCHECK_MSG( M_FONTDATA
!= NULL
, false, wxT("invalid font") );
582 return M_FONTDATA
->m_underlined
;
585 wxString
wxFont::GetFaceName() const
587 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxEmptyString
, wxT("invalid font") );
589 return M_FONTDATA
->m_faceName
;
592 wxFontEncoding
wxFont::GetEncoding() const
594 wxCHECK_MSG( M_FONTDATA
!= NULL
, wxFONTENCODING_DEFAULT
, wxT("invalid font") );
596 return M_FONTDATA
->m_encoding
;
599 bool wxFont::GetNoAntiAliasing() const
601 wxCHECK_MSG( M_FONTDATA
!= NULL
, false, wxT("invalid font") );
603 return M_FONTDATA
->m_noAA
;
606 short wxFont::MacGetFontNum() const
608 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
610 return M_FONTDATA
->m_macFontFamily
;
613 short wxFont::MacGetFontSize() const
615 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
617 return M_FONTDATA
->m_macFontSize
;
620 wxByte
wxFont::MacGetFontStyle() const
622 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
624 return M_FONTDATA
->m_macFontStyle
;
627 wxUint32
wxFont::MacGetATSUFontID() const
629 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
631 return M_FONTDATA
->m_macATSUFontID
;
634 void * wxFont::MacGetATSUStyle() const
636 wxCHECK_MSG( M_FONTDATA
!= NULL
, NULL
, wxT("invalid font") );
638 return M_FONTDATA
->m_macATSUStyle
;
641 wxUint32
wxFont::MacGetATSUAdditionalQDStyles() const
643 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
645 return M_FONTDATA
->m_macATSUAdditionalQDStyles
;
648 wxUint16
wxFont::MacGetThemeFontID() const
650 wxCHECK_MSG( M_FONTDATA
!= NULL
, 0, wxT("invalid font") );
652 return M_FONTDATA
->m_macThemeFontID
;
655 const wxNativeFontInfo
* wxFont::GetNativeFontInfo() const
657 wxCHECK_MSG( M_FONTDATA
!= NULL
, NULL
, wxT("invalid font") );
658 wxCHECK_MSG( Ok(), NULL
, wxT("invalid font") );
660 M_FONTDATA
->m_info
.InitFromFont(*this);
662 return &(M_FONTDATA
->m_info
);