diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index 752bd50b6e1..a7185380e6d 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -248,6 +248,8 @@ struct dwrite_textlayout { UINT32 line_count; UINT32 line_alloc; + DWRITE_TEXT_METRICS1 metrics; + /* gdi-compatible layout specifics */ BOOL gdicompatible; FLOAT pixels_per_dip; @@ -1125,7 +1127,7 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout) i == layout->cluster_count - 1) /* end of the text */ { UINT32 strlength, last_cluster = i, index; - FLOAT descent; + FLOAT descent, trailingspacewidth; if (!overflow) { metrics.length += layout->clustermetrics[i].length; @@ -1145,6 +1147,7 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout) trailing properties for current line */ strlength = metrics.length; index = last_cluster; + trailingspacewidth = 0.0; while (strlength) { DWRITE_CLUSTER_METRICS *cluster = &layout->clustermetrics[index]; @@ -1156,8 +1159,10 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout) metrics.newlineLength += cluster->length; } - if (cluster->isWhitespace) + if (cluster->isWhitespace) { metrics.trailingWhitespaceLength += cluster->length; + trailingspacewidth += cluster->width; + } strlength -= cluster->length; index--; @@ -1184,6 +1189,11 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout) } metrics.height = descent + metrics.baseline; + if (width > layout->metrics.widthIncludingTrailingWhitespace) + layout->metrics.widthIncludingTrailingWhitespace = width; + if (width - trailingspacewidth > layout->metrics.width) + layout->metrics.width = width - trailingspacewidth; + metrics.isTrimmed = width > layout->maxwidth; hr = layout_set_line_metrics(layout, &metrics, &line); if (FAILED(hr)) @@ -1203,6 +1213,12 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout) textpos += layout->clustermetrics[i].length; } + layout->metrics.left = layout->metrics.top = 0.0; + layout->metrics.layoutWidth = layout->maxwidth; + layout->metrics.layoutHeight = layout->maxheight; + layout->metrics.maxBidiReorderingDepth = 1; /* FIXME */ + layout->metrics.lineCount = layout->line_count; + /* Now all line info is here, update effective runs positions in flow direction */ erun = layout_get_next_erun(layout, NULL); inrun = layout_get_next_inline_run(layout, NULL); @@ -1227,8 +1243,12 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout) if (!inrun) break; } + + layout->metrics.height += layout->lines[line].height; } + layout->metrics.heightIncludingTrailingWhitespace = layout->metrics.height; /* FIXME: not true for vertical text */ + layout->recompute &= ~RECOMPUTE_EFFECTIVE_RUNS; return hr; } @@ -2775,8 +2795,16 @@ static HRESULT WINAPI dwritetextlayout1_GetCharacterSpacing(IDWriteTextLayout2 * static HRESULT WINAPI dwritetextlayout2_GetMetrics(IDWriteTextLayout2 *iface, DWRITE_TEXT_METRICS1 *metrics) { struct dwrite_textlayout *This = impl_from_IDWriteTextLayout2(iface); - FIXME("(%p)->(%p): stub\n", This, metrics); - return E_NOTIMPL; + HRESULT hr; + + TRACE("(%p)->(%p)\n", This, metrics); + + hr = layout_compute_effective_runs(This); + if (FAILED(hr)) + return hr; + + *metrics = This->metrics; + return S_OK; } static HRESULT WINAPI dwritetextlayout2_SetVerticalGlyphOrientation(IDWriteTextLayout2 *iface, DWRITE_VERTICAL_GLYPH_ORIENTATION orientation) @@ -3542,6 +3570,7 @@ static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat * list_init(&layout->effects); list_init(&layout->spacing); memset(&layout->format, 0, sizeof(layout->format)); + memset(&layout->metrics, 0, sizeof(layout->metrics)); layout->gdicompatible = FALSE; layout->pixels_per_dip = 0.0; diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index 43233f42201..84e1a2b8211 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -2485,7 +2485,6 @@ static void test_GetMetrics(void) memset(&metrics, 0xcc, sizeof(metrics)); hr = IDWriteTextLayout_GetMetrics(layout, &metrics); -todo_wine { ok(hr == S_OK, "got 0x%08x\n", hr); ok(metrics.left == 0.0, "got %.2f\n", metrics.left); ok(metrics.top == 0.0, "got %.2f\n", metrics.top); @@ -2496,7 +2495,7 @@ todo_wine { ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); -} + IDWriteTextLayout_Release(layout); /* a string with more complex bidi sequence */ @@ -2506,7 +2505,6 @@ todo_wine { memset(&metrics, 0xcc, sizeof(metrics)); metrics.maxBidiReorderingDepth = 0; hr = IDWriteTextLayout_GetMetrics(layout, &metrics); -todo_wine { ok(hr == S_OK, "got 0x%08x\n", hr); ok(metrics.left == 0.0, "got %.2f\n", metrics.left); ok(metrics.top == 0.0, "got %.2f\n", metrics.top); @@ -2515,9 +2513,10 @@ todo_wine { ok(metrics.height > 0.0, "got %.2f\n", metrics.height); ok(metrics.layoutWidth == 500.0, "got %.2f\n", metrics.layoutWidth); ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); +todo_wine ok(metrics.maxBidiReorderingDepth > 1, "got %u\n", metrics.maxBidiReorderingDepth); ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); -} + IDWriteTextLayout_Release(layout); IDWriteTextFormat_Release(format);