]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/carbon/font.cpp
chain to the polling function GLib was using before we replaced it, eliminating all...
[wxWidgets.git] / src / mac / carbon / font.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/mac/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#endif
22
23#include "wx/fontutil.h"
24#include "wx/graphics.h"
25
26#include "wx/mac/private.h"
27
28#ifndef __DARWIN__
29#include <ATSUnicode.h>
30#endif
31
32
33IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
34
35
36class WXDLLEXPORT wxFontRefData: public wxGDIRefData
37{
38 friend class WXDLLEXPORT wxFont;
39
40public:
41 wxFontRefData()
42 : m_fontId(0)
43 , m_pointSize(10)
44 , m_family(wxDEFAULT)
45 , m_style(wxNORMAL)
46 , m_weight(wxNORMAL)
47 , m_underlined(false)
48 , m_faceName(wxT("applicationfont"))
49 , m_encoding(wxFONTENCODING_DEFAULT)
50 , m_macFontFamily(0)
51 , m_macFontSize(0)
52 , m_macFontStyle(0)
53 , m_macATSUStyle(0)
54 , m_macATSUFontID(0)
55 {
56 Init(m_pointSize, m_family, m_style, m_weight,
57 m_underlined, m_faceName, m_encoding);
58 }
59
60 wxFontRefData(const wxFontRefData& data)
61 : wxGDIRefData()
62 , m_fontId(data.m_fontId)
63 , m_pointSize(data.m_pointSize)
64 , m_family(data.m_family)
65 , m_style(data.m_style)
66 , m_weight(data.m_weight)
67 , m_underlined(data.m_underlined)
68 , m_faceName(data.m_faceName)
69 , m_encoding(data.m_encoding)
70 , m_macFontFamily(data.m_macFontFamily)
71 , m_macFontSize(data.m_macFontSize)
72 , m_macFontStyle(data.m_macFontStyle)
73 , m_macATSUStyle(0)
74 , m_macATSUFontID(data.m_macATSUFontID)
75 {
76 Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
77 data.m_underlined, data.m_faceName, data.m_encoding);
78 }
79
80 wxFontRefData(int size,
81 int family,
82 int style,
83 int weight,
84 bool underlined,
85 const wxString& faceName,
86 wxFontEncoding encoding)
87 : m_fontId(0)
88 , m_pointSize(size)
89 , m_family(family)
90 , m_style(style)
91 , m_weight(weight)
92 , m_underlined(underlined)
93 , m_faceName(faceName)
94 , m_encoding(encoding)
95 , m_macFontFamily(0)
96 , m_macFontSize(0)
97 , m_macFontStyle(0)
98 , m_macATSUStyle(0)
99 , m_macATSUFontID(0)
100 {
101 Init(size, family, style, weight, underlined, faceName, encoding);
102 }
103
104 virtual ~wxFontRefData();
105
106 void SetNoAntiAliasing( bool no = true )
107 { m_noAA = no; }
108
109 bool GetNoAntiAliasing() const
110 { return m_noAA; }
111
112 void MacFindFont();
113
114protected:
115 // common part of all ctors
116 void Init(int size,
117 int family,
118 int style,
119 int weight,
120 bool underlined,
121 const wxString& faceName,
122 wxFontEncoding encoding);
123
124 // font characterstics
125 int m_fontId;
126 int m_pointSize;
127 int m_family;
128 int m_style;
129 int m_weight;
130 bool m_underlined;
131 wxString m_faceName;
132 wxFontEncoding m_encoding;
133 bool m_noAA; // No anti-aliasing
134
135public:
136 FMFontFamily m_macFontFamily;
137 FMFontSize m_macFontSize;
138 FMFontStyle m_macFontStyle;
139
140 // ATSU Font Information
141
142 // this is split into an ATSU font id that may
143 // contain some styles (special bold fonts etc) and
144 // these are the additional qd styles that are not
145 // included in the ATSU font id
146 ATSUStyle m_macATSUStyle ;
147 ATSUFontID m_macATSUFontID;
148 FMFontStyle m_macATSUAdditionalQDStyles ;
149
150 // for true themeing support we must store the correct font
151 // information here, as this speeds up and optimizes rendering
152 ThemeFontID m_macThemeFontID ;
153
154 wxNativeFontInfo m_info;
155};
156
157#define M_FONTDATA ((wxFontRefData*)m_refData)
158
159
160// ============================================================================
161// implementation
162// ============================================================================
163
164// ----------------------------------------------------------------------------
165// wxFontRefData
166// ----------------------------------------------------------------------------
167
168void wxFontRefData::Init(int pointSize,
169 int family,
170 int style,
171 int weight,
172 bool underlined,
173 const wxString& faceName,
174 wxFontEncoding encoding)
175{
176 m_style = style;
177 m_pointSize = pointSize;
178 m_family = family;
179 m_style = style;
180 m_weight = weight;
181 m_underlined = underlined;
182 m_faceName = faceName;
183 m_encoding = encoding;
184
185 m_macFontFamily = 0 ;
186 m_macFontSize = 0;
187 m_macFontStyle = 0;
188 m_macATSUFontID = 0;
189 m_macATSUAdditionalQDStyles = 0 ;
190 m_macATSUStyle = NULL ;
191
192 m_macThemeFontID = kThemeCurrentPortFont ;
193 m_noAA = false;
194}
195
196wxFontRefData::~wxFontRefData()
197{
198 if ( m_macATSUStyle )
199 {
200 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
201 m_macATSUStyle = NULL ;
202 }
203}
204
205void wxFontRefData::MacFindFont()
206{
207 OSStatus status ;
208
209 Str255 qdFontName ;
210 if ( m_macThemeFontID != kThemeCurrentPortFont )
211 {
212 Style style ;
213 GetThemeFont( m_macThemeFontID, GetApplicationScript(), qdFontName, &m_macFontSize, &style );
214 m_macFontStyle = style ;
215 m_faceName = wxMacMakeStringFromPascal( qdFontName );
216 if ( m_macFontStyle & bold )
217 m_weight = wxBOLD ;
218 else
219 m_weight = wxNORMAL ;
220 if ( m_macFontStyle & italic )
221 m_style = wxITALIC ;
222 if ( m_macFontStyle & underline )
223 m_underlined = true ;
224 m_pointSize = m_macFontSize ;
225#ifndef __LP64__
226 m_macFontFamily = FMGetFontFamilyFromName( qdFontName );
227#endif
228 }
229 else
230 {
231 if ( m_faceName.empty() )
232 {
233 if ( m_family == wxDEFAULT )
234 {
235#ifndef __LP64__
236 m_macFontFamily = GetAppFont();
237 FMGetFontFamilyName(m_macFontFamily,qdFontName);
238 m_faceName = wxMacMakeStringFromPascal( qdFontName );
239#endif
240 }
241 else
242 {
243 switch ( m_family )
244 {
245 case wxSCRIPT :
246 case wxROMAN :
247 case wxDECORATIVE :
248 m_faceName = wxT("Times");
249 break ;
250
251 case wxSWISS :
252 m_faceName = wxT("Lucida Grande");
253 break ;
254
255 case wxMODERN :
256 m_faceName = wxT("Monaco");
257 break ;
258
259 default:
260 m_faceName = wxT("Times");
261 break ;
262 }
263#ifndef __LP64__
264 wxMacStringToPascal( m_faceName , qdFontName );
265 m_macFontFamily = FMGetFontFamilyFromName( qdFontName );
266#endif
267 }
268 }
269 else
270 {
271#ifndef __LP64__
272 if ( m_faceName == wxT("systemfont") )
273 m_macFontFamily = GetSysFont();
274 else if ( m_faceName == wxT("applicationfont") )
275 m_macFontFamily = GetAppFont();
276 else
277#else
278 if ( m_faceName == wxT("systemfont") )
279 m_faceName = wxT("Lucida Grande");
280 else if ( m_faceName == wxT("applicationfont") )
281 m_faceName = wxT("Lucida Grande");
282#endif
283 {
284 wxMacCFStringHolder cf( m_faceName, wxLocale::GetSystemEncoding() );
285 ATSFontFamilyRef atsfamily = ATSFontFamilyFindFromName( cf , kATSOptionFlagsDefault );
286 wxASSERT_MSG( atsfamily != (ATSFontFamilyRef) -1 , wxT("ATSFontFamilyFindFromName failed") );
287 m_macFontFamily = FMGetFontFamilyFromATSFontFamilyRef( atsfamily );
288 }
289 }
290
291 m_macFontStyle = 0;
292 if (m_weight == wxBOLD)
293 m_macFontStyle |= bold;
294 if (m_style == wxITALIC || m_style == wxSLANT)
295 m_macFontStyle |= italic;
296 if (m_underlined)
297 m_macFontStyle |= underline;
298 m_macFontSize = m_pointSize ;
299 }
300
301 // we try to get as much styles as possible into ATSU
302
303
304 // ATSUFontID and FMFont are equivalent
305 FMFontStyle intrinsicStyle = 0 ;
306#ifndef __LP64__
307 status = FMGetFontFromFontFamilyInstance( m_macFontFamily , m_macFontStyle , &m_macATSUFontID , &intrinsicStyle);
308 wxASSERT_MSG( status == noErr , wxT("couldn't get an ATSUFont from font family") );
309#endif
310 m_macATSUAdditionalQDStyles = m_macFontStyle & (~intrinsicStyle );
311
312 if ( m_macATSUStyle )
313 {
314 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
315 m_macATSUStyle = NULL ;
316 }
317
318 status = ::ATSUCreateStyle((ATSUStyle *)&m_macATSUStyle);
319 wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") );
320
321 ATSUAttributeTag atsuTags[] =
322 {
323 kATSUFontTag ,
324 kATSUSizeTag ,
325 kATSUVerticalCharacterTag,
326 kATSUQDBoldfaceTag ,
327 kATSUQDItalicTag ,
328 kATSUQDUnderlineTag ,
329 kATSUQDCondensedTag ,
330 kATSUQDExtendedTag ,
331 };
332 ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
333 {
334 sizeof( ATSUFontID ) ,
335 sizeof( Fixed ) ,
336 sizeof( ATSUVerticalCharacterType),
337 sizeof( Boolean ) ,
338 sizeof( Boolean ) ,
339 sizeof( Boolean ) ,
340 sizeof( Boolean ) ,
341 sizeof( Boolean ) ,
342 };
343
344 Boolean kTrue = true ;
345 Boolean kFalse = false ;
346
347 Fixed atsuSize = IntToFixed( m_macFontSize );
348 ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
349 ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
350 {
351 &m_macATSUFontID ,
352 &atsuSize ,
353 &kHorizontal,
354 (m_macATSUAdditionalQDStyles & bold) ? &kTrue : &kFalse ,
355 (m_macATSUAdditionalQDStyles & italic) ? &kTrue : &kFalse ,
356 (m_macATSUAdditionalQDStyles & underline) ? &kTrue : &kFalse ,
357 (m_macATSUAdditionalQDStyles & condense) ? &kTrue : &kFalse ,
358 (m_macATSUAdditionalQDStyles & extend) ? &kTrue : &kFalse ,
359 };
360
361 status = ::ATSUSetAttributes(
362 (ATSUStyle)m_macATSUStyle,
363 sizeof(atsuTags) / sizeof(ATSUAttributeTag) ,
364 atsuTags, atsuSizes, atsuValues);
365
366 wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") );
367}
368
369// ----------------------------------------------------------------------------
370// wxFont
371// ----------------------------------------------------------------------------
372
373bool wxFont::Create(const wxNativeFontInfo& info)
374{
375 return Create(
376 info.pointSize, info.family, info.style, info.weight,
377 info.underlined, info.faceName, info.encoding );
378}
379
380wxFont::wxFont(const wxString& fontdesc)
381{
382 wxNativeFontInfo info;
383 if ( info.FromString(fontdesc) )
384 (void)Create(info);
385}
386
387bool wxFont::Create(int pointSize,
388 int family,
389 int style,
390 int weight,
391 bool underlined,
392 const wxString& faceName,
393 wxFontEncoding encoding)
394{
395 UnRef();
396
397 m_refData = new wxFontRefData(
398 pointSize, family, style, weight,
399 underlined, faceName, encoding);
400
401 RealizeResource();
402
403 return true;
404}
405
406bool wxFont::MacCreateThemeFont(wxUint16 themeFontID)
407{
408 UnRef();
409
410 m_refData = new wxFontRefData(
411 12, wxDEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
412 false, wxEmptyString, wxFONTENCODING_DEFAULT );
413
414 M_FONTDATA->m_macThemeFontID = themeFontID ;
415 RealizeResource();
416
417 return true;
418}
419
420wxFont::~wxFont()
421{
422}
423
424bool wxFont::RealizeResource()
425{
426 M_FONTDATA->MacFindFont();
427
428 return true;
429}
430
431void wxFont::SetEncoding(wxFontEncoding encoding)
432{
433 Unshare();
434
435 M_FONTDATA->m_encoding = encoding;
436
437 RealizeResource();
438}
439
440void wxFont::Unshare()
441{
442 // Don't change shared data
443 if (!m_refData)
444 {
445 m_refData = new wxFontRefData();
446 }
447 else
448 {
449 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
450 UnRef();
451 m_refData = ref;
452 }
453}
454
455void wxFont::SetPointSize(int pointSize)
456{
457 Unshare();
458
459 M_FONTDATA->m_pointSize = pointSize;
460
461 RealizeResource();
462}
463
464void wxFont::SetFamily(int family)
465{
466 Unshare();
467
468 M_FONTDATA->m_family = family;
469
470 RealizeResource();
471}
472
473void wxFont::SetStyle(int style)
474{
475 Unshare();
476
477 M_FONTDATA->m_style = style;
478
479 RealizeResource();
480}
481
482void wxFont::SetWeight(int weight)
483{
484 Unshare();
485
486 M_FONTDATA->m_weight = weight;
487
488 RealizeResource();
489}
490
491bool wxFont::SetFaceName(const wxString& faceName)
492{
493 Unshare();
494
495 M_FONTDATA->m_faceName = faceName;
496
497 RealizeResource();
498
499 return wxFontBase::SetFaceName(faceName);
500}
501
502void wxFont::SetUnderlined(bool underlined)
503{
504 Unshare();
505
506 M_FONTDATA->m_underlined = underlined;
507
508 RealizeResource();
509}
510
511void wxFont::SetNoAntiAliasing( bool no )
512{
513 Unshare();
514
515 M_FONTDATA->SetNoAntiAliasing( no );
516
517 RealizeResource();
518}
519
520// ----------------------------------------------------------------------------
521// accessors
522// ----------------------------------------------------------------------------
523
524// TODO: insert checks everywhere for M_FONTDATA == NULL!
525
526int wxFont::GetPointSize() const
527{
528 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
529
530 return M_FONTDATA->m_pointSize;
531}
532
533wxSize wxFont::GetPixelSize() const
534{
535#if wxUSE_GRAPHICS_CONTEXT
536 // TODO: consider caching the value
537 wxGraphicsContext* dc = wxGraphicsContext::CreateFromNative((CGContextRef) NULL);
538 dc->SetFont(*(wxFont *)this,*wxBLACK);
539 wxDouble width, height = 0;
540 dc->GetTextExtent( wxT("g"), &width, &height, NULL, NULL);
541 return wxSize((int)width, (int)height);
542#else
543 wxFontBase::GetPixelSize();
544#endif
545}
546
547int wxFont::GetFamily() const
548{
549 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
550
551 return M_FONTDATA->m_family;
552}
553
554int wxFont::GetStyle() const
555{
556 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
557
558 return M_FONTDATA->m_style;
559}
560
561int wxFont::GetWeight() const
562{
563 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
564
565 return M_FONTDATA->m_weight;
566}
567
568bool wxFont::GetUnderlined() const
569{
570 wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
571
572 return M_FONTDATA->m_underlined;
573}
574
575wxString wxFont::GetFaceName() const
576{
577 wxCHECK_MSG( M_FONTDATA != NULL , wxEmptyString , wxT("invalid font") );
578
579 return M_FONTDATA->m_faceName;
580}
581
582wxFontEncoding wxFont::GetEncoding() const
583{
584 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTENCODING_DEFAULT , wxT("invalid font") );
585
586 return M_FONTDATA->m_encoding;
587}
588
589bool wxFont::GetNoAntiAliasing() const
590{
591 wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
592
593 return M_FONTDATA->m_noAA;
594}
595
596short wxFont::MacGetFontNum() const
597{
598 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
599
600 return M_FONTDATA->m_macFontFamily;
601}
602
603short wxFont::MacGetFontSize() const
604{
605 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
606
607 return M_FONTDATA->m_macFontSize;
608}
609
610wxByte wxFont::MacGetFontStyle() const
611{
612 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
613
614 return M_FONTDATA->m_macFontStyle;
615}
616
617wxUint32 wxFont::MacGetATSUFontID() const
618{
619 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
620
621 return M_FONTDATA->m_macATSUFontID;
622}
623
624void * wxFont::MacGetATSUStyle() const
625{
626 wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
627
628 return M_FONTDATA->m_macATSUStyle;
629}
630
631wxUint32 wxFont::MacGetATSUAdditionalQDStyles() const
632{
633 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
634
635 return M_FONTDATA->m_macATSUAdditionalQDStyles;
636}
637
638wxUint16 wxFont::MacGetThemeFontID() const
639{
640 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
641
642 return M_FONTDATA->m_macThemeFontID;
643}
644
645const wxNativeFontInfo * wxFont::GetNativeFontInfo() const
646{
647 wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
648 wxCHECK_MSG( Ok(), NULL, wxT("invalid font") );
649
650 M_FONTDATA->m_info.InitFromFont(*this);
651
652 return &(M_FONTDATA->m_info);
653}