From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/analyzer.c | 402 +++++++++++++++-------------------- dlls/dwrite/dwrite_private.h | 1 + dlls/dwrite/layout.c | 30 ++- dlls/dwrite/main.c | 1 + dlls/dwrite/tests/layout.c | 50 ++--- 5 files changed, 217 insertions(+), 267 deletions(-)
diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c index 4b666b8ca46..f0295eed48c 100644 --- a/dlls/dwrite/analyzer.c +++ b/dlls/dwrite/analyzer.c @@ -210,16 +210,19 @@ const char *debugstr_sa_script(UINT16 script) return script < Script_LastId ? debugstr_tag(dwritescripts_properties[script].props.isoScriptCode) : "undefined"; }
-/* system font falback configuration */ -static const WCHAR *cjk_families[] = { L"Meiryo" }; - -static const DWRITE_UNICODE_RANGE cjk_ranges[] = +static const struct fallback_description +{ + const char *ranges; + const WCHAR *families; + const WCHAR *locale; +} +system_fallback_config[] = { - { 0x3000, 0x30ff }, /* CJK Symbols and Punctuation, Hiragana, Katakana */ - { 0x31f0, 0x31ff }, /* Katakana Phonetic Extensions */ - { 0x4e00, 0x9fff }, /* CJK Unified Ideographs */ + { "3000-30FF, 31F0-31FF, 4E00-9FFF", L"Meiryo" }, };
+static struct fallback_data system_fallback; + struct text_source_context { IDWriteTextAnalysisSource *source; @@ -381,16 +384,6 @@ static struct fallback_locale * font_fallback_get_locale(const struct list *loca return neutral; }
-static const struct fallback_mapping fontfallback_neutral_data[] = { -#define MAPPING_RANGE(ranges, families) \ - { (DWRITE_UNICODE_RANGE *)ranges, ARRAY_SIZE(ranges), \ - (WCHAR **)families, ARRAY_SIZE(families) } - - MAPPING_RANGE(cjk_ranges, cjk_families), - -#undef MAPPING_RANGE -}; - struct fallback_data { struct fallback_mapping *mappings; @@ -404,8 +397,6 @@ struct dwrite_fontfallback LONG refcount; IDWriteFactory7 *factory; IDWriteFontCollection *systemcollection; - struct fallback_mapping *mappings; - UINT32 mappings_count; struct fallback_data data; size_t mappings_size; }; @@ -2222,34 +2213,6 @@ static ULONG WINAPI fontfallback_Release(IDWriteFontFallback1 *iface) return IDWriteFactory7_Release(fallback->factory); }
-static int __cdecl compare_mapping_range(const void *a, const void *b) -{ - UINT32 ch = *(UINT32 *)a; - DWRITE_UNICODE_RANGE *range = (DWRITE_UNICODE_RANGE *)b; - - if (ch > range->last) - return 1; - else if (ch < range->first) - return -1; - else - return 0; -} - -static const struct fallback_mapping *find_fallback_mapping_system(struct dwrite_fontfallback *fallback, UINT32 ch) -{ - UINT32 i; - - for (i = 0; i < fallback->mappings_count; i++) { - struct fallback_mapping *mapping = &fallback->mappings[i]; - - if (bsearch(&ch, mapping->ranges, mapping->ranges_count, sizeof(*mapping->ranges), - compare_mapping_range) != NULL) - return mapping; - } - - return NULL; -} - static UINT32 fallback_font_get_supported_length(IDWriteFont3 *font, IDWriteTextAnalysisSource *source, UINT32 position, UINT32 length) { @@ -2272,12 +2235,16 @@ static HRESULT fallback_map_characters(const struct dwrite_fontfallback *fallbac { const struct fallback_mapping *mapping = NULL; struct text_source_context context; + const struct fallback_data *data; const WCHAR *locale_name = NULL; struct fallback_locale *locale; UINT32 i, length = 0, mapped; IDWriteFont3 *font; HRESULT hr;
+ /* ~0u is a marker for system fallback data */ + data = fallback->data.count == ~0u ? &system_fallback : &fallback->data; + /* We will try to map as much of given input as GetLocaleName() says. It's assumed that returned length covers whole span of characters set with that locale, so callback is only used once. */ if (FAILED(hr = IDWriteTextAnalysisSource_GetLocaleName(source, position, &length, &locale_name))) @@ -2287,13 +2254,13 @@ static HRESULT fallback_map_characters(const struct dwrite_fontfallback *fallbac if (!locale_name) locale_name = L"";
/* Lookup locale entry once, if specific locale is missing neutral one will be returned. */ - locale = font_fallback_get_locale(&fallback->data.locales, locale_name); + locale = font_fallback_get_locale(&data->locales, locale_name);
if (FAILED(hr = text_source_context_init(&context, source, position, length))) return hr;
/* Find a mapping for given locale. */ text_source_get_next_u32_char(&context); - if (!(mapping = find_fallback_mapping(&fallback->data, locale, context.ch))) + if (!(mapping = find_fallback_mapping(data, locale, context.ch))) { *ret_font = NULL; *ret_length = 0; @@ -2303,7 +2270,7 @@ static HRESULT fallback_map_characters(const struct dwrite_fontfallback *fallbac
while (!text_source_get_next_u32_char(&context)) { - if (find_fallback_mapping(&fallback->data, locale, context.ch) != mapping) break; + if (find_fallback_mapping(data, locale, context.ch) != mapping) break; }
/* Go through families in the mapping, use first family that supports some of the input. */ @@ -2367,136 +2334,46 @@ HRESULT create_matching_font(IDWriteFontCollection *collection, const WCHAR *nam return hr; }
-static HRESULT fallback_map_characters_system(IDWriteFont *font, const WCHAR *text, UINT32 length, UINT32 *mapped_length) -{ - HRESULT hr = S_OK; - UINT32 i; - - for (i = 0; i < length; i++) { - UINT16 script = get_char_script(text[i]); - BOOL exists; - - if (script == Script_Unknown || script == Script_Common) { - ++*mapped_length; - continue; - } - - /* stop on first unsupported character */ - exists = FALSE; - hr = IDWriteFont_HasCharacter(font, text[i], &exists); - if (hr == S_OK && exists) - ++*mapped_length; - else - break; - } - - return hr; -} - -static HRESULT fallback_get_fallback_font(struct dwrite_fontfallback *fallback, const WCHAR *text, UINT32 length, - DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, UINT32 *mapped_length, - IDWriteFont **mapped_font) -{ - const struct fallback_mapping *mapping; - HRESULT hr; - UINT32 i; - - *mapped_font = NULL; - - mapping = find_fallback_mapping_system(fallback, text[0]); - if (!mapping) { - WARN("No mapping range for %#x.\n", text[0]); - return E_FAIL; - } - - /* 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], - weight, style, stretch, &IID_IDWriteFont, (void **)mapped_font); - if (hr == S_OK) { - TRACE("Created fallback font using family %s.\n", debugstr_w(mapping->families[i])); - break; - } - } - - if (!*mapped_font) { - WARN("Failed to create fallback font.\n"); - return E_FAIL; - } - - hr = fallback_map_characters_system(*mapped_font, text, length, mapped_length); - if (FAILED(hr)) - WARN("Mapping with fallback family %s failed, hr %#lx.\n", debugstr_w(mapping->families[i]), hr); - - if (!*mapped_length) { - IDWriteFont_Release(*mapped_font); - *mapped_font = NULL; - } - - return *mapped_length ? S_OK : E_FAIL; -} - static HRESULT WINAPI fontfallback_MapCharacters(IDWriteFontFallback1 *iface, IDWriteTextAnalysisSource *source, - UINT32 position, UINT32 length, IDWriteFontCollection *basecollection, const WCHAR *basefamily, - DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, UINT32 *mapped_length, - IDWriteFont **ret_font, FLOAT *scale) + UINT32 position, UINT32 length, IDWriteFontCollection *basecollection, const WCHAR *basefamily, + DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, UINT32 *mapped_length, + IDWriteFont **ret_font, float *scale) { struct dwrite_fontfallback *fallback = impl_from_IDWriteFontFallback1(iface); - WCHAR *buff = NULL; - const WCHAR *text; - HRESULT hr; + IDWriteFont3 *font;
- TRACE("%p, %p, %u, %u, %p, %s, %u, %u, %u, %p, %p, %p.\n", iface, source, position, length, basecollection, - debugstr_w(basefamily), weight, style, stretch, mapped_length, ret_font, scale); + TRACE("%p, %p, %u, %u, %p, %s, %u, %u, %u, %p, %p, %p.\n", iface, source, position, length, + basecollection, debugstr_w(basefamily), weight, style, stretch, mapped_length, ret_font, scale);
*mapped_length = 0; - *scale = 1.0f; *ret_font = NULL; + *scale = 1.0f;
if (!source) return E_INVALIDARG;
- if (length == 0) + if (!length) return S_OK;
if (!basecollection) - basecollection = (IDWriteFontCollection*)fallback->systemcollection; - - hr = get_text_source_ptr(source, position, length, &text, &buff); - if (FAILED(hr)) - goto done; - - if (basefamily && *basefamily) { - hr = create_matching_font(basecollection, basefamily, weight, style, stretch, &IID_IDWriteFont, (void **)ret_font); - if (FAILED(hr)) - goto done; - - hr = fallback_map_characters_system(*ret_font, text, length, mapped_length); - if (FAILED(hr)) - goto done; - } - - if (!*mapped_length) { - IDWriteFont *mapped_font; + basecollection = fallback->systemcollection;
- 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; + if (basefamily && *basefamily) + { + if (SUCCEEDED(create_matching_font(basecollection, basefamily, weight, style, stretch, + &IID_IDWriteFont, (void **)&font))) + { + if ((*mapped_length = fallback_font_get_supported_length(font, source, position, length))) + { + *ret_font = (IDWriteFont *)font; + *scale = 1.0f; + return S_OK; } - } - else { - if (*ret_font) - IDWriteFont_Release(*ret_font); - *ret_font = mapped_font; + IDWriteFont3_Release(font); } }
-done: - free(buff); - return hr; + return fallback_map_characters(fallback, source, position, length, weight, style, stretch, ret_font, mapped_length, scale); }
static HRESULT WINAPI fontfallback1_MapCharacters(IDWriteFontFallback1 *iface, IDWriteTextAnalysisSource *source, @@ -2519,26 +2396,6 @@ static const IDWriteFontFallback1Vtbl fontfallbackvtbl = fontfallback1_MapCharacters, };
-HRESULT create_system_fontfallback(IDWriteFactory7 *factory, IDWriteFontFallback1 **ret) -{ - struct dwrite_fontfallback *fallback; - - *ret = NULL; - - if (!(fallback = calloc(1, sizeof(*fallback)))) - return E_OUTOFMEMORY; - - fallback->IDWriteFontFallback1_iface.lpVtbl = &fontfallbackvtbl; - fallback->factory = factory; - fallback->mappings = (struct fallback_mapping *)fontfallback_neutral_data; - fallback->mappings_count = ARRAY_SIZE(fontfallback_neutral_data); - IDWriteFactory_GetSystemFontCollection((IDWriteFactory *)fallback->factory, &fallback->systemcollection, FALSE); - - *ret = &fallback->IDWriteFontFallback1_iface; - - return S_OK; -} - void release_system_fontfallback(IDWriteFontFallback1 *iface) { struct dwrite_fontfallback *fallback = impl_from_IDWriteFontFallback1(iface); @@ -2575,63 +2432,13 @@ static ULONG WINAPI customfontfallback_Release(IDWriteFontFallback1 *iface) return refcount; }
-static HRESULT WINAPI customfontfallback_MapCharacters(IDWriteFontFallback1 *iface, IDWriteTextAnalysisSource *source, - UINT32 position, UINT32 length, IDWriteFontCollection *basecollection, const WCHAR *basefamily, - DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, UINT32 *mapped_length, - IDWriteFont **ret_font, float *scale) -{ - struct dwrite_fontfallback *fallback = impl_from_IDWriteFontFallback1(iface); - IDWriteFont3 *font; - - TRACE("%p, %p, %u, %u, %p, %s, %u, %u, %u, %p, %p, %p.\n", iface, source, position, length, - basecollection, debugstr_w(basefamily), weight, style, stretch, mapped_length, ret_font, scale); - - *mapped_length = 0; - *ret_font = NULL; - *scale = 1.0f; - - if (!length) - return S_OK; - - if (!basecollection) - basecollection = fallback->systemcollection; - - if (basefamily && *basefamily) - { - if (SUCCEEDED(create_matching_font(basecollection, basefamily, weight, style, stretch, - &IID_IDWriteFont, (void **)&font))) - { - if ((*mapped_length = fallback_font_get_supported_length(font, source, position, length))) - { - *ret_font = (IDWriteFont *)font; - *scale = 1.0f; - return S_OK; - } - IDWriteFont3_Release(font); - } - } - - return fallback_map_characters(fallback, source, position, length, weight, style, stretch, ret_font, mapped_length, scale); -} - -static HRESULT WINAPI customfontfallback1_MapCharacters(IDWriteFontFallback1 *iface, IDWriteTextAnalysisSource *source, - UINT32 position, UINT32 length, IDWriteFontCollection *basecollection, const WCHAR *basefamily, - DWRITE_FONT_AXIS_VALUE const *axis_values, UINT32 values_count, UINT32 *mapped_length, FLOAT *scale, - IDWriteFontFace5 **ret_fontface) -{ - FIXME("%p, %p, %u, %u, %p, %s, %p, %u, %p, %p, %p.\n", iface, source, position, length, basecollection, - debugstr_w(basefamily), axis_values, values_count, mapped_length, scale, ret_fontface); - - return E_NOTIMPL; -} - static const IDWriteFontFallback1Vtbl customfontfallbackvtbl = { fontfallback_QueryInterface, customfontfallback_AddRef, customfontfallback_Release, - customfontfallback_MapCharacters, - customfontfallback1_MapCharacters, + fontfallback_MapCharacters, + fontfallback1_MapCharacters, };
static HRESULT WINAPI fontfallbackbuilder_QueryInterface(IDWriteFontFallbackBuilder *iface, REFIID riid, void **obj) @@ -2923,7 +2730,7 @@ static const IDWriteFontFallbackBuilderVtbl fontfallbackbuildervtbl = fontfallbackbuilder_CreateFontFallback, };
-HRESULT create_fontfallback_builder(IDWriteFactory7 *factory, IDWriteFontFallbackBuilder **ret) +static HRESULT create_fontfallback_builder_internal(IDWriteFactory7 *factory, struct dwrite_fontfallback_builder **ret) { struct dwrite_fontfallback_builder *builder;
@@ -2938,6 +2745,131 @@ HRESULT create_fontfallback_builder(IDWriteFactory7 *factory, IDWriteFontFallbac IDWriteFactory7_AddRef(builder->factory); list_init(&builder->data.locales);
- *ret = &builder->IDWriteFontFallbackBuilder_iface; + *ret = builder; + + return S_OK; +} + +HRESULT create_fontfallback_builder(IDWriteFactory7 *factory, IDWriteFontFallbackBuilder **ret) +{ + struct dwrite_fontfallback_builder *builder; + HRESULT hr; + + *ret = NULL; + + if (SUCCEEDED(hr = create_fontfallback_builder_internal(factory, &builder))) + *ret = &builder->IDWriteFontFallbackBuilder_iface; + + return hr; +} + +static void system_fallback_parse_ranges(const char *str, DWRITE_UNICODE_RANGE *ranges, + unsigned int max_count, unsigned int *ret) +{ + unsigned int count = 0; + char *end; + + while (*str && count < max_count) + { + ranges[count].first = ranges[count].last = strtoul(str, &end, 16); + if (*end == '-') + { + str = end + 1; + ranges[count].last = strtoul(str, &end, 16); + } + if (*end == ',') str = end + 1; + count++; + } + + *ret = count; +} + +static void system_fallback_parse_families(WCHAR *str, WCHAR **families, unsigned int max_count, + unsigned int *ret) +{ + unsigned int count = 0; + WCHAR *family, *ctx; + + family = wcstok_s(str, L",", &ctx); + while (family && count < max_count) + { + while (*family == ' ') family++; + families[count++] = family; + family = wcstok_s(NULL, L",", &ctx); + } + + *ret = count; +} + +static INIT_ONCE init_system_fallback_once = INIT_ONCE_STATIC_INIT; + +/* Particular factory instance used for initialization is not important, it won't be referenced by + created fallback data. */ +static BOOL WINAPI dwrite_system_fallback_initonce(INIT_ONCE *once, void *param, void **context) +{ + struct dwrite_fontfallback_builder *builder; + IDWriteFontFallbackBuilder *builder_iface; + unsigned int range_count, families_count; + IDWriteFactory7 *factory = param; + DWRITE_UNICODE_RANGE ranges[16]; + WCHAR *families[4], *str; + HRESULT hr; + size_t i; + + if (FAILED(create_fontfallback_builder_internal(factory, &builder))) return FALSE; + builder_iface = &builder->IDWriteFontFallbackBuilder_iface; + + for (i = 0; i < ARRAY_SIZE(system_fallback_config); ++i) + { + const struct fallback_description *entry = &system_fallback_config[i]; + + system_fallback_parse_ranges(entry->ranges, ranges, ARRAY_SIZE(ranges), &range_count); + + /* TODO: reuse the buffer */ + str = wcsdup(entry->families); + system_fallback_parse_families(str, families, ARRAY_SIZE(families), &families_count); + + if (FAILED(hr = IDWriteFontFallbackBuilder_AddMapping(builder_iface, ranges, range_count, + (const WCHAR **)families, families_count, NULL, entry->locale, NULL, 1.0f))) + { + WARN("Failed to add mapping, hr %#lx.\n", hr); + } + + free(str); + } + + hr = fallbackbuilder_init_fallback_data(builder, &system_fallback); + IDWriteFontFallbackBuilder_Release(builder_iface); + + return hr == S_OK; +} + +void release_system_fallback_data(void) +{ + release_fallback_data(&system_fallback); +} + +HRESULT create_system_fontfallback(IDWriteFactory7 *factory, IDWriteFontFallback1 **ret) +{ + struct dwrite_fontfallback *fallback; + + *ret = NULL; + + if (!InitOnceExecuteOnce(&init_system_fallback_once, dwrite_system_fallback_initonce, factory, NULL)) + { + WARN("Failed to initialize system fallback data.\n"); + return E_FAIL; + } + + if (!(fallback = calloc(1, sizeof(*fallback)))) + return E_OUTOFMEMORY; + + fallback->IDWriteFontFallback1_iface.lpVtbl = &fontfallbackvtbl; + fallback->factory = factory; + fallback->data.count = ~0u; + IDWriteFactory_GetSystemFontCollection((IDWriteFactory *)fallback->factory, &fallback->systemcollection, FALSE); + + *ret = &fallback->IDWriteFontFallback1_iface; + return S_OK; } diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index a46d5fe7d96..f274c8acb0f 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -323,6 +323,7 @@ extern HRESULT create_colorglyphenum(D2D1_POINT_2F origin, const DWRITE_GLYPH_RU extern BOOL lb_is_newline_char(WCHAR) DECLSPEC_HIDDEN; extern HRESULT create_system_fontfallback(IDWriteFactory7 *factory, IDWriteFontFallback1 **fallback) DECLSPEC_HIDDEN; extern void release_system_fontfallback(IDWriteFontFallback1 *fallback) DECLSPEC_HIDDEN; +extern void release_system_fallback_data(void) DECLSPEC_HIDDEN; extern HRESULT create_fontfallback_builder(IDWriteFactory7 *factory, IDWriteFontFallbackBuilder **builder) DECLSPEC_HIDDEN; extern HRESULT create_matching_font(IDWriteFontCollection *collection, const WCHAR *family, DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, REFIID riid, void **obj) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index 60fcb8cc71a..447b3d5176b 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -643,7 +643,7 @@ static HRESULT layout_itemize(struct dwrite_textlayout *layout)
static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout) { - IDWriteFontCollection *sys_collection; + IDWriteFontCollection *sys_collection, *collection; IDWriteFontFallback *fallback = NULL; struct layout_range *range; struct layout_run *r; @@ -675,12 +675,10 @@ static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout) continue;
range = get_layout_range_by_pos(layout, run->descr.textPosition); + collection = range->collection ? range->collection : sys_collection;
- if (run->sa.shapes == DWRITE_SCRIPT_SHAPES_NO_VISUAL) { - IDWriteFontCollection *collection; - - collection = range->collection ? range->collection : sys_collection; - + if (run->sa.shapes == DWRITE_SCRIPT_SHAPES_NO_VISUAL) + { if (FAILED(hr = create_matching_font(collection, range->fontfamily, range->weight, range->style, range->stretch, &IID_IDWriteFont, (void **)&font))) { @@ -702,8 +700,9 @@ static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout)
length = run->descr.stringLength;
- while (length) { - UINT32 mapped_length; + while (length) + { + UINT32 mapped_length = 0; FLOAT scale;
run = &r->u.regular; @@ -726,6 +725,21 @@ static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout) goto fatal; }
+ if (!mapped_length) + { + if (FAILED(create_matching_font(range->collection, range->fontfamily, range->weight, range->style, + range->stretch, &IID_IDWriteFont3, (void **)&font))) + { + if (FAILED(hr = create_matching_font(sys_collection, L"Tahoma", range->weight, range->style, + range->stretch, &IID_IDWriteFont3, (void **)&font))) + { + WARN("Failed to create last resort font, hr %#lx.\n", hr); + goto fatal; + } + } + mapped_length = run->descr.stringLength; + } + hr = IDWriteFont_CreateFontFace(font, &run->run.fontFace); IDWriteFont_Release(font); if (FAILED(hr)) { diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index c869ec3df54..8cc5d4dccf7 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -55,6 +55,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved) case DLL_PROCESS_DETACH: if (reserved) break; release_shared_factory(shared_factory); + release_system_fallback_data(); if (unixlib_handle) UNIX_CALL(process_detach, NULL); } return TRUE; diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c index bcc5303ab61..9d6dca91b39 100644 --- a/dlls/dwrite/tests/layout.c +++ b/dlls/dwrite/tests/layout.c @@ -2672,9 +2672,9 @@ if (0) { /* crashes on native */ count = 0; hr = IDWriteTextLayout1_GetClusterMetrics(layout1, clusters, 4, &count); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - ok(count == 3, "Unexpected cluster count %u.\n", count); + todo_wine ok(count == 3, "Unexpected cluster count %u.\n", count); ok(clusters[0].length == 1, "got %u\n", clusters[0].length); - ok(clusters[1].length == 2, "got %u\n", clusters[1].length); + todo_wine ok(clusters[1].length == 2, "got %u\n", clusters[1].length); ok(clusters[2].length == 1, "got %u\n", clusters[2].length);
/* pair kerning flag participates in itemization - combining characters @@ -4639,10 +4639,9 @@ 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, "Unexpected hr %#lx.\n", hr); + todo_wine ok(mappedlength == 1, "got %u\n", mappedlength); -} ok(scale == 1.0f, "got %f\n", scale); todo_wine ok(font != NULL, "got %p\n", font); @@ -4656,10 +4655,10 @@ 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, "Unexpected hr %#lx.\n", hr); + todo_wine ok(mappedlength == 3, "got %u\n", mappedlength); -} + ok(scale == 1.0f, "got %f\n", scale); todo_wine ok(font != NULL, "got %p\n", font); @@ -4673,10 +4672,9 @@ 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, "Unexpected hr %#lx.\n", hr); + todo_wine ok(mappedlength == 1, "got %u\n", mappedlength); -} ok(scale == 1.0f, "got %f\n", scale); todo_wine ok(font != NULL, "got %p\n", font); @@ -4689,10 +4687,9 @@ if (font) { 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, "Unexpected hr %#lx.\n", hr); + todo_wine ok(mappedlength == 1, "got %u\n", mappedlength); -} ok(scale == 1.0f, "got %f\n", scale); todo_wine ok(font != NULL, "got %p\n", font); @@ -4731,17 +4728,21 @@ if (font) { ok(hr == S_OK, "Unexpected hr %#lx.\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);
- exists = FALSE; - hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &strings, &exists); - ok(hr == S_OK && exists, "Unexpected hr %#lx, exists %d.\n", hr, exists); - hr = IDWriteLocalizedStrings_GetString(strings, 0, buffW, ARRAY_SIZE(buffW)); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine - ok(lstrcmpW(buffW, L"Tahoma"), "Unexpected string %s.\n", wine_dbgstr_w(buffW)); - IDWriteLocalizedStrings_Release(strings); - IDWriteFont_Release(font); + if (font) + { + exists = FALSE; + hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &strings, &exists); + ok(hr == S_OK && exists, "Unexpected hr %#lx, exists %d.\n", hr, exists); + hr = IDWriteLocalizedStrings_GetString(strings, 0, buffW, ARRAY_SIZE(buffW)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(lstrcmpW(buffW, L"Tahoma"), "Unexpected string %s.\n", wine_dbgstr_w(buffW)); + IDWriteLocalizedStrings_Release(strings); + IDWriteFont_Release(font); + }
IDWriteFontFallback_Release(fallback); IDWriteFactory2_Release(factory2); @@ -4802,14 +4803,17 @@ static void test_system_fallback(void)
for (i = 0; i < ARRAY_SIZE(tests); ++i) { + font = NULL; + g_source = tests[i].text; hr = IDWriteFontFallback_MapCharacters(fallback, &analysissource, 0, 1, NULL, NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, &length, &font, &scale); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); if (hr != S_OK) continue; + todo_wine ok(length == 1, "Unexpected length %u\n", length); ok(scale == 1.0f, "got %f\n", scale); + if (!font) continue;
get_font_name(font, name, ARRAY_SIZE(name)); todo_wine @@ -5054,21 +5058,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 %#lx.\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 %#lx.\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);
@@ -5367,6 +5367,7 @@ static void test_SetUnderline(void) count = 0; hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, ARRAY_SIZE(clusters), &count); ok(hr == S_OK, "Failed to get cluster metrics, hr %#lx.\n", hr); + todo_wine ok(count == 3, "Unexpected cluster count %u.\n", count);
range.startPosition = 0; @@ -5377,6 +5378,7 @@ static void test_SetUnderline(void) count = 0; hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, ARRAY_SIZE(clusters), &count); ok(hr == S_OK, "Failed to get cluster metrics, hr %#lx.\n", hr); + todo_wine ok(count == 3, "Unexpected cluster count %u.\n", count);
flush_sequence(sequences, RENDERER_ID);