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