Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 17 +++++- dlls/dwrite/font.c | 79 +++++++++++++++++++++++++ dlls/dwrite/freetype.c | 108 ++++++++++++++--------------------- dlls/dwrite/main.c | 6 +- 4 files changed, 141 insertions(+), 69 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 47be661555c..5e41455f66d 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -486,9 +486,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 BOOL init_freetype(void) DECLSPEC_HIDDEN; -extern void release_freetype(void) 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; @@ -734,3 +731,17 @@ extern HRESULT shape_get_typographic_features(struct scriptshaping_context *cont unsigned int max_tagcount, unsigned int *actual_tagcount, unsigned int *tags) DECLSPEC_HIDDEN; extern HRESULT shape_check_typographic_feature(struct scriptshaping_context *context, const unsigned int *scripts, unsigned int tag, unsigned int glyph_count, const UINT16 *glyphs, UINT8 *feature_applies) DECLSPEC_HIDDEN; + +struct font_data_context; +extern HMODULE dwrite_module DECLSPEC_HIDDEN; + +struct font_callback_funcs +{ + int (CDECL *get_font_data)(void *key, const void **data_ptr, UINT64 *data_size, unsigned int *index, + struct font_data_context **context); + void (CDECL *release_font_data)(struct font_data_context *context); +}; + +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; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 245a59d5f54..ca7ce8ca53a 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -7958,3 +7958,82 @@ HRESULT create_fontset_builder(IDWriteFactory7 *factory, IDWriteFontSetBuilder2
return S_OK; } + +struct font_data_context +{ + IDWriteFontFileStream *stream; + void *context; +}; + +static int CDECL get_font_data_cb(void *key, const void **data_ptr, UINT64 *data_size, + unsigned int *index, struct font_data_context **ret_context) +{ + IDWriteFontFace *fontface = key; + struct font_data_context *context; + IDWriteFontFileStream *stream; + IDWriteFontFile *file; + unsigned int count; + void *data_context; + HRESULT hr; + + *ret_context = NULL; + + count = 1; + if (FAILED(IDWriteFontFace_GetFiles(fontface, &count, &file))) return 1; + + hr = get_filestream_from_file(file, &stream); + IDWriteFontFile_Release(file); + if (FAILED(hr)) return 1; + + hr = IDWriteFontFileStream_GetFileSize(stream, data_size); + if (FAILED(hr)) + { + IDWriteFontFileStream_Release(stream); + return 1; + } + + hr = IDWriteFontFileStream_ReadFileFragment(stream, data_ptr, 0, *data_size, &data_context); + if (FAILED(hr)) + { + IDWriteFontFileStream_Release(stream); + return 1; + } + + if (!(context = heap_alloc(sizeof(*context)))) + { + IDWriteFontFileStream_Release(stream); + return 1; + } + + context->stream = stream; + context->context = data_context; + + *ret_context = context; + *index = IDWriteFontFace_GetIndex(fontface); + + return 0; +} + +static void CDECL release_font_data_cb(struct font_data_context *context) +{ + if (!context) return; + IDWriteFontFileStream_ReleaseFileFragment(context->stream, context->context); + IDWriteFontFileStream_Release(context->stream); + heap_free(context); +} + +struct font_callback_funcs callback_funcs = +{ + get_font_data_cb, + release_font_data_cb, +}; + +void init_font_backend(void) +{ + init_font_lib(dwrite_module, DLL_PROCESS_ATTACH, &callback_funcs, NULL); +} + +void release_font_backend(void) +{ + init_font_lib(dwrite_module, DLL_PROCESS_DETACH, &callback_funcs, NULL); +} diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index 9e4001d11c2..c4bbbd4624c 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -31,6 +31,8 @@ #include FT_TRUETYPE_TABLES_H #endif /* HAVE_FT2BUILD_H */
+#include "ntstatus.h" +#define WIN32_NO_STATUS #include "windef.h" #include "wine/debug.h"
@@ -60,6 +62,8 @@ typedef struct FT_Int patch; } FT_Version_t;
+static const struct font_callback_funcs *callback_funcs; + #define MAKE_FUNCPTR(f) static typeof(f) * p##f = NULL MAKE_FUNCPTR(FT_Done_FreeType); MAKE_FUNCPTR(FT_Done_Glyph); @@ -92,86 +96,44 @@ MAKE_FUNCPTR(FTC_Manager_RemoveFaceID); #undef MAKE_FUNCPTR static FT_Error (*pFT_Outline_EmboldenXY)(FT_Outline *, FT_Pos, FT_Pos);
-struct face_finalizer_data -{ - IDWriteFontFileStream *stream; - void *context; -}; - static void face_finalizer(void *object) { FT_Face face = object; - struct face_finalizer_data *data = (struct face_finalizer_data *)face->generic.data; - - IDWriteFontFileStream_ReleaseFileFragment(data->stream, data->context); - IDWriteFontFileStream_Release(data->stream); - heap_free(data); + callback_funcs->release_font_data((struct font_data_context *)face->generic.data); }
static FT_Error face_requester(FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face *face) { - IDWriteFontFace *fontface = (IDWriteFontFace*)face_id; - IDWriteFontFileStream *stream; - IDWriteFontFile *file; + struct font_data_context *context; const void *data_ptr; - UINT32 index, count; FT_Error fterror; UINT64 data_size; - void *context; - HRESULT hr; + UINT32 index;
*face = NULL;
- if (!fontface) { + if (!face_id) + { WARN("NULL fontface requested.\n"); return FT_Err_Ok; }
- count = 1; - hr = IDWriteFontFace_GetFiles(fontface, &count, &file); - if (FAILED(hr)) - return FT_Err_Ok; - - hr = get_filestream_from_file(file, &stream); - IDWriteFontFile_Release(file); - if (FAILED(hr)) + if (callback_funcs->get_font_data(face_id, &data_ptr, &data_size, &index, &context)) return FT_Err_Ok;
- hr = IDWriteFontFileStream_GetFileSize(stream, &data_size); - if (FAILED(hr)) { - fterror = FT_Err_Invalid_Stream_Read; - goto fail; - } - - hr = IDWriteFontFileStream_ReadFileFragment(stream, &data_ptr, 0, data_size, &context); - if (FAILED(hr)) { - fterror = FT_Err_Invalid_Stream_Read; - goto fail; - } - - index = IDWriteFontFace_GetIndex(fontface); fterror = pFT_New_Memory_Face(library, data_ptr, data_size, index, face); - if (fterror == FT_Err_Ok) { - struct face_finalizer_data *data; - - data = heap_alloc(sizeof(*data)); - data->stream = stream; - data->context = context; - - (*face)->generic.data = data; + if (fterror == FT_Err_Ok) + { + (*face)->generic.data = context; (*face)->generic.finalizer = face_finalizer; - return fterror; } else - IDWriteFontFileStream_ReleaseFileFragment(stream, context); - -fail: - IDWriteFontFileStream_Release(stream); + callback_funcs->release_font_data(context);
return fterror; }
-BOOL init_freetype(void) +static BOOL init_freetype(void) { FT_Version_t FT_Version;
@@ -243,12 +205,6 @@ sym_not_found: return FALSE; }
-void release_freetype(void) -{ - pFTC_Manager_Done(cache_manager); - pFT_Done_FreeType(library); -} - void freetype_notify_cacheremove(IDWriteFontFace5 *fontface) { EnterCriticalSection(&freetype_cs); @@ -790,17 +746,22 @@ INT32 freetype_get_glyph_advance(IDWriteFontFace5 *fontface, FLOAT emSize, UINT1 return advance; }
-#else /* HAVE_FREETYPE */ - -BOOL init_freetype(void) +static NTSTATUS init_freetype_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out) { - return FALSE; + callback_funcs = ptr_in; + if (!init_freetype()) return STATUS_DLL_NOT_FOUND; + return STATUS_SUCCESS; }
-void release_freetype(void) +static NTSTATUS release_freetype_lib(void) { + pFTC_Manager_Done(cache_manager); + pFT_Done_FreeType(library); + return STATUS_SUCCESS; }
+#else /* HAVE_FREETYPE */ + void freetype_notify_cacheremove(IDWriteFontFace5 *fontface) { } @@ -838,4 +799,23 @@ INT32 freetype_get_glyph_advance(IDWriteFontFace5 *fontface, FLOAT emSize, UINT1 return 0; }
+static NTSTATUS init_freetype_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out) +{ + return STATUS_DLL_NOT_FOUND; +} + +static NTSTATUS release_freetype_lib(void) +{ + return STATUS_DLL_NOT_FOUND; +} + #endif /* HAVE_FREETYPE */ + +NTSTATUS CDECL init_font_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out) +{ + if (reason == DLL_PROCESS_ATTACH) + return init_freetype_lib(module, reason, ptr_in, ptr_out); + else if (reason == DLL_PROCESS_DETACH) + return release_freetype_lib(); + return STATUS_SUCCESS; +} diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 3326b1550ce..41b81ae951b 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -34,6 +34,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
+HMODULE dwrite_module = 0; static IDWriteFactory7 *shared_factory; static void release_shared_factory(IDWriteFactory7 *factory);
@@ -42,14 +43,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved) switch (reason) { case DLL_PROCESS_ATTACH: + dwrite_module = hinstDLL; DisableThreadLibraryCalls( hinstDLL ); - init_freetype(); + init_font_backend(); init_local_fontfile_loader(); break; case DLL_PROCESS_DETACH: if (reserved) break; release_shared_factory(shared_factory); - release_freetype(); + release_font_backend(); } return TRUE; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/freetype.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index c4bbbd4624c..675d1cf0672 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -77,6 +77,7 @@ MAKE_FUNCPTR(FT_Init_FreeType); MAKE_FUNCPTR(FT_Library_Version); MAKE_FUNCPTR(FT_Load_Glyph); MAKE_FUNCPTR(FT_Matrix_Multiply); +MAKE_FUNCPTR(FT_MulDiv); MAKE_FUNCPTR(FT_New_Memory_Face); MAKE_FUNCPTR(FT_Outline_Copy); MAKE_FUNCPTR(FT_Outline_Decompose); @@ -156,6 +157,7 @@ static BOOL init_freetype(void) LOAD_FUNCPTR(FT_Library_Version) LOAD_FUNCPTR(FT_Load_Glyph) LOAD_FUNCPTR(FT_Matrix_Multiply) + LOAD_FUNCPTR(FT_MulDiv) LOAD_FUNCPTR(FT_New_Memory_Face) LOAD_FUNCPTR(FT_Outline_Copy) LOAD_FUNCPTR(FT_Outline_Decompose) @@ -418,7 +420,7 @@ static void embolden_glyph_outline(FT_Outline *outline, FLOAT emsize) { FT_Pos strength;
- strength = MulDiv(emsize, 1 << 6, 24); + strength = pFT_MulDiv(emsize, 1 << 6, 24); if (pFT_Outline_EmboldenXY) pFT_Outline_EmboldenXY(outline, strength, 0); else
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;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 3 ++- dlls/dwrite/font.c | 3 ++- dlls/dwrite/freetype.c | 12 +++++------- 3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index e748535ddff..8536e3c6a36 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -732,7 +732,8 @@ struct font_callback_funcs 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); + int (CDECL *get_glyph_outline)(void *key, float em_size, unsigned int simulations, 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); diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 24110db1197..57c64e4622d 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -870,6 +870,7 @@ static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace5 *iface, UINT16 const *glyphs, FLOAT const* advances, DWRITE_GLYPH_OFFSET const *offsets, UINT32 count, BOOL is_sideways, BOOL is_rtl, IDWriteGeometrySink *sink) { + struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface); D2D1_POINT_2F *origins, baseline_origin = { 0 }; struct dwrite_outline outline = {{ 0 }}; D2D1_BEZIER_SEGMENT segment; @@ -910,7 +911,7 @@ static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace5 *iface, for (i = 0; i < count; ++i) { outline.tags.count = outline.points.count = 0; - if (font_funcs->get_glyph_outline(iface, emSize, glyphs[i], &outline)) + if (font_funcs->get_glyph_outline(iface, emSize, fontface->simulations, glyphs[i], &outline)) { WARN("Failed to get glyph outline for glyph %u.\n", glyphs[i]); continue; diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index 581d6eab802..21e2b9d0320 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -436,17 +436,14 @@ static void embolden_glyph(FT_Glyph glyph, FLOAT emsize) embolden_glyph_outline(&outline_glyph->outline, emsize); }
-static int CDECL freetype_get_glyph_outline(void *key, float emSize, UINT16 glyph, struct dwrite_outline *outline) +static int CDECL freetype_get_glyph_outline(void *key, float emSize, unsigned int simulations, + UINT16 glyph, struct dwrite_outline *outline) { - IDWriteFontFace5 *fontface = key; FTC_ScalerRec scaler; - USHORT simulations; FT_Size size; int ret;
- simulations = IDWriteFontFace5_GetSimulations(fontface); - - scaler.face_id = fontface; + scaler.face_id = key; scaler.width = emSize; scaler.height = emSize; scaler.pixel = 1; @@ -779,7 +776,8 @@ static void CDECL null_notify_release(void *key) { }
-static int CDECL null_get_glyph_outline(void *key, float emSize, UINT16 glyph, struct dwrite_outline *outline) +static int CDECL null_get_glyph_outline(void *key, float emSize, unsigned int simulations, + UINT16 glyph, struct dwrite_outline *outline) { return 1; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/freetype.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index 21e2b9d0320..efa0f24d96c 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -42,14 +42,14 @@
WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
-static CRITICAL_SECTION freetype_cs; -static CRITICAL_SECTION_DEBUG critsect_debug = +static RTL_CRITICAL_SECTION freetype_cs; +static RTL_CRITICAL_SECTION_DEBUG critsect_debug = { 0, 0, &freetype_cs, { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, 0, 0, { (DWORD_PTR)(__FILE__ ": freetype_cs") } }; -static CRITICAL_SECTION freetype_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; +static RTL_CRITICAL_SECTION freetype_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
static void *ft_handle = NULL; static FT_Library library = 0; @@ -209,9 +209,9 @@ sym_not_found:
static void CDECL freetype_notify_release(void *key) { - EnterCriticalSection(&freetype_cs); + RtlEnterCriticalSection(&freetype_cs); pFTC_Manager_RemoveFaceID(cache_manager, key); - LeaveCriticalSection(&freetype_cs); + RtlLeaveCriticalSection(&freetype_cs); }
static void CDECL freetype_get_design_glyph_metrics(void *key, UINT16 upem, UINT16 ascent, @@ -227,7 +227,7 @@ static void CDECL freetype_get_design_glyph_metrics(void *key, UINT16 upem, UINT scaler.x_res = 0; scaler.y_res = 0;
- EnterCriticalSection(&freetype_cs); + 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; @@ -250,7 +250,7 @@ static void CDECL freetype_get_design_glyph_metrics(void *key, UINT16 upem, UINT } } } - LeaveCriticalSection(&freetype_cs); + RtlLeaveCriticalSection(&freetype_cs); }
struct decompose_context @@ -450,7 +450,7 @@ static int CDECL freetype_get_glyph_outline(void *key, float emSize, unsigned in scaler.x_res = 0; scaler.y_res = 0;
- EnterCriticalSection(&freetype_cs); + RtlEnterCriticalSection(&freetype_cs); if (!(ret = pFTC_Manager_LookupSize(cache_manager, &scaler, &size))) { if (pFT_Load_Glyph(size->face, glyph, FT_LOAD_NO_BITMAP) == 0) @@ -471,7 +471,7 @@ static int CDECL freetype_get_glyph_outline(void *key, float emSize, unsigned in ret = decompose_outline(ft_outline, outline); } } - LeaveCriticalSection(&freetype_cs); + RtlLeaveCriticalSection(&freetype_cs);
return ret; } @@ -481,10 +481,10 @@ static UINT16 CDECL freetype_get_glyph_count(void *key) UINT16 count = 0; FT_Face face;
- EnterCriticalSection(&freetype_cs); + RtlEnterCriticalSection(&freetype_cs); if (pFTC_Manager_LookupFace(cache_manager, key, &face) == 0) count = face->num_glyphs; - LeaveCriticalSection(&freetype_cs); + RtlLeaveCriticalSection(&freetype_cs);
return count; } @@ -545,7 +545,7 @@ static void CDECL freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap) FT_Glyph glyph; FT_Matrix m;
- EnterCriticalSection(&freetype_cs); + RtlEnterCriticalSection(&freetype_cs);
needs_transform = get_glyph_transform(bitmap, &m);
@@ -572,7 +572,7 @@ static void CDECL freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap) pFT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &bbox); }
- LeaveCriticalSection(&freetype_cs); + RtlLeaveCriticalSection(&freetype_cs);
/* flip Y axis */ SetRect(&bitmap->bbox, bbox.xMin, -bbox.yMax, bbox.xMax, -bbox.yMin); @@ -677,7 +677,7 @@ static BOOL CDECL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap) FT_Glyph glyph; FT_Matrix m;
- EnterCriticalSection(&freetype_cs); + RtlEnterCriticalSection(&freetype_cs);
needs_transform = get_glyph_transform(bitmap, &m);
@@ -711,7 +711,7 @@ static BOOL CDECL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap) pFT_Done_Glyph(glyph_copy); }
- LeaveCriticalSection(&freetype_cs); + RtlLeaveCriticalSection(&freetype_cs);
return ret; } @@ -730,7 +730,7 @@ static INT32 CDECL freetype_get_glyph_advance(void *key, float emSize, UINT16 in if (mode == DWRITE_MEASURING_MODE_NATURAL) imagetype.flags |= FT_LOAD_NO_HINTING;
- EnterCriticalSection(&freetype_cs); + RtlEnterCriticalSection(&freetype_cs); if (pFTC_ImageCache_Lookup(image_cache, &imagetype, index, &glyph, NULL) == 0) { *has_contours = glyph->format == FT_GLYPH_FORMAT_OUTLINE && ((FT_OutlineGlyph)glyph)->outline.n_contours; advance = glyph->advance.x >> 16; @@ -739,7 +739,7 @@ static INT32 CDECL freetype_get_glyph_advance(void *key, float emSize, UINT16 in *has_contours = FALSE; advance = 0; } - LeaveCriticalSection(&freetype_cs); + RtlLeaveCriticalSection(&freetype_cs);
return advance; }