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