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