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

Code before:
    try
    {
        const auto textLength = gsl::narrow<UINT32>(_text.size());

        BOOL isTextSimple = FALSE;
        UINT32 uiLengthRead = 0;

        // Start from the beginning.
        UINT32 pos = 0;

        _glyphIndices.resize(textLength);

        while (pos < textLength)
        {
            const HRESULT hr = _fontRenderData->Analyzer()->GetTextComplexity(
                _text.c_str() + pos,
                textLength,
                _fontInUse,
                &isTextSimple,
                &uiLengthRead,
                &_glyphIndices.at(pos));

            RETURN_IF_FAILED(hr);
            _SetCurrentRun(pos);
            _SplitCurrentRun(pos);
            pos += uiLengthRead;
            while (uiLengthRead > 0)
            {
                auto& run = _FetchNextRun(uiLengthRead);
                run.isTextSimple = (bool)isTextSimple;
            }
        }

        _isEntireTextSimple = isTextSimple && _runs.size() == 1;
    }
    CATCH_RETURN();
    return S_OK;
}

// Routine Description:
// - Uses the internal text information and the analyzers/font information from construction
//   to determine the complexity of the text inside this layout, compute the subsections (or runs)
//   that contain similar property information, and stores that information internally.
// - We determine line breakpoints, bidirectional information, the script properties,
//   number substitution, and font fallback properties in this function.
// Arguments:
// - <none> - Uses internal state
// Return Value:
// - S_OK or suitable DirectWrite or STL error code
[[nodiscard]] HRESULT CustomTextLayout::_AnalyzeRuns() noexcept
{

Review comment (performance):
This is going to sound super weird, but are we sure that `uiLengthRead` will always return >0 from `GetTextComplexity()`? 

I've been burned/surprised inside while loops that turn out infinite for weird things like that before.

Code after:
    {
        const auto textLength = gsl::narrow<UINT32>(_text.size());

        BOOL isTextSimple = FALSE;
        UINT32 uiLengthRead = 0;

        // Start from the beginning.
        UINT32 pos = 0;

        _glyphIndices.resize(textLength);

        while (pos < textLength)
        {
            const HRESULT hr = _fontRenderData->Analyzer()->GetTextComplexity(
                &_text.at(pos),
                textLength,
                _fontInUse,
                &isTextSimple,
                &uiLengthRead,
                &_glyphIndices.at(pos));

            RETURN_IF_FAILED(hr);
            _SetCurrentRun(pos);
            _SplitCurrentRun(pos);
            pos += std::max(uiLengthRead, 1u);
            while (uiLengthRead > 0)
            {
                auto& run = _FetchNextRun(uiLengthRead);
                run.isTextSimple = isTextSimple;
            }
        }
    }
    CATCH_RETURN();
    return S_OK;
}

// Routine Description:
// - Uses the internal text information and the analyzers/font information from construction
//   to determine the complexity of the text inside this layout, compute the subsections (or runs)
//   that contain similar property information, and stores that information internally.
// - We determine line breakpoints, bidirectional information, the script properties,
//   number substitution, and font fallback properties in this function.
// Arguments:
// - <none> - Uses internal state
// Return Value:
// - S_OK or suitable DirectWrite or STL error code
[[nodiscard]] HRESULT CustomTextLayout::_AnalyzeRuns() noexcept
{
    try
    {
        // We're going to need the text length in UINT32 format for the DWrite calls.