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:
(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.