Compare commits

...

2 Commits

Author SHA1 Message Date
Dustin L. Howett
49691f891a CHECKPOINT: Start working on TrueTypeFontList and all its fallout 2019-10-08 14:52:14 -07:00
Dustin L. Howett
26d3fcb1d2 Allow FontInfo{,Base,Desired} to store a font name > 32 wch
We now truncate the font name as it goes out to GDI APIs, in console API
servicing, and in the propsheet.

Fixes #602.
2019-10-07 12:58:25 -07:00
25 changed files with 235 additions and 367 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

@@ -148,7 +148,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,8 @@ 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()));
// NOTE: THIS TRUNCATES THE FONT NAME
RETURN_IF_FAILED(StringCchCopyW(consoleFontInfoEx.FaceName, ARRAYSIZE(consoleFontInfoEx.FaceName), fontInfo.GetFaceName().data()));
return S_OK;
}

View File

@@ -9,7 +9,7 @@
RenderFontDefaults::RenderFontDefaults()
{
LOG_IF_NTSTATUS_FAILED(TrueTypeFontList::s_Initialize());
LOG_IF_FAILED(TrueTypeFontList::s_Initialize());
}
RenderFontDefaults::~RenderFontDefaults()
@@ -17,10 +17,8 @@ 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)
{
NTSTATUS status = TrueTypeFontList::s_SearchByCodePage(uiCodePage, pwszFaceName, cchFaceName);
return HRESULT_FROM_NT(status);
return TrueTypeFontList::s_SearchByCodePage(codePage, outFaceName);
}

View File

@@ -22,7 +22,5 @@ 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

@@ -630,9 +630,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

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

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

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());
StringCchCopyW(pStateInfo->FaceName, ARRAYSIZE(pStateInfo->FaceName), currentFont.GetFaceName().data());
const Cursor& cursor = ScreenInfo.GetTextBuffer().GetCursor();
pStateInfo->CursorSize = cursor.GetSize();
@@ -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

