From: Lucian Poston lucianposton@pm.me
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/tests/layout.c | 188 ++++++++++++++++++++++--------------- 1 file changed, 111 insertions(+), 77 deletions(-)
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index c77a0ea51b..e6ed3c13c4 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -2677,83 +2677,6 @@ static void test_SetVerticalGlyphOrientation(void) IDWriteFactory_Release(factory); }
-static void test_fallback(void) -{ - static const WCHAR strW[] = {'a','b','c','d',0}; - IDWriteFontFallback *fallback, *fallback2; - IDWriteTextLayout2 *layout2; - IDWriteTextFormat1 *format1; - IDWriteTextFormat *format; - IDWriteTextLayout *layout; - IDWriteFactory2 *factory2; - IDWriteFactory *factory; - HRESULT hr; - - factory = create_factory(); - - hr = IDWriteFactory_CreateTextFormat(factory, tahomaW, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, - DWRITE_FONT_STRETCH_NORMAL, 10.0, enusW, &format); - ok(hr == S_OK, "got 0x%08x\n", hr); - - hr = IDWriteFactory_CreateTextLayout(factory, strW, 4, format, 1000.0, 1000.0, &layout); - ok(hr == S_OK, "got 0x%08x\n", hr); - IDWriteTextFormat_Release(format); - - hr = IDWriteTextLayout_QueryInterface(layout, &IID_IDWriteTextLayout2, (void**)&layout2); - IDWriteTextLayout_Release(layout); - - if (hr != S_OK) { - win_skip("GetFontFallback() is not supported.\n"); - IDWriteFactory_Release(factory); - return; - } - - if (0) /* crashes on native */ - hr = IDWriteTextLayout2_GetFontFallback(layout2, NULL); - - fallback = (void*)0xdeadbeef; - hr = IDWriteTextLayout2_GetFontFallback(layout2, &fallback); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(fallback == NULL, "got %p\n", fallback); - - hr = IDWriteTextLayout2_QueryInterface(layout2, &IID_IDWriteTextFormat1, (void**)&format1); - ok(hr == S_OK, "got 0x%08x\n", hr); - - fallback = (void*)0xdeadbeef; - hr = IDWriteTextFormat1_GetFontFallback(format1, &fallback); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(fallback == NULL, "got %p\n", fallback); - - hr = IDWriteFactory_QueryInterface(factory, &IID_IDWriteFactory2, (void**)&factory2); - ok(hr == S_OK, "got 0x%08x\n", hr); - - fallback = NULL; - hr = IDWriteFactory2_GetSystemFontFallback(factory2, &fallback); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(fallback != NULL, "got %p\n", fallback); - - hr = IDWriteTextFormat1_SetFontFallback(format1, fallback); - ok(hr == S_OK, "got 0x%08x\n", hr); - - fallback2 = (void*)0xdeadbeef; - hr = IDWriteTextLayout2_GetFontFallback(layout2, &fallback2); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(fallback2 == fallback, "got %p\n", fallback2); - - hr = IDWriteTextLayout2_SetFontFallback(layout2, NULL); - ok(hr == S_OK, "got 0x%08x\n", hr); - - fallback2 = (void*)0xdeadbeef; - hr = IDWriteTextFormat1_GetFontFallback(format1, &fallback2); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(fallback2 == NULL, "got %p\n", fallback2); - - IDWriteFontFallback_Release(fallback); - IDWriteTextFormat1_Release(format1); - IDWriteTextLayout2_Release(layout2); - IDWriteFactory_Release(factory); -} - static void test_DetermineMinWidth(void) { struct minwidth_test { @@ -4939,6 +4862,117 @@ todo_wine { ok(ref == 0, "Factory is not released, ref %u.\n", ref); }
+static void test_fallback(void) +{ + static const WCHAR strW[] = {'a','b','c','d',0}; + IDWriteFontFallback *fallback, *fallback2; + DWRITE_CLUSTER_METRICS clusters[4]; + DWRITE_TEXT_METRICS metrics; + IDWriteTextLayout2 *layout2; + IDWriteTextFormat1 *format1; + IDWriteTextFormat *format; + IDWriteTextLayout *layout; + IDWriteFactory2 *factory2; + IDWriteFactory *factory; + UINT32 count, i; + FLOAT width; + HRESULT hr; + + factory = create_factory(); + + /* Font does not exist in system collection. */ + hr = IDWriteFactory_CreateTextFormat(factory, g_blahfontW, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, 10.0, enusW, &format); + ok(hr == S_OK, "Failed to create text format, hr %#x.\n", hr); + + hr = IDWriteFactory_CreateTextLayout(factory, strW, 4, format, 1000.0, 1000.0, &layout); + ok(hr == S_OK, "Failed to create text layout, hr %#x.\n", hr); + + count = 0; + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); +todo_wine { + ok(hr == S_OK, "Failed to get cluster metrics, hr %#x.\n", hr); + ok(count == 4, "Unexpected count %u.\n", count); +} + for (i = 0, width = 0.0; i < count; i++) + width += clusters[i].width; + + memset(&metrics, 0xcc, sizeof(metrics)); + hr = IDWriteTextLayout_GetMetrics(layout, &metrics); + ok(hr == S_OK, "Failed to get layout metrics, hr %#x.\n", hr); +todo_wine { + ok(metrics.width > 0.0 && metrics.width == width, "Unexpected width %.2f, expected %.2f.\n", metrics.width, width); + ok(metrics.height > 0.0, "Unexpected height %.2f.\n", metrics.height); + ok(metrics.lineCount == 1, "Unexpected line count %u.\n", metrics.lineCount); +} + IDWriteTextLayout_Release(layout); + IDWriteTextFormat_Release(format); + + hr = IDWriteFactory_CreateTextFormat(factory, tahomaW, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, 10.0, enusW, &format); + ok(hr == S_OK, "got 0x%08x\n", hr); + + /* Existing font. */ + hr = IDWriteFactory_CreateTextLayout(factory, strW, 4, format, 1000.0, 1000.0, &layout); + ok(hr == S_OK, "got 0x%08x\n", hr); + IDWriteTextFormat_Release(format); + + hr = IDWriteTextLayout_QueryInterface(layout, &IID_IDWriteTextLayout2, (void**)&layout2); + IDWriteTextLayout_Release(layout); + + if (hr != S_OK) { + win_skip("GetFontFallback() is not supported.\n"); + IDWriteFactory_Release(factory); + return; + } + + if (0) /* crashes on native */ + hr = IDWriteTextLayout2_GetFontFallback(layout2, NULL); + + fallback = (void*)0xdeadbeef; + hr = IDWriteTextLayout2_GetFontFallback(layout2, &fallback); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(fallback == NULL, "got %p\n", fallback); + + hr = IDWriteTextLayout2_QueryInterface(layout2, &IID_IDWriteTextFormat1, (void**)&format1); + ok(hr == S_OK, "got 0x%08x\n", hr); + + fallback = (void*)0xdeadbeef; + hr = IDWriteTextFormat1_GetFontFallback(format1, &fallback); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(fallback == NULL, "got %p\n", fallback); + + hr = IDWriteFactory_QueryInterface(factory, &IID_IDWriteFactory2, (void**)&factory2); + ok(hr == S_OK, "got 0x%08x\n", hr); + + fallback = NULL; + hr = IDWriteFactory2_GetSystemFontFallback(factory2, &fallback); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(fallback != NULL, "got %p\n", fallback); + + hr = IDWriteTextFormat1_SetFontFallback(format1, fallback); + ok(hr == S_OK, "got 0x%08x\n", hr); + + fallback2 = (void*)0xdeadbeef; + hr = IDWriteTextLayout2_GetFontFallback(layout2, &fallback2); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(fallback2 == fallback, "got %p\n", fallback2); + + hr = IDWriteTextLayout2_SetFontFallback(layout2, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + fallback2 = (void*)0xdeadbeef; + hr = IDWriteTextFormat1_GetFontFallback(format1, &fallback2); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(fallback2 == NULL, "got %p\n", fallback2); + + IDWriteFontFallback_Release(fallback); + IDWriteTextFormat1_Release(format1); + IDWriteTextLayout2_Release(layout2); + IDWriteFactory_Release(factory); +} + + static void test_SetTypography(void) { static const WCHAR strW[] = {'a','f','i','b',0};
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/layout.c | 27 +++++++++--- dlls/dwrite/tests/layout.c | 86 +++++++++++++++++++++++++++++++++++++- 2 files changed, 106 insertions(+), 7 deletions(-)
diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index 5deae455b1..a5629270e1 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -53,6 +53,7 @@ struct dwrite_textformat_data { DWRITE_LINE_SPACING spacing;
FLOAT fontsize; + FLOAT tabstop;
DWRITE_TRIMMING trimming; IDWriteInlineObject *trimmingsign; @@ -4272,7 +4273,13 @@ static HRESULT WINAPI dwritetextformat_layout_SetFlowDirection(IDWriteTextFormat static HRESULT WINAPI dwritetextformat_layout_SetIncrementalTabStop(IDWriteTextFormat2 *iface, FLOAT tabstop) { struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat2(iface); - FIXME("(%p)->(%f): stub\n", This, tabstop); + + TRACE("(%p)->(%f)\n", This, tabstop); + + if (tabstop <= 0.0f) + return E_INVALIDARG; + + This->format.tabstop = tabstop; return S_OK; }
@@ -4346,8 +4353,8 @@ static DWRITE_FLOW_DIRECTION WINAPI dwritetextformat_layout_GetFlowDirection(IDW static FLOAT WINAPI dwritetextformat_layout_GetIncrementalTabStop(IDWriteTextFormat2 *iface) { struct dwrite_textlayout *This = impl_layout_from_IDWriteTextFormat2(iface); - FIXME("(%p): stub\n", This); - return 0.0f; + TRACE("(%p)\n", This); + return This->format.tabstop; }
static HRESULT WINAPI dwritetextformat_layout_GetTrimming(IDWriteTextFormat2 *iface, DWRITE_TRIMMING *options, @@ -4875,6 +4882,7 @@ static HRESULT layout_format_from_textformat(struct dwrite_textlayout *layout, I layout->format.style = IDWriteTextFormat_GetFontStyle(format); layout->format.stretch = IDWriteTextFormat_GetFontStretch(format); layout->format.fontsize= IDWriteTextFormat_GetFontSize(format); + layout->format.tabstop = IDWriteTextFormat_GetIncrementalTabStop(format); layout->format.textalignment = IDWriteTextFormat_GetTextAlignment(format); layout->format.paralign = IDWriteTextFormat_GetParagraphAlignment(format); layout->format.wrapping = IDWriteTextFormat_GetWordWrapping(format); @@ -5302,7 +5310,13 @@ static HRESULT WINAPI dwritetextformat_SetFlowDirection(IDWriteTextFormat2 *ifac static HRESULT WINAPI dwritetextformat_SetIncrementalTabStop(IDWriteTextFormat2 *iface, FLOAT tabstop) { struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface); - FIXME("(%p)->(%f): stub\n", This, tabstop); + + TRACE("(%p)->(%f)\n", This, tabstop); + + if (tabstop <= 0.0f) + return E_INVALIDARG; + + This->format.tabstop = tabstop; return S_OK; }
@@ -5368,8 +5382,8 @@ static DWRITE_FLOW_DIRECTION WINAPI dwritetextformat_GetFlowDirection(IDWriteTex static FLOAT WINAPI dwritetextformat_GetIncrementalTabStop(IDWriteTextFormat2 *iface) { struct dwrite_textformat *This = impl_from_IDWriteTextFormat2(iface); - FIXME("(%p): stub\n", This); - return 0.0f; + TRACE("(%p)\n", This); + return This->format.tabstop; }
static HRESULT WINAPI dwritetextformat_GetTrimming(IDWriteTextFormat2 *iface, DWRITE_TRIMMING *options, @@ -5631,6 +5645,7 @@ HRESULT create_textformat(const WCHAR *family_name, IDWriteFontCollection *colle This->format.weight = weight; This->format.style = style; This->format.fontsize = size; + This->format.tabstop = 4.0f * size; This->format.stretch = stretch; This->format.textalignment = DWRITE_TEXT_ALIGNMENT_LEADING; This->format.optical_alignment = DWRITE_OPTICAL_ALIGNMENT_NONE; diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index e6ed3c13c4..a117ca0d62 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -4972,7 +4972,6 @@ todo_wine { IDWriteFactory_Release(factory); }
- static void test_SetTypography(void) { static const WCHAR strW[] = {'a','f','i','b',0}; @@ -5599,6 +5598,90 @@ static void test_GetOverhangMetrics(void) IDWriteFactory_Release(factory); }
+static void test_tab_stops(void) +{ + static const WCHAR strW[] = {'\t','a','\t','b'}; + DWRITE_CLUSTER_METRICS clusters[4]; + IDWriteTextLayout *layout; + IDWriteTextFormat *format; + IDWriteFactory *factory; + DWRITE_TEXT_RANGE range; + FLOAT tabstop, size; + ULONG count; + HRESULT hr; + + factory = create_factory(); + + /* Default tab stop value. */ + for (size = 1.0f; size < 25.0f; size += 5.0f) + { + hr = IDWriteFactory_CreateTextFormat(factory, tahomaW, NULL, DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, size, enusW, &format); + ok(hr == S_OK, "Failed to create text format, hr %#x.\n", hr); + + tabstop = IDWriteTextFormat_GetIncrementalTabStop(format); + ok(tabstop == 4.0f * size, "Unexpected tab stop %f.\n", tabstop); + + IDWriteTextFormat_Release(format); + } + + hr = IDWriteFactory_CreateTextFormat(factory, tahomaW, NULL, DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 10.0f, enusW, &format); + ok(hr == S_OK, "Failed to create text format, hr %#x.\n", hr); + + hr = IDWriteTextFormat_SetIncrementalTabStop(format, 0.0f); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = IDWriteTextFormat_SetIncrementalTabStop(format, -10.0f); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + tabstop = IDWriteTextFormat_GetIncrementalTabStop(format); + ok(tabstop == 40.0f, "Unexpected tab stop %f.\n", tabstop); + + hr = IDWriteTextFormat_SetIncrementalTabStop(format, 100.0f); + ok(hr == S_OK, "Failed to set tab stop value, hr %#x.\n", hr); + + tabstop = IDWriteTextFormat_GetIncrementalTabStop(format); + ok(tabstop == 100.0f, "Unexpected tab stop %f.\n", tabstop); + + hr = IDWriteFactory_CreateTextLayout(factory, strW, 4, format, 1000.0f, 1000.0f, &layout); + ok(hr == S_OK, "Failed to create text layout, hr %x.\n", hr); + + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); + ok(hr == S_OK, "Failed to get cluster metrics, hr %#x.\n", hr); + ok(clusters[0].isWhitespace, "Unexpected isWhitespace.\n"); + ok(!clusters[1].isWhitespace, "Unexpected isWhitespace.\n"); + ok(clusters[2].isWhitespace, "Unexpected isWhitespace.\n"); + ok(!clusters[3].isWhitespace, "Unexpected isWhitespace.\n"); +todo_wine { + ok(clusters[0].width == tabstop, "Unexpected tab width.\n"); + ok(clusters[1].width + clusters[2].width == tabstop, "Unexpected tab width.\n"); +} + range.startPosition = 0; + range.length = ~0u; + hr = IDWriteTextLayout_SetFontSize(layout, 20.0f, range); + ok(hr == S_OK, "Failed to set font size, hr %#x.\n", hr); + + tabstop = IDWriteTextLayout_GetIncrementalTabStop(layout); + ok(tabstop == 100.0f, "Unexpected tab stop %f.\n", tabstop); + + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); + ok(hr == S_OK, "Failed to get cluster metrics, hr %#x.\n", hr); + ok(clusters[0].isWhitespace, "Unexpected isWhitespace.\n"); + ok(!clusters[1].isWhitespace, "Unexpected isWhitespace.\n"); + ok(clusters[2].isWhitespace, "Unexpected isWhitespace.\n"); + ok(!clusters[3].isWhitespace, "Unexpected isWhitespace.\n"); +todo_wine { + ok(clusters[0].width == tabstop, "Unexpected tab width.\n"); + ok(clusters[1].width + clusters[2].width == tabstop, "Unexpected tab width.\n"); +} + IDWriteTextLayout_Release(layout); + + IDWriteTextFormat_Release(format); + + IDWriteFactory_Release(factory); +} + START_TEST(layout) { IDWriteFactory *factory; @@ -5649,6 +5732,7 @@ START_TEST(layout) test_InvalidateLayout(); test_line_spacing(); test_GetOverhangMetrics(); + test_tab_stops();
IDWriteFactory_Release(factory); }