Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/dwrite/Makefile.in | 1 +
dlls/dwrite/dwrite_private.h | 23 +--
dlls/dwrite/font.c | 149 +++++++++-----
dlls/dwrite/freetype.c | 362 ++++++++++++++++++-----------------
dlls/dwrite/main.c | 8 +-
dlls/dwrite/unixlib.h | 113 +++++++++++
6 files changed, 407 insertions(+), 249 deletions(-)
create mode 100644 dlls/dwrite/unixlib.h
diff --git a/dlls/dwrite/Makefile.in b/dlls/dwrite/Makefile.in
index 8b612989386..1c1611f8e16 100644
--- a/dlls/dwrite/Makefile.in
+++ b/dlls/dwrite/Makefile.in
@@ -1,5 +1,6 @@
MODULE = dwrite.dll
IMPORTLIB = dwrite
+UNIXLIB = dwrite.so
IMPORTS = user32 gdi32 advapi32
EXTRAINCL = $(FREETYPE_CFLAGS)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index f83372acc9e..dd346191662 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -223,8 +223,7 @@ extern HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_cmap *cmap,
DWRITE_UNICODE_RANGE *ranges, unsigned int *count) DECLSPEC_HIDDEN;
struct dwrite_fontface;
-typedef void * font_object_handle;
-typedef font_object_handle (*p_dwrite_fontface_get_font_object)(struct dwrite_fontface *fontface);
+typedef UINT64 (*p_dwrite_fontface_get_font_object)(struct dwrite_fontface *fontface);
struct dwrite_fontface
{
@@ -238,7 +237,7 @@ struct dwrite_fontface
IDWriteFactory7 *factory;
struct fontfacecached *cached;
- font_object_handle font_object;
+ UINT64 font_object;
void *data_context;
p_dwrite_fontface_get_font_object get_font_object;
struct
@@ -717,22 +716,4 @@ extern HRESULT shape_check_typographic_feature(struct scriptshaping_context *con
struct font_data_context;
extern HMODULE dwrite_module DECLSPEC_HIDDEN;
-struct font_backend_funcs
-{
- font_object_handle (CDECL *create_font_object)(const void *data_ptr, UINT64 data_size, unsigned int index);
- void (CDECL *release_font_object)(font_object_handle object);
- int (CDECL *get_glyph_outline)(font_object_handle object, float emsize, unsigned int simulations, UINT16 glyph,
- struct dwrite_outline *outline);
- UINT16 (CDECL *get_glyph_count)(font_object_handle object);
- INT32 (CDECL *get_glyph_advance)(font_object_handle object, float em_size, UINT16 glyph,
- DWRITE_MEASURING_MODE measuring_mode, BOOL *has_contours);
- void (CDECL *get_glyph_bbox)(font_object_handle object, struct dwrite_glyphbitmap *bitmap_desc);
- BOOL (CDECL *get_glyph_bitmap)(font_object_handle object, struct dwrite_glyphbitmap *bitmap_desc);
- void (CDECL *get_design_glyph_metrics)(font_object_handle object, UINT16 upem, UINT16 ascent, unsigned int simulations,
- UINT16 glyph, DWRITE_GLYPH_METRICS *metrics);
-};
-
-extern void init_font_backend(void) DECLSPEC_HIDDEN;
-extern void release_font_backend(void) DECLSPEC_HIDDEN;
-
extern void dwrite_fontface_get_glyph_bbox(IDWriteFontFace *fontface, struct dwrite_glyphbitmap *bitmap) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index cb4f856524c..22fb3369bc7 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -26,6 +26,7 @@
#define COBJMACROS
#include "dwrite_private.h"
+#include "unixlib.h"
WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
WINE_DECLARE_DEBUG_CHANNEL(dwrite_file);
@@ -45,8 +46,6 @@ static const FLOAT RECOMMENDED_OUTLINE_AA_THRESHOLD = 100.0f;
static const FLOAT RECOMMENDED_OUTLINE_A_THRESHOLD = 350.0f;
static const FLOAT RECOMMENDED_NATURAL_PPEM = 20.0f;
-static const struct font_backend_funcs *font_funcs;
-
struct cache_key
{
float size;
@@ -59,7 +58,7 @@ struct cache_entry
struct wine_rb_entry entry;
struct list mru;
struct cache_key key;
- float advance;
+ int advance;
RECT bbox;
BYTE *bitmap;
unsigned int bitmap_size;
@@ -117,19 +116,28 @@ static struct cache_entry * fontface_get_cache_entry(struct dwrite_fontface *fon
return entry;
}
-static float fontface_get_glyph_advance(struct dwrite_fontface *fontface, float fontsize, unsigned short glyph,
+static int fontface_get_glyph_advance(struct dwrite_fontface *fontface, float fontsize, unsigned short glyph,
unsigned short mode, BOOL *has_contours)
{
struct cache_key key = { .size = fontsize, .glyph = glyph, .mode = mode };
+ struct get_glyph_advance_params params;
struct cache_entry *entry;
- BOOL value;
+ unsigned int value;
if (!(entry = fontface_get_cache_entry(fontface, 0, &key)))
- return 0.0f;
+ return 0;
if (!entry->has_advance)
{
- entry->advance = font_funcs->get_glyph_advance(fontface->get_font_object(fontface), fontsize, glyph, mode, &value);
+ params.object = fontface->get_font_object(fontface);
+ params.glyph = glyph;
+ params.mode = mode;
+ params.emsize = fontsize;
+ params.advance = &entry->advance;
+ params.has_contours = &value;
+
+ UNIX_CALL(get_glyph_advance, ¶ms);
+
entry->has_contours = !!value;
entry->has_advance = 1;
}
@@ -142,24 +150,31 @@ void dwrite_fontface_get_glyph_bbox(IDWriteFontFace *iface, struct dwrite_glyphb
{
struct cache_key key = { .size = bitmap->emsize, .glyph = bitmap->glyph, .mode = DWRITE_MEASURING_MODE_NATURAL };
struct dwrite_fontface *fontface = unsafe_impl_from_IDWriteFontFace(iface);
+ struct get_glyph_bbox_params params;
struct cache_entry *entry;
+ params.object = fontface->get_font_object(fontface);
+ params.simulations = bitmap->simulations;
+ params.glyph = bitmap->glyph;
+ params.emsize = bitmap->emsize;
+ params.m = bitmap->m ? *bitmap->m : identity;
+
EnterCriticalSection(&fontface->cs);
/* For now bypass cache for transformed cases. */
if (bitmap->m && memcmp(bitmap->m, &identity, sizeof(*bitmap->m)))
{
- font_funcs->get_glyph_bbox(fontface->get_font_object(fontface), bitmap);
+ params.bbox = &bitmap->bbox;
+ UNIX_CALL(get_glyph_bbox, ¶ms);
}
else if ((entry = fontface_get_cache_entry(fontface, 0, &key)))
{
- if (entry->has_bbox)
- bitmap->bbox = entry->bbox;
- else
+ if (!entry->has_bbox)
{
- font_funcs->get_glyph_bbox(fontface->get_font_object(fontface), bitmap);
- entry->bbox = bitmap->bbox;
+ params.bbox = &entry->bbox;
+ UNIX_CALL(get_glyph_bbox, ¶ms);
entry->has_bbox = 1;
}
+ bitmap->bbox = entry->bbox;
}
LeaveCriticalSection(&fontface->cs);
}
@@ -170,22 +185,34 @@ static unsigned int get_glyph_bitmap_pitch(DWRITE_RENDERING_MODE1 rendering_mode
}
static HRESULT dwrite_fontface_get_glyph_bitmap(struct dwrite_fontface *fontface, DWRITE_RENDERING_MODE rendering_mode,
- BOOL *is_1bpp, struct dwrite_glyphbitmap *bitmap)
+ unsigned int *is_1bpp, struct dwrite_glyphbitmap *bitmap)
{
struct cache_key key = { .size = bitmap->emsize, .glyph = bitmap->glyph, .mode = DWRITE_MEASURING_MODE_NATURAL };
+ struct get_glyph_bitmap_params params;
const RECT *bbox = &bitmap->bbox;
+ unsigned int bitmap_size, _1bpp;
struct cache_entry *entry;
- unsigned int bitmap_size;
HRESULT hr = S_OK;
bitmap_size = get_glyph_bitmap_pitch(rendering_mode, bbox->right - bbox->left) *
(bbox->bottom - bbox->top);
+ params.object = fontface->get_font_object(fontface);
+ params.simulations = fontface->simulations;
+ params.glyph = bitmap->glyph;
+ params.mode = rendering_mode;
+ params.emsize = bitmap->emsize;
+ params.m = bitmap->m ? *bitmap->m : identity;
+ params.bbox = bitmap->bbox;
+ params.pitch = bitmap->pitch;
+ params.bitmap = bitmap->buf;
+ params.is_1bpp = is_1bpp;
+
EnterCriticalSection(&fontface->cs);
/* For now bypass cache for transformed cases. */
- if (bitmap->m && memcmp(bitmap->m, &identity, sizeof(*bitmap->m)))
+ if (memcmp(¶ms.m, &identity, sizeof(params.m)))
{
- *is_1bpp = font_funcs->get_glyph_bitmap(fontface->get_font_object(fontface), bitmap);
+ UNIX_CALL(get_glyph_bitmap, ¶ms);
}
else if ((entry = fontface_get_cache_entry(fontface, bitmap_size, &key)))
{
@@ -195,10 +222,13 @@ static HRESULT dwrite_fontface_get_glyph_bitmap(struct dwrite_fontface *fontface
}
else
{
- entry->is_1bpp = font_funcs->get_glyph_bitmap(fontface->get_font_object(fontface), bitmap);
+ params.is_1bpp = &_1bpp;
+ UNIX_CALL(get_glyph_bitmap, ¶ms);
+
entry->bitmap_size = bitmap_size;
if ((entry->bitmap = malloc(entry->bitmap_size)))
memcpy(entry->bitmap, bitmap->buf, entry->bitmap_size);
+ entry->is_1bpp = !!_1bpp;
entry->has_bitmap = 1;
}
*is_1bpp = entry->is_1bpp;
@@ -797,6 +827,7 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface)
{
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
ULONG refcount = InterlockedDecrement(&fontface->refcount);
+ struct release_font_object_params params = { fontface->font_object };
TRACE("%p, refcount %u.\n", iface, refcount);
@@ -837,7 +868,7 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface)
for (i = 0; i < ARRAY_SIZE(fontface->glyphs); i++)
free(fontface->glyphs[i]);
- font_funcs->release_font_object(fontface->font_object);
+ UNIX_CALL(release_font_object, ¶ms);
if (fontface->stream)
{
IDWriteFontFileStream_ReleaseFileFragment(fontface->stream, fontface->data_context);
@@ -924,16 +955,24 @@ static void WINAPI dwritefontface_GetMetrics(IDWriteFontFace5 *iface, DWRITE_FON
static UINT16 WINAPI dwritefontface_GetGlyphCount(IDWriteFontFace5 *iface)
{
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+ struct get_glyph_count_params params;
+ unsigned int count;
TRACE("%p.\n", iface);
- return font_funcs->get_glyph_count(fontface->get_font_object(fontface));
+ params.object = fontface->get_font_object(fontface);
+ params.count = &count;
+ UNIX_CALL(get_glyph_count, ¶ms);
+
+ return count;
}
static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace5 *iface,
UINT16 const *glyphs, UINT32 glyph_count, DWRITE_GLYPH_METRICS *ret, BOOL is_sideways)
{
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+ struct get_design_glyph_metrics_params params;
+ DWRITE_GLYPH_METRICS metrics;
HRESULT hr = S_OK;
unsigned int i;
@@ -945,16 +984,20 @@ static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace5 *ifa
if (is_sideways)
FIXME("sideways metrics are not supported.\n");
+ params.object = fontface->get_font_object(fontface);
+ params.simulations = fontface->simulations;
+ params.upem = fontface->metrics.designUnitsPerEm;
+ params.ascent = fontface->typo_metrics.ascent;
+ params.metrics = &metrics;
+
EnterCriticalSection(&fontface->cs);
for (i = 0; i < glyph_count; ++i)
{
- DWRITE_GLYPH_METRICS metrics;
if (get_cached_glyph_metrics(fontface, glyphs[i], &metrics) != S_OK)
{
- font_funcs->get_design_glyph_metrics(fontface->get_font_object(fontface),
- fontface->metrics.designUnitsPerEm, fontface->typo_metrics.ascent,
- fontface->simulations, glyphs[i], &metrics);
+ params.glyph = glyphs[i];
+ UNIX_CALL(get_design_glyph_metrics, ¶ms);
if (FAILED(hr = set_cached_glyph_metrics(fontface, glyphs[i], &metrics))) break;
}
ret[i] = metrics;
@@ -1024,12 +1067,13 @@ static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace5 *iface,
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
D2D1_POINT_2F *origins, baseline_origin = { 0 };
struct dwrite_outline outline, outline_size;
+ struct get_glyph_outline_params params;
D2D1_BEZIER_SEGMENT segment;
D2D1_POINT_2F point;
DWRITE_GLYPH_RUN run;
unsigned int i, j, p;
+ NTSTATUS status;
HRESULT hr;
- int ret;
TRACE("%p, %.8e, %p, %p, %p, %u, %d, %d, %p.\n", iface, emSize, glyphs, advances, offsets,
count, is_sideways, is_rtl, sink);
@@ -1063,28 +1107,35 @@ static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace5 *iface,
memset(&outline_size, 0, sizeof(outline_size));
memset(&outline, 0, sizeof(outline));
+ params.object = fontface->get_font_object(fontface);
+ params.simulations = fontface->simulations;
+ params.emsize = emSize;
+
for (i = 0; i < count; ++i)
{
outline.tags.count = outline.points.count = 0;
EnterCriticalSection(&fontface->cs);
- if (!(ret = font_funcs->get_glyph_outline(fontface->get_font_object(fontface), emSize, fontface->simulations,
- glyphs[i], &outline_size)))
+
+ params.glyph = glyphs[i];
+ params.outline = &outline_size;
+
+ if (!(status = UNIX_CALL(get_glyph_outline, ¶ms)))
{
dwrite_array_reserve((void **)&outline.tags.values, &outline.tags.size, outline_size.tags.count,
sizeof(*outline.tags.values));
dwrite_array_reserve((void **)&outline.points.values, &outline.points.size, outline_size.points.count,
sizeof(*outline.points.values));
- if ((ret = font_funcs->get_glyph_outline(fontface->get_font_object(fontface), emSize, fontface->simulations,
- glyphs[i], &outline)))
+ params.outline = &outline;
+ if ((status = UNIX_CALL(get_glyph_outline, ¶ms)))
{
WARN("Failed to get glyph outline for glyph %u.\n", glyphs[i]);
}
}
LeaveCriticalSection(&fontface->cs);
- if (ret)
+ if (status)
continue;
for (j = 0, p = 0; j < outline.tags.count; ++j)
@@ -5239,26 +5290,37 @@ HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_ke
return S_OK;
}
-static font_object_handle dwrite_fontface_get_font_object(struct dwrite_fontface *fontface)
+static UINT64 dwrite_fontface_get_font_object(struct dwrite_fontface *fontface)
{
- font_object_handle font_object;
+ struct create_font_object_params create_params;
+ struct release_font_object_params release_params;
+ UINT64 font_object, size;
const void *data_ptr;
void *data_context;
- UINT64 size;
if (!fontface->font_object && SUCCEEDED(IDWriteFontFileStream_GetFileSize(fontface->stream, &size)))
{
if (SUCCEEDED(IDWriteFontFileStream_ReadFileFragment(fontface->stream, &data_ptr, 0, size, &data_context)))
{
- if (!(font_object = font_funcs->create_font_object(data_ptr, size, fontface->index)))
+ create_params.data = data_ptr;
+ create_params.size = size;
+ create_params.index = fontface->index;
+ create_params.object = &font_object;
+
+ UNIX_CALL(create_font_object, &create_params);
+
+ if (!font_object)
{
WARN("Backend failed to create font object.\n");
IDWriteFontFileStream_ReleaseFileFragment(fontface->stream, data_context);
- return NULL;
+ return 0;
}
- if (InterlockedCompareExchangePointer((void **)&fontface->font_object, font_object, NULL))
- font_funcs->release_font_object(font_object);
+ if (InterlockedCompareExchange64((LONGLONG *)&fontface->font_object, font_object, 0))
+ {
+ release_params.object = font_object;
+ UNIX_CALL(release_font_object, &release_params);
+ }
}
}
@@ -5997,7 +6059,7 @@ static HRESULT glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis)
{
BYTE *src = glyph_bitmap.buf, *dst;
int x, y, width, height;
- BOOL is_1bpp;
+ unsigned int is_1bpp;
glyph_bitmap.glyph = analysis->run.glyphIndices[i];
dwrite_fontface_get_glyph_bbox(analysis->run.fontFace, &glyph_bitmap);
@@ -6010,6 +6072,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);
+
if (FAILED(dwrite_fontface_get_glyph_bitmap(fontface, analysis->rendering_mode, &is_1bpp, &glyph_bitmap)))
{
WARN("Failed to render glyph[%u] = %#x.\n", i, glyph_bitmap.glyph);
@@ -8140,13 +8203,3 @@ HRESULT create_fontset_builder(IDWriteFactory7 *factory, IDWriteFontSetBuilder2
return S_OK;
}
-
-void init_font_backend(void)
-{
- __wine_init_unix_lib(dwrite_module, DLL_PROCESS_ATTACH, NULL, &font_funcs);
-}
-
-void release_font_backend(void)
-{
- __wine_init_unix_lib(dwrite_module, DLL_PROCESS_DETACH, NULL, NULL);
-}
diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c
index daaff6a3f8c..05b04c36e29 100644
--- a/dlls/dwrite/freetype.c
+++ b/dlls/dwrite/freetype.c
@@ -40,6 +40,7 @@
#define WIN32_NO_STATUS
#include "windef.h"
#include "wine/debug.h"
+#include "unixlib.h"
#include "dwrite_private.h"
@@ -88,6 +89,8 @@ MAKE_FUNCPTR(FT_Set_Pixel_Sizes);
#undef MAKE_FUNCPTR
static FT_Error (*pFT_Outline_EmboldenXY)(FT_Outline *, FT_Pos, FT_Pos);
+#define FaceFromObject(o) ((FT_Face)(ULONG_PTR)(o))
+
static FT_Size freetype_set_face_size(FT_Face face, FT_UInt emsize)
{
FT_Size size;
@@ -110,7 +113,7 @@ 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 NTSTATUS process_attach(void *args)
{
FT_Version_t FT_Version;
@@ -118,7 +121,7 @@ static BOOL init_freetype(void)
if (!ft_handle)
{
WINE_MESSAGE("Wine cannot find the FreeType font library.\n");
- return FALSE;
+ return STATUS_DLL_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;}
@@ -153,72 +156,89 @@ static BOOL init_freetype(void)
#undef LOAD_FUNCPTR
pFT_Outline_EmboldenXY = dlsym(ft_handle, "FT_Outline_EmboldenXY");
- if (pFT_Init_FreeType(&library) != 0) {
+ if (pFT_Init_FreeType(&library) != 0)
+ {
ERR("Can't init FreeType library\n");
- dlclose(ft_handle);
+ dlclose(ft_handle);
ft_handle = NULL;
- return FALSE;
+ return STATUS_UNSUCCESSFUL;
}
pFT_Library_Version(library, &FT_Version.major, &FT_Version.minor, &FT_Version.patch);
TRACE("FreeType version is %d.%d.%d\n", FT_Version.major, FT_Version.minor, FT_Version.patch);
- return TRUE;
+ return STATUS_SUCCESS;
sym_not_found:
WINE_MESSAGE("Wine cannot find certain functions that it needs from FreeType library.\n");
dlclose(ft_handle);
ft_handle = NULL;
- return FALSE;
+ return STATUS_UNSUCCESSFUL;
}
-static font_object_handle CDECL freetype_create_font_object(const void *data_ptr, UINT64 data_size, unsigned int index)
+static NTSTATUS process_detach(void *args)
{
+ pFT_Done_FreeType(library);
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS create_font_object(void *args)
+{
+ struct create_font_object_params *params = args;
FT_Face face = NULL;
FT_Error fterror;
- fterror = pFT_New_Memory_Face(library, data_ptr, data_size, index, &face);
+ fterror = pFT_New_Memory_Face(library, params->data, params->size, params->index, &face);
if (fterror != FT_Err_Ok)
+ {
WARN("Failed to create a face object, error %d.\n", fterror);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ *params->object = (ULONG_PTR)face;
- return face;
+ return STATUS_SUCCESS;
}
-static void CDECL freetype_release_font_object(font_object_handle object)
+static NTSTATUS release_font_object(void *args)
{
- pFT_Done_Face(object);
+ struct release_font_object_params *params = args;
+ pFT_Done_Face(FaceFromObject(params->object));
+ return STATUS_SUCCESS;
}
-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)
+static NTSTATUS get_design_glyph_metrics(void *args)
{
- FT_Face face = object;
+ struct get_design_glyph_metrics_params *params = args;
+ FT_Face face = FaceFromObject(params->object);
FT_Size size;
- if (!(size = freetype_set_face_size(face, upem)))
- return;
+ if (!(size = freetype_set_face_size(face, params->upem)))
+ return STATUS_UNSUCCESSFUL;
- if (!pFT_Load_Glyph(face, glyph, FT_LOAD_NO_SCALE))
+ if (!pFT_Load_Glyph(face, params->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;
+ params->metrics->leftSideBearing = metrics->horiBearingX;
+ params->metrics->advanceWidth = metrics->horiAdvance;
+ params->metrics->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;
+ params->metrics->advanceHeight = metrics->vertAdvance;
+ params->metrics->verticalOriginY = params->ascent;
+ params->metrics->topSideBearing = params->ascent - metrics->horiBearingY;
+ params->metrics->bottomSideBearing = metrics->vertAdvance - metrics->height - params->metrics->topSideBearing;
/* Adjust in case of bold simulation, glyphs without contours are ignored. */
- if (simulations & DWRITE_FONT_SIMULATIONS_BOLD && freetype_glyph_has_contours(face))
+ if (params->simulations & DWRITE_FONT_SIMULATIONS_BOLD && freetype_glyph_has_contours(face))
{
- if (ret->advanceWidth)
- ret->advanceWidth += (upem + 49) / 50;
+ if (params->metrics->advanceWidth)
+ params->metrics->advanceWidth += (params->upem + 49) / 50;
}
}
pFT_Done_Size(size);
+
+ return STATUS_SUCCESS;
}
struct decompose_context
@@ -425,52 +445,55 @@ static void embolden_glyph(FT_Glyph glyph, FLOAT emsize)
embolden_glyph_outline(&outline_glyph->outline, emsize);
}
-static int CDECL freetype_get_glyph_outline(font_object_handle object, float emsize, unsigned int simulations,
- UINT16 glyph, struct dwrite_outline *outline)
+static NTSTATUS get_glyph_outline(void *args)
{
- FT_Face face = object;
+ struct get_glyph_outline_params *params = args;
+ FT_Face face = FaceFromObject(params->object);
FT_Size size;
- int ret = 0;
- if (!(size = freetype_set_face_size(face, emsize)))
- return 0;
+ if (!(size = freetype_set_face_size(face, params->emsize)))
+ return STATUS_UNSUCCESSFUL;
- if (!pFT_Load_Glyph(face, glyph, FT_LOAD_NO_BITMAP))
+ if (!pFT_Load_Glyph(face, params->glyph, FT_LOAD_NO_BITMAP))
{
FT_Outline *ft_outline = &face->glyph->outline;
FT_Matrix m;
- if (outline->points.values)
+ if (params->outline->points.values)
{
- if (simulations & DWRITE_FONT_SIMULATIONS_BOLD)
- embolden_glyph_outline(ft_outline, emsize);
+ if (params->simulations & DWRITE_FONT_SIMULATIONS_BOLD)
+ embolden_glyph_outline(ft_outline, params->emsize);
m.xx = 1 << 16;
- m.xy = simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE ? (1 << 16) / 3 : 0;
+ m.xy = params->simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE ? (1 << 16) / 3 : 0;
m.yx = 0;
m.yy = -(1 << 16); /* flip Y axis */
pFT_Outline_Transform(ft_outline, &m);
- ret = decompose_outline(ft_outline, outline);
+ decompose_outline(ft_outline, params->outline);
}
else
{
/* Intentionally overestimate numbers to keep it simple. */
- outline->points.count = ft_outline->n_points * 3;
- outline->tags.count = ft_outline->n_points + ft_outline->n_contours * 2;
+ params->outline->points.count = ft_outline->n_points * 3;
+ params->outline->tags.count = ft_outline->n_points + ft_outline->n_contours * 2;
}
}
pFT_Done_Size(size);
- return ret;
+ return STATUS_SUCCESS;
}
-static UINT16 CDECL freetype_get_glyph_count(font_object_handle object)
+static NTSTATUS get_glyph_count(void *args)
{
- FT_Face face = object;
- return face ? face->num_glyphs : 0;
+ struct get_glyph_count_params *params = args;
+ FT_Face face = FaceFromObject(params->object);
+
+ *params->count = face ? face->num_glyphs : 0;
+
+ return STATUS_SUCCESS;
}
static inline void ft_matrix_from_dwrite_matrix(const DWRITE_MATRIX *m, FT_Matrix *ft_matrix)
@@ -481,9 +504,9 @@ static inline void ft_matrix_from_dwrite_matrix(const DWRITE_MATRIX *m, FT_Matri
ft_matrix->yy = m->m22 * 0x10000;
}
-static BOOL get_glyph_transform(struct dwrite_glyphbitmap *bitmap, FT_Matrix *ret)
+static BOOL get_glyph_transform(unsigned int simulations, const DWRITE_MATRIX *m, FT_Matrix *ret)
{
- FT_Matrix m;
+ FT_Matrix ftm;
ret->xx = 1 << 16;
ret->xy = 0;
@@ -492,53 +515,53 @@ 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 (!bitmap->m && !bitmap->simulations)
+ if (!memcmp(m, &identity, sizeof(*m)) && !simulations)
return FALSE;
- if (bitmap->simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE) {
- m.xx = 1 << 16;
- m.xy = (1 << 16) / 3;
- m.yx = 0;
- m.yy = 1 << 16;
- pFT_Matrix_Multiply(&m, ret);
+ if (simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE)
+ {
+ ftm.xx = 1 << 16;
+ ftm.xy = (1 << 16) / 3;
+ ftm.yx = 0;
+ ftm.yy = 1 << 16;
+ pFT_Matrix_Multiply(&ftm, ret);
}
- if (bitmap->m) {
- ft_matrix_from_dwrite_matrix(bitmap->m, &m);
- pFT_Matrix_Multiply(&m, ret);
- }
+ ft_matrix_from_dwrite_matrix(m, &ftm);
+ pFT_Matrix_Multiply(&ftm, ret);
return TRUE;
}
-static void CDECL freetype_get_glyph_bbox(font_object_handle object, struct dwrite_glyphbitmap *bitmap)
+static NTSTATUS get_glyph_bbox(void *args)
{
- FT_Face face = object;
+ struct get_glyph_bbox_params *params = args;
+ FT_Face face = FaceFromObject(params->object);
FT_Glyph glyph = NULL;
FT_BBox bbox = { 0 };
BOOL needs_transform;
FT_Matrix m;
FT_Size size;
- SetRectEmpty(&bitmap->bbox);
+ SetRectEmpty(params->bbox);
- if (!(size = freetype_set_face_size(face, bitmap->emsize)))
- return;
+ if (!(size = freetype_set_face_size(face, params->emsize)))
+ return STATUS_UNSUCCESSFUL;
- needs_transform = FT_IS_SCALABLE(face) && get_glyph_transform(bitmap, &m);
+ needs_transform = FT_IS_SCALABLE(face) && get_glyph_transform(params->simulations, ¶ms->m, &m);
- if (pFT_Load_Glyph(face, bitmap->glyph, needs_transform ? FT_LOAD_NO_BITMAP : 0))
+ if (pFT_Load_Glyph(face, params->glyph, needs_transform ? FT_LOAD_NO_BITMAP : 0))
{
- WARN("Failed to load glyph %u.\n", bitmap->glyph);
+ WARN("Failed to load glyph %u.\n", params->glyph);
pFT_Done_Size(size);
- return;
+ return STATUS_UNSUCCESSFUL;
}
pFT_Get_Glyph(face->glyph, &glyph);
if (needs_transform)
{
- if (bitmap->simulations & DWRITE_FONT_SIMULATIONS_BOLD)
- embolden_glyph(glyph, bitmap->emsize);
+ if (params->simulations & DWRITE_FONT_SIMULATIONS_BOLD)
+ embolden_glyph(glyph, params->emsize);
/* Includes oblique and user transform. */
pFT_Glyph_Transform(glyph, &m, NULL);
@@ -549,15 +572,19 @@ static void CDECL freetype_get_glyph_bbox(font_object_handle object, struct dwri
pFT_Done_Size(size);
/* flip Y axis */
- SetRect(&bitmap->bbox, bbox.xMin, -bbox.yMax, bbox.xMax, -bbox.yMin);
+ SetRect(params->bbox, bbox.xMin, -bbox.yMax, bbox.xMax, -bbox.yMin);
+
+ return STATUS_SUCCESS;
}
-static BOOL freetype_get_aliased_glyph_bitmap(struct dwrite_glyphbitmap *bitmap, FT_Glyph glyph)
+static NTSTATUS freetype_get_aliased_glyph_bitmap(struct get_glyph_bitmap_params *params, FT_Glyph glyph)
{
- const RECT *bbox = &bitmap->bbox;
+ const RECT *bbox = ¶ms->bbox;
int width = bbox->right - bbox->left;
int height = bbox->bottom - bbox->top;
+ *params->is_1bpp = 1;
+
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
const FT_Outline *src = &outline->outline;
@@ -566,9 +593,9 @@ static BOOL freetype_get_aliased_glyph_bitmap(struct dwrite_glyphbitmap *bitmap,
ft_bitmap.width = width;
ft_bitmap.rows = height;
- ft_bitmap.pitch = bitmap->pitch;
+ ft_bitmap.pitch = params->pitch;
ft_bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
- ft_bitmap.buffer = bitmap->buf;
+ ft_bitmap.buffer = params->bitmap;
/* Note: FreeType will only set 'black' bits for us. */
if (pFT_Outline_New(library, src->n_points, src->n_contours, ©) == 0) {
@@ -580,28 +607,29 @@ static BOOL freetype_get_aliased_glyph_bitmap(struct dwrite_glyphbitmap *bitmap,
}
else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
FT_Bitmap *ft_bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
- BYTE *src = ft_bitmap->buffer, *dst = bitmap->buf;
- int w = min(bitmap->pitch, (ft_bitmap->width + 7) >> 3);
+ BYTE *src = ft_bitmap->buffer, *dst = params->bitmap;
+ int w = min(params->pitch, (ft_bitmap->width + 7) >> 3);
int h = min(height, ft_bitmap->rows);
while (h--) {
memcpy(dst, src, w);
src += ft_bitmap->pitch;
- dst += bitmap->pitch;
+ dst += params->pitch;
}
}
else
FIXME("format %x not handled\n", glyph->format);
- return TRUE;
+ return STATUS_SUCCESS;
}
-static BOOL freetype_get_aa_glyph_bitmap(struct dwrite_glyphbitmap *bitmap, FT_Glyph glyph)
+static NTSTATUS freetype_get_aa_glyph_bitmap(struct get_glyph_bitmap_params *params, FT_Glyph glyph)
{
- const RECT *bbox = &bitmap->bbox;
+ const RECT *bbox = ¶ms->bbox;
int width = bbox->right - bbox->left;
int height = bbox->bottom - bbox->top;
- BOOL ret = FALSE;
+
+ *params->is_1bpp = 0;
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
@@ -611,9 +639,9 @@ static BOOL freetype_get_aa_glyph_bitmap(struct dwrite_glyphbitmap *bitmap, FT_G
ft_bitmap.width = width;
ft_bitmap.rows = height;
- ft_bitmap.pitch = bitmap->pitch;
+ ft_bitmap.pitch = params->pitch;
ft_bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
- ft_bitmap.buffer = bitmap->buf;
+ ft_bitmap.buffer = params->bitmap;
/* Note: FreeType will only set 'black' bits for us. */
if (pFT_Outline_New(library, src->n_points, src->n_contours, ©) == 0) {
@@ -625,55 +653,61 @@ static BOOL freetype_get_aa_glyph_bitmap(struct dwrite_glyphbitmap *bitmap, FT_G
}
else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
FT_Bitmap *ft_bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
- BYTE *src = ft_bitmap->buffer, *dst = bitmap->buf;
- int w = min(bitmap->pitch, (ft_bitmap->width + 7) >> 3);
+ BYTE *src = ft_bitmap->buffer, *dst = params->bitmap;
+ int w = min(params->pitch, (ft_bitmap->width + 7) >> 3);
int h = min(height, ft_bitmap->rows);
while (h--) {
memcpy(dst, src, w);
src += ft_bitmap->pitch;
- dst += bitmap->pitch;
+ dst += params->pitch;
}
- ret = TRUE;
+ *params->is_1bpp = 1;
}
else
+ {
FIXME("format %x not handled\n", glyph->format);
+ return STATUS_NOT_IMPLEMENTED;
+ }
- return ret;
+ return STATUS_SUCCESS;
}
-static BOOL CDECL freetype_get_glyph_bitmap(font_object_handle object, struct dwrite_glyphbitmap *bitmap)
+static NTSTATUS get_glyph_bitmap(void *args)
{
- FT_Face face = object;
+ struct get_glyph_bitmap_params *params = args;
+ FT_Face face = FaceFromObject(params->object);
BOOL needs_transform;
BOOL ret = FALSE;
FT_Glyph glyph;
FT_Size size;
FT_Matrix m;
- if (!(size = freetype_set_face_size(face, bitmap->emsize)))
- return FALSE;
+ *params->is_1bpp = 0;
- needs_transform = FT_IS_SCALABLE(face) && get_glyph_transform(bitmap, &m);
+ if (!(size = freetype_set_face_size(face, params->emsize)))
+ return STATUS_UNSUCCESSFUL;
- if (!pFT_Load_Glyph(face, bitmap->glyph, needs_transform ? FT_LOAD_NO_BITMAP : 0))
+ needs_transform = FT_IS_SCALABLE(face) && get_glyph_transform(params->simulations, ¶ms->m, &m);
+
+ if (!pFT_Load_Glyph(face, params->glyph, needs_transform ? FT_LOAD_NO_BITMAP : 0))
{
pFT_Get_Glyph(face->glyph, &glyph);
if (needs_transform)
{
- if (bitmap->simulations & DWRITE_FONT_SIMULATIONS_BOLD)
- embolden_glyph(glyph, bitmap->emsize);
+ if (params->simulations & DWRITE_FONT_SIMULATIONS_BOLD)
+ embolden_glyph(glyph, params->emsize);
/* Includes oblique and user transform. */
pFT_Glyph_Transform(glyph, &m, NULL);
}
- if (bitmap->aliased)
- ret = freetype_get_aliased_glyph_bitmap(bitmap, glyph);
+ if (params->mode == DWRITE_RENDERING_MODE1_ALIASED)
+ ret = freetype_get_aliased_glyph_bitmap(params, glyph);
else
- ret = freetype_get_aa_glyph_bitmap(bitmap, glyph);
+ ret = freetype_get_aa_glyph_bitmap(params, glyph);
pFT_Done_Glyph(glyph);
}
@@ -683,128 +717,100 @@ static BOOL CDECL freetype_get_glyph_bitmap(font_object_handle object, struct dw
return ret;
}
-static INT32 CDECL freetype_get_glyph_advance(font_object_handle object, float emsize, UINT16 glyph,
- DWRITE_MEASURING_MODE mode, BOOL *has_contours)
+static NTSTATUS get_glyph_advance(void *args)
{
- FT_Face face = object;
- INT32 advance = 0;
+ struct get_glyph_advance_params *params = args;
+ FT_Face face = FaceFromObject(params->object);
FT_Size size;
- *has_contours = FALSE;
+ *params->advance = 0;
+ *params->has_contours = FALSE;
- if (!(size = freetype_set_face_size(face, emsize)))
- return 0;
+ if (!(size = freetype_set_face_size(face, params->emsize)))
+ return STATUS_UNSUCCESSFUL;
- if (!pFT_Load_Glyph(face, glyph, mode == DWRITE_MEASURING_MODE_NATURAL ? FT_LOAD_NO_HINTING : 0))
+ if (!pFT_Load_Glyph(face, params->glyph, params->mode == DWRITE_MEASURING_MODE_NATURAL ? FT_LOAD_NO_HINTING : 0))
{
- advance = face->glyph->advance.x >> 6;
- *has_contours = freetype_glyph_has_contours(face);
+ *params->advance = face->glyph->advance.x >> 6;
+ *params->has_contours = freetype_glyph_has_contours(face);
}
pFT_Done_Size(size);
- return advance;
-}
-
-const static struct font_backend_funcs freetype_funcs =
-{
- freetype_create_font_object,
- freetype_release_font_object,
- 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)
-{
- if (!init_freetype()) return STATUS_DLL_NOT_FOUND;
- *(const struct font_backend_funcs **)ptr_out = &freetype_funcs;
- return STATUS_SUCCESS;
-}
-
-static NTSTATUS release_freetype_lib(void)
-{
- pFT_Done_FreeType(library);
return STATUS_SUCCESS;
}
#else /* HAVE_FREETYPE */
-static font_object_handle CDECL null_create_font_object(const void *data_ptr, UINT64 data_size, unsigned int index)
+static NTSTATUS process_attach(void *args)
{
- return NULL;
+ return STATUS_NOT_IMPLEMENTED;
}
-static void CDECL null_release_font_object(font_object_handle object)
+static NTSTATUS process_detach(void *args)
{
+ return STATUS_NOT_IMPLEMENTED;
}
-static int CDECL null_get_glyph_outline(font_object_handle object, float emSize, unsigned int simulations,
- UINT16 glyph, struct dwrite_outline *outline)
+static NTSTATUS create_font_object(void *args)
{
- return 1;
+ return STATUS_NOT_IMPLEMENTED;
}
-static UINT16 CDECL null_get_glyph_count(font_object_handle object)
+static NTSTATUS release_font_object(void *args)
{
- return 0;
+ return STATUS_NOT_IMPLEMENTED;
}
-static INT32 CDECL null_get_glyph_advance(font_object_handle object, float emsize, UINT16 glyph,
- DWRITE_MEASURING_MODE mode, BOOL *has_contours)
+static NTSTATUS get_glyph_outline(void *args)
{
- *has_contours = FALSE;
- return 0;
+ return STATUS_NOT_IMPLEMENTED;
}
-static void CDECL null_get_glyph_bbox(font_object_handle object, struct dwrite_glyphbitmap *bitmap)
+static NTSTATUS get_glyph_count(void *args)
{
- SetRectEmpty(&bitmap->bbox);
+ return STATUS_NOT_IMPLEMENTED;
}
-static BOOL CDECL null_get_glyph_bitmap(font_object_handle object, struct dwrite_glyphbitmap *bitmap)
+static NTSTATUS get_glyph_advance(void *args)
{
- return FALSE;
-}
+ struct get_glyph_advance_params *params = args;
-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)
-{
+ *params->has_contours = 0;
+ *params->advance = 0;
+
+ return STATUS_NOT_IMPLEMENTED;
}
-const static struct font_backend_funcs null_funcs =
+static NTSTATUS get_glyph_bbox(void *args)
{
- null_create_font_object,
- null_release_font_object,
- 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,
-};
+ struct get_glyph_bbox *params = args;
+ SetRectEmpty(params->bbox);
+ return STATUS_NOT_IMPLEMENTED;
+}
-static NTSTATUS init_freetype_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out)
+static NTSTATUS get_glyph_bitmap(void *args)
{
- *(const struct font_backend_funcs **)ptr_out = &null_funcs;
- return STATUS_DLL_NOT_FOUND;
+ return STATUS_NOT_IMPLEMENTED;
}
-static NTSTATUS release_freetype_lib(void)
+static NTSTATUS get_design_glyph_metrics(void *args)
{
- return STATUS_DLL_NOT_FOUND;
+ return STATUS_NOT_IMPLEMENTED;
}
#endif /* HAVE_FREETYPE */
-NTSTATUS CDECL __wine_init_unix_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;
-}
+const unixlib_entry_t __wine_unix_call_funcs[] =
+{
+ process_attach,
+ process_detach,
+ create_font_object,
+ release_font_object,
+ get_glyph_outline,
+ get_glyph_count,
+ get_glyph_advance,
+ get_glyph_bbox,
+ get_glyph_bitmap,
+ get_design_glyph_metrics,
+};
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index d0dd4dd99e9..b21eba0c50a 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -30,11 +30,13 @@
#include "initguid.h"
#include "dwrite_private.h"
+#include "unixlib.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
HMODULE dwrite_module = 0;
+unixlib_handle_t unixlib_handle = 0;
static IDWriteFactory7 *shared_factory;
static void release_shared_factory(IDWriteFactory7 *factory);
@@ -45,13 +47,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved)
case DLL_PROCESS_ATTACH:
dwrite_module = hinstDLL;
DisableThreadLibraryCalls( hinstDLL );
- init_font_backend();
+ if (!NtQueryVirtualMemory(GetCurrentProcess(), hinstDLL, MemoryWineUnixFuncs,
+ &unixlib_handle, sizeof(unixlib_handle), NULL))
+ UNIX_CALL(process_attach, NULL);
init_local_fontfile_loader();
break;
case DLL_PROCESS_DETACH:
if (reserved) break;
release_shared_factory(shared_factory);
- release_font_backend();
+ if (unixlib_handle) UNIX_CALL(process_detach, NULL);
}
return TRUE;
}
diff --git a/dlls/dwrite/unixlib.h b/dlls/dwrite/unixlib.h
new file mode 100644
index 00000000000..533c3168b99
--- /dev/null
+++ b/dlls/dwrite/unixlib.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2021 Nikolay Sivov for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+#include "windef.h"
+#include "winternl.h"
+#include "dwrite.h"
+#include "wine/unixlib.h"
+
+struct create_font_object_params
+{
+ const void *data;
+ UINT64 size;
+ unsigned int index;
+ UINT64 *object;
+};
+
+struct release_font_object_params
+{
+ UINT64 object;
+};
+
+struct get_glyph_outline_params
+{
+ UINT64 object;
+ unsigned int simulations;
+ unsigned int glyph;
+ float emsize;
+ struct dwrite_outline *outline;
+};
+
+struct get_glyph_count_params
+{
+ UINT64 object;
+ unsigned int *count;
+};
+
+struct get_glyph_advance_params
+{
+ UINT64 object;
+ unsigned int glyph;
+ unsigned int mode;
+ float emsize;
+ int *advance;
+ unsigned int *has_contours;
+};
+
+struct get_glyph_bbox_params
+{
+ UINT64 object;
+ unsigned int simulations;
+ unsigned int glyph;
+ float emsize;
+ DWRITE_MATRIX m;
+ RECT *bbox;
+};
+
+struct get_glyph_bitmap_params
+{
+ UINT64 object;
+ unsigned int simulations;
+ unsigned int glyph;
+ unsigned int mode;
+ float emsize;
+ DWRITE_MATRIX m;
+ RECT bbox;
+ int pitch;
+ BYTE *bitmap;
+ unsigned int *is_1bpp;
+};
+
+struct get_design_glyph_metrics_params
+{
+ UINT64 object;
+ unsigned int simulations;
+ unsigned int glyph;
+ unsigned int upem;
+ unsigned int ascent;
+ DWRITE_GLYPH_METRICS *metrics;
+};
+
+enum font_backend_funcs
+{
+ unix_process_attach,
+ unix_process_detach,
+ unix_create_font_object,
+ unix_release_font_object,
+ unix_get_glyph_outline,
+ unix_get_glyph_count,
+ unix_get_glyph_advance,
+ unix_get_glyph_bbox,
+ unix_get_glyph_bitmap,
+ unix_get_design_glyph_metrics,
+};
+
+extern unixlib_handle_t unixlib_handle DECLSPEC_HIDDEN;
+
+#define UNIX_CALL( func, params ) __wine_unix_call( unixlib_handle, unix_ ## func, params )
--
2.33.0