[PATCH 4/5] dwrite: Partially implement GetPropertyValues().

Nikolay Sivov nsivov at codeweavers.com
Wed Mar 10 03:30:28 CST 2021


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/dwrite/font.c       | 116 +++++++++++++++++++++++++++++++++------
 dlls/dwrite/tests/font.c |  39 ++++++++++++-
 2 files changed, 137 insertions(+), 18 deletions(-)

diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 07d96dfe107..c0642b5bbe4 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -254,8 +254,10 @@ struct dwrite_fontset_entry
 {
     LONG refcount;
     IDWriteFontFile *file;
+    DWRITE_FONT_FACE_TYPE face_type;
     unsigned int face_index;
     unsigned int simulations;
+    IDWriteLocalizedStrings *props[DWRITE_FONT_PROPERTY_ID_TYPOGRAPHIC_FACE_NAME + 1];
 };
 
 struct dwrite_fontset
@@ -7104,14 +7106,74 @@ static ULONG WINAPI dwritefontset_AddRef(IDWriteFontSet3 *iface)
     return refcount;
 }
 
+#define MISSING_SET_PROP ((void *)0x1)
+
 static void release_fontset_entry(struct dwrite_fontset_entry *entry)
 {
+    unsigned int i;
+
     if (InterlockedDecrement(&entry->refcount) > 0)
         return;
     IDWriteFontFile_Release(entry->file);
+    for (i = 0; i < ARRAY_SIZE(entry->props); ++i)
+    {
+        if (entry->props[i] && entry->props[i] != MISSING_SET_PROP)
+            IDWriteLocalizedStrings_Release(entry->props[i]);
+    }
     heap_free(entry);
 }
 
