mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 16:45:48 +00:00
dwrite: Create backend font objects for faces.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
78fbea1672
commit
7639820cfb
|
@ -241,6 +241,10 @@ extern UINT16 opentype_cmap_get_glyph(const struct dwrite_cmap *cmap, unsigned i
|
|||
extern HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_cmap *cmap, unsigned int max_count,
|
||||
DWRITE_UNICODE_RANGE *ranges, unsigned int *count) DECLSPEC_HIDDEN;
|
||||
|
||||
struct dwrite_fontface;
|
||||
typedef void * font_object_handle;
|
||||
typedef font_object_handle (*p_dwrite_fontface_get_font_object)(struct dwrite_fontface *fontface);
|
||||
|
||||
struct dwrite_fontface
|
||||
{
|
||||
IDWriteFontFace5 IDWriteFontFace5_iface;
|
||||
|
@ -253,6 +257,9 @@ struct dwrite_fontface
|
|||
|
||||
IDWriteFactory7 *factory;
|
||||
struct fontfacecached *cached;
|
||||
font_object_handle font_object;
|
||||
void *data_context;
|
||||
p_dwrite_fontface_get_font_object get_font_object;
|
||||
|
||||
USHORT simulations;
|
||||
DWRITE_FONT_FACE_TYPE type;
|
||||
|
@ -731,6 +738,8 @@ struct font_callback_funcs
|
|||
|
||||
struct font_backend_funcs
|
||||
{
|
||||
font_object_handle (CDECL *create_font_object)(const void *data_ptr, UINT64 data_size, unsigned int index);
|
||||
void (CDECL *release_font_object)(font_object_handle object);
|
||||
void (CDECL *notify_release)(void *key);
|
||||
int (CDECL *get_glyph_outline)(void *key, float em_size, unsigned int simulations, UINT16 glyph,
|
||||
struct dwrite_outline *outline);
|
||||
|
|
|
@ -636,8 +636,6 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface)
|
|||
IDWriteFontFace5_ReleaseFontTable(iface, fontface->kern.context);
|
||||
if (fontface->file)
|
||||
IDWriteFontFile_Release(fontface->file);
|
||||
if (fontface->stream)
|
||||
IDWriteFontFileStream_Release(fontface->stream);
|
||||
if (fontface->names)
|
||||
IDWriteLocalizedStrings_Release(fontface->names);
|
||||
if (fontface->family_names)
|
||||
|
@ -652,6 +650,12 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface)
|
|||
heap_free(fontface->glyphs[i]);
|
||||
|
||||
font_funcs->notify_release(iface);
|
||||
font_funcs->release_font_object(fontface->font_object);
|
||||
if (fontface->stream)
|
||||
{
|
||||
IDWriteFontFileStream_ReleaseFileFragment(fontface->stream, fontface->data_context);
|
||||
IDWriteFontFileStream_Release(fontface->stream);
|
||||
}
|
||||
|
||||
dwrite_cmap_release(&fontface->cmap);
|
||||
IDWriteFactory7_Release(fontface->factory);
|
||||
|
@ -5013,6 +5017,32 @@ HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_ke
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static font_object_handle dwrite_fontface_get_font_object(struct dwrite_fontface *fontface)
|
||||
{
|
||||
font_object_handle font_object;
|
||||
const void *data_ptr;
|
||||
void *data_context;
|
||||
UINT64 size;
|
||||
|
||||
if (!fontface->font_object && SUCCEEDED(IDWriteFontFileStream_GetFileSize(fontface->stream, &size)))
|
||||
{
|
||||
if (SUCCEEDED(IDWriteFontFileStream_ReadFileFragment(fontface->stream, &data_ptr, 0, size, &data_context)))
|
||||
{
|
||||
if (!(font_object = font_funcs->create_font_object(data_ptr, size, fontface->index)))
|
||||
{
|
||||
WARN("Backend failed to create font object.\n");
|
||||
IDWriteFontFileStream_ReleaseFileFragment(fontface->stream, data_context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (InterlockedCompareExchangePointer((void **)&fontface->font_object, font_object, NULL))
|
||||
font_funcs->release_font_object(font_object);
|
||||
}
|
||||
}
|
||||
|
||||
return fontface->font_object;
|
||||
}
|
||||
|
||||
HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_list, IDWriteFontFace5 **ret)
|
||||
{
|
||||
struct file_stream_desc stream_desc;
|
||||
|
@ -5102,6 +5132,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
|
|||
release_font_data(font_data);
|
||||
|
||||
fontface->cached = factory_cache_fontface(fontface->factory, cached_list, &fontface->IDWriteFontFace5_iface);
|
||||
fontface->get_font_object = dwrite_fontface_get_font_object;
|
||||
|
||||
*ret = &fontface->IDWriteFontFace5_iface;
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ typedef struct
|
|||
static const struct font_callback_funcs *callback_funcs;
|
||||
|
||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f = NULL
|
||||
MAKE_FUNCPTR(FT_Done_Face);
|
||||
MAKE_FUNCPTR(FT_Done_FreeType);
|
||||
MAKE_FUNCPTR(FT_Done_Glyph);
|
||||
MAKE_FUNCPTR(FT_Get_First_Char);
|
||||
|
@ -143,12 +144,14 @@ static BOOL init_freetype(void)
|
|||
FT_Version_t FT_Version;
|
||||
|
||||
ft_handle = dlopen(SONAME_LIBFREETYPE, RTLD_NOW);
|
||||
if (!ft_handle) {
|
||||
if (!ft_handle)
|
||||
{
|
||||
WINE_MESSAGE("Wine cannot find the FreeType font library.\n");
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define LOAD_FUNCPTR(f) if((p##f = dlsym(ft_handle, #f)) == NULL){WARN("Can't find symbol %s\n", #f); goto sym_not_found;}
|
||||
LOAD_FUNCPTR(FT_Done_Face)
|
||||
LOAD_FUNCPTR(FT_Done_FreeType)
|
||||
LOAD_FUNCPTR(FT_Done_Glyph)
|
||||
LOAD_FUNCPTR(FT_Get_First_Char)
|
||||
|
@ -211,6 +214,23 @@ sym_not_found:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static font_object_handle CDECL freetype_create_font_object(const void *data_ptr, UINT64 data_size, unsigned int index)
|
||||
{
|
||||
FT_Face face = NULL;
|
||||
FT_Error fterror;
|
||||
|
||||
fterror = pFT_New_Memory_Face(library, data_ptr, data_size, index, &face);
|
||||
if (fterror != FT_Err_Ok)
|
||||
WARN("Failed to create a face object, error %d.\n", fterror);
|
||||
|
||||
return face;
|
||||
}
|
||||
|
||||
static void CDECL freetype_release_font_object(font_object_handle object)
|
||||
{
|
||||
pFT_Done_Face(object);
|
||||
}
|
||||
|
||||
static void CDECL freetype_notify_release(void *key)
|
||||
{
|
||||
RtlEnterCriticalSection(&freetype_cs);
|
||||
|
@ -777,6 +797,8 @@ static INT32 CDECL freetype_get_glyph_advance(void *key, float emSize, UINT16 in
|
|||
|
||||
const static struct font_backend_funcs freetype_funcs =
|
||||
{
|
||||
freetype_create_font_object,
|
||||
freetype_release_font_object,
|
||||
freetype_notify_release,
|
||||
freetype_get_glyph_outline,
|
||||
freetype_get_glyph_count,
|
||||
|
@ -803,6 +825,15 @@ static NTSTATUS release_freetype_lib(void)
|
|||
|
||||
#else /* HAVE_FREETYPE */
|
||||
|
||||
static font_object_handle CDECL null_create_font_object(const void *data_ptr, UINT64 data_size, unsigned int index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void CDECL null_release_font_object(font_object_handle object)
|
||||
{
|
||||
}
|
||||
|
||||
static void CDECL null_notify_release(void *key)
|
||||
{
|
||||
}
|
||||
|
@ -842,6 +873,8 @@ static void CDECL null_get_design_glyph_metrics(void *key, UINT16 upem, UINT16 a
|
|||
|
||||
const static struct font_backend_funcs null_funcs =
|
||||
{
|
||||
null_create_font_object,
|
||||
null_release_font_object,
|
||||
null_notify_release,
|
||||
null_get_glyph_outline,
|
||||
null_get_glyph_count,
|
||||
|
|
Loading…
Reference in a new issue