]> git.saurik.com Git - wxWidgets.git/blame - src/osx/carbon/font.cpp
Fix for building under 10.4, where the BlendMode constants are not defined.
[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 {
4dd9fdf8 427 uint8_t 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
4abb374e 757#if wxOSX_USE_ATSU_TEXT
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
489468fe
SC
766 {
767 UnRef();
768
769 m_refData = new wxFontRefData(
1fdb23ed 770 12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
489468fe
SC
771 false, wxEmptyString, wxFONTENCODING_DEFAULT );
772
773 M_FONTDATA->m_macThemeFontID = themeFontID ;
774 RealizeResource();
775 return true;
776 }
489468fe
SC
777 return false;
778}
524c47aa 779#endif
489468fe
SC
780
781wxFont::~wxFont()
782{
783}
784
785bool wxFont::RealizeResource()
786{
787 M_FONTDATA->MacFindFont();
788
789 return true;
790}
791
792void wxFont::SetEncoding(wxFontEncoding encoding)
793{
794 Unshare();
795
796 M_FONTDATA->SetEncoding( encoding );
797
798 RealizeResource();
799}
800
801void wxFont::Unshare()
802{
803 // Don't change shared data
804 if (!m_refData)
805 {
806 m_refData = new wxFontRefData();
807 }
808 else
809 {
810 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
811 UnRef();
812 m_refData = ref;
813 }
814}
815
816wxGDIRefData *wxFont::CreateGDIRefData() const
817{
818 return new wxFontRefData;
819}
820
821wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
822{
5c33522f 823 return new wxFontRefData(*static_cast<const wxFontRefData *>(data));
489468fe
SC
824}
825
826void wxFont::SetPointSize(int pointSize)
827{
828 if ( M_FONTDATA->GetPointSize() == pointSize )
829 return;
830
831 Unshare();
832
833 M_FONTDATA->SetPointSize( pointSize );
834
835 RealizeResource();
836}
837
0c14b6c3 838void wxFont::SetFamily(wxFontFamily family)
489468fe
SC
839{
840 Unshare();
841
842 M_FONTDATA->SetFamily( family );
843
844 RealizeResource();
845}
846
0c14b6c3 847void wxFont::SetStyle(wxFontStyle style)
489468fe
SC
848{
849 Unshare();
850
851 M_FONTDATA->SetStyle( style );
852
853 RealizeResource();
854}
855
0c14b6c3 856void wxFont::SetWeight(wxFontWeight weight)
489468fe
SC
857{
858 Unshare();
859
860 M_FONTDATA->SetWeight( weight );
861
862 RealizeResource();
863}
864
865bool wxFont::SetFaceName(const wxString& faceName)
866{
867 Unshare();
868
869 M_FONTDATA->SetFaceName( faceName );
870
871 RealizeResource();
872
873 return wxFontBase::SetFaceName(faceName);
874}
875
876void wxFont::SetUnderlined(bool underlined)
877{
878 Unshare();
879
880 M_FONTDATA->SetUnderlined( underlined );
881
882 RealizeResource();
883}
884
885void wxFont::SetNoAntiAliasing( bool no )
886{
887 Unshare();
888
889 M_FONTDATA->SetNoAntiAliasing( no );
890
891 RealizeResource();
892}
893
894// ----------------------------------------------------------------------------
895// accessors
896// ----------------------------------------------------------------------------
897
898// TODO: insert checks everywhere for M_FONTDATA == NULL!
899
900int wxFont::GetPointSize() const
901{
902 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
903
904 return M_FONTDATA->GetPointSize();
905}
906
907wxSize wxFont::GetPixelSize() const
908{
909#if wxUSE_GRAPHICS_CONTEXT
910 // TODO: consider caching the value
911 wxGraphicsContext* dc = wxGraphicsContext::CreateFromNative((CGContextRef) NULL);
912 dc->SetFont(*(wxFont *)this,*wxBLACK);
913 wxDouble width, height = 0;
914 dc->GetTextExtent( wxT("g"), &width, &height, NULL, NULL);
915 delete dc;
916 return wxSize((int)width, (int)height);
917#else
918 return wxFontBase::GetPixelSize();
919#endif
920}
921
0c14b6c3 922wxFontFamily wxFont::GetFamily() const
489468fe 923{
0c14b6c3 924 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTFAMILY_MAX, wxT("invalid font") );
489468fe
SC
925
926 return M_FONTDATA->GetFamily();
927}
928
0c14b6c3 929wxFontStyle wxFont::GetStyle() const
489468fe 930{
0c14b6c3 931 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTSTYLE_MAX, wxT("invalid font") );
489468fe
SC
932
933 return M_FONTDATA->GetStyle() ;
934}
935
0c14b6c3 936wxFontWeight wxFont::GetWeight() const
489468fe 937{
0c14b6c3 938 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTWEIGHT_MAX, wxT("invalid font") );
489468fe
SC
939
940 return M_FONTDATA->GetWeight();
941}
942
943bool wxFont::GetUnderlined() const
944{
945 wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
946
947 return M_FONTDATA->GetUnderlined();
948}
949
950wxString wxFont::GetFaceName() const
951{
952 wxCHECK_MSG( M_FONTDATA != NULL , wxEmptyString , wxT("invalid font") );
953
954 return M_FONTDATA->GetFaceName() ;
955}
956
957wxFontEncoding wxFont::GetEncoding() const
958{
959 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTENCODING_DEFAULT , wxT("invalid font") );
960
961 return M_FONTDATA->GetEncoding() ;
962}
963
964bool wxFont::GetNoAntiAliasing() const
965{
966 wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
967
968 return M_FONTDATA->GetNoAntiAliasing();
969}
970
292e5e1f 971#if wxOSX_USE_ATSU_TEXT
489468fe
SC
972
973short wxFont::MacGetFontNum() const
974{
975 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
976
977 return M_FONTDATA->m_macFontFamily;
978}
979
980short wxFont::MacGetFontSize() const
981{
982 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
983
984 return M_FONTDATA->m_macFontSize;
985}
986
987wxByte wxFont::MacGetFontStyle() const
988{
989 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
990
991 return M_FONTDATA->m_macFontStyle;
992}
993
994wxUint32 wxFont::MacGetATSUFontID() const
995{
996 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
997
998 return M_FONTDATA->m_macATSUFontID;
999}
1000
1001wxUint32 wxFont::MacGetATSUAdditionalQDStyles() const
1002{
1003 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
1004
1005 return M_FONTDATA->m_macATSUAdditionalQDStyles;
1006}
1007
1008wxUint16 wxFont::MacGetThemeFontID() const
1009{
1010 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
1011
1012 return M_FONTDATA->m_macThemeFontID;
1013}
1014#endif
1015
292e5e1f 1016#if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
489468fe
SC
1017void * wxFont::MacGetATSUStyle() const
1018{
1019 wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
1020
1021 return M_FONTDATA->m_macATSUStyle;
1022}
1023#endif
1024
292e5e1f 1025#if wxOSX_USE_CORE_TEXT
489468fe
SC
1026
1027const void * wxFont::MacGetCTFont() const
1028{
1029 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
1030
1031 return (CTFontRef)(M_FONTDATA->m_ctFont);
1032}
1033
489468fe
SC
1034#endif
1035
1036const wxNativeFontInfo * wxFont::GetNativeFontInfo() const
1037{
1038 wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
1039 wxCHECK_MSG( Ok(), NULL, wxT("invalid font") );
1040
1041 M_FONTDATA->m_info.InitFromFont(*this);
1042
1043 return &(M_FONTDATA->m_info);
1044}