Nikolay Sivov : dwrite: Duplicate mapping data when creating fallback object.
Alexandre Julliard
julliard at winehq.org
Fri Jul 22 15:38:23 CDT 2022
Module: wine
Branch: master
Commit: fcbb0f6c61829b7e65ef939d0034f76a81b5030e
URL: https://gitlab.winehq.org/wine/wine/-/commit/fcbb0f6c61829b7e65ef939d0034f76a81b5030e
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Mon Jul 18 11:36:23 2022 +0300
dwrite: Duplicate mapping data when creating fallback object.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/dwrite/analyzer.c | 108 +++++++++++++++++++++++++++++++++++++++++----
dlls/dwrite/tests/layout.c | 4 +-
2 files changed, 102 insertions(+), 10 deletions(-)
diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c
index e4a52fa95a6..3d5aca98826 100644
--- a/dlls/dwrite/analyzer.c
+++ b/dlls/dwrite/analyzer.c
@@ -317,6 +317,8 @@ struct dwrite_fontfallback
IDWriteFontCollection *systemcollection;
struct fallback_mapping *mappings;
UINT32 mappings_count;
+ struct fallback_data data;
+ size_t mappings_size;
};
struct dwrite_fontfallback_builder
@@ -2352,6 +2354,9 @@ static ULONG WINAPI customfontfallback_Release(IDWriteFontFallback1 *iface)
if (!refcount)
{
IDWriteFactory7_Release(fallback->factory);
+ if (fallback->systemcollection)
+ IDWriteFontCollection_Release(fallback->systemcollection);
+ release_fallback_data(&fallback->data);
free(fallback);
}
@@ -2559,26 +2564,113 @@ static HRESULT WINAPI fontfallbackbuilder_AddMappings(IDWriteFontFallbackBuilder
return E_NOTIMPL;
}
-static HRESULT WINAPI fontfallbackbuilder_CreateFontFallback(IDWriteFontFallbackBuilder *iface,
- IDWriteFontFallback **ret)
+static HRESULT fallbackbuilder_init_fallback_data(const struct dwrite_fontfallback_builder *builder,
+ struct fallback_data *data)
{
- struct dwrite_fontfallback_builder *fallbackbuilder = impl_from_IDWriteFontFallbackBuilder(iface);
- struct dwrite_fontfallback *fallback;
+ struct fallback_locale *iter, *locale;
+ size_t i, j;
- TRACE("%p, %p.\n", iface, ret);
+ /* Duplicate locales list. */
+ list_init(&data->locales);
+ LIST_FOR_EACH_ENTRY(iter, &builder->data.locales, struct fallback_locale, entry)
+ {
+ if (!(locale = calloc(1, sizeof(*locale)))) goto failed;
+ wcscpy(locale->name, iter->name);
+ locale->ranges.count = iter->ranges.count;
+ locale->ranges.size = iter->ranges.count;
+ if (!(locale->ranges.data = malloc(iter->ranges.count * sizeof(*iter->ranges.data))))
+ {
+ free(locale);
+ goto failed;
+ }
+ memcpy(locale->ranges.data, iter->ranges.data, iter->ranges.count * sizeof(*iter->ranges.data));
+ list_add_tail(&data->locales, &locale->entry);
+ }
- *ret = NULL;
+ /* Duplicate mappings. */
+ if (!(data->mappings = calloc(builder->data.count, sizeof(*data->mappings))))
+ goto failed;
+
+ data->count = builder->data.count;
+ for (i = 0; i < data->count; ++i)
+ {
+ struct fallback_mapping *src = &builder->data.mappings[i];
+ struct fallback_mapping *dst = &data->mappings[i];
+
+ if (!(dst->ranges = calloc(src->ranges_count, sizeof(*src->ranges)))) goto failed;
+ memcpy(dst->ranges, src->ranges, src->ranges_count * sizeof(*src->ranges));
+ dst->ranges_count = src->ranges_count;
+
+ if (!(dst->families = calloc(src->families_count, sizeof(*src->families)))) goto failed;
+ dst->families_count = src->families_count;
+ for (j = 0; j < src->families_count; ++j)
+ {
+ if (!(dst->families[j] = wcsdup(src->families[j]))) goto failed;
+ }
+
+ dst->collection = src->collection;
+ if (dst->collection)
+ IDWriteFontCollection_AddRef(dst->collection);
+ dst->scale = src->scale;
+ }
+
+ return S_OK;
+
+failed:
+
+ return E_OUTOFMEMORY;
+}
+
+static HRESULT fallbackbuilder_create_fallback(struct dwrite_fontfallback_builder *builder, struct dwrite_fontfallback **ret)
+{
+ struct dwrite_fontfallback *fallback;
+ HRESULT hr;
if (!(fallback = calloc(1, sizeof(*fallback))))
return E_OUTOFMEMORY;
fallback->IDWriteFontFallback1_iface.lpVtbl = &customfontfallbackvtbl;
fallback->refcount = 1;
- fallback->factory = fallbackbuilder->factory;
+ fallback->factory = builder->factory;
IDWriteFactory7_AddRef(fallback->factory);
+ if (FAILED(hr = IDWriteFactory_GetSystemFontCollection((IDWriteFactory *)fallback->factory,
+ &fallback->systemcollection, FALSE)))
+ {
+ goto done;
+ }
+
+ if (FAILED(hr = fallbackbuilder_init_fallback_data(builder, &fallback->data)))
+ {
+ goto done;
+ }
+
+ *ret = fallback;
- *ret = (IDWriteFontFallback *)&fallback->IDWriteFontFallback1_iface;
return S_OK;
+
+done:
+
+ IDWriteFontFallback1_Release(&fallback->IDWriteFontFallback1_iface);
+ return hr;
+}
+
+static HRESULT WINAPI fontfallbackbuilder_CreateFontFallback(IDWriteFontFallbackBuilder *iface,
+ IDWriteFontFallback **ret)
+{
+ struct dwrite_fontfallback_builder *builder = impl_from_IDWriteFontFallbackBuilder(iface);
+ struct dwrite_fontfallback *fallback;
+ HRESULT hr;
+
+ TRACE("%p, %p.\n", iface, ret);
+
+ *ret = NULL;
+
+ if (SUCCEEDED(hr = fallbackbuilder_create_fallback(builder, &fallback)))
+ {
+ *ret = (IDWriteFontFallback *)&fallback->IDWriteFontFallback1_iface;
+ }
+
+ return hr;
}
static const IDWriteFontFallbackBuilderVtbl fontfallbackbuildervtbl =
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c
index 24ec3be7585..31bccfca3be 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -4861,14 +4861,14 @@ static void test_FontFallbackBuilder(void)
EXPECT_REF(builder, 1);
hr = IDWriteFontFallbackBuilder_CreateFontFallback(builder, &fallback);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- EXPECT_REF(factory2, 3);
+ todo_wine EXPECT_REF(factory2, 3);
EXPECT_REF(fallback, 1);
EXPECT_REF(builder, 1);
IDWriteFontFallback_AddRef(fallback);
EXPECT_REF(builder, 1);
EXPECT_REF(fallback, 2);
- EXPECT_REF(factory2, 3);
+ todo_wine EXPECT_REF(factory2, 3);
IDWriteFontFallback_Release(fallback);
/* New instance is created every time, even if mappings have not changed. */
More information about the wine-cvs
mailing list