I use IDWriteTextAnalysisSink / AnalyzeScript to display mixed LTR (English) and RTL (Hebrew) text in DirectWrite (C++), and I compute text width from:

textwidth = 0;
for (UINT glyph=0; glyph<actualGlyphCount; glyph++) 
  textwidth += glyphAdvances[glyph];

with glyphAdvances returned from GetGlyphPlacements.

However for Right To Left text, this is often inaccurate, leading to overlapping text, etc. Is this the right method?

Thanks.

有帮助吗?

解决方案

You may not need to do quite so much work with IDWriteTextAnalysisSink / AnalyzeScript.

    HRESULT hr = S_OK;
    ComPtr<IDWriteTextFormat> textFormat;
    ComPtr<IDWriteTextLayout> textLayout;

    // Error checking omitted for brevity
    hr = textFactory->CreateTextFormat(L"Arial", nullptr, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 30.0f, L"", textFormat.GetAddressOf());
    hr = textFormat->SetReadingDirection(DWRITE_READING_DIRECTION_RIGHT_TO_LEFT);
    hr = textFactory->CreateTextLayout(L"[HEBREW TEXT HERE]", textsize, textFormat.Get(), 0.0f, 0.0f, textLayout.GetAddressOf());

Render Code:

    renderTarget->Clear(BG_COLOR);
    auto size = renderTarget->GetSize();

    auto margin = 50.0f;
    size.width -= margin * 2.0f;
    size.height -= margin * 2.0f;

    if (S_OK == textLayout->SetMaxWidth(size.width) &&
        S_OK == textLayout->SetMaxHeight(size.height))
    {
        renderTarget->DrawTextLayout(Point2F(margin, margin), textLayout.Get(), brush.Get(), D2D1_DRAW_TEXT_OPTIONS_NONE);
    }

Screenshot from reading hebrew file: enter image description here

(Note: My solution is based on a sample from Kenny Kerr) I realize you are mixing LTR and RTL, however I am not sure that warrants the added complexity of IDWriteTextAnalysisSink / AnalyzeScript.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top