+static struct dwrite_fontset_entry * addref_fontset_entry(struct dwrite_fontset_entry *entry)
+{
+    InterlockedIncrement(&entry->refcount);
+    return entry;
+}
+
+static IDWriteLocalizedStrings * fontset_entry_get_property(struct dwrite_fontset_entry *entry,
+        DWRITE_FONT_PROPERTY_ID property)
+{
+    struct file_stream_desc stream_desc = { 0 };
+    IDWriteLocalizedStrings *value;
+
+    assert(property > DWRITE_FONT_PROPERTY_ID_NONE && property <= DWRITE_FONT_PROPERTY_ID_TYPOGRAPHIC_FACE_NAME);
+
+    if (entry->props[property] == MISSING_SET_PROP)
+        return NULL;
+
+    if ((value = entry->props[property]))
+    {
+        IDWriteLocalizedStrings_AddRef(value);
+        return value;
+    }
+
+    get_filestream_from_file(entry->file, &stream_desc.stream);
+    stream_desc.face_type = entry->face_type;
+    stream_desc.face_index = entry->face_index;
+
+    if (property == DWRITE_FONT_PROPERTY_ID_FULL_NAME)
+        opentype_get_font_info_strings(&stream_desc, DWRITE_INFORMATIONAL_STRING_FULL_NAME, &value);
+    else if (property == DWRITE_FONT_PROPERTY_ID_POSTSCRIPT_NAME)
+        opentype_get_font_info_strings(&stream_desc, DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_NAME, &value);
+    else
+        WARN("Unsupported property %u.\n", property);
+
+    if (stream_desc.stream)
+        IDWriteFontFileStream_Release(stream_desc.stream);
+
+    if (value)
+    {
+        entry->props[property] = value;
+        IDWriteLocalizedStrings_AddRef(value);
+    }
+    else
+        entry->props[property] = MISSING_SET_PROP;
+
+    return value;
+}
+
+static void init_fontset(struct dwrite_fontset *object, IDWriteFactory7 *factory,
+       struct dwrite_fontset_entry **entries, unsigned int count);
+
 static ULONG WINAPI dwritefontset_Release(IDWriteFontSet3 *iface)
 {
     struct dwrite_fontset *set = impl_from_IDWriteFontSet3(iface);
@@ -7192,12 +7254,22 @@ static HRESULT WINAPI dwritefontset_GetPropertyValues_(IDWriteFontSet3 *iface, D
 static HRESULT WINAPI dwritefontset_GetPropertyValues(IDWriteFontSet3 *iface, UINT32 index, DWRITE_FONT_PROPERTY_ID id,
         BOOL *exists, IDWriteLocalizedStrings **values)
 {
-    static int once;
+    struct dwrite_fontset *set = impl_from_IDWriteFontSet3(iface);
 
-    if (!once++)
-        FIXME("%p, %u, %d, %p, %p.\n", iface, index, id, exists, values);
+    TRACE("%p, %u, %d, %p, %p.\n", iface, index, id, exists, values);
 
-    return E_NOTIMPL;
+    if (!(id > DWRITE_FONT_PROPERTY_ID_NONE && id <= DWRITE_FONT_PROPERTY_ID_TYPOGRAPHIC_FACE_NAME) ||
+            index >= set->count)
+    {
+        *values = NULL;
+        *exists = FALSE;
+        return E_INVALIDARG;
+    }
+
+    *values = fontset_entry_get_property(set->entries[index], id);
+    *exists = !!*values;
+
+    return S_OK;
 }
 
 static HRESULT WINAPI dwritefontset_GetPropertyOccurrenceCount(IDWriteFontSet3 *iface, DWRITE_FONT_PROPERTY const *property,
@@ -7387,8 +7459,8 @@ static const IDWriteFontSet3Vtbl fontsetvtbl =
     dwritefontset3_GetFontSourceName,
 };
 
-static HRESULT fontset_create_entry(IDWriteFontFile *file, unsigned int face_index,
-        unsigned int simulations, struct dwrite_fontset_entry **ret)
+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)
 {
     struct dwrite_fontset_entry *entry;
 
@@ -7398,6 +7470,7 @@ static HRESULT fontset_create_entry(IDWriteFontFile *file, unsigned int face_ind
     entry->refcount = 1;
     entry->file = file;
     IDWriteFontFile_AddRef(entry->file);
+    entry->face_type = face_type;
     entry->face_index = face_index;
     entry->simulations = simulations;
 
@@ -7435,7 +7508,8 @@ static HRESULT fontset_create_from_font_data(IDWriteFactory7 *factory, struct dw
 
         for (i = 0; i < count; ++i)
         {
-            fontset_create_entry(fonts[i]->file, fonts[i]->face_index, fonts[i]->simulations, &entries[i]);
+            fontset_create_entry(fonts[i]->file, fonts[i]->face_type, fonts[i]->face_index,
+                    fonts[i]->simulations, &entries[i]);
         }
     }
     init_fontset(object, factory, entries, count);
@@ -7460,10 +7534,7 @@ static HRESULT fontset_builder_create_fontset(IDWriteFactory7 *factory, struct d
         entries = heap_calloc(count, sizeof(*entries));
 
         for (i = 0; i < count; ++i)
-        {
-            entries[i] = src_entries[i];
-            InterlockedIncrement(&entries[i]->refcount);
-        }
+            entries[i] = addref_fontset_entry(src_entries[i]);
     }
     init_fontset(object, factory, entries, count);
 
@@ -7523,7 +7594,7 @@ static ULONG WINAPI dwritefontsetbuilder_Release(IDWriteFontSetBuilder2 *iface)
 }
 
 static HRESULT fontset_builder_add_entry(struct dwrite_fontset_builder *builder, IDWriteFontFile *file,
-        unsigned int face_index, unsigned int simulations)
+        DWRITE_FONT_FACE_TYPE face_type, unsigned int face_index, unsigned int simulations)
 {
     struct dwrite_fontset_entry *entry;
     HRESULT hr;
@@ -7534,7 +7605,7 @@ static HRESULT fontset_builder_add_entry(struct dwrite_fontset_builder *builder,
         return E_OUTOFMEMORY;
     }
 
-    if (FAILED(hr = fontset_create_entry(file, face_index, simulations, &entry)))
+    if (FAILED(hr = fontset_create_entry(file, face_type, face_index, simulations, &entry)))
         return hr;
 
     builder->entries[builder->count++] = entry;
@@ -7558,7 +7629,7 @@ static HRESULT fontset_builder_add_file(struct dwrite_fontset_builder *builder,
 
     for (i = 0; i < face_count; ++i)
     {
-        if (FAILED(hr = fontset_builder_add_entry(builder, file, i, DWRITE_FONT_SIMULATIONS_NONE)))
+        if (FAILED(hr = fontset_builder_add_entry(builder, file, facetype, i, DWRITE_FONT_SIMULATIONS_NONE)))
             break;
     }
 
@@ -7577,17 +7648,30 @@ static HRESULT WINAPI dwritefontsetbuilder_AddFontFaceReference(IDWriteFontSetBu
         IDWriteFontFaceReference *ref)
 {
     struct dwrite_fontset_builder *builder = impl_from_IDWriteFontSetBuilder2(iface);
-    unsigned int face_index, simulations;
+    unsigned int face_count, face_index, simulations;
+    DWRITE_FONT_FILE_TYPE file_type;
+    DWRITE_FONT_FACE_TYPE face_type;
     IDWriteFontFile *file;
+    BOOL supported;
     HRESULT hr;
 
     TRACE("%p, %p.\n", iface, ref);
 
     if (FAILED(hr = IDWriteFontFaceReference_GetFontFile(ref, &file))) return hr;
+    if (FAILED(hr = IDWriteFontFile_Analyze(file, &supported, &file_type, &face_type, &face_count)))
+        goto done;
+
+    if (!supported)
+    {
+        hr = DWRITE_E_FILEFORMAT;
+        goto done;
+    }
 
     face_index = IDWriteFontFaceReference_GetFontFaceIndex(ref);
     simulations = IDWriteFontFaceReference_GetSimulations(ref);
-    hr = fontset_builder_add_entry(builder, file, face_index, simulations);
+    hr = fontset_builder_add_entry(builder, file, face_type, face_index, simulations);
+
+done:
     IDWriteFontFile_Release(file);
 
     return hr;
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index 39a11b8be9a..4367f1d95c8 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -9505,7 +9505,6 @@ static void test_fontsetbuilder(void)
                 BOOL exists = FALSE;
 
                 hr = IDWriteFontSet_GetPropertyValues(fontset, 0, id, &exists, &values);
-            todo_wine
                 ok(hr == S_OK, "Failed to get property value, hr %#x.\n", hr);
 
                 if (!exists)
@@ -9940,8 +9939,11 @@ static void test_family_font_set(void)
     IDWriteFontFamily2 *family2;
     IDWriteFontFamily *family;
     IDWriteFactory *factory;
-    unsigned int refcount;
+    unsigned int count, refcount;
     IDWriteFontSet1 *fontset, *fontset2;
+    IDWriteLocalizedStrings *values;
+    WCHAR buffW[64];
+    BOOL exists;
     HRESULT hr;
 
     factory = create_factory();
@@ -9959,6 +9961,39 @@ static void test_family_font_set(void)
         hr = IDWriteFontFamily2_GetFontSet(family2, &fontset2);
         ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
         ok(fontset != fontset2, "Unexpected fontset instance.\n");
+
+        count = IDWriteFontSet1_GetFontCount(fontset);
+
+        /* Invalid property id. */
+        exists = TRUE;
+        values = (void *)0xdeadbeef;
+        hr = IDWriteFontSet1_GetPropertyValues(fontset, 0, 100, &exists, &values);
+        ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
+        ok(!exists && !values, "Unexpected return value.\n");
+
+        /* Invalid index. */
+        exists = TRUE;
+        values = (void *)0xdeadbeef;
+        hr = IDWriteFontSet1_GetPropertyValues(fontset, count, DWRITE_FONT_PROPERTY_ID_POSTSCRIPT_NAME, &exists, &values);
+        ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
+        ok(!exists && !values, "Unexpected return value.\n");
+
+        exists = TRUE;
+        values = (void *)0xdeadbeef;
+        hr = IDWriteFontSet1_GetPropertyValues(fontset, count, 100, &exists, &values);
+        ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
+        ok(!exists && !values, "Unexpected return value.\n");
+
+        hr = IDWriteFontSet1_GetPropertyValues(fontset, 0, DWRITE_FONT_PROPERTY_ID_POSTSCRIPT_NAME, &exists, &values);
+        ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+        ok(exists == !!values, "Unexpected return value.\n");
+        if (values)
+        {
+            hr = IDWriteLocalizedStrings_GetString(values, 0, buffW, ARRAY_SIZE(buffW));
+            ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+            IDWriteLocalizedStrings_Release(values);
+        }
+
         IDWriteFontSet1_Release(fontset2);
         IDWriteFontSet1_Release(fontset);
 
-- 
2.30.1




More information about the wine-devel mailing list