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