diff --git a/patches/dwrite-FontFallback/0001-dwrite-Test-IDWriteTextFormat-with-nonexistent-font.patch b/patches/dwrite-FontFallback/0001-dwrite-Test-IDWriteTextFormat-with-nonexistent-font.patch new file mode 100644 index 00000000..c12ae5d0 --- /dev/null +++ b/patches/dwrite-FontFallback/0001-dwrite-Test-IDWriteTextFormat-with-nonexistent-font.patch @@ -0,0 +1,77 @@ +From e2978c13fca913a14991e286c463ede69f61831d Mon Sep 17 00:00:00 2001 +From: Lucian Poston +Date: Sun, 20 May 2018 21:40:39 -0700 +Subject: [PATCH 1/6] dwrite: Test IDWriteTextFormat with nonexistent font + +Signed-off-by: Lucian Poston +--- + dlls/dwrite/tests/layout.c | 46 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 46 insertions(+) + +diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c +index 652f6b78ac..4198b8a1b1 100644 +--- a/dlls/dwrite/tests/layout.c ++++ b/dlls/dwrite/tests/layout.c +@@ -30,6 +30,7 @@ + #include "wine/test.h" + + static const WCHAR tahomaW[] = {'T','a','h','o','m','a',0}; ++static const WCHAR nonExistentFontW[] = {'B','l','a','h','!',0}; + static const WCHAR enusW[] = {'e','n','-','u','s',0}; + + struct testanalysissink +@@ -3292,6 +3293,51 @@ todo_wine + ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); + IDWriteTextLayout_Release(layout); + ++ IDWriteTextFormat_Release(format); ++ ++ /* nonexistent font */ ++ hr = IDWriteFactory_CreateTextFormat(factory, nonExistentFontW, 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, 500.0, 1000.0, &layout); ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ ++ count = 0; ++ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); ++todo_wine ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++todo_wine ++ ok(count == 4, "got %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); ++todo_wine ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++todo_wine ++ ok(metrics.left == 0.0, "got %.2f\n", metrics.left); ++todo_wine ++ ok(metrics.top == 0.0, "got %.2f\n", metrics.top); ++todo_wine ++ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); ++todo_wine ++ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", ++ metrics.widthIncludingTrailingWhitespace, width); ++todo_wine ++ ok(metrics.height > 0.0, "got %.2f\n", metrics.height); ++todo_wine ++ ok(metrics.layoutWidth == 500.0, "got %.2f\n", metrics.layoutWidth); ++todo_wine ++ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); ++todo_wine ++ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); ++todo_wine ++ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); ++ ++ IDWriteTextLayout_Release(layout); ++ + IDWriteTextFormat_Release(format); + IDWriteFactory_Release(factory); + } +-- +2.18.0 + diff --git a/patches/dwrite-FontFallback/0002-dwrite-Test-GetMetrics-with-custom-fontcollection.patch b/patches/dwrite-FontFallback/0002-dwrite-Test-GetMetrics-with-custom-fontcollection.patch new file mode 100644 index 00000000..a6f13b94 --- /dev/null +++ b/patches/dwrite-FontFallback/0002-dwrite-Test-GetMetrics-with-custom-fontcollection.patch @@ -0,0 +1,323 @@ +From 22fd0a86b6be3d2e203beee7a0b55f717f32436b Mon Sep 17 00:00:00 2001 +From: Lucian Poston +Date: Wed, 23 May 2018 00:01:42 -0700 +Subject: [PATCH 2/6] dwrite: Test GetMetrics with custom fontcollection + +Signed-off-by: Lucian Poston +--- + dlls/dwrite/tests/layout.c | 278 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 278 insertions(+) + +diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c +index 4198b8a1b1..7542cad8d7 100644 +--- a/dlls/dwrite/tests/layout.c ++++ b/dlls/dwrite/tests/layout.c +@@ -4489,6 +4489,7 @@ static void test_SetWordWrapping(void) + /* Collection dedicated to fallback testing */ + + static const WCHAR g_blahfontW[] = {'B','l','a','h',0}; ++static const WCHAR g_fontNotInCollectionW[] = {'n','o','t','B','l','a','h',0}; + static HRESULT WINAPI fontcollection_QI(IDWriteFontCollection *iface, REFIID riid, void **obj) + { + if (IsEqualIID(riid, &IID_IDWriteFontCollection) || IsEqualIID(riid, &IID_IUnknown)) { +@@ -4548,6 +4549,9 @@ static HRESULT WINAPI fontcollection_FindFamilyName(IDWriteFontCollection *iface + *index = 123456; + *exists = TRUE; + return S_OK; ++ } else if (!lstrcmpW(name, g_fontNotInCollectionW)) { ++ *exists = FALSE; ++ return S_OK; + } + ok(0, "unexpected call, name %s\n", wine_dbgstr_w(name)); + return E_NOTIMPL; +@@ -5568,6 +5572,279 @@ static void test_GetOverhangMetrics(void) + IDWriteFactory_Release(factory); + } + ++static void test_GetMetrics_with_custom_fontcollection(void) ++{ ++ static const WCHAR emptystringW[] = {0}; ++ static const WCHAR mappedW[] = {'a','b','c','d',0}; ++ static const WCHAR notmappedW[] = {'a',0xffff,'b',0}; // u+ffff = not a unicode character ++ DWRITE_CLUSTER_METRICS clusters[4]; ++ DWRITE_TEXT_METRICS metrics; ++ IDWriteTextFormat *format; ++ IDWriteTextLayout *layout; ++ IDWriteFactory *factory; ++ UINT32 count, i; ++ FLOAT width; ++ HRESULT hr; ++ ++ factory = create_factory(); ++ ++ /* font is in font collection */ ++ hr = IDWriteFactory_CreateTextFormat(factory, g_blahfontW, &fallbackcollection, ++ 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); ++ ++ /* text is mapped by fontfallback */ ++ hr = IDWriteFactory_CreateTextLayout(factory, mappedW, 4, format, 1000.0, 1000.0, &layout); ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ count = 9999; ++ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ ok(count == 4, "got %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, "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); ++ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); ++ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", ++ metrics.widthIncludingTrailingWhitespace, width); ++ ok(metrics.height > 0.0, "got %.2f\n", metrics.height); ++ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); ++ 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); ++ ++ /* text is not mapped by fontfallback */ ++ hr = IDWriteFactory_CreateTextLayout(factory, notmappedW, 4, format, 1000.0, 1000.0, &layout); ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ count = 9999; ++ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ ok(count == 4, "got %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, "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); ++ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); ++ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", ++ metrics.widthIncludingTrailingWhitespace, width); ++ ok(metrics.height > 0.0, "got %.2f\n", metrics.height); ++ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); ++ 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); ++ ++ /* empty string */ ++ hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 4, format, 1000.0, 1000.0, &layout); ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ count = 9999; ++ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ ok(count == 4, "got %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, "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); ++ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); ++ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", ++ metrics.widthIncludingTrailingWhitespace, width); ++ ok(metrics.height > 0.0, "got %.2f\n", metrics.height); ++ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); ++ 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); ++ ++ /* zero-length empty string */ ++ hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 0, format, 1000.0, 1000.0, &layout); ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ count = 9999; ++ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ ok(count == 0, "got %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, "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); ++ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); ++ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", ++ metrics.widthIncludingTrailingWhitespace, width); ++ ok(metrics.height > 0.0, "got %.2f\n", metrics.height); ++ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); ++ 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); ++ ++ IDWriteTextFormat_Release(format); ++ ++ /* font not in font collection */ ++ hr = IDWriteFactory_CreateTextFormat(factory, g_fontNotInCollectionW, &fallbackcollection, ++ 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); ++ ++ /* text is mapped by fontfallback */ ++ hr = IDWriteFactory_CreateTextLayout(factory, mappedW, 4, format, 1000.0, 1000.0, &layout); ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ count = 9999; ++ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); ++ todo_wine ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ todo_wine ++ ok(count == 4, "got %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); ++ todo_wine ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ todo_wine ++ ok(metrics.left == 0.0, "got %.2f\n", metrics.left); ++ todo_wine ++ ok(metrics.top == 0.0, "got %.2f\n", metrics.top); ++ todo_wine ++ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); ++ todo_wine ++ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", ++ metrics.widthIncludingTrailingWhitespace, width); ++ todo_wine ++ ok(metrics.height > 0.0, "got %.2f\n", metrics.height); ++ todo_wine ++ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); ++ todo_wine ++ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); ++ todo_wine ++ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); ++ todo_wine ++ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); ++ IDWriteTextLayout_Release(layout); ++ ++ /* text is not mapped by fontfallback */ ++ hr = IDWriteFactory_CreateTextLayout(factory, notmappedW, 4, format, 1000.0, 1000.0, &layout); ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ count = 9999; ++ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); ++ todo_wine ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ todo_wine ++ ok(count == 4, "got %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); ++ todo_wine ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ todo_wine ++ ok(metrics.left == 0.0, "got %.2f\n", metrics.left); ++ todo_wine ++ ok(metrics.top == 0.0, "got %.2f\n", metrics.top); ++ todo_wine ++ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); ++ todo_wine ++ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", ++ metrics.widthIncludingTrailingWhitespace, width); ++ todo_wine ++ ok(metrics.height > 0.0, "got %.2f\n", metrics.height); ++ todo_wine ++ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); ++ todo_wine ++ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); ++ todo_wine ++ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); ++ todo_wine ++ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); ++ IDWriteTextLayout_Release(layout); ++ ++ /* empty string */ ++ hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 4, format, 1000.0, 1000.0, &layout); ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ count = 9999; ++ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); ++ todo_wine ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ todo_wine ++ ok(count == 4, "got %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); ++ todo_wine ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ todo_wine ++ ok(metrics.left == 0.0, "got %.2f\n", metrics.left); ++ todo_wine ++ ok(metrics.top == 0.0, "got %.2f\n", metrics.top); ++ todo_wine ++ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); ++ todo_wine ++ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", ++ metrics.widthIncludingTrailingWhitespace, width); ++ todo_wine ++ ok(metrics.height > 0.0, "got %.2f\n", metrics.height); ++ todo_wine ++ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); ++ todo_wine ++ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); ++ todo_wine ++ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); ++ todo_wine ++ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); ++ IDWriteTextLayout_Release(layout); ++ ++ /* zero-length empty string */ ++ hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 0, format, 1000.0, 1000.0, &layout); ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ count = 9999; ++ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ ok(count == 0, "got %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); ++ todo_wine ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ todo_wine ++ ok(metrics.left == 0.0, "got %.2f\n", metrics.left); ++ todo_wine ++ ok(metrics.top == 0.0, "got %.2f\n", metrics.top); ++ todo_wine ++ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); ++ todo_wine ++ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", ++ metrics.widthIncludingTrailingWhitespace, width); ++ todo_wine ++ ok(metrics.height > 0.0, "got %.2f\n", metrics.height); ++ todo_wine ++ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); ++ todo_wine ++ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); ++ todo_wine ++ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); ++ todo_wine ++ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); ++ IDWriteTextLayout_Release(layout); ++ ++ IDWriteTextFormat_Release(format); ++ ++ IDWriteFactory_Release(factory); ++} ++ + START_TEST(layout) + { + IDWriteFactory *factory; +@@ -5601,6 +5878,7 @@ START_TEST(layout) + test_SetFontStretch(); + test_SetStrikethrough(); + test_GetMetrics(); ++ test_GetMetrics_with_custom_fontcollection(); + test_SetFlowDirection(); + test_SetDrawingEffect(); + test_GetLineMetrics(); +-- +2.18.0 + diff --git a/patches/dwrite-FontFallback/0004-dwrite-Use-font-fallback-when-mapping-characters.patch b/patches/dwrite-FontFallback/0004-dwrite-Use-font-fallback-when-mapping-characters.patch new file mode 100644 index 00000000..54269625 --- /dev/null +++ b/patches/dwrite-FontFallback/0004-dwrite-Use-font-fallback-when-mapping-characters.patch @@ -0,0 +1,352 @@ +From add69d1d24330592891222674844dccf104d6d73 Mon Sep 17 00:00:00 2001 +From: Lucian Poston +Date: Mon, 21 May 2018 18:13:00 -0700 +Subject: [PATCH 4/6] dwrite: Use font fallback when mapping characters + +Signed-off-by: Lucian Poston +--- + dlls/dwrite/analyzer.c | 77 +++++++++++++++++++++++------- + dlls/dwrite/layout.c | 6 +++ + dlls/dwrite/tests/layout.c | 97 +++++++++++++------------------------- + 3 files changed, 98 insertions(+), 82 deletions(-) + +diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c +index 8d553c6d56..21da783fe6 100644 +--- a/dlls/dwrite/analyzer.c ++++ b/dlls/dwrite/analyzer.c +@@ -2078,6 +2078,7 @@ static HRESULT fallback_get_fallback_font(struct dwrite_fontfallback *fallback, + IDWriteFont **mapped_font) + { + const struct fallback_mapping *mapping; ++ IDWriteFontCollection *collection; + HRESULT hr; + UINT32 i; + +@@ -2089,9 +2090,15 @@ static HRESULT fallback_get_fallback_font(struct dwrite_fontfallback *fallback, + return E_FAIL; + } + ++ if (mapping->collection) { ++ collection = mapping->collection; ++ } else { ++ collection = (IDWriteFontCollection *)fallback->systemcollection; ++ } ++ + /* Now let's see what fallback can handle. Pick first font that could be created. */ + for (i = 0; i < mapping->families_count; i++) { +- hr = create_matching_font((IDWriteFontCollection *)fallback->systemcollection, mapping->families[i], ++ hr = create_matching_font(collection, mapping->families[i], + weight, style, stretch, mapped_font); + if (hr == S_OK) { + TRACE("Created fallback font using family %s.\n", debugstr_w(mapping->families[i])); +@@ -2148,32 +2155,66 @@ static HRESULT WINAPI fontfallback_MapCharacters(IDWriteFontFallback *iface, IDW + + if (basefamily && *basefamily) { + hr = create_matching_font(basecollection, basefamily, weight, style, stretch, ret_font); +- if (FAILED(hr)) +- goto done; +- +- hr = fallback_map_characters(*ret_font, text, length, mapped_length); +- if (FAILED(hr)) +- goto done; ++ if (SUCCEEDED(hr)) { ++ hr = fallback_map_characters(*ret_font, text, length, mapped_length); ++ if (FAILED(hr)) { ++ IDWriteFont_Release(*ret_font); ++ *ret_font = NULL; ++ WARN("Mapping with requested family %s failed, hr %#x.\n", debugstr_w(basefamily), hr); ++ } ++ } + } + + if (!*mapped_length) { +- IDWriteFont *mapped_font; ++ if (*ret_font) { ++ IDWriteFont_Release(*ret_font); ++ *ret_font = NULL; ++ } + +- hr = fallback_get_fallback_font(fallback, text, length, weight, style, stretch, mapped_length, &mapped_font); ++ hr = fallback_get_fallback_font(fallback, text, length, weight, style, stretch, mapped_length, ret_font); + if (FAILED(hr)) { +- /* fallback wasn't found, keep base font if any, so we can get at least some visual output */ +- if (*ret_font) { +- *mapped_length = length; +- hr = S_OK; +- } ++ WARN("Mapping with fallback families failed, hr %#x.\n", hr); + } +- else { +- if (*ret_font) +- IDWriteFont_Release(*ret_font); +- *ret_font = mapped_font; ++ } ++ ++ /** ++ * This is a rough hack. We search the system font collection because ++ * the system fontfallback, which would have been searched above, is not ++ * fully implemented as it isn't populated with any system fonts. Once ++ * implemented, the block below can be removed. ++ * */ ++ if (!*mapped_length) { ++ IDWriteFontFamily *family; ++ IDWriteFont *font; ++ UINT32 i, count = IDWriteFontCollection_GetFontFamilyCount((IDWriteFontCollection *)fallback->systemcollection); ++ for (i = 0; i < count; i++) { ++ hr = IDWriteFontCollection_GetFontFamily((IDWriteFontCollection *)fallback->systemcollection, i, &family); ++ if (FAILED(hr)) { ++ ERR("Failed to get font family.\n"); ++ continue; ++ } ++ ++ hr = IDWriteFontFamily_GetFirstMatchingFont(family, weight, stretch, style, &font); ++ IDWriteFontFamily_Release(family); ++ if (FAILED(hr)) { ++ continue; ++ } ++ ++ hr = fallback_map_characters(font, text, length, mapped_length); ++ if (SUCCEEDED(hr) && mapped_length > 0) { ++ *ret_font = font; ++ break; ++ } ++ ++ IDWriteFont_Release(font); + } + } + ++ if (!*mapped_length) { ++ *mapped_length = length == 0 ? 0 : 1; ++ hr = S_OK; ++ } ++ + done: + heap_free(buff); + return hr; +diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c +index 65e0a57678..df3f3beabb 100644 +--- a/dlls/dwrite/layout.c ++++ b/dlls/dwrite/layout.c +@@ -878,6 +878,12 @@ static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout) + goto fatal; + } + ++ if (!font) { ++ hr = E_FAIL; ++ WARN("Failed to create font face, hr %#x.\n", hr); ++ goto fatal; ++ } ++ + hr = IDWriteFont_CreateFontFace(font, &run->run.fontFace); + IDWriteFont_Release(font); + if (FAILED(hr)) { +diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c +index c8f3f5a00f..430bb1f0eb 100644 +--- a/dlls/dwrite/tests/layout.c ++++ b/dlls/dwrite/tests/layout.c +@@ -3310,35 +3310,23 @@ todo_wine + + count = 0; + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); +-todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); +-todo_wine + ok(count == 4, "got %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); +-todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); +-todo_wine + ok(metrics.left == 0.0, "got %.2f\n", metrics.left); +-todo_wine + ok(metrics.top == 0.0, "got %.2f\n", metrics.top); +-todo_wine + ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); +-todo_wine + ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", + metrics.widthIncludingTrailingWhitespace, width); +-todo_wine + ok(metrics.height > 0.0, "got %.2f\n", metrics.height); +-todo_wine + ok(metrics.layoutWidth == 500.0, "got %.2f\n", metrics.layoutWidth); +-todo_wine + ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); +-todo_wine + ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); +-todo_wine + ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); + + IDWriteTextLayout_Release(layout); +@@ -4637,16 +4625,13 @@ static void test_MapCharacters(void) + font = NULL; + hr = IDWriteFontFallback_MapCharacters(fallback, &analysissource, 0, 1, NULL, NULL, DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, &mappedlength, &font, &scale); +-todo_wine { + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(mappedlength == 1, "got %u\n", mappedlength); +-} + ok(scale == 1.0f, "got %f\n", scale); +-todo_wine + ok(font != NULL, "got %p\n", font); +-if (font) { +- IDWriteFont_Release(font); +-} ++ if (font) { ++ IDWriteFont_Release(font); ++ } + /* same latin text, full length */ + g_source = strW; + mappedlength = 0; +@@ -4654,16 +4639,13 @@ if (font) { + font = NULL; + hr = IDWriteFontFallback_MapCharacters(fallback, &analysissource, 0, 3, NULL, NULL, DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, &mappedlength, &font, &scale); +-todo_wine { + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(mappedlength == 3, "got %u\n", mappedlength); +-} + ok(scale == 1.0f, "got %f\n", scale); +-todo_wine + ok(font != NULL, "got %p\n", font); +-if (font) { +- IDWriteFont_Release(font); +-} ++ if (font) { ++ IDWriteFont_Release(font); ++ } + /* string 'a\x3058b' */ + g_source = str2W; + mappedlength = 0; +@@ -4671,38 +4653,32 @@ if (font) { + font = NULL; + hr = IDWriteFontFallback_MapCharacters(fallback, &analysissource, 0, 3, NULL, NULL, DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, &mappedlength, &font, &scale); +-todo_wine { + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(mappedlength == 1, "got %u\n", mappedlength); +-} + ok(scale == 1.0f, "got %f\n", scale); +-todo_wine + ok(font != NULL, "got %p\n", font); +-if (font) { +- IDWriteFont_Release(font); +-} ++ if (font) { ++ IDWriteFont_Release(font); ++ } + g_source = str2W; + mappedlength = 0; + scale = 0.0f; + font = NULL; + hr = IDWriteFontFallback_MapCharacters(fallback, &analysissource, 1, 2, NULL, NULL, DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, &mappedlength, &font, &scale); +-todo_wine { + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(mappedlength == 1, "got %u\n", mappedlength); +-} + ok(scale == 1.0f, "got %f\n", scale); +-todo_wine + ok(font != NULL, "got %p\n", font); +-if (font) { +- /* font returned for Hiragana character, check if it supports Latin too */ +- exists = FALSE; +- hr = IDWriteFont_HasCharacter(font, 'b', &exists); +- ok(hr == S_OK, "got 0x%08x\n", hr); +- ok(exists, "got %d\n", exists); ++ if (font) { ++ /* font returned for Hiragana character, check if it supports Latin too */ ++ exists = FALSE; ++ hr = IDWriteFont_HasCharacter(font, 'b', &exists); ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ ok(exists, "got %d\n", exists); + +- IDWriteFont_Release(font); +-} ++ IDWriteFont_Release(font); ++ } + /* Try with explicit collection, Tahoma will be forced. */ + /* 1. Latin part */ + g_source = str2W; +@@ -4725,7 +4701,10 @@ if (font) { + IDWriteLocalizedStrings_Release(strings); + IDWriteFont_Release(font); + +- /* 2. Hiragana character, force Tahoma font does not support Japanese */ ++ /** ++ * 2. Hiragana character. Tahoma is requested, but it doesn't support ++ * Japanese. A NULL font is returned if there is no fallback for Japanese. ++ */ + g_source = str2W; + mappedlength = 0; + scale = 0.0f; +@@ -4735,17 +4714,19 @@ if (font) { + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(mappedlength == 1, "got %u\n", mappedlength); + ok(scale == 1.0f, "got %f\n", scale); +- ok(font != NULL, "got %p\n", font); + +- exists = FALSE; +- hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &strings, &exists); +- ok(hr == S_OK && exists, "got 0x%08x, exists %d\n", hr, exists); +- hr = IDWriteLocalizedStrings_GetString(strings, 0, buffW, ARRAY_SIZE(buffW)); +- ok(hr == S_OK, "got 0x%08x\n", hr); +-todo_wine +- ok(lstrcmpW(buffW, tahomaW), "%s\n", wine_dbgstr_w(buffW)); +- IDWriteLocalizedStrings_Release(strings); +- IDWriteFont_Release(font); ++ if (!font) { ++ skip("Missing system font for Japanese.\n"); ++ } else { ++ exists = FALSE; ++ hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &strings, &exists); ++ ok(hr == S_OK && exists, "got 0x%08x, exists %d\n", hr, exists); ++ hr = IDWriteLocalizedStrings_GetString(strings, 0, buffW, ARRAY_SIZE(buffW)); ++ ok(hr == S_OK, "got 0x%08x\n", hr); ++ ok(lstrcmpW(buffW, tahomaW), "%s\n", wine_dbgstr_w(buffW)); ++ IDWriteLocalizedStrings_Release(strings); ++ IDWriteFont_Release(font); ++ } + + IDWriteFontFallback_Release(fallback); + IDWriteFactory2_Release(factory2); +@@ -5708,34 +5689,22 @@ static void test_GetMetrics_with_custom_fontcollection(void) + ok(hr == S_OK, "got 0x%08x\n", hr); + count = 9999; + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); +- todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); +- todo_wine + ok(count == 4, "got %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); +- todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); +- todo_wine + ok(metrics.left == 0.0, "got %.2f\n", metrics.left); +- todo_wine + ok(metrics.top == 0.0, "got %.2f\n", metrics.top); +- todo_wine + ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); +- todo_wine + ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", + metrics.widthIncludingTrailingWhitespace, width); +- todo_wine + ok(metrics.height > 0.0, "got %.2f\n", metrics.height); +- todo_wine + ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); +- todo_wine + ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); +- todo_wine + ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); +- todo_wine + ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); + IDWriteTextLayout_Release(layout); + +-- +2.18.0 + diff --git a/patches/dwrite-FontFallback/0005-dwrite-Use-MapCharacters-for-non-visual-characters.patch b/patches/dwrite-FontFallback/0005-dwrite-Use-MapCharacters-for-non-visual-characters.patch new file mode 100644 index 00000000..c305f465 --- /dev/null +++ b/patches/dwrite-FontFallback/0005-dwrite-Use-MapCharacters-for-non-visual-characters.patch @@ -0,0 +1,128 @@ +From 838b8a5edeca6c06c20bdc301f4d5d658e835cc9 Mon Sep 17 00:00:00 2001 +From: Lucian Poston +Date: Wed, 23 May 2018 05:59:20 -0700 +Subject: [PATCH 5/6] dwrite: Use MapCharacters for non-visual characters + +Signed-off-by: Lucian Poston +--- + dlls/dwrite/layout.c | 22 +++++++++++++++------- + dlls/dwrite/tests/layout.c | 24 ------------------------ + 2 files changed, 15 insertions(+), 31 deletions(-) + +diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c +index df3f3beabb..5d06bf9348 100644 +--- a/dlls/dwrite/layout.c ++++ b/dlls/dwrite/layout.c +@@ -822,7 +822,8 @@ static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout) + LIST_FOR_EACH_ENTRY(r, &layout->runs, struct layout_run, entry) { + struct regular_layout_run *run = &r->u.regular; + IDWriteFont *font; +- UINT32 length; ++ UINT32 length, mapped_length; ++ FLOAT scale; + + if (r->kind == LAYOUT_RUN_INLINE) + continue; +@@ -830,12 +831,19 @@ static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout) + range = get_layout_range_by_pos(layout, run->descr.textPosition); + + if (run->sa.shapes == DWRITE_SCRIPT_SHAPES_NO_VISUAL) { +- IDWriteFontCollection *collection; +- +- collection = range->collection ? range->collection : sys_collection; +- +- if (FAILED(hr = create_matching_font(collection, range->fontfamily, range->weight, range->style, +- range->stretch, &font))) { ++ hr = IDWriteFontFallback_MapCharacters(fallback, ++ (IDWriteTextAnalysisSource *)&layout->IDWriteTextAnalysisSource1_iface, ++ run->descr.textPosition, ++ run->descr.stringLength, ++ range->collection, ++ range->fontfamily, ++ range->weight, ++ range->style, ++ range->stretch, ++ &mapped_length, ++ &font, ++ &scale); ++ if (FAILED(hr)) { + WARN("%s: failed to create matching font for non visual run, family %s, collection %p\n", + debugstr_rundescr(&run->descr), debugstr_w(range->fontfamily), range->collection); + break; +diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c +index 430bb1f0eb..cf1d5d7060 100644 +--- a/dlls/dwrite/tests/layout.c ++++ b/dlls/dwrite/tests/layout.c +@@ -5713,34 +5713,22 @@ static void test_GetMetrics_with_custom_fontcollection(void) + ok(hr == S_OK, "got 0x%08x\n", hr); + count = 9999; + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); +- todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); +- todo_wine + ok(count == 4, "got %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); +- todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); +- todo_wine + ok(metrics.left == 0.0, "got %.2f\n", metrics.left); +- todo_wine + ok(metrics.top == 0.0, "got %.2f\n", metrics.top); +- todo_wine + ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); +- todo_wine + ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", + metrics.widthIncludingTrailingWhitespace, width); +- todo_wine + ok(metrics.height > 0.0, "got %.2f\n", metrics.height); +- todo_wine + ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); +- todo_wine + ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); +- todo_wine + ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); +- todo_wine + ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); + IDWriteTextLayout_Release(layout); + +@@ -5749,34 +5737,22 @@ static void test_GetMetrics_with_custom_fontcollection(void) + ok(hr == S_OK, "got 0x%08x\n", hr); + count = 9999; + hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count); +- todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); +- todo_wine + ok(count == 4, "got %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); +- todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); +- todo_wine + ok(metrics.left == 0.0, "got %.2f\n", metrics.left); +- todo_wine + ok(metrics.top == 0.0, "got %.2f\n", metrics.top); +- todo_wine + ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); +- todo_wine + ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", + metrics.widthIncludingTrailingWhitespace, width); +- todo_wine + ok(metrics.height > 0.0, "got %.2f\n", metrics.height); +- todo_wine + ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); +- todo_wine + ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); +- todo_wine + ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); +- todo_wine + ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); + IDWriteTextLayout_Release(layout); + +-- +2.18.0 + diff --git a/patches/dwrite-FontFallback/0006-dwrite-Use-MapCharacters-for-dummy-line-metrics.patch b/patches/dwrite-FontFallback/0006-dwrite-Use-MapCharacters-for-dummy-line-metrics.patch new file mode 100644 index 00000000..c3b05bc0 --- /dev/null +++ b/patches/dwrite-FontFallback/0006-dwrite-Use-MapCharacters-for-dummy-line-metrics.patch @@ -0,0 +1,96 @@ +From a0f4bde380003f7a8e3b713028215bf985dbb3c0 Mon Sep 17 00:00:00 2001 +From: Lucian Poston +Date: Wed, 23 May 2018 07:03:44 -0700 +Subject: [PATCH 6/6] dwrite: Use MapCharacters for dummy line metrics + +Fixes: https://bugs.winehq.org/show_bug.cgi?id=44052 + +Signed-off-by: Lucian Poston +--- + dlls/dwrite/layout.c | 29 +++++++++++++++++++++++++++++ + dlls/dwrite/tests/layout.c | 8 -------- + 2 files changed, 29 insertions(+), 8 deletions(-) + +diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c +index 5d06bf9348..2213717f92 100644 +--- a/dlls/dwrite/layout.c ++++ b/dlls/dwrite/layout.c +@@ -1808,8 +1808,11 @@ static HRESULT layout_set_dummy_line_metrics(struct dwrite_textlayout *layout, U + DWRITE_FONT_METRICS fontmetrics; + struct layout_range *range; + IDWriteFontFace *fontface; ++ IDWriteFontFallback *fallback; + IDWriteFont *font; + HRESULT hr; ++ UINT32 mapped_length; ++ FLOAT scale; + + range = get_layout_range_by_pos(layout, pos); + hr = create_matching_font(range->collection, +@@ -1818,8 +1821,34 @@ static HRESULT layout_set_dummy_line_metrics(struct dwrite_textlayout *layout, U + range->style, + range->stretch, + &font); ++ ++ if (FAILED(hr)) { ++ if (layout->format.fallback) { ++ fallback = layout->format.fallback; ++ IDWriteFontFallback_AddRef(fallback); ++ } else if (FAILED(hr = IDWriteFactory5_GetSystemFontFallback(layout->factory, &fallback))) { ++ WARN("Failed to get system fallback, hr %#x.\n", hr); ++ return hr; ++ } ++ ++ hr = IDWriteFontFallback_MapCharacters(fallback, ++ (IDWriteTextAnalysisSource *)&layout->IDWriteTextAnalysisSource1_iface, ++ pos, ++ layout->len, ++ range->collection, ++ range->fontfamily, ++ range->weight, ++ range->style, ++ range->stretch, ++ &mapped_length, ++ &font, ++ &scale); ++ IDWriteFontFallback_Release(fallback); ++ } + if (FAILED(hr)) + return hr; ++ if (font == NULL) ++ return S_OK; + hr = IDWriteFont_CreateFontFace(font, &fontface); + IDWriteFont_Release(font); + if (FAILED(hr)) +diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c +index cf1d5d7060..6ed7b3c334 100644 +--- a/dlls/dwrite/tests/layout.c ++++ b/dlls/dwrite/tests/layout.c +@@ -5767,24 +5767,16 @@ static void test_GetMetrics_with_custom_fontcollection(void) + width += clusters[i].width; + memset(&metrics, 0xcc, sizeof(metrics)); + hr = IDWriteTextLayout_GetMetrics(layout, &metrics); +- todo_wine + ok(hr == S_OK, "got 0x%08x\n", hr); +- todo_wine + ok(metrics.left == 0.0, "got %.2f\n", metrics.left); +- todo_wine + ok(metrics.top == 0.0, "got %.2f\n", metrics.top); +- todo_wine + ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); +- todo_wine + ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", + metrics.widthIncludingTrailingWhitespace, width); + todo_wine + ok(metrics.height > 0.0, "got %.2f\n", metrics.height); +- todo_wine + ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth); +- todo_wine + ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight); +- todo_wine + ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth); + todo_wine + ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); +-- +2.18.0 + diff --git a/patches/dwrite-FontFallback/definition b/patches/dwrite-FontFallback/definition new file mode 100644 index 00000000..7d93ede0 --- /dev/null +++ b/patches/dwrite-FontFallback/definition @@ -0,0 +1 @@ +Fixes: [44052] - Support for font fallback. diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index a071cf22..0c770eaf 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -135,6 +135,7 @@ patch_enable_all () enable_dinput_Initialize="$1" enable_dsound_EAX="$1" enable_dsound_Fast_Mixer="$1" + enable_dwrite_FontFallback="$1" enable_dxdiagn_Enumerate_DirectSound="$1" enable_dxdiagn_GetChildContainer_Leaf_Nodes="$1" enable_dxgi_GammaRamp="$1" @@ -566,6 +567,9 @@ patch_enable () dsound-Fast_Mixer) enable_dsound_Fast_Mixer="$2" ;; + dwrite-FontFallback) + enable_dwrite_FontFallback="$2" + ;; dxdiagn-Enumerate_DirectSound) enable_dxdiagn_Enumerate_DirectSound="$2" ;; @@ -3420,6 +3424,29 @@ if test "$enable_dsound_EAX" -eq 1; then ) >> "$patchlist" fi +# Patchset dwrite-FontFallback +# | +# | This patchset fixes the following Wine bugs: +# | * [#44052] - Support for font fallback. +# | +# | Modified files: +# | * dlls/dwrite/analyzer.c, dlls/dwrite/layout.c, dlls/dwrite/tests/layout.c +# | +if test "$enable_dwrite_FontFallback" -eq 1; then + patch_apply dwrite-FontFallback/0001-dwrite-Test-IDWriteTextFormat-with-nonexistent-font.patch + patch_apply dwrite-FontFallback/0002-dwrite-Test-GetMetrics-with-custom-fontcollection.patch + patch_apply dwrite-FontFallback/0004-dwrite-Use-font-fallback-when-mapping-characters.patch + patch_apply dwrite-FontFallback/0005-dwrite-Use-MapCharacters-for-non-visual-characters.patch + patch_apply dwrite-FontFallback/0006-dwrite-Use-MapCharacters-for-dummy-line-metrics.patch + ( + printf '%s\n' '+ { "Lucian Poston", "dwrite: Test IDWriteTextFormat with nonexistent font.", 1 },'; + printf '%s\n' '+ { "Lucian Poston", "dwrite: Test GetMetrics with custom fontcollection.", 1 },'; + printf '%s\n' '+ { "Lucian Poston", "dwrite: Use font fallback when mapping characters.", 1 },'; + printf '%s\n' '+ { "Lucian Poston", "dwrite: Use MapCharacters for non-visual characters.", 1 },'; + printf '%s\n' '+ { "Lucian Poston", "dwrite: Use MapCharacters for dummy line metrics.", 1 },'; + ) >> "$patchlist" +fi + # Patchset dxdiagn-Enumerate_DirectSound # | # | This patchset fixes the following Wine bugs: @@ -5542,7 +5569,7 @@ fi # | * [#46174] qwave: Added QOSCreateHandle stub # | # | Modified files: -# | * dlls/qwave/main.c, include/qos2.h +# | * dlls/qwave/main.c, dlls/qwave/qwave.spec, include/qos2.h # | if test "$enable_qwave_QOSCreateHandle" -eq 1; then patch_apply qwave-QOSCreateHandle/0001-qwave-Added-QOSCreateHandle-stub.patch