WindowsAppSDK icon indicating copy to clipboard operation
WindowsAppSDK copied to clipboard

DWriteCore empty vertical text layout crash

Open timeester3648 opened this issue 2 years ago • 1 comments

Describe the bug

DWriteCore crashes when the text layout is empty and the text layout layouts the text vertically.

Steps to reproduce the bug

  1. open the WindowSdkApp samples and open DWriteCoreGallery
  2. In MarkdownWindow.cpp, in the function CreateTextLayoutsFromPseudoMarkdown add this:
result.push_back(CreateTextLayout(bodyFormat.get(), L"A"));

THROW_IF_FAILED(result.back()->SetFlowDirection(DWRITE_FLOW_DIRECTION_RIGHT_TO_LEFT));
THROW_IF_FAILED(result.back()->SetReadingDirection(DWRITE_READING_DIRECTION_TOP_TO_BOTTOM));
return result;

under std::vector<DWRITE_TEXT_RANGE> codeRanges; so the function essentially becomes this:

std::vector<wil::com_ptr<IDWriteTextLayout4>> CreateTextLayoutsFromPseudoMarkdown(std::span<char const> inputText, MarkdownStyle style)
{
    std::vector<wil::com_ptr<IDWriteTextLayout4>> result;

    auto headingFormat = CreateTextFormat(style.headingFamilyName, style.headingFontSize, style.headingAxisValues);
    auto bodyFormat = CreateTextFormat(style.bodyFamilyName, style.bodyFontSize, style.bodyAxisValues);
    auto codeFormat = CreateTextFormat(style.codeFamilyName, style.codeFontSize, style.bodyAxisValues);

    THROW_IF_FAILED(codeFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP));

    auto GetTextFormat = [&](MarkdownBlockType blockType)
    {
        switch (blockType)
        {
        case MarkdownBlockType::Body:     return bodyFormat.get();
        case MarkdownBlockType::Heading:  return headingFormat.get();
        case MarkdownBlockType::Code:     return codeFormat.get();
        default: THROW_HR(E_INVALIDARG);
        }
    };

    std::wstring text;
    std::vector<DWRITE_TEXT_RANGE> boldRanges;
    std::vector<DWRITE_TEXT_RANGE> italicRanges;
    std::vector<DWRITE_TEXT_RANGE> codeRanges;

    result.push_back(CreateTextLayout(bodyFormat.get(), L"A"));

    THROW_IF_FAILED(result.back()->SetFlowDirection(DWRITE_FLOW_DIRECTION_RIGHT_TO_LEFT));
    THROW_IF_FAILED(result.back()->SetReadingDirection(DWRITE_READING_DIRECTION_TOP_TO_BOTTOM));
    return result;
}

if you run this, it works like normal, but if you change result.push_back(CreateTextLayout(bodyFormat.get(), L"A")); to result.push_back(CreateTextLayout(bodyFormat.get(), L"")); (an empty string) it crashes.

if you comment out:

THROW_IF_FAILED(result.back()->SetFlowDirection(DWRITE_FLOW_DIRECTION_RIGHT_TO_LEFT));
THROW_IF_FAILED(result.back()->SetReadingDirection(DWRITE_READING_DIRECTION_TOP_TO_BOTTOM));

Then an empty string does not crash.

In my application, this is the error message I get:

thread '<unnamed>' panicked at 'index out of bounds: the len is 0 but the index is 0', rust\layout\src\run_list.rs:325:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

I tried a multitude of functions, but all of them then reported this exact message, the first point I got this error was at text_layout->Draw but if I ignore the error, and continue, I get the same error with the functions: text_layout->GetMetrics, text_layout->GetLineMetrics and text_layout->HitTestTextPosition. I have not tested other functions.

Expected behavior

Just like when using a horizontal layout, the code does not crash/report an error.

Screenshots

No response

NuGet package version

None

Packaging type

No response

Windows version

No response

IDE

No response

Additional context

No response

timeester3648 avatar Jan 08 '24 21:01 timeester3648

internal bug

codendone avatar Feb 14 '24 19:02 codendone