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