]> git.saurik.com Git - wxWidgets.git/blame - src/osx/carbon/font.cpp
fixing focus, fixes #9985
[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 {
46 Init(10, wxDEFAULT, wxNORMAL, wxNORMAL,
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,
57 int family,
58 int style,
59 int weight,
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
87 void SetFamily( int family )
88 {
89 m_family = family;
90 MacInvalidateNativeFont();
91 }
92
93
94 int GetFamily() const { return m_family; }
95
96 void SetStyle( int style )
97 {
98 m_style = style;
99 MacInvalidateNativeFont();
100 }
101
102
103 int GetStyle() const { return m_style; }
104
105 void SetWeight( int weight )
106 {
107 m_weight = weight;
108 MacInvalidateNativeFont();
109 }
110
111
112 int GetWeight() const { return m_weight; }
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,
145 int family,
146 int style,
147 int weight,
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;
157 int m_family;
158 int m_style;
159 int m_weight;
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,
205 int family,
206 int style,
207 int weight,
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{
348 Init(10, wxDEFAULT, wxNORMAL, wxNORMAL,
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 {
362 if ( m_faceName.empty() && m_family == wxDEFAULT )
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 )
374 m_style = wxITALIC;
375 if ( traits & kCTFontBoldTrait )
376 m_weight = wxBOLD ;
489468fe
SC
377 }
378 else
379 {
380 if ( m_faceName.empty() )
381 {
382 switch ( m_family )
383 {
384 case wxSCRIPT :
385 case wxROMAN :
386 case wxDECORATIVE :
387 m_faceName = wxT("Times");
388 break ;
389
390 case wxSWISS :
92b6654b 391 m_faceName = wxT("Helvetica");
489468fe
SC
392 break ;
393
394 case wxMODERN :
395 case wxTELETYPE:
92b6654b 396 m_faceName = wxT("Courier");
01548e7c
SC
397 if ( m_style == wxITALIC && m_weight == wxNORMAL )
398 {
399 m_style = wxITALIC;
400 }
489468fe
SC
401 break ;
402
403 default:
404 m_faceName = wxT("Times");
405 break ;
406 }
407 }
408
409
410 CTFontSymbolicTraits traits = 0;
411
412 if (m_weight == wxBOLD)
413 traits |= kCTFontBoldTrait;
414 if (m_style == wxITALIC || m_style == wxSLANT)
415 traits |= kCTFontItalicTrait;
416
01548e7c 417 // use font caching
489468fe
SC
418 wxString lookupnameWithSize = wxString::Format( "%s_%ld_%ld", m_faceName.c_str(), traits, m_pointSize );
419
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;
428 if (m_weight == wxBOLD)
429 qdstyle |= bold;
430 if (m_style == wxITALIC || m_style == wxSLANT)
431 qdstyle |= italic;
432
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 }
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 {
469 printf( wxString::Format( "font %s expected %d but got %d traits, %f angle \n" , m_faceName.c_str(), traits, received, angle ) );
470 }
471 CFShow( dict );
472 CFRelease( dict );
b2680ced 473 }
01548e7c 474#endif
b2680ced 475 }
01548e7c 476
489468fe 477 }
292e5e1f 478#if wxOSX_USE_ATSU_TEXT
489468fe 479 OSStatus status = noErr;
01548e7c 480 ATSFontRef atsfont = CTFontGetPlatformFont( m_ctFont, NULL );
489468fe
SC
481 FMFont fmfont = FMGetFontFromATSFontRef( atsfont );
482 ATSUAttributeTag atsuTags[] =
483 {
484 kATSUFontTag ,
485 kATSUSizeTag ,
486 kATSUVerticalCharacterTag,
487 kATSUQDBoldfaceTag ,
488 kATSUQDItalicTag ,
489 kATSUQDUnderlineTag ,
490 };
491 ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
492 {
493 sizeof( ATSUFontID ) ,
494 sizeof( Fixed ) ,
495 sizeof( ATSUVerticalCharacterType),
496 sizeof( Boolean ) ,
497 sizeof( Boolean ) ,
498 sizeof( Boolean ) ,
499 };
500 Boolean kTrue = true ;
501 Boolean kFalse = false ;
502
503 Fixed atsuSize = IntToFixed( m_pointSize );
504 ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
505 ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
506 {
507 &fmfont ,
508 &atsuSize ,
509 &kHorizontal,
510 (m_weight == wxBOLD) ? &kTrue : &kFalse ,
511 (m_style == wxITALIC || m_style == wxSLANT) ? &kTrue : &kFalse ,
512 (m_underlined) ? &kTrue : &kFalse ,
513 };
514
515 if ( m_macATSUStyle )
516 {
517 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
518 m_macATSUStyle = NULL ;
519 }
520 status = ::ATSUCreateStyle((ATSUStyle *)&m_macATSUStyle);
521 wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") );
522 status = ::ATSUSetAttributes(
523 (ATSUStyle)m_macATSUStyle,
524 sizeof(atsuTags) / sizeof(ATSUAttributeTag) ,
525 atsuTags, atsuSizes, atsuValues);
526#endif
527 }
528#endif
292e5e1f 529#if wxOSX_USE_ATSU_TEXT
489468fe
SC
530 {
531 OSStatus status = noErr;
532 Str255 qdFontName ;
533 if ( m_macThemeFontID != kThemeCurrentPortFont )
534 {
535 Style style ;
536 GetThemeFont( m_macThemeFontID, GetApplicationScript(), qdFontName, &m_macFontSize, &style );
537 if ( m_macFontSize == 0 )
538 m_macFontSize = 12;
539 m_macFontStyle = style ;
540 m_faceName = wxMacMakeStringFromPascal( qdFontName );
541 if ( m_macFontStyle & bold )
542 m_weight = wxBOLD ;
543 else
544 m_weight = wxNORMAL ;
545 if ( m_macFontStyle & italic )
546 m_style = wxITALIC ;
547 if ( m_macFontStyle & underline )
548 m_underlined = true ;
549 m_pointSize = m_macFontSize ;
550 m_macFontFamily = FMGetFontFamilyFromName( qdFontName );
551 }
552 else
553 {
554 if ( m_faceName.empty() )
555 {
556 if ( m_family == wxDEFAULT )
557 {
558 m_macFontFamily = GetAppFont();
559 FMGetFontFamilyName(m_macFontFamily,qdFontName);
560 m_faceName = wxMacMakeStringFromPascal( qdFontName );
561 }
562 else
563 {
564 switch ( m_family )
565 {
566 case wxSCRIPT :
567 case wxROMAN :
568 case wxDECORATIVE :
569 m_faceName = wxT("Times");
570 break ;
571
572 case wxSWISS :
92b6654b 573 m_faceName = wxT("Helvetica");
489468fe
SC
574 break ;
575
576 case wxMODERN :
577 case wxTELETYPE:
92b6654b 578 m_faceName = wxT("Courier");
489468fe
SC
579 break ;
580
581 default:
582 m_faceName = wxT("Times");
583 break ;
584 }
585 wxMacStringToPascal( m_faceName , qdFontName );
586 m_macFontFamily = FMGetFontFamilyFromName( qdFontName );
587 if ( m_macFontFamily == kInvalidFontFamily )
588 {
589 wxLogDebug( wxT("ATSFontFamilyFindFromName failed for %s"), m_faceName.c_str() );
590 m_macFontFamily = GetAppFont();
591 }
592 }
593 }
594 else
595 {
596 if ( m_faceName == wxT("systemfont") )
597 m_macFontFamily = GetSysFont();
598 else if ( m_faceName == wxT("applicationfont") )
599 m_macFontFamily = GetAppFont();
600 else
601 {
602 wxCFStringRef cf( m_faceName, wxLocale::GetSystemEncoding() );
603 ATSFontFamilyRef atsfamily = ATSFontFamilyFindFromName( cf , kATSOptionFlagsDefault );
604 if ( atsfamily == (ATSFontFamilyRef) -1 )
605 {
606 wxLogDebug( wxT("ATSFontFamilyFindFromName failed for ") + m_faceName );
607 m_macFontFamily = GetAppFont();
608 }
609 else
610 m_macFontFamily = FMGetFontFamilyFromATSFontFamilyRef( atsfamily );
611 }
612 }
613
614 m_macFontStyle = 0;
615 if (m_weight == wxBOLD)
616 m_macFontStyle |= bold;
617 if (m_style == wxITALIC || m_style == wxSLANT)
618 m_macFontStyle |= italic;
619 if (m_underlined)
620 m_macFontStyle |= underline;
621 m_macFontSize = m_pointSize ;
622 }
623
624 // we try to get as much styles as possible into ATSU
625
626
627 // ATSUFontID and FMFont are equivalent
628 FMFontStyle intrinsicStyle = 0 ;
629 status = FMGetFontFromFontFamilyInstance( m_macFontFamily , m_macFontStyle , &m_macATSUFontID , &intrinsicStyle);
630 wxASSERT_MSG( status == noErr , wxT("couldn't get an ATSUFont from font family") );
631 m_macATSUAdditionalQDStyles = m_macFontStyle & (~intrinsicStyle );
632
633 if ( m_macATSUStyle )
634 {
635 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
636 m_macATSUStyle = NULL ;
637 }
638
639 status = ::ATSUCreateStyle((ATSUStyle *)&m_macATSUStyle);
640 wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") );
641
642 ATSUAttributeTag atsuTags[] =
643 {
644 kATSUFontTag ,
645 kATSUSizeTag ,
646 kATSUVerticalCharacterTag,
647 kATSUQDBoldfaceTag ,
648 kATSUQDItalicTag ,
649 kATSUQDUnderlineTag ,
650 kATSUQDCondensedTag ,
651 kATSUQDExtendedTag ,
652 };
653 ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
654 {
655 sizeof( ATSUFontID ) ,
656 sizeof( Fixed ) ,
657 sizeof( ATSUVerticalCharacterType),
658 sizeof( Boolean ) ,
659 sizeof( Boolean ) ,
660 sizeof( Boolean ) ,
661 sizeof( Boolean ) ,
662 sizeof( Boolean ) ,
663 };
664
665 Boolean kTrue = true ;
666 Boolean kFalse = false ;
667
668 Fixed atsuSize = IntToFixed( m_macFontSize );
669 ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
670 ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
671 {
672 &m_macATSUFontID ,
673 &atsuSize ,
674 &kHorizontal,
675 (m_macATSUAdditionalQDStyles & bold) ? &kTrue : &kFalse ,
676 (m_macATSUAdditionalQDStyles & italic) ? &kTrue : &kFalse ,
677 (m_macATSUAdditionalQDStyles & underline) ? &kTrue : &kFalse ,
678 (m_macATSUAdditionalQDStyles & condense) ? &kTrue : &kFalse ,
679 (m_macATSUAdditionalQDStyles & extend) ? &kTrue : &kFalse ,
680 };
681
682 status = ::ATSUSetAttributes(
683 (ATSUStyle)m_macATSUStyle,
684 sizeof(atsuTags) / sizeof(ATSUAttributeTag) ,
685 atsuTags, atsuSizes, atsuValues);
686
687 wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") );
688 return;
689 }
690#endif
691}
692
693// ----------------------------------------------------------------------------
694// wxFont
695// ----------------------------------------------------------------------------
696
697bool wxFont::Create(const wxNativeFontInfo& info)
698{
699 return Create(
700 info.pointSize, info.family, info.style, info.weight,
701 info.underlined, info.faceName, info.encoding );
702}
703
704wxFont::wxFont(const wxString& fontdesc)
705{
706 wxNativeFontInfo info;
707 if ( info.FromString(fontdesc) )
708 (void)Create(info);
709}
710
711bool wxFont::Create(int pointSize,
712 int family,
713 int style,
714 int weight,
715 bool underlined,
716 const wxString& faceName,
717 wxFontEncoding encoding)
718{
719 UnRef();
720
721 m_refData = new wxFontRefData(
722 pointSize, family, style, weight,
723 underlined, faceName, encoding);
724
725 RealizeResource();
726
727 return true;
728}
729
292e5e1f 730#if wxOSX_USE_CORE_TEXT
489468fe
SC
731
732bool wxFont::MacCreateFromUIFont(wxUint32 ctFontType )
733{
734 UnRef();
735
736 m_refData = new wxFontRefData(ctFontType);
737 RealizeResource();
738
739 return true;
740}
741
742bool wxFont::MacCreateFromCTFontDescriptor( const void * ctFontDescriptor , int size )
743{
744 UnRef();
745
746 m_refData = new wxFontRefData((CTFontDescriptorRef)ctFontDescriptor, size);;
747 RealizeResource();
748
749 return true;
750}
751
752
753#endif
754
524c47aa 755#if wxOSX_USE_CARBON
489468fe
SC
756bool wxFont::MacCreateFromThemeFont(wxUint16 themeFontID)
757{
292e5e1f 758#if wxOSX_USE_CORE_TEXT
489468fe
SC
759 if ( UMAGetSystemVersion() >= 0x1050)
760 {
761 return MacCreateFromUIFont(HIThemeGetUIFontType(themeFontID));
762 }
763#endif
292e5e1f 764#if wxOSX_USE_ATSU_TEXT
489468fe
SC
765 {
766 UnRef();
767
768 m_refData = new wxFontRefData(
769 12, wxDEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
770 false, wxEmptyString, wxFONTENCODING_DEFAULT );
771
772 M_FONTDATA->m_macThemeFontID = themeFontID ;
773 RealizeResource();
774 return true;
775 }
776#endif
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{
823 return new wxFontRefData(*wx_static_cast(const wxFontRefData *, data));
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
838void wxFont::SetFamily(int family)
839{
840 Unshare();
841
842 M_FONTDATA->SetFamily( family );
843
844 RealizeResource();
845}
846
847void wxFont::SetStyle(int style)
848{
849 Unshare();
850
851 M_FONTDATA->SetStyle( style );
852
853 RealizeResource();
854}
855
856void wxFont::SetWeight(int weight)
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
922int wxFont::GetFamily() const
923{
924 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
925
926 return M_FONTDATA->GetFamily();
927}
928
929int wxFont::GetStyle() const
930{
931 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
932
933 return M_FONTDATA->GetStyle() ;
934}
935
936int wxFont::GetWeight() const
937{
938 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
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}