]> git.saurik.com Git - wxWidgets.git/blame - src/msw/font.cpp
background colour of a combobox may now be set (bug 805442)
[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$
a9249b2e
VZ
8// Copyright: (c) wxWindows team
9// Licence: wxWindows licence
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
0c5d3e1c
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
14f355c2 20#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
0c5d3e1c 21 #pragma implementation "font.h"
2bda0e17
KB
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
0c5d3e1c 28 #pragma hdrstop
2bda0e17
KB
29#endif
30
31#ifndef WX_PRECOMP
0c5d3e1c
VZ
32 #include "wx/setup.h"
33 #include "wx/list.h"
34 #include "wx/utils.h"
35 #include "wx/app.h"
36 #include "wx/font.h"
f94dfb38 37 #include "wx/log.h"
e4ffab29 38 #include "wx/encinfo.h"
0c5d3e1c 39#endif // WX_PRECOMP
2bda0e17 40
bff67a6a
VZ
41#include "wx/msw/private.h"
42
76e23cdb 43#include "wx/fontutil.h"
bff67a6a 44#include "wx/fontmap.h"
76e23cdb 45
1e6feb95 46#include "wx/tokenzr.h"
2bda0e17 47
066f1b7a
SC
48#if wxUSE_EXTENDED_RTTI
49
3ff066a4
SC
50wxBEGIN_ENUM( wxFontFamily )
51 wxENUM_MEMBER( wxDEFAULT )
52 wxENUM_MEMBER( wxDECORATIVE )
53 wxENUM_MEMBER( wxROMAN )
54 wxENUM_MEMBER( wxSCRIPT )
55 wxENUM_MEMBER( wxSWISS )
56 wxENUM_MEMBER( wxMODERN )
57 wxENUM_MEMBER( wxTELETYPE )
58wxEND_ENUM( wxFontFamily )
59
60wxBEGIN_ENUM( wxFontStyle )
61 wxENUM_MEMBER( wxNORMAL )
62 wxENUM_MEMBER( wxITALIC )
63 wxENUM_MEMBER( wxSLANT )
64wxEND_ENUM( wxFontStyle )
65
66wxBEGIN_ENUM( wxFontWeight )
67 wxENUM_MEMBER( wxNORMAL )
68 wxENUM_MEMBER( wxLIGHT )
69 wxENUM_MEMBER( wxBOLD )
70wxEND_ENUM( wxFontWeight )
066f1b7a
SC
71
72IMPLEMENT_DYNAMIC_CLASS_WITH_COPY_XTI(wxFont, wxGDIObject,"wx/font.h")
73
3ff066a4
SC
74wxBEGIN_PROPERTIES_TABLE(wxFont)
75 wxPROPERTY( Size,int, SetPointSize, GetPointSize, 12 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
76 wxPROPERTY( Family, int , SetFamily, GetFamily, (int)wxDEFAULT , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // wxFontFamily
77 wxPROPERTY( Style, int , SetStyle, GetStyle, (int)wxNORMAL , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // wxFontStyle
78 wxPROPERTY( Weight, int , SetWeight, GetWeight, (int)wxNORMAL , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // wxFontWeight
79 wxPROPERTY( Underlined, bool , SetUnderlined, GetUnderlined, false , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
80 wxPROPERTY( Face, wxString , SetFaceName, GetFaceName, , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
81 wxPROPERTY( Encoding, wxFontEncoding , SetEncoding, GetEncoding, wxFONTENCODING_DEFAULT , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
82wxEND_PROPERTIES_TABLE()
066f1b7a 83
3ff066a4 84wxCONSTRUCTOR_6( wxFont , int , Size , int , Family , int , Style , int , Weight , bool , Underlined , wxString , Face )
066f1b7a 85
3ff066a4
SC
86wxBEGIN_HANDLERS_TABLE(wxFont)
87wxEND_HANDLERS_TABLE()
066f1b7a
SC
88
89#else
90 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
91#endif
92
2bda0e17 93
3ca6a5f0
BP
94// ----------------------------------------------------------------------------
95// constants
96// ----------------------------------------------------------------------------
97
9cf8de4c
VZ
98// the mask used to extract the pitch from LOGFONT::lfPitchAndFamily field
99static const int PITCH_MASK = FIXED_PITCH | VARIABLE_PITCH;
100
0c5d3e1c
VZ
101// ----------------------------------------------------------------------------
102// wxFontRefData - the internal description of the font
103// ----------------------------------------------------------------------------
2bda0e17 104
0c5d3e1c 105class WXDLLEXPORT wxFontRefData: public wxGDIRefData
2bda0e17 106{
0c5d3e1c 107public:
a9249b2e 108 // constructors
0c5d3e1c
VZ
109 wxFontRefData()
110 {
a9249b2e 111 Init(-1, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
fda7962d 112 FALSE, wxEmptyString, wxFONTENCODING_DEFAULT);
0c5d3e1c
VZ
113 }
114
115 wxFontRefData(int size,
116 int family,
117 int style,
118 int weight,
119 bool underlined,
120 const wxString& faceName,
121 wxFontEncoding encoding)
122 {
123 Init(size, family, style, weight, underlined, faceName, encoding);
124 }
2bda0e17 125
04ef50df 126 wxFontRefData(const wxNativeFontInfo& info, WXHFONT hFont = 0)
09fcd889 127 {
04ef50df 128 Init(info, hFont);
09fcd889
VZ
129 }
130
a9249b2e
VZ
131 wxFontRefData(const wxFontRefData& data)
132 {
133 if ( data.m_nativeFontInfoOk )
134 {
135 Init(data.m_nativeFontInfo);
136 }
137 else
138 {
139 Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
140 data.m_underlined, data.m_faceName, data.m_encoding);
141 }
142 }
143
0c5d3e1c
VZ
144 virtual ~wxFontRefData();
145
a9249b2e
VZ
146 // operations
147 bool Alloc(wxFont *font);
148
149 void Free();
150
151 // all wxFont accessors
152 int GetPointSize() const
153 {
154 return m_nativeFontInfoOk ? m_nativeFontInfo.GetPointSize()
155 : m_pointSize;
156 }
157
158 int GetFamily() const
159 {
160 return m_family;
161 }
162
163 int GetStyle() const
164 {
165 return m_nativeFontInfoOk ? m_nativeFontInfo.GetStyle()
166 : m_style;
167 }
168
169 int GetWeight() const
170 {
171 return m_nativeFontInfoOk ? m_nativeFontInfo.GetWeight()
172 : m_weight;
173 }
174
175 bool GetUnderlined() const
176 {
177 return m_nativeFontInfoOk ? m_nativeFontInfo.GetUnderlined()
178 : m_underlined;
179 }
180
181 wxString GetFaceName() const
182 {
183 wxString s;
184 if ( m_nativeFontInfoOk )
185 s = m_nativeFontInfo.GetFaceName();
186 else
187 s = m_faceName;
188
189 return s;
190 }
191
192 wxFontEncoding GetEncoding() const
193 {
194 return m_nativeFontInfoOk ? m_nativeFontInfo.GetEncoding()
195 : m_encoding;
196 }
197
198 WXHFONT GetHFONT() const { return m_hFont; }
199
200 // ... and setters
201 void SetPointSize(int pointSize)
202 {
203 if ( m_nativeFontInfoOk )
204 m_nativeFontInfo.SetPointSize(pointSize);
205 else
206 m_pointSize = pointSize;
207 }
208
209 void SetFamily(int family)
210 {
211 m_family = family;
212 }
213
214 void SetStyle(int style)
215 {
216 if ( m_nativeFontInfoOk )
217 m_nativeFontInfo.SetStyle((wxFontStyle)style);
218 else
219 m_style = style;
220 }
221
222 void SetWeight(int weight)
223 {
224 if ( m_nativeFontInfoOk )
225 m_nativeFontInfo.SetWeight((wxFontWeight)weight);
226 else
227 m_weight = weight;
228 }
229
230 void SetFaceName(const wxString& faceName)
231 {
232 if ( m_nativeFontInfoOk )
233 m_nativeFontInfo.SetFaceName(faceName);
234 else
235 m_faceName = faceName;
236 }
237
238 void SetUnderlined(bool underlined)
239 {
240 if ( m_nativeFontInfoOk )
241 m_nativeFontInfo.SetUnderlined(underlined);
242 else
243 m_underlined = underlined;
244 }
245
246 void SetEncoding(wxFontEncoding encoding)
247 {
248 if ( m_nativeFontInfoOk )
249 m_nativeFontInfo.SetEncoding(encoding);
250 else
251 m_encoding = encoding;
252 }
253
254 // native font info tests
255 bool HasNativeFontInfo() const { return m_nativeFontInfoOk; }
256
257 const wxNativeFontInfo& GetNativeFontInfo() const
258 { return m_nativeFontInfo; }
259
0c5d3e1c
VZ
260protected:
261 // common part of all ctors
262 void Init(int size,
263 int family,
264 int style,
265 int weight,
266 bool underlined,
267 const wxString& faceName,
268 wxFontEncoding encoding);
269
04ef50df 270 void Init(const wxNativeFontInfo& info, WXHFONT hFont = 0);
09fcd889 271
0c5d3e1c
VZ
272 // font characterstics
273 int m_pointSize;
274 int m_family;
275 int m_style;
276 int m_weight;
277 bool m_underlined;
278 wxString m_faceName;
279 wxFontEncoding m_encoding;
280
281 // Windows font handle
282 WXHFONT m_hFont;
789034a0 283
09fcd889
VZ
284 // Native font info
285 wxNativeFontInfo m_nativeFontInfo;
286 bool m_nativeFontInfoOk;
0c5d3e1c
VZ
287};
288
289// ============================================================================
290// implementation
291// ============================================================================
292
293// ----------------------------------------------------------------------------
294// wxFontRefData
295// ----------------------------------------------------------------------------
296
297void wxFontRefData::Init(int pointSize,
298 int family,
299 int style,
300 int weight,
301 bool underlined,
302 const wxString& faceName,
303 wxFontEncoding encoding)
b823f5a1 304{
b9b3ccd9 305 m_style = style;
a9249b2e 306 m_pointSize = pointSize == -1 ? wxNORMAL_FONT->GetPointSize() : pointSize;
b9b3ccd9
VZ
307 m_family = family;
308 m_style = style;
309 m_weight = weight;
310 m_underlined = underlined;
311 m_faceName = faceName;
0c5d3e1c
VZ
312 m_encoding = encoding;
313
b9b3ccd9 314 m_hFont = 0;
789034a0 315
09fcd889
VZ
316 m_nativeFontInfoOk = FALSE;
317}
318
04ef50df 319void wxFontRefData::Init(const wxNativeFontInfo& info, WXHFONT hFont)
09fcd889 320{
04ef50df
JS
321 // hFont may be zero, or it be passed in case we really want to
322 // use the exact font created in the underlying system
323 // (for example where we can't guarantee conversion from HFONT
324 // to LOGFONT back to HFONT)
325 m_hFont = hFont;
789034a0 326
09fcd889
VZ
327 m_nativeFontInfoOk = TRUE;
328 m_nativeFontInfo = info;
93692400
JS
329 // This is the best we can do since we don't have the
330 // correct information at this point.
331 m_family = wxSWISS;
b823f5a1
JS
332}
333
0c5d3e1c 334wxFontRefData::~wxFontRefData()
a9249b2e
VZ
335{
336 Free();
337}
338
339bool wxFontRefData::Alloc(wxFont *font)
340{
341 if ( !m_nativeFontInfoOk )
342 {
343 wxFillLogFont(&m_nativeFontInfo.lf, font);
344 m_nativeFontInfoOk = TRUE;
345 }
346
347 HFONT hfont = ::CreateFontIndirect(&m_nativeFontInfo.lf);
348 if ( !hfont )
349 {
350 wxLogLastError(wxT("CreateFont"));
351
352 return FALSE;
353 }
354
355 m_hFont = (WXHFONT)hfont;
356
357 return TRUE;
358}
359
360void wxFontRefData::Free()
2bda0e17 361{
b9b3ccd9 362 if ( m_hFont )
0c5d3e1c 363 {
b9b3ccd9 364 if ( !::DeleteObject((HFONT) m_hFont) )
0c5d3e1c 365 {
f6bcfd97 366 wxLogLastError(wxT("DeleteObject(font)"));
0c5d3e1c 367 }
a9249b2e
VZ
368
369 m_hFont = 0;
0c5d3e1c 370 }
2bda0e17
KB
371}
372
09fcd889
VZ
373// ----------------------------------------------------------------------------
374// wxNativeFontInfo
375// ----------------------------------------------------------------------------
376
a9249b2e
VZ
377void wxNativeFontInfo::Init()
378{
379 wxZeroMemory(lf);
380}
381
382int wxNativeFontInfo::GetPointSize() const
383{
7936354d
VZ
384 // FIXME: using the screen here results in incorrect font size calculation
385 // for printing!
a9249b2e
VZ
386 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
387
388 return (int) (((72.0*(double)abs(lf.lfHeight)) / (double) ppInch) + 0.5);
389}
390
391wxFontStyle wxNativeFontInfo::GetStyle() const
392{
393 return lf.lfItalic ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
394}
395
396wxFontWeight wxNativeFontInfo::GetWeight() const
397{
398 if ( lf.lfWeight <= 300 )
399 return wxFONTWEIGHT_LIGHT;
400
401 if ( lf.lfWeight >= 600 )
402 return wxFONTWEIGHT_BOLD;
403
404 return wxFONTWEIGHT_NORMAL;
405}
406
407bool wxNativeFontInfo::GetUnderlined() const
408{
409 return lf.lfUnderline != 0;
410}
411
412wxString wxNativeFontInfo::GetFaceName() const
413{
414 return lf.lfFaceName;
415}
416
36e2bb4e
RD
417wxFontFamily wxNativeFontInfo::GetFamily() const
418{
9cf8de4c 419 wxFontFamily family;
36e2bb4e 420
9cf8de4c
VZ
421 // extract family from pitch-and-family
422 switch ( lf.lfPitchAndFamily & ~PITCH_MASK )
36e2bb4e
RD
423 {
424 case FF_ROMAN:
9cf8de4c 425 family = wxFONTFAMILY_ROMAN;
36e2bb4e
RD
426 break;
427
9cf8de4c
VZ
428 default:
429 wxFAIL_MSG( _T("unknown LOGFONT::lfFamily value") );
430 // fall through
431
36e2bb4e 432 case FF_SWISS:
9cf8de4c 433 family = wxFONTFAMILY_SWISS;
36e2bb4e
RD
434 break;
435
436 case FF_SCRIPT:
9cf8de4c 437 family = wxFONTFAMILY_SCRIPT;
36e2bb4e
RD
438 break;
439
440 case FF_MODERN:
9cf8de4c 441 family = wxFONTFAMILY_MODERN;
36e2bb4e
RD
442 break;
443
444 case FF_DECORATIVE:
9cf8de4c 445 family = wxFONTFAMILY_DECORATIVE;
36e2bb4e 446 break;
36e2bb4e 447 }
9cf8de4c
VZ
448
449 return family;
36e2bb4e
RD
450}
451
a9249b2e
VZ
452wxFontEncoding wxNativeFontInfo::GetEncoding() const
453{
454 return wxGetFontEncFromCharSet(lf.lfCharSet);
455}
456
457void wxNativeFontInfo::SetPointSize(int pointsize)
458{
7936354d
VZ
459#if wxFONT_SIZE_COMPATIBILITY
460 // Incorrect, but compatible with old wxWindows behaviour
461 lf.lfHeight = (pointSize*ppInch)/72;
462#else // wxFONT_SIZE_COMPATIBILITY
463 // FIXME: using the screen here results in incorrect font size calculation
464 // for printing!
a9249b2e
VZ
465 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
466
467 lf.lfHeight = -(int)((pointsize*((double)ppInch)/72.0) + 0.5);
7936354d 468#endif // wxFONT_SIZE_COMPATIBILITY/!wxFONT_SIZE_COMPATIBILITY
a9249b2e
VZ
469}
470
471void wxNativeFontInfo::SetStyle(wxFontStyle style)
472{
473 switch ( style )
474 {
475 default:
476 wxFAIL_MSG( _T("unknown font style") );
477 // fall through
478
479 case wxFONTSTYLE_NORMAL:
a38d0585 480 lf.lfItalic = FALSE;
a9249b2e
VZ
481 break;
482
483 case wxFONTSTYLE_ITALIC:
484 case wxFONTSTYLE_SLANT:
485 lf.lfItalic = TRUE;
486 break;
487 }
488}
489
490void wxNativeFontInfo::SetWeight(wxFontWeight weight)
491{
492 switch ( weight )
493 {
494 default:
495 wxFAIL_MSG( _T("unknown font weight") );
496 // fall through
497
498 case wxFONTWEIGHT_NORMAL:
499 lf.lfWeight = FW_NORMAL;
500 break;
501
502 case wxFONTWEIGHT_LIGHT:
503 lf.lfWeight = FW_LIGHT;
504 break;
505
506 case wxFONTWEIGHT_BOLD:
507 lf.lfWeight = FW_BOLD;
508 break;
509 }
510}
511
512void wxNativeFontInfo::SetUnderlined(bool underlined)
513{
514 lf.lfUnderline = underlined;
515}
516
517void wxNativeFontInfo::SetFaceName(wxString facename)
518{
49eb2344 519 wxStrncpy(lf.lfFaceName, facename, WXSIZEOF(lf.lfFaceName));
a9249b2e
VZ
520}
521
7936354d
VZ
522void wxNativeFontInfo::SetFamily(wxFontFamily family)
523{
524 int ff_family;
525 wxString facename;
526
527 switch ( family )
528 {
529 case wxSCRIPT:
530 ff_family = FF_SCRIPT;
531 facename = _T("Script");
532 break;
533
534 case wxDECORATIVE:
535 ff_family = FF_DECORATIVE;
5e968b74 536 facename = _T("Old English Text MT");
7936354d
VZ
537 break;
538
539 case wxROMAN:
540 ff_family = FF_ROMAN;
541 facename = _T("Times New Roman");
542 break;
543
544 case wxTELETYPE:
545 case wxMODERN:
546 ff_family = FF_MODERN;
547 facename = _T("Courier New");
548 break;
549
550 case wxSWISS:
551 ff_family = FF_SWISS;
552 facename = _T("Arial");
553 break;
554
555 case wxDEFAULT:
556 default:
557 ff_family = FF_SWISS;
558 facename = _T("MS Sans Serif");
559 }
560
561 lf.lfPitchAndFamily = DEFAULT_PITCH | ff_family;
562
563 if ( !wxStrlen(lf.lfFaceName) )
564 {
565 SetFaceName(facename);
566 }
567}
568
a9249b2e
VZ
569void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding)
570{
571 wxNativeEncodingInfo info;
572 if ( !wxGetNativeFontEncoding(encoding, &info) )
573 {
bff67a6a 574#if wxUSE_FONTMAP
142b3bc2 575 if ( wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
e7e52b6d
VZ
576 {
577 if ( !info.facename.empty() )
578 {
579 // if we have this encoding only in some particular facename, use
580 // the facename - it is better to show the correct characters in a
581 // wrong facename than unreadable text in a correct one
582 SetFaceName(info.facename);
583 }
584 }
585 else
bff67a6a
VZ
586#endif // wxUSE_FONTMAP
587 {
588 // unsupported encoding, replace with the default
9cf8de4c 589 info.charset = DEFAULT_CHARSET;
bff67a6a 590 }
a9249b2e
VZ
591 }
592
593 lf.lfCharSet = info.charset;
594}
595
09fcd889
VZ
596bool wxNativeFontInfo::FromString(const wxString& s)
597{
598 long l;
599
600 wxStringTokenizer tokenizer(s, _T(";"));
601
a9249b2e 602 // first the version
09fcd889 603 wxString token = tokenizer.GetNextToken();
a9249b2e
VZ
604 if ( token != _T('0') )
605 return FALSE;
09fcd889
VZ
606
607 token = tokenizer.GetNextToken();
608 if ( !token.ToLong(&l) )
609 return FALSE;
610 lf.lfHeight = l;
611
612 token = tokenizer.GetNextToken();
613 if ( !token.ToLong(&l) )
614 return FALSE;
615 lf.lfWidth = l;
616
617 token = tokenizer.GetNextToken();
618 if ( !token.ToLong(&l) )
619 return FALSE;
620 lf.lfEscapement = l;
621
622 token = tokenizer.GetNextToken();
623 if ( !token.ToLong(&l) )
624 return FALSE;
625 lf.lfOrientation = l;
626
627 token = tokenizer.GetNextToken();
628 if ( !token.ToLong(&l) )
629 return FALSE;
630 lf.lfWeight = l;
631
632 token = tokenizer.GetNextToken();
633 if ( !token.ToLong(&l) )
634 return FALSE;
33ac7e6f 635 lf.lfItalic = (BYTE)l;
09fcd889
VZ
636
637 token = tokenizer.GetNextToken();
638 if ( !token.ToLong(&l) )
639 return FALSE;
33ac7e6f 640 lf.lfUnderline = (BYTE)l;
09fcd889
VZ
641
642 token = tokenizer.GetNextToken();
643 if ( !token.ToLong(&l) )
644 return FALSE;
33ac7e6f 645 lf.lfStrikeOut = (BYTE)l;
09fcd889
VZ
646
647 token = tokenizer.GetNextToken();
648 if ( !token.ToLong(&l) )
649 return FALSE;
33ac7e6f 650 lf.lfCharSet = (BYTE)l;
09fcd889
VZ
651
652 token = tokenizer.GetNextToken();
653 if ( !token.ToLong(&l) )
654 return FALSE;
33ac7e6f 655 lf.lfOutPrecision = (BYTE)l;
09fcd889
VZ
656
657 token = tokenizer.GetNextToken();
658 if ( !token.ToLong(&l) )
659 return FALSE;
33ac7e6f 660 lf.lfClipPrecision = (BYTE)l;
09fcd889
VZ
661
662 token = tokenizer.GetNextToken();
663 if ( !token.ToLong(&l) )
664 return FALSE;
33ac7e6f 665 lf.lfQuality = (BYTE)l;
09fcd889
VZ
666
667 token = tokenizer.GetNextToken();
668 if ( !token.ToLong(&l) )
669 return FALSE;
33ac7e6f 670 lf.lfPitchAndFamily = (BYTE)l;
09fcd889
VZ
671
672 token = tokenizer.GetNextToken();
673 if(!token)
674 return FALSE;
675 wxStrcpy(lf.lfFaceName, token.c_str());
676
677 return TRUE;
678}
679
680wxString wxNativeFontInfo::ToString() const
681{
682 wxString s;
683
4244c20b 684 s.Printf(_T("%d;%ld;%ld;%ld;%ld;%ld;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
09fcd889
VZ
685 0, // version, in case we want to change the format later
686 lf.lfHeight,
687 lf.lfWidth,
688 lf.lfEscapement,
689 lf.lfOrientation,
690 lf.lfWeight,
691 lf.lfItalic,
692 lf.lfUnderline,
693 lf.lfStrikeOut,
694 lf.lfCharSet,
695 lf.lfOutPrecision,
696 lf.lfClipPrecision,
697 lf.lfQuality,
698 lf.lfPitchAndFamily,
699 lf.lfFaceName);
700
701 return s;
702}
703
0c5d3e1c
VZ
704// ----------------------------------------------------------------------------
705// wxFont
706// ----------------------------------------------------------------------------
707
708void wxFont::Init()
2bda0e17 709{
2bda0e17
KB
710}
711
04ef50df 712bool wxFont::Create(const wxNativeFontInfo& info, WXHFONT hFont)
76e23cdb 713{
09fcd889
VZ
714 UnRef();
715
04ef50df 716 m_refData = new wxFontRefData(info, hFont);
09fcd889
VZ
717
718 RealizeResource();
719
720 return TRUE;
76e23cdb
VZ
721}
722
723wxFont::wxFont(const wxString& fontdesc)
724{
725 wxNativeFontInfo info;
726 if ( info.FromString(fontdesc) )
727 (void)Create(info);
728}
729
2bda0e17
KB
730/* Constructor for a font. Note that the real construction is done
731 * in wxDC::SetFont, when information is available about scaling etc.
732 */
0c5d3e1c
VZ
733bool wxFont::Create(int pointSize,
734 int family,
735 int style,
736 int weight,
737 bool underlined,
738 const wxString& faceName,
739 wxFontEncoding encoding)
2bda0e17 740{
0c5d3e1c 741 UnRef();
3ca6a5f0
BP
742
743 // wxDEFAULT is a valid value for the font size too so we must treat it
744 // specially here (otherwise the size would be 70 == wxDEFAULT value)
745 if ( pointSize == wxDEFAULT )
a9249b2e
VZ
746 {
747 pointSize = wxNORMAL_FONT->GetPointSize();
748 }
3ca6a5f0 749
0c5d3e1c
VZ
750 m_refData = new wxFontRefData(pointSize, family, style, weight,
751 underlined, faceName, encoding);
2bda0e17 752
0c5d3e1c 753 RealizeResource();
2bda0e17 754
0c5d3e1c 755 return TRUE;
2bda0e17
KB
756}
757
758wxFont::~wxFont()
759{
2bda0e17
KB
760}
761
0c5d3e1c
VZ
762// ----------------------------------------------------------------------------
763// real implementation
764// ----------------------------------------------------------------------------
765
766bool wxFont::RealizeResource()
2bda0e17 767{
0c5d3e1c
VZ
768 if ( GetResourceHandle() )
769 {
770 // VZ: the old code returned FALSE in this case, but it doesn't seem
771 // to make sense because the font _was_ created
0c5d3e1c
VZ
772 return TRUE;
773 }
774
a9249b2e 775 return M_FONTDATA->Alloc(this);
2bda0e17
KB
776}
777
33ac7e6f 778bool wxFont::FreeResource(bool WXUNUSED(force))
2bda0e17 779{
0c5d3e1c
VZ
780 if ( GetResourceHandle() )
781 {
a9249b2e 782 M_FONTDATA->Free();
0c5d3e1c
VZ
783
784 return TRUE;
785 }
a9249b2e 786
0c5d3e1c 787 return FALSE;
2bda0e17
KB
788}
789
2b5f62a0 790WXHANDLE wxFont::GetResourceHandle() const
f6bcfd97 791{
2b5f62a0 792 return (WXHANDLE)GetHFONT();
f6bcfd97
BP
793}
794
795WXHFONT wxFont::GetHFONT() const
2bda0e17 796{
a9249b2e 797 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
2bda0e17
KB
798}
799
e90babdf 800bool wxFont::IsFree() const
2bda0e17 801{
a9249b2e 802 return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0);
2bda0e17
KB
803}
804
b823f5a1
JS
805void wxFont::Unshare()
806{
b9b3ccd9
VZ
807 // Don't change shared data
808 if ( !m_refData )
b823f5a1 809 {
b9b3ccd9
VZ
810 m_refData = new wxFontRefData();
811 }
b823f5a1
JS
812 else
813 {
b9b3ccd9
VZ
814 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
815 UnRef();
816 m_refData = ref;
817 }
b823f5a1
JS
818}
819
0c5d3e1c
VZ
820// ----------------------------------------------------------------------------
821// change font attribute: we recreate font when doing it
822// ----------------------------------------------------------------------------
823
debe6624 824void wxFont::SetPointSize(int pointSize)
2bda0e17 825{
b823f5a1
JS
826 Unshare();
827
a9249b2e 828 M_FONTDATA->SetPointSize(pointSize);
b823f5a1
JS
829
830 RealizeResource();
2bda0e17
KB
831}
832
debe6624 833void wxFont::SetFamily(int family)
2bda0e17 834{
b823f5a1
JS
835 Unshare();
836
a9249b2e 837 M_FONTDATA->SetFamily(family);
b823f5a1
JS
838
839 RealizeResource();
2bda0e17
KB
840}
841
debe6624 842void wxFont::SetStyle(int style)
2bda0e17 843{
b823f5a1
JS
844 Unshare();
845
a9249b2e 846 M_FONTDATA->SetStyle(style);
b823f5a1
JS
847
848 RealizeResource();
2bda0e17
KB
849}
850
debe6624 851void wxFont::SetWeight(int weight)
2bda0e17 852{
b823f5a1
JS
853 Unshare();
854
a9249b2e 855 M_FONTDATA->SetWeight(weight);
b823f5a1
JS
856
857 RealizeResource();
2bda0e17
KB
858}
859
860void wxFont::SetFaceName(const wxString& faceName)
861{
b823f5a1
JS
862 Unshare();
863
a9249b2e 864 M_FONTDATA->SetFaceName(faceName);
b823f5a1
JS
865
866 RealizeResource();
2bda0e17
KB
867}
868
debe6624 869void wxFont::SetUnderlined(bool underlined)
2bda0e17 870{
b823f5a1
JS
871 Unshare();
872
a9249b2e 873 M_FONTDATA->SetUnderlined(underlined);
b823f5a1
JS
874
875 RealizeResource();
2bda0e17
KB
876}
877
0c5d3e1c 878void wxFont::SetEncoding(wxFontEncoding encoding)
2bda0e17 879{
0c5d3e1c
VZ
880 Unshare();
881
a9249b2e 882 M_FONTDATA->SetEncoding(encoding);
09fcd889
VZ
883
884 RealizeResource();
885}
886
9045ad9d 887void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info)
09fcd889
VZ
888{
889 Unshare();
789034a0
VZ
890
891 FreeResource();
09fcd889 892
a9249b2e 893 *M_FONTDATA = wxFontRefData(info);
0c5d3e1c
VZ
894
895 RealizeResource();
896}
897
898// ----------------------------------------------------------------------------
899// accessors
900// ----------------------------------------------------------------------------
901
902int wxFont::GetPointSize() const
903{
789034a0
VZ
904 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
905
a9249b2e 906 return M_FONTDATA->GetPointSize();
0c5d3e1c
VZ
907}
908
909int wxFont::GetFamily() const
910{
789034a0
VZ
911 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
912
a9249b2e 913 return M_FONTDATA->GetFamily();
2bda0e17
KB
914}
915
0c5d3e1c 916int wxFont::GetStyle() const
2bda0e17 917{
789034a0
VZ
918 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
919
a9249b2e 920 return M_FONTDATA->GetStyle();
2bda0e17
KB
921}
922
0c5d3e1c 923int wxFont::GetWeight() const
2bda0e17 924{
789034a0
VZ
925 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
926
a9249b2e 927 return M_FONTDATA->GetWeight();
2bda0e17
KB
928}
929
0c5d3e1c
VZ
930bool wxFont::GetUnderlined() const
931{
789034a0
VZ
932 wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") );
933
a9249b2e 934 return M_FONTDATA->GetUnderlined();
0c5d3e1c
VZ
935}
936
937wxString wxFont::GetFaceName() const
938{
fda7962d 939 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
789034a0 940
a9249b2e 941 return M_FONTDATA->GetFaceName();
0c5d3e1c
VZ
942}
943
944wxFontEncoding wxFont::GetEncoding() const
945{
789034a0
VZ
946 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
947
a9249b2e 948 return M_FONTDATA->GetEncoding();
0c5d3e1c 949}
a1d58ddc 950
3bf5a59b 951const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
1e6feb95 952{
3bf5a59b
VZ
953 return M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
954 : NULL;
09fcd889
VZ
955}
956
9cf8de4c
VZ
957bool wxFont::IsFixedWidth() const
958{
959 if ( M_FONTDATA->HasNativeFontInfo() )
960 {
961 // the two low-order bits specify the pitch of the font, the rest is
962 // family
963 BYTE pitch = M_FONTDATA->GetNativeFontInfo().
964 lf.lfPitchAndFamily & PITCH_MASK;
965
966 return pitch == FIXED_PITCH;
967 }
968
969 return wxFontBase::IsFixedWidth();
970}
971