@@ -74,25 +74,13 @@ BYTE CodePageToCharSet(
BOOL ShouldAllowAllMonoTTFonts();
LPTTFONTLIST
SearchTTFont(
__in_opt LPCTSTR ptszFace,
BOOL fCodePage,
UINT CodePage);
bool IsAvailableTTFont(const std::wstring_view name);
BOOL IsAvailableTTFont(
LPCTSTR ptszFace);
bool IsAvailableTTFontCP(const std::wstring_view name, unsigned int codePage);
BOOL IsAvailableTTFontCP(
LPCTSTR ptszFace,
UINT CodePage);
bool IsDisableBoldTTFont(const std::wstring_view name);
BOOL IsDisableBoldTTFont(
LPCTSTR ptszFace);
LPTSTR
GetAltFaceName(
LPCTSTR ptszFace);
std::optional<std::wstring> GetAltFaceName(const std::wstring_view name);
[[nodiscard]] NTSTATUS DestroyDbcsMisc(VOID);

View File

@@ -82,79 +82,38 @@ BYTE CodePageToCharSet(
return (BYTE)csi.ciCharset;
}
LPTTFONTLIST
SearchTTFont(
__in_opt LPCTSTR ptszFace,
BOOL fCodePage,
UINT CodePage)
bool IsAvailableTTFont(const std::wstring_view name)
{
return TrueTypeFontList::s_SearchByName(ptszFace, fCodePage, CodePage);
return nullptr != TrueTypeFontList::s_SearchByName(name, std::nullopt);
}
BOOL IsAvailableTTFont(
LPCTSTR ptszFace)
bool IsAvailableTTFontCP(const std::wstring_view name, unsigned int codePage)
{
if (SearchTTFont(ptszFace, FALSE, 0))
{
return TRUE;
}
else
{
return FALSE;
}
return nullptr != TrueTypeFontList::s_SearchByName(name, codePage);
}
BOOL IsAvailableTTFontCP(
LPCTSTR ptszFace,
UINT CodePage)
bool IsDisableBoldTTFont(const std::wstring_view name)
{
if (SearchTTFont(ptszFace, TRUE, CodePage))
{
return TRUE;
}
else
{
return FALSE;
}
auto entry = TrueTypeFontList::s_SearchByName(name, std::nullopt);
return entry && entry->DisableBold;
}
BOOL IsDisableBoldTTFont(
LPCTSTR ptszFace)
std::optional<std::wstring> GetAltFaceName(const std::wstring_view name)
{
LPTTFONTLIST pTTFontList;
pTTFontList = SearchTTFont(ptszFace, FALSE, 0);
if (pTTFontList != NULL)
auto entry = TrueTypeFontList::s_SearchByName(name, std::nullopt);
if (entry)
{
return pTTFontList->fDisableBold;
}
else
{
return FALSE;
}
}
LPTSTR
GetAltFaceName(
LPCTSTR ptszFace)
{
LPTTFONTLIST pTTFontList;
pTTFontList = SearchTTFont(ptszFace, FALSE, 0);
if (pTTFontList != NULL)
{
if (wcscmp(ptszFace, pTTFontList->FaceName1) == 0)
if (entry->FontNames.first == name)
{
return pTTFontList->FaceName2;
return entry->FontNames.second;
}
if (wcscmp(ptszFace, pTTFontList->FaceName2) == 0)
else if (entry->FontNames.second == name)
{
return pTTFontList->FaceName1;
return entry->FontNames.first;
}
}
return NULL;
return std::nullopt;
}
[[nodiscard]] NTSTATUS
@@ -243,9 +202,7 @@ int LanguageDisplay(HWND hDlg, UINT CodePage)
}
// For a given codepage, determine what the default truetype font should be
[[nodiscard]] NTSTATUS GetTTFontFaceForCodePage(const UINT uiCodePage, // the codepage to examine (note: not charset)
_Out_writes_(cchFaceName) PWSTR pszFaceName, // where to write the facename we find
const size_t cchFaceName) // space available in pszFaceName
[[nodiscard]] HRESULT GetTTFontFaceForCodePage(const unsigned int codePage, std::wstring& outFaceName)
{
return TrueTypeFontList::s_SearchByCodePage(uiCodePage, pszFaceName, cchFaceName);
return TrueTypeFontList::s_SearchByCodePage(codePage, outFaceName);
}

View File

@@ -105,9 +105,7 @@ BOOL DoFontEnum(
__in_ecount_opt(nTTPoints) PSHORT pTTPoints,
__in UINT nTTPoints);
[[nodiscard]] NTSTATUS GetTTFontFaceForCodePage(const UINT uiCodePage,
_Out_writes_(cchFaceName) PWSTR pszFaceName,
const size_t cchFaceName);
[[nodiscard]] NTSTATUS GetTTFontFaceForCodePage(const unsigned int codePage, std::wstring& outFaceName);
bool IsFontSizeCustom(__in PCWSTR pwszFaceName, __in const SHORT sSize);
void CreateSizeForAllTTFonts(__in const SHORT sSize);

View File

