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