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