Module: wine Branch: master Commit: fcbb0f6c61829b7e65ef939d0034f76a81b5030e URL: https://gitlab.winehq.org/wine/wine/-/commit/fcbb0f6c61829b7e65ef939d0034f76...
Author: Nikolay Sivov nsivov@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@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. */