Nikolay Sivov : dwrite: Implement GetInformationalStrings() for fontfaces.

Alexandre Julliard julliard at winehq.org
Fri Jan 24 16:14:10 CST 2020


Module: wine
Branch: master
Commit: 6b0e68f2fadd6ff8f7dc4bd88d80481f0aee5a3f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=6b0e68f2fadd6ff8f7dc4bd88d80481f0aee5a3f

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Fri Jan 24 11:17:37 2020 +0300

dwrite: Implement GetInformationalStrings() for fontfaces.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dwrite/dwrite_private.h |  1 +
 dlls/dwrite/font.c           | 95 +++++++++++++++++++++++++++++---------------
 dlls/dwrite/tests/font.c     | 20 ++++++++++
 3 files changed, 83 insertions(+), 33 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index c70326c865..eea3cbabbe 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -231,6 +231,7 @@ struct dwrite_fontface
     FONTSIGNATURE fontsig;
     UINT32 glyph_image_formats;
 
+    IDWriteLocalizedStrings *info_strings[DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME+1];
     IDWriteLocalizedStrings *family_names;
     IDWriteLocalizedStrings *names;
 
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index a81433b242..2732693b4c 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -431,7 +431,8 @@ static void release_font_data(struct dwrite_font_data *data)
     if (InterlockedDecrement(&data->ref) > 0)
         return;
 
-    for (i = DWRITE_INFORMATIONAL_STRING_NONE; i < ARRAY_SIZE(data->info_strings); i++) {
+    for (i = 0; i < ARRAY_SIZE(data->info_strings); ++i)
+    {
         if (data->info_strings[i])
             IDWriteLocalizedStrings_Release(data->info_strings[i]);
     }
@@ -547,6 +548,11 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface)
             IDWriteLocalizedStrings_Release(fontface->names);
         if (fontface->family_names)
             IDWriteLocalizedStrings_Release(fontface->family_names);
+        for (i = 0; i < ARRAY_SIZE(fontface->info_strings); ++i)
+        {
+            if (fontface->info_strings[i])
+                IDWriteLocalizedStrings_Release(fontface->info_strings[i]);
+        }
 
         for (i = 0; i < ARRAY_SIZE(fontface->glyphs); i++)
             heap_free(fontface->glyphs[i]);
@@ -1276,12 +1282,53 @@ static HRESULT WINAPI dwritefontface3_GetFaceNames(IDWriteFontFace5 *iface, IDWr
     return clone_localizedstrings(fontface->names, names);
 }
 
+static HRESULT get_font_info_strings(const struct file_stream_desc *stream_desc, IDWriteFontFile *file,
+        DWRITE_INFORMATIONAL_STRING_ID stringid, IDWriteLocalizedStrings **strings_cache,
+        IDWriteLocalizedStrings **ret, BOOL *exists)
+{
+    HRESULT hr = S_OK;
+
+    *exists = FALSE;
+    *ret = NULL;
+
+    if (stringid > DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME || stringid == DWRITE_INFORMATIONAL_STRING_NONE)
+        return S_OK;
+
+    if (!strings_cache[stringid])
+    {
+        struct file_stream_desc desc = *stream_desc;
+
+        if (!desc.stream)
+            hr = get_filestream_from_file(file, &desc.stream);
+        if (SUCCEEDED(hr))
+            hr = opentype_get_font_info_strings(&desc, stringid, &strings_cache[stringid]);
+
+        if (!stream_desc->stream && desc.stream)
+            IDWriteFontFileStream_Release(desc.stream);
+    }
+
+    if (SUCCEEDED(hr) && strings_cache[stringid])
+    {
+        hr = clone_localizedstrings(strings_cache[stringid], ret);
+        if (SUCCEEDED(hr))
+            *exists = TRUE;
+    }
+
+    return hr;
+}
+
 static HRESULT WINAPI dwritefontface3_GetInformationalStrings(IDWriteFontFace5 *iface,
         DWRITE_INFORMATIONAL_STRING_ID stringid, IDWriteLocalizedStrings **strings, BOOL *exists)
 {
-    FIXME("%p, %u, %p, %p: stub\n", iface, stringid, strings, exists);
+    struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+    struct file_stream_desc stream_desc;
 
-    return E_NOTIMPL;
+    TRACE("%p, %u, %p, %p.\n", iface, stringid, strings, exists);
+
+    stream_desc.stream = fontface->stream;
+    stream_desc.face_index = fontface->index;
+    stream_desc.face_type = fontface->type;
+    return get_font_info_strings(&stream_desc, NULL, stringid, fontface->info_strings, strings, exists);
 }
 
 static BOOL WINAPI dwritefontface3_HasCharacter(IDWriteFontFace5 *iface, UINT32 ch)
