]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/font.cpp
deactivate read-only implementation for unicodetextcontrol because it cannot be selec...
[wxWidgets.git] / src / mac / carbon / font.cpp
CommitLineData
e9576ca5
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: font.cpp
3// Purpose: wxFont class
a31a5f85 4// Author: Stefan Csomor
e9576ca5 5// Modified by:
a31a5f85 6// Created: 1998-01-01
e9576ca5 7// RCS-ID: $Id$
a31a5f85 8// Copyright: (c) Stefan Csomor
65571936 9// Licence: wxWindows licence
e9576ca5
SC
10/////////////////////////////////////////////////////////////////////////////
11
3e527073
SC
12#include "wx/wxprec.h"
13
e9576ca5
SC
14#include "wx/string.h"
15#include "wx/font.h"
5b781a67 16#include "wx/fontutil.h"
e9576ca5 17#include "wx/gdicmn.h"
03e11df5 18#include "wx/utils.h"
3b7e6277
GD
19#include "wx/fontutil.h"
20
76a5e5d2 21#include "wx/mac/private.h"
6eaa4426 22
768c6e8b 23#ifndef __DARWIN__
7f0c3a63 24#include <ATSUnicode.h>
768c6e8b 25#endif
76a5e5d2 26
6eaa4426 27
e9576ca5 28IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
e9576ca5 29
6eaa4426 30
3bf5a59b
VZ
31class WXDLLEXPORT wxFontRefData: public wxGDIRefData
32{
33 friend class WXDLLEXPORT wxFont;
6eaa4426 34
3bf5a59b
VZ
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)
c277569a 43 , m_faceName(wxT("applicationfont"))
3bf5a59b
VZ
44 , m_encoding(wxFONTENCODING_DEFAULT)
45 , m_macFontNum(0)
46 , m_macFontSize(0)
47 , m_macFontStyle(0)
3e527073 48 , m_macATSUStyle(0)
e369bddb 49 , m_macATSUFontID(0)
3bf5a59b 50 {
c277569a
SC
51 Init(m_pointSize, m_family, m_style, m_weight,
52 m_underlined, m_faceName, m_encoding);
3bf5a59b
VZ
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)
3e527073 68 , m_macATSUStyle(0)
e369bddb 69 , m_macATSUFontID(data.m_macATSUFontID)
3bf5a59b
VZ
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)
3e527073 93 , m_macATSUStyle(0)
e369bddb 94 , m_macATSUFontID(0)
3bf5a59b
VZ
95 {
96 Init(size, family, style, weight, underlined, faceName, encoding);
97 }
98
99 virtual ~wxFontRefData();
6eaa4426
DS
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
3bf5a59b
VZ
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
e369bddb
GD
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;
3bf5a59b 128 bool m_noAA; // No anti-aliasing
6eaa4426 129
3bf5a59b 130public:
facd6764
SC
131 short m_macFontNum;
132 short m_macFontSize;
133 Style m_macFontStyle;
6eaa4426 134
facd6764 135 // ATSU Font Information
6eaa4426 136
3103e8a9 137 // this is split into an ATSU font id that may
facd6764
SC
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
3e527073 141 ATSUStyle m_macATSUStyle ;
facd6764
SC
142 ATSUFontID m_macATSUFontID;
143 Style m_macATSUAdditionalQDStyles ;
6eaa4426 144
facd6764
SC
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 ;
3bf5a59b 148
6eaa4426 149 wxNativeFontInfo m_info;
3bf5a59b 150};
6eaa4426
DS
151
152
e7549107
SC
153// ============================================================================
154// implementation
155// ============================================================================
156
157// ----------------------------------------------------------------------------
158// wxFontRefData
159// ----------------------------------------------------------------------------
160
161void wxFontRefData::Init(int pointSize,
6eaa4426
DS
162 int family,
163 int style,
164 int weight,
165 bool underlined,
166 const wxString& faceName,
167 wxFontEncoding encoding)
e9576ca5 168{
e7549107
SC
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
d84afea9
GD
178 m_macFontNum = 0 ;
179 m_macFontSize = 0;
180 m_macFontStyle = 0;
facd6764
SC
181 m_macATSUFontID = 0;
182 m_macATSUAdditionalQDStyles = 0 ;
3e527073 183 m_macATSUStyle = NULL ;
6eaa4426 184
facd6764 185 m_macThemeFontID = kThemeCurrentPortFont ;
6eaa4426 186 m_noAA = false;
e9576ca5
SC
187}
188
189wxFontRefData::~wxFontRefData()
190{
3e527073
SC
191 if ( m_macATSUStyle )
192 {
193 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
194 m_macATSUStyle = NULL ;
195 }
e9576ca5
SC
196}
197
519cb848
SC
198void wxFontRefData::MacFindFont()
199{
6eaa4426 200 if ( m_macThemeFontID != kThemeCurrentPortFont )
e40298d5 201 {
facd6764 202 Str255 fontName ;
6eaa4426
DS
203
204 GetThemeFont( m_macThemeFontID, GetApplicationScript(), fontName, &m_macFontSize, &m_macFontStyle );
facd6764
SC
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 ;
6eaa4426 214 ::GetFNum( fontName, &m_macFontNum );
facd6764 215 m_pointSize = m_macFontSize ;
e40298d5
JS
216 }
217 else
218 {
6eaa4426 219 if ( m_faceName.Length() == 0 )
facd6764 220 {
6eaa4426 221 switch ( m_family )
facd6764
SC
222 {
223 case wxDEFAULT :
6eaa4426 224 m_macFontNum = ::GetAppFont();
facd6764 225 break ;
6eaa4426 226
facd6764 227 case wxSCRIPT :
4b8f2c2b
SC
228 case wxROMAN :
229 case wxDECORATIVE :
6eaa4426 230 ::GetFNum( "\pTimes", &m_macFontNum );
facd6764 231 break ;
6eaa4426 232
facd6764 233 case wxSWISS :
4b8f2c2b 234#ifdef __WXMAC_OSX__
6eaa4426 235 ::GetFNum( "\pLucida Grande", &m_macFontNum );
4b8f2c2b 236#else
6eaa4426 237 ::GetFNum( "\pGeneva", &m_macFontNum );
4b8f2c2b 238#endif
facd6764 239 break ;
6eaa4426 240
facd6764 241 case wxMODERN :
6eaa4426
DS
242 ::GetFNum( "\pMonaco", &m_macFontNum );
243 break ;
244
245 default:
facd6764
SC
246 break ;
247 }
6eaa4426 248
facd6764
SC
249 Str255 name ;
250 ::GetFontName( m_macFontNum , name ) ;
251 m_faceName = wxMacMakeStringFromPascal( name ) ;
252 }
e40298d5
JS
253 else
254 {
facd6764
SC
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 }
e40298d5 265 }
facd6764
SC
266
267 m_macFontStyle = 0;
268 if (m_weight == wxBOLD)
269 m_macFontStyle |= bold;
6eaa4426 270 if (m_style == wxITALIC || m_style == wxSLANT)
facd6764 271 m_macFontStyle |= italic;
6eaa4426 272 if (m_underlined)
facd6764
SC
273 m_macFontStyle |= underline;
274 m_macFontSize = m_pointSize ;
e40298d5
JS
275 }
276
facd6764 277 // we try to get as much styles as possible into ATSU
3e527073
SC
278
279 Fixed atsuSize = IntToFixed( m_macFontSize ) ;
280
facd6764 281 Style atsuStyle = normal ;
6eaa4426 282 verify_noerr(::ATSUFONDtoFontID(m_macFontNum, atsuStyle , (UInt32*)&m_macATSUFontID) );
facd6764
SC
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 }
6eaa4426 292
facd6764
SC
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 }
6eaa4426 302
facd6764
SC
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 }
6eaa4426 312
facd6764 313 m_macATSUAdditionalQDStyles = m_macFontStyle & (~atsuStyle ) ;
3e527073
SC
314
315 if ( m_macATSUStyle )
316 {
317 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
318 m_macATSUStyle = NULL ;
319 }
6eaa4426 320
3e527073
SC
321 OSStatus status = ::ATSUCreateStyle((ATSUStyle *)&m_macATSUStyle) ;
322 wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") ) ;
6eaa4426 323
3e527073
SC
324 ATSUAttributeTag atsuTags[] =
325 {
326 kATSUFontTag ,
327 kATSUSizeTag ,
328 kATSUVerticalCharacterTag,
329 kATSUQDBoldfaceTag ,
330 kATSUQDItalicTag ,
331 kATSUQDUnderlineTag ,
332 kATSUQDCondensedTag ,
333 kATSUQDExtendedTag ,
6eaa4426
DS
334 };
335 ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
3e527073
SC
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 ) ,
6eaa4426
DS
345 };
346
3e527073
SC
347 Boolean kTrue = true ;
348 Boolean kFalse = false ;
349
350 ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
6eaa4426 351 ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
3e527073
SC
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 ,
6eaa4426
DS
361 };
362
363 status = ::ATSUSetAttributes(
364 (ATSUStyle)m_macATSUStyle,
365 sizeof(atsuTags) / sizeof(ATSUAttributeTag) ,
3e527073
SC
366 atsuTags, atsuSizes, atsuValues);
367
6eaa4426 368 wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") ) ;
519cb848
SC
369}
370
e7549107
SC
371// ----------------------------------------------------------------------------
372// wxFont
373// ----------------------------------------------------------------------------
e9576ca5 374
e7549107 375void wxFont::Init()
e9576ca5 376{
e9576ca5
SC
377}
378
5b781a67
SC
379bool wxFont::Create(const wxNativeFontInfo& info)
380{
6eaa4426
DS
381 return Create(
382 info.pointSize, info.family, info.style, info.weight,
383 info.underlined, info.faceName, info.encoding );
5b781a67
SC
384}
385
3b7e6277
GD
386wxFont::wxFont(const wxString& fontdesc)
387{
388 wxNativeFontInfo info;
389 if ( info.FromString(fontdesc) )
390 (void)Create(info);
391}
392
e7549107 393bool wxFont::Create(int pointSize,
6eaa4426
DS
394 int family,
395 int style,
396 int weight,
397 bool underlined,
398 const wxString& faceName,
399 wxFontEncoding encoding)
e9576ca5
SC
400{
401 UnRef();
6eaa4426
DS
402
403 m_refData = new wxFontRefData(
404 pointSize, family, style, weight,
405 underlined, faceName, encoding);
e9576ca5
SC
406
407 RealizeResource();
408
6eaa4426 409 return true;
e9576ca5
SC
410}
411
6eaa4426 412bool wxFont::MacCreateThemeFont(wxUint16 themeFontID)
facd6764
SC
413{
414 UnRef();
6eaa4426
DS
415
416 m_refData = new wxFontRefData(
417 12, wxDEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
418 false, wxEmptyString, wxFONTENCODING_DEFAULT );
419
facd6764
SC
420 M_FONTDATA->m_macThemeFontID = themeFontID ;
421 RealizeResource();
422
6eaa4426 423 return true;
facd6764
SC
424}
425
e9576ca5
SC
426wxFont::~wxFont()
427{
e9576ca5
SC
428}
429
430bool wxFont::RealizeResource()
431{
e40298d5 432 M_FONTDATA->MacFindFont() ;
6eaa4426
DS
433
434 return true;
e9576ca5
SC
435}
436
51abe921
SC
437void wxFont::SetEncoding(wxFontEncoding encoding)
438{
439 Unshare();
440
441 M_FONTDATA->m_encoding = encoding;
442
443 RealizeResource();
444}
445
e9576ca5
SC
446void wxFont::Unshare()
447{
e40298d5
JS
448 // Don't change shared data
449 if (!m_refData)
e9576ca5 450 {
e40298d5
JS
451 m_refData = new wxFontRefData();
452 }
e9576ca5
SC
453 else
454 {
e40298d5
JS
455 wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
456 UnRef();
457 m_refData = ref;
458 }
e9576ca5
SC
459}
460
461void wxFont::SetPointSize(int pointSize)
462{
463 Unshare();
464
465 M_FONTDATA->m_pointSize = pointSize;
466
467 RealizeResource();
468}
469
470void wxFont::SetFamily(int family)
471{
472 Unshare();
473
474 M_FONTDATA->m_family = family;
475
476 RealizeResource();
477}
478
479void wxFont::SetStyle(int style)
480{
481 Unshare();
482
483 M_FONTDATA->m_style = style;
484
485 RealizeResource();
486}
487
488void wxFont::SetWeight(int weight)
489{
490 Unshare();
491
492 M_FONTDATA->m_weight = weight;
493
494 RealizeResource();
495}
496
497void wxFont::SetFaceName(const wxString& faceName)
498{
499 Unshare();
500
501 M_FONTDATA->m_faceName = faceName;
502
503 RealizeResource();
504}
505
506void wxFont::SetUnderlined(bool underlined)
507{
508 Unshare();
509
510 M_FONTDATA->m_underlined = underlined;
511
512 RealizeResource();
513}
514
ac17f9b1
SC
515void wxFont::SetNoAntiAliasing( bool no )
516{
517 Unshare();
518
519 M_FONTDATA->SetNoAntiAliasing( no );
520
521 RealizeResource();
522}
523
e7549107
SC
524// ----------------------------------------------------------------------------
525// accessors
526// ----------------------------------------------------------------------------
527
fcb35beb
VZ
528// TODO: insert checks everywhere for M_FONTDATA == NULL!
529
e7549107 530int wxFont::GetPointSize() const
e9576ca5 531{
77eddfb7 532 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 533
e7549107 534 return M_FONTDATA->m_pointSize;
e9576ca5
SC
535}
536
e7549107 537int wxFont::GetFamily() const
e9576ca5 538{
77eddfb7 539 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 540
e7549107 541 return M_FONTDATA->m_family;
e9576ca5
SC
542}
543
e7549107 544int wxFont::GetStyle() const
e9576ca5 545{
77eddfb7 546 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 547
e7549107
SC
548 return M_FONTDATA->m_style;
549}
550
551int wxFont::GetWeight() const
552{
77eddfb7 553 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 554
e7549107
SC
555 return M_FONTDATA->m_weight;
556}
557
558bool wxFont::GetUnderlined() const
559{
77eddfb7 560 wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
6eaa4426 561
e7549107
SC
562 return M_FONTDATA->m_underlined;
563}
564
565wxString wxFont::GetFaceName() const
566{
facd6764 567 wxCHECK_MSG( M_FONTDATA != NULL , wxEmptyString , wxT("invalid font") );
6eaa4426 568
facd6764 569 return M_FONTDATA->m_faceName;
e7549107
SC
570}
571
572wxFontEncoding wxFont::GetEncoding() const
573{
facd6764 574 wxCHECK_MSG( M_FONTDATA != NULL , wxFONTENCODING_DEFAULT , wxT("invalid font") );
6eaa4426 575
e7549107 576 return M_FONTDATA->m_encoding;
e9576ca5
SC
577}
578
5ac2e80c 579bool wxFont::GetNoAntiAliasing() const
ac17f9b1 580{
77eddfb7 581 wxCHECK_MSG( M_FONTDATA != NULL , false, wxT("invalid font") );
6eaa4426 582
ac17f9b1
SC
583 return M_FONTDATA->m_noAA;
584}
585
facd6764 586short wxFont::MacGetFontNum() const
fcb35beb 587{
77eddfb7 588 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 589
fcb35beb
VZ
590 return M_FONTDATA->m_macFontNum;
591}
592
facd6764 593short wxFont::MacGetFontSize() const
fcb35beb 594{
77eddfb7 595 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 596
fcb35beb
VZ
597 return M_FONTDATA->m_macFontSize;
598}
599
facd6764 600wxByte wxFont::MacGetFontStyle() const
fcb35beb 601{
77eddfb7 602 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 603
fcb35beb
VZ
604 return M_FONTDATA->m_macFontStyle;
605}
606
facd6764 607wxUint32 wxFont::MacGetATSUFontID() const
fcb35beb 608{
77eddfb7 609 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 610
fcb35beb
VZ
611 return M_FONTDATA->m_macATSUFontID;
612}
613
6eaa4426 614void * wxFont::MacGetATSUStyle() const
3e527073
SC
615{
616 wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
6eaa4426 617
3e527073
SC
618 return M_FONTDATA->m_macATSUStyle;
619}
620
facd6764
SC
621wxUint32 wxFont::MacGetATSUAdditionalQDStyles() const
622{
77eddfb7 623 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 624
facd6764
SC
625 return M_FONTDATA->m_macATSUAdditionalQDStyles;
626}
627
6eaa4426 628wxUint16 wxFont::MacGetThemeFontID() const
facd6764 629{
77eddfb7 630 wxCHECK_MSG( M_FONTDATA != NULL , 0, wxT("invalid font") );
6eaa4426 631
facd6764
SC
632 return M_FONTDATA->m_macThemeFontID;
633}
634
6eaa4426 635const wxNativeFontInfo * wxFont::GetNativeFontInfo() const
3bf5a59b 636{
facd6764 637 wxCHECK_MSG( M_FONTDATA != NULL , NULL, wxT("invalid font") );
3bf5a59b
VZ
638 wxCHECK_MSG( Ok(), NULL, wxT("invalid font") );
639
640 M_FONTDATA->m_info.InitFromFont(*this);
641
642 return &(M_FONTDATA->m_info);
643}
644