Nikolay Sivov : dwrite: Introduce callback interface to initialize freetype face objects.

Alexandre Julliard julliard at winehq.org
Mon Mar 29 16:00:03 CDT 2021


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Mon Mar 29 10:48:51 2021 +0300

dwrite: Introduce callback interface to initialize freetype face objects.

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

---

 dlls/dwrite/dwrite_private.h |  17 +++++--
 dlls/dwrite/font.c           |  79 +++++++++++++++++++++++++++++++
 dlls/dwrite/freetype.c       | 108 ++++++++++++++++++-------------------------
 dlls/dwrite/main.c           |   6 ++-
 4 files changed, 141 insertions(+), 69 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 47be661555c..5e41455f66d 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -486,9 +486,6 @@ extern int dwrite_outline_push_tag(struct dwrite_outline *outline, unsigned char
 extern int dwrite_outline_push_points(struct dwrite_outline *outline, const D2D1_POINT_2F *points,
         unsigned int count) DECLSPEC_HIDDEN;
 
-extern BOOL init_freetype(void) DECLSPEC_HIDDEN;
-extern void release_freetype(void) DECLSPEC_HIDDEN;
-
 extern HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph,
         DWRITE_GLYPH_METRICS *metrics) DECLSPEC_HIDDEN;
 extern void freetype_notify_cacheremove(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
@@ -734,3 +731,17 @@ extern HRESULT shape_get_typographic_features(struct scriptshaping_context *cont
         unsigned int max_tagcount, unsigned int *actual_tagcount, unsigned int *tags) DECLSPEC_HIDDEN;
 extern HRESULT shape_check_typographic_feature(struct scriptshaping_context *context, const unsigned int *scripts,
         unsigned int tag, unsigned int glyph_count, const UINT16 *glyphs, UINT8 *feature_applies) DECLSPEC_HIDDEN;
+
+struct font_data_context;
+extern HMODULE dwrite_module DECLSPEC_HIDDEN;
+
+struct font_callback_funcs
+{
+    int (CDECL *get_font_data)(void *key, const void **data_ptr, UINT64 *data_size, unsigned int *index,
+            struct font_data_context **context);
+    void (CDECL *release_font_data)(struct font_data_context *context);
+};
+
+extern NTSTATUS CDECL init_font_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out) DECLSPEC_HIDDEN;
+extern void init_font_backend(void) DECLSPEC_HIDDEN;
+extern void release_font_backend(void) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 245a59d5f54..ca7ce8ca53a 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -7958,3 +7958,82 @@ HRESULT create_fontset_builder(IDWriteFactory7 *factory, IDWriteFontSetBuilder2
 
     return S_OK;
 }
