]> git.saurik.com Git - wxWidgets.git/blob - src/msw/font.cpp
Return correct values for GetFieldRect() when using themes.
[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 #ifndef WX_PRECOMP
28 #include "wx/setup.h"
29 #include "wx/list.h"
30 #include "wx/utils.h"
31 #include "wx/app.h"
32 #include "wx/font.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 void SetFaceName(const wxString& faceName)
261 {
262 if ( m_nativeFontInfoOk )
263 m_nativeFontInfo.SetFaceName(faceName);
264 else
265 m_faceName = faceName;
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
290 protected:
291 // common part of all ctors
292 void Init(int size,
293 const wxSize& pixelSize,
294 bool sizeUsingPixels,
295 int family,
296 int style,
297 int weight,
298 bool underlined,
299 const wxString& faceName,
300 wxFontEncoding encoding);
301
302 void Init(const wxNativeFontInfo& info, WXHFONT hFont = 0);
303
304 // font characterstics
305 int m_pointSize;
306 wxSize m_pixelSize;
307 bool m_sizeUsingPixels;
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;
317
318 // Native font info
319 wxNativeFontInfo m_nativeFontInfo;
320 bool m_nativeFontInfoOk;
321 };
322
323 // ============================================================================
324 // implementation
325 // ============================================================================
326
327 // ----------------------------------------------------------------------------
328 // wxFontRefData
329 // ----------------------------------------------------------------------------
330
331 void wxFontRefData::Init(int pointSize,
332 const wxSize& pixelSize,
333 bool sizeUsingPixels,
334 int family,
335 int style,
336 int weight,
337 bool underlined,
338 const wxString& faceName,
339 wxFontEncoding encoding)
340 {
341 m_style = style;
342 m_pointSize = pointSize == -1 ? wxNORMAL_FONT->GetPointSize() : pointSize;
343 m_pixelSize = pixelSize;
344 m_sizeUsingPixels = sizeUsingPixels;
345 m_family = family;
346 m_style = style;
347 m_weight = weight;
348 m_underlined = underlined;
349 m_faceName = faceName;
350 m_encoding = encoding;
351
352 m_hFont = 0;
353
354 m_nativeFontInfoOk = false;
355 }
356
357 void wxFontRefData::Init(const wxNativeFontInfo& info, WXHFONT hFont)
358 {
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;
364
365 m_nativeFontInfoOk = true;
366 m_nativeFontInfo = info;
367 // This is the best we can do since we don't have the
368 // correct information at this point.
369 m_family = wxSWISS;
370 }
371
372 wxFontRefData::~wxFontRefData()
373 {
374 Free();
375 }
376
377 bool wxFontRefData::Alloc(wxFont *font)
378 {
379 if ( !m_nativeFontInfoOk )
380 {
381 wxFillLogFont(&m_nativeFontInfo.lf, font);
382 m_nativeFontInfoOk = true;
383 }
384
385 HFONT hfont = ::CreateFontIndirect(&m_nativeFontInfo.lf);
386 if ( !hfont )
387 {
388 wxLogLastError(wxT("CreateFont"));
389
390 return false;
391 }
392
393 m_hFont = (WXHFONT)hfont;
394
395 return true;
396 }
397
398 void wxFontRefData::Free()
399 {
400 if ( m_hFont )
401 {
402 if ( !::DeleteObject((HFONT) m_hFont) )
403 {
404 wxLogLastError(wxT("DeleteObject(font)"));
405 }
406
407 m_hFont = 0;
408 }
409 }
410
411 // ----------------------------------------------------------------------------
412 // wxNativeFontInfo
413 // ----------------------------------------------------------------------------
414
415 void wxNativeFontInfo::Init()
416 {
417 wxZeroMemory(lf);
418 }
419
420 int wxNativeFontInfo::GetPointSize() const
421 {
422 // FIXME: using the screen here results in incorrect font size calculation
423 // for printing!
424 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
425
426 return (int) (((72.0*(double)abs(lf.lfHeight)) / (double) ppInch) + 0.5);
427 }
428
429 wxSize wxNativeFontInfo::GetPixelSize() const
430 {
431 wxSize ret;
432 ret.SetHeight(lf.lfHeight);
433 ret.SetWidth(lf.lfWidth);
434 return ret;
435 }
436
437 wxFontStyle wxNativeFontInfo::GetStyle() const
438 {
439 return lf.lfItalic ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
440 }
441
442 wxFontWeight wxNativeFontInfo::GetWeight() const
443 {
444 if ( lf.lfWeight <= 300 )
445 return wxFONTWEIGHT_LIGHT;
446
447 if ( lf.lfWeight >= 600 )
448 return wxFONTWEIGHT_BOLD;
449
450 return wxFONTWEIGHT_NORMAL;
451 }
452
453 bool wxNativeFontInfo::GetUnderlined() const
454 {
455 return lf.lfUnderline != 0;
456 }
457
458 wxString wxNativeFontInfo::GetFaceName() const
459 {
460 return lf.lfFaceName;
461 }
462
463 wxFontFamily wxNativeFontInfo::GetFamily() const
464 {
465 wxFontFamily family;
466
467 // extract family from pitch-and-family
468 switch ( lf.lfPitchAndFamily & ~PITCH_MASK )
469 {
470 case FF_ROMAN:
471 family = wxFONTFAMILY_ROMAN;
472 break;
473
474 default:
475 wxFAIL_MSG( _T("unknown LOGFONT::lfFamily value") );
476 // fall through
477
478 case FF_SWISS:
479 family = wxFONTFAMILY_SWISS;
480 break;
481
482 case FF_SCRIPT:
483 family = wxFONTFAMILY_SCRIPT;
484 break;
485
486 case FF_MODERN:
487 family = wxFONTFAMILY_MODERN;
488 break;
489
490 case FF_DECORATIVE:
491 family = wxFONTFAMILY_DECORATIVE;
492 break;
493 }
494
495 return family;
496 }
497
498 wxFontEncoding wxNativeFontInfo::GetEncoding() const
499 {
500 return wxGetFontEncFromCharSet(lf.lfCharSet);
501 }
502
503 void wxNativeFontInfo::SetPointSize(int pointsize)
504 {
505 // FIXME: using the screen here results in incorrect font size calculation
506 // for printing!
507 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
508
509 lf.lfHeight = -(int)((pointsize*((double)ppInch)/72.0) + 0.5);
510 }
511
512 void wxNativeFontInfo::SetPixelSize(const wxSize& pixelSize)
513 {
514 lf.lfHeight = pixelSize.GetHeight();
515 lf.lfWidth = pixelSize.GetWidth();
516 }
517
518
519 void wxNativeFontInfo::SetStyle(wxFontStyle style)
520 {
521 switch ( style )
522 {
523 default:
524 wxFAIL_MSG( _T("unknown font style") );
525 // fall through
526
527 case wxFONTSTYLE_NORMAL:
528 lf.lfItalic = FALSE;
529 break;
530
531 case wxFONTSTYLE_ITALIC:
532 case wxFONTSTYLE_SLANT:
533 lf.lfItalic = TRUE;
534 break;
535 }
536 }
537
538 void wxNativeFontInfo::SetWeight(wxFontWeight weight)
539 {
540 switch ( weight )
541 {
542 default:
543 wxFAIL_MSG( _T("unknown font weight") );
544 // fall through
545
546 case wxFONTWEIGHT_NORMAL:
547 lf.lfWeight = FW_NORMAL;
548 break;
549
550 case wxFONTWEIGHT_LIGHT:
551 lf.lfWeight = FW_LIGHT;
552 break;
553
554 case wxFONTWEIGHT_BOLD:
555 lf.lfWeight = FW_BOLD;
556 break;
557 }
558 }
559
560 void wxNativeFontInfo::SetUnderlined(bool underlined)
561 {
562 lf.lfUnderline = underlined;
563 }
564
565 void wxNativeFontInfo::SetFaceName(const wxString& facename)
566 {
567 wxStrncpy(lf.lfFaceName, facename, WXSIZEOF(lf.lfFaceName));
568 }
569
570 void wxNativeFontInfo::SetFamily(wxFontFamily family)
571 {
572 BYTE ff_family;
573 wxString facename;
574
575 switch ( family )
576 {
577 case wxSCRIPT:
578 ff_family = FF_SCRIPT;
579 facename = _T("Script");
580 break;
581
582 case wxDECORATIVE:
583 ff_family = FF_DECORATIVE;
584 facename = _T("Old English Text MT");
585 break;
586
587 case wxROMAN:
588 ff_family = FF_ROMAN;
589 facename = _T("Times New Roman");
590 break;
591
592 case wxTELETYPE:
593 case wxMODERN:
594 ff_family = FF_MODERN;
595 facename = _T("Courier New");
596 break;
597
598 case wxSWISS:
599 ff_family = FF_SWISS;
600 facename = _T("Arial");
601 break;
602
603 case wxDEFAULT:
604 default:
605 {
606 // We want Windows 2000 or later to have new fonts even MS Shell Dlg
607 // is returned as default GUI font for compatibility
608 int verMaj;
609 ff_family = FF_SWISS;
610 if(wxGetOsVersion(&verMaj) == wxWINDOWS_NT && verMaj >= 5)
611 facename = _T("MS Shell Dlg 2");
612 else
613 facename = _T("MS Shell Dlg");
614 }
615 }
616
617 lf.lfPitchAndFamily = (BYTE)(DEFAULT_PITCH) | ff_family;
618
619 if ( !wxStrlen(lf.lfFaceName) )
620 {
621 SetFaceName(facename);
622 }
623 }
624
625 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding)
626 {
627 wxNativeEncodingInfo info;
628 if ( !wxGetNativeFontEncoding(encoding, &info) )
629 {
630 #if wxUSE_FONTMAP
631 if ( wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
632 {
633 if ( !info.facename.empty() )
634 {
635 // if we have this encoding only in some particular facename, use
636 // the facename - it is better to show the correct characters in a
637 // wrong facename than unreadable text in a correct one
638 SetFaceName(info.facename);
639 }
640 }
641 else
642 #endif // wxUSE_FONTMAP
643 {
644 // unsupported encoding, replace with the default
645 info.charset = DEFAULT_CHARSET;
646 }
647 }
648
649 lf.lfCharSet = (BYTE)info.charset;
650 }
651
652 bool wxNativeFontInfo::FromString(const wxString& s)
653 {
654 long l;
655
656 wxStringTokenizer tokenizer(s, _T(";"));
657
658 // first the version
659 wxString token = tokenizer.GetNextToken();
660 if ( token != _T('0') )
661 return false;
662
663 token = tokenizer.GetNextToken();
664 if ( !token.ToLong(&l) )
665 return false;
666 lf.lfHeight = l;
667
668 token = tokenizer.GetNextToken();
669 if ( !token.ToLong(&l) )
670 return false;
671 lf.lfWidth = l;
672
673 token = tokenizer.GetNextToken();
674 if ( !token.ToLong(&l) )
675 return false;
676 lf.lfEscapement = l;
677
678 token = tokenizer.GetNextToken();
679 if ( !token.ToLong(&l) )
680 return false;
681 lf.lfOrientation = l;
682
683 token = tokenizer.GetNextToken();
684 if ( !token.ToLong(&l) )
685 return false;
686 lf.lfWeight = l;
687
688 token = tokenizer.GetNextToken();
689 if ( !token.ToLong(&l) )
690 return false;
691 lf.lfItalic = (BYTE)l;
692
693 token = tokenizer.GetNextToken();
694 if ( !token.ToLong(&l) )
695 return false;
696 lf.lfUnderline = (BYTE)l;
697
698 token = tokenizer.GetNextToken();
699 if ( !token.ToLong(&l) )
700 return false;
701 lf.lfStrikeOut = (BYTE)l;
702
703 token = tokenizer.GetNextToken();
704 if ( !token.ToLong(&l) )
705 return false;
706 lf.lfCharSet = (BYTE)l;
707
708 token = tokenizer.GetNextToken();
709 if ( !token.ToLong(&l) )
710 return false;
711 lf.lfOutPrecision = (BYTE)l;
712
713 token = tokenizer.GetNextToken();
714 if ( !token.ToLong(&l) )
715 return false;
716 lf.lfClipPrecision = (BYTE)l;
717
718 token = tokenizer.GetNextToken();
719 if ( !token.ToLong(&l) )
720 return false;
721 lf.lfQuality = (BYTE)l;
722
723 token = tokenizer.GetNextToken();
724 if ( !token.ToLong(&l) )
725 return false;
726 lf.lfPitchAndFamily = (BYTE)l;
727
728 token = tokenizer.GetNextToken();
729 if(!token)
730 return false;
731 wxStrcpy(lf.lfFaceName, token.c_str());
732
733 return true;
734 }
735
736 wxString wxNativeFontInfo::ToString() const
737 {
738 wxString s;
739
740 s.Printf(_T("%d;%ld;%ld;%ld;%ld;%ld;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
741 0, // version, in case we want to change the format later
742 lf.lfHeight,
743 lf.lfWidth,
744 lf.lfEscapement,
745 lf.lfOrientation,
746 lf.lfWeight,
747 lf.lfItalic,
748 lf.lfUnderline,
749 lf.lfStrikeOut,
750 lf.lfCharSet,
751 lf.lfOutPrecision,
752 lf.lfClipPrecision,
753 lf.lfQuality,
754 lf.lfPitchAndFamily,
755 lf.lfFaceName);
756
757 return s;
758 }
759
760 // ----------------------------------------------------------------------------
761 // wxFont
762 // ----------------------------------------------------------------------------
763
764 void wxFont::Init()
765 {
766 }
767
768 bool wxFont::Create(const wxNativeFontInfo& info, WXHFONT hFont)
769 {
770 UnRef();
771
772 m_refData = new wxFontRefData(info, hFont);
773
774 RealizeResource();
775
776 return true;
777 }
778
779 wxFont::wxFont(const wxString& fontdesc)
780 {
781 wxNativeFontInfo info;
782 if ( info.FromString(fontdesc) )
783 (void)Create(info);
784 }
785
786 /* Constructor for a font. Note that the real construction is done
787 * in wxDC::SetFont, when information is available about scaling etc.
788 */
789 bool wxFont::DoCreate(int pointSize,
790 const wxSize& pixelSize,
791 bool sizeUsingPixels,
792 int family,
793 int style,
794 int weight,
795 bool underlined,
796 const wxString& faceName,
797 wxFontEncoding encoding)
798 {
799 UnRef();
800
801 // wxDEFAULT is a valid value for the font size too so we must treat it
802 // specially here (otherwise the size would be 70 == wxDEFAULT value)
803 if ( pointSize == wxDEFAULT )
804 {
805 pointSize = wxNORMAL_FONT->GetPointSize();
806 }
807
808 m_refData = new wxFontRefData(pointSize, pixelSize, sizeUsingPixels,
809 family, style, weight,
810 underlined, faceName, encoding);
811
812 RealizeResource();
813
814 return true;
815 }
816
817 wxFont::~wxFont()
818 {
819 }
820
821 // ----------------------------------------------------------------------------
822 // real implementation
823 // ----------------------------------------------------------------------------
824
825 bool wxFont::RealizeResource()
826 {
827 if ( GetResourceHandle() )
828 {
829 // VZ: the old code returned false in this case, but it doesn't seem
830 // to make sense because the font _was_ created
831 return true;
832 }
833
834 return M_FONTDATA->Alloc(this);
835 }
836
837 bool wxFont::FreeResource(bool WXUNUSED(force))
838 {
839 if ( GetResourceHandle() )
840 {
841 M_FONTDATA->Free();
842
843 return true;
844 }
845
846 return false;
847 }
848
849 WXHANDLE wxFont::GetResourceHandle() const
850 {
851 return (WXHANDLE)GetHFONT();
852 }
853
854 WXHFONT wxFont::GetHFONT() const
855 {
856 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
857 }
858
859 bool wxFont::IsFree() const
860 {
861 return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0);
862 }
863
864 void wxFont::Unshare()
865 {
866 // Don't change shared data
867 if ( !m_refData )
868 {
869 m_refData = new wxFontRefData();
870 }
871 else
872 {
873 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
874 UnRef();
875 m_refData = ref;
876 }
877 }
878
879 // ----------------------------------------------------------------------------
880 // change font attribute: we recreate font when doing it
881 // ----------------------------------------------------------------------------
882
883 void wxFont::SetPointSize(int pointSize)
884 {
885 Unshare();
886
887 M_FONTDATA->SetPointSize(pointSize);
888
889 RealizeResource();
890 }
891
892 void wxFont::SetPixelSize(const wxSize& pixelSize)
893 {
894 Unshare();
895
896 M_FONTDATA->SetPixelSize(pixelSize);
897
898 RealizeResource();
899 }
900
901 void wxFont::SetFamily(int family)
902 {
903 Unshare();
904
905 M_FONTDATA->SetFamily(family);
906
907 RealizeResource();
908 }
909
910 void wxFont::SetStyle(int style)
911 {
912 Unshare();
913
914 M_FONTDATA->SetStyle(style);
915
916 RealizeResource();
917 }
918
919 void wxFont::SetWeight(int weight)
920 {
921 Unshare();
922
923 M_FONTDATA->SetWeight(weight);
924
925 RealizeResource();
926 }
927
928 void wxFont::SetFaceName(const wxString& faceName)
929 {
930 Unshare();
931
932 M_FONTDATA->SetFaceName(faceName);
933
934 RealizeResource();
935 }
936
937 void wxFont::SetUnderlined(bool underlined)
938 {
939 Unshare();
940
941 M_FONTDATA->SetUnderlined(underlined);
942
943 RealizeResource();
944 }
945
946 void wxFont::SetEncoding(wxFontEncoding encoding)
947 {
948 Unshare();
949
950 M_FONTDATA->SetEncoding(encoding);
951
952 RealizeResource();
953 }
954
955 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo& info)
956 {
957 Unshare();
958
959 FreeResource();
960
961 *M_FONTDATA = wxFontRefData(info);
962
963 RealizeResource();
964 }
965
966 // ----------------------------------------------------------------------------
967 // accessors
968 // ----------------------------------------------------------------------------
969
970 int wxFont::GetPointSize() const
971 {
972 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
973
974 return M_FONTDATA->GetPointSize();
975 }
976
977 wxSize wxFont::GetPixelSize() const
978 {
979 return M_FONTDATA->GetPixelSize();
980 }
981
982 bool wxFont::IsUsingSizeInPixels() const
983 {
984 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
985
986 return M_FONTDATA->IsUsingSizeInPixels();
987 }
988
989 int wxFont::GetFamily() const
990 {
991 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
992
993 return M_FONTDATA->GetFamily();
994 }
995
996 int wxFont::GetStyle() const
997 {
998 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
999
1000 return M_FONTDATA->GetStyle();
1001 }
1002
1003 int wxFont::GetWeight() const
1004 {
1005 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
1006
1007 return M_FONTDATA->GetWeight();
1008 }
1009
1010 bool wxFont::GetUnderlined() const
1011 {
1012 wxCHECK_MSG( Ok(), false, wxT("invalid font") );
1013
1014 return M_FONTDATA->GetUnderlined();
1015 }
1016
1017 wxString wxFont::GetFaceName() const
1018 {
1019 wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid font") );
1020
1021 return M_FONTDATA->GetFaceName();
1022 }
1023
1024 wxFontEncoding wxFont::GetEncoding() const
1025 {
1026 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
1027
1028 return M_FONTDATA->GetEncoding();
1029 }
1030
1031 const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
1032 {
1033 return M_FONTDATA->HasNativeFontInfo() ? &(M_FONTDATA->GetNativeFontInfo())
1034 : NULL;
1035 }
1036
1037 bool wxFont::IsFixedWidth() const
1038 {
1039 if ( M_FONTDATA->HasNativeFontInfo() )
1040 {
1041 // the two low-order bits specify the pitch of the font, the rest is
1042 // family
1043 BYTE pitch =
1044 (BYTE)(M_FONTDATA->GetNativeFontInfo().lf.lfPitchAndFamily & PITCH_MASK);
1045
1046 return pitch == FIXED_PITCH;
1047 }
1048
1049 return wxFontBase::IsFixedWidth();
1050 }
1051