From f3d777ba7dd9ca662c984bfd7e3a90fddb30e311 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 29 Mar 2021 10:48:51 +0300 Subject: [PATCH] dwrite: Introduce callback interface to initialize freetype face objects. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/dwrite/dwrite_private.h | 17 ++++- dlls/dwrite/font.c | 79 ++++++++++++++++++++++++ dlls/dwrite/freetype.c | 116 +++++++++++++++-------------------- dlls/dwrite/main.c | 6 +- 4 files changed, 145 insertions(+), 73 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)) + if (callback_funcs->get_font_data(face_id, &data_ptr, &data_size, &index, &context)) return FT_Err_Ok; - hr = get_filestream_from_file(file, &stream); - IDWriteFontFile_Release(file); - if (FAILED(hr)) - 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; } +static NTSTATUS init_freetype_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out) +{ + callback_funcs = ptr_in; + if (!init_freetype()) return STATUS_DLL_NOT_FOUND; + return STATUS_SUCCESS; +} + +static NTSTATUS release_freetype_lib(void) +{ + pFTC_Manager_Done(cache_manager); + pFT_Done_FreeType(library); + return STATUS_SUCCESS; +} + #else /* HAVE_FREETYPE */ -BOOL init_freetype(void) -{ - return FALSE; -} - -void release_freetype(void) -{ -} - 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; }