]> git.saurik.com Git - wxWidgets.git/blob - src/osx/carbon/font.cpp
Review/simplify/cleanup MDI classes for all platforms and introduce base
[wxWidgets.git] / src / osx / carbon / font.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/font.cpp
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
28 #include "wx/osx/private.h"
29
30 #if wxOSX_USE_ATSU_TEXT && !wxOSX_USE_CARBON
31 // include themeing support
32 #include <Carbon/Carbon.h>
33 #endif
34
35 #include <map>
36 #include <string>
37
38 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
39
40
41 class WXDLLEXPORT wxFontRefData: public wxGDIRefData
42 {
43 public:
44 wxFontRefData()
45 {
46 Init(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
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 wxFontFamily family,
58 wxFontStyle style,
59 wxFontWeight weight,
60 bool underlined,
61 const wxString& faceName,
62 wxFontEncoding encoding)
63 {
64 Init(size, family, style, weight, underlined, faceName, encoding);
65 }
66
67 #if wxOSX_USE_CORE_TEXT
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( wxFontFamily family )
88 {
89 m_family = family;
90 MacInvalidateNativeFont();
91 }
92
93
94 wxFontFamily GetFamily() const { return m_family; }
95
96 void SetStyle( wxFontStyle style )
97 {
98 m_style = style;
99 MacInvalidateNativeFont();
100 }
101
102
103 wxFontStyle GetStyle() const { return m_style; }
104
105 void SetWeight( wxFontWeight weight )
106 {
107 m_weight = weight;
108 MacInvalidateNativeFont();
109 }
110
111
112 wxFontWeight 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
142 protected:
143 // common part of all ctors
144 void Init(int size,
145 wxFontFamily family,
146 wxFontStyle style,
147 wxFontWeight weight,
148 bool underlined,
149 const wxString& faceName,
150 wxFontEncoding encoding);
151
152 #if wxOSX_USE_CORE_TEXT
153 void Init( CTFontRef font );
154 #endif
155 // font characterstics
156 int m_pointSize;
157 wxFontFamily m_family;
158 wxFontStyle m_style;
159 wxFontWeight m_weight;
160 bool m_underlined;
161 wxString m_faceName;
162 wxFontEncoding m_encoding;
163 bool m_noAA; // No anti-aliasing
164
165 public:
166 #if wxOSX_USE_ATSU_TEXT
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
184 #if wxOSX_USE_CORE_TEXT
185 wxCFRef<CTFontRef> m_ctFont;
186 #endif
187 #if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
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
204 void wxFontRefData::Init(int pointSize,
205 wxFontFamily family,
206 wxFontStyle style,
207 wxFontWeight 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;
221 #if wxOSX_USE_ATSU_TEXT
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
229 #if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
230 m_macATSUStyle = NULL ;
231 #endif
232 }
233
234 wxFontRefData::~wxFontRefData()
235 {
236 #if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
237 if ( m_macATSUStyle )
238 {
239 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
240 m_macATSUStyle = NULL ;
241 }
242 #endif
243 }
244
245 void wxFontRefData::MacInvalidateNativeFont()
246 {
247 #if wxOSX_USE_CORE_TEXT
248 m_ctFont.reset();
249 #endif
250 #if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
251 if ( m_macATSUStyle )
252 {
253 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
254 m_macATSUStyle = NULL ;
255 }
256 #endif
257 }
258
259 #if wxOSX_USE_CORE_TEXT
260
261 /* from Core Text Manual Common Operations */
262
263 static 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
315 wxFontRefData::wxFontRefData( wxUint32 coreTextFontType )
316 {
317 CTFontRef font = CTFontCreateUIFontForLanguage( coreTextFontType, 0.0, NULL ) ;
318 if ( CTFontGetSize(font) == 0 )
319 {
320 CFRelease(font);
321 font = CTFontCreateUIFontForLanguage( coreTextFontType, 12.0, NULL );
322 }
323 Init( font );
324 }
325
326 wxFontRefData::wxFontRefData( CTFontRef font )
327 {
328 Init( font );
329 }
330
331 wxFontRefData::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 {
340 size = (int)( fsize + 0.5 );
341 }
342 }
343 Init( CTFontCreateWithFontDescriptor(fontdescriptor, size,NULL) );
344 }
345
346 void wxFontRefData::Init( CTFontRef font )
347 {
348 Init(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
349 false, wxT("applicationfont"), wxFONTENCODING_DEFAULT);
350
351 m_ctFont.reset( font );
352 }
353
354 #endif
355
356 void wxFontRefData::MacFindFont()
357 {
358
359 #if wxOSX_USE_CORE_TEXT
360 if ( UMAGetSystemVersion() >= 0x1050 )
361 {
362 if ( m_faceName.empty() && m_family == wxFONTFAMILY_DEFAULT )
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 = wxFONTSTYLE_ITALIC;
375 if ( traits & kCTFontBoldTrait )
376 m_weight = wxFONTWEIGHT_BOLD ;
377 }
378 else
379 {
380 if ( m_faceName.empty() )
381 {
382 switch ( m_family )
383 {
384 case wxFONTFAMILY_SCRIPT :
385 case wxFONTFAMILY_ROMAN :
386 case wxFONTFAMILY_DECORATIVE :
387 m_faceName = wxT("Times");
388 break ;
389
390 case wxFONTFAMILY_SWISS :
391 m_faceName = wxT("Helvetica");
392 break ;
393
394 case wxFONTFAMILY_MODERN :
395 case wxFONTFAMILY_TELETYPE:
396 m_faceName = wxT("Courier");
397 if ( m_style == wxFONTSTYLE_ITALIC && m_weight == wxFONTWEIGHT_NORMAL )
398 {
399 m_style = wxFONTSTYLE_ITALIC;
400 }
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 == wxFONTWEIGHT_BOLD)
413 traits |= kCTFontBoldTrait;
414 if (m_style == wxFONTSTYLE_ITALIC || m_style == wxFONTSTYLE_SLANT)
415 traits |= kCTFontItalicTrait;
416
417 // use font caching
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 {
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 == wxFONTWEIGHT_BOLD)
429 qdstyle |= bold;
430 if (m_style == wxFONTSTYLE_ITALIC || m_style == wxFONTSTYLE_SLANT)
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
458 fontcache[ std::wstring(lookupnameWithSize.wc_str()) ] = m_ctFont;
459 #if 1 // debugging coretext font matching
460 CTFontSymbolicTraits received = CTFontGetSymbolicTraits( m_ctFont ) & 0x03;
461 if ( received != traits )
462 {
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 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() );
472 }
473 CFShow( dict );
474 CFRelease( dict );
475 }
476 #endif
477 }
478
479 }
480 #if wxOSX_USE_ATSU_TEXT
481 OSStatus status = noErr;
482 ATSFontRef atsfont = CTFontGetPlatformFont( m_ctFont, NULL );
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,
512 (m_weight == wxFONTWEIGHT_BOLD) ? &kTrue : &kFalse ,
513 (m_style == wxFONTSTYLE_ITALIC || m_style == wxFONTSTYLE_SLANT) ? &kTrue : &kFalse ,
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
531 #if wxOSX_USE_ATSU_TEXT
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 )
544 m_weight = wxFONTWEIGHT_BOLD ;
545 else
546 m_weight = wxFONTWEIGHT_NORMAL ;
547 if ( m_macFontStyle & italic )
548 m_style = wxFONTSTYLE_ITALIC ;
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 {
558 if ( m_family == wxFONTFAMILY_DEFAULT )
559 {
560 m_macFontFamily = GetAppFont();
561 FMGetFontFamilyName(m_macFontFamily,qdFontName);
562 m_faceName = wxMacMakeStringFromPascal( qdFontName );
563 }
564 else
565 {
566 switch ( m_family )
567 {
568 case wxFONTFAMILY_SCRIPT :
569 case wxFONTFAMILY_ROMAN :
570 case wxFONTFAMILY_DECORATIVE :
571 m_faceName = wxT("Times");
572 break ;
573
574 case wxFONTFAMILY_SWISS :
575 m_faceName = wxT("Helvetica");
576 break ;
577
578 case wxFONTFAMILY_MODERN :
579 case wxFONTFAMILY_TELETYPE:
580 m_faceName = wxT("Courier");
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;
617 if (m_weight == wxFONTWEIGHT_BOLD)
618 m_macFontStyle |= bold;
619 if (m_style == wxFONTSTYLE_ITALIC || m_style == wxFONTSTYLE_SLANT)
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
699 bool 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
706 wxFont::wxFont(const wxString& fontdesc)
707 {
708 wxNativeFontInfo info;
709 if ( info.FromString(fontdesc) )
710 (void)Create(info);
711 }
712
713 bool wxFont::Create(int pointSize,
714 wxFontFamily family,
715 wxFontStyle style,
716 wxFontWeight weight,
717 bool underlined,
718 const wxString& faceName,
719 wxFontEncoding encoding)
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
732 #if wxOSX_USE_CORE_TEXT
733
734 bool wxFont::MacCreateFromUIFont(wxUint32 ctFontType )
735 {
736 UnRef();
737
738 m_refData = new wxFontRefData(ctFontType);
739 RealizeResource();
740
741 return true;
742 }
743
744 bool 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
757 #if wxOSX_USE_CARBON
758 bool wxFont::MacCreateFromThemeFont(wxUint16 themeFontID)
759 {
760 #if wxOSX_USE_CORE_TEXT
761 if ( UMAGetSystemVersion() >= 0x1050)
762 {
763 return MacCreateFromUIFont(HIThemeGetUIFontType(themeFontID));
764 }
765 #endif
766 #if wxOSX_USE_ATSU_TEXT
767 {
768 UnRef();
769
770 m_refData = new wxFontRefData(
771 12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
772 false, wxEmptyString, wxFONTENCODING_DEFAULT );
773
774 M_FONTDATA->m_macThemeFontID = themeFontID ;
775 RealizeResource();
776 return true;
777 }
778 #endif
779 return false;
780 }
781 #endif
782
783 wxFont::~wxFont()
784 {
785 }
786
787 bool wxFont::RealizeResource()
788 {
789 M_FONTDATA->MacFindFont();
790
791 return true;
792 }
793
794 void wxFont::SetEncoding(wxFontEncoding encoding)
795 {
796 Unshare();
797
798 M_FONTDATA->SetEncoding( encoding );
799
800 RealizeResource();
801 }
802
803 void 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
818 wxGDIRefData *wxFont::CreateGDIRefData() const
819 {
820 return new wxFontRefData;
821 }
822
823 wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
824 {
825 return new wxFontRefData(*static_cast<const wxFontRefData *>(data));
826 }
827
828 void 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
840 void wxFont::SetFamily(wxFontFamily family)
841 {
842 Unshare();
843
844 M_FONTDATA->SetFamily( family );
845
846 RealizeResource();
847 }
848
849 void wxFont::SetStyle(wxFontStyle style)
850 {
851 Unshare();
852
853 M_FONTDATA->SetStyle( style );
854
855 RealizeResource();
856 }
857
858 void wxFont::SetWeight(wxFontWeight weight)
859 {
860 Unshare();
861
862 M_FONTDATA->SetWeight( weight );
863
864 RealizeResource();
865 }
866
867 bool 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
878 void wxFont::SetUnderlined(bool underlined)
879 {
880 Unshare();
881
882 M_FONTDATA->SetUnderlined( underlined );
883
884 RealizeResource();
885 }
886
887 void 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
902 int wxFont::GetPointSize() const
903 {
904 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
905
906 return M_FONTDATA->GetPointSize();
907 }
908
909 wxSize 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
924 wxFontFamily wxFont::GetFamily() const
925 {
926 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTFAMILY_MAX, wxT("invalid font") );
927
928 return M_FONTDATA->GetFamily();
929 }
930
931 wxFontStyle wxFont::GetStyle() const
932 {
933 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTSTYLE_MAX, wxT("invalid font") );
934
935 return M_FONTDATA->GetStyle() ;
936 }
937
938 wxFontWeight wxFont::GetWeight() const
939 {
940 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTWEIGHT_MAX, wxT("invalid font") );
941
942 return M_FONTDATA->GetWeight();
943 }
944
945 bool wxFont::GetUnderlined() const
946 {
947 wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
948
949 return M_FONTDATA->GetUnderlined();
950 }
951
952 wxString wxFont::GetFaceName() const
953 {
954 wxCHECK_MSG( M_FONTDATA != NULL , wxEmptyString , wxT("invalid font") );
955
956 return M_FONTDATA->GetFaceName() ;
957 }
958
959 wxFontEncoding wxFont::GetEncoding() const
960 {
961 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTENCODING_DEFAULT , wxT("invalid font") );
962
963 return M_FONTDATA->GetEncoding() ;
964 }
965
966 bool wxFont::GetNoAntiAliasing() const
967 {
968 wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
969
970 return M_FONTDATA->GetNoAntiAliasing();
971 }
972
973 #if wxOSX_USE_ATSU_TEXT
974
975 short wxFont::MacGetFontNum() const
976 {
977 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
978
979 return M_FONTDATA->m_macFontFamily;
980 }
981
982 short wxFont::MacGetFontSize() const
983 {
984 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
985
986 return M_FONTDATA->m_macFontSize;
987 }
988
989 wxByte wxFont::MacGetFontStyle() const
990 {
991 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
992
993 return M_FONTDATA->m_macFontStyle;
994 }
995
996 wxUint32 wxFont::MacGetATSUFontID() const
997 {
998 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
999
1000 return M_FONTDATA->m_macATSUFontID;
1001 }
1002
1003 wxUint32 wxFont::MacGetATSUAdditionalQDStyles() const
1004 {
1005 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
1006
1007 return M_FONTDATA->m_macATSUAdditionalQDStyles;
1008 }
1009
1010 wxUint16 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
1018 #if wxOSX_USE_CORE_TEXT || wxOSX_USE_ATSU_TEXT
1019 void * 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
1027 #if wxOSX_USE_CORE_TEXT
1028
1029 const 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
1036 #endif
1037
1038 const 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 }