1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/font.cpp
3 // Purpose: wxFont class
4 // Author: Julian Smart
8 // Copyright: (c) wxWidgets team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
34 #include "wx/msw/private.h"
37 #include "wx/encinfo.h"
38 #include "wx/fontutil.h"
39 #include "wx/fontmap.h"
42 #include "wx/sysopt.h"
45 #include "wx/scopeguard.h"
46 #include "wx/tokenzr.h"
48 // ----------------------------------------------------------------------------
50 // ----------------------------------------------------------------------------
52 // the mask used to extract the pitch from LOGFONT::lfPitchAndFamily field
53 static const int PITCH_MASK
= FIXED_PITCH
| VARIABLE_PITCH
;
55 // ----------------------------------------------------------------------------
56 // wxFontRefData - the internal description of the font
57 // ----------------------------------------------------------------------------
59 class WXDLLEXPORT wxFontRefData
: public wxGDIRefData
65 Init(-1, wxSize(0,0), false, wxFONTFAMILY_DEFAULT
, wxFONTSTYLE_NORMAL
,
66 wxFONTWEIGHT_NORMAL
, false, false, wxEmptyString
,
67 wxFONTENCODING_DEFAULT
);
70 wxFontRefData(int size
,
71 const wxSize
& pixelSize
,
78 const wxString
& faceName
,
79 wxFontEncoding encoding
)
81 Init(size
, pixelSize
, sizeUsingPixels
, family
, style
, weight
,
82 underlined
, strikethrough
, faceName
, encoding
);
85 wxFontRefData(const wxNativeFontInfo
& info
, WXHFONT hFont
= 0)
90 wxFontRefData(const wxFontRefData
& data
) : wxGDIRefData()
92 Init(data
.m_nativeFontInfo
);
95 virtual ~wxFontRefData();
102 // all wxFont accessors
103 int GetPointSize() const
105 return m_nativeFontInfo
.GetPointSize();
108 wxSize
GetPixelSize() const
110 return m_nativeFontInfo
.GetPixelSize();
113 bool IsUsingSizeInPixels() const
115 return m_sizeUsingPixels
;
118 wxFontFamily
GetFamily() const
120 return m_nativeFontInfo
.GetFamily();
123 wxFontStyle
GetStyle() const
125 return m_nativeFontInfo
.GetStyle();
128 wxFontWeight
GetWeight() const
130 return m_nativeFontInfo
.GetWeight();
133 bool GetUnderlined() const
135 return m_nativeFontInfo
.GetUnderlined();
138 bool GetStrikethrough() const
140 return m_nativeFontInfo
.GetStrikethrough();
143 wxString
GetFaceName() const
145 wxString facename
= m_nativeFontInfo
.GetFaceName();
146 if ( facename
.empty() )
148 facename
= GetMSWFaceName();
149 if ( !facename
.empty() )
151 // cache the face name, it shouldn't change unless the family
152 // does and wxNativeFontInfo::SetFamily() resets the face name
153 const_cast<wxFontRefData
*>(this)->SetFaceName(facename
);
160 wxFontEncoding
GetEncoding() const
162 return m_nativeFontInfo
.GetEncoding();
165 WXHFONT
GetHFONT() const
169 return (WXHFONT
)m_hFont
;
172 bool HasHFONT() const
177 // ... and setters: notice that all of them invalidate the currently
178 // allocated HFONT, if any, so that the next call to GetHFONT() recreates a
180 void SetPointSize(int pointSize
)
184 m_nativeFontInfo
.SetPointSize(pointSize
);
185 m_sizeUsingPixels
= false;
188 void SetPixelSize(const wxSize
& pixelSize
)
190 wxCHECK_RET( pixelSize
.GetWidth() >= 0, "negative font width" );
191 wxCHECK_RET( pixelSize
.GetHeight() != 0, "zero font height" );
195 m_nativeFontInfo
.SetPixelSize(pixelSize
);
196 m_sizeUsingPixels
= true;
199 void SetFamily(wxFontFamily family
)
203 m_nativeFontInfo
.SetFamily(family
);
206 void SetStyle(wxFontStyle style
)
210 m_nativeFontInfo
.SetStyle(style
);
213 void SetWeight(wxFontWeight weight
)
217 m_nativeFontInfo
.SetWeight(weight
);
220 bool SetFaceName(const wxString
& faceName
)
224 return m_nativeFontInfo
.SetFaceName(faceName
);
227 void SetUnderlined(bool underlined
)
231 m_nativeFontInfo
.SetUnderlined(underlined
);
234 void SetStrikethrough(bool strikethrough
)
238 m_nativeFontInfo
.SetStrikethrough(strikethrough
);
241 void SetEncoding(wxFontEncoding encoding
)
245 m_nativeFontInfo
.SetEncoding(encoding
);
248 const wxNativeFontInfo
& GetNativeFontInfo() const
250 // we need to create the font now to get the corresponding LOGFONT if
251 // it hadn't been done yet
254 // ensure that we have a valid face name in our font information:
255 // GetFaceName() will try to retrieve it from our HFONT and save it if
259 return m_nativeFontInfo
;
262 void SetNativeFontInfo(const wxNativeFontInfo
& nativeFontInfo
)
266 m_nativeFontInfo
= nativeFontInfo
;
270 // common part of all ctors
272 const wxSize
& pixelSize
,
273 bool sizeUsingPixels
,
279 const wxString
& faceName
,
280 wxFontEncoding encoding
);
282 void Init(const wxNativeFontInfo
& info
, WXHFONT hFont
= 0);
284 void AllocIfNeeded() const
287 const_cast<wxFontRefData
*>(this)->Alloc();
290 // retrieve the face name really being used by the font: this is used to
291 // get the face name selected by the system when we don't specify it (but
292 // use just the family for example)
293 wxString
GetMSWFaceName() const
296 SelectInHDC
selectFont(hdc
, (HFONT
)GetHFONT());
298 UINT otmSize
= GetOutlineTextMetrics(hdc
, 0, NULL
);
301 wxLogLastError("GetOutlineTextMetrics(NULL)");
305 OUTLINETEXTMETRIC
* const
306 otm
= static_cast<OUTLINETEXTMETRIC
*>(malloc(otmSize
));
307 wxON_BLOCK_EXIT1( free
, otm
);
309 otm
->otmSize
= otmSize
;
310 if ( !GetOutlineTextMetrics(hdc
, otmSize
, otm
) )
312 wxLogLastError("GetOutlineTextMetrics()");
316 // in spite of its type, the otmpFamilyName field of OUTLINETEXTMETRIC
317 // gives an offset in _bytes_ of the face (not family!) name from the
318 // struct start while the name itself is an array of TCHARs
320 // FWIW otmpFaceName contains the same thing as otmpFamilyName followed
321 // by a possible " Italic" or " Bold" or something else suffix
322 return reinterpret_cast<wxChar
*>(otm
) +
323 wxPtrToUInt(otm
->otmpFamilyName
)/sizeof(wxChar
);
326 // are we using m_nativeFontInfo.lf.lfHeight for point size or pixel size?
327 bool m_sizeUsingPixels
;
329 // Windows font handle, created on demand in GetHFONT()
333 wxNativeFontInfo m_nativeFontInfo
;
336 #define M_FONTDATA ((wxFontRefData*)m_refData)
338 // ============================================================================
340 // ============================================================================
342 // ----------------------------------------------------------------------------
344 // ----------------------------------------------------------------------------
346 void wxFontRefData::Init(int pointSize
,
347 const wxSize
& pixelSize
,
348 bool sizeUsingPixels
,
354 const wxString
& faceName
,
355 wxFontEncoding encoding
)
359 m_sizeUsingPixels
= sizeUsingPixels
;
360 if ( m_sizeUsingPixels
)
361 SetPixelSize(pixelSize
);
363 SetPointSize(pointSize
);
367 SetUnderlined(underlined
);
368 SetStrikethrough(strikethrough
);
370 // set the family/facename
372 if ( !faceName
.empty() )
373 SetFaceName(faceName
);
375 // deal with encoding now (it may override the font family and facename
376 // so do it after setting them)
377 SetEncoding(encoding
);
380 void wxFontRefData::Init(const wxNativeFontInfo
& info
, WXHFONT hFont
)
382 // hFont may be zero, or it be passed in case we really want to
383 // use the exact font created in the underlying system
384 // (for example where we can't guarantee conversion from HFONT
385 // to LOGFONT back to HFONT)
386 m_hFont
= (HFONT
)hFont
;
387 m_nativeFontInfo
= info
;
389 // TODO: m_sizeUsingPixels?
392 wxFontRefData::~wxFontRefData()
397 bool wxFontRefData::Alloc()
399 m_hFont
= ::CreateFontIndirect(&m_nativeFontInfo
.lf
);
402 wxLogLastError(wxT("CreateFont"));
409 void wxFontRefData::Free()
413 if ( !::DeleteObject(m_hFont
) )
415 wxLogLastError(wxT("DeleteObject(font)"));
422 // ----------------------------------------------------------------------------
424 // ----------------------------------------------------------------------------
426 void wxNativeFontInfo::Init()
430 // we get better font quality if we use PROOF_QUALITY instead of
431 // DEFAULT_QUALITY but some fonts (e.g. "Terminal 6pt") are not available
432 // then so we allow to set a global option to choose between quality and
433 // wider font selection
435 lf
.lfQuality
= CLEARTYPE_QUALITY
;
437 lf
.lfQuality
= wxSystemOptions::GetOptionInt("msw.font.no-proof-quality")
443 int wxNativeFontInfo::GetPointSize() const
445 // FIXME: using the screen here results in incorrect font size calculation
447 const int ppInch
= ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY
);
449 // BC++ 2007 doesn't provide abs(long) overload, hence the cast
450 return (int) (((72.0*abs((int)lf
.lfHeight
)) / (double) ppInch
) + 0.5);
453 wxSize
wxNativeFontInfo::GetPixelSize() const
456 ret
.SetHeight(abs((int)lf
.lfHeight
));
457 ret
.SetWidth(lf
.lfWidth
);
461 wxFontStyle
wxNativeFontInfo::GetStyle() const
463 return lf
.lfItalic
? wxFONTSTYLE_ITALIC
: wxFONTSTYLE_NORMAL
;
466 wxFontWeight
wxNativeFontInfo::GetWeight() const
468 if ( lf
.lfWeight
<= 300 )
469 return wxFONTWEIGHT_LIGHT
;
471 if ( lf
.lfWeight
>= 600 )
472 return wxFONTWEIGHT_BOLD
;
474 return wxFONTWEIGHT_NORMAL
;
477 bool wxNativeFontInfo::GetUnderlined() const
479 return lf
.lfUnderline
!= 0;
482 bool wxNativeFontInfo::GetStrikethrough() const
484 return lf
.lfStrikeOut
!= 0;
487 wxString
wxNativeFontInfo::GetFaceName() const
489 return lf
.lfFaceName
;
492 wxFontFamily
wxNativeFontInfo::GetFamily() const
496 // extract family from pitch-and-family
497 switch ( lf
.lfPitchAndFamily
& ~PITCH_MASK
)
500 family
= wxFONTFAMILY_UNKNOWN
;
504 family
= wxFONTFAMILY_ROMAN
;
508 family
= wxFONTFAMILY_SWISS
;
512 family
= wxFONTFAMILY_SCRIPT
;
516 family
= wxFONTFAMILY_MODERN
;
520 family
= wxFONTFAMILY_DECORATIVE
;
524 wxFAIL_MSG( "unknown LOGFONT::lfFamily value" );
525 family
= wxFONTFAMILY_UNKNOWN
;
526 // just to avoid a warning
532 wxFontEncoding
wxNativeFontInfo::GetEncoding() const
534 return wxGetFontEncFromCharSet(lf
.lfCharSet
);
537 void wxNativeFontInfo::SetPointSize(int pointsize
)
539 // FIXME: using the screen here results in incorrect font size calculation
541 const int ppInch
= ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY
);
543 lf
.lfHeight
= -(int)((pointsize
*((double)ppInch
)/72.0) + 0.5);
546 void wxNativeFontInfo::SetPixelSize(const wxSize
& pixelSize
)
548 // MSW accepts both positive and negative heights here but they mean
549 // different things: positive specifies the cell height while negative
550 // specifies the character height. We used to just pass the value to MSW
551 // unchanged but changed the behaviour for positive values in 2.9.1 to
552 // match other ports and, more importantly, the expected behaviour. So now
553 // passing the negative height doesn't make sense at all any more but we
554 // still accept it for compatibility with the existing code which worked
555 // around the wrong interpretation of the height argument in older wxMSW
556 // versions by passing a negative value explicitly itself.
557 lf
.lfHeight
= -abs(pixelSize
.GetHeight());
558 lf
.lfWidth
= pixelSize
.GetWidth();
561 void wxNativeFontInfo::SetStyle(wxFontStyle style
)
566 wxFAIL_MSG( "unknown font style" );
569 case wxFONTSTYLE_NORMAL
:
573 case wxFONTSTYLE_ITALIC
:
574 case wxFONTSTYLE_SLANT
:
580 void wxNativeFontInfo::SetWeight(wxFontWeight weight
)
585 wxFAIL_MSG( "unknown font weight" );
588 case wxFONTWEIGHT_NORMAL
:
589 lf
.lfWeight
= FW_NORMAL
;
592 case wxFONTWEIGHT_LIGHT
:
593 lf
.lfWeight
= FW_LIGHT
;
596 case wxFONTWEIGHT_BOLD
:
597 lf
.lfWeight
= FW_BOLD
;
602 void wxNativeFontInfo::SetUnderlined(bool underlined
)
604 lf
.lfUnderline
= underlined
;
607 void wxNativeFontInfo::SetStrikethrough(bool strikethrough
)
609 lf
.lfStrikeOut
= strikethrough
;
612 bool wxNativeFontInfo::SetFaceName(const wxString
& facename
)
614 wxStrlcpy(lf
.lfFaceName
, facename
.c_str(), WXSIZEOF(lf
.lfFaceName
));
618 void wxNativeFontInfo::SetFamily(wxFontFamily family
)
620 BYTE ff_family
= FF_DONTCARE
;
624 case wxFONTFAMILY_SCRIPT
:
625 ff_family
= FF_SCRIPT
;
628 case wxFONTFAMILY_DECORATIVE
:
629 ff_family
= FF_DECORATIVE
;
632 case wxFONTFAMILY_ROMAN
:
633 ff_family
= FF_ROMAN
;
636 case wxFONTFAMILY_TELETYPE
:
637 case wxFONTFAMILY_MODERN
:
638 ff_family
= FF_MODERN
;
641 case wxFONTFAMILY_SWISS
:
642 case wxFONTFAMILY_DEFAULT
:
643 ff_family
= FF_SWISS
;
646 case wxFONTFAMILY_UNKNOWN
:
647 wxFAIL_MSG( "invalid font family" );
651 wxCHECK_RET( ff_family
!= FF_DONTCARE
, "unknown wxFontFamily" );
653 lf
.lfPitchAndFamily
= (BYTE
)(DEFAULT_PITCH
) | ff_family
;
655 // reset the facename so that CreateFontIndirect() will automatically choose a
656 // face name based only on the font family.
657 lf
.lfFaceName
[0] = '\0';
660 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding
)
662 wxNativeEncodingInfo info
;
663 if ( !wxGetNativeFontEncoding(encoding
, &info
) )
666 if ( wxFontMapper::Get()->GetAltForEncoding(encoding
, &info
) )
668 if ( !info
.facename
.empty() )
670 // if we have this encoding only in some particular facename, use
671 // the facename - it is better to show the correct characters in a
672 // wrong facename than unreadable text in a correct one
673 SetFaceName(info
.facename
);
677 #endif // wxUSE_FONTMAP
679 // unsupported encoding, replace with the default
680 info
.charset
= DEFAULT_CHARSET
;
684 lf
.lfCharSet
= (BYTE
)info
.charset
;
687 bool wxNativeFontInfo::FromString(const wxString
& s
)
691 wxStringTokenizer
tokenizer(s
, wxS(";"), wxTOKEN_RET_EMPTY_ALL
);
694 wxString token
= tokenizer
.GetNextToken();
695 if ( token
!= wxS('0') )
698 token
= tokenizer
.GetNextToken();
699 if ( !token
.ToLong(&l
) )
703 token
= tokenizer
.GetNextToken();
704 if ( !token
.ToLong(&l
) )
708 token
= tokenizer
.GetNextToken();
709 if ( !token
.ToLong(&l
) )
713 token
= tokenizer
.GetNextToken();
714 if ( !token
.ToLong(&l
) )
716 lf
.lfOrientation
= l
;
718 token
= tokenizer
.GetNextToken();
719 if ( !token
.ToLong(&l
) )
723 token
= tokenizer
.GetNextToken();
724 if ( !token
.ToLong(&l
) )
726 lf
.lfItalic
= (BYTE
)l
;
728 token
= tokenizer
.GetNextToken();
729 if ( !token
.ToLong(&l
) )
731 lf
.lfUnderline
= (BYTE
)l
;
733 token
= tokenizer
.GetNextToken();
734 if ( !token
.ToLong(&l
) )
736 lf
.lfStrikeOut
= (BYTE
)l
;
738 token
= tokenizer
.GetNextToken();
739 if ( !token
.ToLong(&l
) )
741 lf
.lfCharSet
= (BYTE
)l
;
743 token
= tokenizer
.GetNextToken();
744 if ( !token
.ToLong(&l
) )
746 lf
.lfOutPrecision
= (BYTE
)l
;
748 token
= tokenizer
.GetNextToken();
749 if ( !token
.ToLong(&l
) )
751 lf
.lfClipPrecision
= (BYTE
)l
;
753 token
= tokenizer
.GetNextToken();
754 if ( !token
.ToLong(&l
) )
756 lf
.lfQuality
= (BYTE
)l
;
758 token
= tokenizer
.GetNextToken();
759 if ( !token
.ToLong(&l
) )
761 lf
.lfPitchAndFamily
= (BYTE
)l
;
763 if ( !tokenizer
.HasMoreTokens() )
766 // the face name may be empty
767 SetFaceName(tokenizer
.GetNextToken());
772 wxString
wxNativeFontInfo::ToString() const
776 s
.Printf(wxS("%d;%ld;%ld;%ld;%ld;%ld;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
777 0, // version, in case we want to change the format later
796 // ----------------------------------------------------------------------------
798 // ----------------------------------------------------------------------------
800 wxFont::wxFont(const wxString
& fontdesc
)
802 wxNativeFontInfo info
;
803 if ( info
.FromString(fontdesc
) )
807 wxFont::wxFont(const wxFontInfo
& info
)
809 m_refData
= new wxFontRefData(info
.GetPointSize(),
811 info
.IsUsingSizeInPixels(),
816 info
.IsStrikethrough(),
821 bool wxFont::Create(const wxNativeFontInfo
& info
, WXHFONT hFont
)
825 m_refData
= new wxFontRefData(info
, hFont
);
827 return RealizeResource();
830 bool wxFont::DoCreate(int pointSize
,
831 const wxSize
& pixelSize
,
832 bool sizeUsingPixels
,
837 const wxString
& faceName
,
838 wxFontEncoding encoding
)
842 // wxDEFAULT is a valid value for the font size too so we must treat it
843 // specially here (otherwise the size would be 70 == wxDEFAULT value)
844 if ( pointSize
== wxDEFAULT
|| pointSize
== -1 )
846 pointSize
= wxNORMAL_FONT
->GetPointSize();
849 m_refData
= new wxFontRefData(pointSize
, pixelSize
, sizeUsingPixels
,
850 family
, style
, weight
,
851 underlined
, false, faceName
, encoding
);
853 return RealizeResource();
860 // ----------------------------------------------------------------------------
861 // real implementation
862 // ----------------------------------------------------------------------------
864 wxGDIRefData
*wxFont::CreateGDIRefData() const
866 return new wxFontRefData();
869 wxGDIRefData
*wxFont::CloneGDIRefData(const wxGDIRefData
*data
) const
871 return new wxFontRefData(*static_cast<const wxFontRefData
*>(data
));
874 bool wxFont::RealizeResource()
876 // NOTE: the GetHFONT() call automatically triggers a reallocation of
877 // the HFONT if necessary (will do nothing if we already have the resource);
878 // it returns NULL only if there is a failure in wxFontRefData::Alloc()...
879 return GetHFONT() != NULL
;
882 bool wxFont::FreeResource(bool WXUNUSED(force
))
892 WXHANDLE
wxFont::GetResourceHandle() const
894 return (WXHANDLE
)GetHFONT();
897 WXHFONT
wxFont::GetHFONT() const
899 // NOTE: wxFontRefData::GetHFONT() will automatically call
900 // wxFontRefData::Alloc() if necessary
901 return M_FONTDATA
? M_FONTDATA
->GetHFONT() : 0;
904 bool wxFont::IsFree() const
906 return M_FONTDATA
&& !M_FONTDATA
->HasHFONT();
909 // ----------------------------------------------------------------------------
910 // change font attribute: we recreate font when doing it
911 // ----------------------------------------------------------------------------
913 void wxFont::SetPointSize(int pointSize
)
918 M_FONTDATA
->SetPointSize(pointSize
);
921 void wxFont::SetPixelSize(const wxSize
& pixelSize
)
925 M_FONTDATA
->SetPixelSize(pixelSize
);
928 void wxFont::SetFamily(wxFontFamily family
)
932 M_FONTDATA
->SetFamily(family
);
935 void wxFont::SetStyle(wxFontStyle style
)
939 M_FONTDATA
->SetStyle(style
);
942 void wxFont::SetWeight(wxFontWeight weight
)
946 M_FONTDATA
->SetWeight(weight
);
949 bool wxFont::SetFaceName(const wxString
& faceName
)
953 if ( !M_FONTDATA
->SetFaceName(faceName
) )
956 // NB: using win32's GetObject() API on M_FONTDATA->GetHFONT()
957 // to retrieve a LOGFONT and then compare lf.lfFaceName
958 // with given facename is not reliable at all:
959 // Windows copies the facename given to ::CreateFontIndirect()
960 // without any validity check.
961 // Thus we use wxFontBase::SetFaceName to check if facename
963 return wxFontBase::SetFaceName(faceName
);
966 void wxFont::SetUnderlined(bool underlined
)
970 M_FONTDATA
->SetUnderlined(underlined
);
973 void wxFont::SetStrikethrough(bool strikethrough
)
977 M_FONTDATA
->SetStrikethrough(strikethrough
);
980 void wxFont::SetEncoding(wxFontEncoding encoding
)
984 M_FONTDATA
->SetEncoding(encoding
);
987 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo
& info
)
991 M_FONTDATA
->SetNativeFontInfo(info
);
994 // ----------------------------------------------------------------------------
996 // ----------------------------------------------------------------------------
998 int wxFont::GetPointSize() const
1000 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
1002 return M_FONTDATA
->GetPointSize();
1005 wxSize
wxFont::GetPixelSize() const
1007 wxCHECK_MSG( IsOk(), wxDefaultSize
, wxT("invalid font") );
1009 return M_FONTDATA
->GetPixelSize();
1012 bool wxFont::IsUsingSizeInPixels() const
1014 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
1016 return M_FONTDATA
->IsUsingSizeInPixels();
1019 wxFontFamily
wxFont::DoGetFamily() const
1021 return M_FONTDATA
->GetFamily();
1024 wxFontStyle
wxFont::GetStyle() const
1026 wxCHECK_MSG( IsOk(), wxFONTSTYLE_MAX
, wxT("invalid font") );
1028 return M_FONTDATA
->GetStyle();
1031 wxFontWeight
wxFont::GetWeight() const
1033 wxCHECK_MSG( IsOk(), wxFONTWEIGHT_MAX
, wxT("invalid font") );
1035 return M_FONTDATA
->GetWeight();
1038 bool wxFont::GetUnderlined() const
1040 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
1042 return M_FONTDATA
->GetUnderlined();
1045 bool wxFont::GetStrikethrough() const
1047 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
1049 return M_FONTDATA
->GetStrikethrough();
1052 wxString
wxFont::GetFaceName() const
1054 wxCHECK_MSG( IsOk(), wxEmptyString
, wxT("invalid font") );
1056 return M_FONTDATA
->GetFaceName();
1059 wxFontEncoding
wxFont::GetEncoding() const
1061 wxCHECK_MSG( IsOk(), wxFONTENCODING_DEFAULT
, wxT("invalid font") );
1063 return M_FONTDATA
->GetEncoding();
1066 const wxNativeFontInfo
*wxFont::GetNativeFontInfo() const
1068 return IsOk() ? &(M_FONTDATA
->GetNativeFontInfo()) : NULL
;
1071 bool wxFont::IsFixedWidth() const
1073 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
1075 // LOGFONT doesn't contain the correct pitch information so we need to call
1076 // GetTextMetrics() to get it
1078 SelectInHDC
selectFont(hdc
, M_FONTDATA
->GetHFONT());
1081 if ( !::GetTextMetrics(hdc
, &tm
) )
1083 wxLogLastError(wxT("GetTextMetrics"));
1087 // Quoting MSDN description of TMPF_FIXED_PITCH: "Note very carefully that
1088 // those meanings are the opposite of what the constant name implies."
1089 return !(tm
.tmPitchAndFamily
& TMPF_FIXED_PITCH
);