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;
|
||||
void *data_context;
|
||||
p_dwrite_fontface_get_font_object get_font_object;
|
||||
CRITICAL_SECTION cs;
|
||||
|
||||
USHORT simulations;
|
||||
DWRITE_FONT_FACE_TYPE type;
|
||||
|
@ -748,7 +749,7 @@ struct font_backend_funcs
|
|||
BOOL *has_contours);
|
||||
void (CDECL *get_glyph_bbox)(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);
|
||||
};
|
||||
|
||||
|
|
|
@ -659,6 +659,7 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface)
|
|||
|
||||
dwrite_cmap_release(&fontface->cmap);
|
||||
IDWriteFactory7_Release(fontface->factory);
|
||||
DeleteCriticalSection(&fontface->cs);
|
||||
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)
|
||||
{
|
||||
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
|
||||
HRESULT hr = S_OK;
|
||||
unsigned int i;
|
||||
HRESULT hr;
|
||||
|
||||
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)
|
||||
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;
|
||||
|
||||
hr = get_cached_glyph_metrics(fontface, glyphs[i], &metrics);
|
||||
if (hr != S_OK)
|
||||
if (get_cached_glyph_metrics(fontface, glyphs[i], &metrics) != S_OK)
|
||||
{
|
||||
font_funcs->get_design_glyph_metrics(iface, fontface->metrics.designUnitsPerEm,
|
||||
fontface->typo_metrics.ascent, fontface->simulations, glyphs[i], &metrics);
|
||||
hr = set_cached_glyph_metrics(fontface, glyphs[i], &metrics);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
font_funcs->get_design_glyph_metrics(fontface->get_font_object(fontface),
|
||||
fontface->metrics.designUnitsPerEm, fontface->typo_metrics.ascent,
|
||||
fontface->simulations, glyphs[i], &metrics);
|
||||
if (FAILED(hr = set_cached_glyph_metrics(fontface, glyphs[i], &metrics))) break;
|
||||
}
|
||||
ret[i] = metrics;
|
||||
}
|
||||
LeaveCriticalSection(&fontface->cs);
|
||||
|
||||
return S_OK;
|
||||
return hr;
|
||||
}
|
||||
|
||||
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);
|
||||
fontface->stream = desc->stream;
|
||||
IDWriteFontFileStream_AddRef(fontface->stream);
|
||||
InitializeCriticalSection(&fontface->cs);
|
||||
|
||||
stream_desc.stream = fontface->stream;
|
||||
stream_desc.face_type = desc->face_type;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include FT_FREETYPE_H
|
||||
#include FT_OUTLINE_H
|
||||
#include FT_TRUETYPE_TABLES_H
|
||||
#include FT_SIZES_H
|
||||
#endif /* HAVE_FT2BUILD_H */
|
||||
|
||||
#include "ntstatus.h"
|
||||
|
@ -69,9 +70,11 @@ typedef struct
|
|||
static const struct font_callback_funcs *callback_funcs;
|
||||
|
||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f = NULL
|
||||
MAKE_FUNCPTR(FT_Activate_Size);
|
||||
MAKE_FUNCPTR(FT_Done_Face);
|
||||
MAKE_FUNCPTR(FT_Done_FreeType);
|
||||
MAKE_FUNCPTR(FT_Done_Glyph);
|
||||
MAKE_FUNCPTR(FT_Done_Size);
|
||||
MAKE_FUNCPTR(FT_Get_First_Char);
|
||||
MAKE_FUNCPTR(FT_Get_Kerning);
|
||||
MAKE_FUNCPTR(FT_Get_Sfnt_Table);
|
||||
|
@ -84,6 +87,7 @@ MAKE_FUNCPTR(FT_Load_Glyph);
|
|||
MAKE_FUNCPTR(FT_Matrix_Multiply);
|
||||
MAKE_FUNCPTR(FT_MulDiv);
|
||||
MAKE_FUNCPTR(FT_New_Memory_Face);
|
||||
MAKE_FUNCPTR(FT_New_Size);
|
||||
MAKE_FUNCPTR(FT_Outline_Copy);
|
||||
MAKE_FUNCPTR(FT_Outline_Decompose);
|
||||
MAKE_FUNCPTR(FT_Outline_Done);
|
||||
|
@ -92,6 +96,7 @@ MAKE_FUNCPTR(FT_Outline_Get_Bitmap);
|
|||
MAKE_FUNCPTR(FT_Outline_New);
|
||||
MAKE_FUNCPTR(FT_Outline_Transform);
|
||||
MAKE_FUNCPTR(FT_Outline_Translate);
|
||||
MAKE_FUNCPTR(FT_Set_Pixel_Sizes);
|
||||
MAKE_FUNCPTR(FTC_ImageCache_Lookup);
|
||||
MAKE_FUNCPTR(FTC_ImageCache_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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;}
|
||||
LOAD_FUNCPTR(FT_Activate_Size)
|
||||
LOAD_FUNCPTR(FT_Done_Face)
|
||||
LOAD_FUNCPTR(FT_Done_FreeType)
|
||||
LOAD_FUNCPTR(FT_Done_Glyph)
|
||||
LOAD_FUNCPTR(FT_Done_Size)
|
||||
LOAD_FUNCPTR(FT_Get_First_Char)
|
||||
LOAD_FUNCPTR(FT_Get_Kerning)
|
||||
LOAD_FUNCPTR(FT_Get_Sfnt_Table)
|
||||
|
@ -166,6 +195,7 @@ static BOOL init_freetype(void)
|
|||
LOAD_FUNCPTR(FT_Matrix_Multiply)
|
||||
LOAD_FUNCPTR(FT_MulDiv)
|
||||
LOAD_FUNCPTR(FT_New_Memory_Face)
|
||||
LOAD_FUNCPTR(FT_New_Size)
|
||||
LOAD_FUNCPTR(FT_Outline_Copy)
|
||||
LOAD_FUNCPTR(FT_Outline_Decompose)
|
||||
LOAD_FUNCPTR(FT_Outline_Done)
|
||||
|
@ -174,6 +204,7 @@ static BOOL init_freetype(void)
|
|||
LOAD_FUNCPTR(FT_Outline_New)
|
||||
LOAD_FUNCPTR(FT_Outline_Transform)
|
||||
LOAD_FUNCPTR(FT_Outline_Translate)
|
||||
LOAD_FUNCPTR(FT_Set_Pixel_Sizes)
|
||||
LOAD_FUNCPTR(FTC_ImageCache_Lookup)
|
||||
LOAD_FUNCPTR(FTC_ImageCache_New)
|
||||
LOAD_FUNCPTR(FTC_Manager_New)
|
||||
|
@ -238,43 +269,37 @@ static void CDECL freetype_notify_release(void *key)
|
|||
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)
|
||||
{
|
||||
FTC_ScalerRec scaler;
|
||||
FT_Face face = object;
|
||||
FT_Size size;
|
||||
|
||||
scaler.face_id = key;
|
||||
scaler.width = upem;
|
||||
scaler.height = upem;
|
||||
scaler.pixel = 1;
|
||||
scaler.x_res = 0;
|
||||
scaler.y_res = 0;
|
||||
if (!(size = freetype_set_face_size(face, upem)))
|
||||
return;
|
||||
|
||||
RtlEnterCriticalSection(&freetype_cs);
|
||||
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 = &size->face->glyph->metrics;
|
||||
if (!pFT_Load_Glyph(face, glyph, FT_LOAD_NO_SCALE))
|
||||
{
|
||||
FT_Glyph_Metrics *metrics = &face->glyph->metrics;
|
||||
|
||||
ret->leftSideBearing = metrics->horiBearingX;
|
||||
ret->advanceWidth = metrics->horiAdvance;
|
||||
ret->rightSideBearing = metrics->horiAdvance - metrics->horiBearingX - metrics->width;
|
||||
ret->leftSideBearing = metrics->horiBearingX;
|
||||
ret->advanceWidth = metrics->horiAdvance;
|
||||
ret->rightSideBearing = metrics->horiAdvance - metrics->horiBearingX - metrics->width;
|
||||
|
||||
ret->advanceHeight = metrics->vertAdvance;
|
||||
ret->verticalOriginY = ascent;
|
||||
ret->topSideBearing = ascent - metrics->horiBearingY;
|
||||
ret->bottomSideBearing = metrics->vertAdvance - metrics->height - ret->topSideBearing;
|
||||
ret->advanceHeight = metrics->vertAdvance;
|
||||
ret->verticalOriginY = ascent;
|
||||
ret->topSideBearing = ascent - metrics->horiBearingY;
|
||||
ret->bottomSideBearing = metrics->vertAdvance - metrics->height - ret->topSideBearing;
|
||||
|
||||
/* Adjust in case of bold simulation, glyphs without contours are ignored. */
|
||||
if (simulations & DWRITE_FONT_SIMULATIONS_BOLD &&
|
||||
size->face->glyph->format == FT_GLYPH_FORMAT_OUTLINE && size->face->glyph->outline.n_contours)
|
||||
{
|
||||
if (ret->advanceWidth)
|
||||
ret->advanceWidth += (upem + 49) / 50;
|
||||
}
|
||||
}
|
||||
/* Adjust in case of bold simulation, glyphs without contours are ignored. */
|
||||
if (simulations & DWRITE_FONT_SIMULATIONS_BOLD && freetype_glyph_has_contours(face))
|
||||
{
|
||||
if (ret->advanceWidth)
|
||||
ret->advanceWidth += (upem + 49) / 50;
|
||||
}
|
||||
}
|
||||
RtlLeaveCriticalSection(&freetype_cs);
|
||||
|
||||
pFT_Done_Size(size);
|
||||
}
|
||||
|
||||
struct decompose_context
|
||||
|
@ -859,7 +884,7 @@ static BOOL CDECL null_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
|
|||
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)
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue