Aric Stewart : dwrite: Initial implementation of CreateCustomFontFileReference.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Aug 20 14:30:34 CDT 2014


Module: wine
Branch: master
Commit: bb9721bd2914174e30b5b85bc94eee350dd9beab
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=bb9721bd2914174e30b5b85bc94eee350dd9beab

Author: Aric Stewart <aric at codeweavers.com>
Date:   Tue Aug 12 14:11:34 2014 -0500

dwrite: Initial implementation of CreateCustomFontFileReference.

---

 dlls/dwrite/dwrite_private.h |   1 +
 dlls/dwrite/font.c           | 112 +++++++++++++++++++++++++++++++++++++++++++
 dlls/dwrite/main.c           |  16 ++++++-
 dlls/dwrite/tests/font.c     |  17 +++++++
 4 files changed, 144 insertions(+), 2 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 8db35a3..fcc9b7f 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -89,3 +89,4 @@ extern HRESULT add_localizedstring(IDWriteLocalizedStrings*,const WCHAR*,const W
 extern HRESULT get_system_fontcollection(IDWriteFontCollection**) DECLSPEC_HIDDEN;
 extern void release_system_fontcollection(void) DECLSPEC_HIDDEN;
 extern HRESULT get_textanalyzer(IDWriteTextAnalyzer**) DECLSPEC_HIDDEN;
+extern HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_key, UINT32 key_size, IDWriteFontFile **font_file) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 0962784..afeca27 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -162,6 +162,15 @@ struct dwrite_fontface {
     LOGFONTW logfont;
 };
 
+struct dwrite_fontfile {
+    IDWriteFontFile IDWriteFontFile_iface;
+    LONG ref;
+
+    IDWriteFontFileLoader *loader;
+    void *reference_key;
+    UINT32 key_size;
+};
+
 static HRESULT create_fontfamily(const WCHAR *familyname, IDWriteFontFamily **family);
 
 static inline struct dwrite_fontface *impl_from_IDWriteFontFace(IDWriteFontFace *iface)
@@ -174,6 +183,11 @@ static inline struct dwrite_font *impl_from_IDWriteFont(IDWriteFont *iface)
     return CONTAINING_RECORD(iface, struct dwrite_font, IDWriteFont_iface);
 }
 
+static inline struct dwrite_fontfile *impl_from_IDWriteFontFile(IDWriteFontFile *iface)
+{
+    return CONTAINING_RECORD(iface, struct dwrite_fontfile, IDWriteFontFile_iface);
+}
+
 static inline struct dwrite_fontfamily *impl_from_IDWriteFontFamily(IDWriteFontFamily *iface)
 {
     return CONTAINING_RECORD(iface, struct dwrite_fontfamily, IDWriteFontFamily_iface);
@@ -978,3 +992,101 @@ HRESULT create_font_from_logfont(const LOGFONTW *logfont, IDWriteFont **font)
 
     return S_OK;
 }