+
+struct font_data_context
+{
+    IDWriteFontFileStream *stream;
+    void *context;
+};
+
+static int CDECL get_font_data_cb(void *key, const void **data_ptr, UINT64 *data_size,
+        unsigned int *index, struct font_data_context **ret_context)
+{
+    IDWriteFontFace *fontface = key;
+    struct font_data_context *context;
+    IDWriteFontFileStream *stream;
+    IDWriteFontFile *file;
+    unsigned int count;
+    void *data_context;
+    HRESULT hr;
+
+    *ret_context = NULL;
+
+    count = 1;
+    if (FAILED(IDWriteFontFace_GetFiles(fontface, &count, &file))) return 1;
+
+    hr = get_filestream_from_file(file, &stream);
+    IDWriteFontFile_Release(file);
+    if (FAILED(hr)) return 1;
+
+    hr = IDWriteFontFileStream_GetFileSize(stream, data_size);
+    if (FAILED(hr))
+    {
+        IDWriteFontFileStream_Release(stream);
+        return 1;
+    }
+
+    hr = IDWriteFontFileStream_ReadFileFragment(stream, data_ptr, 0, *data_size, &data_context);
+    if (FAILED(hr))
+    {
+        IDWriteFontFileStream_Release(stream);
+        return 1;
+    }
+
+    if (!(context = heap_alloc(sizeof(*context))))
+    {
+        IDWriteFontFileStream_Release(stream);
+        return 1;
+    }
+
+    context->stream = stream;
+    context->context = data_context;
+
+    *ret_context = context;
+    *index = IDWriteFontFace_GetIndex(fontface);
+
+    return 0;
+}
+
+static void CDECL release_font_data_cb(struct font_data_context *context)
+{
+    if (!context) return;
+    IDWriteFontFileStream_ReleaseFileFragment(context->stream, context->context);
+    IDWriteFontFileStream_Release(context->stream);
+    heap_free(context);
+}
+
+struct font_callback_funcs callback_funcs =
+{
+    get_font_data_cb,
+    release_font_data_cb,
+};
+
+void init_font_backend(void)
+{
+    init_font_lib(dwrite_module, DLL_PROCESS_ATTACH, &callback_funcs, NULL);
+}
+
+void release_font_backend(void)
+{
+    init_font_lib(dwrite_module, DLL_PROCESS_DETACH, &callback_funcs, NULL);
+}
diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c
index 9e4001d11c2..c4bbbd4624c 100644
--- a/dlls/dwrite/freetype.c
+++ b/dlls/dwrite/freetype.c
@@ -31,6 +31,8 @@
 #include FT_TRUETYPE_TABLES_H
 #endif /* HAVE_FT2BUILD_H */
 
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
 #include "windef.h"
 #include "wine/debug.h"
 
@@ -60,6 +62,8 @@ typedef struct
     FT_Int patch;
 } FT_Version_t;
 
+static const struct font_callback_funcs *callback_funcs;
+
 #define MAKE_FUNCPTR(f) static typeof(f) * p##f = NULL
 MAKE_FUNCPTR(FT_Done_FreeType);
 MAKE_FUNCPTR(FT_Done_Glyph);
@@ -92,86 +96,44 @@ MAKE_FUNCPTR(FTC_Manager_RemoveFaceID);
 #undef MAKE_FUNCPTR
 static FT_Error (*pFT_Outline_EmboldenXY)(FT_Outline *, FT_Pos, FT_Pos);
 
