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