Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
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;
}
--
2.30.2