Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- dlls/dwrite/analyzer.c | 51 ++++++++++++++++++++------------------ dlls/dwrite/tests/layout.c | 14 ----------- 2 files changed, 27 insertions(+), 38 deletions(-)
diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c index daa553adbaf..c811caf0a66 100644 --- a/dlls/dwrite/analyzer.c +++ b/dlls/dwrite/analyzer.c @@ -2066,7 +2066,7 @@ static HRESULT fallback_map_characters(IDWriteFont *font, const WCHAR *text, UIN /* stop on first unsupported character */ exists = FALSE; hr = IDWriteFont_HasCharacter(font, text[i], &exists); - if (hr == S_OK && exists) + if (SUCCEEDED(hr) && exists) ++*mapped_length; else break; @@ -2084,11 +2084,12 @@ static HRESULT fallback_get_fallback_font(struct dwrite_fontfallback *fallback, UINT32 i;
*mapped_font = NULL; + *mapped_length = 0;
mapping = find_fallback_mapping(fallback, text[0]); if (!mapping) { WARN("No mapping range for %#x.\n", text[0]); - return E_FAIL; + return S_OK; }
/* Now let's see what fallback can handle. Pick first font that could be created. */ @@ -2103,19 +2104,18 @@ static HRESULT fallback_get_fallback_font(struct dwrite_fontfallback *fallback,
if (!*mapped_font) { WARN("Failed to create fallback font.\n"); - return E_FAIL; + return S_OK; }
hr = fallback_map_characters(*mapped_font, text, length, mapped_length); - if (FAILED(hr)) - WARN("Mapping with fallback family %s failed, hr %#x.\n", debugstr_w(mapping->families[i]), hr);
if (!*mapped_length) { + WARN("Mapping with fallback family %s failed.\n", debugstr_w(mapping->families[i])); IDWriteFont_Release(*mapped_font); *mapped_font = NULL; }
- return *mapped_length ? S_OK : E_FAIL; + return hr; }
static HRESULT WINAPI fontfallback_MapCharacters(IDWriteFontFallback1 *iface, IDWriteTextAnalysisSource *source, @@ -2150,30 +2150,33 @@ static HRESULT WINAPI fontfallback_MapCharacters(IDWriteFontFallback1 *iface, ID
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); + /* It is not a fatal error for create_matching_font to + fail. We still have other fallbacks to try. */ + + if (SUCCEEDED(hr)) { + hr = fallback_map_characters(*ret_font, text, length, mapped_length); + if (FAILED(hr)) + goto done; + } + } + + if (!*mapped_length) { + if (*ret_font) { + IDWriteFont_Release(*ret_font); + *ret_font = NULL; + } + + hr = fallback_get_fallback_font(fallback, text, length, weight, style, stretch, mapped_length, ret_font); if (FAILED(hr)) goto done; }
if (!*mapped_length) { - IDWriteFont *mapped_font; - - hr = fallback_get_fallback_font(fallback, text, length, weight, style, stretch, mapped_length, &mapped_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; - } - } - else { - if (*ret_font) - IDWriteFont_Release(*ret_font); - *ret_font = mapped_font; - } + /* fallback wasn't found, ask the caller to skip one character + and try again; FIXME: skip the appropriate number of + characters instead of just one */ + *mapped_length = 1; }
done: diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index 36372dd8c5a..7941fa180c1 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -4808,12 +4808,9 @@ if (font) { font = NULL; hr = IDWriteFontFallback_MapCharacters(fallback, &analysissource, 0, 4, &fallbackcollection, g_fontNotInCollectionW, 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); @@ -4826,12 +4823,9 @@ if (font) { font = NULL; hr = IDWriteFontFallback_MapCharacters(fallback, &analysissource, 1, 1, &fallbackcollection, g_fontNotInCollectionW, 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); @@ -5090,21 +5084,17 @@ static void test_fallback(void)
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);
@@ -6631,10 +6621,8 @@ 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); ok(count == 4, "got %u\n", count); -} width = 0.0; if (hr == S_OK) for (i = 0; i < count; i++) @@ -6647,12 +6635,10 @@ todo_wine { ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width); ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n", metrics.widthIncludingTrailingWhitespace, width); -todo_wine 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); -todo_wine ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount); IDWriteTextLayout_Release(layout);