-struct face_finalizer_data
-{
-    IDWriteFontFileStream *stream;
-    void *context;
-};
-
 static void face_finalizer(void *object)
 {
     FT_Face face = object;
-    struct face_finalizer_data *data = (struct face_finalizer_data *)face->generic.data;
-
-    IDWriteFontFileStream_ReleaseFileFragment(data->stream, data->context);
-    IDWriteFontFileStream_Release(data->stream);
-    heap_free(data);
+    callback_funcs->release_font_data((struct font_data_context *)face->generic.data);
 }
 
 static FT_Error face_requester(FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face *face)
 {
-    IDWriteFontFace *fontface = (IDWriteFontFace*)face_id;
-    IDWriteFontFileStream *stream;
-    IDWriteFontFile *file;
+    struct font_data_context *context;
     const void *data_ptr;
-    UINT32 index, count;
     FT_Error fterror;
     UINT64 data_size;
-    void *context;
-    HRESULT hr;
+    UINT32 index;
 
     *face = NULL;
 
-    if (!fontface) {
+    if (!face_id)
+    {
         WARN("NULL fontface requested.\n");
         return FT_Err_Ok;
     }
 
-    count = 1;
-    hr = IDWriteFontFace_GetFiles(fontface, &count, &file);
-    if (FAILED(hr))
-        return FT_Err_Ok;
-
-    hr = get_filestream_from_file(file, &stream);
-    IDWriteFontFile_Release(file);
-    if (FAILED(hr))
+    if (callback_funcs->get_font_data(face_id, &data_ptr, &data_size, &index, &context))
         return FT_Err_Ok;
 
-    hr = IDWriteFontFileStream_GetFileSize(stream, &data_size);
-    if (FAILED(hr)) {
-        fterror = FT_Err_Invalid_Stream_Read;
-        goto fail;
-    }
-
-    hr = IDWriteFontFileStream_ReadFileFragment(stream, &data_ptr, 0, data_size, &context);
-    if (FAILED(hr)) {
-        fterror = FT_Err_Invalid_Stream_Read;
-        goto fail;
-    }
-
-    index = IDWriteFontFace_GetIndex(fontface);
     fterror = pFT_New_Memory_Face(library, data_ptr, data_size, index, face);
-    if (fterror == FT_Err_Ok) {
-        struct face_finalizer_data *data;
-
-        data = heap_alloc(sizeof(*data));
-        data->stream = stream;
-        data->context = context;
-
-        (*face)->generic.data = data;
+    if (fterror == FT_Err_Ok)
+    {
+        (*face)->generic.data = context;
         (*face)->generic.finalizer = face_finalizer;
-        return fterror;
     }
     else
-        IDWriteFontFileStream_ReleaseFileFragment(stream, context);
-
-fail:
-    IDWriteFontFileStream_Release(stream);
+        callback_funcs->release_font_data(context);
 
     return fterror;
 }
 
-BOOL init_freetype(void)
+static BOOL init_freetype(void)
 {
     FT_Version_t FT_Version;
 
@@ -243,12 +205,6 @@ sym_not_found:
     return FALSE;
 }
 
-void release_freetype(void)
-{
-    pFTC_Manager_Done(cache_manager);
-    pFT_Done_FreeType(library);
-}
-
 void freetype_notify_cacheremove(IDWriteFontFace5 *fontface)
 {
     EnterCriticalSection(&freetype_cs);
@@ -790,17 +746,22 @@ INT32 freetype_get_glyph_advance(IDWriteFontFace5 *fontface, FLOAT emSize, UINT1
     return advance;
 }
 
-#else /* HAVE_FREETYPE */
-
-BOOL init_freetype(void)
+static NTSTATUS init_freetype_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out)
 {
-    return FALSE;
+    callback_funcs = ptr_in;
+    if (!init_freetype()) return STATUS_DLL_NOT_FOUND;
+    return STATUS_SUCCESS;
 }
 
-void release_freetype(void)
+static NTSTATUS release_freetype_lib(void)
 {
+    pFTC_Manager_Done(cache_manager);
+    pFT_Done_FreeType(library);
+    return STATUS_SUCCESS;
 }
 
+#else /* HAVE_FREETYPE */
+
 void freetype_notify_cacheremove(IDWriteFontFace5 *fontface)
 {
 }
@@ -838,4 +799,23 @@ INT32 freetype_get_glyph_advance(IDWriteFontFace5 *fontface, FLOAT emSize, UINT1
     return 0;
 }
 
+static NTSTATUS init_freetype_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out)
+{
+    return STATUS_DLL_NOT_FOUND;
+}
+
+static NTSTATUS release_freetype_lib(void)
+{
+    return STATUS_DLL_NOT_FOUND;
+}
+
 #endif /* HAVE_FREETYPE */
+
+NTSTATUS CDECL init_font_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out)
+{
+    if (reason == DLL_PROCESS_ATTACH)
+        return init_freetype_lib(module, reason, ptr_in, ptr_out);
+    else if (reason == DLL_PROCESS_DETACH)
+        return release_freetype_lib();
+    return STATUS_SUCCESS;
+}
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 3326b1550ce..41b81ae951b 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -34,6 +34,7 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
 
+HMODULE dwrite_module = 0;
 static IDWriteFactory7 *shared_factory;
 static void release_shared_factory(IDWriteFactory7 *factory);
 
@@ -42,14 +43,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved)
     switch (reason)
     {
     case DLL_PROCESS_ATTACH:
+        dwrite_module = hinstDLL;
         DisableThreadLibraryCalls( hinstDLL );
-        init_freetype();
+        init_font_backend();
         init_local_fontfile_loader();
         break;
     case DLL_PROCESS_DETACH:
         if (reserved) break;
         release_shared_factory(shared_factory);
-        release_freetype();
+        release_font_backend();
     }
     return TRUE;
 }




More information about the wine-cvs mailing list