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