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