[PATCH 1/5] dwrite: Switch to unixlib syscall interface

Nikolay Sivov nsivov at codeweavers.com
Wed Dec 8 05:10:42 CST 2021


Signed-off-by: Nikolay Sivov <nsivov at 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, &params);
+
         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, &params);
     }
     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, &params);
             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(&params.m, &identity, sizeof(params.m)))
     {
-        *is_1bpp = font_funcs->get_glyph_bitmap(fontface->get_font_object(fontface), bitmap);
+        UNIX_CALL(get_glyph_bitmap, &params);
     }
     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, &params);
+
             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, &params);
         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, &params);
+
+    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, &params);
             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, &params)))
         {
             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, &params)))
             {
                 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, &params->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 = &params->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, &copy) == 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 = &params->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, &copy) == 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, &params->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




More information about the wine-devel mailing list