Repository: microsoft/terminal
File: src/renderer/base/renderer.cpp (C++)

Code before:
    // match, and those code points will be treated the same as everything else.
    const auto softFontCharCount = cellSize.cy ? bitPattern.size() / cellSize.cy : 0;
    _lastSoftFontChar = _firstSoftFontChar + softFontCharCount - 1;

    foreachEngine(pEngine)
    {
        LOG_IF_FAILED(pEngine->UpdateSoftFont(bitPattern, cellSize, centeringHint));
    }
    TriggerRedrawAll();
}

bool Renderer::_isSoftFontChar(const std::wstring_view& v) const noexcept
{
    return v.size() == 1 && v[0] >= _firstSoftFontChar && v[0] <= _lastSoftFontChar;
}

// Routine Description:
// - Get the information on what font we would be using if we decided to create a font with the given parameters
// - This is for use with speculative calculations.
// Arguments:
// - iDpi - The DPI of the target display
// - pFontInfoDesired - A description of the font we would like to have.
// - pFontInfo - Data that will be fixed up/filled on return with the chosen font data.
// Return Value:
// - S_OK if set successfully or relevant GDI error via HRESULT.
[[nodiscard]] HRESULT Renderer::GetProposedFont(const int iDpi, const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo)
{
    // There will only every really be two engines - the real head and the VT
    //      renderer. We won't know which is which, so iterate over them.
    //      Only return the result of the successful one if it's not S_FALSE (which is the VT renderer)
    // TODO: 14560740 - The Window might be able to get at this info in a more sane manner
    foreachEngine(pEngine)
    {
        const HRESULT hr = LOG_IF_FAILED(pEngine->GetProposedFont(FontInfoDesired, FontInfo, iDpi));
        // We're looking for specifically S_OK, S_FALSE is not good enough.
        if (hr == S_OK)
        {
            return hr;
        }
    }

    return E_FAIL;
}

// Routine Description:
// - Tests against the current rendering engine to see if this particular character would be considered
// full-width (inscribed in a square, twice as wide as a standard Western character, typically used for CJK
// languages) or half-width.
// - Typically used to determine how many positions in the backing buffer a particular character should fill.
// NOTE: This only handles 1 or 2 wide (in monospace terms) characters.
// Arguments:

Review comment (suggestion):
If we make this function non-static we can access the members directly and don't need to pass them as arguments. Also `.first()` does bounds-checking.

Code after:
// - cellSize - The cell size for an individual glyph.
// - centeringHint - The horizontal extent that glyphs are offset from center.
// Return Value:
// - <none>
void Renderer::UpdateSoftFont(const gsl::span<const uint16_t> bitPattern, const SIZE cellSize, const size_t centeringHint)
{
    // We reserve PUA code points U+EF20 to U+EF7F for soft fonts, but the range
    // that we test for in _IsSoftFontChar will depend on the size of the active
    // bitPattern. If it's empty (i.e. no soft font is set), then nothing will
    // match, and those code points will be treated the same as everything else.
    const auto softFontCharCount = cellSize.cy ? bitPattern.size() / cellSize.cy : 0;
    _lastSoftFontChar = _firstSoftFontChar + softFontCharCount - 1;

    FOREACH_ENGINE(pEngine)
    {
        LOG_IF_FAILED(pEngine->UpdateSoftFont(bitPattern, cellSize, centeringHint));
    }
    TriggerRedrawAll();
}

// We initially tried to have a "_isSoftFontChar" member function, but MSVC
// failed to inline it at _all_ call sites (check invocations inside loops).
// This issue strangely doesn't occur with static functions.
bool Renderer::s_IsSoftFontChar(const std::wstring_view& v, const size_t firstSoftFontChar, const size_t lastSoftFontChar)
{
    return v.size() == 1 && v[0] >= firstSoftFontChar && v[0] <= lastSoftFontChar;
}

// Routine Description:
// - Get the information on what font we would be using if we decided to create a font with the given parameters
// - This is for use with speculative calculations.
// Arguments:
// - iDpi - The DPI of the target display
// - pFontInfoDesired - A description of the font we would like to have.
// - pFontInfo - Data that will be fixed up/filled on return with the chosen font data.
// Return Value:
// - S_OK if set successfully or relevant GDI error via HRESULT.
[[nodiscard]] HRESULT Renderer::GetProposedFont(const int iDpi, const FontInfoDesired& FontInfoDesired, _Out_ FontInfo& FontInfo)
{
    // There will only every really be two engines - the real head and the VT
    //      renderer. We won't know which is which, so iterate over them.
    //      Only return the result of the successful one if it's not S_FALSE (which is the VT renderer)
    // TODO: 14560740 - The Window might be able to get at this info in a more sane manner
    FOREACH_ENGINE(pEngine)
    {
        const HRESULT hr = LOG_IF_FAILED(pEngine->GetProposedFont(FontInfoDesired, FontInfo, iDpi));
        // We're looking for specifically S_OK, S_FALSE is not good enough.
        if (hr == S_OK)
        {
            return hr;
        }