dwrite: Do not use freetype cache for design glyph metrics.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
822a49d524
commit
6356717c47
|
@ -260,6 +260,7 @@ struct dwrite_fontface
|
||||||
font_object_handle font_object;
|
font_object_handle font_object;
|
||||||
void *data_context;
|
void *data_context;
|
||||||
p_dwrite_fontface_get_font_object get_font_object;
|
p_dwrite_fontface_get_font_object get_font_object;
|
||||||
|
CRITICAL_SECTION cs;
|
||||||
|
|
||||||
USHORT simulations;
|
USHORT simulations;
|
||||||
DWRITE_FONT_FACE_TYPE type;
|
DWRITE_FONT_FACE_TYPE type;
|
||||||
|
@ -748,7 +749,7 @@ struct font_backend_funcs
|
||||||
BOOL *has_contours);
|
BOOL *has_contours);
|
||||||
void (CDECL *get_glyph_bbox)(struct dwrite_glyphbitmap *bitmap_desc);
|
void (CDECL *get_glyph_bbox)(struct dwrite_glyphbitmap *bitmap_desc);
|
||||||
BOOL (CDECL *get_glyph_bitmap)(struct dwrite_glyphbitmap *bitmap_desc);
|
BOOL (CDECL *get_glyph_bitmap)(struct dwrite_glyphbitmap *bitmap_desc);
|
||||||
void (CDECL *get_design_glyph_metrics)(void *key, UINT16 upem, UINT16 ascent, unsigned int simulations,
|
void (CDECL *get_design_glyph_metrics)(font_object_handle object, UINT16 upem, UINT16 ascent, unsigned int simulations,
|
||||||
UINT16 glyph, DWRITE_GLYPH_METRICS *metrics);
|
UINT16 glyph, DWRITE_GLYPH_METRICS *metrics);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -659,6 +659,7 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface)
|
||||||
|
|
||||||
dwrite_cmap_release(&fontface->cmap);
|
dwrite_cmap_release(&fontface->cmap);
|
||||||
IDWriteFactory7_Release(fontface->factory);
|
IDWriteFactory7_Release(fontface->factory);
|
||||||
|
DeleteCriticalSection(&fontface->cs);
|
||||||
heap_free(fontface);
|
heap_free(fontface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -745,8 +746,8 @@ static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace5 *ifa
|
||||||
UINT16 const *glyphs, UINT32 glyph_count, DWRITE_GLYPH_METRICS *ret, BOOL is_sideways)
|
UINT16 const *glyphs, UINT32 glyph_count, DWRITE_GLYPH_METRICS *ret, BOOL is_sideways)
|
||||||
{
|
{
|
||||||
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
|
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
|
||||||
|
HRESULT hr = S_OK;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
TRACE("%p, %p, %u, %p, %d.\n", iface, glyphs, glyph_count, ret, is_sideways);
|
TRACE("%p, %p, %u, %p, %d.\n", iface, glyphs, glyph_count, ret, is_sideways);
|
||||||
|
|
||||||
|
@ -756,22 +757,23 @@ static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace5 *ifa
|
||||||
if (is_sideways)
|
if (is_sideways)
|
||||||
FIXME("sideways metrics are not supported.\n");
|
FIXME("sideways metrics are not supported.\n");
|
||||||
|
|
||||||
for (i = 0; i < glyph_count; i++) {
|
EnterCriticalSection(&fontface->cs);
|
||||||
|
for (i = 0; i < glyph_count; ++i)
|
||||||
|
{
|
||||||
DWRITE_GLYPH_METRICS metrics;
|
DWRITE_GLYPH_METRICS metrics;
|
||||||
|
|
||||||
hr = get_cached_glyph_metrics(fontface, glyphs[i], &metrics);
|
if (get_cached_glyph_metrics(fontface, glyphs[i], &metrics) != S_OK)
|
||||||
if (hr != S_OK)
|
|
||||||
{
|
{
|
||||||
font_funcs->get_design_glyph_metrics(iface, fontface->metrics.designUnitsPerEm,
|
font_funcs->get_design_glyph_metrics(fontface->get_font_object(fontface),
|
||||||
fontface->typo_metrics.ascent, fontface->simulations, glyphs[i], &metrics);
|
fontface->metrics.designUnitsPerEm, fontface->typo_metrics.ascent,
|
||||||
hr = set_cached_glyph_metrics(fontface, glyphs[i], &metrics);
|
fontface->simulations, glyphs[i], &metrics);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr = set_cached_glyph_metrics(fontface, glyphs[i], &metrics))) break;
|
||||||
return hr;
|
|
||||||
}
|
}
|
||||||
ret[i] = metrics;
|
ret[i] = metrics;
|
||||||
}
|
}
|
||||||
|
LeaveCriticalSection(&fontface->cs);
|
||||||
|
|
||||||
return S_OK;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI dwritefontface_GetGlyphIndices(IDWriteFontFace5 *iface, UINT32 const *codepoints,
|
static HRESULT WINAPI dwritefontface_GetGlyphIndices(IDWriteFontFace5 *iface, UINT32 const *codepoints,
|
||||||
|
@ -5076,6 +5078,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
|
||||||
IDWriteFontFile_AddRef(fontface->file);
|
IDWriteFontFile_AddRef(fontface->file);
|
||||||
fontface->stream = desc->stream;
|
fontface->stream = desc->stream;
|
||||||
IDWriteFontFileStream_AddRef(fontface->stream);
|
IDWriteFontFileStream_AddRef(fontface->stream);
|
||||||
|
InitializeCriticalSection(&fontface->cs);
|
||||||
|
|
||||||
stream_desc.stream = fontface->stream;
|
stream_desc.stream = fontface->stream;
|
||||||
stream_desc.face_type = desc->face_type;
|
stream_desc.face_type = desc->face_type;
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
#include FT_OUTLINE_H
|
#include FT_OUTLINE_H
|
||||||
#include FT_TRUETYPE_TABLES_H
|
#include FT_TRUETYPE_TABLES_H
|
||||||
|
#include FT_SIZES_H
|
||||||
#endif /* HAVE_FT2BUILD_H */
|
#endif /* HAVE_FT2BUILD_H */
|
||||||
|
|
||||||
#include "ntstatus.h"
|
#include "ntstatus.h"
|
||||||
|
@ -69,9 +70,11 @@ typedef struct
|
||||||
static const struct font_callback_funcs *callback_funcs;
|
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_Activate_Size);
|
||||||
MAKE_FUNCPTR(FT_Done_Face);
|
MAKE_FUNCPTR(FT_Done_Face);
|
||||||
MAKE_FUNCPTR(FT_Done_FreeType);
|
MAKE_FUNCPTR(FT_Done_FreeType);
|
||||||
MAKE_FUNCPTR(FT_Done_Glyph);
|
MAKE_FUNCPTR(FT_Done_Glyph);
|
||||||
|
MAKE_FUNCPTR(FT_Done_Size);
|
||||||
MAKE_FUNCPTR(FT_Get_First_Char);
|
MAKE_FUNCPTR(FT_Get_First_Char);
|
||||||
MAKE_FUNCPTR(FT_Get_Kerning);
|
MAKE_FUNCPTR(FT_Get_Kerning);
|
||||||
MAKE_FUNCPTR(FT_Get_Sfnt_Table);
|
MAKE_FUNCPTR(FT_Get_Sfnt_Table);
|
||||||
|
@ -84,6 +87,7 @@ MAKE_FUNCPTR(FT_Load_Glyph);
|
||||||
MAKE_FUNCPTR(FT_Matrix_Multiply);
|
MAKE_FUNCPTR(FT_Matrix_Multiply);
|
||||||
MAKE_FUNCPTR(FT_MulDiv);
|
MAKE_FUNCPTR(FT_MulDiv);
|
||||||
MAKE_FUNCPTR(FT_New_Memory_Face);
|
MAKE_FUNCPTR(FT_New_Memory_Face);
|
||||||
|
MAKE_FUNCPTR(FT_New_Size);
|
||||||
MAKE_FUNCPTR(FT_Outline_Copy);
|
MAKE_FUNCPTR(FT_Outline_Copy);
|
||||||
MAKE_FUNCPTR(FT_Outline_Decompose);
|
MAKE_FUNCPTR(FT_Outline_Decompose);
|
||||||
MAKE_FUNCPTR(FT_Outline_Done);
|
MAKE_FUNCPTR(FT_Outline_Done);
|
||||||
|
@ -92,6 +96,7 @@ MAKE_FUNCPTR(FT_Outline_Get_Bitmap);
|
||||||
MAKE_FUNCPTR(FT_Outline_New);
|
MAKE_FUNCPTR(FT_Outline_New);
|
||||||
MAKE_FUNCPTR(FT_Outline_Transform);
|
MAKE_FUNCPTR(FT_Outline_Transform);
|
||||||
MAKE_FUNCPTR(FT_Outline_Translate);
|
MAKE_FUNCPTR(FT_Outline_Translate);
|
||||||
|
MAKE_FUNCPTR(FT_Set_Pixel_Sizes);
|
||||||
MAKE_FUNCPTR(FTC_ImageCache_Lookup);
|
MAKE_FUNCPTR(FTC_ImageCache_Lookup);
|
||||||
MAKE_FUNCPTR(FTC_ImageCache_New);
|
MAKE_FUNCPTR(FTC_ImageCache_New);
|
||||||
MAKE_FUNCPTR(FTC_Manager_New);
|
MAKE_FUNCPTR(FTC_Manager_New);
|
||||||
|
@ -139,6 +144,28 @@ static FT_Error face_requester(FTC_FaceID face_id, FT_Library library, FT_Pointe
|
||||||
return fterror;
|
return fterror;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FT_Size freetype_set_face_size(FT_Face face, FT_UInt emsize)
|
||||||
|
{
|
||||||
|
FT_Size size;
|
||||||
|
|
||||||
|
if (pFT_New_Size(face, &size)) return NULL;
|
||||||
|
|
||||||
|
pFT_Activate_Size(size);
|
||||||
|
|
||||||
|
if (pFT_Set_Pixel_Sizes(face, emsize, emsize))
|
||||||
|
{
|
||||||
|
pFT_Done_Size(size);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL freetype_glyph_has_contours(FT_Face face)
|
||||||
|
{
|
||||||
|
return face->glyph->format == FT_GLYPH_FORMAT_OUTLINE && face->glyph->outline.n_contours;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL init_freetype(void)
|
static BOOL init_freetype(void)
|
||||||
{
|
{
|
||||||
FT_Version_t FT_Version;
|
FT_Version_t FT_Version;
|
||||||
|
@ -151,9 +178,11 @@ static BOOL init_freetype(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOAD_FUNCPTR(f) if((p##f = dlsym(ft_handle, #f)) == NULL){WARN("Can't find symbol %s\n", #f); goto sym_not_found;}
|
#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_Activate_Size)
|
||||||
LOAD_FUNCPTR(FT_Done_Face)
|
LOAD_FUNCPTR(FT_Done_Face)
|
||||||
LOAD_FUNCPTR(FT_Done_FreeType)
|
LOAD_FUNCPTR(FT_Done_FreeType)
|
||||||
LOAD_FUNCPTR(FT_Done_Glyph)
|
LOAD_FUNCPTR(FT_Done_Glyph)
|
||||||
|
LOAD_FUNCPTR(FT_Done_Size)
|
||||||
LOAD_FUNCPTR(FT_Get_First_Char)
|
LOAD_FUNCPTR(FT_Get_First_Char)
|
||||||
LOAD_FUNCPTR(FT_Get_Kerning)
|
LOAD_FUNCPTR(FT_Get_Kerning)
|
||||||
LOAD_FUNCPTR(FT_Get_Sfnt_Table)
|
LOAD_FUNCPTR(FT_Get_Sfnt_Table)
|
||||||
|
@ -166,6 +195,7 @@ static BOOL init_freetype(void)
|
||||||
LOAD_FUNCPTR(FT_Matrix_Multiply)
|
LOAD_FUNCPTR(FT_Matrix_Multiply)
|
||||||
LOAD_FUNCPTR(FT_MulDiv)
|
LOAD_FUNCPTR(FT_MulDiv)
|
||||||
LOAD_FUNCPTR(FT_New_Memory_Face)
|
LOAD_FUNCPTR(FT_New_Memory_Face)
|
||||||
|
LOAD_FUNCPTR(FT_New_Size)
|
||||||
LOAD_FUNCPTR(FT_Outline_Copy)
|
LOAD_FUNCPTR(FT_Outline_Copy)
|
||||||
LOAD_FUNCPTR(FT_Outline_Decompose)
|
LOAD_FUNCPTR(FT_Outline_Decompose)
|
||||||
LOAD_FUNCPTR(FT_Outline_Done)
|
LOAD_FUNCPTR(FT_Outline_Done)
|
||||||
|
@ -174,6 +204,7 @@ static BOOL init_freetype(void)
|
||||||
LOAD_FUNCPTR(FT_Outline_New)
|
LOAD_FUNCPTR(FT_Outline_New)
|
||||||
LOAD_FUNCPTR(FT_Outline_Transform)
|
LOAD_FUNCPTR(FT_Outline_Transform)
|
||||||
LOAD_FUNCPTR(FT_Outline_Translate)
|
LOAD_FUNCPTR(FT_Outline_Translate)
|
||||||
|
LOAD_FUNCPTR(FT_Set_Pixel_Sizes)
|
||||||
LOAD_FUNCPTR(FTC_ImageCache_Lookup)
|
LOAD_FUNCPTR(FTC_ImageCache_Lookup)
|
||||||
LOAD_FUNCPTR(FTC_ImageCache_New)
|
LOAD_FUNCPTR(FTC_ImageCache_New)
|
||||||
LOAD_FUNCPTR(FTC_Manager_New)
|
LOAD_FUNCPTR(FTC_Manager_New)
|
||||||
|
@ -238,43 +269,37 @@ static void CDECL freetype_notify_release(void *key)
|
||||||
RtlLeaveCriticalSection(&freetype_cs);
|
RtlLeaveCriticalSection(&freetype_cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CDECL freetype_get_design_glyph_metrics(void *key, UINT16 upem, UINT16 ascent,
|
static void CDECL freetype_get_design_glyph_metrics(font_object_handle object, UINT16 upem, UINT16 ascent,
|
||||||
unsigned int simulations, UINT16 glyph, DWRITE_GLYPH_METRICS *ret)
|
unsigned int simulations, UINT16 glyph, DWRITE_GLYPH_METRICS *ret)
|
||||||
{
|
{
|
||||||
FTC_ScalerRec scaler;
|
FT_Face face = object;
|
||||||
FT_Size size;
|
FT_Size size;
|
||||||
|
|
||||||
scaler.face_id = key;
|
if (!(size = freetype_set_face_size(face, upem)))
|
||||||
scaler.width = upem;
|
return;
|
||||||
scaler.height = upem;
|
|
||||||
scaler.pixel = 1;
|
|
||||||
scaler.x_res = 0;
|
|
||||||
scaler.y_res = 0;
|
|
||||||
|
|
||||||
RtlEnterCriticalSection(&freetype_cs);
|
if (!pFT_Load_Glyph(face, glyph, FT_LOAD_NO_SCALE))
|
||||||
if (pFTC_Manager_LookupSize(cache_manager, &scaler, &size) == 0) {
|
{
|
||||||
if (pFT_Load_Glyph(size->face, glyph, FT_LOAD_NO_SCALE) == 0) {
|
FT_Glyph_Metrics *metrics = &face->glyph->metrics;
|
||||||
FT_Glyph_Metrics *metrics = &size->face->glyph->metrics;
|
|
||||||
|
|
||||||
ret->leftSideBearing = metrics->horiBearingX;
|
ret->leftSideBearing = metrics->horiBearingX;
|
||||||
ret->advanceWidth = metrics->horiAdvance;
|
ret->advanceWidth = metrics->horiAdvance;
|
||||||
ret->rightSideBearing = metrics->horiAdvance - metrics->horiBearingX - metrics->width;
|
ret->rightSideBearing = metrics->horiAdvance - metrics->horiBearingX - metrics->width;
|
||||||
|
|
||||||
ret->advanceHeight = metrics->vertAdvance;
|
ret->advanceHeight = metrics->vertAdvance;
|
||||||
ret->verticalOriginY = ascent;
|
ret->verticalOriginY = ascent;
|
||||||
ret->topSideBearing = ascent - metrics->horiBearingY;
|
ret->topSideBearing = ascent - metrics->horiBearingY;
|
||||||
ret->bottomSideBearing = metrics->vertAdvance - metrics->height - ret->topSideBearing;
|
ret->bottomSideBearing = metrics->vertAdvance - metrics->height - ret->topSideBearing;
|
||||||
|
|
||||||
/* Adjust in case of bold simulation, glyphs without contours are ignored. */
|
/* Adjust in case of bold simulation, glyphs without contours are ignored. */
|
||||||
if (simulations & DWRITE_FONT_SIMULATIONS_BOLD &&
|
if (simulations & DWRITE_FONT_SIMULATIONS_BOLD && freetype_glyph_has_contours(face))
|
||||||
size->face->glyph->format == FT_GLYPH_FORMAT_OUTLINE && size->face->glyph->outline.n_contours)
|
{
|
||||||
{
|
if (ret->advanceWidth)
|
||||||
if (ret->advanceWidth)
|
ret->advanceWidth += (upem + 49) / 50;
|
||||||
ret->advanceWidth += (upem + 49) / 50;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
RtlLeaveCriticalSection(&freetype_cs);
|
|
||||||
|
pFT_Done_Size(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct decompose_context
|
struct decompose_context
|
||||||
|
@ -859,7 +884,7 @@ static BOOL CDECL null_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CDECL null_get_design_glyph_metrics(void *key, UINT16 upem, UINT16 ascent, unsigned int simulations,
|
static void CDECL null_get_design_glyph_metrics(font_object_handle object, UINT16 upem, UINT16 ascent, unsigned int simulations,
|
||||||
UINT16 glyph, DWRITE_GLYPH_METRICS *metrics)
|
UINT16 glyph, DWRITE_GLYPH_METRICS *metrics)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue