[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