Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/tests/font.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 38eb1aeeb7d..af88c716ad8 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -7982,9 +7982,10 @@ static void test_CreateFontFaceReference(void) IDWriteFontFace3 *fontface, *fontface1; DWRITE_FONT_AXIS_VALUE axis_values[16]; IDWriteFontCollection1 *collection; + UINT32 axis_count, index, count, i; + IDWriteFontFaceReference1 *ref2; IDWriteFontFile *file, *file1; IDWriteFactory3 *factory; - UINT32 index, count, i; IDWriteFont3 *font3; ULONG refcount; WCHAR *path; @@ -8091,6 +8092,13 @@ static void test_CreateFontFaceReference(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(file != file1, "got %p, previous file %p\n", file1, file);
+ if (SUCCEEDED(IDWriteFontFaceReference_QueryInterface(ref, &IID_IDWriteFontFaceReference1, (void **)&ref2))) + { + axis_count = IDWriteFontFaceReference1_GetFontAxisValueCount(ref2); + ok(!axis_count, "Unexpected axis value count.\n"); + IDWriteFontFaceReference1_Release(ref2); + } + IDWriteFontFaceReference_Release(ref); IDWriteFontFile_Release(file); IDWriteFontFile_Release(file1); @@ -8112,8 +8120,6 @@ static void test_CreateFontFaceReference(void)
for (j = 0; j < font_count; j++) { - IDWriteFontFaceReference1 *ref2; - hr = IDWriteFontFamily1_GetFont(family, j, &font3); ok(hr == S_OK, "Failed to get font, hr %#lx.\n", hr);
@@ -8132,7 +8138,7 @@ static void test_CreateFontFaceReference(void) if (SUCCEEDED(hr = IDWriteFontFaceReference_QueryInterface(ref, &IID_IDWriteFontFaceReference1, (void **)&ref2))) { - UINT32 axis_count = IDWriteFontFaceReference1_GetFontAxisValueCount(ref2); + axis_count = IDWriteFontFaceReference1_GetFontAxisValueCount(ref2); todo_wine ok(axis_count >= 4, "Unexpected axis value count.\n");
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/tests/font.c | 45 ++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 15 deletions(-)
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index af88c716ad8..3d4c4caad98 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -321,11 +321,12 @@ typedef struct { BYTE data[1]; } sbix_glyph_data;
-typedef struct { +struct cblc_header +{ WORD majorVersion; WORD minorVersion; DWORD numSizes; -} CBLCHeader; +};
typedef struct { BYTE res[12]; @@ -3526,6 +3527,14 @@ struct dwrite_fonttable UINT32 size; };
+static const void *table_read_ensure(const struct dwrite_fonttable *table, unsigned int offset, unsigned int size) +{ + if (size > table->size || offset > table->size - size) + return NULL; + + return table->data + offset; +} + static WORD table_read_be_word(const struct dwrite_fonttable *table, void *ptr, DWORD offset) { if (!ptr) @@ -9303,34 +9312,40 @@ static DWORD get_sbix_formats(IDWriteFontFace4 *fontface)
static DWORD get_cblc_formats(IDWriteFontFace4 *fontface) { - CBLCBitmapSizeTable *sizes; - UINT32 num_sizes, size, s; + const CBLCBitmapSizeTable *sizes; + struct dwrite_fonttable cblc; + unsigned int i, num_sizes; BOOL exists = FALSE; - CBLCHeader *header; DWORD ret = 0; - void *context; HRESULT hr;
- hr = IDWriteFontFace4_TryGetFontTable(fontface, MS_CBLC_TAG, (const void **)&header, &size, &context, &exists); - ok(hr == S_OK, "TryGetFontTable() failed, %#lx\n", hr); - ok(exists, "Expected CBLC table\n"); + hr = IDWriteFontFace4_TryGetFontTable(fontface, MS_CBLC_TAG, (const void **)&cblc.data, &cblc.size, &cblc.context, &exists); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(exists, "Expected CBLC table.\n");
if (!exists) return 0;
- num_sizes = GET_BE_DWORD(header->numSizes); - sizes = (CBLCBitmapSizeTable *)(header + 1); - - for (s = 0; s < num_sizes; s++) { - BYTE bpp = sizes[s].bitDepth; + num_sizes = table_read_be_dword(&cblc, NULL, FIELD_OFFSET(struct cblc_header, numSizes)); + if (!(sizes = table_read_ensure(&cblc, sizeof(struct cblc_header), num_sizes * sizeof(*sizes)))) + { + skip("Malformed CBLC table.\n"); + num_sizes = 0; + }
+ for (i = 0; i < num_sizes; ++i) + { + BYTE bpp = sizes[i].bitDepth; if (bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8) ret |= DWRITE_GLYPH_IMAGE_FORMATS_PNG; else if (bpp == 32) ret |= DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8; + + if (ret == (DWRITE_GLYPH_IMAGE_FORMATS_PNG | DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8)) + break; }
- IDWriteFontFace4_ReleaseFontTable(fontface, context); + IDWriteFontFace4_ReleaseFontTable(fontface, cblc.context);
return ret; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/font.c | 5 ----- 1 file changed, 5 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 93adb65ec76..c663ed77b96 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -415,11 +415,6 @@ struct dwrite_colorglyphenum struct dwrite_fonttable colr; /* used to access layers */ };
-#define GLYPH_BLOCK_SHIFT 8 -#define GLYPH_BLOCK_SIZE (1UL << GLYPH_BLOCK_SHIFT) -#define GLYPH_BLOCK_MASK (GLYPH_BLOCK_SIZE - 1) -#define GLYPH_MAX 65536 - struct dwrite_fontfile { IDWriteFontFile IDWriteFontFile_iface;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/font.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index c663ed77b96..6b3aeebc8c3 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -2,7 +2,7 @@ * Font and collections * * Copyright 2011 Huw Davies - * Copyright 2012, 2014-2017 Nikolay Sivov for CodeWeavers + * Copyright 2012, 2014-2022 Nikolay Sivov for CodeWeavers * Copyright 2014 Aric Stewart for CodeWeavers * * This library is free software; you can redistribute it and/or @@ -3524,13 +3524,13 @@ static HRESULT fontcollection_add_family(struct dwrite_fontcollection *collectio return S_OK; }
-static HRESULT init_font_collection(struct dwrite_fontcollection *collection, BOOL is_system) +static HRESULT init_font_collection(struct dwrite_fontcollection *collection, IDWriteFactory7 *factory, + BOOL is_system) { collection->IDWriteFontCollection3_iface.lpVtbl = is_system ? &systemfontcollectionvtbl : &fontcollectionvtbl; collection->refcount = 1; - collection->count = 0; - collection->size = 0; - collection->family_data = NULL; + collection->factory = factory; + IDWriteFactory7_AddRef(collection->factory);
return S_OK; } @@ -4637,7 +4637,7 @@ HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerat if (!(collection = calloc(1, sizeof(*collection)))) return E_OUTOFMEMORY;
- hr = init_font_collection(collection, is_system); + hr = init_font_collection(collection, factory, is_system); if (FAILED(hr)) { free(collection); @@ -4776,9 +4776,6 @@ HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerat if (is_system) fontcollection_add_replacements(collection);
- collection->factory = factory; - IDWriteFactory7_AddRef(factory); - return hr; }
@@ -5092,7 +5089,7 @@ HRESULT get_eudc_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection3 if (!(collection = calloc(1, sizeof(*collection)))) return E_OUTOFMEMORY;
- hr = init_font_collection(collection, FALSE); + hr = init_font_collection(collection, factory, FALSE); if (FAILED(hr)) { free(collection); @@ -5100,8 +5097,6 @@ HRESULT get_eudc_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection3 }
*ret = &collection->IDWriteFontCollection3_iface; - collection->factory = factory; - IDWriteFactory7_AddRef(factory);
/* return empty collection if EUDC fonts are not configured */ swprintf(eudckeypathW, ARRAY_SIZE(eudckeypathW), L"EUDC\%u", GetACP());
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/font.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 6b3aeebc8c3..aa14eb3360c 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -333,6 +333,7 @@ struct dwrite_fontcollection LONG refcount;
IDWriteFactory7 *factory; + DWRITE_FONT_FAMILY_MODEL family_model; struct dwrite_fontfamily_data **family_data; size_t size; size_t count; @@ -3438,9 +3439,11 @@ static HRESULT WINAPI dwritefontcollection2_GetMatchingFonts(IDWriteFontCollecti
static DWRITE_FONT_FAMILY_MODEL WINAPI dwritefontcollection2_GetFontFamilyModel(IDWriteFontCollection3 *iface) { - FIXME("%p.\n", iface); + struct dwrite_fontcollection *collection = impl_from_IDWriteFontCollection3(iface); + + TRACE("%p.\n", iface);
- return DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE; + return collection->family_model; }
static HRESULT WINAPI dwritefontcollection2_GetFontSet(IDWriteFontCollection3 *iface, IDWriteFontSet1 **fontset) @@ -3525,12 +3528,13 @@ static HRESULT fontcollection_add_family(struct dwrite_fontcollection *collectio }
static HRESULT init_font_collection(struct dwrite_fontcollection *collection, IDWriteFactory7 *factory, - BOOL is_system) + DWRITE_FONT_FAMILY_MODEL family_model, BOOL is_system) { collection->IDWriteFontCollection3_iface.lpVtbl = is_system ? &systemfontcollectionvtbl : &fontcollectionvtbl; collection->refcount = 1; collection->factory = factory; IDWriteFactory7_AddRef(collection->factory); + collection->family_model = family_model;
return S_OK; } @@ -4637,7 +4641,7 @@ HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerat if (!(collection = calloc(1, sizeof(*collection)))) return E_OUTOFMEMORY;
- hr = init_font_collection(collection, factory, is_system); + hr = init_font_collection(collection, factory, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, is_system); if (FAILED(hr)) { free(collection); @@ -5089,7 +5093,7 @@ HRESULT get_eudc_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection3 if (!(collection = calloc(1, sizeof(*collection)))) return E_OUTOFMEMORY;
- hr = init_font_collection(collection, factory, FALSE); + hr = init_font_collection(collection, factory, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, FALSE); if (FAILED(hr)) { free(collection);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/font.c | 81 ++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 38 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index aa14eb3360c..bdd8c7fcc8b 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -452,13 +452,18 @@ struct dwrite_fontresource IDWriteFactory7 *factory; };
-struct dwrite_fontset_entry +struct dwrite_fontset_entry_desc { - LONG refcount; IDWriteFontFile *file; DWRITE_FONT_FACE_TYPE face_type; unsigned int face_index; unsigned int simulations; +}; + +struct dwrite_fontset_entry +{ + LONG refcount; + struct dwrite_fontset_entry_desc desc; IDWriteLocalizedStrings *props[DWRITE_FONT_PROPERTY_ID_TYPOGRAPHIC_FACE_NAME + 1]; };
@@ -7465,7 +7470,7 @@ static void release_fontset_entry(struct dwrite_fontset_entry *entry)
if (InterlockedDecrement(&entry->refcount) > 0) return; - IDWriteFontFile_Release(entry->file); + IDWriteFontFile_Release(entry->desc.file); for (i = 0; i < ARRAY_SIZE(entry->props); ++i) { if (entry->props[i] && entry->props[i] != MISSING_SET_PROP) @@ -7497,9 +7502,9 @@ static IDWriteLocalizedStrings * fontset_entry_get_property(struct dwrite_fontse return value; }
- get_filestream_from_file(entry->file, &stream_desc.stream); - stream_desc.face_type = entry->face_type; - stream_desc.face_index = entry->face_index; + get_filestream_from_file(entry->desc.file, &stream_desc.stream); + stream_desc.face_type = entry->desc.face_type; + stream_desc.face_index = entry->desc.face_index;
if (property == DWRITE_FONT_PROPERTY_ID_FULL_NAME) opentype_get_font_info_strings(&stream_desc, DWRITE_INFORMATIONAL_STRING_FULL_NAME, &value); @@ -7572,8 +7577,8 @@ static HRESULT WINAPI dwritefontset_GetFontFaceReference(IDWriteFontSet3 *iface, if (index >= set->count) return E_INVALIDARG;
- return IDWriteFactory7_CreateFontFaceReference_(set->factory, set->entries[index]->file, - set->entries[index]->face_index, set->entries[index]->simulations, reference); + return IDWriteFactory7_CreateFontFaceReference_(set->factory, set->entries[index]->desc.file, + set->entries[index]->desc.face_index, set->entries[index]->desc.simulations, reference); }
static HRESULT WINAPI dwritefontset_FindFontFaceReference(IDWriteFontSet3 *iface, @@ -7820,8 +7825,8 @@ static HRESULT WINAPI dwritefontset1_CreateFontResource(IDWriteFontSet3 *iface, if (index >= set->count) return E_INVALIDARG;
- return IDWriteFactory7_CreateFontResource(set->factory, set->entries[index]->file, - set->entries[index]->face_index, resource); + return IDWriteFactory7_CreateFontResource(set->factory, set->entries[index]->desc.file, + set->entries[index]->desc.face_index, resource); }
static HRESULT WINAPI dwritefontset1_CreateFontFace(IDWriteFontSet3 *iface, UINT32 index, IDWriteFontFace5 **fontface) @@ -7909,11 +7914,11 @@ static HRESULT fontset_create_entry(IDWriteFontFile *file, DWRITE_FONT_FACE_TYPE return E_OUTOFMEMORY;
entry->refcount = 1; - entry->file = file; - IDWriteFontFile_AddRef(entry->file); - entry->face_type = face_type; - entry->face_index = face_index; - entry->simulations = simulations; + entry->desc.file = file; + IDWriteFontFile_AddRef(entry->desc.file); + entry->desc.face_type = face_type; + entry->desc.face_index = face_index; + entry->desc.simulations = simulations;
*ret = entry;
@@ -8034,8 +8039,7 @@ static ULONG WINAPI dwritefontsetbuilder_Release(IDWriteFontSetBuilder2 *iface) return refcount; }
-static HRESULT fontset_builder_add_entry(struct dwrite_fontset_builder *builder, IDWriteFontFile *file, - DWRITE_FONT_FACE_TYPE face_type, unsigned int face_index, unsigned int simulations) +static HRESULT fontset_builder_add_entry(struct dwrite_fontset_builder *builder, const struct dwrite_fontset_entry_desc *desc) { struct dwrite_fontset_entry *entry; HRESULT hr; @@ -8046,7 +8050,7 @@ static HRESULT fontset_builder_add_entry(struct dwrite_fontset_builder *builder, return E_OUTOFMEMORY; }
- if (FAILED(hr = fontset_create_entry(file, face_type, face_index, simulations, &entry))) + if (FAILED(hr = fontset_create_entry(desc->file, desc->face_type, desc->face_index, desc->simulations, &entry))) return hr;
builder->entries[builder->count++] = entry; @@ -8056,13 +8060,14 @@ static HRESULT fontset_builder_add_entry(struct dwrite_fontset_builder *builder,
static HRESULT fontset_builder_add_file(struct dwrite_fontset_builder *builder, IDWriteFontFile *file) { + struct dwrite_fontset_entry_desc desc = { 0 }; DWRITE_FONT_FILE_TYPE filetype; - DWRITE_FONT_FACE_TYPE facetype; unsigned int i, face_count; BOOL supported = FALSE; HRESULT hr;
- if (FAILED(hr = IDWriteFontFile_Analyze(file, &supported, &filetype, &facetype, &face_count))) + desc.file = file; + if (FAILED(hr = IDWriteFontFile_Analyze(desc.file, &supported, &filetype, &desc.face_type, &face_count))) return hr;
if (!supported) @@ -8070,7 +8075,8 @@ static HRESULT fontset_builder_add_file(struct dwrite_fontset_builder *builder,
for (i = 0; i < face_count; ++i) { - if (FAILED(hr = fontset_builder_add_entry(builder, file, facetype, i, DWRITE_FONT_SIMULATIONS_NONE))) + desc.face_index = i; + if (FAILED(hr = fontset_builder_add_entry(builder, &desc))) break; }
@@ -8086,34 +8092,33 @@ static HRESULT WINAPI dwritefontsetbuilder_AddFontFaceReference_(IDWriteFontSetB }
static HRESULT WINAPI dwritefontsetbuilder_AddFontFaceReference(IDWriteFontSetBuilder2 *iface, - IDWriteFontFaceReference *ref) + IDWriteFontFaceReference *reference) { struct dwrite_fontset_builder *builder = impl_from_IDWriteFontSetBuilder2(iface); - unsigned int face_count, face_index, simulations; + struct dwrite_fontset_entry_desc desc = { 0 }; DWRITE_FONT_FILE_TYPE file_type; - DWRITE_FONT_FACE_TYPE face_type; - IDWriteFontFile *file; + unsigned int face_count; BOOL supported; HRESULT hr;
- TRACE("%p, %p.\n", iface, ref); + TRACE("%p, %p.\n", iface, reference);
- if (FAILED(hr = IDWriteFontFaceReference_GetFontFile(ref, &file))) return hr; - if (FAILED(hr = IDWriteFontFile_Analyze(file, &supported, &file_type, &face_type, &face_count))) - goto done; + if (FAILED(hr = IDWriteFontFaceReference_GetFontFile(reference, &desc.file))) return hr;
- if (!supported) + if (SUCCEEDED(hr = IDWriteFontFile_Analyze(desc.file, &supported, &file_type, &desc.face_type, &face_count))) { - hr = DWRITE_E_FILEFORMAT; - goto done; - } + if (!supported) + hr = DWRITE_E_FILEFORMAT;
- face_index = IDWriteFontFaceReference_GetFontFaceIndex(ref); - simulations = IDWriteFontFaceReference_GetSimulations(ref); - hr = fontset_builder_add_entry(builder, file, face_type, face_index, simulations); + if (SUCCEEDED(hr)) + { + desc.face_index = IDWriteFontFaceReference_GetFontFaceIndex(reference); + desc.simulations = IDWriteFontFaceReference_GetSimulations(reference); + hr = fontset_builder_add_entry(builder, &desc); + } + }
-done: - IDWriteFontFile_Release(file); + IDWriteFontFile_Release(desc.file);
return hr; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 3 +- dlls/dwrite/font.c | 21 ++++++++------ dlls/dwrite/opentype.c | 56 ++++++++++++++++++++++++++---------- 3 files changed, 55 insertions(+), 25 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 00fe325518f..35cf5add34b 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -469,7 +469,8 @@ extern void opentype_get_font_typo_metrics(struct file_stream_desc *stream_desc, unsigned int *descent) 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_familyname(const struct file_stream_desc *desc, DWRITE_FONT_FAMILY_MODEL family_model, + IDWriteLocalizedStrings **names) DECLSPEC_HIDDEN; extern HRESULT opentype_get_font_facename(struct file_stream_desc*,WCHAR*,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN; extern void opentype_get_typographic_features(struct ot_gsubgpos_table *table, unsigned int script_index, unsigned int language_index, struct tag_array *tags) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index bdd8c7fcc8b..e32b2d0f4cb 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -4279,7 +4279,8 @@ static BOOL font_apply_differentiation_rules(struct dwrite_font_data *font, WCHA return TRUE; }
-static HRESULT init_font_data(const struct fontface_desc *desc, struct dwrite_font_data **ret) +static HRESULT init_font_data(const struct fontface_desc *desc, DWRITE_FONT_FAMILY_MODEL family_model, + struct dwrite_font_data **ret) { static const float width_axis_values[] = { @@ -4319,10 +4320,9 @@ static HRESULT init_font_data(const struct fontface_desc *desc, struct dwrite_fo opentype_get_font_metrics(&stream_desc, &data->metrics, NULL); opentype_get_font_facename(&stream_desc, props.lf.lfFaceName, &data->names);
- /* get family name from font file */ - hr = opentype_get_font_familyname(&stream_desc, &data->family_names); - if (FAILED(hr)) { - WARN("unable to get family name from font\n"); + if (FAILED(hr = opentype_get_font_familyname(&stream_desc, family_model, &data->family_names))) + { + WARN("Unable to get family name from the font file, hr %#lx.\n", hr); release_font_data(data); return hr; } @@ -4337,7 +4337,10 @@ static HRESULT init_font_data(const struct fontface_desc *desc, struct dwrite_fo
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)) { + + if (family_model == DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE + && font_apply_differentiation_rules(data, familyW, faceW)) + { set_en_localizedstring(data->family_names, familyW); set_en_localizedstring(data->names, faceW); } @@ -4722,7 +4725,7 @@ HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerat desc.font_data = NULL;
/* Allocate an initialize new font data structure. */ - hr = init_font_data(&desc, &font_data); + hr = init_font_data(&desc, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, &font_data); if (FAILED(hr)) { /* move to next one */ @@ -5060,7 +5063,7 @@ 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, &font_data); + hr = init_font_data(&desc, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, &font_data); if (FAILED(hr)) continue;
@@ -5388,7 +5391,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li } else { - hr = init_font_data(desc, &font_data); + hr = init_font_data(desc, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, &font_data); if (FAILED(hr)) { IDWriteFontFace5_Release(&fontface->IDWriteFontFace5_iface); diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index c671218c486..c4b2177639b 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -2565,12 +2565,26 @@ HRESULT opentype_get_font_info_strings(const struct file_stream_desc *stream_des return S_OK; }
-/* FamilyName locating order is WWS Family Name -> Preferred Family Name -> Family Name. If font claims to - have 'Preferred Family Name' in WWS format, then WWS name is not used. */ -HRESULT opentype_get_font_familyname(struct file_stream_desc *stream_desc, IDWriteLocalizedStrings **names) +HRESULT opentype_get_font_familyname(const struct file_stream_desc *stream_desc, DWRITE_FONT_FAMILY_MODEL family_model, + IDWriteLocalizedStrings **names) { + static const unsigned int wws_candidates[] = + { + OPENTYPE_STRING_WWS_FAMILY_NAME, + OPENTYPE_STRING_TYPOGRAPHIC_FAMILY_NAME, + OPENTYPE_STRING_FAMILY_NAME, + ~0u, + }; + static const unsigned int typographic_candidates[] = + { + OPENTYPE_STRING_TYPOGRAPHIC_FAMILY_NAME, + OPENTYPE_STRING_WWS_FAMILY_NAME, + OPENTYPE_STRING_FAMILY_NAME, + ~0u, + }; struct dwrite_fonttable os2, name; - UINT16 fsselection; + const unsigned int *id; + BOOL try_wws_name; HRESULT hr;
opentype_get_font_table(stream_desc, MS_OS2_TAG, &os2); @@ -2578,20 +2592,32 @@ HRESULT opentype_get_font_familyname(struct file_stream_desc *stream_desc, IDWri
*names = NULL;
- /* If Preferred Family doesn't conform to WWS model try WWS name. */ - fsselection = os2.data ? table_read_be_word(&os2, FIELD_OFFSET(struct tt_os2, fsSelection)) : 0; - if (os2.data && !(fsselection & OS2_FSSELECTION_WWS)) - hr = opentype_get_font_strings_from_id(&name, OPENTYPE_STRING_WWS_FAMILY_NAME, names); + if (family_model == DWRITE_FONT_FAMILY_MODEL_TYPOGRAPHIC) + { + id = typographic_candidates; + } else - hr = E_FAIL; + { + /* FamilyName locating order is WWS Family Name -> Preferred Family Name -> Family Name. If font claims to + have 'Preferred Family Name' in WWS format, then WWS name is not used. */
- if (FAILED(hr)) - hr = opentype_get_font_strings_from_id(&name, OPENTYPE_STRING_TYPOGRAPHIC_FAMILY_NAME, names); - if (FAILED(hr)) - hr = opentype_get_font_strings_from_id(&name, OPENTYPE_STRING_FAMILY_NAME, names); + opentype_get_font_table(stream_desc, MS_OS2_TAG, &os2); + /* If Preferred Family doesn't conform to WWS model try WWS name. */ + try_wws_name = os2.data && !(table_read_be_word(&os2, FIELD_OFFSET(struct tt_os2, fsSelection)) & OS2_FSSELECTION_WWS); + if (os2.context) + IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, os2.context); + + id = wws_candidates; + if (!try_wws_name) id++; + } + + while (*id != ~0u) + { + if (SUCCEEDED(hr = opentype_get_font_strings_from_id(&name, *id, names))) + break; + id++; + }
- if (os2.context) - IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, os2.context); if (name.context) IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, name.context);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 2 + dlls/dwrite/font.c | 117 +++++++++++++++++++++++++++++++++++ dlls/dwrite/main.c | 11 ++-- dlls/dwrite/tests/font.c | 28 +++------ 4 files changed, 134 insertions(+), 24 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 35cf5add34b..60e8b87f499 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -347,6 +347,8 @@ extern HRESULT create_font_resource(IDWriteFactory7 *factory, IDWriteFontFile *f extern HRESULT create_fontset_builder(IDWriteFactory7 *factory, IDWriteFontSetBuilder2 **ret) DECLSPEC_HIDDEN; extern HRESULT compute_glyph_origins(DWRITE_GLYPH_RUN const *run, DWRITE_MEASURING_MODE measuring_mode, D2D1_POINT_2F baseline_origin, DWRITE_MATRIX const *transform, D2D1_POINT_2F *origins) DECLSPEC_HIDDEN; +extern HRESULT create_font_collection_from_set(IDWriteFactory7 *factory, IDWriteFontSet *set, + DWRITE_FONT_FAMILY_MODEL family_model, REFGUID riid, void **ret) DECLSPEC_HIDDEN;
struct dwrite_fontface;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index e32b2d0f4cb..23dad8970b8 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -624,6 +624,8 @@ static struct dwrite_fontset *impl_from_IDWriteFontSet3(IDWriteFontSet3 *iface) return CONTAINING_RECORD(iface, struct dwrite_fontset, IDWriteFontSet3_iface); }
+static struct dwrite_fontset *unsafe_impl_from_IDWriteFontSet(IDWriteFontSet *iface); + static HRESULT get_cached_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph, DWRITE_GLYPH_METRICS *metrics) { static const DWRITE_GLYPH_METRICS nil; @@ -4791,6 +4793,113 @@ HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerat return hr; }
+static HRESULT collection_add_font_entry(struct dwrite_fontcollection *collection, const struct fontface_desc *desc) +{ + struct dwrite_font_data *font_data; + WCHAR familyW[255]; + UINT32 index; + HRESULT hr; + + if (FAILED(hr = init_font_data(desc, collection->family_model, &font_data))) + return hr; + + fontstrings_get_en_string(font_data->family_names, familyW, ARRAY_SIZE(familyW)); + + /* ignore dot named faces */ + if (familyW[0] == '.') + { + WARN("Ignoring face %s\n", debugstr_w(familyW)); + release_font_data(font_data); + return S_OK; + } + + index = collection_find_family(collection, familyW); + if (index != ~0u) + hr = fontfamily_add_font(collection->family_data[index], font_data); + else + { + struct dwrite_fontfamily_data *family_data; + + /* Create and initialize new family */ + 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); + if (hr == S_OK) + hr = fontcollection_add_family(collection, family_data); + + if (FAILED(hr)) + release_fontfamily_data(family_data); + } + } + + if (FAILED(hr)) + release_font_data(font_data); + + return hr; +} + +HRESULT create_font_collection_from_set(IDWriteFactory7 *factory, IDWriteFontSet *fontset, + DWRITE_FONT_FAMILY_MODEL family_model, REFGUID riid, void **ret) +{ + struct dwrite_fontset *set = unsafe_impl_from_IDWriteFontSet(fontset); + struct dwrite_fontcollection *collection; + HRESULT hr = S_OK; + size_t i; + + *ret = NULL; + + if (!(collection = calloc(1, sizeof(*collection)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = init_font_collection(collection, factory, family_model, FALSE))) + { + free(collection); + return hr; + } + + for (i = 0; i < set->count; ++i) + { + const struct dwrite_fontset_entry *entry = set->entries[i]; + IDWriteFontFileStream *stream; + struct fontface_desc desc; + + if (FAILED(get_filestream_from_file(entry->desc.file, &stream))) + { + WARN("Failed to get file stream.\n"); + continue; + } + + desc.factory = factory; + desc.face_type = entry->desc.face_type; + desc.file = entry->desc.file; + desc.stream = stream; + desc.index = entry->desc.face_index; + desc.simulations = entry->desc.simulations; + desc.font_data = NULL; + + if (FAILED(hr = collection_add_font_entry(collection, &desc))) + WARN("Failed to add font collection element, hr %#lx.\n", hr); + + IDWriteFontFileStream_Release(stream); + } + + if (family_model == DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE) + { + for (i = 0; i < collection->count; ++i) + { + fontfamily_add_bold_simulated_face(collection->family_data[i]); + fontfamily_add_oblique_simulated_face(collection->family_data[i]); + } + } + + hr = IDWriteFontCollection3_QueryInterface(&collection->IDWriteFontCollection3_iface, riid, ret); + IDWriteFontCollection3_Release(&collection->IDWriteFontCollection3_iface); + + return hr; +} + struct system_fontfile_enumerator { IDWriteFontFileEnumerator IDWriteFontFileEnumerator_iface; @@ -7908,6 +8017,14 @@ static const IDWriteFontSet3Vtbl fontsetvtbl = dwritefontset3_GetFontSourceName, };
+static struct dwrite_fontset *unsafe_impl_from_IDWriteFontSet(IDWriteFontSet *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == (IDWriteFontSetVtbl *)&fontsetvtbl); + return CONTAINING_RECORD(iface, struct dwrite_fontset, IDWriteFontSet3_iface); +} + static HRESULT fontset_create_entry(IDWriteFontFile *file, DWRITE_FONT_FACE_TYPE face_type, unsigned int face_index, unsigned int simulations, struct dwrite_fontset_entry **ret) { diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 82dc34a0cdc..4d7d6a7eab0 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -1670,11 +1670,12 @@ static HRESULT WINAPI dwritefactory3_CreateFontSetBuilder(IDWriteFactory7 *iface }
static HRESULT WINAPI dwritefactory3_CreateFontCollectionFromFontSet(IDWriteFactory7 *iface, IDWriteFontSet *fontset, - IDWriteFontCollection1 **collection) + IDWriteFontCollection1 **collection) { - FIXME("%p, %p, %p: stub\n", iface, fontset, collection); + TRACE("%p, %p, %p.\n", iface, fontset, collection);
- return E_NOTIMPL; + return create_font_collection_from_set(iface, fontset, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, + &IID_IDWriteFontCollection1, (void **)collection); }
static HRESULT WINAPI dwritefactory3_GetSystemFontCollection(IDWriteFactory7 *iface, BOOL include_downloadable, @@ -1856,9 +1857,9 @@ static HRESULT WINAPI dwritefactory6_GetSystemFontCollection(IDWriteFactory7 *if static HRESULT WINAPI dwritefactory6_CreateFontCollectionFromFontSet(IDWriteFactory7 *iface, IDWriteFontSet *fontset, DWRITE_FONT_FAMILY_MODEL family_model, IDWriteFontCollection2 **collection) { - FIXME("%p, %p, %d, %p.\n", iface, fontset, family_model, collection); + TRACE("%p, %p, %d, %p.\n", iface, fontset, family_model, collection);
- return E_NOTIMPL; + return create_font_collection_from_set(iface, fontset, family_model, &IID_IDWriteFontCollection2, (void **)collection); }
static HRESULT WINAPI dwritefactory6_CreateFontSetBuilder(IDWriteFactory7 *iface, IDWriteFontSetBuilder2 **builder) diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 3d4c4caad98..2ca1a5f9c81 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -9656,14 +9656,10 @@ static void test_fontsetbuilder(void) hr = IDWriteFontSetBuilder1_CreateFontSet(builder1, &fontset); ok(hr == S_OK, "Unexpected hr %#lx.\n",hr); hr = IDWriteFactory3_CreateFontCollectionFromFontSet(factory, fontset, &collection); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n",hr); - if (SUCCEEDED(hr)) - { - count = IDWriteFontCollection1_GetFontFamilyCount(collection); - ok(count == 1, "Unexpected family count %u.\n", count); - IDWriteFontCollection1_Release(collection); - } + count = IDWriteFontCollection1_GetFontFamilyCount(collection); + ok(count == 1, "Unexpected family count %u.\n", count); + IDWriteFontCollection1_Release(collection); IDWriteFontSet_Release(fontset);
hr = IDWriteFontSetBuilder1_AddFontFile(builder1, file); @@ -9673,15 +9669,11 @@ static void test_fontsetbuilder(void) ok(hr == S_OK, "Unexpected hr %#lx.\n",hr);
hr = IDWriteFactory3_CreateFontCollectionFromFontSet(factory, fontset, &collection); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n",hr); - if (SUCCEEDED(hr)) - { - check_familymodel(collection, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE); - count = IDWriteFontCollection1_GetFontFamilyCount(collection); - ok(count == 1, "Unexpected family count %u.\n", count); - IDWriteFontCollection1_Release(collection); - } + check_familymodel(collection, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE); + count = IDWriteFontCollection1_GetFontFamilyCount(collection); + ok(count == 1, "Unexpected family count %u.\n", count); + IDWriteFontCollection1_Release(collection);
/* No attempt to eliminate duplicates. */ count = IDWriteFontSet_GetFontCount(fontset); @@ -10405,22 +10397,20 @@ static void test_CreateFontCollectionFromFontSet(void) ok(hr == S_OK, "Unexpected hr %#lx.\n",hr);
hr = IDWriteFactory5_CreateFontCollectionFromFontSet(factory, fontset, &collection); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n",hr);
-if (SUCCEEDED(hr)) -{ count = IDWriteFontCollection1_GetFontFamilyCount(collection); + todo_wine ok(count == 2, "Unexpected family count %u.\n", count);
/* Explicit fontset properties are prioritized and not replaced by actual properties from a file. */ exists = FALSE; hr = IDWriteFontCollection1_FindFamilyName(collection, L"Another Font", &index, &exists); ok(hr == S_OK, "Unexpected hr %#lx.\n",hr); + todo_wine ok(!!exists, "Unexpected return value %d.\n", exists);
IDWriteFontCollection1_Release(collection); -} IDWriteFontSet_Release(fontset);
IDWriteFontSetBuilder1_Release(builder);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 4 +- dlls/dwrite/font.c | 28 +++++++--- dlls/dwrite/main.c | 100 +++++++++++++++++++++++------------ dlls/dwrite/tests/font.c | 5 +- 4 files changed, 90 insertions(+), 47 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 60e8b87f499..fdc916adc40 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -299,7 +299,8 @@ extern void set_en_localizedstring(IDWriteLocalizedStrings*,const WCHAR*) DEC extern void sort_localizedstrings(IDWriteLocalizedStrings*) DECLSPEC_HIDDEN; extern unsigned int get_localizedstrings_count(IDWriteLocalizedStrings *strings) DECLSPEC_HIDDEN; extern BOOL localizedstrings_contains(IDWriteLocalizedStrings *strings, const WCHAR *str) DECLSPEC_HIDDEN; -extern HRESULT get_system_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection1 **collection) DECLSPEC_HIDDEN; +extern HRESULT get_system_fontcollection(IDWriteFactory7 *factory, DWRITE_FONT_FAMILY_MODEL family_model, + IDWriteFontCollection **collection) DECLSPEC_HIDDEN; extern HRESULT get_eudc_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection3 **collection) DECLSPEC_HIDDEN; extern IDWriteTextAnalyzer2 *get_text_analyzer(void) DECLSPEC_HIDDEN; extern HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_key, UINT32 key_size, IDWriteFontFile **font_file) DECLSPEC_HIDDEN; @@ -349,6 +350,7 @@ extern HRESULT compute_glyph_origins(DWRITE_GLYPH_RUN const *run, DWRITE_MEASURI D2D1_POINT_2F baseline_origin, DWRITE_MATRIX const *transform, D2D1_POINT_2F *origins) DECLSPEC_HIDDEN; extern HRESULT create_font_collection_from_set(IDWriteFactory7 *factory, IDWriteFontSet *set, DWRITE_FONT_FAMILY_MODEL family_model, REFGUID riid, void **ret) DECLSPEC_HIDDEN; +extern HRESULT create_system_fontset(IDWriteFactory7 *factory, REFIID riid, void **obj) DECLSPEC_HIDDEN;
struct dwrite_fontface;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 23dad8970b8..385c7fdeb03 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -5092,20 +5092,34 @@ static HRESULT create_system_fontfile_enumerator(IDWriteFactory7 *factory, IDWri return S_OK; }
-HRESULT get_system_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection1 **collection) +HRESULT get_system_fontcollection(IDWriteFactory7 *factory, DWRITE_FONT_FAMILY_MODEL family_model, + IDWriteFontCollection **collection) { IDWriteFontFileEnumerator *enumerator; + IDWriteFontSet *fontset; HRESULT hr;
*collection = NULL;
- hr = create_system_fontfile_enumerator(factory, &enumerator); - if (FAILED(hr)) - return hr; + if (family_model == DWRITE_FONT_FAMILY_MODEL_TYPOGRAPHIC) + { + if (SUCCEEDED(hr = create_system_fontset(factory, &IID_IDWriteFontSet, (void **)&fontset))) + { + hr = create_font_collection_from_set(factory, fontset, family_model, + &IID_IDWriteFontCollection, (void **)collection); + IDWriteFontSet_Release(fontset); + } + } + else + { + if (SUCCEEDED(hr = create_system_fontfile_enumerator(factory, &enumerator))) + { + TRACE("Building system font collection for factory %p.\n", factory); + hr = create_font_collection(factory, enumerator, TRUE, (IDWriteFontCollection3 **)collection); + IDWriteFontFileEnumerator_Release(enumerator); + } + }
- TRACE("building system font collection for factory %p\n", factory); - hr = create_font_collection(factory, enumerator, TRUE, (IDWriteFontCollection3 **)collection); - IDWriteFontFileEnumerator_Release(enumerator); return hr; }
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 4d7d6a7eab0..01b47e673bb 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -598,7 +598,7 @@ struct dwritefactory IDWriteFactory7 IDWriteFactory7_iface; LONG refcount;
- IDWriteFontCollection1 *system_collection; + IDWriteFontCollection *system_collections[DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE + 1]; IDWriteFontCollection1 *eudc_collection; IDWriteGdiInterop1 *gdiinterop; IDWriteFontFallback1 *fallback; @@ -640,6 +640,7 @@ static void release_dwritefactory(struct dwritefactory *factory) { struct fileloader *fileloader, *fileloader2; struct collectionloader *loader, *loader2; + unsigned int i;
EnterCriticalSection(&factory->cs); release_fontface_cache(&factory->localfontfaces); @@ -654,8 +655,11 @@ static void release_dwritefactory(struct dwritefactory *factory) LIST_FOR_EACH_ENTRY_SAFE(fileloader, fileloader2, &factory->file_loaders, struct fileloader, entry) release_fileloader(fileloader);
- if (factory->system_collection) - IDWriteFontCollection1_Release(factory->system_collection); + for (i = 0; i < ARRAY_SIZE(factory->system_collections); ++i) + { + if (factory->system_collections[i]) + IDWriteFontCollection_Release(factory->system_collections[i]); + } if (factory->eudc_collection) IDWriteFontCollection1_Release(factory->eudc_collection); if (factory->fallback) @@ -703,26 +707,35 @@ static struct collectionloader *factory_get_collection_loader(struct dwritefacto return found; }
-static IDWriteFontCollection1 *factory_get_system_collection(struct dwritefactory *factory) +static HRESULT factory_get_system_collection(struct dwritefactory *factory, + DWRITE_FONT_FAMILY_MODEL family_model, REFIID riid, void **out) { - IDWriteFontCollection1 *collection; + IDWriteFontCollection *collection; HRESULT hr;
- if (factory->system_collection) { - IDWriteFontCollection1_AddRef(factory->system_collection); - return factory->system_collection; + *out = NULL; + + if (family_model != DWRITE_FONT_FAMILY_MODEL_TYPOGRAPHIC && + family_model != DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE) + { + return E_INVALIDARG; }
- if (FAILED(hr = get_system_fontcollection(&factory->IDWriteFactory7_iface, &collection))) + if (factory->system_collections[family_model]) + return IDWriteFontCollection_QueryInterface(factory->system_collections[family_model], riid, out); + + if (FAILED(hr = get_system_fontcollection(&factory->IDWriteFactory7_iface, family_model, &collection))) { WARN("Failed to create system font collection, hr %#lx.\n", hr); - return NULL; + return hr; }
- if (InterlockedCompareExchangePointer((void **)&factory->system_collection, collection, NULL)) - IDWriteFontCollection1_Release(collection); + if (InterlockedCompareExchangePointer((void **)&factory->system_collections[family_model], collection, NULL)) + IDWriteFontCollection_Release(collection);
- return factory->system_collection; + hr = IDWriteFontCollection_QueryInterface(factory->system_collections[family_model], riid, out); + IDWriteFontCollection_Release(factory->system_collections[family_model]); + return hr; }
static HRESULT WINAPI dwritefactory_QueryInterface(IDWriteFactory7 *iface, REFIID riid, void **obj) @@ -773,10 +786,17 @@ static ULONG WINAPI dwritefactory_Release(IDWriteFactory7 *iface) }
static HRESULT WINAPI dwritefactory_GetSystemFontCollection(IDWriteFactory7 *iface, - IDWriteFontCollection **collection, BOOL check_for_updates) + IDWriteFontCollection **collection, BOOL check_for_updates) { - return IDWriteFactory5_GetSystemFontCollection((IDWriteFactory5 *)iface, FALSE, (IDWriteFontCollection1 **)collection, - check_for_updates); + struct dwritefactory *factory = impl_from_IDWriteFactory7(iface); + + TRACE("%p, %p, %d.\n", iface, collection, check_for_updates); + + if (check_for_updates) + FIXME("checking for system font updates not implemented\n"); + + return factory_get_system_collection(factory, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, + &IID_IDWriteFontCollection, (void **)collection); }
static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory7 *iface, @@ -1167,14 +1187,16 @@ static HRESULT WINAPI dwritefactory_CreateTextFormat(IDWriteFactory7 *iface, WCH TRACE("%p, %s, %p, %d, %d, %d, %.8e, %s, %p.\n", iface, debugstr_w(family_name), collection, weight, style, stretch, size, debugstr_w(locale), format);
+ *format = NULL; + if (collection) + { IDWriteFontCollection_AddRef(collection); - else { - collection = (IDWriteFontCollection *)factory_get_system_collection(factory); - if (!collection) { - *format = NULL; - return E_FAIL; - } + } + else if (FAILED(hr = factory_get_system_collection(factory, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, + &IID_IDWriteFontCollection, (void **)&collection))) + { + return hr; }
hr = create_textformat(family_name, collection, weight, style, stretch, size, locale, format); @@ -1611,7 +1633,7 @@ static int __cdecl create_system_fontset_compare(const void *left, const void *r return wcsicmp(_l, _r); };
-static HRESULT create_system_fontset(IDWriteFactory7 *factory, REFIID riid, void **obj) +HRESULT create_system_fontset(IDWriteFactory7 *factory, REFIID riid, void **obj) { IDWriteFontSetBuilder2 *builder; IDWriteFontSet *fontset; @@ -1691,9 +1713,8 @@ static HRESULT WINAPI dwritefactory3_GetSystemFontCollection(IDWriteFactory7 *if if (check_for_updates) FIXME("checking for system font updates not implemented\n");
- *collection = factory_get_system_collection(factory); - - return *collection ? S_OK : E_FAIL; + return factory_get_system_collection(factory, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, + &IID_IDWriteFontCollection1, (void **)collection); }
static HRESULT WINAPI dwritefactory3_GetFontDownloadQueue(IDWriteFactory7 *iface, IDWriteFontDownloadQueue **queue) @@ -1849,9 +1870,14 @@ static HRESULT WINAPI dwritefactory6_GetSystemFontSet(IDWriteFactory7 *iface, BO static HRESULT WINAPI dwritefactory6_GetSystemFontCollection(IDWriteFactory7 *iface, BOOL include_downloadable, DWRITE_FONT_FAMILY_MODEL family_model, IDWriteFontCollection2 **collection) { - FIXME("%p, %d, %d, %p.\n", iface, include_downloadable, family_model, collection); + struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
- return E_NOTIMPL; + TRACE("%p, %d, %d, %p.\n", iface, include_downloadable, family_model, collection); + + if (include_downloadable) + FIXME("remote fonts are not supported\n"); + + return factory_get_system_collection(factory, family_model, &IID_IDWriteFontCollection2, (void **)collection); }
static HRESULT WINAPI dwritefactory6_CreateFontCollectionFromFontSet(IDWriteFactory7 *iface, IDWriteFontSet *fontset, @@ -1893,9 +1919,14 @@ static HRESULT WINAPI dwritefactory7_GetSystemFontSet(IDWriteFactory7 *iface, BO static HRESULT WINAPI dwritefactory7_GetSystemFontCollection(IDWriteFactory7 *iface, BOOL include_downloadable, DWRITE_FONT_FAMILY_MODEL family_model, IDWriteFontCollection3 **collection) { - FIXME("%p, %d, %d, %p.\n", iface, include_downloadable, family_model, collection); + struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
- return E_NOTIMPL; + TRACE("%p, %d, %d, %p.\n", iface, include_downloadable, family_model, collection); + + if (include_downloadable) + FIXME("remote fonts are not supported\n"); + + return factory_get_system_collection(factory, family_model, &IID_IDWriteFontCollection3, (void **)collection); }
static const IDWriteFactory7Vtbl dwritefactoryvtbl = @@ -2040,10 +2071,6 @@ static void init_dwritefactory(struct dwritefactory *factory, DWRITE_FACTORY_TYP &shareddwritefactoryvtbl : &dwritefactoryvtbl; factory->refcount = 1; factory->localfontfileloader = get_local_fontfile_loader(); - factory->system_collection = NULL; - factory->eudc_collection = NULL; - factory->gdiinterop = NULL; - factory->fallback = NULL;
list_init(&factory->collection_loaders); list_init(&factory->file_loaders); @@ -2056,7 +2083,10 @@ static void init_dwritefactory(struct dwritefactory *factory, DWRITE_FACTORY_TYP void factory_detach_fontcollection(IDWriteFactory7 *iface, IDWriteFontCollection3 *collection) { struct dwritefactory *factory = impl_from_IDWriteFactory7(iface); - InterlockedCompareExchangePointer((void **)&factory->system_collection, NULL, collection); + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(factory->system_collections); ++i) + InterlockedCompareExchangePointer((void **)&factory->system_collections[i], NULL, collection); InterlockedCompareExchangePointer((void **)&factory->eudc_collection, NULL, collection); IDWriteFactory7_Release(iface); } diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 2ca1a5f9c81..81008db6f23 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -2654,10 +2654,8 @@ static void test_system_fontcollection(void)
hr = IDWriteFactory6_GetSystemFontCollection(factory6, FALSE, DWRITE_FONT_FAMILY_MODEL_TYPOGRAPHIC, &collection2); - todo_wine ok(hr == S_OK, "Failed to get collection, hr %#lx.\n", hr); - if (SUCCEEDED(hr)) - { + hr = IDWriteFactory6_GetSystemFontCollection(factory6, FALSE, DWRITE_FONT_FAMILY_MODEL_TYPOGRAPHIC, &c2); ok(hr == S_OK, "Failed to get collection, hr %#lx.\n", hr); ok(c2 == collection2 && collection != (IDWriteFontCollection *)c2, "Unexpected collection instance.\n"); @@ -2668,7 +2666,6 @@ static void test_system_fontcollection(void) &collection2); ok(hr == S_OK, "Failed to get collection, hr %#lx.\n", hr); IDWriteFontCollection2_Release(collection2); - } IDWriteFactory6_Release(factory6); } else