[PATCH 8/9] dwrite: Initial implementation of CreateFontCollectionFromFontSet().
Nikolay Sivov
nsivov at codeweavers.com
Mon Apr 25 05:31:48 CDT 2022
Signed-off-by: Nikolay Sivov <nsivov at 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);
--
2.35.1
More information about the wine-devel
mailing list