Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 30 ++++++----- dlls/dwrite/font.c | 37 ++++++++----- dlls/dwrite/freetype.c | 100 +++++++++++++++++++++-------------- dlls/dwrite/layout.c | 4 +- 4 files changed, 102 insertions(+), 69 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 5e41455f66d..e748535ddff 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -442,10 +442,9 @@ extern unsigned int opentype_get_gasp_flags(const struct dwrite_fonttable *gasp, /* BiDi helpers */ extern HRESULT bidi_computelevels(const WCHAR*,UINT32,UINT8,UINT8*,UINT8*) DECLSPEC_HIDDEN;
-/* FreeType integration */ struct dwrite_glyphbitmap { - IDWriteFontFace4 *fontface; + void *key; DWORD simulations; float emsize; BOOL nohint; @@ -486,18 +485,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, unsigned int count) DECLSPEC_HIDDEN;
-extern HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph, - DWRITE_GLYPH_METRICS *metrics) DECLSPEC_HIDDEN; -extern void freetype_notify_cacheremove(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN; -extern int freetype_get_glyph_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 glyph, - struct dwrite_outline *outline) DECLSPEC_HIDDEN; -extern UINT16 freetype_get_glyphcount(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN; -extern void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap_desc) DECLSPEC_HIDDEN; -extern BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN; -extern INT32 freetype_get_glyph_advance(IDWriteFontFace5 *fontface, FLOAT emsize, UINT16 index, - DWRITE_MEASURING_MODE measuring_mode, BOOL *has_contours) DECLSPEC_HIDDEN; -extern void freetype_get_design_glyph_bbox(IDWriteFontFace4*,UINT16,UINT16,RECT*) DECLSPEC_HIDDEN; - /* Glyph shaping */ enum SCRIPT_JUSTIFY { @@ -742,6 +729,21 @@ struct font_callback_funcs void (CDECL *release_font_data)(struct font_data_context *context); };
+struct font_backend_funcs +{ + void (CDECL *notify_release)(void *key); + int (CDECL *get_glyph_outline)(void *key, float em_size, UINT16 glyph, struct dwrite_outline *outline); + UINT16 (CDECL *get_glyph_count)(void *key); + INT32 (CDECL *get_glyph_advance)(void *key, float em_size, UINT16 index, DWRITE_MEASURING_MODE measuring_mode, + 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, + UINT16 glyph, DWRITE_GLYPH_METRICS *metrics); +}; + 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; + +extern void dwrite_fontface_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index ca7ce8ca53a..24110db1197 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -63,6 +63,13 @@ static const WCHAR demiW[] = {'d','e','m','i',0}; static const WCHAR spaceW[] = {' ',0}; static const WCHAR enusW[] = {'e','n','-','u','s',0};
+static const struct font_backend_funcs *font_funcs; + +void dwrite_fontface_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap) +{ + font_funcs->get_glyph_bbox(bitmap); +} + struct dwrite_font_propvec { FLOAT stretch; FLOAT style; @@ -662,7 +669,7 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface) for (i = 0; i < ARRAY_SIZE(fontface->glyphs); i++) heap_free(fontface->glyphs[i]);
- freetype_notify_cacheremove(iface); + font_funcs->notify_release(iface);
dwrite_cmap_release(&fontface->cmap); IDWriteFactory7_Release(fontface->factory); @@ -743,7 +750,7 @@ static UINT16 WINAPI dwritefontface_GetGlyphCount(IDWriteFontFace5 *iface) { TRACE("%p.\n", iface);
- return freetype_get_glyphcount(iface); + return font_funcs->get_glyph_count(iface); }
static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace5 *iface, @@ -765,8 +772,10 @@ static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace5 *ifa DWRITE_GLYPH_METRICS metrics;
hr = get_cached_glyph_metrics(fontface, glyphs[i], &metrics); - if (hr != S_OK) { - freetype_get_design_glyph_metrics(fontface, glyphs[i], &metrics); + if (hr != 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; @@ -901,7 +910,7 @@ static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace5 *iface, for (i = 0; i < count; ++i) { outline.tags.count = outline.points.count = 0; - if (freetype_get_glyph_outline(iface, emSize, glyphs[i], &outline)) + if (font_funcs->get_glyph_outline(iface, emSize, glyphs[i], &outline)) { WARN("Failed to get glyph outline for glyph %u.\n", glyphs[i]); continue; @@ -1049,7 +1058,7 @@ static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFac if (FAILED(hr)) return hr;
- ret->advanceWidth = freetype_get_glyph_advance(iface, size, glyphs[i], mode, &has_contours); + ret->advanceWidth = font_funcs->get_glyph_advance(iface, size, glyphs[i], mode, &has_contours); if (has_contours) ret->advanceWidth = round_metric(ret->advanceWidth * fontface->metrics.designUnitsPerEm / size + adjustment); else @@ -1180,7 +1189,7 @@ static int fontface_get_design_advance(struct dwrite_fontface *fontface, DWRITE_ switch (measuring_mode) { case DWRITE_MEASURING_MODE_NATURAL: - advance = freetype_get_glyph_advance(&fontface->IDWriteFontFace5_iface, fontface->metrics.designUnitsPerEm, + advance = font_funcs->get_glyph_advance(&fontface->IDWriteFontFace5_iface, fontface->metrics.designUnitsPerEm, glyph, measuring_mode, &has_contours); if (has_contours) advance += adjustment; @@ -1195,7 +1204,7 @@ static int fontface_get_design_advance(struct dwrite_fontface *fontface, DWRITE_ if (transform && memcmp(transform, &identity, sizeof(*transform))) FIXME("Transform is not supported.\n");
- advance = freetype_get_glyph_advance(&fontface->IDWriteFontFace5_iface, emsize, glyph, measuring_mode, + advance = font_funcs->get_glyph_advance(&fontface->IDWriteFontFace5_iface, emsize, glyph, measuring_mode, &has_contours); if (has_contours) advance = round_metric(advance * fontface->metrics.designUnitsPerEm / emsize + adjustment); @@ -5709,7 +5718,7 @@ static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *a WARN("failed to get IDWriteFontFace4, 0x%08x\n", hr);
memset(&glyph_bitmap, 0, sizeof(glyph_bitmap)); - glyph_bitmap.fontface = fontface; + glyph_bitmap.key = fontface; glyph_bitmap.simulations = IDWriteFontFace4_GetSimulations(fontface); glyph_bitmap.emsize = analysis->run.fontEmSize; glyph_bitmap.nohint = is_natural_rendering_mode(analysis->rendering_mode); @@ -5721,7 +5730,7 @@ static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *a UINT32 bitmap_size;
glyph_bitmap.glyph = analysis->run.glyphIndices[i]; - freetype_get_glyph_bbox(&glyph_bitmap); + font_funcs->get_glyph_bbox(&glyph_bitmap);
bitmap_size = get_glyph_bitmap_pitch(analysis->rendering_mode, bbox->right - bbox->left) * (bbox->bottom - bbox->top); @@ -5799,7 +5808,7 @@ static HRESULT glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis) origin.x = origin.y = 0.0f;
memset(&glyph_bitmap, 0, sizeof(glyph_bitmap)); - glyph_bitmap.fontface = fontface; + glyph_bitmap.key = fontface; glyph_bitmap.simulations = IDWriteFontFace4_GetSimulations(fontface); glyph_bitmap.emsize = analysis->run.fontEmSize; glyph_bitmap.nohint = is_natural_rendering_mode(analysis->rendering_mode); @@ -5819,7 +5828,7 @@ static HRESULT glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis) BOOL is_1bpp;
glyph_bitmap.glyph = analysis->run.glyphIndices[i]; - freetype_get_glyph_bbox(&glyph_bitmap); + font_funcs->get_glyph_bbox(&glyph_bitmap);
if (IsRectEmpty(bbox)) continue; @@ -5829,7 +5838,7 @@ static HRESULT glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis)
glyph_bitmap.pitch = get_glyph_bitmap_pitch(analysis->rendering_mode, width); memset(src, 0, height * glyph_bitmap.pitch); - is_1bpp = freetype_get_glyph_bitmap(&glyph_bitmap); + is_1bpp = font_funcs->get_glyph_bitmap(&glyph_bitmap);
OffsetRect(bbox, analysis->origins[i].x, analysis->origins[i].y);
@@ -8030,7 +8039,7 @@ struct font_callback_funcs callback_funcs =
void init_font_backend(void) { - init_font_lib(dwrite_module, DLL_PROCESS_ATTACH, &callback_funcs, NULL); + init_font_lib(dwrite_module, DLL_PROCESS_ATTACH, &callback_funcs, &font_funcs); }
void release_font_backend(void) diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index 675d1cf0672..581d6eab802 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -207,21 +207,22 @@ sym_not_found: return FALSE; }
-void freetype_notify_cacheremove(IDWriteFontFace5 *fontface) +static void CDECL freetype_notify_release(void *key) { EnterCriticalSection(&freetype_cs); - pFTC_Manager_RemoveFaceID(cache_manager, fontface); + pFTC_Manager_RemoveFaceID(cache_manager, key); LeaveCriticalSection(&freetype_cs); }
-HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph, DWRITE_GLYPH_METRICS *ret) +static void CDECL freetype_get_design_glyph_metrics(void *key, UINT16 upem, UINT16 ascent, + unsigned int simulations, UINT16 glyph, DWRITE_GLYPH_METRICS *ret) { FTC_ScalerRec scaler; FT_Size size;
- scaler.face_id = &fontface->IDWriteFontFace5_iface; - scaler.width = fontface->metrics.designUnitsPerEm; - scaler.height = fontface->metrics.designUnitsPerEm; + scaler.face_id = key; + scaler.width = upem; + scaler.height = upem; scaler.pixel = 1; scaler.x_res = 0; scaler.y_res = 0; @@ -236,22 +237,20 @@ HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT ret->rightSideBearing = metrics->horiAdvance - metrics->horiBearingX - metrics->width;
ret->advanceHeight = metrics->vertAdvance; - ret->verticalOriginY = fontface->typo_metrics.ascent; - ret->topSideBearing = fontface->typo_metrics.ascent - metrics->horiBearingY; + 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 (fontface->simulations & DWRITE_FONT_SIMULATIONS_BOLD && + 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 += (fontface->metrics.designUnitsPerEm + 49) / 50; + ret->advanceWidth += (upem + 49) / 50; } } } LeaveCriticalSection(&freetype_cs); - - return S_OK; }
struct decompose_context @@ -437,9 +436,9 @@ static void embolden_glyph(FT_Glyph glyph, FLOAT emsize) embolden_glyph_outline(&outline_glyph->outline, emsize); }
-int freetype_get_glyph_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 glyph, - struct dwrite_outline *outline) +static int CDECL freetype_get_glyph_outline(void *key, float emSize, UINT16 glyph, struct dwrite_outline *outline) { + IDWriteFontFace5 *fontface = key; FTC_ScalerRec scaler; USHORT simulations; FT_Size size; @@ -480,13 +479,13 @@ int freetype_get_glyph_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 return ret; }
-UINT16 freetype_get_glyphcount(IDWriteFontFace5 *fontface) +static UINT16 CDECL freetype_get_glyph_count(void *key) { UINT16 count = 0; FT_Face face;
EnterCriticalSection(&freetype_cs); - if (pFTC_Manager_LookupFace(cache_manager, fontface, &face) == 0) + if (pFTC_Manager_LookupFace(cache_manager, key, &face) == 0) count = face->num_glyphs; LeaveCriticalSection(&freetype_cs);
@@ -502,10 +501,10 @@ static inline void ft_matrix_from_dwrite_matrix(const DWRITE_MATRIX *m, FT_Matri }
/* Should be used only while holding 'freetype_cs' */ -static BOOL is_face_scalable(IDWriteFontFace4 *fontface) +static BOOL is_face_scalable(void *key) { FT_Face face; - if (pFTC_Manager_LookupFace(cache_manager, fontface, &face) == 0) + if (pFTC_Manager_LookupFace(cache_manager, key, &face) == 0) return FT_IS_SCALABLE(face); else return FALSE; @@ -522,7 +521,7 @@ static BOOL get_glyph_transform(struct dwrite_glyphbitmap *bitmap, FT_Matrix *re
/* Some fonts provide mostly bitmaps and very few outlines, for example for .notdef. Disable transform if that's the case. */ - if (!is_face_scalable(bitmap->fontface) || (!bitmap->m && bitmap->simulations == 0)) + if (!is_face_scalable(bitmap->key) || (!bitmap->m && bitmap->simulations == 0)) return FALSE;
if (bitmap->simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE) { @@ -541,7 +540,7 @@ static BOOL get_glyph_transform(struct dwrite_glyphbitmap *bitmap, FT_Matrix *re return TRUE; }
-void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap) +static void CDECL freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap) { FTC_ImageTypeRec imagetype; FT_BBox bbox = { 0 }; @@ -553,7 +552,7 @@ void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap)
needs_transform = get_glyph_transform(bitmap, &m);
- imagetype.face_id = bitmap->fontface; + imagetype.face_id = bitmap->key; imagetype.width = 0; imagetype.height = bitmap->emsize; imagetype.flags = needs_transform ? FT_LOAD_NO_BITMAP : FT_LOAD_DEFAULT; @@ -673,7 +672,7 @@ static BOOL freetype_get_aa_glyph_bitmap(struct dwrite_glyphbitmap *bitmap, FT_G return ret; }
-BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap) +static BOOL CDECL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap) { FTC_ImageTypeRec imagetype; BOOL needs_transform; @@ -685,7 +684,7 @@ BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
needs_transform = get_glyph_transform(bitmap, &m);
- imagetype.face_id = bitmap->fontface; + imagetype.face_id = bitmap->key; imagetype.width = 0; imagetype.height = bitmap->emsize; imagetype.flags = needs_transform ? FT_LOAD_NO_BITMAP : FT_LOAD_DEFAULT; @@ -720,14 +719,14 @@ BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap) return ret; }
-INT32 freetype_get_glyph_advance(IDWriteFontFace5 *fontface, FLOAT emSize, UINT16 index, DWRITE_MEASURING_MODE mode, - BOOL *has_contours) +static INT32 CDECL freetype_get_glyph_advance(void *key, float emSize, UINT16 index, + DWRITE_MEASURING_MODE mode, BOOL *has_contours) { FTC_ImageTypeRec imagetype; FT_Glyph glyph; INT32 advance;
- imagetype.face_id = fontface; + imagetype.face_id = key; imagetype.width = 0; imagetype.height = emSize; imagetype.flags = FT_LOAD_DEFAULT; @@ -748,10 +747,22 @@ INT32 freetype_get_glyph_advance(IDWriteFontFace5 *fontface, FLOAT emSize, UINT1 return advance; }
+const static struct font_backend_funcs freetype_funcs = +{ + freetype_notify_release, + freetype_get_glyph_outline, + freetype_get_glyph_count, + freetype_get_glyph_advance, + freetype_get_glyph_bbox, + freetype_get_glyph_bitmap, + freetype_get_design_glyph_metrics, +}; + 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; + *(const struct font_backend_funcs **)ptr_out = &freetype_funcs; return STATUS_SUCCESS; }
@@ -764,45 +775,56 @@ static NTSTATUS release_freetype_lib(void)
#else /* HAVE_FREETYPE */
-void freetype_notify_cacheremove(IDWriteFontFace5 *fontface) +static void CDECL null_notify_release(void *key) { }
-HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph, DWRITE_GLYPH_METRICS *ret) +static int CDECL null_get_glyph_outline(void *key, float emSize, UINT16 glyph, struct dwrite_outline *outline) { - return E_NOTIMPL; + return 1; }
-int freetype_get_glyph_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 glyph, - struct dwrite_outline *outline) +static UINT16 CDECL null_get_glyph_count(void *key) { - return 1; + return 0; }
-UINT16 freetype_get_glyphcount(IDWriteFontFace5 *fontface) +static INT32 CDECL null_get_glyph_advance(void *key, float emSize, UINT16 index, DWRITE_MEASURING_MODE mode, + BOOL *has_contours) { + *has_contours = FALSE; return 0; }
-void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap) +static void CDECL null_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap) { SetRectEmpty(&bitmap->bbox); }
-BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap) +static BOOL CDECL null_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap) { return FALSE; }
-INT32 freetype_get_glyph_advance(IDWriteFontFace5 *fontface, FLOAT emSize, UINT16 index, DWRITE_MEASURING_MODE mode, - BOOL *has_contours) +static void CDECL null_get_design_glyph_metrics(void *key, UINT16 upem, UINT16 ascent, unsigned int simulations, + UINT16 glyph, DWRITE_GLYPH_METRICS *metrics) { - *has_contours = FALSE; - return 0; }
+const static struct font_backend_funcs null_funcs = +{ + null_notify_release, + null_get_glyph_outline, + null_get_glyph_count, + null_get_glyph_advance, + null_get_glyph_bbox, + null_get_glyph_bitmap, + null_get_design_glyph_metrics, +}; + static NTSTATUS init_freetype_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out) { + *(const struct font_backend_funcs **)ptr_out = &null_funcs; return STATUS_DLL_NOT_FOUND; }
diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c index 99048b97a3c..06ebcb8057c 100644 --- a/dlls/dwrite/layout.c +++ b/dlls/dwrite/layout.c @@ -3936,7 +3936,7 @@ static void layout_get_erun_bbox(struct dwrite_textlayout *layout, struct layout RECT *bbox;
memset(&glyph_bitmap, 0, sizeof(glyph_bitmap)); - glyph_bitmap.fontface = (IDWriteFontFace4 *)glyph_run->fontFace; + glyph_bitmap.key = glyph_run->fontFace; glyph_bitmap.simulations = IDWriteFontFace_GetSimulations(glyph_run->fontFace); glyph_bitmap.emsize = glyph_run->fontEmSize; glyph_bitmap.nohint = layout->measuringmode == DWRITE_MEASURING_MODE_NATURAL; @@ -3952,7 +3952,7 @@ static void layout_get_erun_bbox(struct dwrite_textlayout *layout, struct layout origin.x -= glyph_run->glyphAdvances[i + start_glyph];
glyph_bitmap.glyph = glyph_run->glyphIndices[i + start_glyph]; - freetype_get_glyph_bbox(&glyph_bitmap); + dwrite_fontface_get_glyph_bbox(&glyph_bitmap);
glyph_bbox.left = bbox->left; glyph_bbox.top = bbox->top;