95cc7d9625
FontInfoBase and it's descendents are missing noexcept annotations, which virally forces other code to not be noexcept as well during AuditMode checks. Apart from adding noexcept, this commit also * Passes std::wstring_view by reference. * Pass the FillLegacyNameBuffer argument as a simple pointer-to-array, allowing us to fill the buffer with a single memcpy. (gsl::span's iterators inhibit any internal STL optimizations.) * Move operator== declarations inside the class to reduce code size. All other changes are an effect of the virality of noexcept. This is an offshoot from #11623. ## Validation Steps Performed * It still compiles ✔️
126 lines
4.5 KiB
C++
126 lines
4.5 KiB
C++
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT license.
|
|
|
|
#include "precomp.h"
|
|
|
|
#include <cwchar>
|
|
|
|
#include "../inc/FontInfoBase.hpp"
|
|
|
|
FontInfoBase::FontInfoBase(const std::wstring_view& faceName,
|
|
const unsigned char family,
|
|
const unsigned int weight,
|
|
const bool fSetDefaultRasterFont,
|
|
const unsigned int codePage) noexcept :
|
|
_faceName(faceName),
|
|
_family(family),
|
|
_weight(weight),
|
|
_fDefaultRasterSetFromEngine(fSetDefaultRasterFont),
|
|
_codePage(codePage)
|
|
{
|
|
ValidateFont();
|
|
}
|
|
|
|
bool FontInfoBase::operator==(const FontInfoBase& other) noexcept
|
|
{
|
|
return _faceName == other._faceName &&
|
|
_weight == other._weight &&
|
|
_family == other._family &&
|
|
_codePage == other._codePage &&
|
|
_fDefaultRasterSetFromEngine == other._fDefaultRasterSetFromEngine;
|
|
}
|
|
|
|
unsigned char FontInfoBase::GetFamily() const noexcept
|
|
{
|
|
return _family;
|
|
}
|
|
|
|
// When the default raster font is forced set from the engine, this is how we differentiate it from a simple apply.
|
|
// Default raster font is internally represented as a blank face name and zeros for weight, family, and size. This is
|
|
// the hint for the engine to use whatever comes back from GetStockObject(OEM_FIXED_FONT) (at least in the GDI world).
|
|
bool FontInfoBase::WasDefaultRasterSetFromEngine() const noexcept
|
|
{
|
|
return _fDefaultRasterSetFromEngine;
|
|
}
|
|
|
|
unsigned int FontInfoBase::GetWeight() const noexcept
|
|
{
|
|
return _weight;
|
|
}
|
|
|
|
const std::wstring& FontInfoBase::GetFaceName() const noexcept
|
|
{
|
|
return _faceName;
|
|
}
|
|
|
|
unsigned int FontInfoBase::GetCodePage() const noexcept
|
|
{
|
|
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
|
|
void FontInfoBase::FillLegacyNameBuffer(wchar_t (&buffer)[LF_FACESIZE]) const noexcept
|
|
{
|
|
const auto toCopy = std::min(std::size(buffer) - 1, _faceName.size());
|
|
const auto last = std::copy_n(_faceName.data(), toCopy, &buffer[0]);
|
|
*last = L'\0';
|
|
}
|
|
|
|
// NOTE: this method is intended to only be used from the engine itself to respond what font it has chosen.
|
|
void FontInfoBase::SetFromEngine(const std::wstring_view& faceName,
|
|
const unsigned char family,
|
|
const unsigned int weight,
|
|
const bool fSetDefaultRasterFont) noexcept
|
|
{
|
|
_faceName = faceName;
|
|
_family = family;
|
|
_weight = weight;
|
|
_fDefaultRasterSetFromEngine = fSetDefaultRasterFont;
|
|
}
|
|
|
|
// Internally, default raster font is represented by empty facename, and zeros for weight, family, and size. Since
|
|
// FontInfoBase doesn't have sizing information, this helper checks everything else.
|
|
bool FontInfoBase::IsDefaultRasterFontNoSize() const noexcept
|
|
{
|
|
return (_weight == 0 && _family == 0 && _faceName.empty());
|
|
}
|
|
|
|
void FontInfoBase::ValidateFont() noexcept
|
|
{
|
|
// If we were given a blank name, it meant raster fonts, which to us is always Terminal.
|
|
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 (_faceName == DEFAULT_TT_FONT_FACENAME)
|
|
{
|
|
std::wstring defaultFontFace;
|
|
if (SUCCEEDED(s_pFontDefaultList->RetrieveDefaultFontNameForCodepage(GetCodePage(),
|
|
defaultFontFace)))
|
|
{
|
|
_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.
|
|
_family = TMPF_TRUETYPE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool FontInfoBase::IsTrueTypeFont() const noexcept
|
|
{
|
|
return WI_IsFlagSet(_family, TMPF_TRUETYPE);
|
|
}
|
|
|
|
Microsoft::Console::Render::IFontDefaultList* FontInfoBase::s_pFontDefaultList;
|
|
|
|
void FontInfoBase::s_SetFontDefaultList(_In_ Microsoft::Console::Render::IFontDefaultList* const pFontDefaultList) noexcept
|
|
{
|
|
s_pFontDefaultList = pFontDefaultList;
|
|
}
|