@@ -11,187 +11,125 @@
#define DEFAULT_NON_DBCS_FONTFACE L"Consolas"
SINGLE_LIST_ENTRY TrueTypeFontList::s_ttFontList;
std::vector<TrueTypeFontList::Entry> TrueTypeFontList::s_ttFontList;
WORD ConvertStringToDec(
__in LPTSTR lpch)
[[nodiscard]] HRESULT TrueTypeFontList::s_Initialize()
try
{
TCHAR ch;
WORD val = 0;
while ((ch = *lpch) != TEXT('\0'))
{
if (TEXT('0') <= ch && ch <= TEXT('9'))
val = (val * 10) + (ch - TEXT('0'));
else
break;
lpch++;
}
return val;
}
[[nodiscard]] NTSTATUS TrueTypeFontList::s_Initialize()
{
HKEY hkRegistry;
WCHAR awchValue[512];
WCHAR awchData[512];
DWORD dwIndex;
LPWSTR pwsz;
wil::unique_hkey hkRegistry;
// Prevent memory leak. Delete if it's already allocated before refilling it.
LOG_IF_FAILED(s_Destroy());
NTSTATUS Status = RegistrySerialization::s_OpenKey(HKEY_LOCAL_MACHINE,
MACHINE_REGISTRY_CONSOLE_TTFONT_WIN32_PATH,
&hkRegistry);
if (NT_SUCCESS(Status))
RETURN_IF_NTSTATUS_FAILED(RegistrySerialization::s_OpenKey(HKEY_LOCAL_MACHINE,
MACHINE_REGISTRY_CONSOLE_TTFONT_WIN32_PATH,
&hkRegistry));
for (DWORD dwIndex = 0;; dwIndex++)
{
LPTTFONTLIST pTTFontList;
wchar_t awchValue[512];
wchar_t awchData[512];
NTSTATUS Status = RegistrySerialization::s_EnumValue(hkRegistry.get(),
dwIndex,
sizeof(awchValue),
(LPWSTR)awchValue,
sizeof(awchData),
(PBYTE)awchData);
for (dwIndex = 0;; dwIndex++)
if (Status == ERROR_NO_MORE_ITEMS)
{
Status = RegistrySerialization::s_EnumValue(hkRegistry,
dwIndex,
sizeof(awchValue),
(LPWSTR)awchValue,
sizeof(awchData),
(PBYTE)awchData);
// This is fine.
break;
}
if (Status == ERROR_NO_MORE_ITEMS)
RETURN_IF_NTSTATUS_FAILED(Status);
const wchar_t* pwsz{ awchData };
Entry fontEntry;
fontEntry.CodePage = std::stoi(awchValue);
if (*pwsz == BOLD_MARK)
{
fontEntry.DisableBold = TRUE;
pwsz++;
}
else
{
fontEntry.DisableBold = FALSE;
}
fontEntry.FontNames.first = pwsz;
// wcslen is only valid on non-null pointers.
if (pwsz != nullptr)
{
pwsz += wcslen(pwsz) + 1;
// Validate that pwsz must be pointing to a position in awchData array after the movement.
if (pwsz >= awchData && pwsz < (awchData + ARRAYSIZE(awchData)))
{
Status = STATUS_SUCCESS;
break;
}
if (!NT_SUCCESS(Status))
{
break;
}
pTTFontList = (TTFONTLIST*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TTFONTLIST));
if (pTTFontList == nullptr)
{
break;
}
pTTFontList->List.Next = nullptr;
pTTFontList->CodePage = ConvertStringToDec(awchValue);
pwsz = awchData;
if (*pwsz == BOLD_MARK)
{
pTTFontList->fDisableBold = TRUE;
pwsz++;
}
else
{
pTTFontList->fDisableBold = FALSE;
}
StringCchCopyW(pTTFontList->FaceName1,
ARRAYSIZE(pTTFontList->FaceName1),
pwsz);
// wcslen is only valid on non-null pointers.
if (pwsz != nullptr)
{
pwsz += wcslen(pwsz) + 1;
// Validate that pwsz must be pointing to a position in awchData array after the movement.
if (pwsz >= awchData && pwsz < (awchData + ARRAYSIZE(awchData)))
if (*pwsz == BOLD_MARK)
{
if (*pwsz == BOLD_MARK)
{
pTTFontList->fDisableBold = TRUE;
pwsz++;
}
StringCchCopyW(pTTFontList->FaceName2,
ARRAYSIZE(pTTFontList->FaceName2),
pwsz);
fontEntry.DisableBold = TRUE;
pwsz++;
}
fontEntry.FontNames.second = pwsz;
}
PushEntryList(&s_ttFontList, &(pTTFontList->List));
}
RegCloseKey(hkRegistry);
s_ttFontList.emplace_back(std::move(fontEntry));
}
return STATUS_SUCCESS;
return S_OK;
}
CATCH_RETURN();
[[nodiscard]] NTSTATUS TrueTypeFontList::s_Destroy()
[[nodiscard]] HRESULT TrueTypeFontList::s_Destroy()
try
{
while (s_ttFontList.Next != nullptr)
{
LPTTFONTLIST pTTFontList = (LPTTFONTLIST)PopEntryList(&s_ttFontList);
if (pTTFontList != nullptr)
{
HeapFree(GetProcessHeap(), 0, pTTFontList);
}
}
s_ttFontList.Next = nullptr;
return STATUS_SUCCESS;
s_ttFontList.clear();
return S_OK;
}
CATCH_RETURN();
LPTTFONTLIST TrueTypeFontList::s_SearchByName(_In_opt_ LPCWSTR pwszFace,
_In_ BOOL fCodePage,
_In_ UINT CodePage)
const TrueTypeFontList::Entry* TrueTypeFontList::s_SearchByName(const std::wstring_view name,
const std::optional<unsigned int> CodePage)
{
PSINGLE_LIST_ENTRY pTemp = s_ttFontList.Next;
if (pwszFace)
if (!name.empty())
{
while (pTemp != nullptr)
for (const auto& entry : s_ttFontList)
{
LPTTFONTLIST pTTFontList = (LPTTFONTLIST)pTemp;
if (wcscmp(pwszFace, pTTFontList->FaceName1) == 0 ||
wcscmp(pwszFace, pTTFontList->FaceName2) == 0)
if (name != entry.FontNames.first &&
name != entry.FontNames.second)
{
if (fCodePage)
if (pTTFontList->CodePage == CodePage)
return pTTFontList;
else
return nullptr;
else
return pTTFontList;
continue;
}
pTemp = pTemp->Next;
if (CodePage.has_value() && entry.CodePage != CodePage.value())
{
continue;
}
return &entry;
}
}
return nullptr;
}
[[nodiscard]] NTSTATUS TrueTypeFontList::s_SearchByCodePage(const UINT uiCodePage,
_Out_writes_(cchFaceName) PWSTR pwszFaceName,
const size_t cchFaceName)
[[nodiscard]] HRESULT TrueTypeFontList::s_SearchByCodePage(const unsigned int codePage,
std::wstring& outFaceName)
{
NTSTATUS status = STATUS_SUCCESS;
BOOL fFontFound = FALSE;
// Look through our list entries to see if we can find a corresponding truetype font for this codepage
for (PSINGLE_LIST_ENTRY pListEntry = s_ttFontList.Next; pListEntry != nullptr && !fFontFound; pListEntry = pListEntry->Next)
for (const auto& entry : s_ttFontList)
{
LPTTFONTLIST pTTFontEntry = (LPTTFONTLIST)pListEntry;
if (pTTFontEntry->CodePage == uiCodePage)
if (entry.CodePage == codePage)
{
// found a match, use this font's primary facename
status = StringCchCopyW(pwszFaceName, cchFaceName, pTTFontEntry->FaceName1);
fFontFound = TRUE;
outFaceName = entry.FontNames.first;
return S_OK;
}
}
if (!fFontFound)
{
status = StringCchCopyW(pwszFaceName, cchFaceName, DEFAULT_NON_DBCS_FONTFACE);
}
return status;
// Fallthrough: we didn't find a font; presume it's non-DBCS.
outFaceName = DEFAULT_NON_DBCS_FONTFACE;
return S_OK;
}

