mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 23:02:16 +00:00
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,
|
extern int dwrite_outline_push_points(struct dwrite_outline *outline, const D2D1_POINT_2F *points,
|
||||||
unsigned int count) DECLSPEC_HIDDEN;
|
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,
|
extern HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph,
|
||||||
DWRITE_GLYPH_METRICS *metrics) DECLSPEC_HIDDEN;
|
DWRITE_GLYPH_METRICS *metrics) DECLSPEC_HIDDEN;
|
||||||
extern void freetype_notify_cacheremove(IDWriteFontFace5 *fontface) 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;
|
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,
|
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;
|
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;
|
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
|
#include FT_TRUETYPE_TABLES_H
|
||||||
#endif /* HAVE_FT2BUILD_H */
|
#endif /* HAVE_FT2BUILD_H */
|
||||||
|
|
||||||
|
#include "ntstatus.h"
|
||||||
|
#define WIN32_NO_STATUS
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
|
@ -60,6 +62,8 @@ typedef struct
|
||||||
FT_Int patch;
|
FT_Int patch;
|
||||||
} FT_Version_t;
|
} FT_Version_t;
|
||||||
|
|
||||||
|
static const struct font_callback_funcs *callback_funcs;
|
||||||
|
|
||||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f = NULL
|
#define MAKE_FUNCPTR(f) static typeof(f) * p##f = NULL
|
||||||
MAKE_FUNCPTR(FT_Done_FreeType);
|
MAKE_FUNCPTR(FT_Done_FreeType);
|
||||||
MAKE_FUNCPTR(FT_Done_Glyph);
|
MAKE_FUNCPTR(FT_Done_Glyph);
|
||||||
|
@ -92,86 +96,44 @@ MAKE_FUNCPTR(FTC_Manager_RemoveFaceID);
|
||||||
#undef MAKE_FUNCPTR
|
#undef MAKE_FUNCPTR
|
||||||
static FT_Error (*pFT_Outline_EmboldenXY)(FT_Outline *, FT_Pos, FT_Pos);
|
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)
|
static void face_finalizer(void *object)
|
||||||
{
|
{
|
||||||
FT_Face face = object;
|
FT_Face face = object;
|
||||||
struct face_finalizer_data *data = (struct face_finalizer_data *)face->generic.data;
|
callback_funcs->release_font_data((struct font_data_context *)face->generic.data);
|
||||||
|
|
||||||
IDWriteFontFileStream_ReleaseFileFragment(data->stream, data->context);
|
|
||||||
IDWriteFontFileStream_Release(data->stream);
|
|
||||||
heap_free(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static FT_Error face_requester(FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face *face)
|
static FT_Error face_requester(FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face *face)
|
||||||
{
|
{
|
||||||
IDWriteFontFace *fontface = (IDWriteFontFace*)face_id;
|
struct font_data_context *context;
|
||||||
IDWriteFontFileStream *stream;
|
|
||||||
IDWriteFontFile *file;
|
|
||||||
const void *data_ptr;
|
const void *data_ptr;
|
||||||
UINT32 index, count;
|
|
||||||
FT_Error fterror;
|
FT_Error fterror;
|
||||||
UINT64 data_size;
|
UINT64 data_size;
|
||||||
void *context;
|
UINT32 index;
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
*face = NULL;
|
*face = NULL;
|
||||||
|
|
||||||
if (!fontface) {
|
if (!face_id)
|
||||||
|
{
|
||||||
WARN("NULL fontface requested.\n");
|
WARN("NULL fontface requested.\n");
|
||||||
return FT_Err_Ok;
|
return FT_Err_Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = 1;
|
if (callback_funcs->get_font_data(face_id, &data_ptr, &data_size, &index, &context))
|
||||||
hr = IDWriteFontFace_GetFiles(fontface, &count, &file);
|
|
||||||
if (FAILED(hr))
|
|
||||||
return FT_Err_Ok;
|
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);
|
fterror = pFT_New_Memory_Face(library, data_ptr, data_size, index, face);
|
||||||
if (fterror == FT_Err_Ok) {
|
if (fterror == FT_Err_Ok)
|
||||||
struct face_finalizer_data *data;
|
{
|
||||||
|
(*face)->generic.data = context;
|
||||||
data = heap_alloc(sizeof(*data));
|
|
||||||
data->stream = stream;
|
|
||||||
data->context = context;
|
|
||||||
|
|
||||||
(*face)->generic.data = data;
|
|
||||||
(*face)->generic.finalizer = face_finalizer;
|
(*face)->generic.finalizer = face_finalizer;
|
||||||
return fterror;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
IDWriteFontFileStream_ReleaseFileFragment(stream, context);
|
callback_funcs->release_font_data(context);
|
||||||
|
|
||||||
fail:
|
|
||||||
IDWriteFontFileStream_Release(stream);
|
|
||||||
|
|
||||||
return fterror;
|
return fterror;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL init_freetype(void)
|
static BOOL init_freetype(void)
|
||||||
{
|
{
|
||||||
FT_Version_t FT_Version;
|
FT_Version_t FT_Version;
|
||||||
|
|
||||||
|
@ -243,12 +205,6 @@ sym_not_found:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void release_freetype(void)
|
|
||||||
{
|
|
||||||
pFTC_Manager_Done(cache_manager);
|
|
||||||
pFT_Done_FreeType(library);
|
|
||||||
}
|
|
||||||
|
|
||||||
void freetype_notify_cacheremove(IDWriteFontFace5 *fontface)
|
void freetype_notify_cacheremove(IDWriteFontFace5 *fontface)
|
||||||
{
|
{
|
||||||
EnterCriticalSection(&freetype_cs);
|
EnterCriticalSection(&freetype_cs);
|
||||||
|
@ -790,17 +746,22 @@ INT32 freetype_get_glyph_advance(IDWriteFontFace5 *fontface, FLOAT emSize, UINT1
|
||||||
return advance;
|
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 */
|
#else /* HAVE_FREETYPE */
|
||||||
|
|
||||||
BOOL init_freetype(void)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void release_freetype(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void freetype_notify_cacheremove(IDWriteFontFace5 *fontface)
|
void freetype_notify_cacheremove(IDWriteFontFace5 *fontface)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -838,4 +799,23 @@ INT32 freetype_get_glyph_advance(IDWriteFontFace5 *fontface, FLOAT emSize, UINT1
|
||||||
return 0;
|
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 */
|
#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);
|
WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
|
||||||
|
|
||||||
|
HMODULE dwrite_module = 0;
|
||||||
static IDWriteFactory7 *shared_factory;
|
static IDWriteFactory7 *shared_factory;
|
||||||
static void release_shared_factory(IDWriteFactory7 *factory);
|
static void release_shared_factory(IDWriteFactory7 *factory);
|
||||||
|
|
||||||
|
@ -42,14 +43,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved)
|
||||||
switch (reason)
|
switch (reason)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
|
dwrite_module = hinstDLL;
|
||||||
DisableThreadLibraryCalls( hinstDLL );
|
DisableThreadLibraryCalls( hinstDLL );
|
||||||
init_freetype();
|
init_font_backend();
|
||||||
init_local_fontfile_loader();
|
init_local_fontfile_loader();
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
if (reserved) break;
|
if (reserved) break;
|
||||||
release_shared_factory(shared_factory);
|
release_shared_factory(shared_factory);
|
||||||
release_freetype();
|
release_font_backend();
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue