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