+
+static HRESULT WINAPI dwritefontfile_QueryInterface(IDWriteFontFile *iface, REFIID riid, void **obj)
+{
+    struct dwrite_fontfile *This = impl_from_IDWriteFontFile(iface);
+
+    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
+
+    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDWriteFontFile))
+    {
+        *obj = iface;
+        IDWriteFontFile_AddRef(iface);
+        return S_OK;
+    }
+
+    *obj = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI dwritefontfile_AddRef(IDWriteFontFile *iface)
+{
+    struct dwrite_fontfile *This = impl_from_IDWriteFontFile(iface);
+    ULONG ref = InterlockedIncrement(&This->ref);
+    TRACE("(%p)->(%d)\n", This, ref);
+    return ref;
+}
+
+static ULONG WINAPI dwritefontfile_Release(IDWriteFontFile *iface)
+{
+    struct dwrite_fontfile *This = impl_from_IDWriteFontFile(iface);
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p)->(%d)\n", This, ref);
+
+    if (!ref)
+    {
+        IDWriteFontFileLoader_Release(This->loader);
+        heap_free(This->reference_key);
+        heap_free(This);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI dwritefontfile_GetReferenceKey(IDWriteFontFile *iface, const void **fontFileReferenceKey, UINT32 *fontFileReferenceKeySize)
+{
+    struct dwrite_fontfile *This = impl_from_IDWriteFontFile(iface);
+    TRACE("(%p)->(%p, %p)\n", This, fontFileReferenceKey, fontFileReferenceKeySize);
+    *fontFileReferenceKey = This->reference_key;
+    *fontFileReferenceKeySize = This->key_size;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI dwritefontfile_GetLoader(IDWriteFontFile *iface, IDWriteFontFileLoader **fontFileLoader)
+{
+    struct dwrite_fontfile *This = impl_from_IDWriteFontFile(iface);
+    TRACE("(%p)->(%p)\n", This, fontFileLoader);
+    *fontFileLoader = This->loader;
+    IDWriteFontFileLoader_AddRef(This->loader);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI dwritefontfile_Analyze(IDWriteFontFile *iface, BOOL *isSupportedFontType, DWRITE_FONT_FILE_TYPE *fontFileType, DWRITE_FONT_FACE_TYPE *fontFaceType, UINT32 *numberOfFaces)
+{
+    struct dwrite_fontfile *This = impl_from_IDWriteFontFile(iface);
+    FIXME("(%p)->(%p, %p, %p, %p): Stub\n", This, isSupportedFontType, fontFileType, fontFaceType, numberOfFaces);
+    return E_NOTIMPL;
+}
+
+static const IDWriteFontFileVtbl dwritefontfilevtbl = {
+    dwritefontfile_QueryInterface,
+    dwritefontfile_AddRef,
+    dwritefontfile_Release,
+    dwritefontfile_GetReferenceKey,
+    dwritefontfile_GetLoader,
+    dwritefontfile_Analyze,
+};
+
+HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_key, UINT32 key_size, IDWriteFontFile **font_file)
+{
+    struct dwrite_fontfile *This;
+
+    This = heap_alloc(sizeof(struct dwrite_fontfile));
+    if (!This) return E_OUTOFMEMORY;
+
+    This->IDWriteFontFile_iface.lpVtbl = &dwritefontfilevtbl;
+    This->ref = 1;
+    IDWriteFontFileLoader_AddRef(loader);
+    This->loader = loader;
+    This->reference_key = heap_alloc(key_size);
+    memcpy(This->reference_key, reference_key, key_size);
+    This->key_size = key_size;
+
+    *font_file = &This->IDWriteFontFile_iface;
+
+    return S_OK;
+}
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 3620718..f736301 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -509,9 +509,21 @@ static HRESULT WINAPI dwritefactory_CreateFontFileReference(IDWriteFactory *ifac
 static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory *iface,
     void const *reference_key, UINT32 key_size, IDWriteFontFileLoader *loader, IDWriteFontFile **font_file)
 {
+    int i;
     struct dwritefactory *This = impl_from_IDWriteFactory(iface);
-    FIXME("(%p)->(%p %u %p %p): stub\n", This, reference_key, key_size, loader, font_file);
-    return E_NOTIMPL;
+    HRESULT hr;
+
+    TRACE("(%p)->(%p %u %p %p)\n", This, reference_key, key_size, loader, font_file);
+
+    if (loader == NULL)
+        return E_INVALIDARG;
+
+    for (i = 0; i < This->file_loader_count; i++)
+        if (This->file_loaders[i] == loader) break;
+    if (i == This->file_loader_count)
+        return E_INVALIDARG;
+    hr = create_font_file(loader, reference_key, key_size, font_file);
+    return hr;
 }
 
 static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory *iface,
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index 243af9f..4368bcf 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -761,6 +761,8 @@ static void test_FontLoader(void)
 {
     IDWriteFontFileLoader floader = { &dwritefontfileloadervtbl };
     IDWriteFontFileLoader floader2 = { &dwritefontfileloadervtbl };
+    IDWriteFontFileLoader floader3 = { &dwritefontfileloadervtbl };
+    IDWriteFontFile *ffile = NULL;
     HRESULT hr;
 
     hr = IDWriteFactory_RegisterFontFileLoader(factory, NULL);
@@ -772,6 +774,21 @@ static void test_FontLoader(void)
     hr = IDWriteFactory_RegisterFontFileLoader(factory, &floader);
     ok(hr == DWRITE_E_ALREADYREGISTERED, "got 0x%08x\n", hr);
 
+    hr = IDWriteFactory_CreateCustomFontFileReference(factory, "test", 4, &floader, &ffile);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    if (SUCCEEDED(hr))
+        IDWriteFontFile_Release(ffile);
+
+    hr = IDWriteFactory_CreateCustomFontFileReference(factory, "test", 4, &floader3, &ffile);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+    if (SUCCEEDED(hr))
+        IDWriteFontFile_Release(ffile);
+
+    hr = IDWriteFactory_CreateCustomFontFileReference(factory, "test", 4, NULL, &ffile);
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+    if (SUCCEEDED(hr))
+        IDWriteFontFile_Release(ffile);
+
     hr = IDWriteFactory_UnregisterFontFileLoader(factory, &floader);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     hr = IDWriteFactory_UnregisterFontFileLoader(factory, &floader);




More information about the wine-cvs mailing list