]> git.saurik.com Git - wxWidgets.git/blame - src/msw/font.cpp
Fixed small alignment issues
[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
66160760
VZ
42#ifndef __WXWINCE__
43 #include "wx/sysopt.h"
44#endif
45
1e6feb95 46#include "wx/tokenzr.h"
2bda0e17 47
066f1b7a
SC
48#if wxUSE_EXTENDED_RTTI
49
3ff066a4 50wxBEGIN_ENUM( wxFontFamily )
cbe874bd
WS
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 )
3ff066a4
SC
58wxEND_ENUM( wxFontFamily )
59
60wxBEGIN_ENUM( wxFontStyle )
cbe874bd
WS
61 wxENUM_MEMBER( wxNORMAL )
62 wxENUM_MEMBER( wxITALIC )
63 wxENUM_MEMBER( wxSLANT )
3ff066a4
SC
64wxEND_ENUM( wxFontStyle )
65
66wxBEGIN_ENUM( wxFontWeight )
cbe874bd
WS
67 wxENUM_MEMBER( wxNORMAL )
68 wxENUM_MEMBER( wxLIGHT )
69 wxENUM_MEMBER( wxBOLD )
3ff066a4 70wxEND_ENUM( wxFontWeight )
066f1b7a
SC
71
72IMPLEMENT_DYNAMIC_CLASS_WITH_COPY_XTI(wxFont, wxGDIObject,"wx/font.h")
73
3ff066a4 74wxBEGIN_PROPERTIES_TABLE(wxFont)
cbe874bd
WS
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, EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
81 wxPROPERTY( Encoding, wxFontEncoding , SetEncoding, GetEncoding, wxFONTENCODING_DEFAULT , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
3ff066a4 82wxEND_PROPERTIES_TABLE()
066f1b7a 83
cbe874bd 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
cbe874bd 90 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
066f1b7a
SC
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 {
c47addef 111 Init(-1, wxSize(0,0), false, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
8b5d5223 112 wxFONTWEIGHT_NORMAL, false, wxEmptyString,
544229d1 113 wxFONTENCODING_DEFAULT);
0c5d3e1c
VZ
114 }
115
116 wxFontRefData(int size,
544229d1
VZ
117 const wxSize& pixelSize,
118 bool sizeUsingPixels,
0c14b6c3
FM
119 wxFontFamily family,
120 wxFontStyle style,
121 wxFontWeight weight,
0c5d3e1c
VZ
122 bool underlined,
123 const wxString& faceName,
124 wxFontEncoding encoding)
125 {
544229d1
VZ
126 Init(size, pixelSize, sizeUsingPixels, family, style, weight,
127 underlined, faceName, encoding);
0c5d3e1c 128 }
2bda0e17 129
04ef50df 130 wxFontRefData(const wxNativeFontInfo& info, WXHFONT hFont = 0)
09fcd889 131 {
04ef50df 132 Init(info, hFont);
09fcd889
VZ
133 }
134
04a18b0d 135 wxFontRefData(const wxFontRefData& data) : wxGDIRefData()
a9249b2e
VZ
136 {
137 if ( data.m_nativeFontInfoOk )
138 {
139 Init(data.m_nativeFontInfo);
140 }
141 else
142 {
544229d1
VZ
143 Init(data.m_pointSize, data.m_pixelSize, data.m_sizeUsingPixels,
144 data.m_family, data.m_style, data.m_weight,
a9249b2e
VZ
145 data.m_underlined, data.m_faceName, data.m_encoding);
146 }
147 }
148
0c5d3e1c
VZ
149 virtual ~wxFontRefData();
150
a9249b2e 151 // operations
8e34db1d 152 bool Alloc(const wxFont *font);
a9249b2e
VZ
153
154 void Free();
155
156 // all wxFont accessors
157 int GetPointSize() const
158 {
159 return m_nativeFontInfoOk ? m_nativeFontInfo.GetPointSize()
160 : m_pointSize;
161 }
162
544229d1
VZ
163 wxSize GetPixelSize() const
164 {
165 return m_nativeFontInfoOk ? m_nativeFontInfo.GetPixelSize()
166 : m_pixelSize;
167 }
907173e5 168
544229d1
VZ
169 bool IsUsingSizeInPixels() const
170 {
907173e5 171 return m_nativeFontInfoOk ? true : m_sizeUsingPixels;
544229d1
VZ
172 }
173
9817be8a 174 wxFontFamily GetFamily() const
a9249b2e
VZ
175 {
176 return m_family;
177 }
178
9817be8a 179 wxFontStyle GetStyle() const
a9249b2e
VZ
180 {
181 return m_nativeFontInfoOk ? m_nativeFontInfo.GetStyle()
182 : m_style;
183 }
184
9817be8a 185 wxFontWeight GetWeight() const
a9249b2e
VZ
186 {
187 return m_nativeFontInfoOk ? m_nativeFontInfo.GetWeight()
188 : m_weight;
189 }
190
191 bool GetUnderlined() const
192 {
193 return m_nativeFontInfoOk ? m_nativeFontInfo.GetUnderlined()
194 : m_underlined;
195 }
196
197 wxString GetFaceName() const
198 {
199 wxString s;
200 if ( m_nativeFontInfoOk )
201 s = m_nativeFontInfo.GetFaceName();
202 else
203 s = m_faceName;
204
205 return s;
206 }
207
208 wxFontEncoding GetEncoding() const
209 {
210 return m_nativeFontInfoOk ? m_nativeFontInfo.GetEncoding()
211 : m_encoding;
212 }
213
8e34db1d
VZ
214 WXHFONT GetHFONT(const wxFont *font) const
215 {
216 if ( !m_hFont )
5c33522f 217 const_cast<wxFontRefData *>(this)->Alloc(font);
8e34db1d
VZ
218
219 return (WXHFONT)m_hFont;
220 }
221
222 bool HasHFONT() const
223 {
224 return m_hFont != 0;
225 }
a9249b2e 226
8e34db1d
VZ
227 // ... and setters: notice that all of them invalidate the currently
228 // allocated HFONT, if any, so that the next call to GetHFONT() recreates a
229 // new one
a9249b2e
VZ
230 void SetPointSize(int pointSize)
231 {
8e34db1d
VZ
232 Free();
233
a9249b2e 234 if ( m_nativeFontInfoOk )
544229d1 235 {
a9249b2e 236 m_nativeFontInfo.SetPointSize(pointSize);
544229d1 237 }
a9249b2e 238 else
544229d1 239 {
a9249b2e 240 m_pointSize = pointSize;
8b5d5223 241 m_sizeUsingPixels = false;
544229d1
VZ
242 }
243 }
244
245 void SetPixelSize(const wxSize& pixelSize)
246 {
8e34db1d
VZ
247 Free();
248
544229d1
VZ
249 if ( m_nativeFontInfoOk )
250 {
251 m_nativeFontInfo.SetPixelSize(pixelSize);
252 }
253 else
254 {
255 m_pixelSize = pixelSize;
8b5d5223 256 m_sizeUsingPixels = true;
544229d1 257 }
a9249b2e
VZ
258 }
259
0c14b6c3 260 void SetFamily(wxFontFamily family)
a9249b2e 261 {
8e34db1d
VZ
262 Free();
263
a9249b2e
VZ
264 m_family = family;
265 }
266
0c14b6c3 267 void SetStyle(wxFontStyle style)
a9249b2e 268 {
8e34db1d
VZ
269 Free();
270
a9249b2e
VZ
271 if ( m_nativeFontInfoOk )
272 m_nativeFontInfo.SetStyle((wxFontStyle)style);
273 else
274 m_style = style;
275 }
276
0c14b6c3 277 void SetWeight(wxFontWeight weight)
a9249b2e 278 {
8e34db1d
VZ
279 Free();
280
a9249b2e
VZ
281 if ( m_nativeFontInfoOk )
282 m_nativeFontInfo.SetWeight((wxFontWeight)weight);
283 else
284 m_weight = weight;
285 }
286
85ab460e 287 bool SetFaceName(const wxString& faceName)
a9249b2e 288 {
8e34db1d
VZ
289 Free();
290
a9249b2e 291 if ( m_nativeFontInfoOk )
85ab460e
VZ
292 return m_nativeFontInfo.SetFaceName(faceName);
293
164e8d41 294 m_faceName = faceName;
85ab460e 295 return true;
a9249b2e
VZ
296 }
297
298 void SetUnderlined(bool underlined)
299 {
8e34db1d
VZ
300 Free();
301
a9249b2e
VZ
302 if ( m_nativeFontInfoOk )
303 m_nativeFontInfo.SetUnderlined(underlined);
304 else
305 m_underlined = underlined;
306 }
307
308 void SetEncoding(wxFontEncoding encoding)
309 {
8e34db1d
VZ
310 Free();
311
a9249b2e
VZ
312 if ( m_nativeFontInfoOk )
313 m_nativeFontInfo.SetEncoding(encoding);
314 else
315 m_encoding = encoding;
316 }
317
8e34db1d 318 // native font info
a9249b2e
VZ
319 bool HasNativeFontInfo() const { return m_nativeFontInfoOk; }
320
321 const wxNativeFontInfo& GetNativeFontInfo() const
322 { return m_nativeFontInfo; }
323
8e34db1d 324 void SetNativeFontInfo(const wxNativeFontInfo& nativeFontInfo)
9cc79dd6
VZ
325 {
326 Free();
327
328 m_nativeFontInfo = nativeFontInfo;
329 m_nativeFontInfoOk = true;
330 }
8e34db1d 331
0c5d3e1c
VZ
332protected:
333 // common part of all ctors
334 void Init(int size,
544229d1
VZ
335 const wxSize& pixelSize,
336 bool sizeUsingPixels,
0c14b6c3
FM
337 wxFontFamily family,
338 wxFontStyle style,
339 wxFontWeight weight,
0c5d3e1c
VZ
340 bool underlined,
341 const wxString& faceName,
342 wxFontEncoding encoding);
343
04ef50df 344 void Init(const wxNativeFontInfo& info, WXHFONT hFont = 0);
09fcd889 345
8e34db1d 346 // font characteristics
0c5d3e1c 347 int m_pointSize;
544229d1
VZ
348 wxSize m_pixelSize;
349 bool m_sizeUsingPixels;
0c14b6c3
FM
350 wxFontFamily m_family;
351 wxFontStyle m_style;
352 wxFontWeight m_weight;
0c5d3e1c
VZ
353 bool m_underlined;
354 wxString m_faceName;
355 wxFontEncoding m_encoding;
356
8e34db1d
VZ
357 // Windows font handle, created on demand in GetHFONT()
358 HFONT m_hFont;
789034a0 359
09fcd889
VZ
360 // Native font info
361 wxNativeFontInfo m_nativeFontInfo;
362 bool m_nativeFontInfoOk;
0c5d3e1c
VZ
363};
364
68c95704 365#define M_FONTDATA ((wxFontRefData*)m_refData)
873fd4af 366
0c5d3e1c
VZ
367// ============================================================================
368// implementation
369// ============================================================================
370
371// ----------------------------------------------------------------------------
372// wxFontRefData
373// ----------------------------------------------------------------------------
374
375void wxFontRefData::Init(int pointSize,
544229d1
VZ
376 const wxSize& pixelSize,
377 bool sizeUsingPixels,
0c14b6c3
FM
378 wxFontFamily family,
379 wxFontStyle style,
380 wxFontWeight weight,
0c5d3e1c
VZ
381 bool underlined,
382 const wxString& faceName,
383 wxFontEncoding encoding)
b823f5a1 384{
b9b3ccd9 385 m_style = style;
a9249b2e 386 m_pointSize = pointSize == -1 ? wxNORMAL_FONT->GetPointSize() : pointSize;
544229d1
VZ
387 m_pixelSize = pixelSize;
388 m_sizeUsingPixels = sizeUsingPixels;
b9b3ccd9
VZ
389 m_family = family;
390 m_style = style;
391 m_weight = weight;
392 m_underlined = underlined;
393 m_faceName = faceName;
0c5d3e1c
VZ
394 m_encoding = encoding;
395
b9b3ccd9 396 m_hFont = 0;
789034a0 397
cbe874bd 398 m_nativeFontInfoOk = false;
09fcd889
VZ
399}
400
04ef50df 401void wxFontRefData::Init(const wxNativeFontInfo& info, WXHFONT hFont)
09fcd889 402{
04ef50df
JS
403 // hFont may be zero, or it be passed in case we really want to
404 // use the exact font created in the underlying system
405 // (for example where we can't guarantee conversion from HFONT
406 // to LOGFONT back to HFONT)
8e34db1d 407 m_hFont = (HFONT)hFont;
789034a0 408
cbe874bd 409 m_nativeFontInfoOk = true;
09fcd889 410 m_nativeFontInfo = info;
d014871d 411
93692400
JS
412 // This is the best we can do since we don't have the
413 // correct information at this point.
9817be8a 414 m_family = wxFONTFAMILY_SWISS;
b823f5a1
JS
415}
416
0c5d3e1c 417wxFontRefData::~wxFontRefData()
a9249b2e
VZ
418{
419 Free();
420}
421
8e34db1d 422bool wxFontRefData::Alloc(const wxFont *font)
a9249b2e
VZ
423{
424 if ( !m_nativeFontInfoOk )
425 {
d014871d
FM
426 // NOTE: we use wxNativeInfo::InitFromFont to avoid code duplication:
427 // it results in using our m_* variables (except for m_hFont and
428 // for m_nativeFontInfo obviously) for the initialization
429 // of the wxNativeInfo::lf member.
430 m_nativeFontInfo.InitFromFont(*font);
cbe874bd 431 m_nativeFontInfoOk = true;
a9249b2e
VZ
432 }
433
8e34db1d
VZ
434 m_hFont = ::CreateFontIndirect(&m_nativeFontInfo.lf);
435 if ( !m_hFont )
a9249b2e
VZ
436 {
437 wxLogLastError(wxT("CreateFont"));
cbe874bd 438 return false;
a9249b2e
VZ
439 }
440
cbe874bd 441 return true;
a9249b2e
VZ
442}
443
444void wxFontRefData::Free()
2bda0e17 445{
b9b3ccd9 446 if ( m_hFont )
0c5d3e1c 447 {
8e34db1d 448 if ( !::DeleteObject(m_hFont) )
0c5d3e1c 449 {
f6bcfd97 450 wxLogLastError(wxT("DeleteObject(font)"));
0c5d3e1c 451 }
a9249b2e
VZ
452
453 m_hFont = 0;
0c5d3e1c 454 }
2bda0e17
KB
455}
456
09fcd889
VZ
457// ----------------------------------------------------------------------------
458// wxNativeFontInfo
459// ----------------------------------------------------------------------------
460
a9249b2e
VZ
461void wxNativeFontInfo::Init()
462{
463 wxZeroMemory(lf);
64c1effe 464
66160760
VZ
465 // we get better font quality if we use PROOF_QUALITY instead of
466 // DEFAULT_QUALITY but some fonts (e.g. "Terminal 6pt") are not available
467 // then so we allow to set a global option to choose between quality and
468 // wider font selection
99ae6124
WS
469#ifdef __WXWINCE__
470 lf.lfQuality = CLEARTYPE_QUALITY;
471#else
66160760
VZ
472 lf.lfQuality = wxSystemOptions::GetOptionInt(_T("msw.font.no-proof-quality"))
473 ? DEFAULT_QUALITY
474 : PROOF_QUALITY;
99ae6124 475#endif
a9249b2e
VZ
476}
477
478int wxNativeFontInfo::GetPointSize() const
479{
7936354d
VZ
480 // FIXME: using the screen here results in incorrect font size calculation
481 // for printing!
a9249b2e
VZ
482 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
483
ee8fd6b1
VZ
484 // BC++ 2007 doesn't provide abs(long) overload, hence the cast
485 return (int) (((72.0*abs((int)lf.lfHeight)) / (double) ppInch) + 0.5);
a9249b2e
VZ
486}
487
544229d1
VZ
488wxSize wxNativeFontInfo::GetPixelSize() const
489{
490 wxSize ret;
cde96954 491 ret.SetHeight(abs((int)lf.lfHeight));
544229d1
VZ
492 ret.SetWidth(lf.lfWidth);
493 return ret;
494}
495
a9249b2e
VZ
496wxFontStyle wxNativeFontInfo::GetStyle() const
497{
498 return lf.lfItalic ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
499}
500
501wxFontWeight wxNativeFontInfo::GetWeight() const
502{
503 if ( lf.lfWeight <= 300 )
504 return wxFONTWEIGHT_LIGHT;
505
506 if ( lf.lfWeight >= 600 )
507 return wxFONTWEIGHT_BOLD;
508
509 return wxFONTWEIGHT_NORMAL;
510}
511
512bool wxNativeFontInfo::GetUnderlined() const
513{
514 return lf.lfUnderline != 0;
515}
516
517wxString wxNativeFontInfo::GetFaceName() const
518{
519 return lf.lfFaceName;
520}
521
36e2bb4e
RD
522wxFontFamily wxNativeFontInfo::GetFamily() const
523{
9cf8de4c 524 wxFontFamily family;
36e2bb4e 525
9cf8de4c
VZ
526 // extract family from pitch-and-family
527 switch ( lf.lfPitchAndFamily & ~PITCH_MASK )
36e2bb4e
RD
528 {
529 case FF_ROMAN:
9cf8de4c 530 family = wxFONTFAMILY_ROMAN;
36e2bb4e
RD
531 break;
532
9cf8de4c
VZ
533 default:
534 wxFAIL_MSG( _T("unknown LOGFONT::lfFamily value") );
535 // fall through
536
36e2bb4e 537 case FF_SWISS:
9cf8de4c 538 family = wxFONTFAMILY_SWISS;
36e2bb4e
RD
539 break;
540
541 case FF_SCRIPT:
9cf8de4c 542 family = wxFONTFAMILY_SCRIPT;
36e2bb4e
RD
543 break;
544
545 case FF_MODERN:
9cf8de4c 546 family = wxFONTFAMILY_MODERN;
36e2bb4e
RD
547 break;
548
549 case FF_DECORATIVE:
9cf8de4c 550 family = wxFONTFAMILY_DECORATIVE;
36e2bb4e 551 break;
36e2bb4e 552 }
9cf8de4c
VZ
553
554 return family;
36e2bb4e
RD
555}
556
a9249b2e
VZ
557wxFontEncoding wxNativeFontInfo::GetEncoding() const
558{
559 return wxGetFontEncFromCharSet(lf.lfCharSet);
560}
561
562void wxNativeFontInfo::SetPointSize(int pointsize)
563{
7936354d
VZ
564 // FIXME: using the screen here results in incorrect font size calculation
565 // for printing!
a9249b2e
VZ
566 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
567
568 lf.lfHeight = -(int)((pointsize*((double)ppInch)/72.0) + 0.5);
569}
570
544229d1
VZ
571void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize)
572{
b5791cc7
FM
573 // NOTE: although the MSW port allows for negative pixel size heights,
574 // other ports don't and since it's a very useful feature assert
575 // here if we get a negative height:
576 wxCHECK_RET( pixelSize.GetWidth() >= 0 && pixelSize.GetHeight() > 0,
577 "Negative values for the pixel size or zero pixel height are not allowed" );
578
544229d1
VZ
579 lf.lfHeight = pixelSize.GetHeight();
580 lf.lfWidth = pixelSize.GetWidth();
581}
582
a9249b2e
VZ
583void wxNativeFontInfo::SetStyle(wxFontStyle style)
584{
585 switch ( style )
586 {
587 default:
588 wxFAIL_MSG( _T("unknown font style") );
589 // fall through
590
591 case wxFONTSTYLE_NORMAL:
a38d0585 592 lf.lfItalic = FALSE;
a9249b2e
VZ
593 break;
594
595 case wxFONTSTYLE_ITALIC:
596 case wxFONTSTYLE_SLANT:
597 lf.lfItalic = TRUE;
598 break;
599 }
600}
601
602void wxNativeFontInfo::SetWeight(wxFontWeight weight)
603{
604 switch ( weight )
605 {
606 default:
607 wxFAIL_MSG( _T("unknown font weight") );
608 // fall through
609
610 case wxFONTWEIGHT_NORMAL:
611 lf.lfWeight = FW_NORMAL;
612 break;
613
614 case wxFONTWEIGHT_LIGHT:
615 lf.lfWeight = FW_LIGHT;
616 break;
617
618 case wxFONTWEIGHT_BOLD:
619 lf.lfWeight = FW_BOLD;
620 break;
621 }
622}
623
624void wxNativeFontInfo::SetUnderlined(bool underlined)
625{
626 lf.lfUnderline = underlined;
627}
628
85ab460e 629bool wxNativeFontInfo::SetFaceName(const wxString& facename)
a9249b2e 630{
64accea5 631 wxStrlcpy(lf.lfFaceName, facename.c_str(), WXSIZEOF(lf.lfFaceName));
85ab460e 632 return true;
a9249b2e
VZ
633}
634
7936354d
VZ
635void wxNativeFontInfo::SetFamily(wxFontFamily family)
636{
373a5fb3 637 BYTE ff_family;
85ab460e
VZ
638 wxArrayString facename;
639
48a1108e 640 // the list of fonts associated with a family was partially
85ab460e 641 // taken from http://www.codestyle.org/css/font-family
7936354d
VZ
642
643 switch ( family )
644 {
645 case wxSCRIPT:
646 ff_family = FF_SCRIPT;
85ab460e
VZ
647 facename.Add(_T("Script"));
648 facename.Add(_T("Brush Script MT"));
649 facename.Add(_T("Comic Sans MS"));
650 facename.Add(_T("Lucida Handwriting"));
7936354d
VZ
651 break;
652
653 case wxDECORATIVE:
654 ff_family = FF_DECORATIVE;
85ab460e
VZ
655 facename.Add(_T("Old English Text MT"));
656 facename.Add(_T("Comic Sans MS"));
657 facename.Add(_T("Lucida Handwriting"));
7936354d
VZ
658 break;
659
660 case wxROMAN:
661 ff_family = FF_ROMAN;
85ab460e
VZ
662 facename.Add(_T("Times New Roman"));
663 facename.Add(_T("Georgia"));
664 facename.Add(_T("Garamond"));
665 facename.Add(_T("Bookman Old Style"));
666 facename.Add(_T("Book Antiqua"));
7936354d
VZ
667 break;
668
669 case wxTELETYPE:
670 case wxMODERN:
671 ff_family = FF_MODERN;
85ab460e
VZ
672 facename.Add(_T("Courier New"));
673 facename.Add(_T("Lucida Console"));
674 facename.Add(_T("Andale Mono"));
675 facename.Add(_T("OCR A Extended"));
676 facename.Add(_T("Terminal"));
7936354d
VZ
677 break;
678
679 case wxSWISS:
680 ff_family = FF_SWISS;
85ab460e
VZ
681 facename.Add(_T("Arial"));
682 facename.Add(_T("Century Gothic"));
683 facename.Add(_T("Lucida Sans Unicode"));
684 facename.Add(_T("Tahoma"));
685 facename.Add(_T("Trebuchet MS"));
686 facename.Add(_T("Verdana"));
7936354d
VZ
687 break;
688
689 case wxDEFAULT:
690 default:
b4772c24
JS
691 {
692 // We want Windows 2000 or later to have new fonts even MS Shell Dlg
693 // is returned as default GUI font for compatibility
694 int verMaj;
7936354d 695 ff_family = FF_SWISS;
406d283a 696 if(wxGetOsVersion(&verMaj) == wxOS_WINDOWS_NT && verMaj >= 5)
85ab460e 697 facename.Add(_T("MS Shell Dlg 2"));
b4772c24 698 else
85ab460e
VZ
699 facename.Add(_T("MS Shell Dlg"));
700
701 // Quoting the MSDN:
48a1108e
WS
702 // "MS Shell Dlg is a mapping mechanism that enables
703 // U.S. English Microsoft Windows NT, and Microsoft Windows 2000 to
704 // support locales that have characters that are not contained in code
85ab460e 705 // page 1252. It is not a font but a face name for a nonexistent font."
b4772c24 706 }
7936354d
VZ
707 }
708
5c519b6c 709 lf.lfPitchAndFamily = (BYTE)(DEFAULT_PITCH) | ff_family;
7936354d
VZ
710
711 if ( !wxStrlen(lf.lfFaceName) )
712 {
713 SetFaceName(facename);
714 }
715}
716
a9249b2e
VZ
717void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding)
718{
719 wxNativeEncodingInfo info;
720 if ( !wxGetNativeFontEncoding(encoding, &info) )
721 {
bff67a6a 722#if wxUSE_FONTMAP
142b3bc2 723 if ( wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
e7e52b6d
VZ
724 {
725 if ( !info.facename.empty() )
726 {
727 // if we have this encoding only in some particular facename, use
728 // the facename - it is better to show the correct characters in a
729 // wrong facename than unreadable text in a correct one
730 SetFaceName(info.facename);
731 }
732 }
733 else
bff67a6a
VZ
734#endif // wxUSE_FONTMAP
735 {
736 // unsupported encoding, replace with the default
9cf8de4c 737 info.charset = DEFAULT_CHARSET;
bff67a6a 738 }
a9249b2e
VZ
739 }
740
373a5fb3 741 lf.lfCharSet = (BYTE)info.charset;
a9249b2e
VZ
742}
743
09fcd889
VZ
744bool wxNativeFontInfo::FromString(const wxString& s)
745{
746 long l;
747
748 wxStringTokenizer tokenizer(s, _T(";"));
749
a9249b2e 750 // first the version
09fcd889 751 wxString token = tokenizer.GetNextToken();
a9249b2e 752 if ( token != _T('0') )
cbe874bd 753 return false;
09fcd889
VZ
754
755 token = tokenizer.GetNextToken();
756 if ( !token.ToLong(&l) )
cbe874bd 757 return false;
09fcd889
VZ
758 lf.lfHeight = l;
759
760 token = tokenizer.GetNextToken();
761 if ( !token.ToLong(&l) )
cbe874bd 762 return false;
09fcd889
VZ
763 lf.lfWidth = l;
764
765 token = tokenizer.GetNextToken();
766 if ( !token.ToLong(&l) )
cbe874bd 767 return false;
09fcd889
VZ
768 lf.lfEscapement = l;
769
770 token = tokenizer.GetNextToken();
771 if ( !token.ToLong(&l) )
cbe874bd 772 return false;
09fcd889
VZ
773 lf.lfOrientation = l;
774
775 token = tokenizer.GetNextToken();
776 if ( !token.ToLong(&l) )
cbe874bd 777 return false;
09fcd889
VZ
778 lf.lfWeight = l;
779
780 token = tokenizer.GetNextToken();
781 if ( !token.ToLong(&l) )
cbe874bd 782 return false;
33ac7e6f 783 lf.lfItalic = (BYTE)l;
09fcd889
VZ
784
785 token = tokenizer.GetNextToken();
786 if ( !token.ToLong(&l) )
cbe874bd 787 return false;
33ac7e6f 788 lf.lfUnderline = (BYTE)l;
09fcd889
VZ
789
790 token = tokenizer.GetNextToken();
791 if ( !token.ToLong(&l) )
cbe874bd 792 return false;
33ac7e6f 793 lf.lfStrikeOut = (BYTE)l;
09fcd889
VZ
794
795 token = tokenizer.GetNextToken();
796 if ( !token.ToLong(&l) )
cbe874bd 797 return false;
33ac7e6f 798 lf.lfCharSet = (BYTE)l;
09fcd889
VZ
799
800 token = tokenizer.GetNextToken();
801 if ( !token.ToLong(&l) )
cbe874bd 802 return false;
33ac7e6f 803 lf.lfOutPrecision = (BYTE)l;
09fcd889
VZ
804
805 token = tokenizer.GetNextToken();
806 if ( !token.ToLong(&l) )
cbe874bd 807 return false;
33ac7e6f 808 lf.lfClipPrecision = (BYTE)l;
09fcd889
VZ
809
810 token = tokenizer.GetNextToken();
811 if ( !token.ToLong(&l) )
cbe874bd 812 return false;
33ac7e6f 813 lf.lfQuality = (BYTE)l;
09fcd889
VZ
814
815 token = tokenizer.GetNextToken();
816 if ( !token.ToLong(&l) )
cbe874bd 817 return false;
33ac7e6f 818 lf.lfPitchAndFamily = (BYTE)l;
09fcd889
VZ
819
820 token = tokenizer.GetNextToken();
821 if(!token)
cbe874bd 822 return false;
09fcd889
VZ
823 wxStrcpy(lf.lfFaceName, token.c_str());
824
cbe874bd 825 return true;
09fcd889
VZ
826}
827
828wxString wxNativeFontInfo::ToString() const
829{
830 wxString s;
831
4244c20b 832 s.Printf(_T("%d;%ld;%ld;%ld;%ld;%ld;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
09fcd889
VZ
833 0, // version, in case we want to change the format later
834 lf.lfHeight,
835 lf.lfWidth,
836 lf.lfEscapement,
837 lf.lfOrientation,
838 lf.lfWeight,
839 lf.lfItalic,
840 lf.lfUnderline,
841 lf.lfStrikeOut,
842 lf.lfCharSet,
843 lf.lfOutPrecision,
844 lf.lfClipPrecision,
845 lf.lfQuality,
846 lf.lfPitchAndFamily,
c9f78968 847 (const wxChar*)lf.lfFaceName);
09fcd889
VZ
848
849 return s;
850}
851
0c5d3e1c
VZ
852// ----------------------------------------------------------------------------
853// wxFont
854// ----------------------------------------------------------------------------
855
d014871d
FM
856wxFont::wxFont(const wxString& fontdesc)
857{
858 wxNativeFontInfo info;
859 if ( info.FromString(fontdesc) )
860 (void)Create(info);
861}
862
04ef50df 863bool wxFont::Create(const wxNativeFontInfo& info, WXHFONT hFont)
76e23cdb 864{
09fcd889
VZ
865 UnRef();
866
04ef50df 867 m_refData = new wxFontRefData(info, hFont);
09fcd889 868
adbd3cbc 869 return RealizeResource();
76e23cdb
VZ
870}
871
df455719
VZ
872bool wxFont::DoCreate(int pointSize,
873 const wxSize& pixelSize,
874 bool sizeUsingPixels,
0c14b6c3
FM
875 wxFontFamily family,
876 wxFontStyle style,
877 wxFontWeight weight,
df455719
VZ
878 bool underlined,
879 const wxString& faceName,
880 wxFontEncoding encoding)
2bda0e17 881{
0c5d3e1c 882 UnRef();
3ca6a5f0
BP
883
884 // wxDEFAULT is a valid value for the font size too so we must treat it
885 // specially here (otherwise the size would be 70 == wxDEFAULT value)
886 if ( pointSize == wxDEFAULT )
a9249b2e
VZ
887 {
888 pointSize = wxNORMAL_FONT->GetPointSize();
889 }
3ca6a5f0 890
544229d1
VZ
891 m_refData = new wxFontRefData(pointSize, pixelSize, sizeUsingPixels,
892 family, style, weight,
0c5d3e1c 893 underlined, faceName, encoding);
2bda0e17 894
adbd3cbc 895 return RealizeResource();
2bda0e17
KB
896}
897
898wxFont::~wxFont()
899{
2bda0e17
KB
900}
901
0c5d3e1c
VZ
902// ----------------------------------------------------------------------------
903// real implementation
904// ----------------------------------------------------------------------------
905
8f884a0d 906wxGDIRefData *wxFont::CreateGDIRefData() const
f030b28c
VZ
907{
908 return new wxFontRefData();
909}
910
8f884a0d 911wxGDIRefData *wxFont::CloneGDIRefData(const wxGDIRefData *data) const
f030b28c 912{
5c33522f 913 return new wxFontRefData(*static_cast<const wxFontRefData *>(data));
f030b28c
VZ
914}
915
0c5d3e1c 916bool wxFont::RealizeResource()
2bda0e17 917{
d014871d
FM
918 // NOTE: the GetHFONT() call automatically triggers a reallocation of
919 // the HFONT if necessary (will do nothing if we already have the resource);
920 // it returns NULL only if there is a failure in wxFontRefData::Alloc()...
921 return GetHFONT() != NULL;
2bda0e17
KB
922}
923
33ac7e6f 924bool wxFont::FreeResource(bool WXUNUSED(force))
2bda0e17 925{
d014871d 926 if ( !M_FONTDATA )
adbd3cbc 927 return false;
0c5d3e1c 928
adbd3cbc 929 M_FONTDATA->Free();
a9249b2e 930
adbd3cbc 931 return true;
2bda0e17
KB
932}
933
2b5f62a0 934WXHANDLE wxFont::GetResourceHandle() const
f6bcfd97 935{
2b5f62a0 936 return (WXHANDLE)GetHFONT();
f6bcfd97
BP
937}
938
939WXHFONT wxFont::GetHFONT() const
2bda0e17 940{
d014871d
FM
941 // NOTE: wxFontRefData::GetHFONT() will automatically call
942 // wxFontRefData::Alloc() if necessary
8e34db1d 943 return M_FONTDATA ? M_FONTDATA->GetHFONT(this) : 0;
2bda0e17
KB
944}
945
e90babdf 946bool wxFont::IsFree() const
2bda0e17 947{
8e34db1d 948 return M_FONTDATA && !M_FONTDATA->HasHFONT();
adbd3cbc
VZ
949}
950
0c5d3e1c
VZ
951// ----------------------------------------------------------------------------
952// change font attribute: we recreate font when doing it
953// ----------------------------------------------------------------------------
954
debe6624 955void wxFont::SetPointSize(int pointSize)
2bda0e17 956{
f030b28c 957 AllocExclusive();
b823f5a1 958
8e34db1d 959 M_FONTDATA->Free();
a9249b2e 960 M_FONTDATA->SetPointSize(pointSize);
2bda0e17
KB
961}
962
544229d1
VZ
963void wxFont::SetPixelSize(const wxSize& pixelSize)
964{
f030b28c 965 AllocExclusive();
544229d1
VZ
966
967 M_FONTDATA->SetPixelSize(pixelSize);
544229d1
VZ
968}
969
0c14b6c3 970void wxFont::SetFamily(wxFontFamily family)
2bda0e17 971{
f030b28c 972 AllocExclusive();
b823f5a1 973
a9249b2e 974 M_FONTDATA->SetFamily(family);
2bda0e17
KB
975}
976
0c14b6c3 977void wxFont::SetStyle(wxFontStyle style)
2bda0e17 978{
f030b28c 979 AllocExclusive();
b823f5a1 980
a9249b2e 981 M_FONTDATA->SetStyle(style);
2bda0e17
KB
982}
983
0c14b6c3 984void wxFont::SetWeight(wxFontWeight weight)
2bda0e17 985{
f030b28c 986 AllocExclusive();
b823f5a1 987
a9249b2e 988 M_FONTDATA->SetWeight(weight);
2bda0e17
KB
989}
990
85ab460e 991bool wxFont::SetFaceName(const wxString& faceName)
2bda0e17 992{
f030b28c 993 AllocExclusive();
b823f5a1 994
8e34db1d
VZ
995 if ( !M_FONTDATA->SetFaceName(faceName) )
996 return false;
85ab460e
VZ
997
998 // NB: using win32's GetObject() API on M_FONTDATA->GetHFONT()
999 // to retrieve a LOGFONT and then compare lf.lfFaceName
1000 // with given facename is not reliable at all:
1001 // Windows copies the facename given to ::CreateFontIndirect()
1002 // without any validity check.
1003 // Thus we use wxFontBase::SetFaceName to check if facename
1004 // is valid...
8e34db1d 1005 return wxFontBase::SetFaceName(faceName);
2bda0e17
KB
1006}
1007
debe6624 1008void wxFont::SetUnderlined(bool underlined)
2bda0e17 1009{
f030b28c 1010 AllocExclusive();
b823f5a1 1011
a9249b2e 1012 M_FONTDATA->SetUnderlined(underlined);
2bda0e17
KB
1013}
1014
0c5d3e1c 1015void wxFont::SetEncoding(wxFontEncoding encoding)
2bda0e17 1016{
f030b28c 1017 AllocExclusive();
0c5d3e1c 1018
a9249b2e 1019 M_FONTDATA->SetEncoding(encoding);
09fcd889
VZ
1020}
1021
9045ad9d 1022void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info)
09fcd889 1023{
f030b28c 1024 AllocExclusive();
09fcd889 1025
8e34db1d 1026 M_FONTDATA->SetNativeFontInfo(info);
0c5d3e1c
VZ
1027}
1028
1029// ----------------------------------------------------------------------------
1030// accessors
1031// ----------------------------------------------------------------------------
1032
1033int wxFont::GetPointSize() const
1034{
d014871d 1035 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
789034a0 1036
a9249b2e 1037 return M_FONTDATA->GetPointSize();
0c5d3e1c
VZ
1038}
1039
544229d1
VZ
1040wxSize wxFont::GetPixelSize() const
1041{
d014871d 1042 wxCHECK_MSG( IsOk(), wxDefaultSize, wxT("invalid font") );
68585e17 1043
544229d1
VZ
1044 return M_FONTDATA->GetPixelSize();
1045}
1046
1047bool wxFont::IsUsingSizeInPixels() const
1048{
d014871d 1049 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
544229d1
VZ
1050
1051 return M_FONTDATA->IsUsingSizeInPixels();
1052}
1053
0c14b6c3 1054wxFontFamily wxFont::GetFamily() const
0c5d3e1c 1055{
d014871d 1056 wxCHECK_MSG( IsOk(), wxFONTFAMILY_MAX, wxT("invalid font") );
789034a0 1057
a9249b2e 1058 return M_FONTDATA->GetFamily();
2bda0e17
KB
1059}
1060
0c14b6c3 1061wxFontStyle wxFont::GetStyle() const
2bda0e17 1062{
d014871d 1063 wxCHECK_MSG( IsOk(), wxFONTSTYLE_MAX, wxT("invalid font") );
789034a0 1064
a9249b2e 1065 return M_FONTDATA->GetStyle();
2bda0e17
KB
1066}
1067
0c14b6c3 1068wxFontWeight wxFont::GetWeight() const
2bda0e17 1069{
d014871d 1070 wxCHECK_MSG( IsOk(), wxFONTWEIGHT_MAX, wxT("invalid font") );
789034a0 1071
a9249b2e 1072 return M_FONTDATA->GetWeight();
2bda0e17
KB
1073}
1074
0c5d3e1c
VZ
1075bool wxFont::GetUnderlined() const
1076{
d014871d 1077 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
789034a0 1078
a9249b2e 1079 return M_FONTDATA->GetUnderlined();
0c5d3e1c
VZ
1080}
1081
1082wxString wxFont::GetFaceName() const
1083{
d014871d 1084 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
789034a0 1085
a9249b2e 1086 return M_FONTDATA->GetFaceName();
0c5d3e1c
VZ
1087}
1088
1089wxFontEncoding wxFont::GetEncoding() const
1090{
d014871d 1091 wxCHECK_MSG( IsOk(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
789034a0 1092
a9249b2e 1093 return M_FONTDATA->GetEncoding();
0c5d3e1c 1094}
a1d58ddc 1095
3bf5a59b 1096const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
1e6feb95 1097{
d014871d 1098 return IsOk() && M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
3bf5a59b 1099 : NULL;
09fcd889
VZ
1100}
1101
85ab460e
VZ
1102wxString wxFont::GetNativeFontInfoDesc() const
1103{
d014871d 1104 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
68585e17 1105
85ab460e 1106 // be sure we have an HFONT associated...
d014871d 1107 const_cast<wxFont*>(this)->RealizeResource();
85ab460e
VZ
1108 return wxFontBase::GetNativeFontInfoDesc();
1109}
1110
1111wxString wxFont::GetNativeFontInfoUserDesc() const
1112{
d014871d 1113 wxCHECK_MSG( IsOk(), wxEmptyString, wxT("invalid font") );
68585e17 1114
85ab460e 1115 // be sure we have an HFONT associated...
d014871d 1116 const_cast<wxFont*>(this)->RealizeResource();
85ab460e
VZ
1117 return wxFontBase::GetNativeFontInfoUserDesc();
1118}
1119
9cf8de4c
VZ
1120bool wxFont::IsFixedWidth() const
1121{
d014871d
FM
1122 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
1123
9cf8de4c
VZ
1124 if ( M_FONTDATA->HasNativeFontInfo() )
1125 {
1126 // the two low-order bits specify the pitch of the font, the rest is
1127 // family
907173e5
WS
1128 BYTE pitch =
1129 (BYTE)(M_FONTDATA->GetNativeFontInfo().lf.lfPitchAndFamily & PITCH_MASK);
9cf8de4c
VZ
1130
1131 return pitch == FIXED_PITCH;
1132 }
1133
1134 return wxFontBase::IsFixedWidth();
1135}