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