From e5fb775142511c0035fd86d3ed4f612fa1e2ccf3 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Tue, 19 Jul 2016 00:10:36 +0300 Subject: [PATCH] dwrite: Implement SetTrimming() for layout. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/dwrite/layout.c | 46 +++++++++++++++++++++++++++++++--------- dlls/dwrite/tests/layout.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 10 deletions(-) diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index d292764f581..a9c0572940e 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -411,6 +411,30 @@ static inline HRESULT format_set_flowdirection(struct dwrite_textformat_data *fo return S_OK; } +static inline HRESULT format_set_trimming(struct dwrite_textformat_data *format, + DWRITE_TRIMMING const *trimming, IDWriteInlineObject *trimming_sign, BOOL *changed) +{ + if (changed) + *changed = FALSE; + + if ((UINT32)trimming->granularity > DWRITE_TRIMMING_GRANULARITY_WORD) + return E_INVALIDARG; + + if (changed) { + *changed = !!memcmp(&format->trimming, trimming, sizeof(*trimming)); + if (format->trimmingsign != trimming_sign) + *changed = TRUE; + } + + format->trimming = *trimming; + if (format->trimmingsign) + IDWriteInlineObject_Release(format->trimmingsign); + format->trimmingsign = trimming_sign; + if (format->trimmingsign) + IDWriteInlineObject_AddRef(format->trimmingsign); + return S_OK; +} + static inline HRESULT format_set_linespacing(struct dwrite_textformat_data *format, DWRITE_LINE_SPACING_METHOD method, FLOAT spacing, FLOAT baseline, BOOL *changed) { @@ -3855,8 +3879,17 @@ static HRESULT WINAPI dwritetextformat_layout_SetTrimming(IDWriteTextFormat1 *if IDWriteInlineObject *trimming_sign) { struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat1(iface); - FIXME("(%p)->(%p %p): stub\n", This, trimming, trimming_sign); - return E_NOTIMPL; + BOOL changed; + HRESULT hr; + + TRACE("(%p)->(%p %p)\n", This, trimming, trimming_sign); + + hr = format_set_trimming(&This->format, trimming, trimming_sign, &changed); + + if (changed) + This->recompute |= RECOMPUTE_LINES; + + return hr; } static HRESULT WINAPI dwritetextformat_layout_SetLineSpacing(IDWriteTextFormat1 *iface, DWRITE_LINE_SPACING_METHOD method, @@ -4839,14 +4872,7 @@ static HRESULT WINAPI dwritetextformat_SetTrimming(IDWriteTextFormat2 *iface, DW { struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface); TRACE("(%p)->(%p %p)\n", This, trimming, trimming_sign); - - This->format.trimming = *trimming; - if (This->format.trimmingsign) - IDWriteInlineObject_Release(This->format.trimmingsign); - This->format.trimmingsign = trimming_sign; - if (This->format.trimmingsign) - IDWriteInlineObject_AddRef(This->format.trimmingsign); - return S_OK; + return format_set_trimming(&This->format, trimming, trimming_sign, NULL); } static HRESULT WINAPI dwritetextformat_SetLineSpacing(IDWriteTextFormat2 *iface, DWRITE_LINE_SPACING_METHOD method, diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index 689b3b4b85f..9f3b8c31a79 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -1069,6 +1069,13 @@ if (0) /* crashes on native */ hr = IDWriteTextFormat_SetTrimming(format, &trimming, NULL); ok(hr == S_OK, "got 0x%08x\n", hr); + /* invalid granularity */ + trimming.granularity = 10; + trimming.delimiter = 0; + trimming.delimiterCount = 0; + hr = IDWriteTextFormat_SetTrimming(format, &trimming, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + IDWriteTextFormat_Release(format); IDWriteFactory_Release(factory); } @@ -1771,13 +1778,17 @@ static void test_GetClusterMetrics(void) static const WCHAR str4W[] = {'a',' ',0}; DWRITE_INLINE_OBJECT_METRICS inline_metrics; DWRITE_CLUSTER_METRICS metrics[22]; + DWRITE_TEXT_METRICS text_metrics; + DWRITE_TRIMMING trimming_options; IDWriteTextLayout1 *layout1; IDWriteInlineObject *trimm; IDWriteTextFormat *format; IDWriteTextLayout *layout; + DWRITE_LINE_METRICS line; DWRITE_TEXT_RANGE range; IDWriteFactory *factory; UINT32 count, i; + FLOAT width; HRESULT hr; factory = create_factory(); @@ -2121,6 +2132,47 @@ todo_wine IDWriteTextLayout_Release(layout); + /* trigger line trimming */ + hr = IDWriteFactory_CreateTextLayout(factory, strW, lstrlenW(strW), format, 100.0f, 200.0f, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + + count = 0; + memset(metrics, 0, sizeof(metrics)); + hr = IDWriteTextLayout_GetClusterMetrics(layout, metrics, 4, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 4, "got %u\n", count); + + hr = IDWriteTextLayout_GetMetrics(layout, &text_metrics); + ok(hr == S_OK, "got 0x%08x\n", hr); + + width = metrics[0].width + inline_metrics.width; + ok(width < text_metrics.width, "unexpected trimming sign width\n"); + + /* enable trimming, reduce layout width so only first cluster and trimming sign fits */ + trimming_options.granularity = DWRITE_TRIMMING_GRANULARITY_CHARACTER; + trimming_options.delimiter = 0; + trimming_options.delimiterCount = 0; + hr = IDWriteTextLayout_SetTrimming(layout, &trimming_options, trimm); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteTextLayout_SetMaxWidth(layout, width); + ok(hr == S_OK, "got 0x%08x\n", hr); + + count = 0; + memset(metrics, 0, sizeof(metrics)); + hr = IDWriteTextLayout_GetClusterMetrics(layout, metrics, 4, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 4, "got %u\n", count); + + hr = IDWriteTextLayout_GetLineMetrics(layout, &line, 1, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 1, "got %u\n", count); +todo_wine + ok(line.length == 4, "got %u\n", line.length); + ok(line.isTrimmed, "got %d\n", line.isTrimmed); + + IDWriteTextLayout_Release(layout); + IDWriteInlineObject_Release(trimm); IDWriteTextFormat_Release(format); IDWriteFactory_Release(factory); -- 2.11.4.GIT