]> git.saurik.com Git - wxWidgets.git/blob - src/osx/carbon/font.cpp
360a7fa9aa3907e28ea3fcad89e31fdd7ae5e885
[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 #include "wx/tokenzr.h"
28
29 #include "wx/osx/private.h"
30
31 #include <map>
32 #include <string>
33
34 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
35
36 class WXDLLEXPORT wxFontRefData: public wxGDIRefData
37 {
38 public:
39
40 wxFontRefData()
41 {
42 Init();
43 m_info.Init(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
44 false, wxEmptyString, wxFONTENCODING_DEFAULT);
45 }
46
47 wxFontRefData(const wxFontRefData& data);
48
49 wxFontRefData( const wxNativeFontInfo& info ) : m_info(info)
50 {
51 Init();
52 }
53
54 wxFontRefData(wxOSXSystemFont font, int size);
55
56 #if wxOSX_USE_CORE_TEXT
57 wxFontRefData( wxUint32 coreTextFontType );
58 wxFontRefData( CTFontRef font );
59 wxFontRefData( CTFontDescriptorRef fontdescriptor, int size );
60 #endif
61
62 virtual ~wxFontRefData();
63
64 void SetPointSize( int size )
65 {
66 if( GetPointSize() != size )
67 {
68 m_info.SetPointSize(size);
69 Free();
70 }
71 }
72
73 int GetPointSize() const { return m_info.GetPointSize(); }
74
75 void SetFamily( wxFontFamily family )
76 {
77 if ( m_info.m_family != family )
78 {
79 m_info.SetFamily( family );
80 Free();
81 }
82 }
83
84 wxFontFamily GetFamily() const { return m_info.GetFamily(); }
85
86 void SetStyle( wxFontStyle style )
87 {
88 if ( m_info.m_style != style )
89 {
90 m_info.SetStyle( style );
91 Free();
92 }
93 }
94
95
96 wxFontStyle GetStyle() const { return m_info.GetStyle(); }
97
98 void SetWeight( wxFontWeight weight )
99 {
100 if ( m_info.m_weight != weight )
101 {
102 m_info.SetWeight( weight );
103 Free();
104 }
105 }
106
107
108 wxFontWeight GetWeight() const { return m_info.GetWeight(); }
109
110 void SetUnderlined( bool u )
111 {
112 if ( m_info.m_underlined != u )
113 {
114 m_info.SetUnderlined( u );
115 Free();
116 }
117 }
118
119 bool GetUnderlined() const { return m_info.GetUnderlined(); }
120
121 void SetFaceName( const wxString& facename )
122 {
123 if ( m_info.m_faceName != facename )
124 {
125 m_info.SetFaceName( facename );
126 Free();
127 }
128 }
129
130 wxString GetFaceName() const { return m_info.GetFaceName(); }
131
132 void SetEncoding( wxFontEncoding encoding )
133 {
134 if ( m_info.m_encoding != encoding )
135 {
136 m_info.SetEncoding( encoding );
137 Free();
138 }
139 }
140
141 wxFontEncoding GetEncoding() const { return m_info.GetEncoding(); }
142
143 void Free();
144
145 void MacFindFont();
146
147 protected:
148 // common part of all ctors
149 void Init();
150 #if wxOSX_USE_CORE_TEXT
151 // void Init( CTFontRef font );
152 #endif
153 public:
154 bool m_fontValid;
155 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
156 // for true theming support we must store the correct font
157 // information here, as this speeds up and optimizes rendering
158 ThemeFontID m_macThemeFontID ;
159 #endif
160 #if wxOSX_USE_CORE_TEXT
161 wxCFRef<CTFontRef> m_ctFont;
162 #endif
163 #if wxOSX_USE_ATSU_TEXT
164 void CreateATSUFont();
165
166 ATSUStyle m_macATSUStyle ;
167 #endif
168 wxCFRef<CGFontRef> m_cgFont;
169 #if wxOSX_USE_COCOA
170 WX_NSFont m_nsFont;
171 #endif
172 #if wxOSX_USE_IPHONE
173 WX_UIFont m_uiFont;
174 #endif
175 wxNativeFontInfo m_info;
176 };
177
178 #define M_FONTDATA ((wxFontRefData*)m_refData)
179
180 wxFontRefData::wxFontRefData(const wxFontRefData& data)
181 {
182 Init();
183 m_info = data.m_info;
184 m_fontValid = data.m_fontValid;
185 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
186 m_macThemeFontID = data.m_macThemeFontID;
187 #endif
188 #if wxOSX_USE_CORE_TEXT
189 m_ctFont = data.m_ctFont;
190 #endif
191 m_cgFont = data.m_cgFont;
192 #if wxOSX_USE_ATSU_TEXT
193 if ( data.m_macATSUStyle != NULL )
194 {
195 ATSUCreateStyle(&m_macATSUStyle) ;
196 ATSUCopyAttributes(data.m_macATSUStyle, m_macATSUStyle);
197 }
198 #endif
199 #if wxOSX_USE_COCOA
200 m_nsFont = (NSFont*) wxMacCocoaRetain(data.m_nsFont);
201 #endif
202 #if wxOSX_USE_IPHONE
203 m_uiFont = (UIFont*) wxMacCocoaRetain(data.m_uiFont);
204 #endif
205
206 }
207
208 // ============================================================================
209 // implementation
210 // ============================================================================
211
212 // ----------------------------------------------------------------------------
213 // wxFontRefData
214 // ----------------------------------------------------------------------------
215
216 void wxFontRefData::Init()
217 {
218 #if wxOSX_USE_CARBON && wxOSX_USE_ATSU_TEXT
219 m_macThemeFontID = kThemeCurrentPortFont ;
220 #endif
221 #if wxOSX_USE_ATSU_TEXT
222 m_macATSUStyle = NULL ;
223 #endif
224 #if wxOSX_USE_COCOA
225 m_nsFont = NULL;
226 #endif
227 #if wxOSX_USE_IPHONE
228 m_uiFont = NULL;
229 #endif
230 m_fontValid = false;
231 }
232
233 wxFontRefData::~wxFontRefData()
234 {
235 Free();
236 }
237
238 void wxFontRefData::Free()
239 {
240 #if wxOSX_USE_CORE_TEXT
241 m_ctFont.reset();
242 #endif
243 m_cgFont.reset();
244 #if wxOSX_USE_ATSU_TEXT
245 #if wxOSX_USE_CARBON
246 m_macThemeFontID = kThemeCurrentPortFont ;
247 #endif
248 if ( m_macATSUStyle )
249 {
250 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
251 m_macATSUStyle = NULL ;
252 }
253 #endif
254 #if wxOSX_USE_COCOA
255 if (m_nsFont != NULL)
256 {
257 wxMacCocoaRelease(m_nsFont);
258 m_nsFont = NULL;
259 }
260 #endif
261 #if wxOSX_USE_IPHONE
262 if (m_uiFont != NULL)
263 {
264 wxMacCocoaRelease(m_uiFont);
265 m_uiFont = NULL;
266 }
267 #endif
268 m_fontValid = false;
269 }
270
271 wxFontRefData::wxFontRefData(wxOSXSystemFont font, int size)
272 {
273 wxASSERT( font != wxOSX_SYSTEM_FONT_NONE );
274 Init();
275
276 #if wxOSX_USE_CORE_TEXT
277 if ( UMAGetSystemVersion() >= 0x1050 )
278 {
279 CTFontUIFontType uifont = kCTFontSystemFontType;
280 switch( font )
281 {
282 case wxOSX_SYSTEM_FONT_NORMAL:
283 uifont = kCTFontSystemFontType;
284 break;
285 case wxOSX_SYSTEM_FONT_BOLD:
286 uifont = kCTFontEmphasizedSystemFontType;
287 break;
288 case wxOSX_SYSTEM_FONT_SMALL:
289 uifont = kCTFontSmallSystemFontType;
290 break;
291 case wxOSX_SYSTEM_FONT_SMALL_BOLD:
292 uifont = kCTFontSmallEmphasizedSystemFontType;
293 break;
294 case wxOSX_SYSTEM_FONT_MINI:
295 uifont = kCTFontMiniSystemFontType;
296 break;
297 case wxOSX_SYSTEM_FONT_MINI_BOLD:
298 uifont = kCTFontMiniEmphasizedSystemFontType;
299 break;
300 case wxOSX_SYSTEM_FONT_LABELS:
301 uifont = kCTFontLabelFontType;
302 break;
303 case wxOSX_SYSTEM_FONT_VIEWS:
304 uifont = kCTFontViewsFontType;
305 break;
306 default:
307 break;
308 }
309 m_ctFont.reset(CTFontCreateUIFontForLanguage( uifont, (CGFloat) size, NULL ));
310 wxCFRef<CTFontDescriptorRef> descr;
311 descr.reset( CTFontCopyFontDescriptor( m_ctFont ) );
312 m_info.Init(descr);
313 }
314 #endif
315 #if wxOSX_USE_ATSU_TEXT
316 {
317 #if !wxOSX_USE_CARBON
318 // not needed outside
319 ThemeFontID m_macThemeFontID = kThemeSystemFont;
320 #endif
321 switch( font )
322 {
323 case wxOSX_SYSTEM_FONT_NORMAL:
324 m_macThemeFontID = kThemeSystemFont;
325 break;
326 case wxOSX_SYSTEM_FONT_BOLD:
327 m_macThemeFontID = kThemeEmphasizedSystemFont;
328 break;
329 case wxOSX_SYSTEM_FONT_SMALL:
330 m_macThemeFontID = kThemeSmallSystemFont;
331 break;
332 case wxOSX_SYSTEM_FONT_SMALL_BOLD:
333 m_macThemeFontID = kThemeSmallEmphasizedSystemFont;
334 break;
335 case wxOSX_SYSTEM_FONT_MINI:
336 m_macThemeFontID = kThemeMiniSystemFont;
337 break;
338 case wxOSX_SYSTEM_FONT_MINI_BOLD:
339 // bold not available under theming
340 m_macThemeFontID = kThemeMiniSystemFont;
341 break;
342 case wxOSX_SYSTEM_FONT_LABELS:
343 m_macThemeFontID = kThemeLabelFont;
344 break;
345 case wxOSX_SYSTEM_FONT_VIEWS:
346 m_macThemeFontID = kThemeViewsFont;
347 break;
348 default:
349 break;
350 }
351 if ( m_info.m_faceName.empty() )
352 {
353 Style style ;
354 FMFontSize fontSize;
355 Str255 qdFontName ;
356
357 GetThemeFont( m_macThemeFontID, GetApplicationScript(), qdFontName, &fontSize, &style );
358 if ( size != 0 )
359 fontSize = size;
360
361 wxFontStyle fontstyle = wxFONTSTYLE_NORMAL;
362 wxFontWeight fontweight = wxFONTWEIGHT_NORMAL;
363 bool underlined = false;
364
365 if ( style & bold )
366 fontweight = wxFONTWEIGHT_BOLD ;
367 else
368 fontweight = wxFONTWEIGHT_NORMAL ;
369 if ( style & italic )
370 fontstyle = wxFONTSTYLE_ITALIC ;
371 if ( style & underline )
372 underlined = true ;
373
374 m_info.Init(fontSize,wxFONTFAMILY_DEFAULT,fontstyle,fontweight,underlined,
375 wxMacMakeStringFromPascal( qdFontName ), wxFONTENCODING_DEFAULT);
376 }
377 }
378 #endif
379 #if wxOSX_USE_COCOA
380 m_nsFont = wxFont::OSXCreateNSFont( font, &m_info );
381 #endif
382 #if wxOSX_USE_IPHONE
383 m_uiFont = wxFont::OSXCreateUIFont( font, &m_info );
384 #endif
385 m_info.EnsureValid();
386 #if wxOSX_USE_ATSU_TEXT
387 CreateATSUFont();
388 #endif
389
390 m_fontValid = true;
391 }
392
393 #if wxOSX_USE_ATSU_TEXT
394 void wxFontRefData::CreateATSUFont()
395 {
396 // we try to get as much styles as possible into ATSU
397
398 OSStatus status = ::ATSUCreateStyle(&m_macATSUStyle);
399 wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") );
400
401 ATSUAttributeTag atsuTags[] =
402 {
403 kATSUFontTag ,
404 kATSUSizeTag ,
405 kATSUVerticalCharacterTag,
406 kATSUQDBoldfaceTag ,
407 kATSUQDItalicTag ,
408 kATSUQDUnderlineTag ,
409 kATSUQDCondensedTag ,
410 kATSUQDExtendedTag ,
411 };
412 ByteCount atsuSizes[WXSIZEOF(atsuTags)] =
413 {
414 sizeof( ATSUFontID ) ,
415 sizeof( Fixed ) ,
416 sizeof( ATSUVerticalCharacterType),
417 sizeof( Boolean ) ,
418 sizeof( Boolean ) ,
419 sizeof( Boolean ) ,
420 sizeof( Boolean ) ,
421 sizeof( Boolean ) ,
422 };
423
424 Boolean kTrue = true ;
425 Boolean kFalse = false ;
426
427 Fixed atsuSize = IntToFixed( m_info.m_pointSize );
428 ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
429 FMFontStyle addQDStyle = m_info.m_atsuAdditionalQDStyles;
430 ATSUAttributeValuePtr atsuValues[WXSIZEOF(atsuTags)] =
431 {
432 &m_info.m_atsuFontID ,
433 &atsuSize ,
434 &kHorizontal,
435 (addQDStyle & bold) ? &kTrue : &kFalse ,
436 (addQDStyle & italic) ? &kTrue : &kFalse ,
437 (addQDStyle & underline) ? &kTrue : &kFalse ,
438 (addQDStyle & condense) ? &kTrue : &kFalse ,
439 (addQDStyle & extend) ? &kTrue : &kFalse ,
440 };
441
442 status = ::ATSUSetAttributes(
443 (ATSUStyle)m_macATSUStyle,
444 WXSIZEOF(atsuTags),
445 atsuTags, atsuSizes, atsuValues);
446
447 wxASSERT_MSG( status == noErr , wxString::Format(wxT("couldn't modify ATSU style. Status was %d"), (int) status).c_str() );
448
449 if ( m_cgFont.get() == NULL )
450 {
451 ATSFontRef fontRef = FMGetATSFontRefFromFont(m_info.m_atsuFontID);
452 m_cgFont.reset( CGFontCreateWithPlatformFont( &fontRef ) );
453 }
454 }
455 #endif
456
457 static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }
458 static const CGAffineTransform kSlantTransform = CGAffineTransformMake( 1, 0, tan(DegToRad(11)), 1, 0, 0 );
459
460 void wxFontRefData::MacFindFont()
461 {
462 if ( m_fontValid )
463 return;
464
465 wxCHECK_RET( m_info.m_pointSize > 0, wxT("Point size should not be zero.") );
466
467 m_info.EnsureValid();
468
469 #if wxOSX_USE_CORE_TEXT
470 if ( UMAGetSystemVersion() >= 0x1050 )
471 {
472 CTFontSymbolicTraits traits = 0;
473
474 if (m_info.m_weight == wxFONTWEIGHT_BOLD)
475 traits |= kCTFontBoldTrait;
476 if (m_info.m_style == wxFONTSTYLE_ITALIC || m_info.m_style == wxFONTSTYLE_SLANT)
477 traits |= kCTFontItalicTrait;
478
479 // use font caching
480 wxString lookupnameWithSize = wxString::Format( "%s_%u_%d", m_info.m_faceName, traits, m_info.m_pointSize );
481
482 static std::map< std::wstring , wxCFRef< CTFontRef > > fontcache ;
483 m_ctFont = fontcache[ std::wstring(lookupnameWithSize.wc_str()) ];
484 if ( !m_ctFont )
485 {
486 m_ctFont.reset(CTFontCreateWithName( wxCFStringRef(m_info.m_faceName), m_info.m_pointSize , NULL ));
487 if ( m_ctFont.get() == NULL )
488 {
489 // TODO try fallbacks according to font type
490 m_ctFont.reset(CTFontCreateUIFontForLanguage( kCTFontSystemFontType, m_info.m_pointSize , NULL ));
491 }
492 else
493 {
494 if ( traits != 0 )
495 {
496 // attempt native font variant, if not available, fallback to italic emulation mode and remove bold
497 CTFontRef fontWithTraits = CTFontCreateCopyWithSymbolicTraits( m_ctFont, 0, NULL, traits, traits );
498 if ( fontWithTraits == NULL )
499 {
500 CTFontSymbolicTraits remainingTraits = traits;
501 const CGAffineTransform* remainingTransform = NULL;
502
503 if( remainingTraits & kCTFontItalicTrait )
504 {
505 remainingTraits &= ~kCTFontItalicTrait;
506 remainingTransform = &kSlantTransform;
507 if ( remainingTraits & kCTFontBoldTrait )
508 {
509 // first try an emulated oblique with an existing bold font
510 fontWithTraits = CTFontCreateCopyWithSymbolicTraits( m_ctFont, 0, remainingTransform, remainingTraits, remainingTraits );
511 if ( fontWithTraits == NULL )
512 {
513 // give in on the bold, try native oblique
514 fontWithTraits = CTFontCreateCopyWithSymbolicTraits( m_ctFont, 0, NULL, kCTFontItalicTrait, kCTFontItalicTrait );
515 }
516 }
517 }
518
519 if ( fontWithTraits == NULL )
520 {
521 fontWithTraits = CTFontCreateWithName( wxCFStringRef(m_info.m_faceName), m_info.m_pointSize, remainingTransform );
522 }
523
524 }
525 if ( fontWithTraits != NULL )
526 m_ctFont.reset(fontWithTraits);
527 }
528 }
529 }
530
531 m_cgFont.reset(CTFontCopyGraphicsFont(m_ctFont, NULL));
532 }
533
534 #endif
535 #if wxOSX_USE_ATSU_TEXT
536 CreateATSUFont();
537 #endif
538 #if wxOSX_USE_COCOA
539 m_nsFont = wxFont::OSXCreateNSFont( &m_info );
540 #endif
541 #if wxOSX_USE_IPHONE
542 m_uiFont = wxFont::OSXCreateUIFont( &m_info );
543 #endif
544 m_fontValid = true;
545 }
546
547 // ----------------------------------------------------------------------------
548 // wxFont
549 // ----------------------------------------------------------------------------
550
551 bool wxFont::Create(const wxNativeFontInfo& info)
552 {
553 UnRef();
554
555 m_refData = new wxFontRefData( info );
556 RealizeResource();
557
558 return true;
559 }
560
561 wxFont::wxFont(wxOSXSystemFont font)
562 {
563 m_refData = new wxFontRefData( font, 0 );
564 }
565
566 wxFont::wxFont(const wxString& fontdesc)
567 {
568 wxNativeFontInfo info;
569 if ( info.FromString(fontdesc) )
570 (void)Create(info);
571 }
572
573 bool wxFont::Create(int pointSize,
574 wxFontFamily family,
575 wxFontStyle style,
576 wxFontWeight weight,
577 bool underlined,
578 const wxString& faceNameParam,
579 wxFontEncoding encoding)
580 {
581 UnRef();
582
583 wxString faceName = faceNameParam;
584
585 if ( faceName.empty() )
586 {
587 switch ( family )
588 {
589 case wxFONTFAMILY_DEFAULT :
590 faceName = wxT("Lucida Grande");
591 break;
592
593 case wxFONTFAMILY_SCRIPT :
594 case wxFONTFAMILY_ROMAN :
595 case wxFONTFAMILY_DECORATIVE :
596 faceName = wxT("Times");
597 break ;
598
599 case wxFONTFAMILY_SWISS :
600 faceName = wxT("Helvetica");
601 break ;
602
603 case wxFONTFAMILY_MODERN :
604 case wxFONTFAMILY_TELETYPE:
605 faceName = wxT("Courier");
606 break ;
607
608 default:
609 faceName = wxT("Times");
610 break ;
611 }
612 }
613
614 wxNativeFontInfo info;
615
616 info.Init(pointSize, family, style, weight,
617 underlined, faceName, encoding);
618
619 m_refData = new wxFontRefData(info);
620
621 return true;
622 }
623
624 wxFont::~wxFont()
625 {
626 }
627
628 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info)
629 {
630 UnRef();
631
632 m_refData = new wxFontRefData( info);
633 }
634
635
636 bool wxFont::RealizeResource()
637 {
638 M_FONTDATA->MacFindFont();
639
640 return true;
641 }
642
643 void wxFont::SetEncoding(wxFontEncoding encoding)
644 {
645 AllocExclusive();
646
647 M_FONTDATA->SetEncoding( encoding );
648 }
649
650 wxGDIRefData *wxFont::CreateGDIRefData() const
651 {
652 return new wxFontRefData;
653 }
654
655 wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
656 {
657 return new wxFontRefData(*static_cast<const wxFontRefData *>(data));
658 }
659
660 void wxFont::SetPointSize(int pointSize)
661 {
662 if ( M_FONTDATA->GetPointSize() == pointSize )
663 return;
664
665 AllocExclusive();
666
667 M_FONTDATA->SetPointSize( pointSize );
668 }
669
670 void wxFont::SetFamily(wxFontFamily family)
671 {
672 AllocExclusive();
673
674 M_FONTDATA->SetFamily( family );
675 }
676
677 void wxFont::SetStyle(wxFontStyle style)
678 {
679 AllocExclusive();
680
681 M_FONTDATA->SetStyle( style );
682 }
683
684 void wxFont::SetWeight(wxFontWeight weight)
685 {
686 AllocExclusive();
687
688 M_FONTDATA->SetWeight( weight );
689 }
690
691 bool wxFont::SetFaceName(const wxString& faceName)
692 {
693 AllocExclusive();
694
695 M_FONTDATA->SetFaceName( faceName );
696
697 return wxFontBase::SetFaceName(faceName);
698 }
699
700 void wxFont::SetUnderlined(bool underlined)
701 {
702 AllocExclusive();
703
704 M_FONTDATA->SetUnderlined( underlined );
705 }
706
707 // ----------------------------------------------------------------------------
708 // accessors
709 // ----------------------------------------------------------------------------
710
711 // TODO: insert checks everywhere for M_FONTDATA == NULL!
712
713 int wxFont::GetPointSize() const
714 {
715 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
716
717 return M_FONTDATA->GetPointSize();
718 }
719
720 wxSize wxFont::GetPixelSize() const
721 {
722 #if wxUSE_GRAPHICS_CONTEXT
723 // TODO: consider caching the value
724 wxGraphicsContext* dc = wxGraphicsContext::CreateFromNative((CGContextRef) NULL);
725 dc->SetFont(*(wxFont *)this,*wxBLACK);
726 wxDouble width, height = 0;
727 dc->GetTextExtent( wxT("g"), &width, &height, NULL, NULL);
728 delete dc;
729 return wxSize((int)width, (int)height);
730 #else
731 return wxFontBase::GetPixelSize();
732 #endif
733 }
734
735 wxFontFamily wxFont::DoGetFamily() const
736 {
737 return M_FONTDATA->GetFamily();
738 }
739
740 wxFontStyle wxFont::GetStyle() const
741 {
742 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTSTYLE_MAX, wxT("invalid font") );
743
744 return M_FONTDATA->GetStyle() ;
745 }
746
747 wxFontWeight wxFont::GetWeight() const
748 {
749 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTWEIGHT_MAX, wxT("invalid font") );
750
751 return M_FONTDATA->GetWeight();
752 }
753
754 bool wxFont::GetUnderlined() const
755 {
756 wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
757
758 return M_FONTDATA->GetUnderlined();
759 }
760
761 wxString wxFont::GetFaceName() const
762 {
763 wxCHECK_MSG( M_FONTDATA != NULL , wxEmptyString , wxT("invalid font") );
764
765 return M_FONTDATA->GetFaceName() ;
766 }
767
768 wxFontEncoding wxFont::GetEncoding() const
769 {
770 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTENCODING_DEFAULT , wxT("invalid font") );
771
772 return M_FONTDATA->GetEncoding() ;
773 }
774
775 #if wxOSX_USE_ATSU_TEXT && wxOSX_USE_CARBON
776
777 short wxFont::MacGetFontNum() const
778 {
779 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
780
781 // cast away constness otherwise lazy font resolution is not possible
782 const_cast<wxFont *>(this)->RealizeResource();
783
784 return M_FONTDATA->m_info.m_qdFontFamily;
785 }
786
787 wxByte wxFont::MacGetFontStyle() const
788 {
789 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
790
791 // cast away constness otherwise lazy font resolution is not possible
792 const_cast<wxFont *>(this)->RealizeResource();
793
794 return M_FONTDATA->m_info.m_qdFontStyle;
795 }
796
797 wxUint16 wxFont::MacGetThemeFontID() const
798 {
799 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
800
801 return M_FONTDATA->m_macThemeFontID;
802 }
803
804 #endif
805
806 #if wxOSX_USE_ATSU_TEXT
807 void * wxFont::MacGetATSUStyle() const
808 {
809 wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
810
811 // cast away constness otherwise lazy font resolution is not possible
812 const_cast<wxFont *>(this)->RealizeResource();
813
814 return M_FONTDATA->m_macATSUStyle;
815 }
816
817 #if WXWIN_COMPATIBILITY_2_8
818 wxUint32 wxFont::MacGetATSUFontID() const
819 {
820 wxCHECK_MSG( M_FONTDATA != NULL, 0, wxT("invalid font") );
821
822 // cast away constness otherwise lazy font resolution is not possible
823 const_cast<wxFont *>(this)->RealizeResource();
824
825 return M_FONTDATA->m_info.m_atsuFontID;
826 }
827
828 wxUint32 wxFont::MacGetATSUAdditionalQDStyles() const
829 {
830 wxCHECK_MSG( M_FONTDATA != NULL, 0, wxT("invalid font") );
831
832 // cast away constness otherwise lazy font resolution is not possible
833 const_cast<wxFont *>(this)->RealizeResource();
834
835 return M_FONTDATA->m_info.m_atsuAdditionalQDStyles;
836 }
837 #endif
838
839 #endif
840
841 #if wxOSX_USE_CORE_TEXT
842
843 CTFontRef wxFont::OSXGetCTFont() const
844 {
845 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
846
847 // cast away constness otherwise lazy font resolution is not possible
848 const_cast<wxFont *>(this)->RealizeResource();
849
850 return (CTFontRef)(M_FONTDATA->m_ctFont);
851 }
852
853 #endif
854
855 #if wxOSX_USE_COCOA_OR_CARBON
856
857 CGFontRef wxFont::OSXGetCGFont() const
858 {
859 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
860
861 // cast away constness otherwise lazy font resolution is not possible
862 const_cast<wxFont *>(this)->RealizeResource();
863
864 return (M_FONTDATA->m_cgFont);
865 }
866
867 #endif
868
869
870 #if wxOSX_USE_COCOA
871
872 NSFont* wxFont::OSXGetNSFont() const
873 {
874 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
875
876 // cast away constness otherwise lazy font resolution is not possible
877 const_cast<wxFont *>(this)->RealizeResource();
878
879 return (M_FONTDATA->m_nsFont);
880 }
881
882 #endif
883
884 #if wxOSX_USE_IPHONE
885
886 UIFont* wxFont::OSXGetUIFont() const
887 {
888 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
889
890 // cast away constness otherwise lazy font resolution is not possible
891 const_cast<wxFont *>(this)->RealizeResource();
892
893 return (M_FONTDATA->m_uiFont);
894 }
895
896 #endif
897
898 const wxNativeFontInfo * wxFont::GetNativeFontInfo() const
899 {
900 wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
901 wxCHECK_MSG( Ok(), NULL, wxT("invalid font") );
902
903 // cast away constness otherwise lazy font resolution is not possible
904 const_cast<wxFont *>(this)->RealizeResource();
905
906 // M_FONTDATA->m_info.InitFromFont(*this);
907
908 return &(M_FONTDATA->m_info);
909 }
910
911 // ----------------------------------------------------------------------------
912 // wxNativeFontInfo
913 // ----------------------------------------------------------------------------
914
915 #if 0 // wxOSX_USE_CORE_TEXT
916
917 /* from Core Text Manual Common Operations */
918
919 static CTFontDescriptorRef wxMacCreateCTFontDescriptor(CFStringRef iFamilyName, CTFontSymbolicTraits iTraits )
920 {
921 CTFontDescriptorRef descriptor = NULL;
922 CFMutableDictionaryRef attributes;
923
924 wxASSERT(iFamilyName != NULL);
925 // Create a mutable dictionary to hold our attributes.
926 attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
927 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
928 wxASSERT(attributes != NULL);
929
930 if (attributes != NULL) {
931 // Add a family name to our attributes.
932 CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, iFamilyName);
933
934
935 if ( iTraits ) {
936 CFMutableDictionaryRef traits;
937 CFNumberRef symTraits;
938
939 // Create the traits dictionary.
940 symTraits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type,
941 &iTraits);
942 wxASSERT(symTraits != NULL);
943
944 if (symTraits != NULL) {
945 // Create a dictionary to hold our traits values.
946 traits = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
947 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
948 wxASSERT(traits != NULL);
949
950 if (traits != NULL) {
951 // Add the symbolic traits value to the traits dictionary.
952 CFDictionaryAddValue(traits, kCTFontSymbolicTrait, symTraits);
953
954 // Add the traits attribute to our attributes.
955 CFDictionaryAddValue(attributes, kCTFontTraitsAttribute, traits);
956 CFRelease(traits);
957 }
958 CFRelease(symTraits);
959 }
960 }
961 // Create the font descriptor with our attributes
962 descriptor = CTFontDescriptorCreateWithAttributes(attributes);
963 wxASSERT(descriptor != NULL);
964
965 CFRelease(attributes);
966 }
967 // Return our font descriptor.
968 return descriptor ;
969 }
970
971 #endif
972
973 void wxNativeFontInfo::Init()
974 {
975 #if wxOSX_USE_ATSU_TEXT
976 m_atsuFontID = 0 ;
977 m_atsuAdditionalQDStyles = 0;
978 m_atsuFontValid = false;
979 #if wxOSX_USE_CARBON
980 m_qdFontStyle = 0;
981 m_qdFontFamily = 0;
982 #endif
983 #endif
984 m_pointSize = 0;
985 m_family = wxFONTFAMILY_DEFAULT;
986 m_style = wxFONTSTYLE_NORMAL;
987 m_weight = wxFONTWEIGHT_NORMAL;
988 m_underlined = false;
989 m_faceName.clear();
990 m_encoding = wxFont::GetDefaultEncoding();
991 m_descriptorValid = false;
992 }
993
994 #if wxOSX_USE_CORE_TEXT
995 void wxNativeFontInfo::Init(CTFontDescriptorRef descr)
996 {
997 Init();
998
999 wxCFRef< CFNumberRef > sizevalue( (CFNumberRef) CTFontDescriptorCopyAttribute( descr, kCTFontSizeAttribute ) );
1000 float fsize;
1001 if ( CFNumberGetValue( sizevalue , kCFNumberFloatType , &fsize ) )
1002 m_pointSize = (int)( fsize + 0.5 );
1003
1004 wxCFRef< CFDictionaryRef > traitsvalue( (CFDictionaryRef) CTFontDescriptorCopyAttribute( descr, kCTFontTraitsAttribute ) );
1005 CTFontSymbolicTraits traits;
1006 if ( CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(traitsvalue,kCTFontSymbolicTrait),kCFNumberIntType,&traits) )
1007 {
1008 if ( traits & kCTFontItalicTrait )
1009 m_style = wxFONTSTYLE_ITALIC;
1010 if ( traits & kCTFontBoldTrait )
1011 m_weight = wxFONTWEIGHT_BOLD ;
1012 }
1013
1014 wxCFStringRef familyName( (CFStringRef) CTFontDescriptorCopyAttribute(descr, kCTFontFamilyNameAttribute));
1015 m_faceName = familyName.AsString();
1016 }
1017 #endif
1018
1019 void wxNativeFontInfo::EnsureValid()
1020 {
1021 if ( m_descriptorValid )
1022 return;
1023
1024 #if wxOSX_USE_ATSU_TEXT
1025 if ( !m_atsuFontValid )
1026 {
1027 #if !wxOSX_USE_CARBON
1028 // not needed outside
1029 wxInt16 m_qdFontFamily;
1030 wxInt16 m_qdFontStyle;
1031 #endif
1032 wxCFStringRef cf( m_faceName, wxLocale::GetSystemEncoding() );
1033 ATSFontFamilyRef atsfamily = ATSFontFamilyFindFromName( cf , kATSOptionFlagsDefault );
1034 if ( atsfamily == (ATSFontFamilyRef) -1 )
1035 {
1036 wxLogDebug( wxT("ATSFontFamilyFindFromName failed for ") + m_faceName );
1037 m_qdFontFamily = GetAppFont();
1038 }
1039 else
1040 {
1041 m_qdFontFamily = FMGetFontFamilyFromATSFontFamilyRef( atsfamily );
1042 }
1043
1044 m_qdFontStyle = 0;
1045 if (m_weight == wxFONTWEIGHT_BOLD)
1046 m_qdFontStyle |= bold;
1047 if (m_style == wxFONTSTYLE_ITALIC || m_style == wxFONTSTYLE_SLANT)
1048 m_qdFontStyle |= italic;
1049 if (m_underlined)
1050 m_qdFontStyle |= underline;
1051
1052
1053 // we try to get as much styles as possible into ATSU
1054
1055 // ATSUFontID and FMFont are equivalent
1056 FMFontStyle intrinsicStyle = 0 ;
1057 OSStatus status = FMGetFontFromFontFamilyInstance( m_qdFontFamily , m_qdFontStyle , (FMFont*)&m_atsuFontID , &intrinsicStyle);
1058 if ( status != noErr )
1059 {
1060 wxFAIL_MSG( wxT("couldn't get an ATSUFont from font family") );
1061 }
1062 m_atsuAdditionalQDStyles = m_qdFontStyle & (~intrinsicStyle );
1063 m_atsuFontValid = true;
1064 }
1065 #endif
1066 m_descriptorValid = true;
1067 }
1068
1069 void wxNativeFontInfo::Init(const wxNativeFontInfo& info)
1070 {
1071 Init();
1072 #if wxOSX_USE_ATSU_TEXT
1073 m_atsuFontValid = info.m_atsuFontValid;
1074 m_atsuFontID = info.m_atsuFontID ;
1075 m_atsuAdditionalQDStyles = info.m_atsuAdditionalQDStyles;
1076 #if wxOSX_USE_CARBON
1077 m_qdFontFamily = info.m_qdFontFamily;
1078 m_qdFontStyle = info.m_qdFontStyle;
1079 #endif
1080 #endif
1081 m_pointSize = info.m_pointSize;
1082 m_family = info.m_family;
1083 m_style = info.m_style;
1084 m_weight = info.m_weight;
1085 m_underlined = info.m_underlined;
1086 m_faceName = info.m_faceName;
1087 m_encoding = info.m_encoding;
1088 m_descriptorValid = info.m_descriptorValid;
1089 }
1090
1091 void wxNativeFontInfo::Init(int size,
1092 wxFontFamily family,
1093 wxFontStyle style,
1094 wxFontWeight weight,
1095 bool underlined,
1096 const wxString& faceName,
1097 wxFontEncoding encoding)
1098 {
1099 Init();
1100 m_pointSize = size;
1101 m_family = family;
1102 m_style = style;
1103 m_weight = weight;
1104 m_underlined = underlined;
1105 m_faceName = faceName;
1106 if ( encoding == wxFONTENCODING_DEFAULT )
1107 encoding = wxFont::GetDefaultEncoding();
1108 m_encoding = encoding;
1109
1110 }
1111
1112 void wxNativeFontInfo::Free()
1113 {
1114 #if wxOSX_USE_ATSU_TEXT
1115 m_atsuFontID = 0 ;
1116 m_atsuAdditionalQDStyles = 0;
1117 m_atsuFontValid = false;
1118 #endif
1119 m_descriptorValid = false;
1120 }
1121
1122 bool wxNativeFontInfo::FromString(const wxString& s)
1123 {
1124 long l;
1125
1126 wxStringTokenizer tokenizer(s, wxT(";"));
1127
1128 wxString token = tokenizer.GetNextToken();
1129 //
1130 // Ignore the version for now
1131 //
1132
1133 token = tokenizer.GetNextToken();
1134 if ( !token.ToLong(&l) )
1135 return false;
1136 m_pointSize = (int)l;
1137
1138 token = tokenizer.GetNextToken();
1139 if ( !token.ToLong(&l) )
1140 return false;
1141 m_family = (wxFontFamily)l;
1142
1143 token = tokenizer.GetNextToken();
1144 if ( !token.ToLong(&l) )
1145 return false;
1146 m_style = (wxFontStyle)l;
1147
1148 token = tokenizer.GetNextToken();
1149 if ( !token.ToLong(&l) )
1150 return false;
1151 m_weight = (wxFontWeight)l;
1152
1153 token = tokenizer.GetNextToken();
1154 if ( !token.ToLong(&l) )
1155 return false;
1156 m_underlined = l != 0;
1157
1158 m_faceName = tokenizer.GetNextToken();
1159
1160 #ifndef __WXMAC__
1161 if( !faceName )
1162 return false;
1163 #endif
1164
1165 token = tokenizer.GetNextToken();
1166 if ( !token.ToLong(&l) )
1167 return false;
1168 m_encoding = (wxFontEncoding)l;
1169
1170 return true;
1171 }
1172
1173 wxString wxNativeFontInfo::ToString() const
1174 {
1175 wxString s;
1176
1177 s.Printf(wxT("%d;%d;%d;%d;%d;%d;%s;%d"),
1178 0, // version
1179 m_pointSize,
1180 m_family,
1181 (int)m_style,
1182 (int)m_weight,
1183 m_underlined,
1184 m_faceName.GetData(),
1185 (int)m_encoding);
1186
1187 return s;
1188 }
1189
1190 int wxNativeFontInfo::GetPointSize() const
1191 {
1192 return m_pointSize;
1193 }
1194
1195 wxFontStyle wxNativeFontInfo::GetStyle() const
1196 {
1197 return m_style;
1198 }
1199
1200 wxFontWeight wxNativeFontInfo::GetWeight() const
1201 {
1202 return m_weight;
1203 }
1204
1205 bool wxNativeFontInfo::GetUnderlined() const
1206 {
1207 return m_underlined;
1208 }
1209
1210 wxString wxNativeFontInfo::GetFaceName() const
1211 {
1212 return m_faceName;
1213 }
1214
1215 wxFontFamily wxNativeFontInfo::GetFamily() const
1216 {
1217 return m_family;
1218 }
1219
1220 wxFontEncoding wxNativeFontInfo::GetEncoding() const
1221 {
1222 return m_encoding;
1223 }
1224
1225 // changing the font descriptor
1226
1227 void wxNativeFontInfo::SetPointSize(int pointsize)
1228 {
1229 if ( m_pointSize != pointsize )
1230 {
1231 m_pointSize = pointsize;
1232 Free();
1233 }
1234 }
1235
1236 void wxNativeFontInfo::SetStyle(wxFontStyle style_)
1237 {
1238 if ( m_style != style_ )
1239 {
1240 m_style = style_;
1241 Free();
1242 }
1243 }
1244
1245 void wxNativeFontInfo::SetWeight(wxFontWeight weight_)
1246 {
1247 if ( m_weight != weight_ )
1248 {
1249 m_weight = weight_;
1250 Free();
1251 }
1252 }
1253
1254 void wxNativeFontInfo::SetUnderlined(bool underlined_)
1255 {
1256 if ( m_underlined != underlined_ )
1257 {
1258 m_underlined = underlined_;
1259 Free();
1260 }
1261 }
1262
1263 bool wxNativeFontInfo::SetFaceName(const wxString& facename_)
1264 {
1265 if ( m_faceName != facename_ )
1266 {
1267 m_faceName = facename_;
1268 Free();
1269 }
1270 return true;
1271 }
1272
1273 void wxNativeFontInfo::SetFamily(wxFontFamily family_)
1274 {
1275 if ( m_family != family_ )
1276 {
1277 m_family = family_;
1278 Free();
1279 }
1280 }
1281
1282 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding_)
1283 {
1284 if ( encoding_ == wxFONTENCODING_DEFAULT )
1285 encoding_ = wxFont::GetDefaultEncoding();
1286 m_encoding = encoding_;
1287 // not reflected in native descriptors
1288 }