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