dwrite: Introduce callback interface to initialize freetype face objects.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
ff983fe75f
commit
f3d777ba7d
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user