Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 4 ++- dlls/dwrite/font.c | 57 ++++++++++++++++++++---------------- dlls/dwrite/main.c | 2 +- dlls/dwrite/tests/font.c | 30 ++++++++++++++++++- 4 files changed, 65 insertions(+), 28 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index cf3f13b1c6..58b5e9a0e0 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -231,6 +231,8 @@ struct dwrite_fontface FONTSIGNATURE fontsig; UINT32 glyph_image_formats;
+ IDWriteLocalizedStrings *names; + struct scriptshaping_cache *shaping_cache;
LOGFONTW lf; @@ -245,7 +247,7 @@ extern HRESULT create_trimmingsign(IDWriteFactory7 *factory, IDWriteTextFormat * extern HRESULT create_typography(IDWriteTypography**) DECLSPEC_HIDDEN; extern HRESULT create_localizedstrings(IDWriteLocalizedStrings**) DECLSPEC_HIDDEN; extern HRESULT add_localizedstring(IDWriteLocalizedStrings*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN; -extern HRESULT clone_localizedstring(IDWriteLocalizedStrings *iface, IDWriteLocalizedStrings **strings) DECLSPEC_HIDDEN; +extern HRESULT clone_localizedstrings(IDWriteLocalizedStrings *iface, IDWriteLocalizedStrings **strings) DECLSPEC_HIDDEN; extern void set_en_localizedstring(IDWriteLocalizedStrings*,const WCHAR*) DECLSPEC_HIDDEN; extern void sort_localizedstrings(IDWriteLocalizedStrings*) DECLSPEC_HIDDEN; extern HRESULT get_system_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection1 **collection) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 4e08b2f632..df1bc5adcb 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -539,6 +539,8 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface) if (fontface->stream) IDWriteFontFileStream_Release(fontface->stream); heap_free(fontface->files); + if (fontface->names) + IDWriteLocalizedStrings_Release(fontface->names);
for (i = 0; i < ARRAY_SIZE(fontface->glyphs); i++) heap_free(fontface->glyphs[i]); @@ -1259,9 +1261,11 @@ static HRESULT WINAPI dwritefontface3_GetFamilyNames(IDWriteFontFace5 *iface, ID
static HRESULT WINAPI dwritefontface3_GetFaceNames(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->names, names); }
static HRESULT WINAPI dwritefontface3_GetInformationalStrings(IDWriteFontFace5 *iface, @@ -1616,9 +1620,11 @@ static BOOL WINAPI dwritefont_IsSymbolFont(IDWriteFont3 *iface)
static HRESULT WINAPI dwritefont_GetFaceNames(IDWriteFont3 *iface, IDWriteLocalizedStrings **names) { - struct dwrite_font *This = impl_from_IDWriteFont3(iface); - TRACE("(%p)->(%p)\n", This, names); - return clone_localizedstring(This->data->names, names); + struct dwrite_font *font = impl_from_IDWriteFont3(iface); + + TRACE("%p, %p.\n", iface, names); + + return clone_localizedstrings(font->data->names, names); }
static HRESULT WINAPI dwritefont_GetInformationalStrings(IDWriteFont3 *iface, @@ -1663,7 +1669,7 @@ static HRESULT WINAPI dwritefont_GetInformationalStrings(IDWriteFont3 *iface, IDWriteFontFace5_Release(fontface); }
- hr = clone_localizedstring(data->info_strings[stringid], strings); + hr = clone_localizedstrings(data->info_strings[stringid], strings); if (FAILED(hr)) return hr;
@@ -2166,7 +2172,10 @@ static HRESULT WINAPI dwritefontfamily_GetFont(IDWriteFontFamily2 *iface, UINT32 static HRESULT WINAPI dwritefontfamily_GetFamilyNames(IDWriteFontFamily2 *iface, IDWriteLocalizedStrings **names) { struct dwrite_fontfamily *family = impl_from_IDWriteFontFamily2(iface); - return clone_localizedstring(family->data->familyname, names); + + TRACE("%p, %p.\n", iface, names); + + return clone_localizedstrings(family->data->familyname, names); }
static BOOL is_better_font_match(const struct dwrite_font_propvec *next, const struct dwrite_font_propvec *cur, @@ -4614,6 +4623,7 @@ HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_ke HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_list, IDWriteFontFace5 **ret) { struct file_stream_desc stream_desc; + struct dwrite_font_data *font_data; struct dwrite_fontface *fontface; HRESULT hr; int i; @@ -4678,38 +4688,35 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li */ if (desc->font_data) { - fontface->weight = desc->font_data->weight; - fontface->style = desc->font_data->style; - fontface->stretch = desc->font_data->stretch; - fontface->panose = desc->font_data->panose; - fontface->fontsig = desc->font_data->fontsig; - fontface->lf = desc->font_data->lf; - fontface->flags |= desc->font_data->flags & (FONT_IS_SYMBOL | FONT_IS_MONOSPACED | FONT_IS_COLORED); + font_data = desc->font_data; + addref_font_data(font_data); } else { IDWriteLocalizedStrings *names; - struct dwrite_font_data *data;
- hr = init_font_data(desc, &names, &data); + hr = init_font_data(desc, &names, &font_data); if (FAILED(hr)) { IDWriteFontFace5_Release(&fontface->IDWriteFontFace5_iface); return hr; }
- fontface->weight = data->weight; - fontface->style = data->style; - fontface->stretch = data->stretch; - fontface->panose = data->panose; - fontface->fontsig = data->fontsig; - fontface->lf = data->lf; - fontface->flags |= data->flags & (FONT_IS_SYMBOL | FONT_IS_MONOSPACED | FONT_IS_COLORED); - IDWriteLocalizedStrings_Release(names); - release_font_data(data); }
+ fontface->weight = font_data->weight; + fontface->style = font_data->style; + fontface->stretch = font_data->stretch; + fontface->panose = font_data->panose; + fontface->fontsig = font_data->fontsig; + fontface->lf = font_data->lf; + fontface->flags |= font_data->flags & (FONT_IS_SYMBOL | FONT_IS_MONOSPACED | FONT_IS_COLORED); + fontface->names = font_data->names; + if (fontface->names) + IDWriteLocalizedStrings_AddRef(fontface->names); + release_font_data(font_data); + fontface->cached = factory_cache_fontface(fontface->factory, cached_list, &fontface->IDWriteFontFace5_iface);
*ret = &fontface->IDWriteFontFace5_iface; diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 317a6cedaf..283cccb76c 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -468,7 +468,7 @@ HRESULT add_localizedstring(IDWriteLocalizedStrings *iface, const WCHAR *locale, return S_OK; }
-HRESULT clone_localizedstring(IDWriteLocalizedStrings *iface, IDWriteLocalizedStrings **ret) +HRESULT clone_localizedstrings(IDWriteLocalizedStrings *iface, IDWriteLocalizedStrings **ret) { struct localizedstrings *strings, *strings_clone; size_t i; diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index ac70a4c137..6a2acd7cd8 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -4410,8 +4410,10 @@ static void test_GetFaceNames(void) static const WCHAR obliqueW[] = {'O','b','l','i','q','u','e',0}; static const WCHAR enus2W[] = {'e','n','-','U','s',0}; static const WCHAR enusW[] = {'e','n','-','u','s',0}; - IDWriteLocalizedStrings *strings, *strings2; + IDWriteLocalizedStrings *strings, *strings2, *strings3; + IDWriteFontFace3 *fontface3; IDWriteGdiInterop *interop; + IDWriteFontFace *fontface; IDWriteFactory *factory; UINT32 count, index; IDWriteFont *font; @@ -4470,6 +4472,32 @@ static void test_GetFaceNames(void) ok(!lstrcmpW(buffW, obliqueW), "got %s\n", wine_dbgstr_w(buffW)); IDWriteLocalizedStrings_Release(strings);
+ hr = IDWriteFont_CreateFontFace(font, &fontface); + ok(hr == S_OK, "Failed to create a font face, hr %#x.\n", hr); + + if (SUCCEEDED(IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace3, (void **)&fontface3))) + { + hr = IDWriteFontFace3_GetFaceNames(fontface3, &strings2); + ok(hr == S_OK, "Failed to get face names, hr %#x.\n", hr); + + hr = IDWriteFontFace3_GetFaceNames(fontface3, &strings3); + ok(hr == S_OK, "Failed to get face names, hr %#x.\n", hr); + ok(strings2 != strings3, "Unexpected instance.\n"); + IDWriteLocalizedStrings_Release(strings3); + + buffW[0] = 0; + hr = IDWriteLocalizedStrings_GetString(strings2, 0, buffW, ARRAY_SIZE(buffW)); + ok(hr == S_OK, "Failed to get a string, hr %#x.\n", hr); + ok(!lstrcmpW(buffW, obliqueW), "Unexpected name %s.\n", wine_dbgstr_w(buffW)); + IDWriteLocalizedStrings_Release(strings2); + + IDWriteFontFace3_Release(fontface3); + } + else + win_skip("GetFaceNames() is not supported.\n"); + + IDWriteFontFace_Release(fontface); + IDWriteFont_Release(font); IDWriteGdiInterop_Release(interop); ref = IDWriteFactory_Release(factory);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- 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 58b5e9a0e0..6299da25e3 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 df1bc5adcb..9bec665d19 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 6a2acd7cd8..cb5f7631f5 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);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 5 +++-- dlls/dwrite/font.c | 40 ++++++++++++++---------------------- dlls/dwrite/opentype.c | 19 +++++++++++++---- 3 files changed, 33 insertions(+), 31 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 6299da25e3..c70326c865 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -324,7 +324,7 @@ extern const void* get_fontface_table(IDWriteFontFace5 *fontface, UINT32 tag, struct dwrite_fonttable *table) DECLSPEC_HIDDEN;
extern HRESULT opentype_analyze_font(IDWriteFontFileStream*,BOOL*,DWRITE_FONT_FILE_TYPE*,DWRITE_FONT_FACE_TYPE*,UINT32*) DECLSPEC_HIDDEN; -extern HRESULT opentype_try_get_font_table(struct file_stream_desc *stream_desc, UINT32 tag, const void **data, +extern HRESULT opentype_try_get_font_table(const struct file_stream_desc *stream_desc, UINT32 tag, const void **data, void **context, UINT32 *size, BOOL *exists) DECLSPEC_HIDDEN; extern HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_fonttable *table, unsigned int max_count, DWRITE_UNICODE_RANGE *ranges, unsigned int *count) DECLSPEC_HIDDEN; @@ -332,7 +332,8 @@ extern void opentype_get_font_properties(struct file_stream_desc*,struct dwrite_ extern void opentype_get_font_metrics(struct file_stream_desc*,DWRITE_FONT_METRICS1*,DWRITE_CARET_METRICS*) DECLSPEC_HIDDEN; extern void opentype_get_font_typo_metrics(struct file_stream_desc *stream_desc, unsigned int *ascent, unsigned int *descent) DECLSPEC_HIDDEN; -extern HRESULT opentype_get_font_info_strings(const void*,DWRITE_INFORMATIONAL_STRING_ID,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN; +extern HRESULT opentype_get_font_info_strings(const struct file_stream_desc *stream_desc, + DWRITE_INFORMATIONAL_STRING_ID id, IDWriteLocalizedStrings **strings) DECLSPEC_HIDDEN; extern HRESULT opentype_get_font_familyname(struct file_stream_desc*,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN; extern HRESULT opentype_get_font_facename(struct file_stream_desc*,WCHAR*,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN; extern HRESULT opentype_get_typographic_features(IDWriteFontFace*,UINT32,UINT32,UINT32,UINT32*,DWRITE_FONT_FEATURE_TAG*) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 9bec665d19..a81433b242 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -1640,7 +1640,7 @@ static HRESULT WINAPI dwritefont_GetInformationalStrings(IDWriteFont3 *iface, { struct dwrite_font *font = impl_from_IDWriteFont3(iface); struct dwrite_font_data *data = font->data; - HRESULT hr; + HRESULT hr = S_OK;
TRACE("%p, %d, %p, %p.\n", iface, stringid, strings, exists);
@@ -1652,37 +1652,27 @@ static HRESULT WINAPI dwritefont_GetInformationalStrings(IDWriteFont3 *iface,
if (!data->info_strings[stringid]) { - IDWriteFontFace5 *fontface; - const void *table_data; - BOOL table_exists; - void *context; - UINT32 size; + struct file_stream_desc stream_desc;
- hr = get_fontface_from_font(font, &fontface); - if (FAILED(hr)) - return hr; + if (SUCCEEDED(hr = get_filestream_from_file(data->file, &stream_desc.stream))) + { + stream_desc.face_type = data->face_type; + stream_desc.face_index = data->face_index;
- table_exists = FALSE; - hr = IDWriteFontFace5_TryGetFontTable(fontface, MS_NAME_TAG, &table_data, &size, &context, &table_exists); - if (FAILED(hr) || !table_exists) - WARN("no NAME table found.\n"); + hr = opentype_get_font_info_strings(&stream_desc, stringid, &data->info_strings[stringid]);
- if (table_exists) - { - hr = opentype_get_font_info_strings(table_data, stringid, &data->info_strings[stringid]); - IDWriteFontFace5_ReleaseFontTable(fontface, context); - if (FAILED(hr) || !data->info_strings[stringid]) - return hr; + IDWriteFontFileStream_Release(stream_desc.stream); } - IDWriteFontFace5_Release(fontface); }
- hr = clone_localizedstrings(data->info_strings[stringid], strings); - if (FAILED(hr)) - return hr; + if (SUCCEEDED(hr) && data->info_strings[stringid]) + { + hr = clone_localizedstrings(data->info_strings[stringid], strings); + if (SUCCEEDED(hr)) + *exists = TRUE; + }
- *exists = TRUE; - return S_OK; + return hr; }
static DWRITE_FONT_SIMULATIONS WINAPI dwritefont_GetSimulations(IDWriteFont3 *iface) diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index db277ae905..1e71ce8614 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -1380,7 +1380,7 @@ HRESULT opentype_analyze_font(IDWriteFontFileStream *stream, BOOL *supported, DW return S_OK; }
-HRESULT opentype_try_get_font_table(struct file_stream_desc *stream_desc, UINT32 tag, const void **table_data, +HRESULT opentype_try_get_font_table(const struct file_stream_desc *stream_desc, UINT32 tag, const void **table_data, void **table_context, UINT32 *table_size, BOOL *found) { void *table_directory_context, *sfnt_context; @@ -1448,7 +1448,7 @@ HRESULT opentype_try_get_font_table(struct file_stream_desc *stream_desc, UINT32 return hr; }
-static HRESULT opentype_get_font_table(struct file_stream_desc *stream_desc, UINT32 tag, +static HRESULT opentype_get_font_table(const struct file_stream_desc *stream_desc, UINT32 tag, struct dwrite_fonttable *table) { return opentype_try_get_font_table(stream_desc, tag, (const void **)&table->data, &table->context, &table->size, &table->exists); @@ -2109,9 +2109,20 @@ static HRESULT opentype_get_font_strings_from_id(const void *table_data, enum OP }
/* Provides a conversion from DWRITE to OpenType name ids, input id should be valid, it's not checked. */ -HRESULT opentype_get_font_info_strings(const void *table_data, DWRITE_INFORMATIONAL_STRING_ID id, IDWriteLocalizedStrings **strings) +HRESULT opentype_get_font_info_strings(const struct file_stream_desc *stream_desc, DWRITE_INFORMATIONAL_STRING_ID id, + IDWriteLocalizedStrings **strings) { - return opentype_get_font_strings_from_id(table_data, dwriteid_to_opentypeid[id], strings); + struct dwrite_fonttable name; + HRESULT hr; + + opentype_get_font_table(stream_desc, MS_NAME_TAG, &name); + + hr = opentype_get_font_strings_from_id(name.data, dwriteid_to_opentypeid[id], strings); + + if (name.context) + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, name.context); + + return hr; }
/* FamilyName locating order is WWS Family Name -> Preferred Family Name -> Family Name. If font claims to
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 1 + dlls/dwrite/font.c | 95 +++++++++++++++++++++++------------- dlls/dwrite/tests/font.c | 20 ++++++++ 3 files changed, 83 insertions(+), 33 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index c70326c865..eea3cbabbe 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 *info_strings[DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME+1]; IDWriteLocalizedStrings *family_names; IDWriteLocalizedStrings *names;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index a81433b242..2732693b4c 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -431,7 +431,8 @@ static void release_font_data(struct dwrite_font_data *data) if (InterlockedDecrement(&data->ref) > 0) return;
- for (i = DWRITE_INFORMATIONAL_STRING_NONE; i < ARRAY_SIZE(data->info_strings); i++) { + for (i = 0; i < ARRAY_SIZE(data->info_strings); ++i) + { if (data->info_strings[i]) IDWriteLocalizedStrings_Release(data->info_strings[i]); } @@ -547,6 +548,11 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface) IDWriteLocalizedStrings_Release(fontface->names); if (fontface->family_names) IDWriteLocalizedStrings_Release(fontface->family_names); + for (i = 0; i < ARRAY_SIZE(fontface->info_strings); ++i) + { + if (fontface->info_strings[i]) + IDWriteLocalizedStrings_Release(fontface->info_strings[i]); + }
for (i = 0; i < ARRAY_SIZE(fontface->glyphs); i++) heap_free(fontface->glyphs[i]); @@ -1276,12 +1282,53 @@ static HRESULT WINAPI dwritefontface3_GetFaceNames(IDWriteFontFace5 *iface, IDWr return clone_localizedstrings(fontface->names, names); }
+static HRESULT get_font_info_strings(const struct file_stream_desc *stream_desc, IDWriteFontFile *file, + DWRITE_INFORMATIONAL_STRING_ID stringid, IDWriteLocalizedStrings **strings_cache, + IDWriteLocalizedStrings **ret, BOOL *exists) +{ + HRESULT hr = S_OK; + + *exists = FALSE; + *ret = NULL; + + if (stringid > DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME || stringid == DWRITE_INFORMATIONAL_STRING_NONE) + return S_OK; + + if (!strings_cache[stringid]) + { + struct file_stream_desc desc = *stream_desc; + + if (!desc.stream) + hr = get_filestream_from_file(file, &desc.stream); + if (SUCCEEDED(hr)) + hr = opentype_get_font_info_strings(&desc, stringid, &strings_cache[stringid]); + + if (!stream_desc->stream && desc.stream) + IDWriteFontFileStream_Release(desc.stream); + } + + if (SUCCEEDED(hr) && strings_cache[stringid]) + { + hr = clone_localizedstrings(strings_cache[stringid], ret); + if (SUCCEEDED(hr)) + *exists = TRUE; + } + + return hr; +} + static HRESULT WINAPI dwritefontface3_GetInformationalStrings(IDWriteFontFace5 *iface, DWRITE_INFORMATIONAL_STRING_ID stringid, IDWriteLocalizedStrings **strings, BOOL *exists) { - FIXME("%p, %u, %p, %p: stub\n", iface, stringid, strings, exists); + struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface); + struct file_stream_desc stream_desc;
- return E_NOTIMPL; + TRACE("%p, %u, %p, %p.\n", iface, stringid, strings, exists); + + stream_desc.stream = fontface->stream; + stream_desc.face_index = fontface->index; + stream_desc.face_type = fontface->type; + return get_font_info_strings(&stream_desc, NULL, stringid, fontface->info_strings, strings, exists); }
static BOOL WINAPI dwritefontface3_HasCharacter(IDWriteFontFace5 *iface, UINT32 ch) @@ -1640,39 +1687,15 @@ static HRESULT WINAPI dwritefont_GetInformationalStrings(IDWriteFont3 *iface, { struct dwrite_font *font = impl_from_IDWriteFont3(iface); struct dwrite_font_data *data = font->data; - HRESULT hr = S_OK; + struct file_stream_desc stream_desc;
TRACE("%p, %d, %p, %p.\n", iface, stringid, strings, exists);
- *exists = FALSE; - *strings = NULL; - - if (stringid > DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME || stringid == DWRITE_INFORMATIONAL_STRING_NONE) - return S_OK; - - if (!data->info_strings[stringid]) - { - struct file_stream_desc stream_desc; - - if (SUCCEEDED(hr = get_filestream_from_file(data->file, &stream_desc.stream))) - { - stream_desc.face_type = data->face_type; - stream_desc.face_index = data->face_index; - - hr = opentype_get_font_info_strings(&stream_desc, stringid, &data->info_strings[stringid]); - - IDWriteFontFileStream_Release(stream_desc.stream); - } - } - - if (SUCCEEDED(hr) && data->info_strings[stringid]) - { - hr = clone_localizedstrings(data->info_strings[stringid], strings); - if (SUCCEEDED(hr)) - *exists = TRUE; - } - - return hr; + /* Stream will be created if necessary. */ + stream_desc.stream = NULL; + stream_desc.face_index = data->face_index; + stream_desc.face_type = data->face_type; + return get_font_info_strings(&stream_desc, data->file, stringid, data->info_strings, strings, exists); }
static DWRITE_FONT_SIMULATIONS WINAPI dwritefont_GetSimulations(IDWriteFont3 *iface) @@ -4709,6 +4732,12 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li fontface->family_names = font_data->family_names; if (fontface->family_names) IDWriteLocalizedStrings_AddRef(fontface->family_names); + memcpy(fontface->info_strings, font_data->info_strings, sizeof(fontface->info_strings)); + for (i = 0; i < ARRAY_SIZE(fontface->info_strings); ++i) + { + if (fontface->info_strings[i]) + IDWriteLocalizedStrings_AddRef(fontface->info_strings[i]); + } 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 cb5f7631f5..19c6928dd7 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -4026,6 +4026,8 @@ static void test_GetInformationalStrings(void) { IDWriteLocalizedStrings *strings, *strings2; IDWriteFontCollection *collection; + IDWriteFontFace3 *fontface3; + IDWriteFontFace *fontface; IDWriteFontFamily *family; IDWriteFactory *factory; IDWriteFont *font; @@ -4072,6 +4074,24 @@ static void test_GetInformationalStrings(void)
IDWriteLocalizedStrings_Release(strings); IDWriteLocalizedStrings_Release(strings2); + + hr = IDWriteFont_CreateFontFace(font, &fontface); + ok(hr == S_OK, "Failed to create fontface, hr %#x.\n", hr); + + if (SUCCEEDED(hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace3, (void **)&fontface3))) + { + hr = IDWriteFontFace3_GetInformationalStrings(fontface3, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, + &strings, &exists); + ok(hr == S_OK, "Failed to get info strings, hr %#x.\n", hr); + IDWriteLocalizedStrings_Release(strings); + + IDWriteFontFace3_Release(fontface3); + } + else + win_skip("IDWriteFontFace3::GetInformationalStrings() is not supported.\n"); + + IDWriteFontFace_Release(fontface); + IDWriteFont_Release(font); IDWriteFontFamily_Release(family); IDWriteFontCollection_Release(collection);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 2 +- dlls/dwrite/font.c | 9 ++++++--- dlls/dwrite/opentype.c | 5 +++-- 3 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index eea3cbabbe..6adba28280 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -231,7 +231,7 @@ struct dwrite_fontface FONTSIGNATURE fontsig; UINT32 glyph_image_formats;
- IDWriteLocalizedStrings *info_strings[DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME+1]; + IDWriteLocalizedStrings *info_strings[DWRITE_INFORMATIONAL_STRING_WEIGHT_STRETCH_STYLE_FAMILY_NAME + 1]; IDWriteLocalizedStrings *family_names; IDWriteLocalizedStrings *names;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 2732693b4c..8bcbe11fcb 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -82,7 +82,7 @@ struct dwrite_font_data struct dwrite_font_propvec propvec;
DWRITE_FONT_METRICS1 metrics; - IDWriteLocalizedStrings *info_strings[DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME+1]; + IDWriteLocalizedStrings *info_strings[DWRITE_INFORMATIONAL_STRING_WEIGHT_STRETCH_STYLE_FAMILY_NAME + 1]; IDWriteLocalizedStrings *family_names; IDWriteLocalizedStrings *names;
@@ -1291,8 +1291,11 @@ static HRESULT get_font_info_strings(const struct file_stream_desc *stream_desc, *exists = FALSE; *ret = NULL;
- if (stringid > DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME || stringid == DWRITE_INFORMATIONAL_STRING_NONE) + if (stringid > DWRITE_INFORMATIONAL_STRING_WEIGHT_STRETCH_STYLE_FAMILY_NAME + || stringid == DWRITE_INFORMATIONAL_STRING_NONE) + { return S_OK; + }
if (!strings_cache[stringid]) { @@ -1301,7 +1304,7 @@ static HRESULT get_font_info_strings(const struct file_stream_desc *stream_desc, if (!desc.stream) hr = get_filestream_from_file(file, &desc.stream); if (SUCCEEDED(hr)) - hr = opentype_get_font_info_strings(&desc, stringid, &strings_cache[stringid]); + opentype_get_font_info_strings(&desc, stringid, &strings_cache[stringid]);
if (!stream_desc->stream && desc.stream) IDWriteFontFileStream_Release(desc.stream); diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 1e71ce8614..fd420e4360 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -1098,7 +1098,7 @@ enum OPENTYPE_STRING_ID OPENTYPE_STRING_WWS_SUBFAMILY_NAME };
-static const UINT16 dwriteid_to_opentypeid[DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME+1] = +static const UINT16 dwriteid_to_opentypeid[DWRITE_INFORMATIONAL_STRING_WEIGHT_STRETCH_STYLE_FAMILY_NAME + 1] = { (UINT16)-1, /* DWRITE_INFORMATIONAL_STRING_NONE is not used */ OPENTYPE_STRING_COPYRIGHT_NOTICE, @@ -1118,7 +1118,8 @@ static const UINT16 dwriteid_to_opentypeid[DWRITE_INFORMATIONAL_STRING_POSTSCRIP OPENTYPE_STRING_SAMPLE_TEXT, OPENTYPE_STRING_FULL_FONTNAME, OPENTYPE_STRING_POSTSCRIPT_FONTNAME, - OPENTYPE_STRING_POSTSCRIPT_CID_NAME + OPENTYPE_STRING_POSTSCRIPT_CID_NAME, + OPENTYPE_STRING_WWS_FAMILY_NAME, };
/* CPAL table */