]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/font.cpp
remove some duplication in font scaling code
[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"
987e9419 19 #include "wx/intl.h"
dd05139a 20 #include "wx/gdicmn.h"
162f6b2a 21 #include "wx/log.h"
df91131c
WS
22#endif
23
5b781a67 24#include "wx/fontutil.h"
ccd67a6a 25#include "wx/graphics.h"
3b7e6277 26
b3c1d21c 27#include "wx/mac/uma.h"
6eaa4426 28
768c6e8b 29#ifndef __DARWIN__
7f0c3a63 30#include <ATSUnicode.h>
768c6e8b 31#endif
76a5e5d2 32
99c13b27 33#include <map>
6eaa4426 34
e9576ca5 35IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
e9576ca5 36
6eaa4426 37
3bf5a59b
VZ
38class WXDLLEXPORT wxFontRefData: public wxGDIRefData
39{
3bf5a59b
VZ
40public:
41 wxFontRefData()
3bf5a59b 42 {
c07e1e2c
SC
43 Init(10, wxDEFAULT, wxNORMAL, wxNORMAL,
44 false, wxT("applicationfont"), wxFONTENCODING_DEFAULT);
3bf5a59b
VZ
45 }
46
47 wxFontRefData(const wxFontRefData& data)
3bf5a59b
VZ
48 {
49 Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
50 data.m_underlined, data.m_faceName, data.m_encoding);
51 }
52
53 wxFontRefData(int size,
54 int family,
55 int style,
56 int weight,
57 bool underlined,
58 const wxString& faceName,
59 wxFontEncoding encoding)
3bf5a59b
VZ
60 {
61 Init(size, family, style, weight, underlined, faceName, encoding);
62 }
8f884a0d 63
8b534a7b
SC
64#if wxMAC_USE_CORE_TEXT
65 wxFontRefData( wxUint32 coreTextFontType );
66 wxFontRefData( CTFontRef font );
67 wxFontRefData( CTFontDescriptorRef fontdescriptor, int size );
68#endif
3bf5a59b
VZ
69
70 virtual ~wxFontRefData();
6eaa4426 71
8b534a7b 72 void SetNoAntiAliasing( bool no = true ) { m_noAA = no; }
6eaa4426 73
8b534a7b 74 bool GetNoAntiAliasing() const { return m_noAA; }
6eaa4426 75
8f884a0d 76 void SetPointSize( int size )
8b534a7b
SC
77 {
78 m_pointSize = size;
79 MacInvalidateNativeFont();
80 }
8f884a0d 81
8b534a7b 82 int GetPointSize() const { return m_pointSize; }
8f884a0d
VZ
83
84 void SetFamily( int family )
8b534a7b
SC
85 {
86 m_family = family;
87 MacInvalidateNativeFont();
88 }
8f884a0d
VZ
89
90
8b534a7b 91 int GetFamily() const { return m_family; }
8f884a0d
VZ
92
93 void SetStyle( int style )
8b534a7b
SC
94 {
95 m_style = style;
96 MacInvalidateNativeFont();
97 }
8f884a0d
VZ
98
99
8b534a7b 100 int GetStyle() const { return m_style; }
8f884a0d
VZ
101
102 void SetWeight( int weight )
8b534a7b
SC
103 {
104 m_weight = weight;
105 MacInvalidateNativeFont();
106 }
8f884a0d
VZ
107
108
8b534a7b 109 int GetWeight() const { return m_weight; }
8f884a0d
VZ
110
111 void SetUnderlined( bool u )
8b534a7b
SC
112 {
113 m_underlined = u;
114 MacInvalidateNativeFont();
115 }
8f884a0d 116
8b534a7b 117 bool GetUnderlined() const { return m_underlined; }
8f884a0d
VZ
118
119 void SetFaceName( const wxString& facename )
8b534a7b
SC
120 {
121 m_faceName = facename;
122 MacInvalidateNativeFont();
123 }
8f884a0d 124
8b534a7b 125 const wxString& GetFaceName() const { return m_faceName; }
8f884a0d
VZ
126
127 void SetEncoding( wxFontEncoding encoding )
8b534a7b
SC
128 {
129 m_encoding = encoding;
130 MacInvalidateNativeFont();
8f884a0d
VZ
131 }
132
133 wxFontEncoding GetEncoding() const { return m_encoding; }
134
8b534a7b 135 void MacInvalidateNativeFont();
8f884a0d 136
2a0155df 137 void MacFindFont();
8f884a0d 138
3bf5a59b
VZ
139protected:
140 // common part of all ctors
141 void Init(int size,
142 int family,
143 int style,
144 int weight,
145 bool underlined,
146 const wxString& faceName,
147 wxFontEncoding encoding);
148
8b534a7b
SC
149#if wxMAC_USE_CORE_TEXT
150 void Init( CTFontRef font );
8f884a0d 151#endif
3bf5a59b 152 // font characterstics
e369bddb
GD
153 int m_pointSize;
154 int m_family;
155 int m_style;
156 int m_weight;
157 bool m_underlined;
158 wxString m_faceName;
159 wxFontEncoding m_encoding;
3bf5a59b 160 bool m_noAA; // No anti-aliasing
6eaa4426 161
3bf5a59b 162public:
c07e1e2c 163#if wxMAC_USE_ATSU_TEXT
2a0155df
SC
164 FMFontFamily m_macFontFamily;
165 FMFontSize m_macFontSize;
166 FMFontStyle m_macFontStyle;
6eaa4426 167
facd6764 168 // ATSU Font Information
6eaa4426 169
3103e8a9 170 // this is split into an ATSU font id that may
facd6764
SC
171 // contain some styles (special bold fonts etc) and
172 // these are the additional qd styles that are not
173 // included in the ATSU font id
174 ATSUFontID m_macATSUFontID;
2a0155df 175 FMFontStyle m_macATSUAdditionalQDStyles ;
6eaa4426 176
facd6764
SC
177 // for true themeing support we must store the correct font
178 // information here, as this speeds up and optimizes rendering
179 ThemeFontID m_macThemeFontID ;
c07e1e2c
SC
180#endif
181#if wxMAC_USE_CORE_TEXT
182 wxCFRef<CTFontRef> m_ctFont;
8b534a7b 183 wxCFRef<CTFontDescriptorRef> m_ctFontDescriptor;
f34105c6
SC
184#endif
185#if wxMAC_USE_CORE_TEXT || wxMAC_USE_ATSU_TEXT
186 ATSUStyle m_macATSUStyle ;
6239ee05 187#endif
6eaa4426 188 wxNativeFontInfo m_info;
3bf5a59b 189};
6eaa4426 190
68c95704 191#define M_FONTDATA ((wxFontRefData*)m_refData)
873fd4af 192
6eaa4426 193
e7549107
SC
194// ============================================================================
195// implementation
196// ============================================================================
197
198// ----------------------------------------------------------------------------
199// wxFontRefData
200// ----------------------------------------------------------------------------
201
202void wxFontRefData::Init(int pointSize,
6eaa4426
DS
203 int family,
204 int style,
205 int weight,
206 bool underlined,
207 const wxString& faceName,
208 wxFontEncoding encoding)
e9576ca5 209{
e7549107
SC
210 m_style = style;
211 m_pointSize = pointSize;
212 m_family = family;
213 m_style = style;
214 m_weight = weight;
215 m_underlined = underlined;
216 m_faceName = faceName;
217 m_encoding = encoding;
c07e1e2c 218 m_noAA = false;
c07e1e2c 219#if wxMAC_USE_ATSU_TEXT
2a0155df 220 m_macFontFamily = 0 ;
d84afea9
GD
221 m_macFontSize = 0;
222 m_macFontStyle = 0;
facd6764
SC
223 m_macATSUFontID = 0;
224 m_macATSUAdditionalQDStyles = 0 ;
facd6764 225 m_macThemeFontID = kThemeCurrentPortFont ;
f34105c6
SC
226#endif
227#if wxMAC_USE_CORE_TEXT || wxMAC_USE_ATSU_TEXT
6239ee05 228 m_macATSUStyle = NULL ;
c07e1e2c 229#endif
e9576ca5
SC
230}
231
232wxFontRefData::~wxFontRefData()
233{
f34105c6 234#if wxMAC_USE_CORE_TEXT || wxMAC_USE_ATSU_TEXT
3e527073
SC
235 if ( m_macATSUStyle )
236 {
237 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
238 m_macATSUStyle = NULL ;
239 }
9f4e08ae 240#endif
e9576ca5
SC
241}
242
8b534a7b
SC
243void wxFontRefData::MacInvalidateNativeFont()
244{
245#if wxMAC_USE_CORE_TEXT
246 m_ctFont.reset();
247 m_ctFontDescriptor.reset();
248#endif
f34105c6 249#if wxMAC_USE_CORE_TEXT || wxMAC_USE_ATSU_TEXT
8b534a7b
SC
250 if ( m_macATSUStyle )
251 {
252 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
253 m_macATSUStyle = NULL ;
254 }
255#endif
256}
257
c07e1e2c 258#if wxMAC_USE_CORE_TEXT
6239ee05 259
8f884a0d 260/* from Core Text Manual Common Operations */
c07e1e2c 261
8b534a7b 262static CTFontDescriptorRef wxMacCreateCTFontDescriptor(CFStringRef iFamilyName, CTFontSymbolicTraits iTraits )
c07e1e2c
SC
263{
264 CTFontDescriptorRef descriptor = NULL;
265 CFMutableDictionaryRef attributes;
8f884a0d 266
c07e1e2c
SC
267 assert(iFamilyName != NULL);
268 // Create a mutable dictionary to hold our attributes.
269 attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
270 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
271 check(attributes != NULL);
8f884a0d
VZ
272
273 if (attributes != NULL) {
c07e1e2c
SC
274 // Add a family name to our attributes.
275 CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, iFamilyName);
8f884a0d
VZ
276
277
c07e1e2c
SC
278 if ( iTraits ) {
279 CFMutableDictionaryRef traits;
280 CFNumberRef symTraits;
281
282 // Create the traits dictionary.
283 symTraits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type,
284 &iTraits);
285 check(symTraits != NULL);
8f884a0d 286
c07e1e2c
SC
287 if (symTraits != NULL) {
288 // Create a dictionary to hold our traits values.
289 traits = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
290 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
291 check(traits != NULL);
8f884a0d 292
c07e1e2c
SC
293 if (traits != NULL) {
294 // Add the symbolic traits value to the traits dictionary.
295 CFDictionaryAddValue(traits, kCTFontSymbolicTrait, symTraits);
8f884a0d 296
c07e1e2c
SC
297 // Add the traits attribute to our attributes.
298 CFDictionaryAddValue(attributes, kCTFontTraitsAttribute, traits);
299 CFRelease(traits);
300 }
301 CFRelease(symTraits);
6239ee05
SC
302 }
303 }
99c13b27 304 // Create the font descriptor with our attributes
c07e1e2c
SC
305 descriptor = CTFontDescriptorCreateWithAttributes(attributes);
306 check(descriptor != NULL);
8f884a0d 307
c07e1e2c 308 CFRelease(attributes);
6239ee05 309 }
c07e1e2c 310 // Return our font descriptor.
8b534a7b
SC
311 return descriptor ;
312}
313
314wxFontRefData::wxFontRefData( wxUint32 coreTextFontType )
315{
316 CTFontRef font = CTFontCreateUIFontForLanguage( coreTextFontType, 0.0, NULL ) ;
317 if ( CTFontGetSize(m_ctFont) == 0 )
318 {
319 CFRelease(font);
320 font = CTFontCreateUIFontForLanguage( coreTextFontType, 12.0, NULL );
321 }
322 Init( font );
323}
324
325wxFontRefData::wxFontRefData( CTFontRef font )
326{
327 Init( font );
328}
329
330wxFontRefData::wxFontRefData( CTFontDescriptorRef fontdescriptor, int size )
331{
332 if ( size == 0 )
333 {
334 wxCFRef< CFNumberRef > value( (CFNumberRef) CTFontDescriptorCopyAttribute( fontdescriptor, kCTFontSizeAttribute ) );
8f884a0d 335
8b534a7b
SC
336 float fsize;
337 if ( CFNumberGetValue( value , kCFNumberFloatType , &fsize ) )
338 {
339 size = (int) fsize + 0.5 ;
340 }
341 }
342 Init( CTFontCreateWithFontDescriptor(fontdescriptor, size,NULL) );
343}
344
345void wxFontRefData::Init( CTFontRef font )
346{
347 Init(10, wxDEFAULT, wxNORMAL, wxNORMAL,
348 false, wxT("applicationfont"), wxFONTENCODING_DEFAULT);
349
350 m_ctFont.reset( font );
c07e1e2c 351}
6239ee05 352
1bd568fa 353#endif
6239ee05 354
c07e1e2c
SC
355void wxFontRefData::MacFindFont()
356{
6239ee05 357
c07e1e2c 358#if wxMAC_USE_CORE_TEXT
b3c1d21c 359 if ( UMAGetSystemVersion() >= 0x1050 )
e40298d5 360 {
8b534a7b 361 if ( m_faceName.empty() && m_family == wxDEFAULT )
c07e1e2c 362 {
8b534a7b 363 m_ctFont.reset(CTFontCreateUIFontForLanguage( kCTFontSystemFontType, 0.0, NULL ));
c07e1e2c 364 }
8f884a0d 365
dbe4a80c 366 if ( m_ctFont )
8f884a0d 367 {
dbe4a80c 368 wxCFStringRef name( CTFontCopyFamilyName( m_ctFont ) );
c07e1e2c 369 m_faceName = name.AsString();
c07e1e2c 370 m_pointSize = CTFontGetSize(m_ctFont) ;
8b534a7b
SC
371 CTFontSymbolicTraits traits = CTFontGetSymbolicTraits( m_ctFont );
372 if ( traits & kCTFontItalicTrait )
373 m_style = wxITALIC;
374 if ( traits & kCTFontBoldTrait )
375 m_weight = wxBOLD ;
376 if ( !m_ctFontDescriptor.get() )
377 m_ctFontDescriptor.reset( CTFontCopyFontDescriptor( m_ctFont ) );
c07e1e2c
SC
378 }
379 else
380 {
381 if ( m_faceName.empty() )
2a0155df
SC
382 {
383 switch ( m_family )
384 {
385 case wxSCRIPT :
386 case wxROMAN :
387 case wxDECORATIVE :
388 m_faceName = wxT("Times");
389 break ;
8f884a0d 390
2a0155df
SC
391 case wxSWISS :
392 m_faceName = wxT("Lucida Grande");
393 break ;
8f884a0d 394
2a0155df 395 case wxMODERN :
d9485f89 396 case wxTELETYPE:
2a0155df
SC
397 m_faceName = wxT("Monaco");
398 break ;
8f884a0d 399
2a0155df
SC
400 default:
401 m_faceName = wxT("Times");
402 break ;
403 }
facd6764 404 }
c07e1e2c 405
99c13b27 406
c07e1e2c 407 CTFontSymbolicTraits traits = 0;
8f884a0d 408
c07e1e2c
SC
409 if (m_weight == wxBOLD)
410 traits |= kCTFontBoldTrait;
411 if (m_style == wxITALIC || m_style == wxSLANT)
412 traits |= kCTFontItalicTrait;
99c13b27
SC
413
414// use font descriptor caching
415#if 1
ee223f80 416 wxString lookupname = wxString::Format( "%s_%ld", m_faceName.c_str(), traits );
99c13b27
SC
417
418 static std::map< std::wstring , wxCFRef< CTFontDescriptorRef > > fontdescriptorcache ;
419
420 m_ctFontDescriptor = fontdescriptorcache[ std::wstring(lookupname.wc_str()) ];
421 if ( !m_ctFontDescriptor )
422 {
423 wxCFStringRef cf( m_faceName, wxLocale::GetSystemEncoding() );
424 m_ctFontDescriptor.reset( wxMacCreateCTFontDescriptor( cf, traits ) );
425 fontdescriptorcache[ std::wstring(lookupname.wc_str()) ] = m_ctFontDescriptor;
426 }
427#else
428 wxCFStringRef cf( m_faceName, wxLocale::GetSystemEncoding() );
8b534a7b 429 m_ctFontDescriptor.reset( wxMacCreateCTFontDescriptor( cf, traits ) );
99c13b27
SC
430#endif
431
432// use font caching
433#if 1
ee223f80 434 wxString lookupnameWithSize = wxString::Format( "%s_%ld_%ld", m_faceName.c_str(), traits, m_pointSize );
99c13b27
SC
435
436 static std::map< std::wstring , wxCFRef< CTFontRef > > fontcache ;
437 m_ctFont = fontcache[ std::wstring(lookupnameWithSize.wc_str()) ];
438 if ( !m_ctFont )
439 {
440 m_ctFont.reset( CTFontCreateWithFontDescriptor( m_ctFontDescriptor, m_pointSize, NULL ) );
441 fontcache[ std::wstring(lookupnameWithSize.wc_str()) ] = m_ctFont;
442 }
443#else
8b534a7b 444 m_ctFont.reset( CTFontCreateWithFontDescriptor( m_ctFontDescriptor, m_pointSize, NULL ) );
99c13b27 445#endif
facd6764 446 }
f34105c6
SC
447#if wxMAC_USE_ATSU_TEXT == 0
448 OSStatus status = noErr;
449 CTFontDescriptorRef desc = m_ctFontDescriptor ;
450 ATSFontRef atsfont = CTFontGetPlatformFont( m_ctFont, &desc );
451 FMFont fmfont = FMGetFontFromATSFontRef( atsfont );
452 ATSUAttributeTag atsuTags[] =
453 {
454 kATSUFontTag ,
455 kATSUSizeTag ,
456 kATSUVerticalCharacterTag,
457 kATSUQDBoldfaceTag ,
458 kATSUQDItalicTag ,
459 kATSUQDUnderlineTag ,
460 };
461 ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
462 {
463 sizeof( ATSUFontID ) ,
464 sizeof( Fixed ) ,
465 sizeof( ATSUVerticalCharacterType),
466 sizeof( Boolean ) ,
467 sizeof( Boolean ) ,
468 sizeof( Boolean ) ,
469 };
470 Boolean kTrue = true ;
471 Boolean kFalse = false ;
8f884a0d 472
f34105c6
SC
473 Fixed atsuSize = IntToFixed( m_pointSize );
474 ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
475 ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
476 {
477 &fmfont ,
478 &atsuSize ,
479 &kHorizontal,
480 (m_weight == wxBOLD) ? &kTrue : &kFalse ,
481 (m_style == wxITALIC || m_style == wxSLANT) ? &kTrue : &kFalse ,
482 (m_underlined) ? &kTrue : &kFalse ,
483 };
8f884a0d 484
f34105c6
SC
485 if ( m_macATSUStyle )
486 {
487 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
488 m_macATSUStyle = NULL ;
489 }
490 status = ::ATSUCreateStyle((ATSUStyle *)&m_macATSUStyle);
491 wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") );
492 status = ::ATSUSetAttributes(
493 (ATSUStyle)m_macATSUStyle,
494 sizeof(atsuTags) / sizeof(ATSUAttributeTag) ,
495 atsuTags, atsuSizes, atsuValues);
496#endif
c07e1e2c
SC
497 }
498#endif
499#if wxMAC_USE_ATSU_TEXT
500 {
9f4e08ae 501 OSStatus status = noErr;
c07e1e2c
SC
502 Str255 qdFontName ;
503 if ( m_macThemeFontID != kThemeCurrentPortFont )
e40298d5 504 {
c07e1e2c
SC
505 Style style ;
506 GetThemeFont( m_macThemeFontID, GetApplicationScript(), qdFontName, &m_macFontSize, &style );
507 if ( m_macFontSize == 0 )
508 m_macFontSize = 12;
509 m_macFontStyle = style ;
510 m_faceName = wxMacMakeStringFromPascal( qdFontName );
511 if ( m_macFontStyle & bold )
512 m_weight = wxBOLD ;
facd6764 513 else
c07e1e2c
SC
514 m_weight = wxNORMAL ;
515 if ( m_macFontStyle & italic )
516 m_style = wxITALIC ;
517 if ( m_macFontStyle & underline )
518 m_underlined = true ;
519 m_pointSize = m_macFontSize ;
520 m_macFontFamily = FMGetFontFamilyFromName( qdFontName );
521 }
522 else
523 {
524 if ( m_faceName.empty() )
facd6764 525 {
c07e1e2c 526 if ( m_family == wxDEFAULT )
dedf5d9f 527 {
dedf5d9f 528 m_macFontFamily = GetAppFont();
c07e1e2c
SC
529 FMGetFontFamilyName(m_macFontFamily,qdFontName);
530 m_faceName = wxMacMakeStringFromPascal( qdFontName );
531 }
532 else
533 {
534 switch ( m_family )
535 {
536 case wxSCRIPT :
537 case wxROMAN :
538 case wxDECORATIVE :
539 m_faceName = wxT("Times");
540 break ;
8f884a0d 541
c07e1e2c
SC
542 case wxSWISS :
543 m_faceName = wxT("Lucida Grande");
544 break ;
8f884a0d 545
c07e1e2c
SC
546 case wxMODERN :
547 case wxTELETYPE:
548 m_faceName = wxT("Monaco");
549 break ;
8f884a0d 550
c07e1e2c
SC
551 default:
552 m_faceName = wxT("Times");
553 break ;
554 }
555 wxMacStringToPascal( m_faceName , qdFontName );
556 m_macFontFamily = FMGetFontFamilyFromName( qdFontName );
557 if ( m_macFontFamily == kInvalidFontFamily )
558 {
559 wxLogDebug( wxT("ATSFontFamilyFindFromName failed for %s"), m_faceName.c_str() );
560 m_macFontFamily = GetAppFont();
561 }
dedf5d9f 562 }
c07e1e2c
SC
563 }
564 else
565 {
566 if ( m_faceName == wxT("systemfont") )
567 m_macFontFamily = GetSysFont();
568 else if ( m_faceName == wxT("applicationfont") )
569 m_macFontFamily = GetAppFont();
dedf5d9f 570 else
c07e1e2c 571 {
dbe4a80c 572 wxCFStringRef cf( m_faceName, wxLocale::GetSystemEncoding() );
c07e1e2c
SC
573 ATSFontFamilyRef atsfamily = ATSFontFamilyFindFromName( cf , kATSOptionFlagsDefault );
574 if ( atsfamily == (ATSFontFamilyRef) -1 )
575 {
576 wxLogDebug( wxT("ATSFontFamilyFindFromName failed for ") + m_faceName );
577 m_macFontFamily = GetAppFont();
578 }
579 else
580 m_macFontFamily = FMGetFontFamilyFromATSFontFamilyRef( atsfamily );
581 }
facd6764 582 }
8f884a0d 583
c07e1e2c
SC
584 m_macFontStyle = 0;
585 if (m_weight == wxBOLD)
586 m_macFontStyle |= bold;
587 if (m_style == wxITALIC || m_style == wxSLANT)
588 m_macFontStyle |= italic;
589 if (m_underlined)
590 m_macFontStyle |= underline;
591 m_macFontSize = m_pointSize ;
e40298d5 592 }
8f884a0d 593
c07e1e2c 594 // we try to get as much styles as possible into ATSU
8f884a0d
VZ
595
596
c07e1e2c
SC
597 // ATSUFontID and FMFont are equivalent
598 FMFontStyle intrinsicStyle = 0 ;
599 status = FMGetFontFromFontFamilyInstance( m_macFontFamily , m_macFontStyle , &m_macATSUFontID , &intrinsicStyle);
600 wxASSERT_MSG( status == noErr , wxT("couldn't get an ATSUFont from font family") );
601 m_macATSUAdditionalQDStyles = m_macFontStyle & (~intrinsicStyle );
8f884a0d 602
c07e1e2c
SC
603 if ( m_macATSUStyle )
604 {
605 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
606 m_macATSUStyle = NULL ;
607 }
8f884a0d 608
c07e1e2c
SC
609 status = ::ATSUCreateStyle((ATSUStyle *)&m_macATSUStyle);
610 wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") );
8f884a0d 611
c07e1e2c
SC
612 ATSUAttributeTag atsuTags[] =
613 {
614 kATSUFontTag ,
615 kATSUSizeTag ,
616 kATSUVerticalCharacterTag,
617 kATSUQDBoldfaceTag ,
618 kATSUQDItalicTag ,
619 kATSUQDUnderlineTag ,
620 kATSUQDCondensedTag ,
621 kATSUQDExtendedTag ,
622 };
623 ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
624 {
625 sizeof( ATSUFontID ) ,
626 sizeof( Fixed ) ,
627 sizeof( ATSUVerticalCharacterType),
628 sizeof( Boolean ) ,
629 sizeof( Boolean ) ,
630 sizeof( Boolean ) ,
631 sizeof( Boolean ) ,
632 sizeof( Boolean ) ,
633 };
8f884a0d 634
c07e1e2c
SC
635 Boolean kTrue = true ;
636 Boolean kFalse = false ;
8f884a0d 637
c07e1e2c
SC
638 Fixed atsuSize = IntToFixed( m_macFontSize );
639 ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
640 ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
641 {
3e527073
SC
642 &m_macATSUFontID ,
643 &atsuSize ,
644 &kHorizontal,
645 (m_macATSUAdditionalQDStyles & bold) ? &kTrue : &kFalse ,
646 (m_macATSUAdditionalQDStyles & italic) ? &kTrue : &kFalse ,
647 (m_macATSUAdditionalQDStyles & underline) ? &kTrue : &kFalse ,
648 (m_macATSUAdditionalQDStyles & condense) ? &kTrue : &kFalse ,
649 (m_macATSUAdditionalQDStyles & extend) ? &kTrue : &kFalse ,
c07e1e2c 650 };
8f884a0d 651
c07e1e2c
SC
652 status = ::ATSUSetAttributes(
653 (ATSUStyle)m_macATSUStyle,
654 sizeof(atsuTags) / sizeof(ATSUAttributeTag) ,
655 atsuTags, atsuSizes, atsuValues);
8f884a0d 656
c07e1e2c
SC
657 wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") );
658 return;
659 }
6239ee05 660#endif
519cb848
SC
661}
662
e7549107
SC
663// ----------------------------------------------------------------------------
664// wxFont
665// ----------------------------------------------------------------------------
e9576ca5 666
5b781a67
SC
667bool wxFont::Create(const wxNativeFontInfo& info)
668{
6eaa4426
DS
669 return Create(
670 info.pointSize, info.family, info.style, info.weight,
671 info.underlined, info.faceName, info.encoding );
5b781a67
SC
672}
673
3b7e6277
GD
674wxFont::wxFont(const wxString& fontdesc)
675{
676 wxNativeFontInfo info;
677 if ( info.FromString(fontdesc) )
678 (void)Create(info);
679}
680
e7549107 681bool wxFont::Create(int pointSize,
6eaa4426
DS
682 int family,
683 int style,
684 int weight,
685 bool underlined,
686 const wxString& faceName,
687 wxFontEncoding encoding)
e9576ca5
SC
688{
689 UnRef();
6eaa4426
DS
690
691 m_refData = new wxFontRefData(
692 pointSize, family, style, weight,
693 underlined, faceName, encoding);
e9576ca5
SC
694
695 RealizeResource();
696
6eaa4426 697 return true;
e9576ca5
SC
698}
699
c07e1e2c 700#if wxMAC_USE_CORE_TEXT
6239ee05 701
8b534a7b 702bool wxFont::MacCreateFromUIFont(wxUint32 ctFontType )
6239ee05
SC
703{
704 UnRef();
705
8b534a7b 706 m_refData = new wxFontRefData(ctFontType);
6239ee05
SC
707 RealizeResource();
708
709 return true;
710}
711
8b534a7b
SC
712bool wxFont::MacCreateFromCTFontDescriptor( const void * ctFontDescriptor , int size )
713{
714 UnRef();
8f884a0d 715
8b534a7b
SC
716 m_refData = new wxFontRefData((CTFontDescriptorRef)ctFontDescriptor, size);;
717 RealizeResource();
8f884a0d 718
8b534a7b
SC
719 return true;
720}
721
722
6239ee05
SC
723#endif
724
8b534a7b 725bool wxFont::MacCreateFromThemeFont(wxUint16 themeFontID)
facd6764 726{
c07e1e2c 727#if wxMAC_USE_CORE_TEXT
b3c1d21c 728 if ( UMAGetSystemVersion() >= 0x1050)
c07e1e2c 729 {
8b534a7b 730 return MacCreateFromUIFont(HIThemeGetUIFontType(themeFontID));
c07e1e2c
SC
731 }
732#endif
9f4e08ae 733#if wxMAC_USE_ATSU_TEXT
c07e1e2c
SC
734 {
735 UnRef();
6eaa4426 736
c07e1e2c
SC
737 m_refData = new wxFontRefData(
738 12, wxDEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
739 false, wxEmptyString, wxFONTENCODING_DEFAULT );
facd6764 740
c07e1e2c
SC
741 M_FONTDATA->m_macThemeFontID = themeFontID ;
742 RealizeResource();
9f4e08ae 743 return true;
c07e1e2c 744 }
6239ee05 745#endif
9f4e08ae 746 return false;
facd6764
SC
747}
748
e9576ca5
SC
749wxFont::~wxFont()
750{
e9576ca5
SC
751}
752
753bool wxFont::RealizeResource()
754{
2a0155df 755 M_FONTDATA->MacFindFont();
6eaa4426
DS
756
757 return true;
e9576ca5
SC
758}
759
51abe921
SC
760void wxFont::SetEncoding(wxFontEncoding encoding)
761{
83dcd781 762 Unshare();
51abe921 763
8b534a7b 764 M_FONTDATA->SetEncoding( encoding );
51abe921
SC
765
766 RealizeResource();
767}
768
83dcd781 769void wxFont::Unshare()
e9576ca5 770{
83dcd781
PC
771 // Don't change shared data
772 if (!m_refData)
773 {
774 m_refData = new wxFontRefData();
775 }
776 else
777 {
778 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
779 UnRef();
780 m_refData = ref;
781 }
e9576ca5
SC
782}
783
8f884a0d
VZ
784wxGDIRefData *wxFont::CreateGDIRefData() const
785{
786 return new wxFontRefData;
787}
788
789wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
790{
791 return new wxFontRefData(*wx_static_cast(const wxFontRefData *, data));
792}
793
e9576ca5
SC
794void wxFont::SetPointSize(int pointSize)
795{
8b534a7b 796 if ( M_FONTDATA->GetPointSize() == pointSize )
c07e1e2c 797 return;
8f884a0d 798
83dcd781 799 Unshare();
e9576ca5 800
8b534a7b 801 M_FONTDATA->SetPointSize( pointSize );
e9576ca5
SC
802
803 RealizeResource();
804}
805
806void wxFont::SetFamily(int family)
807{
83dcd781 808 Unshare();
e9576ca5 809
8b534a7b 810 M_FONTDATA->SetFamily( family );
e9576ca5
SC
811
812 RealizeResource();
813}
814
815void wxFont::SetStyle(int style)
816{
83dcd781 817 Unshare();
e9576ca5 818
8b534a7b 819 M_FONTDATA->SetStyle( style );
e9576ca5
SC
820
821 RealizeResource();
822}
823
824void wxFont::SetWeight(int weight)
825{
83dcd781 826 Unshare();
e9576ca5 827
8b534a7b 828 M_FONTDATA->SetWeight( weight );
e9576ca5
SC
829
830 RealizeResource();
831}
832
85ab460e 833bool wxFont::SetFaceName(const wxString& faceName)
e9576ca5 834{
83dcd781 835 Unshare();
e9576ca5 836
8b534a7b 837 M_FONTDATA->SetFaceName( faceName );
e9576ca5
SC
838
839 RealizeResource();
85ab460e
VZ
840
841 return wxFontBase::SetFaceName(faceName);
e9576ca5
SC
842}
843
844void wxFont::SetUnderlined(bool underlined)
845{
83dcd781 846 Unshare();
e9576ca5 847
8b534a7b 848 M_FONTDATA->SetUnderlined( underlined );
e9576ca5
SC
849
850 RealizeResource();
851}
852
ac17f9b1
SC
853void wxFont::SetNoAntiAliasing( bool no )
854{
83dcd781 855 Unshare();
ac17f9b1
SC
856
857 M_FONTDATA->SetNoAntiAliasing( no );
858
859 RealizeResource();
860}
861
e7549107
SC
862// ----------------------------------------------------------------------------
863// accessors
864// ----------------------------------------------------------------------------
865
fcb35beb
VZ
866// TODO: insert checks everywhere for M_FONTDATA == NULL!
867
e7549107 868int wxFont::GetPointSize() const
e9576ca5 869{
77eddfb7 870 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 871
8b534a7b 872 return M_FONTDATA->GetPointSize();
e9576ca5
SC
873}
874
ccd67a6a
KO
875wxSize wxFont::GetPixelSize() const
876{
877#if wxUSE_GRAPHICS_CONTEXT
878 // TODO: consider caching the value
879 wxGraphicsContext* dc = wxGraphicsContext::CreateFromNative((CGContextRef) NULL);
40503c98 880 dc->SetFont(*(wxFont *)this,*wxBLACK);
ccd67a6a 881 wxDouble width, height = 0;
8a438f46 882 dc->GetTextExtent( wxT("g"), &width, &height, NULL, NULL);
6239ee05 883 delete dc;
8a438f46 884 return wxSize((int)width, (int)height);
ccd67a6a 885#else
5d465013 886 return wxFontBase::GetPixelSize();
ccd67a6a
KO
887#endif
888}
889
e7549107 890int wxFont::GetFamily() const
e9576ca5 891{
77eddfb7 892 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 893
8b534a7b 894 return M_FONTDATA->GetFamily();
e9576ca5
SC
895}
896
e7549107 897int wxFont::GetStyle() const
e9576ca5 898{
77eddfb7 899 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 900
8b534a7b 901 return M_FONTDATA->GetStyle() ;
e7549107
SC
902}
903
904int wxFont::GetWeight() const
905{
77eddfb7 906 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 907
8b534a7b 908 return M_FONTDATA->GetWeight();
e7549107
SC
909}
910
911bool wxFont::GetUnderlined() const
912{
77eddfb7 913 wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
6eaa4426 914
8b534a7b 915 return M_FONTDATA->GetUnderlined();
e7549107
SC
916}
917
918wxString wxFont::GetFaceName() const
919{
facd6764 920 wxCHECK_MSG( M_FONTDATA != NULL , wxEmptyString , wxT("invalid font") );
6eaa4426 921
8b534a7b 922 return M_FONTDATA->GetFaceName() ;
e7549107
SC
923}
924
925wxFontEncoding wxFont::GetEncoding() const
926{
facd6764 927 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTENCODING_DEFAULT , wxT("invalid font") );
6eaa4426 928
8b534a7b 929 return M_FONTDATA->GetEncoding() ;
e9576ca5
SC
930}
931
5ac2e80c 932bool wxFont::GetNoAntiAliasing() const
ac17f9b1 933{
77eddfb7 934 wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
6eaa4426 935
8b534a7b 936 return M_FONTDATA->GetNoAntiAliasing();
ac17f9b1
SC
937}
938
c07e1e2c 939#if wxMAC_USE_ATSU_TEXT
6239ee05 940
facd6764 941short wxFont::MacGetFontNum() const
fcb35beb 942{
77eddfb7 943 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 944
2a0155df 945 return M_FONTDATA->m_macFontFamily;
fcb35beb
VZ
946}
947
facd6764 948short wxFont::MacGetFontSize() const
fcb35beb 949{
77eddfb7 950 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 951
fcb35beb
VZ
952 return M_FONTDATA->m_macFontSize;
953}
954
facd6764 955wxByte wxFont::MacGetFontStyle() const
fcb35beb 956{
77eddfb7 957 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 958
fcb35beb
VZ
959 return M_FONTDATA->m_macFontStyle;
960}
961
facd6764 962wxUint32 wxFont::MacGetATSUFontID() const
fcb35beb 963{
77eddfb7 964 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 965
fcb35beb
VZ
966 return M_FONTDATA->m_macATSUFontID;
967}
968
facd6764
SC
969wxUint32 wxFont::MacGetATSUAdditionalQDStyles() const
970{
77eddfb7 971 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 972
facd6764
SC
973 return M_FONTDATA->m_macATSUAdditionalQDStyles;
974}
975
6eaa4426 976wxUint16 wxFont::MacGetThemeFontID() const
facd6764 977{
77eddfb7 978 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 979
facd6764
SC
980 return M_FONTDATA->m_macThemeFontID;
981}
c07e1e2c 982#endif
6239ee05 983
f34105c6
SC
984#if wxMAC_USE_CORE_TEXT || wxMAC_USE_ATSU_TEXT
985void * wxFont::MacGetATSUStyle() const
986{
987 wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
8f884a0d 988
f34105c6
SC
989 return M_FONTDATA->m_macATSUStyle;
990}
991#endif
992
c07e1e2c 993#if wxMAC_USE_CORE_TEXT
6239ee05 994
c07e1e2c 995const void * wxFont::MacGetCTFont() const
6239ee05 996{
c07e1e2c 997 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6239ee05 998
c07e1e2c 999 return (CTFontRef)(M_FONTDATA->m_ctFont);
6239ee05
SC
1000}
1001
8b534a7b
SC
1002const void * wxFont::MacGetCTFontDescriptor() const
1003{
1004 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
8f884a0d 1005
8b534a7b
SC
1006 return (CTFontDescriptorRef)(M_FONTDATA->m_ctFontDescriptor);
1007}
1008
6239ee05 1009#endif
facd6764 1010
6eaa4426 1011const wxNativeFontInfo * wxFont::GetNativeFontInfo() const
3bf5a59b 1012{
facd6764 1013 wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
3bf5a59b
VZ
1014 wxCHECK_MSG( Ok(), NULL, wxT("invalid font") );
1015
1016 M_FONTDATA->m_info.InitFromFont(*this);
1017
1018 return &(M_FONTDATA->m_info);
1019}