]> git.saurik.com Git - wxWidgets.git/blob - src/msw/font.cpp
memory leak fixed
[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) wxWindows team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
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 #endif // WX_PRECOMP
39
40 #include "wx/msw/private.h"
41
42 #include "wx/fontutil.h"
43 #include "wx/fontmap.h"
44
45 #include "wx/tokenzr.h"
46
47 IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
48
49 // ----------------------------------------------------------------------------
50 // constants
51 // ----------------------------------------------------------------------------
52
53 // ----------------------------------------------------------------------------
54 // wxFontRefData - the internal description of the font
55 // ----------------------------------------------------------------------------
56
57 class WXDLLEXPORT wxFontRefData: public wxGDIRefData
58 {
59 public:
60 // constructors
61 wxFontRefData()
62 {
63 Init(-1, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
64 FALSE, _T(""), wxFONTENCODING_DEFAULT);
65 }
66
67 wxFontRefData(int size,
68 int family,
69 int style,
70 int weight,
71 bool underlined,
72 const wxString& faceName,
73 wxFontEncoding encoding)
74 {
75 Init(size, family, style, weight, underlined, faceName, encoding);
76 }
77
78 wxFontRefData(const wxNativeFontInfo& info, WXHFONT hFont = 0)
79 {
80 Init(info, hFont);
81 }
82
83 wxFontRefData(const wxFontRefData& data)
84 {
85 if ( data.m_nativeFontInfoOk )
86 {
87 Init(data.m_nativeFontInfo);
88 }
89 else
90 {
91 Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
92 data.m_underlined, data.m_faceName, data.m_encoding);
93 }
94 }
95
96 virtual ~wxFontRefData();
97
98 // operations
99 bool Alloc(wxFont *font);
100
101 void Free();
102
103 // all wxFont accessors
104 int GetPointSize() const
105 {
106 return m_nativeFontInfoOk ? m_nativeFontInfo.GetPointSize()
107 : m_pointSize;
108 }
109
110 int GetFamily() const
111 {
112 return m_family;
113 }
114
115 int GetStyle() const
116 {
117 return m_nativeFontInfoOk ? m_nativeFontInfo.GetStyle()
118 : m_style;
119 }
120
121 int GetWeight() const
122 {
123 return m_nativeFontInfoOk ? m_nativeFontInfo.GetWeight()
124 : m_weight;
125 }
126
127 bool GetUnderlined() const
128 {
129 return m_nativeFontInfoOk ? m_nativeFontInfo.GetUnderlined()
130 : m_underlined;
131 }
132
133 wxString GetFaceName() const
134 {
135 wxString s;
136 if ( m_nativeFontInfoOk )
137 s = m_nativeFontInfo.GetFaceName();
138 else
139 s = m_faceName;
140
141 return s;
142 }
143
144 wxFontEncoding GetEncoding() const
145 {
146 return m_nativeFontInfoOk ? m_nativeFontInfo.GetEncoding()
147 : m_encoding;
148 }
149
150 WXHFONT GetHFONT() const { return m_hFont; }
151
152 // ... and setters
153 void SetPointSize(int pointSize)
154 {
155 if ( m_nativeFontInfoOk )
156 m_nativeFontInfo.SetPointSize(pointSize);
157 else
158 m_pointSize = pointSize;
159 }
160
161 void SetFamily(int family)
162 {
163 m_family = family;
164 }
165
166 void SetStyle(int style)
167 {
168 if ( m_nativeFontInfoOk )
169 m_nativeFontInfo.SetStyle((wxFontStyle)style);
170 else
171 m_style = style;
172 }
173
174 void SetWeight(int weight)
175 {
176 if ( m_nativeFontInfoOk )
177 m_nativeFontInfo.SetWeight((wxFontWeight)weight);
178 else
179 m_weight = weight;
180 }
181
182 void SetFaceName(const wxString& faceName)
183 {
184 if ( m_nativeFontInfoOk )
185 m_nativeFontInfo.SetFaceName(faceName);
186 else
187 m_faceName = faceName;
188 }
189
190 void SetUnderlined(bool underlined)
191 {
192 if ( m_nativeFontInfoOk )
193 m_nativeFontInfo.SetUnderlined(underlined);
194 else
195 m_underlined = underlined;
196 }
197
198 void SetEncoding(wxFontEncoding encoding)
199 {
200 if ( m_nativeFontInfoOk )
201 m_nativeFontInfo.SetEncoding(encoding);
202 else
203 m_encoding = encoding;
204 }
205
206 // native font info tests
207 bool HasNativeFontInfo() const { return m_nativeFontInfoOk; }
208
209 const wxNativeFontInfo& GetNativeFontInfo() const
210 { return m_nativeFontInfo; }
211
212 protected:
213 // common part of all ctors
214 void Init(int size,
215 int family,
216 int style,
217 int weight,
218 bool underlined,
219 const wxString& faceName,
220 wxFontEncoding encoding);
221
222 void Init(const wxNativeFontInfo& info, WXHFONT hFont = 0);
223
224 // font characterstics
225 int m_pointSize;
226 int m_family;
227 int m_style;
228 int m_weight;
229 bool m_underlined;
230 wxString m_faceName;
231 wxFontEncoding m_encoding;
232
233 // Windows font handle
234 WXHFONT m_hFont;
235
236 // Native font info
237 wxNativeFontInfo m_nativeFontInfo;
238 bool m_nativeFontInfoOk;
239 };
240
241 // ============================================================================
242 // implementation
243 // ============================================================================
244
245 // ----------------------------------------------------------------------------
246 // wxFontRefData
247 // ----------------------------------------------------------------------------
248
249 void wxFontRefData::Init(int pointSize,
250 int family,
251 int style,
252 int weight,
253 bool underlined,
254 const wxString& faceName,
255 wxFontEncoding encoding)
256 {
257 m_style = style;
258 m_pointSize = pointSize == -1 ? wxNORMAL_FONT->GetPointSize() : pointSize;
259 m_family = family;
260 m_style = style;
261 m_weight = weight;
262 m_underlined = underlined;
263 m_faceName = faceName;
264 m_encoding = encoding;
265
266 m_hFont = 0;
267
268 m_nativeFontInfoOk = FALSE;
269 }
270
271 void wxFontRefData::Init(const wxNativeFontInfo& info, WXHFONT hFont)
272 {
273 // we don't really need the family, what for?
274 #if 0
275 // extract family from pitch-and-family
276 int lfFamily = info.lf.lfPitchAndFamily;
277 if ( lfFamily & FIXED_PITCH )
278 lfFamily -= FIXED_PITCH;
279 if ( lfFamily & VARIABLE_PITCH )
280 lfFamily -= VARIABLE_PITCH;
281
282 switch ( lfFamily )
283 {
284 case FF_ROMAN:
285 m_family = wxROMAN;
286 break;
287
288 case FF_SWISS:
289 m_family = wxSWISS;
290 break;
291
292 case FF_SCRIPT:
293 m_family = wxSCRIPT;
294 break;
295
296 case FF_MODERN:
297 m_family = wxMODERN;
298 break;
299
300 case FF_DECORATIVE:
301 m_family = wxDECORATIVE;
302 break;
303
304 default:
305 m_family = wxSWISS;
306 }
307 #endif // 0
308
309 // hFont may be zero, or it be passed in case we really want to
310 // use the exact font created in the underlying system
311 // (for example where we can't guarantee conversion from HFONT
312 // to LOGFONT back to HFONT)
313 m_hFont = hFont;
314
315 m_nativeFontInfoOk = TRUE;
316 m_nativeFontInfo = info;
317 }
318
319 wxFontRefData::~wxFontRefData()
320 {
321 Free();
322 }
323
324 bool wxFontRefData::Alloc(wxFont *font)
325 {
326 if ( !m_nativeFontInfoOk )
327 {
328 wxFillLogFont(&m_nativeFontInfo.lf, font);
329 m_nativeFontInfoOk = TRUE;
330 }
331
332 HFONT hfont = ::CreateFontIndirect(&m_nativeFontInfo.lf);
333 if ( !hfont )
334 {
335 wxLogLastError(wxT("CreateFont"));
336
337 return FALSE;
338 }
339
340 m_hFont = (WXHFONT)hfont;
341
342 return TRUE;
343 }
344
345 void wxFontRefData::Free()
346 {
347 if ( m_hFont )
348 {
349 if ( !::DeleteObject((HFONT) m_hFont) )
350 {
351 wxLogLastError(wxT("DeleteObject(font)"));
352 }
353
354 m_hFont = 0;
355 }
356 }
357
358 // ----------------------------------------------------------------------------
359 // wxNativeFontInfo
360 // ----------------------------------------------------------------------------
361
362 void wxNativeFontInfo::Init()
363 {
364 wxZeroMemory(lf);
365 }
366
367 int wxNativeFontInfo::GetPointSize() const
368 {
369 // FIXME: using the screen here results in incorrect font size calculation
370 // for printing!
371 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
372
373 return (int) (((72.0*(double)abs(lf.lfHeight)) / (double) ppInch) + 0.5);
374 }
375
376 wxFontStyle wxNativeFontInfo::GetStyle() const
377 {
378 return lf.lfItalic ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
379 }
380
381 wxFontWeight wxNativeFontInfo::GetWeight() const
382 {
383 if ( lf.lfWeight <= 300 )
384 return wxFONTWEIGHT_LIGHT;
385
386 if ( lf.lfWeight >= 600 )
387 return wxFONTWEIGHT_BOLD;
388
389 return wxFONTWEIGHT_NORMAL;
390 }
391
392 bool wxNativeFontInfo::GetUnderlined() const
393 {
394 return lf.lfUnderline != 0;
395 }
396
397 wxString wxNativeFontInfo::GetFaceName() const
398 {
399 return lf.lfFaceName;
400 }
401
402 wxFontEncoding wxNativeFontInfo::GetEncoding() const
403 {
404 return wxGetFontEncFromCharSet(lf.lfCharSet);
405 }
406
407 void wxNativeFontInfo::SetPointSize(int pointsize)
408 {
409 #if wxFONT_SIZE_COMPATIBILITY
410 // Incorrect, but compatible with old wxWindows behaviour
411 lf.lfHeight = (pointSize*ppInch)/72;
412 #else // wxFONT_SIZE_COMPATIBILITY
413 // FIXME: using the screen here results in incorrect font size calculation
414 // for printing!
415 const int ppInch = ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY);
416
417 lf.lfHeight = -(int)((pointsize*((double)ppInch)/72.0) + 0.5);
418 #endif // wxFONT_SIZE_COMPATIBILITY/!wxFONT_SIZE_COMPATIBILITY
419 }
420
421 void wxNativeFontInfo::SetStyle(wxFontStyle style)
422 {
423 switch ( style )
424 {
425 default:
426 wxFAIL_MSG( _T("unknown font style") );
427 // fall through
428
429 case wxFONTSTYLE_NORMAL:
430 break;
431
432 case wxFONTSTYLE_ITALIC:
433 case wxFONTSTYLE_SLANT:
434 lf.lfItalic = TRUE;
435 break;
436 }
437 }
438
439 void wxNativeFontInfo::SetWeight(wxFontWeight weight)
440 {
441 switch ( weight )
442 {
443 default:
444 wxFAIL_MSG( _T("unknown font weight") );
445 // fall through
446
447 case wxFONTWEIGHT_NORMAL:
448 lf.lfWeight = FW_NORMAL;
449 break;
450
451 case wxFONTWEIGHT_LIGHT:
452 lf.lfWeight = FW_LIGHT;
453 break;
454
455 case wxFONTWEIGHT_BOLD:
456 lf.lfWeight = FW_BOLD;
457 break;
458 }
459 }
460
461 void wxNativeFontInfo::SetUnderlined(bool underlined)
462 {
463 lf.lfUnderline = underlined;
464 }
465
466 void wxNativeFontInfo::SetFaceName(wxString facename)
467 {
468 wxStrncpy(lf.lfFaceName, facename, WXSIZEOF(lf.lfFaceName));
469 }
470
471 void wxNativeFontInfo::SetFamily(wxFontFamily family)
472 {
473 int ff_family;
474 wxString facename;
475
476 switch ( family )
477 {
478 case wxSCRIPT:
479 ff_family = FF_SCRIPT;
480 facename = _T("Script");
481 break;
482
483 case wxDECORATIVE:
484 ff_family = FF_DECORATIVE;
485 facename = _T("Old English Text MT");
486 break;
487
488 case wxROMAN:
489 ff_family = FF_ROMAN;
490 facename = _T("Times New Roman");
491 break;
492
493 case wxTELETYPE:
494 case wxMODERN:
495 ff_family = FF_MODERN;
496 facename = _T("Courier New");
497 break;
498
499 case wxSWISS:
500 ff_family = FF_SWISS;
501 facename = _T("Arial");
502 break;
503
504 case wxDEFAULT:
505 default:
506 ff_family = FF_SWISS;
507 facename = _T("MS Sans Serif");
508 }
509
510 lf.lfPitchAndFamily = DEFAULT_PITCH | ff_family;
511
512 if ( !wxStrlen(lf.lfFaceName) )
513 {
514 SetFaceName(facename);
515 }
516 }
517
518 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding)
519 {
520 wxNativeEncodingInfo info;
521 if ( !wxGetNativeFontEncoding(encoding, &info) )
522 {
523 #if wxUSE_FONTMAP
524 if ( wxTheFontMapper->GetAltForEncoding(encoding, &info) )
525 {
526 if ( !info.facename.empty() )
527 {
528 // if we have this encoding only in some particular facename, use
529 // the facename - it is better to show the correct characters in a
530 // wrong facename than unreadable text in a correct one
531 SetFaceName(info.facename);
532 }
533 }
534 else
535 #endif // wxUSE_FONTMAP
536 {
537 // unsupported encoding, replace with the default
538 info.charset = ANSI_CHARSET;
539 }
540 }
541
542 lf.lfCharSet = info.charset;
543 }
544
545 bool wxNativeFontInfo::FromString(const wxString& s)
546 {
547 long l;
548
549 wxStringTokenizer tokenizer(s, _T(";"));
550
551 // first the version
552 wxString token = tokenizer.GetNextToken();
553 if ( token != _T('0') )
554 return FALSE;
555
556 token = tokenizer.GetNextToken();
557 if ( !token.ToLong(&l) )
558 return FALSE;
559 lf.lfHeight = l;
560
561 token = tokenizer.GetNextToken();
562 if ( !token.ToLong(&l) )
563 return FALSE;
564 lf.lfWidth = l;
565
566 token = tokenizer.GetNextToken();
567 if ( !token.ToLong(&l) )
568 return FALSE;
569 lf.lfEscapement = l;
570
571 token = tokenizer.GetNextToken();
572 if ( !token.ToLong(&l) )
573 return FALSE;
574 lf.lfOrientation = l;
575
576 token = tokenizer.GetNextToken();
577 if ( !token.ToLong(&l) )
578 return FALSE;
579 lf.lfWeight = l;
580
581 token = tokenizer.GetNextToken();
582 if ( !token.ToLong(&l) )
583 return FALSE;
584 lf.lfItalic = (BYTE)l;
585
586 token = tokenizer.GetNextToken();
587 if ( !token.ToLong(&l) )
588 return FALSE;
589 lf.lfUnderline = (BYTE)l;
590
591 token = tokenizer.GetNextToken();
592 if ( !token.ToLong(&l) )
593 return FALSE;
594 lf.lfStrikeOut = (BYTE)l;
595
596 token = tokenizer.GetNextToken();
597 if ( !token.ToLong(&l) )
598 return FALSE;
599 lf.lfCharSet = (BYTE)l;
600
601 token = tokenizer.GetNextToken();
602 if ( !token.ToLong(&l) )
603 return FALSE;
604 lf.lfOutPrecision = (BYTE)l;
605
606 token = tokenizer.GetNextToken();
607 if ( !token.ToLong(&l) )
608 return FALSE;
609 lf.lfClipPrecision = (BYTE)l;
610
611 token = tokenizer.GetNextToken();
612 if ( !token.ToLong(&l) )
613 return FALSE;
614 lf.lfQuality = (BYTE)l;
615
616 token = tokenizer.GetNextToken();
617 if ( !token.ToLong(&l) )
618 return FALSE;
619 lf.lfPitchAndFamily = (BYTE)l;
620
621 token = tokenizer.GetNextToken();
622 if(!token)
623 return FALSE;
624 wxStrcpy(lf.lfFaceName, token.c_str());
625
626 return TRUE;
627 }
628
629 wxString wxNativeFontInfo::ToString() const
630 {
631 wxString s;
632
633 s.Printf(_T("%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
634 0, // version, in case we want to change the format later
635 lf.lfHeight,
636 lf.lfWidth,
637 lf.lfEscapement,
638 lf.lfOrientation,
639 lf.lfWeight,
640 lf.lfItalic,
641 lf.lfUnderline,
642 lf.lfStrikeOut,
643 lf.lfCharSet,
644 lf.lfOutPrecision,
645 lf.lfClipPrecision,
646 lf.lfQuality,
647 lf.lfPitchAndFamily,
648 lf.lfFaceName);
649
650 return s;
651 }
652
653 // ----------------------------------------------------------------------------
654 // wxFont
655 // ----------------------------------------------------------------------------
656
657 void wxFont::Init()
658 {
659 }
660
661 bool wxFont::Create(const wxNativeFontInfo& info, WXHFONT hFont)
662 {
663 UnRef();
664
665 m_refData = new wxFontRefData(info, hFont);
666
667 RealizeResource();
668
669 return TRUE;
670 }
671
672 wxFont::wxFont(const wxString& fontdesc)
673 {
674 wxNativeFontInfo info;
675 if ( info.FromString(fontdesc) )
676 (void)Create(info);
677 }
678
679 /* Constructor for a font. Note that the real construction is done
680 * in wxDC::SetFont, when information is available about scaling etc.
681 */
682 bool wxFont::Create(int pointSize,
683 int family,
684 int style,
685 int weight,
686 bool underlined,
687 const wxString& faceName,
688 wxFontEncoding encoding)
689 {
690 UnRef();
691
692 // wxDEFAULT is a valid value for the font size too so we must treat it
693 // specially here (otherwise the size would be 70 == wxDEFAULT value)
694 if ( pointSize == wxDEFAULT )
695 {
696 pointSize = wxNORMAL_FONT->GetPointSize();
697 }
698
699 m_refData = new wxFontRefData(pointSize, family, style, weight,
700 underlined, faceName, encoding);
701
702 RealizeResource();
703
704 return TRUE;
705 }
706
707 wxFont::~wxFont()
708 {
709 }
710
711 // ----------------------------------------------------------------------------
712 // real implementation
713 // ----------------------------------------------------------------------------
714
715 bool wxFont::RealizeResource()
716 {
717 if ( GetResourceHandle() )
718 {
719 // VZ: the old code returned FALSE in this case, but it doesn't seem
720 // to make sense because the font _was_ created
721 return TRUE;
722 }
723
724 return M_FONTDATA->Alloc(this);
725 }
726
727 bool wxFont::FreeResource(bool WXUNUSED(force))
728 {
729 if ( GetResourceHandle() )
730 {
731 M_FONTDATA->Free();
732
733 return TRUE;
734 }
735
736 return FALSE;
737 }
738
739 WXHANDLE wxFont::GetResourceHandle()
740 {
741 return GetHFONT();
742 }
743
744 WXHFONT wxFont::GetHFONT() const
745 {
746 return M_FONTDATA ? M_FONTDATA->GetHFONT() : 0;
747 }
748
749 bool wxFont::IsFree() const
750 {
751 return M_FONTDATA && (M_FONTDATA->GetHFONT() == 0);
752 }
753
754 void wxFont::Unshare()
755 {
756 // Don't change shared data
757 if ( !m_refData )
758 {
759 m_refData = new wxFontRefData();
760 }
761 else
762 {
763 wxFontRefData* ref = new wxFontRefData(*M_FONTDATA);
764 UnRef();
765 m_refData = ref;
766 }
767 }
768
769 // ----------------------------------------------------------------------------
770 // change font attribute: we recreate font when doing it
771 // ----------------------------------------------------------------------------
772
773 void wxFont::SetPointSize(int pointSize)
774 {
775 Unshare();
776
777 M_FONTDATA->SetPointSize(pointSize);
778
779 RealizeResource();
780 }
781
782 void wxFont::SetFamily(int family)
783 {
784 Unshare();
785
786 M_FONTDATA->SetFamily(family);
787
788 RealizeResource();
789 }
790
791 void wxFont::SetStyle(int style)
792 {
793 Unshare();
794
795 M_FONTDATA->SetStyle(style);
796
797 RealizeResource();
798 }
799
800 void wxFont::SetWeight(int weight)
801 {
802 Unshare();
803
804 M_FONTDATA->SetWeight(weight);
805
806 RealizeResource();
807 }
808
809 void wxFont::SetFaceName(const wxString& faceName)
810 {
811 Unshare();
812
813 M_FONTDATA->SetFaceName(faceName);
814
815 RealizeResource();
816 }
817
818 void wxFont::SetUnderlined(bool underlined)
819 {
820 Unshare();
821
822 M_FONTDATA->SetUnderlined(underlined);
823
824 RealizeResource();
825 }
826
827 void wxFont::SetEncoding(wxFontEncoding encoding)
828 {
829 Unshare();
830
831 M_FONTDATA->SetEncoding(encoding);
832
833 RealizeResource();
834 }
835
836 void wxFont::SetNativeFontInfo(const wxNativeFontInfo& info)
837 {
838 Unshare();
839
840 FreeResource();
841
842 *M_FONTDATA = wxFontRefData(info);
843
844 RealizeResource();
845 }
846
847 // ----------------------------------------------------------------------------
848 // accessors
849 // ----------------------------------------------------------------------------
850
851 int wxFont::GetPointSize() const
852 {
853 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
854
855 return M_FONTDATA->GetPointSize();
856 }
857
858 int wxFont::GetFamily() const
859 {
860 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
861
862 return M_FONTDATA->GetFamily();
863 }
864
865 int wxFont::GetStyle() const
866 {
867 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
868
869 return M_FONTDATA->GetStyle();
870 }
871
872 int wxFont::GetWeight() const
873 {
874 wxCHECK_MSG( Ok(), 0, wxT("invalid font") );
875
876 return M_FONTDATA->GetWeight();
877 }
878
879 bool wxFont::GetUnderlined() const
880 {
881 wxCHECK_MSG( Ok(), FALSE, wxT("invalid font") );
882
883 return M_FONTDATA->GetUnderlined();
884 }
885
886 wxString wxFont::GetFaceName() const
887 {
888 wxCHECK_MSG( Ok(), wxT(""), wxT("invalid font") );
889
890 return M_FONTDATA->GetFaceName();
891 }
892
893 wxFontEncoding wxFont::GetEncoding() const
894 {
895 wxCHECK_MSG( Ok(), wxFONTENCODING_DEFAULT, wxT("invalid font") );
896
897 return M_FONTDATA->GetEncoding();
898 }
899
900 wxNativeFontInfo *wxFont::GetNativeFontInfo() const
901 {
902 if ( M_FONTDATA->HasNativeFontInfo() )
903 return new wxNativeFontInfo(M_FONTDATA->GetNativeFontInfo());
904
905 return 0;
906 }
907