From 2d289681ebf8dd257f60add756ee3b21719a5e69 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Fri, 24 Jan 2020 11:17:35 +0300 Subject: [PATCH] dwrite: Implement GetFamilyNames() for fontfaces. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/dwrite/dwrite_private.h | 1 + dlls/dwrite/font.c | 56 +++++++++++++++++++----------------- dlls/dwrite/tests/font.c | 30 +++++++++++++++++-- 3 files changed, 58 insertions(+), 29 deletions(-) diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 58b5e9a0e04..6299da25e36 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -231,6 +231,7 @@ struct dwrite_fontface FONTSIGNATURE fontsig; UINT32 glyph_image_formats; + IDWriteLocalizedStrings *family_names; IDWriteLocalizedStrings *names; struct scriptshaping_cache *shaping_cache; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index df1bc5adcb2..9bec665d19d 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -83,6 +83,7 @@ struct dwrite_font_data DWRITE_FONT_METRICS1 metrics; IDWriteLocalizedStrings *info_strings[DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME+1]; + IDWriteLocalizedStrings *family_names; IDWriteLocalizedStrings *names; /* data needed to create fontface instance */ @@ -437,6 +438,9 @@ static void release_font_data(struct dwrite_font_data *data) if (data->names) IDWriteLocalizedStrings_Release(data->names); + if (data->family_names) + IDWriteLocalizedStrings_Release(data->family_names); + IDWriteFontFile_Release(data->file); heap_free(data->facename); heap_free(data); @@ -541,6 +545,8 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface) heap_free(fontface->files); if (fontface->names) IDWriteLocalizedStrings_Release(fontface->names); + if (fontface->family_names) + IDWriteLocalizedStrings_Release(fontface->family_names); for (i = 0; i < ARRAY_SIZE(fontface->glyphs); i++) heap_free(fontface->glyphs[i]); @@ -1254,9 +1260,11 @@ static DWRITE_FONT_STYLE WINAPI dwritefontface3_GetStyle(IDWriteFontFace5 *iface static HRESULT WINAPI dwritefontface3_GetFamilyNames(IDWriteFontFace5 *iface, IDWriteLocalizedStrings **names) { - FIXME("%p, %p: stub\n", iface, names); + struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface); - return E_NOTIMPL; + TRACE("%p, %p.\n", iface, names); + + return clone_localizedstrings(fontface->family_names, names); } static HRESULT WINAPI dwritefontface3_GetFaceNames(IDWriteFontFace5 *iface, IDWriteLocalizedStrings **names) @@ -3622,8 +3630,7 @@ static BOOL font_apply_differentiation_rules(struct dwrite_font_data *font, WCHA return TRUE; } -static HRESULT init_font_data(const struct fontface_desc *desc, IDWriteLocalizedStrings **family_name, - struct dwrite_font_data **ret) +static HRESULT init_font_data(const struct fontface_desc *desc, struct dwrite_font_data **ret) { struct file_stream_desc stream_desc; struct dwrite_font_props props; @@ -3654,7 +3661,7 @@ static HRESULT init_font_data(const struct fontface_desc *desc, IDWriteLocalized opentype_get_font_facename(&stream_desc, props.lf.lfFaceName, &data->names); /* get family name from font file */ - hr = opentype_get_font_familyname(&stream_desc, family_name); + hr = opentype_get_font_familyname(&stream_desc, &data->family_names); if (FAILED(hr)) { WARN("unable to get family name from font\n"); release_font_data(data); @@ -3669,10 +3676,10 @@ static HRESULT init_font_data(const struct fontface_desc *desc, IDWriteLocalized data->lf = props.lf; data->flags = props.flags; - fontstrings_get_en_string(*family_name, familyW, ARRAY_SIZE(familyW)); + fontstrings_get_en_string(data->family_names, familyW, ARRAY_SIZE(familyW)); fontstrings_get_en_string(data->names, faceW, ARRAY_SIZE(faceW)); if (font_apply_differentiation_rules(data, familyW, faceW)) { - set_en_localizedstring(*family_name, familyW); + set_en_localizedstring(data->family_names, familyW); set_en_localizedstring(data->names, faceW); } @@ -3703,6 +3710,7 @@ static HRESULT init_font_data_from_font(const struct dwrite_font_data *src, DWRI memset(data->info_strings, 0, sizeof(data->info_strings)); data->names = NULL; IDWriteFontFile_AddRef(data->file); + IDWriteLocalizedStrings_AddRef(data->family_names); create_localizedstrings(&data->names); add_localizedstring(data->names, enusW, facenameW); @@ -4033,8 +4041,8 @@ HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerat fileenum->file = file; list_add_tail(&scannedfiles, &fileenum->entry); - for (i = 0; i < face_count; i++) { - IDWriteLocalizedStrings *family_name = NULL; + for (i = 0; i < face_count; ++i) + { struct dwrite_font_data *font_data; struct fontface_desc desc; WCHAR familyW[255]; @@ -4049,20 +4057,21 @@ HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerat desc.simulations = DWRITE_FONT_SIMULATIONS_NONE; desc.font_data = NULL; - /* alloc and init new font data structure */ - hr = init_font_data(&desc, &family_name, &font_data); - if (FAILED(hr)) { + /* Allocate an initialize new font data structure. */ + hr = init_font_data(&desc, &font_data); + if (FAILED(hr)) + { /* move to next one */ hr = S_OK; continue; } - fontstrings_get_en_string(family_name, familyW, ARRAY_SIZE(familyW)); + fontstrings_get_en_string(font_data->family_names, familyW, ARRAY_SIZE(familyW)); /* ignore dot named faces */ - if (familyW[0] == '.') { + if (familyW[0] == '.') + { WARN("Ignoring face %s\n", debugstr_w(familyW)); - IDWriteLocalizedStrings_Release(family_name); release_font_data(font_data); continue; } @@ -4074,7 +4083,7 @@ HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerat struct dwrite_fontfamily_data *family_data; /* create and init new family */ - hr = init_fontfamily_data(family_name, &family_data); + hr = init_fontfamily_data(font_data->family_names, &family_data); if (hr == S_OK) { /* add font to family, family - to collection */ hr = fontfamily_add_font(family_data, font_data); @@ -4086,8 +4095,6 @@ HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerat } } - IDWriteLocalizedStrings_Release(family_name); - if (FAILED(hr)) break; } @@ -4394,12 +4401,10 @@ static HRESULT eudc_collection_add_family(IDWriteFactory7 *factory, struct dwrit desc.simulations = DWRITE_FONT_SIMULATIONS_NONE; desc.font_data = NULL; - hr = init_font_data(&desc, &names, &font_data); + hr = init_font_data(&desc, &font_data); if (FAILED(hr)) continue; - IDWriteLocalizedStrings_Release(names); - /* add font to family */ hr = fontfamily_add_font(family_data, font_data); if (hr != S_OK) @@ -4693,16 +4698,12 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li } else { - IDWriteLocalizedStrings *names; - - hr = init_font_data(desc, &names, &font_data); + hr = init_font_data(desc, &font_data); if (FAILED(hr)) { IDWriteFontFace5_Release(&fontface->IDWriteFontFace5_iface); return hr; } - - IDWriteLocalizedStrings_Release(names); } fontface->weight = font_data->weight; @@ -4715,6 +4716,9 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li fontface->names = font_data->names; if (fontface->names) IDWriteLocalizedStrings_AddRef(fontface->names); + fontface->family_names = font_data->family_names; + if (fontface->family_names) + IDWriteLocalizedStrings_AddRef(fontface->family_names); release_font_data(font_data); fontface->cached = factory_cache_fontface(fontface->factory, cached_list, &fontface->IDWriteFontFace5_iface); diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 6a2acd7cd88..cb5f7631f5c 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -1677,9 +1677,11 @@ if (0) /* crashes on native */ static void test_GetFamilyNames(void) { - IDWriteFontFamily *family; IDWriteLocalizedStrings *names, *names2; + IDWriteFontFace3 *fontface3; IDWriteGdiInterop *interop; + IDWriteFontFamily *family; + IDWriteFontFace *fontface; IDWriteFactory *factory; IDWriteFont *font; LOGFONTW logfont; @@ -1761,11 +1763,33 @@ static void test_GetFamilyNames(void) buffer[0] = 0; hr = IDWriteLocalizedStrings_GetString(names, 0, buffer, len+1); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(buffer[0] != 0, "got %x\n", buffer[0]); + ok(hr == S_OK, "Failed to get a string, hr %#x.\n", hr); + ok(!lstrcmpW(buffer, L"Tahoma"), "Unexpected family name %s.\n", wine_dbgstr_w(buffer)); IDWriteLocalizedStrings_Release(names); + /* GetFamilyNames() on font face */ + hr = IDWriteFont_CreateFontFace(font, &fontface); + ok(hr == S_OK, "Failed to create fontface, hr %#x.\n", hr); + + if (SUCCEEDED(IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace3, (void **)&fontface3))) + { + hr = IDWriteFontFace3_GetFamilyNames(fontface3, &names); + ok(hr == S_OK, "Failed to get family names, hr %#x.\n", hr); + + buffer[0] = 0; + hr = IDWriteLocalizedStrings_GetString(names, 0, buffer, len+1); + ok(hr == S_OK, "Failed to get a string, hr %#x.\n", hr); + ok(!lstrcmpW(buffer, L"Tahoma"), "Unexpected family name %s.\n", wine_dbgstr_w(buffer)); + + IDWriteLocalizedStrings_Release(names); + IDWriteFontFace3_Release(fontface3); + } + else + win_skip("IDWriteFontFace3::GetFamilyNames() is not supported.\n"); + + IDWriteFontFace_Release(fontface); + IDWriteFontFamily_Release(family); IDWriteFont_Release(font); IDWriteGdiInterop_Release(interop);