@@ -1640,39 +1687,15 @@ static HRESULT WINAPI dwritefont_GetInformationalStrings(IDWriteFont3 *iface,
 {
     struct dwrite_font *font = impl_from_IDWriteFont3(iface);
     struct dwrite_font_data *data = font->data;
-    HRESULT hr = S_OK;
+    struct file_stream_desc stream_desc;
 
     TRACE("%p, %d, %p, %p.\n", iface, stringid, strings, exists);
 
-    *exists = FALSE;
-    *strings = NULL;
-
-    if (stringid > DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME || stringid == DWRITE_INFORMATIONAL_STRING_NONE)
-        return S_OK;
-
-    if (!data->info_strings[stringid])
-    {
-        struct file_stream_desc stream_desc;
-
-        if (SUCCEEDED(hr = get_filestream_from_file(data->file, &stream_desc.stream)))
-        {
-            stream_desc.face_type = data->face_type;
-            stream_desc.face_index = data->face_index;
-
-            hr = opentype_get_font_info_strings(&stream_desc, stringid, &data->info_strings[stringid]);
-
-            IDWriteFontFileStream_Release(stream_desc.stream);
-        }
-    }
-
-    if (SUCCEEDED(hr) && data->info_strings[stringid])
-    {
-        hr = clone_localizedstrings(data->info_strings[stringid], strings);
-        if (SUCCEEDED(hr))
-            *exists = TRUE;
-    }
-
-    return hr;
+    /* Stream will be created if necessary. */
+    stream_desc.stream = NULL;
+    stream_desc.face_index = data->face_index;
+    stream_desc.face_type = data->face_type;
+    return get_font_info_strings(&stream_desc, data->file, stringid, data->info_strings, strings, exists);
 }
 
 static DWRITE_FONT_SIMULATIONS WINAPI dwritefont_GetSimulations(IDWriteFont3 *iface)
@@ -4709,6 +4732,12 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
     fontface->family_names = font_data->family_names;
     if (fontface->family_names)
         IDWriteLocalizedStrings_AddRef(fontface->family_names);
+    memcpy(fontface->info_strings, font_data->info_strings, sizeof(fontface->info_strings));
+    for (i = 0; i < ARRAY_SIZE(fontface->info_strings); ++i)
+    {
+        if (fontface->info_strings[i])
+            IDWriteLocalizedStrings_AddRef(fontface->info_strings[i]);
+    }
     release_font_data(font_data);
 
     fontface->cached = factory_cache_fontface(fontface->factory, cached_list, &fontface->IDWriteFontFace5_iface);
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index cb5f7631f5..19c6928dd7 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -4026,6 +4026,8 @@ static void test_GetInformationalStrings(void)
 {
     IDWriteLocalizedStrings *strings, *strings2;
     IDWriteFontCollection *collection;
+    IDWriteFontFace3 *fontface3;
+    IDWriteFontFace *fontface;
     IDWriteFontFamily *family;
     IDWriteFactory *factory;
     IDWriteFont *font;
@@ -4072,6 +4074,24 @@ static void test_GetInformationalStrings(void)
 
     IDWriteLocalizedStrings_Release(strings);
     IDWriteLocalizedStrings_Release(strings2);
+
+    hr = IDWriteFont_CreateFontFace(font, &fontface);
+    ok(hr == S_OK, "Failed to create fontface, hr %#x.\n", hr);
+
+    if (SUCCEEDED(hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace3, (void **)&fontface3)))
+    {
+        hr = IDWriteFontFace3_GetInformationalStrings(fontface3, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES,
+                &strings, &exists);
+        ok(hr == S_OK, "Failed to get info strings, hr %#x.\n", hr);
+        IDWriteLocalizedStrings_Release(strings);
+
+        IDWriteFontFace3_Release(fontface3);
+    }
+    else
+        win_skip("IDWriteFontFace3::GetInformationalStrings() is not supported.\n");
+
+    IDWriteFontFace_Release(fontface);
+
     IDWriteFont_Release(font);
     IDWriteFontFamily_Release(family);
     IDWriteFontCollection_Release(collection);




More information about the wine-cvs mailing list