]> git.saurik.com Git - wxWidgets.git/blame - src/msw/font.cpp
Compile fix for gcc on MSW
[wxWidgets.git] / src / msw / font.cpp
CommitLineData
2bda0e17 1/////////////////////////////////////////////////////////////////////////////
a9249b2e 2// Name: src/msw/font.cpp
2bda0e17
KB
3// Purpose: wxFont class
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
77ffb593 8// Copyright: (c) wxWidgets team
65571936 9// Licence: wxWindows licence
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
0c5d3e1c
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
2bda0e17
KB
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
0c5d3e1c 24 #pragma hdrstop
2bda0e17
KB
25#endif
26
48a1108e
WS
27#include "wx/font.h"
28
2bda0e17 29#ifndef WX_PRECOMP
0c5d3e1c
VZ
30 #include "wx/list.h"
31 #include "wx/utils.h"
32 #include "wx/app.h"
f94dfb38 33 #include "wx/log.h"
e4ffab29 34 #include "wx/encinfo.h"
0c5d3e1c 35#endif // WX_PRECOMP
2bda0e17 36
bff67a6a
VZ
37#include "wx/msw/private.h"
38
76e23cdb 39#include "wx/fontutil.h"
bff67a6a 40#include "wx/fontmap.h"
76e23cdb 41
1e6feb95 42#include "wx/tokenzr.h"
2bda0e17 43
066f1b7a
SC
44#if wxUSE_EXTENDED_RTTI
45
3ff066a4 46wxBEGIN_ENUM( wxFontFamily )
cbe874bd
WS
47 wxENUM_MEMBER( wxDEFAULT )
48 wxENUM_MEMBER( wxDECORATIVE )
49 wxENUM_MEMBER( wxROMAN )
50 wxENUM_MEMBER( wxSCRIPT )
51 wxENUM_MEMBER( wxSWISS )
52 wxENUM_MEMBER( wxMODERN )
53 wxENUM_MEMBER( wxTELETYPE )
3ff066a4
SC
54wxEND_ENUM( wxFontFamily )
55
56wxBEGIN_ENUM( wxFontStyle )
cbe874bd
WS
57 wxENUM_MEMBER( wxNORMAL )
58 wxENUM_MEMBER( wxITALIC )
59 wxENUM_MEMBER( wxSLANT )
3ff066a4
SC
60wxEND_ENUM( wxFontStyle )
61
62wxBEGIN_ENUM( wxFontWeight )
cbe874bd
WS
63 wxENUM_MEMBER( wxNORMAL )
64 wxENUM_MEMBER( wxLIGHT )
65 wxENUM_MEMBER( wxBOLD )
3ff066a4 66wxEND_ENUM( wxFontWeight )
066f1b7a
SC
67
68IMPLEMENT_DYNAMIC_CLASS_WITH_COPY_XTI(wxFont, wxGDIObject,"wx/font.h")
69
3ff066a4 70wxBEGIN_PROPERTIES_TABLE(wxFont)
cbe874bd
WS
71 wxPROPERTY( Size,int, SetPointSize, GetPointSize, 12 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
72 wxPROPERTY( Family, int , SetFamily, GetFamily, (int)wxDEFAULT , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // wxFontFamily
73 wxPROPERTY( Style, int , SetStyle, GetStyle, (int)wxNORMAL , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // wxFontStyle
74 wxPROPERTY( Weight, int , SetWeight, GetWeight, (int)wxNORMAL , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // wxFontWeight
75 wxPROPERTY( Underlined, bool , SetUnderlined, GetUnderlined, false , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
76 wxPROPERTY( Face, wxString , SetFaceName, GetFaceName, EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
77 wxPROPERTY( Encoding, wxFontEncoding , SetEncoding, GetEncoding, wxFONTENCODING_DEFAULT , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
3ff066a4 78wxEND_PROPERTIES_TABLE()
066f1b7a 79
cbe874bd 80wxCONSTRUCTOR_6( wxFont , int , Size , int , Family , int , Style , int , Weight , bool , Underlined , wxString , Face )
066f1b7a 81
3ff066a4
SC
82wxBEGIN_HANDLERS_TABLE(wxFont)
83wxEND_HANDLERS_TABLE()
066f1b7a
SC
84
85#else
cbe874bd 86 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
066f1b7a
SC
87#endif
88
2bda0e17 89
3ca6a5f0
BP
90// ----------------------------------------------------------------------------
91// constants
92// ----------------------------------------------------------------------------
93
9cf8de4c
VZ
94// the mask used to extract the pitch from LOGFONT::lfPitchAndFamily field
95static const int PITCH_MASK = FIXED_PITCH | VARIABLE_PITCH;
96
0c5d3e1c
VZ
97// ----------------------------------------------------------------------------
98// wxFontRefData - the internal description of the font
99// ----------------------------------------------------------------------------
2bda0e17 100
0c5d3e1c 101class WXDLLEXPORT wxFontRefData: public wxGDIRefData
2bda0e17 102{
0c5d3e1c 103public:
a9249b2e 104 // constructors
0c5d3e1c
VZ
105 wxFontRefData()
106 {
c47addef 107 Init(-1, wxSize(0,0), false, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
8b5d5223 108 wxFONTWEIGHT_NORMAL, false, wxEmptyString,
544229d1 109 wxFONTENCODING_DEFAULT);
0c5d3e1c
VZ
110 }
111
112 wxFontRefData(int size,
544229d1
VZ
113 const wxSize& pixelSize,
114 bool sizeUsingPixels,
0c5d3e1c
VZ
115 int family,
116 int style,
117 int weight,
118 bool underlined,
119 const wxString& faceName,
120 wxFontEncoding encoding)
121 {
544229d1
VZ
122 Init(size, pixelSize, sizeUsingPixels, family, style, weight,
123 underlined, faceName, encoding);
0c5d3e1c 124 }
2bda0e17 125
04ef50df 126 wxFontRefData(const wxNativeFontInfo& info, WXHFONT hFont = 0)
09fcd889 127 {
04ef50df 128 Init(info, hFont);
09fcd889
VZ
129 }
130
04a18b0d 131 wxFontRefData(const wxFontRefData& data) : wxGDIRefData()
a9249b2e
VZ
132 {
133 if ( data.m_nativeFontInfoOk )
134 {
135 Init(data.m_nativeFontInfo);
136 }
137 else
138 {
544229d1
VZ
139 Init(data.m_pointSize, data.m_pixelSize, data.m_sizeUsingPixels,
140 data.m_family, data.m_style, data.m_weight,
a9249b2e
VZ
141 data.m_underlined, data.m_faceName, data.m_encoding);
142 }
143 }
144
0c5d3e1c
VZ
145 virtual ~wxFontRefData();
146
a9249b2e 147 // operations
8e34db1d 148 bool Alloc(const wxFont *font);
a9249b2e
VZ
149
150 void Free();
151
152 // all wxFont accessors
153 int GetPointSize() const
154 {
155 return m_nativeFontInfoOk ? m_nativeFontInfo.GetPointSize()
156 : m_pointSize;
157 }
158
544229d1
VZ
159 wxSize GetPixelSize() const
160 {
161 return m_nativeFontInfoOk ? m_nativeFontInfo.GetPixelSize()
162 : m_pixelSize;
163 }
907173e5 164
544229d1
VZ
165 bool IsUsingSizeInPixels() const
166 {
907173e5 167 return m_nativeFontInfoOk ? true : m_sizeUsingPixels;
544229d1
VZ
168 }
169
a9249b2e
VZ
170 int GetFamily() const
171 {
172 return m_family;
173 }
174
175 int GetStyle() const
176 {
177 return m_nativeFontInfoOk ? m_nativeFontInfo.GetStyle()
178 : m_style;
179 }
180
181 int GetWeight() const
182 {
183 return m_nativeFontInfoOk ? m_nativeFontInfo.GetWeight()
184 : m_weight;
185 }
186
187 bool GetUnderlined() const
188 {
189 return m_nativeFontInfoOk ? m_nativeFontInfo.GetUnderlined()
190 : m_underlined;
191 }
192
193 wxString GetFaceName() const
194 {
195 wxString s;
196 if ( m_nativeFontInfoOk )
197 s = m_nativeFontInfo.GetFaceName();
198 else
199 s = m_faceName;
200
201 return s;
202 }
203
204 wxFontEncoding GetEncoding() const
205 {
206 return m_nativeFontInfoOk ? m_nativeFontInfo.GetEncoding()
207 : m_encoding;
208 }
209
8e34db1d
VZ
210 WXHFONT GetHFONT(const wxFont *font) const
211 {
212 if ( !m_hFont )
213 wx_const_cast(wxFontRefData *, this)->Alloc(font);
214
215 return (WXHFONT)m_hFont;
216 }
217
218 bool HasHFONT() const
219 {
220 return m_hFont != 0;
221 }
a9249b2e 222
8e34db1d
VZ
223 // ... and setters: notice that all of them invalidate the currently
224 // allocated HFONT, if any, so that the next call to GetHFONT() recreates a
225 // new one
a9249b2e
VZ
226 void SetPointSize(int pointSize)
227 {
8e34db1d
VZ
228 Free();
229
a9249b2e 230 if ( m_nativeFontInfoOk )
544229d1 231 {
a9249b2e 232 m_nativeFontInfo.SetPointSize(pointSize);
544229d1 233 }
a9249b2e 234 else
544229d1 235 {
a9249b2e 236 m_pointSize = pointSize;
8b5d5223 237 m_sizeUsingPixels = false;
544229d1
VZ
238 }
239 }
240
241 void SetPixelSize(const wxSize& pixelSize)
242 {
8e34db1d
VZ
243 Free();
244
544229d1
VZ
245 if ( m_nativeFontInfoOk )
246 {
247 m_nativeFontInfo.SetPixelSize(pixelSize);
248 }
249 else
250 {
251 m_pixelSize = pixelSize;
8b5d5223 252 m_sizeUsingPixels = true;
544229d1 253 }
a9249b2e
VZ
254 }
255
256 void SetFamily(int family)
257 {
8e34db1d
VZ
258 Free();
259
a9249b2e
VZ
260 m_family = family;
261 }
262
263 void SetStyle(int style)
264 {
8e34db1d
VZ
265 Free();
266
a9249b2e
VZ
267 if ( m_nativeFontInfoOk )
268 m_nativeFontInfo.SetStyle((wxFontStyle)style);
269 else
270 m_style = style;
271 }
272
273 void SetWeight(int weight)
274 {
8e34db1d
VZ
275 Free();
276
a9249b2e
VZ
277 if ( m_nativeFontInfoOk )
278 m_nativeFontInfo.SetWeight((wxFontWeight)weight);
279 else
280 m_weight = weight;
281 }
282
85ab460e 283 bool SetFaceName(const wxString& faceName)
a9249b2e 284 {
8e34db1d
VZ
285 Free();
286
a9249b2e 287 if ( m_nativeFontInfoOk )
85ab460e
VZ
288 return m_nativeFontInfo.SetFaceName(faceName);
289
164e8d41 290 m_faceName = faceName;
85ab460e 291 return true;
a9249b2e
VZ
292 }
293
294 void SetUnderlined(bool underlined)
295 {
8e34db1d
VZ
296 Free();
297
a9249b2e
VZ
298 if ( m_nativeFontInfoOk )
299 m_nativeFontInfo.SetUnderlined(underlined);
300 else
301 m_underlined = underlined;
302 }
303
304 void SetEncoding(wxFontEncoding encoding)
305 {
8e34db1d
VZ
306 Free();
307
a9249b2e
VZ
308 if ( m_nativeFontInfoOk )
309 m_nativeFontInfo.SetEncoding(encoding);
310 else
311 m_encoding = encoding;
312 }
313
8e34db1d 314 // native font info
a9249b2e
VZ
315 bool HasNativeFontInfo() const { return m_nativeFontInfoOk; }
316
317 const wxNativeFontInfo& GetNativeFontInfo() const
318 { return m_nativeFontInfo; }
319
8e34db1d
VZ
320 void SetNativeFontInfo(const wxNativeFontInfo& nativeFontInfo)
321 { Free(); m_nativeFontInfo = nativeFontInfo; }
322
0c5d3e1c
VZ
323protected:
324 // common part of all ctors
325 void Init(int size,
544229d1
VZ
326 const wxSize& pixelSize,
327 bool sizeUsingPixels,
0c5d3e1c
VZ
328 int family,
329 int style,
330 int weight,
331 bool underlined,
332 const wxString& faceName,
333 wxFontEncoding encoding);
334
04ef50df 335 void Init(const wxNativeFontInfo& info, WXHFONT hFont = 0);
09fcd889 336
8e34db1d 337 // font characteristics
0c5d3e1c 338 int m_pointSize;
544229d1
VZ
339 wxSize m_pixelSize;
340 bool m_sizeUsingPixels;
0c5d3e1c
VZ
341 int m_family;
342 int m_style;
343 int m_weight;
344 bool m_underlined;
345 wxString m_faceName;
346 wxFontEncoding m_encoding;
347
8e34db1d
VZ
348 // Windows font handle, created on demand in GetHFONT()
349 HFONT m_hFont;
789034a0 350
09fcd889
VZ
351 // Native font info
352 wxNativeFontInfo m_nativeFontInfo;
353 bool m_nativeFontInfoOk;
0c5d3e1c
VZ
354};
355
68c95704 356#define M_FONTDATA ((wxFontRefData*)m_refData)
873fd4af 357
0c5d3e1c
VZ
358// ============================================================================
359// implementation
360// ============================================================================
361
362// ----------------------------------------------------------------------------
363// wxFontRefData
364// ----------------------------------------------------------------------------
365
366void wxFontRefData::Init(int pointSize,
544229d1
VZ
367 const wxSize& pixelSize,
368 bool sizeUsingPixels,
0c5d3e1c
VZ
369 int family,
370 int style,
371 int weight,
372 bool underlined,
373 const wxString& faceName,
374 wxFontEncoding encoding)
b823f5a1 375{
b9b3ccd9 376 m_style = style;
a9249b2e 377 m_pointSize = pointSize == -1 ? wxNORMAL_FONT->GetPointSize() : pointSize;
544229d1
VZ
378 m_pixelSize = pixelSize;
379 m_sizeUsingPixels = sizeUsingPixels;
b9b3ccd9
VZ
380 m_family = family;
381 m_style = style;
382 m_weight = weight;
383 m_underlined = underlined;
384 m_faceName = faceName;
0c5d3e1c
VZ
385 m_encoding = encoding;
386
b9b3ccd9 387 m_hFont = 0;
789034a0 388
cbe874bd 389 m_nativeFontInfoOk = false;
09fcd889
VZ
390}
391
04ef50df 392void wxFontRefData::Init(const wxNativeFontInfo& info, WXHFONT hFont)
09fcd889 393{
04ef50df
JS
394 // hFont may be zero, or it be passed in case we really want to
395 // use the exact font created in the underlying system
396 // (for example where we can't guarantee conversion from HFONT
397 // to LOGFONT back to HFONT)
8e34db1d 398 m_hFont = (HFONT)hFont;
789034a0 399
cbe874bd 400 m_nativeFontInfoOk = true;
09fcd889 401 m_nativeFontInfo = info;
93692400
JS
402 // This is the best we can do since we don't have the
403 // correct information at this point.
404 m_family = wxSWISS;
b823f5a1
JS
405}
406
0c5d3e1c 407wxFontRefData::~wxFontRefData()
a9249b2e
VZ
408{
409 Free();
410}
411
8e34db1d 412bool wxFontRefData::Alloc(const wxFont *font)
a9249b2e
VZ
413{
414 if ( !m_nativeFontInfoOk )
415 {
416 wxFillLogFont(&m_nativeFontInfo.lf, font);
cbe874bd 417 m_nativeFontInfoOk = true;
a9249b2e
VZ
418 }
419
8e34db1d
VZ
420 m_hFont = ::CreateFontIndirect(&m_nativeFontInfo.lf);
421 if ( !m_hFont )
a9249b2e
VZ
422 {
423 wxLogLastError(wxT("CreateFont"));
cbe874bd 424 return false;
a9249b2e
VZ
425 }
426
cbe874bd 427 return true;
a9249b2e
VZ
428}
429
430void wxFontRefData::Free()
2bda0e17 431{
b9b3ccd9 432 if ( m_hFont )
0c5d3e1c 433 {
8e34db1d 434 if ( !::DeleteObject(m_hFont) )
0c5d3e1c 435 {
f6bcfd97 436 wxLogLastError(wxT("DeleteObject(font)"));
0c5d3e1c 437 }
a9249b2e
VZ
438
439 m_hFont = 0;
0c5d3e1c 440 }
2bda0e17
KB
441}
442
09fcd889
VZ
443// ----------------------------------------------------------------------------
444// wxNativeFontInfo
445// ----------------------------------------------------------------------------
446
a9249b2e
VZ
447void wxNativeFontInfo::Init()
448{
449 wxZeroMemory(lf);
64c1effe
VZ
450
451 // we get better font quality if we use this instead of DEFAULT_QUALITY
452 // apparently without any drawbacks
99ae6124
WS
453#ifdef __WXWINCE__
454 lf.lfQuality = CLEARTYPE_QUALITY;
455#else
64c1effe 456 lf.lfQuality = PROOF_QUALITY;
99ae6124 457#endif
a9249b2e
VZ
458}
459
460int wxNativeFontInfo::GetPointSize() const
461{
7936354d
VZ
462 // FIXME: using the screen here results in incorrect font size calculation
463 // for printing!
a9249b2e
VZ
464 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
465
466 return (int) (((72.0*(double)abs(lf.lfHeight)) / (double) ppInch) + 0.5);
467}
468
544229d1
VZ
469wxSize wxNativeFontInfo::GetPixelSize() const
470{
471 wxSize ret;
472 ret.SetHeight(lf.lfHeight);
473 ret.SetWidth(lf.lfWidth);
474 return ret;
475}
476
a9249b2e
VZ
477wxFontStyle wxNativeFontInfo::GetStyle() const
478{
479 return lf.lfItalic ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
480}
481
482wxFontWeight wxNativeFontInfo::GetWeight() const
483{
484 if ( lf.lfWeight <= 300 )
485 return wxFONTWEIGHT_LIGHT;
486
487 if ( lf.lfWeight >= 600 )
488 return wxFONTWEIGHT_BOLD;
489
490 return wxFONTWEIGHT_NORMAL;
491}
492
493bool wxNativeFontInfo::GetUnderlined() const
494{
495 return lf.lfUnderline != 0;
496}
497
498wxString wxNativeFontInfo::GetFaceName() const
499{
500 return lf.lfFaceName;
501}
502
36e2bb4e
RD
503wxFontFamily wxNativeFontInfo::GetFamily() const
504{
9cf8de4c 505 wxFontFamily family;
36e2bb4e 506
9cf8de4c
VZ
507 // extract family from pitch-and-family
508 switch ( lf.lfPitchAndFamily & ~PITCH_MASK )
36e2bb4e
RD
509 {
510 case FF_ROMAN:
9cf8de4c 511 family = wxFONTFAMILY_ROMAN;
36e2bb4e
RD
512 break;
513
9cf8de4c
VZ
514 default:
515 wxFAIL_MSG( _T("unknown LOGFONT::lfFamily value") );
516 // fall through
517
36e2bb4e 518 case FF_SWISS:
9cf8de4c 519 family = wxFONTFAMILY_SWISS;
36e2bb4e
RD
520 break;
521
522 case FF_SCRIPT:
9cf8de4c 523 family = wxFONTFAMILY_SCRIPT;
36e2bb4e
RD
524 break;
525
526 case FF_MODERN:
9cf8de4c 527 family = wxFONTFAMILY_MODERN;
36e2bb4e
RD
528 break;
529
530 case FF_DECORATIVE:
9cf8de4c 531 family = wxFONTFAMILY_DECORATIVE;
36e2bb4e 532 break;
36e2bb4e 533 }
9cf8de4c
VZ
534
535 return family;
36e2bb4e
RD
536}
537
a9249b2e
VZ
538wxFontEncoding wxNativeFontInfo::GetEncoding() const
539{
540 return wxGetFontEncFromCharSet(lf.lfCharSet);
541}
542
543void wxNativeFontInfo::SetPointSize(int pointsize)
544{
7936354d
VZ
545 // FIXME: using the screen here results in incorrect font size calculation
546 // for printing!
a9249b2e
VZ
547 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
548
549 lf.lfHeight = -(int)((pointsize*((double)ppInch)/72.0) + 0.5);
550}
551
544229d1
VZ
552void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize)
553{
554 lf.lfHeight = pixelSize.GetHeight();
555 lf.lfWidth = pixelSize.GetWidth();
556}
557
558
a9249b2e
VZ
559void wxNativeFontInfo::SetStyle(wxFontStyle style)
560{
561 switch ( style )
562 {
563 default:
564 wxFAIL_MSG( _T("unknown font style") );
565 // fall through
566
567 case wxFONTSTYLE_NORMAL:
a38d0585 568 lf.lfItalic = FALSE;
a9249b2e
VZ
569 break;
570
571 case wxFONTSTYLE_ITALIC:
572 case wxFONTSTYLE_SLANT:
573 lf.lfItalic = TRUE;
574 break;
575 }
576}
577
578void wxNativeFontInfo::SetWeight(wxFontWeight weight)
579{
580 switch ( weight )
581 {
582 default:
583 wxFAIL_MSG( _T("unknown font weight") );
584 // fall through
585
586 case wxFONTWEIGHT_NORMAL:
587 lf.lfWeight = FW_NORMAL;
588 break;
589
590 case wxFONTWEIGHT_LIGHT:
591 lf.lfWeight = FW_LIGHT;
592 break;
593
594 case wxFONTWEIGHT_BOLD:
595 lf.lfWeight = FW_BOLD;
596 break;
597 }
598}
599
600void wxNativeFontInfo::SetUnderlined(bool underlined)
601{
602 lf.lfUnderline = underlined;
603}
604
85ab460e 605bool wxNativeFontInfo::SetFaceName(const wxString& facename)
a9249b2e 606{
85ab460e
VZ
607 size_t len = WXSIZEOF(lf.lfFaceName);
608 wxStrncpy(lf.lfFaceName, facename, len);
609 lf.lfFaceName[len - 1] = '\0'; // truncate the face name
610 return true;
a9249b2e
VZ
611}
612
7936354d
VZ
613void wxNativeFontInfo::SetFamily(wxFontFamily family)
614{
373a5fb3 615 BYTE ff_family;
85ab460e
VZ
616 wxArrayString facename;
617
48a1108e 618 // the list of fonts associated with a family was partially
85ab460e 619 // taken from http://www.codestyle.org/css/font-family
7936354d
VZ
620
621 switch ( family )
622 {
623 case wxSCRIPT:
624 ff_family = FF_SCRIPT;
85ab460e
VZ
625 facename.Add(_T("Script"));
626 facename.Add(_T("Brush Script MT"));
627 facename.Add(_T("Comic Sans MS"));
628 facename.Add(_T("Lucida Handwriting"));
7936354d
VZ
629 break;
630
631 case wxDECORATIVE:
632 ff_family = FF_DECORATIVE;
85ab460e
VZ
633 facename.Add(_T("Old English Text MT"));
634 facename.Add(_T("Comic Sans MS"));
635 facename.Add(_T("Lucida Handwriting"));
7936354d
VZ
636 break;
637
638 case wxROMAN:
639 ff_family = FF_ROMAN;
85ab460e
VZ
640 facename.Add(_T("Times New Roman"));
641 facename.Add(_T("Georgia"));
642 facename.Add(_T("Garamond"));
643 facename.Add(_T("Bookman Old Style"));
644 facename.Add(_T("Book Antiqua"));
7936354d
VZ
645 break;
646
647 case wxTELETYPE:
648 case wxMODERN:
649 ff_family = FF_MODERN;
85ab460e
VZ
650 facename.Add(_T("Courier New"));
651 facename.Add(_T("Lucida Console"));
652 facename.Add(_T("Andale Mono"));
653 facename.Add(_T("OCR A Extended"));
654 facename.Add(_T("Terminal"));
7936354d
VZ
655 break;
656
657 case wxSWISS:
658 ff_family = FF_SWISS;
85ab460e
VZ
659 facename.Add(_T("Arial"));
660 facename.Add(_T("Century Gothic"));
661 facename.Add(_T("Lucida Sans Unicode"));
662 facename.Add(_T("Tahoma"));
663 facename.Add(_T("Trebuchet MS"));
664 facename.Add(_T("Verdana"));
7936354d
VZ
665 break;
666
667 case wxDEFAULT:
668 default:
b4772c24
JS
669 {
670 // We want Windows 2000 or later to have new fonts even MS Shell Dlg
671 // is returned as default GUI font for compatibility
672 int verMaj;
7936354d 673 ff_family = FF_SWISS;
406d283a 674 if(wxGetOsVersion(&verMaj) == wxOS_WINDOWS_NT && verMaj >= 5)
85ab460e 675 facename.Add(_T("MS Shell Dlg 2"));
b4772c24 676 else
85ab460e
VZ
677 facename.Add(_T("MS Shell Dlg"));
678
679 // Quoting the MSDN:
48a1108e
WS
680 // "MS Shell Dlg is a mapping mechanism that enables
681 // U.S. English Microsoft Windows NT, and Microsoft Windows 2000 to
682 // support locales that have characters that are not contained in code
85ab460e 683 // page 1252. It is not a font but a face name for a nonexistent font."
b4772c24 684 }
7936354d
VZ
685 }
686
5c519b6c 687 lf.lfPitchAndFamily = (BYTE)(DEFAULT_PITCH) | ff_family;
7936354d
VZ
688
689 if ( !wxStrlen(lf.lfFaceName) )
690 {
691 SetFaceName(facename);
692 }
693}
694
a9249b2e
VZ
695void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding)
696{
697 wxNativeEncodingInfo info;
698 if ( !wxGetNativeFontEncoding(encoding, &info) )
699 {
bff67a6a 700#if wxUSE_FONTMAP
142b3bc2 701 if ( wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
e7e52b6d
VZ
702 {
703 if ( !info.facename.empty() )
704 {
705 // if we have this encoding only in some particular facename, use
706 // the facename - it is better to show the correct characters in a
707 // wrong facename than unreadable text in a correct one
708 SetFaceName(info.facename);
709 }
710 }
711 else
bff67a6a
VZ
712#endif // wxUSE_FONTMAP
713 {
714 // unsupported encoding, replace with the default
9cf8de4c 715 info.charset = DEFAULT_CHARSET;
bff67a6a 716 }
a9249b2e
VZ
717 }
718
373a5fb3 719 lf.lfCharSet = (BYTE)info.charset;
a9249b2e
VZ
720}
721
09fcd889
VZ
722bool wxNativeFontInfo::FromString(const wxString& s)
723{
724 long l;
725
726 wxStringTokenizer tokenizer(s, _T(";"));
727
a9249b2e 728 // first the version
09fcd889 729 wxString token = tokenizer.GetNextToken();
a9249b2e 730 if ( token != _T('0') )
cbe874bd 731 return false;
09fcd889
VZ
732
733 token = tokenizer.GetNextToken();
734 if ( !token.ToLong(&l) )
cbe874bd 735 return false;
09fcd889
VZ
736 lf.lfHeight = l;
737
738 token = tokenizer.GetNextToken();
739 if ( !token.ToLong(&l) )
cbe874bd 740 return false;
09fcd889
VZ
741 lf.lfWidth = l;
742
743 token = tokenizer.GetNextToken();
744 if ( !token.ToLong(&l) )
cbe874bd 745 return false;
09fcd889
VZ
746 lf.lfEscapement = l;
747
748 token = tokenizer.GetNextToken();
749 if ( !token.ToLong(&l) )
cbe874bd 750 return false;
09fcd889
VZ
751 lf.lfOrientation = l;
752
753 token = tokenizer.GetNextToken();
754 if ( !token.ToLong(&l) )
cbe874bd 755 return false;
09fcd889
VZ
756 lf.lfWeight = l;
757
758 token = tokenizer.GetNextToken();
759 if ( !token.ToLong(&l) )
cbe874bd 760 return false;
33ac7e6f 761 lf.lfItalic = (BYTE)l;
09fcd889
VZ
762
763 token = tokenizer.GetNextToken();
764 if ( !token.ToLong(&l) )
cbe874bd 765 return false;
33ac7e6f 766 lf.lfUnderline = (BYTE)l;
09fcd889
VZ
767
768 token = tokenizer.GetNextToken();
769 if ( !token.ToLong(&l) )
cbe874bd 770 return false;
33ac7e6f 771 lf.lfStrikeOut = (BYTE)l;
09fcd889
VZ
772
773 token = tokenizer.GetNextToken();
774 if ( !token.ToLong(&l) )
cbe874bd 775 return false;
33ac7e6f 776 lf.lfCharSet = (BYTE)l;
09fcd889
VZ
777
778 token = tokenizer.GetNextToken();
779 if ( !token.ToLong(&l) )
cbe874bd 780 return false;
33ac7e6f 781 lf.lfOutPrecision = (BYTE)l;
09fcd889
VZ
782
783 token = tokenizer.GetNextToken();
784 if ( !token.ToLong(&l) )
cbe874bd 785 return false;
33ac7e6f 786 lf.lfClipPrecision = (BYTE)l;
09fcd889
VZ
787
788 token = tokenizer.GetNextToken();
789 if ( !token.ToLong(&l) )
cbe874bd 790 return false;
33ac7e6f 791 lf.lfQuality = (BYTE)l;
09fcd889
VZ
792
793 token = tokenizer.GetNextToken();
794 if ( !token.ToLong(&l) )
cbe874bd 795 return false;
33ac7e6f 796 lf.lfPitchAndFamily = (BYTE)l;
09fcd889
VZ
797
798 token = tokenizer.GetNextToken();
799 if(!token)
cbe874bd 800 return false;
09fcd889
VZ
801 wxStrcpy(lf.lfFaceName, token.c_str());
802
cbe874bd 803 return true;
09fcd889
VZ
804}
805
806wxString wxNativeFontInfo::ToString() const
807{
808 wxString s;
809
4244c20b 810 s.Printf(_T("%d;%ld;%ld;%ld;%ld;%ld;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
09fcd889
VZ
811 0, // version, in case we want to change the format later
812 lf.lfHeight,
813 lf.lfWidth,
814 lf.lfEscapement,
815 lf.lfOrientation,
816 lf.lfWeight,
817 lf.lfItalic,
818 lf.lfUnderline,
819 lf.lfStrikeOut,
820 lf.lfCharSet,
821 lf.lfOutPrecision,
822 lf.lfClipPrecision,
823 lf.lfQuality,
824 lf.lfPitchAndFamily,
c9f78968 825 (const wxChar*)lf.lfFaceName);
09fcd889
VZ
826
827 return s;
828}
829
0c5d3e1c
VZ
830// ----------------------------------------------------------------------------
831// wxFont
832// ----------------------------------------------------------------------------
833
04ef50df 834bool wxFont::Create(const wxNativeFontInfo& info, WXHFONT hFont)
76e23cdb 835{
09fcd889
VZ
836 UnRef();
837
04ef50df 838 m_refData = new wxFontRefData(info, hFont);
09fcd889 839
adbd3cbc 840 return RealizeResource();
76e23cdb
VZ
841}
842
843wxFont::wxFont(const wxString& fontdesc)
844{
845 wxNativeFontInfo info;
846 if ( info.FromString(fontdesc) )
847 (void)Create(info);
848}
849
df455719
VZ
850bool wxFont::DoCreate(int pointSize,
851 const wxSize& pixelSize,
852 bool sizeUsingPixels,
853 int family,
854 int style,
855 int weight,
856 bool underlined,
857 const wxString& faceName,
858 wxFontEncoding encoding)
2bda0e17 859{
0c5d3e1c 860 UnRef();
3ca6a5f0
BP
861
862 // wxDEFAULT is a valid value for the font size too so we must treat it
863 // specially here (otherwise the size would be 70 == wxDEFAULT value)
864 if ( pointSize == wxDEFAULT )
a9249b2e
VZ
865 {
866 pointSize = wxNORMAL_FONT->GetPointSize();
867 }
3ca6a5f0 868
544229d1
VZ
869 m_refData = new wxFontRefData(pointSize, pixelSize, sizeUsingPixels,
870 family, style, weight,
0c5d3e1c 871 underlined, faceName, encoding);
2bda0e17 872
adbd3cbc 873 return RealizeResource();
2bda0e17
KB
874}
875
876wxFont::~wxFont()
877{
2bda0e17
KB
878}
879
0c5d3e1c
VZ
880// ----------------------------------------------------------------------------
881// real implementation
882// ----------------------------------------------------------------------------
883
f030b28c
VZ
884wxObjectRefData *wxFont::CreateRefData() const
885{
886 return new wxFontRefData();
887}
888
889wxObjectRefData *wxFont::CloneRefData(const wxObjectRefData *data) const
890{
891 return new wxFontRefData(*wx_static_cast(const wxFontRefData *, data));
892}
893
0c5d3e1c 894bool wxFont::RealizeResource()
2bda0e17 895{
adbd3cbc
VZ
896 // don't do anything if we already have a valid font
897 if ( GetHFONT() )
cbe874bd 898 return true;
0c5d3e1c 899
a9249b2e 900 return M_FONTDATA->Alloc(this);
2bda0e17
KB
901}
902
33ac7e6f 903bool wxFont::FreeResource(bool WXUNUSED(force))
2bda0e17 904{
adbd3cbc
VZ
905 if ( !GetHFONT() )
906 return false;
0c5d3e1c 907
adbd3cbc 908 M_FONTDATA->Free();
a9249b2e 909
adbd3cbc 910 return true;
2bda0e17
KB
911}
912
2b5f62a0 913WXHANDLE wxFont::GetResourceHandle() const
f6bcfd97 914{
2b5f62a0 915 return (WXHANDLE)GetHFONT();
f6bcfd97
BP
916}
917
918WXHFONT wxFont::GetHFONT() const
2bda0e17 919{
8e34db1d 920 return M_FONTDATA ? M_FONTDATA->GetHFONT(this) : 0;
2bda0e17
KB
921}
922
e90babdf 923bool wxFont::IsFree() const
2bda0e17 924{
8e34db1d 925 return M_FONTDATA && !M_FONTDATA->HasHFONT();
adbd3cbc
VZ
926}
927
0c5d3e1c
VZ
928// ----------------------------------------------------------------------------
929// change font attribute: we recreate font when doing it
930// ----------------------------------------------------------------------------
931
debe6624 932void wxFont::SetPointSize(int pointSize)
2bda0e17 933{
f030b28c 934 AllocExclusive();
b823f5a1 935
8e34db1d 936 M_FONTDATA->Free();
a9249b2e 937 M_FONTDATA->SetPointSize(pointSize);
2bda0e17
KB
938}
939
544229d1
VZ
940void wxFont::SetPixelSize(const wxSize& pixelSize)
941{
f030b28c 942 AllocExclusive();
544229d1
VZ
943
944 M_FONTDATA->SetPixelSize(pixelSize);
544229d1
VZ
945}
946
debe6624 947void wxFont::SetFamily(int family)
2bda0e17 948{
f030b28c 949 AllocExclusive();
b823f5a1 950
a9249b2e 951 M_FONTDATA->SetFamily(family);
2bda0e17
KB
952}
953
debe6624 954void wxFont::SetStyle(int style)
2bda0e17 955{
f030b28c 956 AllocExclusive();
b823f5a1 957
a9249b2e 958 M_FONTDATA->SetStyle(style);
2bda0e17
KB
959}
960
debe6624 961void wxFont::SetWeight(int weight)
2bda0e17 962{
f030b28c 963 AllocExclusive();
b823f5a1 964
a9249b2e 965 M_FONTDATA->SetWeight(weight);
2bda0e17
KB
966}
967
85ab460e 968bool wxFont::SetFaceName(const wxString& faceName)
2bda0e17 969{
f030b28c 970 AllocExclusive();
b823f5a1 971
8e34db1d
VZ
972 if ( !M_FONTDATA->SetFaceName(faceName) )
973 return false;
85ab460e
VZ
974
975 // NB: using win32's GetObject() API on M_FONTDATA->GetHFONT()
976 // to retrieve a LOGFONT and then compare lf.lfFaceName
977 // with given facename is not reliable at all:
978 // Windows copies the facename given to ::CreateFontIndirect()
979 // without any validity check.
980 // Thus we use wxFontBase::SetFaceName to check if facename
981 // is valid...
8e34db1d 982 return wxFontBase::SetFaceName(faceName);
2bda0e17
KB
983}
984
debe6624 985void wxFont::SetUnderlined(bool underlined)
2bda0e17 986{
f030b28c 987 AllocExclusive();
b823f5a1 988
a9249b2e 989 M_FONTDATA->SetUnderlined(underlined);
2bda0e17
KB
990}
991
0c5d3e1c 992void wxFont::SetEncoding(wxFontEncoding encoding)
2bda0e17 993{
f030b28c 994 AllocExclusive();
0c5d3e1c 995
a9249b2e 996 M_FONTDATA->SetEncoding(encoding);
09fcd889
VZ
997}
998
9045ad9d 999void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info)
09fcd889 1000{
f030b28c 1001 AllocExclusive();
09fcd889 1002
8e34db1d 1003 M_FONTDATA->SetNativeFontInfo(info);
0c5d3e1c
VZ
1004}
1005
1006// ----------------------------------------------------------------------------
1007// accessors
1008// ----------------------------------------------------------------------------
1009
1010int wxFont::GetPointSize() const
1011{
789034a0
VZ
1012 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1013
a9249b2e 1014 return M_FONTDATA->GetPointSize();
0c5d3e1c
VZ
1015}
1016
544229d1
VZ
1017wxSize wxFont::GetPixelSize() const
1018{
68585e17
RD
1019 wxCHECK_MSG( Ok(), wxDefaultSize, wxT("invalid font") );
1020
544229d1
VZ
1021 return M_FONTDATA->GetPixelSize();
1022}
1023
1024bool wxFont::IsUsingSizeInPixels() const
1025{
1026 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1027
1028 return M_FONTDATA->IsUsingSizeInPixels();
1029}
1030
0c5d3e1c
VZ
1031int wxFont::GetFamily() const
1032{
789034a0
VZ
1033 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1034
a9249b2e 1035 return M_FONTDATA->GetFamily();
2bda0e17
KB
1036}
1037
0c5d3e1c 1038int wxFont::GetStyle() const
2bda0e17 1039{
789034a0
VZ
1040 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1041
a9249b2e 1042 return M_FONTDATA->GetStyle();
2bda0e17
KB
1043}
1044
0c5d3e1c 1045int wxFont::GetWeight() const
2bda0e17 1046{
789034a0
VZ
1047 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1048
a9249b2e 1049 return M_FONTDATA->GetWeight();
2bda0e17
KB
1050}
1051
0c5d3e1c
VZ
1052bool wxFont::GetUnderlined() const
1053{
cbe874bd 1054 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
789034a0 1055
a9249b2e 1056 return M_FONTDATA->GetUnderlined();
0c5d3e1c
VZ
1057}
1058
1059wxString wxFont::GetFaceName() const
1060{
fda7962d 1061 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
789034a0 1062
a9249b2e 1063 return M_FONTDATA->GetFaceName();
0c5d3e1c
VZ
1064}
1065
1066wxFontEncoding wxFont::GetEncoding() const
1067{
789034a0
VZ
1068 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
1069
a9249b2e 1070 return M_FONTDATA->GetEncoding();
0c5d3e1c 1071}
a1d58ddc 1072
3bf5a59b 1073const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
1e6feb95 1074{
68585e17 1075 return Ok() && M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
3bf5a59b 1076 : NULL;
09fcd889
VZ
1077}
1078
85ab460e
VZ
1079wxString wxFont::GetNativeFontInfoDesc() const
1080{
68585e17
RD
1081 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
1082
85ab460e
VZ
1083 // be sure we have an HFONT associated...
1084 wxConstCast(this, wxFont)->RealizeResource();
1085 return wxFontBase::GetNativeFontInfoDesc();
1086}
1087
1088wxString wxFont::GetNativeFontInfoUserDesc() const
1089{
68585e17
RD
1090 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
1091
85ab460e
VZ
1092 // be sure we have an HFONT associated...
1093 wxConstCast(this, wxFont)->RealizeResource();
1094 return wxFontBase::GetNativeFontInfoUserDesc();
1095}
1096
9cf8de4c
VZ
1097bool wxFont::IsFixedWidth() const
1098{
1099 if ( M_FONTDATA->HasNativeFontInfo() )
1100 {
1101 // the two low-order bits specify the pitch of the font, the rest is
1102 // family
907173e5
WS
1103 BYTE pitch =
1104 (BYTE)(M_FONTDATA->GetNativeFontInfo().lf.lfPitchAndFamily & PITCH_MASK);
9cf8de4c
VZ
1105
1106 return pitch == FIXED_PITCH;
1107 }
1108
1109 return wxFontBase::IsFixedWidth();
1110}