View File

@@ -18,16 +18,21 @@ Author(s):
class TrueTypeFontList
{
public:
static SINGLE_LIST_ENTRY s_ttFontList;
struct Entry
{
unsigned int CodePage;
bool DisableBold;
std::pair<std::wstring, std::wstring> FontNames;
};
[[nodiscard]] static NTSTATUS s_Initialize();
[[nodiscard]] static NTSTATUS s_Destroy();
static std::vector<Entry> s_ttFontList;
static LPTTFONTLIST s_SearchByName(_In_opt_ LPCWSTR pwszFace,
_In_ BOOL fCodePage,
_In_ UINT CodePage);
[[nodiscard]] static HRESULT s_Initialize();
[[nodiscard]] static HRESULT s_Destroy();
[[nodiscard]] static NTSTATUS s_SearchByCodePage(const UINT uiCodePage,
_Out_writes_(cchFaceName) PWSTR pwszFaceName,
const size_t cchFaceName);
static const Entry* s_SearchByName(const std::wstring_view name,
const std::optional<unsigned int> CodePage);
[[nodiscard]] static HRESULT s_SearchByCodePage(const unsigned int codePage,
std::wstring& outFaceName);
};

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 BYTE 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();
}
@@ -49,7 +45,7 @@ FontInfoBase::~FontInfoBase()
BYTE 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,30 @@ bool FontInfoBase::WasDefaultRasterSetFromEngine() const
return _fDefaultRasterSetFromEngine;
}
LONG FontInfoBase::GetWeight() const
unsigned int FontInfoBase::GetWeight() const
{
return _lWeight;
return _weight;
}
PCWCHAR FontInfoBase::GetFaceName() const
std::wstring FontInfoBase::GetFaceName() const
{
return (PCWCHAR)_wszFaceName;
return _faceName;
}
UINT FontInfoBase::GetCodePage() const
unsigned int FontInfoBase::GetCodePage() const
{
return _uiCodePage;
return _codePage;
}
// 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 BYTE 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 +87,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 +96,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 +114,14 @@ void FontInfoBase::ValidateFont()
bool FontInfoBase::IsTrueTypeFont() const
{
return (_bFamily & TMPF_TRUETYPE) != 0;
return WI_IsFlagSet(_family, TMPF_TRUETYPE);
}
#pragma warning(push)
#pragma warning(suppress : 4356)
Microsoft::Console::Render::IFontDefaultList* FontInfoBase::s_pFontDefaultList;
#pragma warning(pop)
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 BYTE 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 BYTE 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 BYTE 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

