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);