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
);