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