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