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