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