]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/font.cpp
wxTabCtrl off build fix.
[wxWidgets.git] / src / mac / carbon / font.cpp
CommitLineData
e9576ca5 1/////////////////////////////////////////////////////////////////////////////
df91131c 2// Name: src/mac/carbon/font.cpp
e9576ca5 3// Purpose: wxFont class
a31a5f85 4// Author: Stefan Csomor
e9576ca5 5// Modified by:
a31a5f85 6// Created: 1998-01-01
e9576ca5 7// RCS-ID: $Id$
a31a5f85 8// Copyright: (c) Stefan Csomor
65571936 9// Licence: wxWindows licence
e9576ca5
SC
10/////////////////////////////////////////////////////////////////////////////
11
3e527073
SC
12#include "wx/wxprec.h"
13
e9576ca5 14#include "wx/font.h"
df91131c
WS
15
16#ifndef WX_PRECOMP
17 #include "wx/string.h"
de6185e2 18 #include "wx/utils.h"
df91131c
WS
19#endif
20
5b781a67 21#include "wx/fontutil.h"
e9576ca5 22#include "wx/gdicmn.h"
3b7e6277
GD
23#include "wx/fontutil.h"
24
76a5e5d2 25#include "wx/mac/private.h"
6eaa4426 26
768c6e8b 27#ifndef __DARWIN__
7f0c3a63 28#include <ATSUnicode.h>
768c6e8b 29#endif
76a5e5d2 30
6eaa4426 31
e9576ca5 32IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
e9576ca5 33
6eaa4426 34
3bf5a59b
VZ
35class WXDLLEXPORT wxFontRefData: public wxGDIRefData
36{
37 friend class WXDLLEXPORT wxFont;
6eaa4426 38
3bf5a59b
VZ
39public:
40 wxFontRefData()
41 : m_fontId(0)
42 , m_pointSize(10)
43 , m_family(wxDEFAULT)
44 , m_style(wxNORMAL)
45 , m_weight(wxNORMAL)
df91131c 46 , m_underlined(false)
c277569a 47 , m_faceName(wxT("applicationfont"))
3bf5a59b 48 , m_encoding(wxFONTENCODING_DEFAULT)
2a0155df 49 , m_macFontFamily(0)
3bf5a59b
VZ
50 , m_macFontSize(0)
51 , m_macFontStyle(0)
3e527073 52 , m_macATSUStyle(0)
e369bddb 53 , m_macATSUFontID(0)
3bf5a59b 54 {
c277569a
SC
55 Init(m_pointSize, m_family, m_style, m_weight,
56 m_underlined, m_faceName, m_encoding);
3bf5a59b
VZ
57 }
58
59 wxFontRefData(const wxFontRefData& data)
60 : wxGDIRefData()
61 , m_fontId(data.m_fontId)
62 , m_pointSize(data.m_pointSize)
63 , m_family(data.m_family)
64 , m_style(data.m_style)
65 , m_weight(data.m_weight)
66 , m_underlined(data.m_underlined)
67 , m_faceName(data.m_faceName)
68 , m_encoding(data.m_encoding)
2a0155df 69 , m_macFontFamily(data.m_macFontFamily)
3bf5a59b
VZ
70 , m_macFontSize(data.m_macFontSize)
71 , m_macFontStyle(data.m_macFontStyle)
3e527073 72 , m_macATSUStyle(0)
e369bddb 73 , m_macATSUFontID(data.m_macATSUFontID)
3bf5a59b
VZ
74 {
75 Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
76 data.m_underlined, data.m_faceName, data.m_encoding);
77 }
78
79 wxFontRefData(int size,
80 int family,
81 int style,
82 int weight,
83 bool underlined,
84 const wxString& faceName,
85 wxFontEncoding encoding)
86 : m_fontId(0)
87 , m_pointSize(size)
88 , m_family(family)
89 , m_style(style)
90 , m_weight(weight)
91 , m_underlined(underlined)
92 , m_faceName(faceName)
93 , m_encoding(encoding)
2a0155df 94 , m_macFontFamily(0)
3bf5a59b
VZ
95 , m_macFontSize(0)
96 , m_macFontStyle(0)
3e527073 97 , m_macATSUStyle(0)
e369bddb 98 , m_macATSUFontID(0)
3bf5a59b
VZ
99 {
100 Init(size, family, style, weight, underlined, faceName, encoding);
101 }
102
103 virtual ~wxFontRefData();
6eaa4426
DS
104
105 void SetNoAntiAliasing( bool no = true )
106 { m_noAA = no; }
107
108 bool GetNoAntiAliasing() const
109 { return m_noAA; }
110
2a0155df 111 void MacFindFont();
6eaa4426 112
3bf5a59b
VZ
113protected:
114 // common part of all ctors
115 void Init(int size,
116 int family,
117 int style,
118 int weight,
119 bool underlined,
120 const wxString& faceName,
121 wxFontEncoding encoding);
122
123 // font characterstics
e369bddb
GD
124 int m_fontId;
125 int m_pointSize;
126 int m_family;
127 int m_style;
128 int m_weight;
129 bool m_underlined;
130 wxString m_faceName;
131 wxFontEncoding m_encoding;
3bf5a59b 132 bool m_noAA; // No anti-aliasing
6eaa4426 133
3bf5a59b 134public:
2a0155df
SC
135 FMFontFamily m_macFontFamily;
136 FMFontSize m_macFontSize;
137 FMFontStyle m_macFontStyle;
6eaa4426 138
facd6764 139 // ATSU Font Information
6eaa4426 140
3103e8a9 141 // this is split into an ATSU font id that may
facd6764
SC
142 // contain some styles (special bold fonts etc) and
143 // these are the additional qd styles that are not
144 // included in the ATSU font id
3e527073 145 ATSUStyle m_macATSUStyle ;
facd6764 146 ATSUFontID m_macATSUFontID;
2a0155df 147 FMFontStyle m_macATSUAdditionalQDStyles ;
6eaa4426 148
facd6764
SC
149 // for true themeing support we must store the correct font
150 // information here, as this speeds up and optimizes rendering
151 ThemeFontID m_macThemeFontID ;
3bf5a59b 152
6eaa4426 153 wxNativeFontInfo m_info;
3bf5a59b 154};
6eaa4426
DS
155
156
e7549107
SC
157// ============================================================================
158// implementation
159// ============================================================================
160
161// ----------------------------------------------------------------------------
162// wxFontRefData
163// ----------------------------------------------------------------------------
164
165void wxFontRefData::Init(int pointSize,
6eaa4426
DS
166 int family,
167 int style,
168 int weight,
169 bool underlined,
170 const wxString& faceName,
171 wxFontEncoding encoding)
e9576ca5 172{
e7549107
SC
173 m_style = style;
174 m_pointSize = pointSize;
175 m_family = family;
176 m_style = style;
177 m_weight = weight;
178 m_underlined = underlined;
179 m_faceName = faceName;
180 m_encoding = encoding;
181
2a0155df 182 m_macFontFamily = 0 ;
d84afea9
GD
183 m_macFontSize = 0;
184 m_macFontStyle = 0;
facd6764
SC
185 m_macATSUFontID = 0;
186 m_macATSUAdditionalQDStyles = 0 ;
3e527073 187 m_macATSUStyle = NULL ;
6eaa4426 188
facd6764 189 m_macThemeFontID = kThemeCurrentPortFont ;
6eaa4426 190 m_noAA = false;
e9576ca5
SC
191}
192
193wxFontRefData::~wxFontRefData()
194{
3e527073
SC
195 if ( m_macATSUStyle )
196 {
197 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
198 m_macATSUStyle = NULL ;
199 }
e9576ca5
SC
200}
201
519cb848
SC
202void wxFontRefData::MacFindFont()
203{
2a0155df 204 OSStatus status ;
de6185e2 205
2a0155df 206 Str255 qdFontName ;
6eaa4426 207 if ( m_macThemeFontID != kThemeCurrentPortFont )
e40298d5 208 {
2a0155df
SC
209 Style style ;
210 GetThemeFont( m_macThemeFontID, GetApplicationScript(), qdFontName, &m_macFontSize, &style );
211 m_macFontStyle = style ;
212 m_faceName = wxMacMakeStringFromPascal( qdFontName );
facd6764
SC
213 if ( m_macFontStyle & bold )
214 m_weight = wxBOLD ;
215 else
216 m_weight = wxNORMAL ;
217 if ( m_macFontStyle & italic )
218 m_style = wxITALIC ;
219 if ( m_macFontStyle & underline )
220 m_underlined = true ;
facd6764 221 m_pointSize = m_macFontSize ;
de6185e2 222
2a0155df 223 m_macFontFamily = FMGetFontFamilyFromName( qdFontName );
e40298d5
JS
224 }
225 else
226 {
df91131c 227 if ( m_faceName.empty() )
facd6764 228 {
2a0155df 229 if ( m_family == wxDEFAULT )
facd6764 230 {
2a0155df
SC
231 m_macFontFamily = GetAppFont();
232 FMGetFontFamilyName(m_macFontFamily,qdFontName);
233 m_faceName = wxMacMakeStringFromPascal( qdFontName );
234 }
235 else
236 {
237 switch ( m_family )
238 {
239 case wxSCRIPT :
240 case wxROMAN :
241 case wxDECORATIVE :
242 m_faceName = wxT("Times");
243 break ;
244
245 case wxSWISS :
246 m_faceName = wxT("Lucida Grande");
247 break ;
248
249 case wxMODERN :
250 m_faceName = wxT("Monaco");
251 break ;
252
253 default:
254 m_faceName = wxT("Times");
255 break ;
256 }
257 wxMacStringToPascal( m_faceName , qdFontName );
258 m_macFontFamily = FMGetFontFamilyFromName( qdFontName );
facd6764 259 }
facd6764 260 }
e40298d5
JS
261 else
262 {
facd6764 263 if ( m_faceName == wxT("systemfont") )
2a0155df 264 m_macFontFamily = GetSysFont();
facd6764 265 else if ( m_faceName == wxT("applicationfont") )
2a0155df 266 m_macFontFamily = GetAppFont();
facd6764
SC
267 else
268 {
2a0155df
SC
269 wxMacCFStringHolder cf( m_faceName, wxLocale::GetSystemEncoding() );
270 ATSFontFamilyRef atsfamily = ATSFontFamilyFindFromName( cf , kATSOptionFlagsDefault );
271 m_macFontFamily = FMGetFontFamilyFromATSFontFamilyRef( atsfamily );
facd6764 272 }
e40298d5 273 }
facd6764
SC
274
275 m_macFontStyle = 0;
276 if (m_weight == wxBOLD)
277 m_macFontStyle |= bold;
6eaa4426 278 if (m_style == wxITALIC || m_style == wxSLANT)
facd6764 279 m_macFontStyle |= italic;
6eaa4426 280 if (m_underlined)
facd6764
SC
281 m_macFontStyle |= underline;
282 m_macFontSize = m_pointSize ;
e40298d5
JS
283 }
284
facd6764 285 // we try to get as much styles as possible into ATSU
3e527073 286
6eaa4426 287
2a0155df
SC
288 // ATSUFontID and FMFont are equivalent
289 FMFontStyle intrinsicStyle = 0 ;
290 status = FMGetFontFromFontFamilyInstance( m_macFontFamily , m_macFontStyle , &m_macATSUFontID , &intrinsicStyle);
291 wxASSERT_MSG( status == noErr , wxT("couldn't get an ATSUFont from font family") );
3e527073 292
2a0155df 293 m_macATSUAdditionalQDStyles = m_macFontStyle & (~intrinsicStyle );
de6185e2 294
3e527073
SC
295 if ( m_macATSUStyle )
296 {
297 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
298 m_macATSUStyle = NULL ;
299 }
6eaa4426 300
2a0155df
SC
301 status = ::ATSUCreateStyle((ATSUStyle *)&m_macATSUStyle);
302 wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") );
6eaa4426 303
3e527073
SC
304 ATSUAttributeTag atsuTags[] =
305 {
2a0155df
SC
306 kATSUFontTag ,
307 kATSUSizeTag ,
308 kATSUVerticalCharacterTag,
309 kATSUQDBoldfaceTag ,
310 kATSUQDItalicTag ,
311 kATSUQDUnderlineTag ,
312 kATSUQDCondensedTag ,
313 kATSUQDExtendedTag ,
6eaa4426
DS
314 };
315 ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
3e527073 316 {
2a0155df
SC
317 sizeof( ATSUFontID ) ,
318 sizeof( Fixed ) ,
319 sizeof( ATSUVerticalCharacterType),
320 sizeof( Boolean ) ,
321 sizeof( Boolean ) ,
322 sizeof( Boolean ) ,
323 sizeof( Boolean ) ,
324 sizeof( Boolean ) ,
6eaa4426
DS
325 };
326
3e527073
SC
327 Boolean kTrue = true ;
328 Boolean kFalse = false ;
329
2a0155df 330 Fixed atsuSize = IntToFixed( m_macFontSize );
3e527073 331 ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
6eaa4426 332 ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
3e527073
SC
333 {
334 &m_macATSUFontID ,
335 &atsuSize ,
336 &kHorizontal,
337 (m_macATSUAdditionalQDStyles & bold) ? &kTrue : &kFalse ,
338 (m_macATSUAdditionalQDStyles & italic) ? &kTrue : &kFalse ,
339 (m_macATSUAdditionalQDStyles & underline) ? &kTrue : &kFalse ,
340 (m_macATSUAdditionalQDStyles & condense) ? &kTrue : &kFalse ,
341 (m_macATSUAdditionalQDStyles & extend) ? &kTrue : &kFalse ,
6eaa4426
DS
342 };
343
344 status = ::ATSUSetAttributes(
345 (ATSUStyle)m_macATSUStyle,
346 sizeof(atsuTags) / sizeof(ATSUAttributeTag) ,
3e527073
SC
347 atsuTags, atsuSizes, atsuValues);
348
2a0155df 349 wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") );
519cb848
SC
350}
351
e7549107
SC
352// ----------------------------------------------------------------------------
353// wxFont
354// ----------------------------------------------------------------------------
e9576ca5 355
5b781a67
SC
356bool wxFont::Create(const wxNativeFontInfo& info)
357{
6eaa4426
DS
358 return Create(
359 info.pointSize, info.family, info.style, info.weight,
360 info.underlined, info.faceName, info.encoding );
5b781a67
SC
361}
362
3b7e6277
GD
363wxFont::wxFont(const wxString& fontdesc)
364{
365 wxNativeFontInfo info;
366 if ( info.FromString(fontdesc) )
367 (void)Create(info);
368}
369
e7549107 370bool wxFont::Create(int pointSize,
6eaa4426
DS
371 int family,
372 int style,
373 int weight,
374 bool underlined,
375 const wxString& faceName,
376 wxFontEncoding encoding)
e9576ca5
SC
377{
378 UnRef();
6eaa4426
DS
379
380 m_refData = new wxFontRefData(
381 pointSize, family, style, weight,
382 underlined, faceName, encoding);
e9576ca5
SC
383
384 RealizeResource();
385
6eaa4426 386 return true;
e9576ca5
SC
387}
388
6eaa4426 389bool wxFont::MacCreateThemeFont(wxUint16 themeFontID)
facd6764
SC
390{
391 UnRef();
6eaa4426
DS
392
393 m_refData = new wxFontRefData(
394 12, wxDEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
395 false, wxEmptyString, wxFONTENCODING_DEFAULT );
396
facd6764
SC
397 M_FONTDATA->m_macThemeFontID = themeFontID ;
398 RealizeResource();
399
6eaa4426 400 return true;
facd6764
SC
401}
402
e9576ca5
SC
403wxFont::~wxFont()
404{
e9576ca5
SC
405}
406
407bool wxFont::RealizeResource()
408{
2a0155df 409 M_FONTDATA->MacFindFont();
6eaa4426
DS
410
411 return true;
e9576ca5
SC
412}
413
51abe921
SC
414void wxFont::SetEncoding(wxFontEncoding encoding)
415{
416 Unshare();
417
418 M_FONTDATA->m_encoding = encoding;
419
420 RealizeResource();
421}
422
e9576ca5
SC
423void wxFont::Unshare()
424{
e40298d5
JS
425 // Don't change shared data
426 if (!m_refData)
e9576ca5 427 {
e40298d5
JS
428 m_refData = new wxFontRefData();
429 }
e9576ca5
SC
430 else
431 {
e40298d5
JS
432 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
433 UnRef();
434 m_refData = ref;
435 }
e9576ca5
SC
436}
437
438void wxFont::SetPointSize(int pointSize)
439{
440 Unshare();
441
442 M_FONTDATA->m_pointSize = pointSize;
443
444 RealizeResource();
445}
446
447void wxFont::SetFamily(int family)
448{
449 Unshare();
450
451 M_FONTDATA->m_family = family;
452
453 RealizeResource();
454}
455
456void wxFont::SetStyle(int style)
457{
458 Unshare();
459
460 M_FONTDATA->m_style = style;
461
462 RealizeResource();
463}
464
465void wxFont::SetWeight(int weight)
466{
467 Unshare();
468
469 M_FONTDATA->m_weight = weight;
470
471 RealizeResource();
472}
473
474void wxFont::SetFaceName(const wxString& faceName)
475{
476 Unshare();
477
478 M_FONTDATA->m_faceName = faceName;
479
480 RealizeResource();
481}
482
483void wxFont::SetUnderlined(bool underlined)
484{
485 Unshare();
486
487 M_FONTDATA->m_underlined = underlined;
488
489 RealizeResource();
490}
491
ac17f9b1
SC
492void wxFont::SetNoAntiAliasing( bool no )
493{
494 Unshare();
495
496 M_FONTDATA->SetNoAntiAliasing( no );
497
498 RealizeResource();
499}
500
e7549107
SC
501// ----------------------------------------------------------------------------
502// accessors
503// ----------------------------------------------------------------------------
504
fcb35beb
VZ
505// TODO: insert checks everywhere for M_FONTDATA == NULL!
506
e7549107 507int wxFont::GetPointSize() const
e9576ca5 508{
77eddfb7 509 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 510
e7549107 511 return M_FONTDATA->m_pointSize;
e9576ca5
SC
512}
513
e7549107 514int wxFont::GetFamily() const
e9576ca5 515{
77eddfb7 516 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 517
e7549107 518 return M_FONTDATA->m_family;
e9576ca5
SC
519}
520
e7549107 521int wxFont::GetStyle() const
e9576ca5 522{
77eddfb7 523 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 524
e7549107
SC
525 return M_FONTDATA->m_style;
526}
527
528int wxFont::GetWeight() const
529{
77eddfb7 530 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 531
e7549107
SC
532 return M_FONTDATA->m_weight;
533}
534
535bool wxFont::GetUnderlined() const
536{
77eddfb7 537 wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
6eaa4426 538
e7549107
SC
539 return M_FONTDATA->m_underlined;
540}
541
542wxString wxFont::GetFaceName() const
543{
facd6764 544 wxCHECK_MSG( M_FONTDATA != NULL , wxEmptyString , wxT("invalid font") );
6eaa4426 545
facd6764 546 return M_FONTDATA->m_faceName;
e7549107
SC
547}
548
549wxFontEncoding wxFont::GetEncoding() const
550{
facd6764 551 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTENCODING_DEFAULT , wxT("invalid font") );
6eaa4426 552
e7549107 553 return M_FONTDATA->m_encoding;
e9576ca5
SC
554}
555
5ac2e80c 556bool wxFont::GetNoAntiAliasing() const
ac17f9b1 557{
77eddfb7 558 wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
6eaa4426 559
ac17f9b1
SC
560 return M_FONTDATA->m_noAA;
561}
562
facd6764 563short wxFont::MacGetFontNum() const
fcb35beb 564{
77eddfb7 565 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 566
2a0155df 567 return M_FONTDATA->m_macFontFamily;
fcb35beb
VZ
568}
569
facd6764 570short wxFont::MacGetFontSize() const
fcb35beb 571{
77eddfb7 572 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 573
fcb35beb
VZ
574 return M_FONTDATA->m_macFontSize;
575}
576
facd6764 577wxByte wxFont::MacGetFontStyle() const
fcb35beb 578{
77eddfb7 579 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 580
fcb35beb
VZ
581 return M_FONTDATA->m_macFontStyle;
582}
583
facd6764 584wxUint32 wxFont::MacGetATSUFontID() const
fcb35beb 585{
77eddfb7 586 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 587
fcb35beb
VZ
588 return M_FONTDATA->m_macATSUFontID;
589}
590
6eaa4426 591void * wxFont::MacGetATSUStyle() const
3e527073
SC
592{
593 wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
6eaa4426 594
3e527073
SC
595 return M_FONTDATA->m_macATSUStyle;
596}
597
facd6764
SC
598wxUint32 wxFont::MacGetATSUAdditionalQDStyles() const
599{
77eddfb7 600 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 601
facd6764
SC
602 return M_FONTDATA->m_macATSUAdditionalQDStyles;
603}
604
6eaa4426 605wxUint16 wxFont::MacGetThemeFontID() const
facd6764 606{
77eddfb7 607 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 608
facd6764
SC
609 return M_FONTDATA->m_macThemeFontID;
610}
611
6eaa4426 612const wxNativeFontInfo * wxFont::GetNativeFontInfo() const
3bf5a59b 613{
facd6764 614 wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
3bf5a59b
VZ
615 wxCHECK_MSG( Ok(), NULL, wxT("invalid font") );
616
617 M_FONTDATA->m_info.InitFromFont(*this);
618
619 return &(M_FONTDATA->m_info);
620}