]> git.saurik.com Git - wxWidgets.git/blame - src/msw/font.cpp
Also update focus rect when changing selection in single selection mode, fixes #11332
[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 {
5414d62e
VZ
219 wxCHECK_RET( pixelSize.GetWidth() >= 0, "negative font width" );
220 wxCHECK_RET( pixelSize.GetHeight() != 0, "zero font height" );
221
8e34db1d
VZ
222 Free();
223
df898907
FM
224 m_nativeFontInfo.SetPixelSize(pixelSize);
225 m_sizeUsingPixels = true;
a9249b2e
VZ
226 }
227
0c14b6c3 228 void SetFamily(wxFontFamily family)
a9249b2e 229 {
8e34db1d
VZ
230 Free();
231
df898907 232 m_nativeFontInfo.SetFamily(family);
a9249b2e
VZ
233 }
234
0c14b6c3 235 void SetStyle(wxFontStyle style)
a9249b2e 236 {
8e34db1d
VZ
237 Free();
238
df898907 239 m_nativeFontInfo.SetStyle(style);
a9249b2e
VZ
240 }
241
0c14b6c3 242 void SetWeight(wxFontWeight weight)
a9249b2e 243 {
8e34db1d
VZ
244 Free();
245
df898907 246 m_nativeFontInfo.SetWeight(weight);
a9249b2e
VZ
247 }
248
85ab460e 249 bool SetFaceName(const wxString& faceName)
a9249b2e 250 {
8e34db1d
VZ
251 Free();
252
df898907 253 return m_nativeFontInfo.SetFaceName(faceName);
a9249b2e
VZ
254 }
255
256 void SetUnderlined(bool underlined)
257 {
8e34db1d
VZ
258 Free();
259
df898907 260 m_nativeFontInfo.SetUnderlined(underlined);
a9249b2e
VZ
261 }
262
263 void SetEncoding(wxFontEncoding encoding)
264 {
8e34db1d
VZ
265 Free();
266
df898907 267 m_nativeFontInfo.SetEncoding(encoding);
a9249b2e
VZ
268 }
269
a9249b2e
VZ
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
0572fce8 294 // are we using m_nativeFontInfo.lf.lfHeight for point size or pixel size?
df898907 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{
0572fce8
VZ
324 m_hFont = NULL;
325
544229d1 326 m_sizeUsingPixels = sizeUsingPixels;
0572fce8
VZ
327 if ( m_sizeUsingPixels )
328 SetPixelSize(pixelSize);
329 else
330 SetPointSize(pointSize);
df898907 331
0572fce8
VZ
332 SetStyle(style);
333 SetWeight(weight);
334 SetUnderlined(underlined);
0c5d3e1c 335
0572fce8
VZ
336 // set the family/facename
337 SetFamily(family);
338 if ( !faceName.empty() )
339 SetFaceName(faceName);
789034a0 340
0572fce8
VZ
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{
5414d62e
VZ
509 // MSW accepts both positive and negative heights here but they mean
510 // different things: positive specifies the cell height while negative
511 // specifies the character height. We used to just pass the value to MSW
512 // unchanged but changed the behaviour for positive values in 2.9.1 to
513 // match other ports and, more importantly, the expected behaviour. So now
514 // passing the negative height doesn't make sense at all any more but we
515 // still accept it for compatibility with the existing code which worked
516 // around the wrong interpretation of the height argument in older wxMSW
517 // versions by passing a negative value explicitly itself.
518 lf.lfHeight = -abs(pixelSize.GetHeight());
544229d1
VZ
519 lf.lfWidth = pixelSize.GetWidth();
520}
521
a9249b2e
VZ
522void wxNativeFontInfo::SetStyle(wxFontStyle style)
523{
524 switch ( style )
525 {
526 default:
df898907 527 wxFAIL_MSG( "unknown font style" );
a9249b2e
VZ
528 // fall through
529
530 case wxFONTSTYLE_NORMAL:
a38d0585 531 lf.lfItalic = FALSE;
a9249b2e
VZ
532 break;
533
534 case wxFONTSTYLE_ITALIC:
535 case wxFONTSTYLE_SLANT:
536 lf.lfItalic = TRUE;
537 break;
538 }
539}
540
541void wxNativeFontInfo::SetWeight(wxFontWeight weight)
542{
543 switch ( weight )
544 {
545 default:
df898907 546 wxFAIL_MSG( "unknown font weight" );
a9249b2e
VZ
547 // fall through
548
549 case wxFONTWEIGHT_NORMAL:
550 lf.lfWeight = FW_NORMAL;
551 break;
552
553 case wxFONTWEIGHT_LIGHT:
554 lf.lfWeight = FW_LIGHT;
555 break;
556
557 case wxFONTWEIGHT_BOLD:
558 lf.lfWeight = FW_BOLD;
559 break;
560 }
561}
562
563void wxNativeFontInfo::SetUnderlined(bool underlined)
564{
565 lf.lfUnderline = underlined;
566}
567
85ab460e 568bool wxNativeFontInfo::SetFaceName(const wxString& facename)
a9249b2e 569{
64accea5 570 wxStrlcpy(lf.lfFaceName, facename.c_str(), WXSIZEOF(lf.lfFaceName));
85ab460e 571 return true;
a9249b2e
VZ
572}
573
7936354d
VZ
574void wxNativeFontInfo::SetFamily(wxFontFamily family)
575{
373a5fb3 576 BYTE ff_family;
85ab460e
VZ
577 wxArrayString facename;
578
48a1108e 579 // the list of fonts associated with a family was partially
85ab460e 580 // taken from http://www.codestyle.org/css/font-family
7936354d
VZ
581
582 switch ( family )
583 {
df898907 584 case wxFONTFAMILY_SCRIPT:
7936354d 585 ff_family = FF_SCRIPT;
df898907
FM
586 facename.Add(wxS("Script"));
587 facename.Add(wxS("Brush Script MT"));
588 facename.Add(wxS("Comic Sans MS"));
589 facename.Add(wxS("Lucida Handwriting"));
7936354d
VZ
590 break;
591
df898907 592 case wxFONTFAMILY_DECORATIVE:
7936354d 593 ff_family = FF_DECORATIVE;
df898907
FM
594 facename.Add(wxS("Old English Text MT"));
595 facename.Add(wxS("Comic Sans MS"));
596 facename.Add(wxS("Lucida Handwriting"));
7936354d
VZ
597 break;
598
df898907 599 case wxFONTFAMILY_ROMAN:
7936354d 600 ff_family = FF_ROMAN;
df898907
FM
601 facename.Add(wxS("Times New Roman"));
602 facename.Add(wxS("Georgia"));
603 facename.Add(wxS("Garamond"));
604 facename.Add(wxS("Bookman Old Style"));
605 facename.Add(wxS("Book Antiqua"));
7936354d
VZ
606 break;
607
df898907
FM
608 case wxFONTFAMILY_TELETYPE:
609 case wxFONTFAMILY_MODERN:
7936354d 610 ff_family = FF_MODERN;
df898907
FM
611 facename.Add(wxS("Courier New"));
612 facename.Add(wxS("Lucida Console"));
613 facename.Add(wxS("Andale Mono"));
614 facename.Add(wxS("OCR A Extended"));
615 facename.Add(wxS("Terminal"));
7936354d
VZ
616 break;
617
df898907 618 case wxFONTFAMILY_SWISS:
7936354d 619 ff_family = FF_SWISS;
df898907
FM
620 facename.Add(wxS("Arial"));
621 facename.Add(wxS("Century Gothic"));
622 facename.Add(wxS("Lucida Sans Unicode"));
623 facename.Add(wxS("Tahoma"));
624 facename.Add(wxS("Trebuchet MS"));
625 facename.Add(wxS("Verdana"));
7936354d
VZ
626 break;
627
df898907 628 case wxFONTFAMILY_DEFAULT:
7936354d 629 default:
b4772c24
JS
630 {
631 // We want Windows 2000 or later to have new fonts even MS Shell Dlg
632 // is returned as default GUI font for compatibility
633 int verMaj;
7936354d 634 ff_family = FF_SWISS;
406d283a 635 if(wxGetOsVersion(&verMaj) == wxOS_WINDOWS_NT && verMaj >= 5)
df898907 636 facename.Add(wxS("MS Shell Dlg 2"));
b4772c24 637 else
df898907 638 facename.Add(wxS("MS Shell Dlg"));
85ab460e
VZ
639
640 // Quoting the MSDN:
48a1108e
WS
641 // "MS Shell Dlg is a mapping mechanism that enables
642 // U.S. English Microsoft Windows NT, and Microsoft Windows 2000 to
643 // support locales that have characters that are not contained in code
85ab460e 644 // page 1252. It is not a font but a face name for a nonexistent font."
b4772c24 645 }
7936354d
VZ
646 }
647
5c519b6c 648 lf.lfPitchAndFamily = (BYTE)(DEFAULT_PITCH) | ff_family;
7936354d 649
060c4f90
FM
650 // reset the facename so that CreateFontIndirect() will automatically choose a
651 // face name based only on the font family.
652 lf.lfFaceName[0] = '\0';
7936354d
VZ
653}
654
a9249b2e
VZ
655void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding)
656{
657 wxNativeEncodingInfo info;
658 if ( !wxGetNativeFontEncoding(encoding, &info) )
659 {
bff67a6a 660#if wxUSE_FONTMAP
142b3bc2 661 if ( wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
e7e52b6d
VZ
662 {
663 if ( !info.facename.empty() )
664 {
665 // if we have this encoding only in some particular facename, use
666 // the facename - it is better to show the correct characters in a
667 // wrong facename than unreadable text in a correct one
668 SetFaceName(info.facename);
669 }
670 }
671 else
bff67a6a
VZ
672#endif // wxUSE_FONTMAP
673 {
674 // unsupported encoding, replace with the default
9cf8de4c 675 info.charset = DEFAULT_CHARSET;
bff67a6a 676 }
a9249b2e
VZ
677 }
678
373a5fb3 679 lf.lfCharSet = (BYTE)info.charset;
a9249b2e
VZ
680}
681
09fcd889
VZ
682bool wxNativeFontInfo::FromString(const wxString& s)
683{
684 long l;
685
d508a9d9 686 wxStringTokenizer tokenizer(s, wxS(";"), wxTOKEN_RET_EMPTY_ALL);
09fcd889 687
a9249b2e 688 // first the version
09fcd889 689 wxString token = tokenizer.GetNextToken();
df898907 690 if ( token != wxS('0') )
cbe874bd 691 return false;
09fcd889
VZ
692
693 token = tokenizer.GetNextToken();
694 if ( !token.ToLong(&l) )
cbe874bd 695 return false;
09fcd889
VZ
696 lf.lfHeight = l;
697
698 token = tokenizer.GetNextToken();
699 if ( !token.ToLong(&l) )
cbe874bd 700 return false;
09fcd889
VZ
701 lf.lfWidth = l;
702
703 token = tokenizer.GetNextToken();
704 if ( !token.ToLong(&l) )
cbe874bd 705 return false;
09fcd889
VZ
706 lf.lfEscapement = l;
707
708 token = tokenizer.GetNextToken();
709 if ( !token.ToLong(&l) )
cbe874bd 710 return false;
09fcd889
VZ
711 lf.lfOrientation = l;
712
713 token = tokenizer.GetNextToken();
714 if ( !token.ToLong(&l) )
cbe874bd 715 return false;
09fcd889
VZ
716 lf.lfWeight = l;
717
718 token = tokenizer.GetNextToken();
719 if ( !token.ToLong(&l) )
cbe874bd 720 return false;
33ac7e6f 721 lf.lfItalic = (BYTE)l;
09fcd889
VZ
722
723 token = tokenizer.GetNextToken();
724 if ( !token.ToLong(&l) )
cbe874bd 725 return false;
33ac7e6f 726 lf.lfUnderline = (BYTE)l;
09fcd889
VZ
727
728 token = tokenizer.GetNextToken();
729 if ( !token.ToLong(&l) )
cbe874bd 730 return false;
33ac7e6f 731 lf.lfStrikeOut = (BYTE)l;
09fcd889
VZ
732
733 token = tokenizer.GetNextToken();
734 if ( !token.ToLong(&l) )
cbe874bd 735 return false;
33ac7e6f 736 lf.lfCharSet = (BYTE)l;
09fcd889
VZ
737
738 token = tokenizer.GetNextToken();
739 if ( !token.ToLong(&l) )
cbe874bd 740 return false;
33ac7e6f 741 lf.lfOutPrecision = (BYTE)l;
09fcd889
VZ
742
743 token = tokenizer.GetNextToken();
744 if ( !token.ToLong(&l) )
cbe874bd 745 return false;
33ac7e6f 746 lf.lfClipPrecision = (BYTE)l;
09fcd889
VZ
747
748 token = tokenizer.GetNextToken();
749 if ( !token.ToLong(&l) )
cbe874bd 750 return false;
33ac7e6f 751 lf.lfQuality = (BYTE)l;
09fcd889
VZ
752
753 token = tokenizer.GetNextToken();
754 if ( !token.ToLong(&l) )
cbe874bd 755 return false;
33ac7e6f 756 lf.lfPitchAndFamily = (BYTE)l;
09fcd889 757
d508a9d9 758 if ( !tokenizer.HasMoreTokens() )
cbe874bd 759 return false;
d508a9d9
VZ
760
761 // the face name may be empty
762 wxStrcpy(lf.lfFaceName, tokenizer.GetNextToken());
09fcd889 763
cbe874bd 764 return true;
09fcd889
VZ
765}
766
767wxString wxNativeFontInfo::ToString() const
768{
769 wxString s;
770
df898907 771 s.Printf(wxS("%d;%ld;%ld;%ld;%ld;%ld;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
09fcd889
VZ
772 0, // version, in case we want to change the format later
773 lf.lfHeight,
774 lf.lfWidth,
775 lf.lfEscapement,
776 lf.lfOrientation,
777 lf.lfWeight,
778 lf.lfItalic,
779 lf.lfUnderline,
780 lf.lfStrikeOut,
781 lf.lfCharSet,
782 lf.lfOutPrecision,
783 lf.lfClipPrecision,
784 lf.lfQuality,
785 lf.lfPitchAndFamily,
d508a9d9 786 lf.lfFaceName);
09fcd889
VZ
787
788 return s;
789}
790
0c5d3e1c
VZ
791// ----------------------------------------------------------------------------
792// wxFont
793// ----------------------------------------------------------------------------
794
d014871d
FM
795wxFont::wxFont(const wxString& fontdesc)
796{
797 wxNativeFontInfo info;
798 if ( info.FromString(fontdesc) )
799 (void)Create(info);
800}
801
04ef50df 802bool wxFont::Create(const wxNativeFontInfo& info, WXHFONT hFont)
76e23cdb 803{
09fcd889
VZ
804 UnRef();
805
04ef50df 806 m_refData = new wxFontRefData(info, hFont);
09fcd889 807
adbd3cbc 808 return RealizeResource();
76e23cdb
VZ
809}
810
df455719
VZ
811bool wxFont::DoCreate(int pointSize,
812 const wxSize& pixelSize,
813 bool sizeUsingPixels,
0c14b6c3
FM
814 wxFontFamily family,
815 wxFontStyle style,
816 wxFontWeight weight,
df455719
VZ
817 bool underlined,
818 const wxString& faceName,
819 wxFontEncoding encoding)
2bda0e17 820{
0c5d3e1c 821 UnRef();
3ca6a5f0
BP
822
823 // wxDEFAULT is a valid value for the font size too so we must treat it
824 // specially here (otherwise the size would be 70 == wxDEFAULT value)
825 if ( pointSize == wxDEFAULT )
a9249b2e
VZ
826 {
827 pointSize = wxNORMAL_FONT->GetPointSize();
828 }
3ca6a5f0 829
544229d1
VZ
830 m_refData = new wxFontRefData(pointSize, pixelSize, sizeUsingPixels,
831 family, style, weight,
0c5d3e1c 832 underlined, faceName, encoding);
2bda0e17 833
adbd3cbc 834 return RealizeResource();
2bda0e17
KB
835}
836
837wxFont::~wxFont()
838{
2bda0e17
KB
839}
840
0c5d3e1c
VZ
841// ----------------------------------------------------------------------------
842// real implementation
843// ----------------------------------------------------------------------------
844
8f884a0d 845wxGDIRefData *wxFont::CreateGDIRefData() const
f030b28c
VZ
846{
847 return new wxFontRefData();
848}
849
8f884a0d 850wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
f030b28c 851{
5c33522f 852 return new wxFontRefData(*static_cast<const wxFontRefData *>(data));
f030b28c
VZ
853}
854
0c5d3e1c 855bool wxFont::RealizeResource()
2bda0e17 856{
d014871d 857 // NOTE: the GetHFONT() call automatically triggers a reallocation of
0572fce8 858 // the HFONT if necessary (will do nothing if we already have the resource);
d014871d
FM
859 // it returns NULL only if there is a failure in wxFontRefData::Alloc()...
860 return GetHFONT() != NULL;
2bda0e17
KB
861}
862
33ac7e6f 863bool wxFont::FreeResource(bool WXUNUSED(force))
2bda0e17 864{
d014871d 865 if ( !M_FONTDATA )
adbd3cbc 866 return false;
0c5d3e1c 867
adbd3cbc 868 M_FONTDATA->Free();
a9249b2e 869
adbd3cbc 870 return true;
2bda0e17
KB
871}
872
2b5f62a0 873WXHANDLE wxFont::GetResourceHandle() const
f6bcfd97 874{
2b5f62a0 875 return (WXHANDLE)GetHFONT();
f6bcfd97
BP
876}
877
878WXHFONT wxFont::GetHFONT() const
2bda0e17 879{
d014871d
FM
880 // NOTE: wxFontRefData::GetHFONT() will automatically call
881 // wxFontRefData::Alloc() if necessary
df898907 882 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
2bda0e17
KB
883}
884
e90babdf 885bool wxFont::IsFree() const
2bda0e17 886{
8e34db1d 887 return M_FONTDATA && !M_FONTDATA->HasHFONT();
adbd3cbc
VZ
888}
889
0c5d3e1c
VZ
890// ----------------------------------------------------------------------------
891// change font attribute: we recreate font when doing it
892// ----------------------------------------------------------------------------
893
debe6624 894void wxFont::SetPointSize(int pointSize)
2bda0e17 895{
f030b28c 896 AllocExclusive();
b823f5a1 897
8e34db1d 898 M_FONTDATA->Free();
a9249b2e 899 M_FONTDATA->SetPointSize(pointSize);
2bda0e17
KB
900}
901
544229d1
VZ
902void wxFont::SetPixelSize(const wxSize& pixelSize)
903{
f030b28c 904 AllocExclusive();
544229d1
VZ
905
906 M_FONTDATA->SetPixelSize(pixelSize);
544229d1
VZ
907}
908
0c14b6c3 909void wxFont::SetFamily(wxFontFamily family)
2bda0e17 910{
f030b28c 911 AllocExclusive();
b823f5a1 912
a9249b2e 913 M_FONTDATA->SetFamily(family);
2bda0e17
KB
914}
915
0c14b6c3 916void wxFont::SetStyle(wxFontStyle style)
2bda0e17 917{
f030b28c 918 AllocExclusive();
b823f5a1 919
a9249b2e 920 M_FONTDATA->SetStyle(style);
2bda0e17
KB
921}
922
0c14b6c3 923void wxFont::SetWeight(wxFontWeight weight)
2bda0e17 924{
f030b28c 925 AllocExclusive();
b823f5a1 926
a9249b2e 927 M_FONTDATA->SetWeight(weight);
2bda0e17
KB
928}
929
85ab460e 930bool wxFont::SetFaceName(const wxString& faceName)
2bda0e17 931{
f030b28c 932 AllocExclusive();
b823f5a1 933
8e34db1d
VZ
934 if ( !M_FONTDATA->SetFaceName(faceName) )
935 return false;
85ab460e
VZ
936
937 // NB: using win32's GetObject() API on M_FONTDATA->GetHFONT()
938 // to retrieve a LOGFONT and then compare lf.lfFaceName
939 // with given facename is not reliable at all:
940 // Windows copies the facename given to ::CreateFontIndirect()
941 // without any validity check.
942 // Thus we use wxFontBase::SetFaceName to check if facename
943 // is valid...
8e34db1d 944 return wxFontBase::SetFaceName(faceName);
2bda0e17
KB
945}
946
debe6624 947void wxFont::SetUnderlined(bool underlined)
2bda0e17 948{
f030b28c 949 AllocExclusive();
b823f5a1 950
a9249b2e 951 M_FONTDATA->SetUnderlined(underlined);
2bda0e17
KB
952}
953
0c5d3e1c 954void wxFont::SetEncoding(wxFontEncoding encoding)
2bda0e17 955{
f030b28c 956 AllocExclusive();
0c5d3e1c 957
a9249b2e 958 M_FONTDATA->SetEncoding(encoding);
09fcd889
VZ
959}
960
9045ad9d 961void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info)
09fcd889 962{
f030b28c 963 AllocExclusive();
09fcd889 964
8e34db1d 965 M_FONTDATA->SetNativeFontInfo(info);
0c5d3e1c
VZ
966}
967
968// ----------------------------------------------------------------------------
969// accessors
970// ----------------------------------------------------------------------------
971
972int wxFont::GetPointSize() const
973{
d014871d 974 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
789034a0 975
a9249b2e 976 return M_FONTDATA->GetPointSize();
0c5d3e1c
VZ
977}
978
544229d1
VZ
979wxSize wxFont::GetPixelSize() const
980{
d014871d 981 wxCHECK_MSG( IsOk(), wxDefaultSize, wxT("invalid font") );
68585e17 982
544229d1
VZ
983 return M_FONTDATA->GetPixelSize();
984}
985
986bool wxFont::IsUsingSizeInPixels() const
987{
d014871d 988 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
544229d1
VZ
989
990 return M_FONTDATA->IsUsingSizeInPixels();
991}
992
0c14b6c3 993wxFontFamily wxFont::GetFamily() const
0c5d3e1c 994{
d014871d 995 wxCHECK_MSG( IsOk(), wxFONTFAMILY_MAX, wxT("invalid font") );
789034a0 996
a9249b2e 997 return M_FONTDATA->GetFamily();
2bda0e17
KB
998}
999
0c14b6c3 1000wxFontStyle wxFont::GetStyle() const
2bda0e17 1001{
d014871d 1002 wxCHECK_MSG( IsOk(), wxFONTSTYLE_MAX, wxT("invalid font") );
789034a0 1003
a9249b2e 1004 return M_FONTDATA->GetStyle();
2bda0e17
KB
1005}
1006
0c14b6c3 1007wxFontWeight wxFont::GetWeight() const
2bda0e17 1008{
d014871d 1009 wxCHECK_MSG( IsOk(), wxFONTWEIGHT_MAX, wxT("invalid font") );
789034a0 1010
a9249b2e 1011 return M_FONTDATA->GetWeight();
2bda0e17
KB
1012}
1013
0c5d3e1c
VZ
1014bool wxFont::GetUnderlined() const
1015{
d014871d 1016 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
789034a0 1017
a9249b2e 1018 return M_FONTDATA->GetUnderlined();
0c5d3e1c
VZ
1019}
1020
1021wxString wxFont::GetFaceName() const
1022{
d014871d 1023 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
789034a0 1024
a9249b2e 1025 return M_FONTDATA->GetFaceName();
0c5d3e1c
VZ
1026}
1027
1028wxFontEncoding wxFont::GetEncoding() const
1029{
d014871d 1030 wxCHECK_MSG( IsOk(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
789034a0 1031
a9249b2e 1032 return M_FONTDATA->GetEncoding();
0c5d3e1c 1033}
a1d58ddc 1034
3bf5a59b 1035const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
1e6feb95 1036{
7c6e85dc 1037 return IsOk() ? &(M_FONTDATA->GetNativeFontInfo()) : NULL;
09fcd889
VZ
1038}
1039
85ab460e
VZ
1040wxString wxFont::GetNativeFontInfoDesc() const
1041{
d014871d 1042 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
68585e17 1043
85ab460e 1044 // be sure we have an HFONT associated...
d014871d 1045 const_cast<wxFont*>(this)->RealizeResource();
85ab460e
VZ
1046 return wxFontBase::GetNativeFontInfoDesc();
1047}
1048
1049wxString wxFont::GetNativeFontInfoUserDesc() const
1050{
d014871d 1051 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
68585e17 1052
85ab460e 1053 // be sure we have an HFONT associated...
d014871d 1054 const_cast<wxFont*>(this)->RealizeResource();
85ab460e
VZ
1055 return wxFontBase::GetNativeFontInfoUserDesc();
1056}
1057
9cf8de4c
VZ
1058bool wxFont::IsFixedWidth() const
1059{
d014871d
FM
1060 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
1061
7c6e85dc
VZ
1062 // the two low-order bits specify the pitch of the font, the rest is
1063 // family
1064 BYTE pitch =
1065 (BYTE)(M_FONTDATA->GetNativeFontInfo().lf.lfPitchAndFamily & PITCH_MASK);
9cf8de4c 1066
7c6e85dc 1067 return pitch == FIXED_PITCH;
9cf8de4c 1068}