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