1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/font.cpp
3 // Purpose: wxFont class
4 // Author: Julian Smart
7 // Copyright: (c) wxWidgets team
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
33 #include "wx/msw/private.h"
36 #include "wx/encinfo.h"
37 #include "wx/fontutil.h"
38 #include "wx/fontmap.h"
41 #include "wx/sysopt.h"
44 #include "wx/scopeguard.h"
45 #include "wx/tokenzr.h"
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
51 // the mask used to extract the pitch from LOGFONT::lfPitchAndFamily field
52 static const int PITCH_MASK
= FIXED_PITCH
| VARIABLE_PITCH
;
54 // ----------------------------------------------------------------------------
55 // wxFontRefData - the internal description of the font
56 // ----------------------------------------------------------------------------
58 class WXDLLEXPORT wxFontRefData
: public wxGDIRefData
64 Init(-1, wxSize(0,0), false, wxFONTFAMILY_DEFAULT
, wxFONTSTYLE_NORMAL
,
65 wxFONTWEIGHT_NORMAL
, false, false, wxEmptyString
,
66 wxFONTENCODING_DEFAULT
);
69 wxFontRefData(int size
,
70 const wxSize
& pixelSize
,
77 const wxString
& faceName
,
78 wxFontEncoding encoding
)
80 Init(size
, pixelSize
, sizeUsingPixels
, family
, style
, weight
,
81 underlined
, strikethrough
, faceName
, encoding
);
84 wxFontRefData(const wxNativeFontInfo
& info
, WXHFONT hFont
= 0)
89 wxFontRefData(const wxFontRefData
& data
) : wxGDIRefData()
91 Init(data
.m_nativeFontInfo
);
94 virtual ~wxFontRefData();
101 // all wxFont accessors
102 int GetPointSize() const
104 return m_nativeFontInfo
.GetPointSize();
107 wxSize
GetPixelSize() const
109 return m_nativeFontInfo
.GetPixelSize();
112 bool IsUsingSizeInPixels() const
114 return m_sizeUsingPixels
;
117 wxFontFamily
GetFamily() const
119 return m_nativeFontInfo
.GetFamily();
122 wxFontStyle
GetStyle() const
124 return m_nativeFontInfo
.GetStyle();
127 wxFontWeight
GetWeight() const
129 return m_nativeFontInfo
.GetWeight();
132 bool GetUnderlined() const
134 return m_nativeFontInfo
.GetUnderlined();
137 bool GetStrikethrough() const
139 return m_nativeFontInfo
.GetStrikethrough();
142 wxString
GetFaceName() const
144 wxString facename
= m_nativeFontInfo
.GetFaceName();
145 if ( facename
.empty() )
147 facename
= GetMSWFaceName();
148 if ( !facename
.empty() )
150 // cache the face name, it shouldn't change unless the family
151 // does and wxNativeFontInfo::SetFamily() resets the face name
152 const_cast<wxFontRefData
*>(this)->SetFaceName(facename
);
159 wxFontEncoding
GetEncoding() const
161 return m_nativeFontInfo
.GetEncoding();
164 WXHFONT
GetHFONT() const
168 return (WXHFONT
)m_hFont
;
171 bool HasHFONT() const
176 // ... and setters: notice that all of them invalidate the currently
177 // allocated HFONT, if any, so that the next call to GetHFONT() recreates a
179 void SetPointSize(int pointSize
)
183 m_nativeFontInfo
.SetPointSize(pointSize
);
184 m_sizeUsingPixels
= false;
187 void SetPixelSize(const wxSize
& pixelSize
)
189 wxCHECK_RET( pixelSize
.GetWidth() >= 0, "negative font width" );
190 wxCHECK_RET( pixelSize
.GetHeight() != 0, "zero font height" );
194 m_nativeFontInfo
.SetPixelSize(pixelSize
);
195 m_sizeUsingPixels
= true;
198 void SetFamily(wxFontFamily family
)
202 m_nativeFontInfo
.SetFamily(family
);
205 void SetStyle(wxFontStyle style
)
209 m_nativeFontInfo
.SetStyle(style
);
212 void SetWeight(wxFontWeight weight
)
216 m_nativeFontInfo
.SetWeight(weight
);
219 bool SetFaceName(const wxString
& faceName
)
223 return m_nativeFontInfo
.SetFaceName(faceName
);
226 void SetUnderlined(bool underlined
)
230 m_nativeFontInfo
.SetUnderlined(underlined
);
233 void SetStrikethrough(bool strikethrough
)
237 m_nativeFontInfo
.SetStrikethrough(strikethrough
);
240 void SetEncoding(wxFontEncoding encoding
)
244 m_nativeFontInfo
.SetEncoding(encoding
);
247 const wxNativeFontInfo
& GetNativeFontInfo() const
249 // we need to create the font now to get the corresponding LOGFONT if
250 // it hadn't been done yet
253 // ensure that we have a valid face name in our font information:
254 // GetFaceName() will try to retrieve it from our HFONT and save it if
258 return m_nativeFontInfo
;
261 void SetNativeFontInfo(const wxNativeFontInfo
& nativeFontInfo
)
265 m_nativeFontInfo
= nativeFontInfo
;
269 // common part of all ctors
271 const wxSize
& pixelSize
,
272 bool sizeUsingPixels
,
278 const wxString
& faceName
,
279 wxFontEncoding encoding
);
281 void Init(const wxNativeFontInfo
& info
, WXHFONT hFont
= 0);
283 void AllocIfNeeded() const
286 const_cast<wxFontRefData
*>(this)->Alloc();
289 // retrieve the face name really being used by the font: this is used to
290 // get the face name selected by the system when we don't specify it (but
291 // use just the family for example)
292 wxString
GetMSWFaceName() const
295 SelectInHDC
selectFont(hdc
, (HFONT
)GetHFONT());
297 UINT otmSize
= GetOutlineTextMetrics(hdc
, 0, NULL
);
300 wxLogLastError("GetOutlineTextMetrics(NULL)");
304 OUTLINETEXTMETRIC
* const
305 otm
= static_cast<OUTLINETEXTMETRIC
*>(malloc(otmSize
));
306 wxON_BLOCK_EXIT1( free
, otm
);
308 otm
->otmSize
= otmSize
;
309 if ( !GetOutlineTextMetrics(hdc
, otmSize
, otm
) )
311 wxLogLastError("GetOutlineTextMetrics()");
315 // in spite of its type, the otmpFamilyName field of OUTLINETEXTMETRIC
316 // gives an offset in _bytes_ of the face (not family!) name from the
317 // struct start while the name itself is an array of TCHARs
319 // FWIW otmpFaceName contains the same thing as otmpFamilyName followed
320 // by a possible " Italic" or " Bold" or something else suffix
321 return reinterpret_cast<wxChar
*>(otm
) +
322 wxPtrToUInt(otm
->otmpFamilyName
)/sizeof(wxChar
);
325 // are we using m_nativeFontInfo.lf.lfHeight for point size or pixel size?
326 bool m_sizeUsingPixels
;
328 // Windows font handle, created on demand in GetHFONT()
332 wxNativeFontInfo m_nativeFontInfo
;
335 #define M_FONTDATA ((wxFontRefData*)m_refData)
337 // ============================================================================
339 // ============================================================================
341 // ----------------------------------------------------------------------------
343 // ----------------------------------------------------------------------------
345 void wxFontRefData::Init(int pointSize
,
346 const wxSize
& pixelSize
,
347 bool sizeUsingPixels
,
353 const wxString
& faceName
,
354 wxFontEncoding encoding
)
358 m_sizeUsingPixels
= sizeUsingPixels
;
359 if ( m_sizeUsingPixels
)
360 SetPixelSize(pixelSize
);
362 SetPointSize(pointSize
);
366 SetUnderlined(underlined
);
367 SetStrikethrough(strikethrough
);
369 // set the family/facename
371 if ( !faceName
.empty() )
372 SetFaceName(faceName
);
374 // deal with encoding now (it may override the font family and facename
375 // so do it after setting them)
376 SetEncoding(encoding
);
379 void wxFontRefData::Init(const wxNativeFontInfo
& info
, WXHFONT hFont
)
381 // hFont may be zero, or it be passed in case we really want to
382 // use the exact font created in the underlying system
383 // (for example where we can't guarantee conversion from HFONT
384 // to LOGFONT back to HFONT)
385 m_hFont
= (HFONT
)hFont
;
386 m_nativeFontInfo
= info
;
388 // TODO: m_sizeUsingPixels?
391 wxFontRefData::~wxFontRefData()
396 bool wxFontRefData::Alloc()
398 m_hFont
= ::CreateFontIndirect(&m_nativeFontInfo
.lf
);
401 wxLogLastError(wxT("CreateFont"));
408 void wxFontRefData::Free()
412 if ( !::DeleteObject(m_hFont
) )
414 wxLogLastError(wxT("DeleteObject(font)"));
421 // ----------------------------------------------------------------------------
423 // ----------------------------------------------------------------------------
425 void wxNativeFontInfo::Init()
429 // we get better font quality if we use PROOF_QUALITY instead of
430 // DEFAULT_QUALITY but some fonts (e.g. "Terminal 6pt") are not available
431 // then so we allow to set a global option to choose between quality and
432 // wider font selection
434 lf
.lfQuality
= CLEARTYPE_QUALITY
;
436 lf
.lfQuality
= wxSystemOptions::GetOptionInt("msw.font.no-proof-quality")
442 int wxNativeFontInfo::GetPointSize() const
444 // FIXME: using the screen here results in incorrect font size calculation
446 const int ppInch
= ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY
);
448 // BC++ 2007 doesn't provide abs(long) overload, hence the cast
449 return (int) (((72.0*abs((int)lf
.lfHeight
)) / (double) ppInch
) + 0.5);
452 wxSize
wxNativeFontInfo::GetPixelSize() const
455 ret
.SetHeight(abs((int)lf
.lfHeight
));
456 ret
.SetWidth(lf
.lfWidth
);
460 wxFontStyle
wxNativeFontInfo::GetStyle() const
462 return lf
.lfItalic
? wxFONTSTYLE_ITALIC
: wxFONTSTYLE_NORMAL
;
465 wxFontWeight
wxNativeFontInfo::GetWeight() const
467 if ( lf
.lfWeight
<= 300 )
468 return wxFONTWEIGHT_LIGHT
;
470 if ( lf
.lfWeight
>= 600 )
471 return wxFONTWEIGHT_BOLD
;
473 return wxFONTWEIGHT_NORMAL
;
476 bool wxNativeFontInfo::GetUnderlined() const
478 return lf
.lfUnderline
!= 0;
481 bool wxNativeFontInfo::GetStrikethrough() const
483 return lf
.lfStrikeOut
!= 0;
486 wxString
wxNativeFontInfo::GetFaceName() const
488 return lf
.lfFaceName
;
491 wxFontFamily
wxNativeFontInfo::GetFamily() const
495 // extract family from pitch-and-family
496 switch ( lf
.lfPitchAndFamily
& ~PITCH_MASK
)
499 family
= wxFONTFAMILY_UNKNOWN
;
503 family
= wxFONTFAMILY_ROMAN
;
507 family
= wxFONTFAMILY_SWISS
;
511 family
= wxFONTFAMILY_SCRIPT
;
515 family
= wxFONTFAMILY_MODERN
;
519 family
= wxFONTFAMILY_DECORATIVE
;
523 wxFAIL_MSG( "unknown LOGFONT::lfFamily value" );
524 family
= wxFONTFAMILY_UNKNOWN
;
525 // just to avoid a warning
531 wxFontEncoding
wxNativeFontInfo::GetEncoding() const
533 return wxGetFontEncFromCharSet(lf
.lfCharSet
);
536 void wxNativeFontInfo::SetPointSize(int pointsize
)
538 // FIXME: using the screen here results in incorrect font size calculation
540 const int ppInch
= ::GetDeviceCaps(ScreenHDC(), LOGPIXELSY
);
542 lf
.lfHeight
= -(int)((pointsize
*((double)ppInch
)/72.0) + 0.5);
545 void wxNativeFontInfo::SetPixelSize(const wxSize
& pixelSize
)
547 // MSW accepts both positive and negative heights here but they mean
548 // different things: positive specifies the cell height while negative
549 // specifies the character height. We used to just pass the value to MSW
550 // unchanged but changed the behaviour for positive values in 2.9.1 to
551 // match other ports and, more importantly, the expected behaviour. So now
552 // passing the negative height doesn't make sense at all any more but we
553 // still accept it for compatibility with the existing code which worked
554 // around the wrong interpretation of the height argument in older wxMSW
555 // versions by passing a negative value explicitly itself.
556 lf
.lfHeight
= -abs(pixelSize
.GetHeight());
557 lf
.lfWidth
= pixelSize
.GetWidth();
560 void wxNativeFontInfo::SetStyle(wxFontStyle style
)
565 wxFAIL_MSG( "unknown font style" );
568 case wxFONTSTYLE_NORMAL
:
572 case wxFONTSTYLE_ITALIC
:
573 case wxFONTSTYLE_SLANT
:
579 void wxNativeFontInfo::SetWeight(wxFontWeight weight
)
584 wxFAIL_MSG( "unknown font weight" );
587 case wxFONTWEIGHT_NORMAL
:
588 lf
.lfWeight
= FW_NORMAL
;
591 case wxFONTWEIGHT_LIGHT
:
592 lf
.lfWeight
= FW_LIGHT
;
595 case wxFONTWEIGHT_BOLD
:
596 lf
.lfWeight
= FW_BOLD
;
601 void wxNativeFontInfo::SetUnderlined(bool underlined
)
603 lf
.lfUnderline
= underlined
;
606 void wxNativeFontInfo::SetStrikethrough(bool strikethrough
)
608 lf
.lfStrikeOut
= strikethrough
;
611 bool wxNativeFontInfo::SetFaceName(const wxString
& facename
)
613 wxStrlcpy(lf
.lfFaceName
, facename
.c_str(), WXSIZEOF(lf
.lfFaceName
));
617 void wxNativeFontInfo::SetFamily(wxFontFamily family
)
619 BYTE ff_family
= FF_DONTCARE
;
623 case wxFONTFAMILY_SCRIPT
:
624 ff_family
= FF_SCRIPT
;
627 case wxFONTFAMILY_DECORATIVE
:
628 ff_family
= FF_DECORATIVE
;
631 case wxFONTFAMILY_ROMAN
:
632 ff_family
= FF_ROMAN
;
635 case wxFONTFAMILY_TELETYPE
:
636 case wxFONTFAMILY_MODERN
:
637 ff_family
= FF_MODERN
;
640 case wxFONTFAMILY_SWISS
:
641 case wxFONTFAMILY_DEFAULT
:
642 ff_family
= FF_SWISS
;
645 case wxFONTFAMILY_UNKNOWN
:
646 wxFAIL_MSG( "invalid font family" );
650 wxCHECK_RET( ff_family
!= FF_DONTCARE
, "unknown wxFontFamily" );
652 lf
.lfPitchAndFamily
= (BYTE
)(DEFAULT_PITCH
) | ff_family
;
654 // reset the facename so that CreateFontIndirect() will automatically choose a
655 // face name based only on the font family.
656 lf
.lfFaceName
[0] = '\0';
659 void wxNativeFontInfo::SetEncoding(wxFontEncoding encoding
)
661 wxNativeEncodingInfo info
;
662 if ( !wxGetNativeFontEncoding(encoding
, &info
) )
665 if ( wxFontMapper::Get()->GetAltForEncoding(encoding
, &info
) )
667 if ( !info
.facename
.empty() )
669 // if we have this encoding only in some particular facename, use
670 // the facename - it is better to show the correct characters in a
671 // wrong facename than unreadable text in a correct one
672 SetFaceName(info
.facename
);
676 #endif // wxUSE_FONTMAP
678 // unsupported encoding, replace with the default
679 info
.charset
= DEFAULT_CHARSET
;
683 lf
.lfCharSet
= (BYTE
)info
.charset
;
686 bool wxNativeFontInfo::FromString(const wxString
& s
)
690 wxStringTokenizer
tokenizer(s
, wxS(";"), wxTOKEN_RET_EMPTY_ALL
);
693 wxString token
= tokenizer
.GetNextToken();
694 if ( token
!= wxS('0') )
697 token
= tokenizer
.GetNextToken();
698 if ( !token
.ToLong(&l
) )
702 token
= tokenizer
.GetNextToken();
703 if ( !token
.ToLong(&l
) )
707 token
= tokenizer
.GetNextToken();
708 if ( !token
.ToLong(&l
) )
712 token
= tokenizer
.GetNextToken();
713 if ( !token
.ToLong(&l
) )
715 lf
.lfOrientation
= l
;
717 token
= tokenizer
.GetNextToken();
718 if ( !token
.ToLong(&l
) )
722 token
= tokenizer
.GetNextToken();
723 if ( !token
.ToLong(&l
) )
725 lf
.lfItalic
= (BYTE
)l
;
727 token
= tokenizer
.GetNextToken();
728 if ( !token
.ToLong(&l
) )
730 lf
.lfUnderline
= (BYTE
)l
;
732 token
= tokenizer
.GetNextToken();
733 if ( !token
.ToLong(&l
) )
735 lf
.lfStrikeOut
= (BYTE
)l
;
737 token
= tokenizer
.GetNextToken();
738 if ( !token
.ToLong(&l
) )
740 lf
.lfCharSet
= (BYTE
)l
;
742 token
= tokenizer
.GetNextToken();
743 if ( !token
.ToLong(&l
) )
745 lf
.lfOutPrecision
= (BYTE
)l
;
747 token
= tokenizer
.GetNextToken();
748 if ( !token
.ToLong(&l
) )
750 lf
.lfClipPrecision
= (BYTE
)l
;
752 token
= tokenizer
.GetNextToken();
753 if ( !token
.ToLong(&l
) )
755 lf
.lfQuality
= (BYTE
)l
;
757 token
= tokenizer
.GetNextToken();
758 if ( !token
.ToLong(&l
) )
760 lf
.lfPitchAndFamily
= (BYTE
)l
;
762 if ( !tokenizer
.HasMoreTokens() )
765 // the face name may be empty
766 SetFaceName(tokenizer
.GetNextToken());
771 wxString
wxNativeFontInfo::ToString() const
775 s
.Printf(wxS("%d;%ld;%ld;%ld;%ld;%ld;%d;%d;%d;%d;%d;%d;%d;%d;%s"),
776 0, // version, in case we want to change the format later
795 // ----------------------------------------------------------------------------
797 // ----------------------------------------------------------------------------
799 wxFont::wxFont(const wxString
& fontdesc
)
801 wxNativeFontInfo info
;
802 if ( info
.FromString(fontdesc
) )
806 wxFont::wxFont(const wxFontInfo
& info
)
808 m_refData
= new wxFontRefData(info
.GetPointSize(),
810 info
.IsUsingSizeInPixels(),
815 info
.IsStrikethrough(),
820 bool wxFont::Create(const wxNativeFontInfo
& info
, WXHFONT hFont
)
824 m_refData
= new wxFontRefData(info
, hFont
);
826 return RealizeResource();
829 bool wxFont::DoCreate(int pointSize
,
830 const wxSize
& pixelSize
,
831 bool sizeUsingPixels
,
836 const wxString
& faceName
,
837 wxFontEncoding encoding
)
841 // wxDEFAULT is a valid value for the font size too so we must treat it
842 // specially here (otherwise the size would be 70 == wxDEFAULT value)
843 if ( pointSize
== wxDEFAULT
|| pointSize
== -1 )
845 pointSize
= wxNORMAL_FONT
->GetPointSize();
848 m_refData
= new wxFontRefData(pointSize
, pixelSize
, sizeUsingPixels
,
849 family
, style
, weight
,
850 underlined
, false, faceName
, encoding
);
852 return RealizeResource();
859 // ----------------------------------------------------------------------------
860 // real implementation
861 // ----------------------------------------------------------------------------
863 wxGDIRefData
*wxFont::CreateGDIRefData() const
865 return new wxFontRefData();
868 wxGDIRefData
*wxFont::CloneGDIRefData(const wxGDIRefData
*data
) const
870 return new wxFontRefData(*static_cast<const wxFontRefData
*>(data
));
873 bool wxFont::RealizeResource()
875 // NOTE: the GetHFONT() call automatically triggers a reallocation of
876 // the HFONT if necessary (will do nothing if we already have the resource);
877 // it returns NULL only if there is a failure in wxFontRefData::Alloc()...
878 return GetHFONT() != NULL
;
881 bool wxFont::FreeResource(bool WXUNUSED(force
))
891 WXHANDLE
wxFont::GetResourceHandle() const
893 return (WXHANDLE
)GetHFONT();
896 WXHFONT
wxFont::GetHFONT() const
898 // NOTE: wxFontRefData::GetHFONT() will automatically call
899 // wxFontRefData::Alloc() if necessary
900 return M_FONTDATA
? M_FONTDATA
->GetHFONT() : 0;
903 bool wxFont::IsFree() const
905 return M_FONTDATA
&& !M_FONTDATA
->HasHFONT();
908 // ----------------------------------------------------------------------------
909 // change font attribute: we recreate font when doing it
910 // ----------------------------------------------------------------------------
912 void wxFont::SetPointSize(int pointSize
)
917 M_FONTDATA
->SetPointSize(pointSize
);
920 void wxFont::SetPixelSize(const wxSize
& pixelSize
)
924 M_FONTDATA
->SetPixelSize(pixelSize
);
927 void wxFont::SetFamily(wxFontFamily family
)
931 M_FONTDATA
->SetFamily(family
);
934 void wxFont::SetStyle(wxFontStyle style
)
938 M_FONTDATA
->SetStyle(style
);
941 void wxFont::SetWeight(wxFontWeight weight
)
945 M_FONTDATA
->SetWeight(weight
);
948 bool wxFont::SetFaceName(const wxString
& faceName
)
952 if ( !M_FONTDATA
->SetFaceName(faceName
) )
955 // NB: using win32's GetObject() API on M_FONTDATA->GetHFONT()
956 // to retrieve a LOGFONT and then compare lf.lfFaceName
957 // with given facename is not reliable at all:
958 // Windows copies the facename given to ::CreateFontIndirect()
959 // without any validity check.
960 // Thus we use wxFontBase::SetFaceName to check if facename
962 return wxFontBase::SetFaceName(faceName
);
965 void wxFont::SetUnderlined(bool underlined
)
969 M_FONTDATA
->SetUnderlined(underlined
);
972 void wxFont::SetStrikethrough(bool strikethrough
)
976 M_FONTDATA
->SetStrikethrough(strikethrough
);
979 void wxFont::SetEncoding(wxFontEncoding encoding
)
983 M_FONTDATA
->SetEncoding(encoding
);
986 void wxFont::DoSetNativeFontInfo(const wxNativeFontInfo
& info
)
990 M_FONTDATA
->SetNativeFontInfo(info
);
993 // ----------------------------------------------------------------------------
995 // ----------------------------------------------------------------------------
997 int wxFont::GetPointSize() const
999 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
1001 return M_FONTDATA
->GetPointSize();
1004 wxSize
wxFont::GetPixelSize() const
1006 wxCHECK_MSG( IsOk(), wxDefaultSize
, wxT("invalid font") );
1008 return M_FONTDATA
->GetPixelSize();
1011 bool wxFont::IsUsingSizeInPixels() const
1013 wxCHECK_MSG( IsOk(), 0, wxT("invalid font") );
1015 return M_FONTDATA
->IsUsingSizeInPixels();
1018 wxFontFamily
wxFont::DoGetFamily() const
1020 return M_FONTDATA
->GetFamily();
1023 wxFontStyle
wxFont::GetStyle() const
1025 wxCHECK_MSG( IsOk(), wxFONTSTYLE_MAX
, wxT("invalid font") );
1027 return M_FONTDATA
->GetStyle();
1030 wxFontWeight
wxFont::GetWeight() const
1032 wxCHECK_MSG( IsOk(), wxFONTWEIGHT_MAX
, wxT("invalid font") );
1034 return M_FONTDATA
->GetWeight();
1037 bool wxFont::GetUnderlined() const
1039 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
1041 return M_FONTDATA
->GetUnderlined();
1044 bool wxFont::GetStrikethrough() const
1046 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
1048 return M_FONTDATA
->GetStrikethrough();
1051 wxString
wxFont::GetFaceName() const
1053 wxCHECK_MSG( IsOk(), wxEmptyString
, wxT("invalid font") );
1055 return M_FONTDATA
->GetFaceName();
1058 wxFontEncoding
wxFont::GetEncoding() const
1060 wxCHECK_MSG( IsOk(), wxFONTENCODING_DEFAULT
, wxT("invalid font") );
1062 return M_FONTDATA
->GetEncoding();
1065 const wxNativeFontInfo
*wxFont::GetNativeFontInfo() const
1067 return IsOk() ? &(M_FONTDATA
->GetNativeFontInfo()) : NULL
;
1070 bool wxFont::IsFixedWidth() const
1072 wxCHECK_MSG( IsOk(), false, wxT("invalid font") );
1074 // LOGFONT doesn't contain the correct pitch information so we need to call
1075 // GetTextMetrics() to get it
1077 SelectInHDC
selectFont(hdc
, M_FONTDATA
->GetHFONT());
1080 if ( !::GetTextMetrics(hdc
, &tm
) )
1082 wxLogLastError(wxT("GetTextMetrics"));
1086 // Quoting MSDN description of TMPF_FIXED_PITCH: "Note very carefully that
1087 // those meanings are the opposite of what the constant name implies."
1088 return !(tm
.tmPitchAndFamily
& TMPF_FIXED_PITCH
);