[PATCH 6/6] dwrite: Search more generously for font fallbacks.
Giovanni Mascellani
gmascellani at codeweavers.com
Mon Mar 8 03:31:19 CST 2021
Signed-off-by: Giovanni Mascellani <gmascellani at codeweavers.com>
---
dlls/dwrite/analyzer.c | 51 ++++++++++++++++++++------------------
dlls/dwrite/tests/layout.c | 10 --------
2 files changed, 27 insertions(+), 34 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 8574af5465f..5a04b19b77c 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -4771,12 +4771,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);
@@ -4789,12 +4786,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);
@@ -5053,21 +5047,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);
--
2.30.1
More information about the wine-devel
mailing list