]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/font.cpp
wxWinCE (small screen) adjustements. Added possible testing of sizable calendar control.
[wxWidgets.git] / src / mac / carbon / font.cpp
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
28 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
29
30
31 class WXDLLEXPORT wxFontRefData: public wxGDIRefData
32 {
33 friend class WXDLLEXPORT wxFont;
34
35 public:
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
109 protected:
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
130 public:
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
161 void 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
189 wxFontRefData::~wxFontRefData()
190 {
191 if ( m_macATSUStyle )
192 {
193 ::ATSUDisposeStyle((ATSUStyle)m_macATSUStyle);
194 m_macATSUStyle = NULL ;
195 }
196 }
197
198 void 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
375 void wxFont::Init()
376 {
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 }
644