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