Allow FontInfo{,Base,Desired} to store a font name > 32 wch (#3107)

We now truncate the font name as it goes out to GDI APIs, in console API
servicing, and in the propsheet.

I attempted to defer truncating the font to as far up the stack as
possible, so as to make FontInfo usable for the broadest set of cases.

There were a couple questions that came up: I know that `Settings` gets
memset (memsat?) by the registry deserializer, and perhaps that's
another place for us to tackle. Right now, this pull request enables
fonts whose names are >= 32 characters _in Windows Terminal only_, but
the underpinnings are there for conhost as well. We'd need to explicitly
break at the API, or perhaps return a failure or log something to
telemetry.

* Should we log truncation at the API boundary to telemetry?
-> Later; followup filed (#3123)

* Should we fix Settings here, or later?
-> Later; followup filed (#3123)

* `TrueTypeFontList` is built out of things in winconp, the private
console header. Concern about interop structures.
-> Not used for interop, followup filed to clean it up (#3123)

* Is `unsigned int` right for codepage? For width?
-> Yes: codepage became UINT (from WORD) when we moved from Win16 to
Win32

This commit also includes a workaround for #3170. Growing
CONSOLE_INFORMATION made us lose the struct layout lottery during
release builds, and this was an expedient fix.

Closes #602.
Related to #3123.
This commit is contained in:
Dustin L. Howett 2019-10-14 21:23:45 -07:00 committed by Dustin L. Howett (MSFT)
parent b9233c03d1
commit b664761c79
24 changed files with 154 additions and 158 deletions

View file

@ -1065,14 +1065,10 @@ const TextBuffer::TextAndColor TextBuffer::GetTextForClipboard(const bool lineSe
// - htmlTitle - value used in title tag of html header. Used to name the application
// Return Value:
// - string containing the generated HTML
std::string TextBuffer::GenHTML(const TextAndColor& rows, const int fontHeightPoints, const PCWCHAR fontFaceName, const COLORREF backgroundColor, const std::string& htmlTitle)
std::string TextBuffer::GenHTML(const TextAndColor& rows, const int fontHeightPoints, const std::wstring_view fontFaceName, const COLORREF backgroundColor, const std::string& htmlTitle)
{
try
{
// TODO: GH 602 the font name needs to be passed and stored around as an actual bounded type, not an implicit bounds on LF_FACESIZE
const auto faceLength = wcsnlen_s(fontFaceName, LF_FACESIZE);
const std::wstring_view faceNameView{ fontFaceName, faceLength };
std::ostringstream htmlBuilder;
// First we have to add some standard
@ -1096,7 +1092,7 @@ std::string TextBuffer::GenHTML(const TextAndColor& rows, const int fontHeightPo
htmlBuilder << "font-family:";
htmlBuilder << "'";
htmlBuilder << ConvertToA(CP_UTF8, faceNameView);
htmlBuilder << ConvertToA(CP_UTF8, fontFaceName);
htmlBuilder << "',";
// even with different font, add monospace as fallback
htmlBuilder << "monospace;";

View file

@ -146,7 +146,7 @@ public:
static std::string GenHTML(const TextAndColor& rows,
const int fontHeightPoints,
const PCWCHAR fontFaceName,
const std::wstring_view fontFaceName,
const COLORREF backgroundColor,
const std::string& htmlTitle);

View file

@ -269,7 +269,7 @@ void ApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept
consoleFontInfoEx.FontFamily = fontInfo.GetFamily();
consoleFontInfoEx.FontWeight = fontInfo.GetWeight();
RETURN_IF_FAILED(StringCchCopyW(consoleFontInfoEx.FaceName, ARRAYSIZE(consoleFontInfoEx.FaceName), fontInfo.GetFaceName()));
RETURN_IF_FAILED(fontInfo.FillLegacyNameBuffer(gsl::make_span(consoleFontInfoEx.FaceName)));
return S_OK;
}
@ -300,7 +300,7 @@ void ApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept
RETURN_IF_FAILED(StringCchCopyW(FaceName, ARRAYSIZE(FaceName), consoleFontInfoEx.FaceName));
FontInfo fi(FaceName,
static_cast<BYTE>(consoleFontInfoEx.FontFamily),
gsl::narrow_cast<unsigned char>(consoleFontInfoEx.FontFamily),
consoleFontInfoEx.FontWeight,
consoleFontInfoEx.dwFontSize,
gci.OutputCP);

View file

@ -26,7 +26,7 @@ using namespace Microsoft::Console::Interactivity;
CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
FontInfo fiFont(gci.GetFaceName(),
static_cast<BYTE>(gci.GetFontFamily()),
gsl::narrow_cast<unsigned char>(gci.GetFontFamily()),
gci.GetFontWeight(),
gci.GetFontSize(),
gci.GetCodePage());

View file

@ -17,10 +17,14 @@ RenderFontDefaults::~RenderFontDefaults()
LOG_IF_FAILED(TrueTypeFontList::s_Destroy());
}
[[nodiscard]] HRESULT RenderFontDefaults::RetrieveDefaultFontNameForCodepage(const UINT uiCodePage,
_Out_writes_(cchFaceName) PWSTR pwszFaceName,
const size_t cchFaceName)
[[nodiscard]] HRESULT RenderFontDefaults::RetrieveDefaultFontNameForCodepage(const unsigned int codePage,
std::wstring& outFaceName)
try
{
NTSTATUS status = TrueTypeFontList::s_SearchByCodePage(uiCodePage, pwszFaceName, cchFaceName);
// GH#3123: Propagate font length changes up through Settings and propsheet
wchar_t faceName[LF_FACESIZE]{ 0 };
NTSTATUS status = TrueTypeFontList::s_SearchByCodePage(codePage, faceName, ARRAYSIZE(faceName));
outFaceName.assign(faceName);
return HRESULT_FROM_NT(status);
}
CATCH_RETURN();

View file

@ -22,7 +22,6 @@ public:
RenderFontDefaults();
~RenderFontDefaults();
[[nodiscard]] HRESULT RetrieveDefaultFontNameForCodepage(const UINT uiCodePage,
_Out_writes_(cchFaceName) PWSTR pwszFaceName,
const size_t cchFaceName);
[[nodiscard]] HRESULT RetrieveDefaultFontNameForCodepage(const unsigned int codePage,
std::wstring& outFaceName);
};

View file

@ -12,8 +12,6 @@
using namespace Microsoft::Console::Interactivity;
using namespace Microsoft::Console::Types;
std::unique_ptr<Selection> Selection::_instance;
Selection::Selection() :
_fSelectionVisible(false),
_ulSavedCursorSize(0),
@ -32,10 +30,7 @@ Selection::Selection() :
Selection& Selection::Instance()
{
if (!_instance)
{
_instance.reset(new Selection());
}
static std::unique_ptr<Selection> _instance{ new Selection() };
return *_instance;
}

View file

@ -84,8 +84,6 @@ private:
void _CancelMarkSelection();
void _CancelMouseSelection();
static std::unique_ptr<Selection> _instance;
// -------------------------------------------------------------------------------------------------------
// input handling (selectionInput.cpp)
public:

View file

@ -45,6 +45,7 @@ Settings::Settings() :
_fCtrlKeyShortcutsDisabled(false),
_bWindowAlpha(BYTE_MAX), // 255 alpha = opaque. 0 = transparent.
_fFilterOnPaste(false),
_LaunchFaceName{},
_fTrimLeadingZeros(FALSE),
_fEnableColorSelection(FALSE),
_fAllowAltF4Close(true),
@ -76,8 +77,6 @@ Settings::Settings() :
ZeroMemory((void*)&_FaceName, sizeof(_FaceName));
wcscpy_s(_FaceName, DEFAULT_TT_FONT_FACENAME);
ZeroMemory((void*)&_LaunchFaceName, sizeof(_LaunchFaceName));
_CursorColor = Cursor::s_InvertCursorColor;
_CursorType = CursorType::Legacy;
@ -404,13 +403,13 @@ void Settings::SetFilterOnPaste(const bool fFilterOnPaste)
_fFilterOnPaste = fFilterOnPaste;
}
const WCHAR* const Settings::GetLaunchFaceName() const
const std::wstring_view Settings::GetLaunchFaceName() const
{
return _LaunchFaceName;
}
void Settings::SetLaunchFaceName(_In_ PCWSTR const LaunchFaceName, const size_t cchLength)
void Settings::SetLaunchFaceName(const std::wstring_view launchFaceName)
{
StringCchCopyW(_LaunchFaceName, cchLength, LaunchFaceName);
_LaunchFaceName = launchFaceName;
}
UINT Settings::GetCodePage() const
@ -630,9 +629,10 @@ const WCHAR* const Settings::GetFaceName() const
{
return _FaceName;
}
void Settings::SetFaceName(_In_ PCWSTR const pcszFaceName, const size_t cchLength)
void Settings::SetFaceName(const std::wstring_view faceName)
{
StringCchCopyW(_FaceName, cchLength, pcszFaceName);
auto extent = std::min<size_t>(faceName.size(), ARRAYSIZE(_FaceName));
StringCchCopyW(_FaceName, extent, faceName.data());
}
UINT Settings::GetCursorSize() const

View file

@ -55,8 +55,8 @@ public:
bool GetFilterOnPaste() const;
void SetFilterOnPaste(const bool fFilterOnPaste);
const WCHAR* const GetLaunchFaceName() const;
void SetLaunchFaceName(_In_ PCWSTR const LaunchFaceName, const size_t cchLength);
const std::wstring_view GetLaunchFaceName() const;
void SetLaunchFaceName(const std::wstring_view launchFaceName);
UINT GetCodePage() const;
void SetCodePage(const UINT uCodePage);
@ -130,7 +130,7 @@ public:
const WCHAR* const GetFaceName() const;
bool IsFaceNameSet() const;
void SetFaceName(_In_ PCWSTR const pcszFaceName, const size_t cchLength);
void SetFaceName(const std::wstring_view faceName);
UINT GetCursorSize() const;
void SetCursorSize(const UINT uCursorSize);
@ -226,7 +226,7 @@ private:
BYTE _bWindowAlpha; // describes the opacity of the window
bool _fFilterOnPaste; // should we filter text when the user pastes? (e.g. remove <tab>)
WCHAR _LaunchFaceName[LF_FACESIZE];
std::wstring _LaunchFaceName;
bool _fAllowAltF4Close;
DWORD _dwVirtTermLevel;
bool _fAutoReturnOnNewline;

View file

@ -46,7 +46,7 @@ const UINT CONSOLE_LPC_PORT_FAILURE_ID = 21791;
Globals.pFontDefaultList = new RenderFontDefaults();
FontInfo::s_SetFontDefaultList(Globals.pFontDefaultList);
FontInfoBase::s_SetFontDefaultList(Globals.pFontDefaultList);
}
CATCH_RETURN();
@ -187,7 +187,7 @@ static bool s_IsOnDesktop()
//Save initial font name for comparison on exit. We want telemetry when the font has changed
if (settings.IsFaceNameSet())
{
settings.SetLaunchFaceName(settings.GetFaceName(), LF_FACESIZE);
settings.SetLaunchFaceName(settings.GetFaceName());
}
// Allocate console will read the global ServiceLocator::LocateGlobals().getConsoleInformation

View file

@ -439,7 +439,7 @@ void Telemetry::WriteFinalTraceLog()
TraceLoggingBool(gci.GetEnableColorSelection(), "EnabledColorSelection"),
TraceLoggingBool(gci.GetFilterOnPaste(), "FilterOnPaste"),
TraceLoggingBool(gci.GetTrimLeadingZeros(), "TrimLeadingZeros"),
TraceLoggingValue(gci.GetLaunchFaceName(), "LaunchFontName"),
TraceLoggingValue(gci.GetLaunchFaceName().data(), "LaunchFontName"),
TraceLoggingValue(CommandHistory::s_CountOfHistories(), "CommandHistoriesNumber"),
TraceLoggingValue(gci.GetCodePage(), "CodePage"),
TraceLoggingValue(gci.GetCursorSize(), "CursorSize"),

View file

@ -5,6 +5,8 @@
#include "SystemConfigurationProvider.hpp"
static constexpr wchar_t DEFAULT_TT_FONT_FACENAME[]{ L"__DefaultTTFont__" };
using namespace Microsoft::Console::Interactivity::OneCore;
UINT SystemConfigurationProvider::GetCaretBlinkTime()
@ -60,7 +62,7 @@ void SystemConfigurationProvider::GetSettingsFromLink(
// Hence, we make it seem like the console is in fact configred to use a
// TrueType font by the user.
pLinkSettings->SetFaceName(DEFAULT_TT_FONT_FACENAME, ARRAYSIZE(DEFAULT_TT_FONT_FACENAME));
pLinkSettings->SetFaceName(DEFAULT_TT_FONT_FACENAME);
pLinkSettings->SetFontFamily(TMPF_TRUETYPE);
return;

View file

@ -18,10 +18,6 @@ Author(s):
#pragma hdrstop
#ifndef DEFAULT_TT_FONT_FACENAME
#define DEFAULT_TT_FONT_FACENAME L"__DefaultTTFont__"
#endif
class InputTests;
namespace Microsoft::Console::Interactivity::OneCore

View file

@ -313,7 +313,7 @@ void Menu::s_ShowPropertiesDialog(HWND const hwnd, BOOL const Defaults)
pStateInfo->FontFamily = currentFont.GetFamily();
pStateInfo->FontSize = currentFont.GetUnscaledSize();
pStateInfo->FontWeight = currentFont.GetWeight();
StringCchCopyW(pStateInfo->FaceName, ARRAYSIZE(pStateInfo->FaceName), currentFont.GetFaceName());
LOG_IF_FAILED(StringCchCopyW(pStateInfo->FaceName, ARRAYSIZE(pStateInfo->FaceName), currentFont.GetFaceName().data()));
const Cursor& cursor = ScreenInfo.GetTextBuffer().GetCursor();
pStateInfo->CursorSize = cursor.GetSize();
@ -447,7 +447,7 @@ void Menu::s_PropertiesUpdate(PCONSOLE_STATE_INFO pStateInfo)
// end V2 console properties
// Apply font information (must come before all character calculations for window/buffer size).
FontInfo fiNewFont(pStateInfo->FaceName, static_cast<BYTE>(pStateInfo->FontFamily), pStateInfo->FontWeight, pStateInfo->FontSize, pStateInfo->CodePage);
FontInfo fiNewFont(pStateInfo->FaceName, gsl::narrow_cast<unsigned char>(pStateInfo->FontFamily), pStateInfo->FontWeight, pStateInfo->FontSize, pStateInfo->CodePage);
ScreenInfo.UpdateFont(&fiNewFont);
@ -457,7 +457,7 @@ void Menu::s_PropertiesUpdate(PCONSOLE_STATE_INFO pStateInfo)
gci.SetFontFamily(fontApplied.GetFamily());
gci.SetFontSize(fontApplied.GetUnscaledSize());
gci.SetFontWeight(fontApplied.GetWeight());
gci.SetFaceName(fontApplied.GetFaceName(), LF_FACESIZE);
gci.SetFaceName(fontApplied.GetFaceName());
// Set the cursor properties in the Settings
const auto cursorType = static_cast<CursorType>(pStateInfo->CursorType);

View file

@ -9,28 +9,24 @@
bool operator==(const FontInfoBase& a, const FontInfoBase& b)
{
return (wcscmp(a._wszFaceName, b._wszFaceName) == 0 &&
a._lWeight == b._lWeight &&
a._bFamily == b._bFamily &&
a._uiCodePage == b._uiCodePage &&
a._fDefaultRasterSetFromEngine == b._fDefaultRasterSetFromEngine);
return a._faceName == b._faceName &&
a._weight == b._weight &&
a._family == b._family &&
a._codePage == b._codePage &&
a._fDefaultRasterSetFromEngine == b._fDefaultRasterSetFromEngine;
}
FontInfoBase::FontInfoBase(_In_ PCWSTR const pwszFaceName,
const BYTE bFamily,
const LONG lWeight,
FontInfoBase::FontInfoBase(const std::wstring_view faceName,
const unsigned char family,
const unsigned int weight,
const bool fSetDefaultRasterFont,
const UINT uiCodePage) :
_bFamily(bFamily),
_lWeight(lWeight),
const unsigned int codePage) :
_faceName(faceName),
_family(family),
_weight(weight),
_fDefaultRasterSetFromEngine(fSetDefaultRasterFont),
_uiCodePage(uiCodePage)
_codePage(codePage)
{
if (nullptr != pwszFaceName)
{
wcscpy_s(_wszFaceName, ARRAYSIZE(_wszFaceName), pwszFaceName);
}
ValidateFont();
}
@ -47,9 +43,9 @@ FontInfoBase::~FontInfoBase()
{
}
BYTE FontInfoBase::GetFamily() const
unsigned char FontInfoBase::GetFamily() const
{
return _bFamily;
return _family;
}
// When the default raster font is forced set from the engine, this is how we differentiate it from a simple apply.
@ -60,30 +56,46 @@ bool FontInfoBase::WasDefaultRasterSetFromEngine() const
return _fDefaultRasterSetFromEngine;
}
LONG FontInfoBase::GetWeight() const
unsigned int FontInfoBase::GetWeight() const
{
return _lWeight;
return _weight;
}
PCWCHAR FontInfoBase::GetFaceName() const
const std::wstring_view FontInfoBase::GetFaceName() const
{
return (PCWCHAR)_wszFaceName;
return _faceName;
}
UINT FontInfoBase::GetCodePage() const
unsigned int FontInfoBase::GetCodePage() const
{
return _uiCodePage;
return _codePage;
}
// Method Description:
// - Populates a fixed-length **null-terminated** buffer with the name of this font, truncating it as necessary.
// Positions within the buffer that are not filled by the font name are zeroed.
// Arguments:
// - buffer: the buffer into which to copy characters
// - size: the size of buffer
HRESULT FontInfoBase::FillLegacyNameBuffer(gsl::span<wchar_t> buffer) const
try
{
auto toCopy = std::min<size_t>(buffer.size() - 1, _faceName.size());
auto last = std::copy(_faceName.cbegin(), _faceName.cbegin() + toCopy, buffer.begin());
std::fill(last, buffer.end(), L'\0');
return S_OK;
}
CATCH_RETURN();
// NOTE: this method is intended to only be used from the engine itself to respond what font it has chosen.
void FontInfoBase::SetFromEngine(_In_ PCWSTR const pwszFaceName,
const BYTE bFamily,
const LONG lWeight,
void FontInfoBase::SetFromEngine(const std::wstring_view faceName,
const unsigned char family,
const unsigned int weight,
const bool fSetDefaultRasterFont)
{
wcscpy_s(_wszFaceName, ARRAYSIZE(_wszFaceName), pwszFaceName);
_bFamily = bFamily;
_lWeight = lWeight;
_faceName = faceName;
_family = family;
_weight = weight;
_fDefaultRasterSetFromEngine = fSetDefaultRasterFont;
}
@ -91,7 +103,7 @@ void FontInfoBase::SetFromEngine(_In_ PCWSTR const pwszFaceName,
// FontInfoBase doesn't have sizing information, this helper checks everything else.
bool FontInfoBase::IsDefaultRasterFontNoSize() const
{
return (_lWeight == 0 && _bFamily == 0 && wcsnlen_s(_wszFaceName, ARRAYSIZE(_wszFaceName)) == 0);
return (_weight == 0 && _family == 0 && _faceName.empty());
}
void FontInfoBase::ValidateFont()
@ -100,18 +112,17 @@ void FontInfoBase::ValidateFont()
if (!IsDefaultRasterFontNoSize() && s_pFontDefaultList != nullptr)
{
// If we have a list of default fonts and our current font is the placeholder for the defaults, substitute here.
if (0 == wcsncmp(_wszFaceName, DEFAULT_TT_FONT_FACENAME, ARRAYSIZE(DEFAULT_TT_FONT_FACENAME)))
if (_faceName == DEFAULT_TT_FONT_FACENAME)
{
WCHAR pwszDefaultFontFace[LF_FACESIZE];
std::wstring defaultFontFace;
if (SUCCEEDED(s_pFontDefaultList->RetrieveDefaultFontNameForCodepage(GetCodePage(),
pwszDefaultFontFace,
ARRAYSIZE(pwszDefaultFontFace))))
defaultFontFace)))
{
wcscpy_s(_wszFaceName, ARRAYSIZE(_wszFaceName), pwszDefaultFontFace);
_faceName = defaultFontFace;
// If we're assigning a default true type font name, make sure the family is also set to TrueType
// to help GDI select the appropriate font when we actually create it.
_bFamily = TMPF_TRUETYPE;
_family = TMPF_TRUETYPE;
}
}
}
@ -119,9 +130,11 @@ void FontInfoBase::ValidateFont()
bool FontInfoBase::IsTrueTypeFont() const
{
return (_bFamily & TMPF_TRUETYPE) != 0;
return WI_IsFlagSet(_family, TMPF_TRUETYPE);
}
Microsoft::Console::Render::IFontDefaultList* FontInfoBase::s_pFontDefaultList;
void FontInfoBase::s_SetFontDefaultList(_In_ Microsoft::Console::Render::IFontDefaultList* const pFontDefaultList)
{
s_pFontDefaultList = pFontDefaultList;

View file

@ -22,12 +22,12 @@ COORD FontInfoDesired::GetEngineSize() const
return coordSize;
}
FontInfoDesired::FontInfoDesired(_In_ PCWSTR const pwszFaceName,
const BYTE bFamily,
const LONG lWeight,
FontInfoDesired::FontInfoDesired(const std::wstring_view faceName,
const unsigned char family,
const unsigned int weight,
const COORD coordSizeDesired,
const UINT uiCodePage) :
FontInfoBase(pwszFaceName, bFamily, lWeight, false, uiCodePage),
const unsigned int codePage) :
FontInfoBase(faceName, family, weight, false, codePage),
_coordSizeDesired(coordSizeDesired)
{
}
@ -45,7 +45,7 @@ bool FontInfoDesired::IsDefaultRasterFont() const
{
// Either the raster was set from the engine...
// OR the face name is empty with a size of 0x0 or 8x12.
return WasDefaultRasterSetFromEngine() || (wcsnlen_s(GetFaceName(), LF_FACESIZE) == 0 &&
return WasDefaultRasterSetFromEngine() || (GetFaceName().empty() &&
((_coordSizeDesired.X == 0 && _coordSizeDesired.Y == 0) ||
(_coordSizeDesired.X == 8 && _coordSizeDesired.Y == 12)));
}

View file

@ -12,13 +12,13 @@ bool operator==(const FontInfo& a, const FontInfo& b)
a._coordSizeUnscaled == b._coordSizeUnscaled);
}
FontInfo::FontInfo(_In_ PCWSTR const pwszFaceName,
const BYTE bFamily,
const LONG lWeight,
FontInfo::FontInfo(const std::wstring_view faceName,
const unsigned char family,
const unsigned int weight,
const COORD coordSize,
const UINT uiCodePage,
const bool fSetDefaultRasterFont /*= false*/) :
FontInfoBase(pwszFaceName, bFamily, lWeight, fSetDefaultRasterFont, uiCodePage),
const unsigned int codePage,
const bool fSetDefaultRasterFont /* = false */) :
FontInfoBase(faceName, family, weight, fSetDefaultRasterFont, codePage),
_coordSize(coordSize),
_coordSizeUnscaled(coordSize)
{
@ -42,16 +42,16 @@ COORD FontInfo::GetSize() const
return _coordSize;
}
void FontInfo::SetFromEngine(_In_ PCWSTR const pwszFaceName,
const BYTE bFamily,
const LONG lWeight,
void FontInfo::SetFromEngine(const std::wstring_view faceName,
const unsigned char family,
const unsigned int weight,
const bool fSetDefaultRasterFont,
const COORD coordSize,
const COORD coordSizeUnscaled)
{
FontInfoBase::SetFromEngine(pwszFaceName,
bFamily,
lWeight,
FontInfoBase::SetFromEngine(faceName,
family,
weight,
fSetDefaultRasterFont);
_coordSize = coordSize;
@ -87,13 +87,3 @@ void FontInfo::_ValidateCoordSize()
}
}
}
#pragma warning(push)
#pragma warning(suppress : 4356)
Microsoft::Console::Render::IFontDefaultList* FontInfo::s_pFontDefaultList;
#pragma warning(pop)
void FontInfo::s_SetFontDefaultList(_In_ Microsoft::Console::Render::IFontDefaultList* const pFontDefaultList)
{
FontInfoBase::s_SetFontDefaultList(pFontDefaultList);
}

View file

@ -1765,8 +1765,6 @@ float DxEngine::GetScaling() const noexcept
coordSize.X = gsl::narrow<SHORT>(widthExact);
coordSize.Y = gsl::narrow<SHORT>(lineSpacing.height);
const DWORD weightDword = static_cast<DWORD>(textFormat->GetFontWeight());
// Unscaled is for the purposes of re-communicating this font back to the renderer again later.
// As such, we need to give the same original size parameter back here without padding
// or rounding or scaling manipulation.
@ -1774,9 +1772,9 @@ float DxEngine::GetScaling() const noexcept
const COORD scaled = coordSize;
actual.SetFromEngine(fontName.data(),
actual.SetFromEngine(fontName,
desired.GetFamily(),
weightDword,
textFormat->GetFontWeight(),
false,
scaled,
unscaled);

View file

@ -374,7 +374,7 @@ GdiEngine::~GdiEngine()
// Because the API is affected by the raster/TT status of the actively selected font, we can't have
// GDI choosing a TT font for us when we ask for Raster. We have to settle for forcing the current system
// Terminal font to load even if it doesn't have the glyphs necessary such that the APIs continue to work fine.
if (0 == wcscmp(FontDesired.GetFaceName(), L"Terminal"))
if (FontDesired.GetFaceName() == DEFAULT_RASTER_FONT_FACENAME)
{
lf.lfCharSet = OEM_CHARSET;
}
@ -385,7 +385,7 @@ GdiEngine::~GdiEngine()
{
// if we failed to translate from codepage to charset, choose our charset depending on what kind of font we're
// dealing with. Raster Fonts need to be presented with the OEM charset, while TT fonts need to be ANSI.
csi.ciCharset = (((FontDesired.GetFamily()) & TMPF_TRUETYPE) == TMPF_TRUETYPE) ? ANSI_CHARSET : OEM_CHARSET;
csi.ciCharset = FontDesired.IsTrueTypeFont() ? ANSI_CHARSET : OEM_CHARSET;
}
lf.lfCharSet = (BYTE)csi.ciCharset;
@ -396,7 +396,7 @@ GdiEngine::~GdiEngine()
// NOTE: not using what GDI gave us because some fonts don't quite roundtrip (e.g. MS Gothic and VL Gothic)
lf.lfPitchAndFamily = (FIXED_PITCH | FF_MODERN);
wcscpy_s(lf.lfFaceName, ARRAYSIZE(lf.lfFaceName), FontDesired.GetFaceName());
RETURN_IF_FAILED(FontDesired.FillLegacyNameBuffer(gsl::make_span(lf.lfFaceName)));
// Create font.
hFont.reset(CreateFontIndirectW(&lf));
@ -438,8 +438,14 @@ GdiEngine::~GdiEngine()
// Now fill up the FontInfo we were passed with the full details of which font we actually chose
{
// Get the actual font face that we chose
WCHAR wszFaceName[LF_FACESIZE];
RETURN_HR_IF(E_FAIL, !(GetTextFaceW(hdcTemp.get(), ARRAYSIZE(wszFaceName), wszFaceName)));
const size_t faceNameLength{ gsl::narrow<size_t>(GetTextFaceW(hdcTemp.get(), 0, nullptr)) };
std::wstring currentFaceName{};
currentFaceName.resize(faceNameLength);
RETURN_HR_IF(E_FAIL, !(GetTextFaceW(hdcTemp.get(), gsl::narrow_cast<int>(faceNameLength), currentFaceName.data())));
currentFaceName.resize(faceNameLength - 1); // remove the null terminator (wstring!)
if (FontDesired.IsDefaultRasterFont())
{
@ -450,9 +456,9 @@ GdiEngine::~GdiEngine()
coordFontRequested.X = (SHORT)s_ShrinkByDpi(coordFont.X, iDpi);
}
Font.SetFromEngine(wszFaceName,
Font.SetFromEngine(currentFaceName,
tm.tmPitchAndFamily,
tm.tmWeight,
gsl::narrow_cast<unsigned int>(tm.tmWeight),
FontDesired.IsDefaultRasterFont(),
coordFont,
coordFontRequested);

View file

@ -28,11 +28,11 @@ Author(s):
class FontInfo : public FontInfoBase
{
public:
FontInfo(_In_ PCWSTR const pwszFaceName,
const BYTE bFamily,
const LONG lWeight,
FontInfo(const std::wstring_view faceName,
const unsigned char family,
const unsigned int weight,
const COORD coordSize,
const UINT uiCodePage,
const unsigned int codePage,
const bool fSetDefaultRasterFont = false);
FontInfo(const FontInfo& fiFont);
@ -40,17 +40,15 @@ public:
COORD GetSize() const;
COORD GetUnscaledSize() const;
void SetFromEngine(_In_ PCWSTR const pwszFaceName,
const BYTE bFamily,
const LONG lWeight,
void SetFromEngine(const std::wstring_view faceName,
const unsigned char family,
const unsigned int weight,
const bool fSetDefaultRasterFont,
const COORD coordSize,
const COORD coordSizeUnscaled);
void ValidateFont();
static void s_SetFontDefaultList(_In_ Microsoft::Console::Render::IFontDefaultList* const pFontDefaultList);
friend bool operator==(const FontInfo& a, const FontInfo& b);
private:

View file

@ -20,32 +20,34 @@ Author(s):
#include "IFontDefaultList.hpp"
#define DEFAULT_TT_FONT_FACENAME L"__DefaultTTFont__"
#define DEFAULT_RASTER_FONT_FACENAME L"Terminal"
static constexpr wchar_t DEFAULT_TT_FONT_FACENAME[]{ L"__DefaultTTFont__" };
static constexpr wchar_t DEFAULT_RASTER_FONT_FACENAME[]{ L"Terminal" };
class FontInfoBase
{
public:
FontInfoBase(_In_ PCWSTR const pwszFaceName,
const BYTE bFamily,
const LONG lWeight,
FontInfoBase(const std::wstring_view faceName,
const unsigned char family,
const unsigned int weight,
const bool fSetDefaultRasterFont,
const UINT uiCodePage);
const unsigned int uiCodePage);
FontInfoBase(const FontInfoBase& fibFont);
~FontInfoBase();
BYTE GetFamily() const;
LONG GetWeight() const;
PCWCHAR GetFaceName() const;
UINT GetCodePage() const;
unsigned char GetFamily() const;
unsigned int GetWeight() const;
const std::wstring_view GetFaceName() const;
unsigned int GetCodePage() const;
HRESULT FillLegacyNameBuffer(gsl::span<wchar_t> buffer) const;
bool IsTrueTypeFont() const;
void SetFromEngine(_In_ PCWSTR const pwszFaceName,
const BYTE bFamily,
const LONG lWeight,
void SetFromEngine(const std::wstring_view faceName,
const unsigned char family,
const unsigned int weight,
const bool fSetDefaultRasterFont);
bool WasDefaultRasterSetFromEngine() const;
@ -60,10 +62,10 @@ protected:
bool IsDefaultRasterFontNoSize() const;
private:
WCHAR _wszFaceName[LF_FACESIZE];
LONG _lWeight;
BYTE _bFamily;
UINT _uiCodePage;
std::wstring _faceName;
unsigned int _weight;
unsigned char _family;
unsigned int _codePage;
bool _fDefaultRasterSetFromEngine;
};

View file

@ -24,11 +24,11 @@ Author(s):
class FontInfoDesired : public FontInfoBase
{
public:
FontInfoDesired(_In_ PCWSTR const pwszFaceName,
const BYTE bFamily,
const LONG lWeight,
FontInfoDesired(const std::wstring_view faceName,
const unsigned char family,
const unsigned int weight,
const COORD coordSizeDesired,
const UINT uiCodePage);
const unsigned int uiCodePage);
FontInfoDesired(const FontInfo& fiFont);

View file

@ -18,8 +18,7 @@ namespace Microsoft::Console::Render
class IFontDefaultList
{
public:
[[nodiscard]] virtual HRESULT RetrieveDefaultFontNameForCodepage(const UINT uiCodePage,
_Out_writes_(cchFaceName) PWSTR pwszFaceName,
const size_t cchFaceName) = 0;
[[nodiscard]] virtual HRESULT RetrieveDefaultFontNameForCodepage(const unsigned int codepage,
std::wstring& outFaceName) = 0;
};
}