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