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