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