@@ -1760,8 +1760,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.
@@ -1769,9 +1767,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() == L"Terminal")
{
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,8 @@ 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());
// NOTE: GDI cannot support font faces > 32 characters in length. THIS TRUNCATES THE FONT.
wcscpy_s(lf.lfFaceName, ARRAYSIZE(lf.lfFaceName), FontDesired.GetFaceName().data());
// Create font.
hFont.reset(CreateFontIndirectW(&lf));
@@ -438,8 +439,12 @@ 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 auto faceNameLength{ GetTextFaceW(hdcTemp.get(), 0, nullptr) };
wistd::unique_ptr<wchar_t[]> currentFaceName{ wil::make_unique_nothrow<wchar_t[]>(faceNameLength) };
RETURN_IF_NULL_ALLOC(currentFaceName);
RETURN_HR_IF(E_FAIL, !(GetTextFaceW(hdcTemp.get(), faceNameLength, currentFaceName.get())));
if (FontDesired.IsDefaultRasterFont())
{
@@ -450,9 +455,9 @@ GdiEngine::~GdiEngine()
coordFontRequested.X = (SHORT)s_ShrinkByDpi(coordFont.X, iDpi);
}
Font.SetFromEngine(wszFaceName,
Font.SetFromEngine(currentFaceName.get(),
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 BYTE 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 BYTE 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,32 @@ 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 BYTE 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 int GetWeight() const;
std::wstring GetFaceName() const;
unsigned int GetCodePage() const;
bool IsTrueTypeFont() const;
void SetFromEngine(_In_ PCWSTR const pwszFaceName,
const BYTE bFamily,
const LONG lWeight,
void SetFromEngine(const std::wstring_view faceName,
const BYTE family,
const unsigned int weight,
const bool fSetDefaultRasterFont);
bool WasDefaultRasterSetFromEngine() const;
@@ -60,10 +60,10 @@ protected:
bool IsDefaultRasterFontNoSize() const;
private:
WCHAR _wszFaceName[LF_FACESIZE];
LONG _lWeight;
BYTE _bFamily;
UINT _uiCodePage;
std::wstring _faceName;
unsigned int _weight;
BYTE _family; // BYTE for compatibility with GDI
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 BYTE 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 uiCodePage,
_Out_ std::wstring& outFaceName) = 0;
};
}