Nikolay Sivov : dwrite: Do not use freetype cache for design glyph metrics.
Alexandre Julliard
julliard at winehq.org
Thu Dec 2 15:30:17 CST 2021
Module: wine
Branch: master
Commit: 6356717c47ee7c1aa5bc385fc91fd8e21cb7b040
URL: https://source.winehq.org/git/wine.git/?a=commit;h=6356717c47ee7c1aa5bc385fc91fd8e21cb7b040
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Thu Dec 2 15:37:17 2021 +0300
dwrite: Do not use freetype cache for design glyph metrics.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/dwrite/dwrite_private.h | 3 +-
dlls/dwrite/font.c | 23 +++++++-----
dlls/dwrite/freetype.c | 89 ++++++++++++++++++++++++++++----------------
3 files changed, 72 insertions(+), 43 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 75bc1be902a..3d445cddae2 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -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);
};
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 5f4f5587a62..4b135b83d68 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -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;
diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c
index 6b566649edc..b19ae3616bc 100644
--- a/dlls/dwrite/freetype.c
+++ b/dlls/dwrite/freetype.c
@@ -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;
-
- 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;
-
- /* 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;
- }
- }
+ 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->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 && 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)
{
}
More information about the wine-cvs
mailing list