]> git.saurik.com Git - wxWidgets.git/blame - src/msw/font.cpp
deal with the fonts without any specified face name in wxNativeFontInfo::To/FromUserS...
[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
df898907 680 wxStringTokenizer tokenizer(s, wxS(";"));
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
VZ
751
752 token = tokenizer.GetNextToken();
753 if(!token)
cbe874bd 754 return false;
09fcd889
VZ
755 wxStrcpy(lf.lfFaceName, token.c_str());
756
cbe874bd 757 return true;
09fcd889
VZ
758}
759
760wxString wxNativeFontInfo::ToString() const
761{
762 wxString s;
763
df898907 764 s.Printf(wxS("%d;%ld;%ld;%ld;%ld;%ld;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
09fcd889
VZ
765 0, // version, in case we want to change the format later
766 lf.lfHeight,
767 lf.lfWidth,
768 lf.lfEscapement,
769 lf.lfOrientation,
770 lf.lfWeight,
771 lf.lfItalic,
772 lf.lfUnderline,
773 lf.lfStrikeOut,
774 lf.lfCharSet,
775 lf.lfOutPrecision,
776 lf.lfClipPrecision,
777 lf.lfQuality,
778 lf.lfPitchAndFamily,
c9f78968 779 (const wxChar*)lf.lfFaceName);
09fcd889
VZ
780
781 return s;
782}
783
0c5d3e1c
VZ
784// ----------------------------------------------------------------------------
785// wxFont
786// ----------------------------------------------------------------------------
787
d014871d
FM
788wxFont::wxFont(const wxString& fontdesc)
789{
790 wxNativeFontInfo info;
791 if ( info.FromString(fontdesc) )
792 (void)Create(info);
793}
794
04ef50df 795bool wxFont::Create(const wxNativeFontInfo& info, WXHFONT hFont)
76e23cdb 796{
09fcd889
VZ
797 UnRef();
798
04ef50df 799 m_refData = new wxFontRefData(info, hFont);
09fcd889 800
adbd3cbc 801 return RealizeResource();
76e23cdb
VZ
802}
803
df455719
VZ
804bool wxFont::DoCreate(int pointSize,
805 const wxSize& pixelSize,
806 bool sizeUsingPixels,
0c14b6c3
FM
807 wxFontFamily family,
808 wxFontStyle style,
809 wxFontWeight weight,
df455719
VZ
810 bool underlined,
811 const wxString& faceName,
812 wxFontEncoding encoding)
2bda0e17 813{
0c5d3e1c 814 UnRef();
3ca6a5f0
BP
815
816 // wxDEFAULT is a valid value for the font size too so we must treat it
817 // specially here (otherwise the size would be 70 == wxDEFAULT value)
818 if ( pointSize == wxDEFAULT )
a9249b2e
VZ
819 {
820 pointSize = wxNORMAL_FONT->GetPointSize();
821 }
3ca6a5f0 822
544229d1
VZ
823 m_refData = new wxFontRefData(pointSize, pixelSize, sizeUsingPixels,
824 family, style, weight,
0c5d3e1c 825 underlined, faceName, encoding);
2bda0e17 826
adbd3cbc 827 return RealizeResource();
2bda0e17
KB
828}
829
830wxFont::~wxFont()
831{
2bda0e17
KB
832}
833
0c5d3e1c
VZ
834// ----------------------------------------------------------------------------
835// real implementation
836// ----------------------------------------------------------------------------
837
8f884a0d 838wxGDIRefData *wxFont::CreateGDIRefData() const
f030b28c
VZ
839{
840 return new wxFontRefData();
841}
842
8f884a0d 843wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
f030b28c 844{
5c33522f 845 return new wxFontRefData(*static_cast<const wxFontRefData *>(data));
f030b28c
VZ
846}
847
0c5d3e1c 848bool wxFont::RealizeResource()
2bda0e17 849{
d014871d 850 // NOTE: the GetHFONT() call automatically triggers a reallocation of
0572fce8 851 // the HFONT if necessary (will do nothing if we already have the resource);
d014871d
FM
852 // it returns NULL only if there is a failure in wxFontRefData::Alloc()...
853 return GetHFONT() != NULL;
2bda0e17
KB
854}
855
33ac7e6f 856bool wxFont::FreeResource(bool WXUNUSED(force))
2bda0e17 857{
d014871d 858 if ( !M_FONTDATA )
adbd3cbc 859 return false;
0c5d3e1c 860
adbd3cbc 861 M_FONTDATA->Free();
a9249b2e 862
adbd3cbc 863 return true;
2bda0e17
KB
864}
865
2b5f62a0 866WXHANDLE wxFont::GetResourceHandle() const
f6bcfd97 867{
2b5f62a0 868 return (WXHANDLE)GetHFONT();
f6bcfd97
BP
869}
870
871WXHFONT wxFont::GetHFONT() const
2bda0e17 872{
d014871d
FM
873 // NOTE: wxFontRefData::GetHFONT() will automatically call
874 // wxFontRefData::Alloc() if necessary
df898907 875 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
2bda0e17
KB
876}
877
e90babdf 878bool wxFont::IsFree() const
2bda0e17 879{
8e34db1d 880 return M_FONTDATA && !M_FONTDATA->HasHFONT();
adbd3cbc
VZ
881}
882
0c5d3e1c
VZ
883// ----------------------------------------------------------------------------
884// change font attribute: we recreate font when doing it
885// ----------------------------------------------------------------------------
886
debe6624 887void wxFont::SetPointSize(int pointSize)
2bda0e17 888{
f030b28c 889 AllocExclusive();
b823f5a1 890
8e34db1d 891 M_FONTDATA->Free();
a9249b2e 892 M_FONTDATA->SetPointSize(pointSize);
2bda0e17
KB
893}
894
544229d1
VZ
895void wxFont::SetPixelSize(const wxSize& pixelSize)
896{
f030b28c 897 AllocExclusive();
544229d1
VZ
898
899 M_FONTDATA->SetPixelSize(pixelSize);
544229d1
VZ
900}
901
0c14b6c3 902void wxFont::SetFamily(wxFontFamily family)
2bda0e17 903{
f030b28c 904 AllocExclusive();
b823f5a1 905
a9249b2e 906 M_FONTDATA->SetFamily(family);
2bda0e17
KB
907}
908
0c14b6c3 909void wxFont::SetStyle(wxFontStyle style)
2bda0e17 910{
f030b28c 911 AllocExclusive();
b823f5a1 912
a9249b2e 913 M_FONTDATA->SetStyle(style);
2bda0e17
KB
914}
915
0c14b6c3 916void wxFont::SetWeight(wxFontWeight weight)
2bda0e17 917{
f030b28c 918 AllocExclusive();
b823f5a1 919
a9249b2e 920 M_FONTDATA->SetWeight(weight);
2bda0e17
KB
921}
922
85ab460e 923bool wxFont::SetFaceName(const wxString& faceName)
2bda0e17 924{
f030b28c 925 AllocExclusive();
b823f5a1 926
8e34db1d
VZ
927 if ( !M_FONTDATA->SetFaceName(faceName) )
928 return false;
85ab460e
VZ
929
930 // NB: using win32's GetObject() API on M_FONTDATA->GetHFONT()
931 // to retrieve a LOGFONT and then compare lf.lfFaceName
932 // with given facename is not reliable at all:
933 // Windows copies the facename given to ::CreateFontIndirect()
934 // without any validity check.
935 // Thus we use wxFontBase::SetFaceName to check if facename
936 // is valid...
8e34db1d 937 return wxFontBase::SetFaceName(faceName);
2bda0e17
KB
938}
939
debe6624 940void wxFont::SetUnderlined(bool underlined)
2bda0e17 941{
f030b28c 942 AllocExclusive();
b823f5a1 943
a9249b2e 944 M_FONTDATA->SetUnderlined(underlined);
2bda0e17
KB
945}
946
0c5d3e1c 947void wxFont::SetEncoding(wxFontEncoding encoding)
2bda0e17 948{
f030b28c 949 AllocExclusive();
0c5d3e1c 950
a9249b2e 951 M_FONTDATA->SetEncoding(encoding);
09fcd889
VZ
952}
953
9045ad9d 954void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info)
09fcd889 955{
f030b28c 956 AllocExclusive();
09fcd889 957
8e34db1d 958 M_FONTDATA->SetNativeFontInfo(info);
0c5d3e1c
VZ
959}
960
961// ----------------------------------------------------------------------------
962// accessors
963// ----------------------------------------------------------------------------
964
965int wxFont::GetPointSize() const
966{
d014871d 967 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
789034a0 968
a9249b2e 969 return M_FONTDATA->GetPointSize();
0c5d3e1c
VZ
970}
971
544229d1
VZ
972wxSize wxFont::GetPixelSize() const
973{
d014871d 974 wxCHECK_MSG( IsOk(), wxDefaultSize, wxT("invalid font") );
68585e17 975
544229d1
VZ
976 return M_FONTDATA->GetPixelSize();
977}
978
979bool wxFont::IsUsingSizeInPixels() const
980{
d014871d 981 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
544229d1
VZ
982
983 return M_FONTDATA->IsUsingSizeInPixels();
984}
985
0c14b6c3 986wxFontFamily wxFont::GetFamily() const
0c5d3e1c 987{
d014871d 988 wxCHECK_MSG( IsOk(), wxFONTFAMILY_MAX, wxT("invalid font") );
789034a0 989
a9249b2e 990 return M_FONTDATA->GetFamily();
2bda0e17
KB
991}
992
0c14b6c3 993wxFontStyle wxFont::GetStyle() const
2bda0e17 994{
d014871d 995 wxCHECK_MSG( IsOk(), wxFONTSTYLE_MAX, wxT("invalid font") );
789034a0 996
a9249b2e 997 return M_FONTDATA->GetStyle();
2bda0e17
KB
998}
999
0c14b6c3 1000wxFontWeight wxFont::GetWeight() const
2bda0e17 1001{
d014871d 1002 wxCHECK_MSG( IsOk(), wxFONTWEIGHT_MAX, wxT("invalid font") );
789034a0 1003
a9249b2e 1004 return M_FONTDATA->GetWeight();
2bda0e17
KB
1005}
1006
0c5d3e1c
VZ
1007bool wxFont::GetUnderlined() const
1008{
d014871d 1009 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
789034a0 1010
a9249b2e 1011 return M_FONTDATA->GetUnderlined();
0c5d3e1c
VZ
1012}
1013
1014wxString wxFont::GetFaceName() const
1015{
d014871d 1016 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
789034a0 1017
a9249b2e 1018 return M_FONTDATA->GetFaceName();
0c5d3e1c
VZ
1019}
1020
1021wxFontEncoding wxFont::GetEncoding() const
1022{
d014871d 1023 wxCHECK_MSG( IsOk(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
789034a0 1024
a9249b2e 1025 return M_FONTDATA->GetEncoding();
0c5d3e1c 1026}
a1d58ddc 1027
3bf5a59b 1028const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
1e6feb95 1029{
7c6e85dc 1030 return IsOk() ? &(M_FONTDATA->GetNativeFontInfo()) : NULL;
09fcd889
VZ
1031}
1032
85ab460e
VZ
1033wxString wxFont::GetNativeFontInfoDesc() const
1034{
d014871d 1035 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
68585e17 1036
85ab460e 1037 // be sure we have an HFONT associated...
d014871d 1038 const_cast<wxFont*>(this)->RealizeResource();
85ab460e
VZ
1039 return wxFontBase::GetNativeFontInfoDesc();
1040}
1041
1042wxString wxFont::GetNativeFontInfoUserDesc() const
1043{
d014871d 1044 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
68585e17 1045
85ab460e 1046 // be sure we have an HFONT associated...
d014871d 1047 const_cast<wxFont*>(this)->RealizeResource();
85ab460e
VZ
1048 return wxFontBase::GetNativeFontInfoUserDesc();
1049}
1050
9cf8de4c
VZ
1051bool wxFont::IsFixedWidth() const
1052{
d014871d
FM
1053 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
1054
7c6e85dc
VZ
1055 // the two low-order bits specify the pitch of the font, the rest is
1056 // family
1057 BYTE pitch =
1058 (BYTE)(M_FONTDATA->GetNativeFontInfo().lf.lfPitchAndFamily & PITCH_MASK);
9cf8de4c 1059
7c6e85dc 1060 return pitch == FIXED_PITCH;
9cf8de4c 1061}