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