dwrite: Switch to unixlib syscall interface.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0b3d65f822
commit
275a2d71d6
|
@ -1,5 +1,6 @@
|
||||||
MODULE = dwrite.dll
|
MODULE = dwrite.dll
|
||||||
IMPORTLIB = dwrite
|
IMPORTLIB = dwrite
|
||||||
|
UNIXLIB = dwrite.so
|
||||||
IMPORTS = user32 gdi32 advapi32
|
IMPORTS = user32 gdi32 advapi32
|
||||||
EXTRAINCL = $(FREETYPE_CFLAGS)
|
EXTRAINCL = $(FREETYPE_CFLAGS)
|
||||||
|
|
||||||
|
|
|
@ -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;
|
DWRITE_UNICODE_RANGE *ranges, unsigned int *count) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
struct dwrite_fontface;
|
struct dwrite_fontface;
|
||||||
typedef void * font_object_handle;
|
typedef UINT64 (*p_dwrite_fontface_get_font_object)(struct dwrite_fontface *fontface);
|
||||||
typedef font_object_handle (*p_dwrite_fontface_get_font_object)(struct dwrite_fontface *fontface);
|
|
||||||
|
|
||||||
struct dwrite_fontface
|
struct dwrite_fontface
|
||||||
{
|
{
|
||||||
|
@ -238,7 +237,7 @@ struct dwrite_fontface
|
||||||
|
|
||||||
IDWriteFactory7 *factory;
|
IDWriteFactory7 *factory;
|
||||||
struct fontfacecached *cached;
|
struct fontfacecached *cached;
|
||||||
font_object_handle font_object;
|
UINT64 font_object;
|
||||||
void *data_context;
|
void *data_context;
|
||||||
p_dwrite_fontface_get_font_object get_font_object;
|
p_dwrite_fontface_get_font_object get_font_object;
|
||||||
struct
|
struct
|
||||||
|
@ -717,22 +716,4 @@ extern HRESULT shape_check_typographic_feature(struct scriptshaping_context *con
|
||||||
struct font_data_context;
|
struct font_data_context;
|
||||||
extern HMODULE dwrite_module DECLSPEC_HIDDEN;
|
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;
|
extern void dwrite_fontface_get_glyph_bbox(IDWriteFontFace *fontface, struct dwrite_glyphbitmap *bitmap) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#define COBJMACROS
|
#define COBJMACROS
|
||||||
|
|
||||||
#include "dwrite_private.h"
|
#include "dwrite_private.h"
|
||||||
|
#include "unixlib.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
|
WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(dwrite_file);
|
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_OUTLINE_A_THRESHOLD = 350.0f;
|
||||||
static const FLOAT RECOMMENDED_NATURAL_PPEM = 20.0f;
|
static const FLOAT RECOMMENDED_NATURAL_PPEM = 20.0f;
|
||||||
|
|
||||||
static const struct font_backend_funcs *font_funcs;
|
|
||||||
|
|
||||||
struct cache_key
|
struct cache_key
|
||||||
{
|
{
|
||||||
float size;
|
float size;
|
||||||
|
@ -59,7 +58,7 @@ struct cache_entry
|
||||||
struct wine_rb_entry entry;
|
struct wine_rb_entry entry;
|
||||||
struct list mru;
|
struct list mru;
|
||||||
struct cache_key key;
|
struct cache_key key;
|
||||||
float advance;
|
int advance;
|
||||||
RECT bbox;
|
RECT bbox;
|
||||||
BYTE *bitmap;
|
BYTE *bitmap;
|
||||||
unsigned int bitmap_size;
|
unsigned int bitmap_size;
|
||||||
|
@ -117,19 +116,28 @@ static struct cache_entry * fontface_get_cache_entry(struct dwrite_fontface *fon
|
||||||
return entry;
|
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)
|
unsigned short mode, BOOL *has_contours)
|
||||||
{
|
{
|
||||||
struct cache_key key = { .size = fontsize, .glyph = glyph, .mode = mode };
|
struct cache_key key = { .size = fontsize, .glyph = glyph, .mode = mode };
|
||||||
|
struct get_glyph_advance_params params;
|
||||||
struct cache_entry *entry;
|
struct cache_entry *entry;
|
||||||
BOOL value;
|
unsigned int value;
|
||||||
|
|
||||||
if (!(entry = fontface_get_cache_entry(fontface, 0, &key)))
|
if (!(entry = fontface_get_cache_entry(fontface, 0, &key)))
|
||||||
return 0.0f;
|
return 0;
|
||||||
|
|
||||||
if (!entry->has_advance)
|
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_contours = !!value;
|
||||||
entry->has_advance = 1;
|
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 cache_key key = { .size = bitmap->emsize, .glyph = bitmap->glyph, .mode = DWRITE_MEASURING_MODE_NATURAL };
|
||||||
struct dwrite_fontface *fontface = unsafe_impl_from_IDWriteFontFace(iface);
|
struct dwrite_fontface *fontface = unsafe_impl_from_IDWriteFontFace(iface);
|
||||||
|
struct get_glyph_bbox_params params;
|
||||||
struct cache_entry *entry;
|
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);
|
EnterCriticalSection(&fontface->cs);
|
||||||
/* For now bypass cache for transformed cases. */
|
/* For now bypass cache for transformed cases. */
|
||||||
if (bitmap->m && memcmp(bitmap->m, &identity, sizeof(*bitmap->m)))
|
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)))
|
else if ((entry = fontface_get_cache_entry(fontface, 0, &key)))
|
||||||
{
|
{
|
||||||
if (entry->has_bbox)
|
if (!entry->has_bbox)
|
||||||
bitmap->bbox = entry->bbox;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
font_funcs->get_glyph_bbox(fontface->get_font_object(fontface), bitmap);
|
params.bbox = &entry->bbox;
|
||||||
entry->bbox = bitmap->bbox;
|
UNIX_CALL(get_glyph_bbox, ¶ms);
|
||||||
entry->has_bbox = 1;
|
entry->has_bbox = 1;
|
||||||
}
|
}
|
||||||
|
bitmap->bbox = entry->bbox;
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&fontface->cs);
|
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,
|
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 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;
|
const RECT *bbox = &bitmap->bbox;
|
||||||
|
unsigned int bitmap_size, _1bpp;
|
||||||
struct cache_entry *entry;
|
struct cache_entry *entry;
|
||||||
unsigned int bitmap_size;
|
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
bitmap_size = get_glyph_bitmap_pitch(rendering_mode, bbox->right - bbox->left) *
|
bitmap_size = get_glyph_bitmap_pitch(rendering_mode, bbox->right - bbox->left) *
|
||||||
(bbox->bottom - bbox->top);
|
(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);
|
EnterCriticalSection(&fontface->cs);
|
||||||
/* For now bypass cache for transformed cases. */
|
/* 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)))
|
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
|
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;
|
entry->bitmap_size = bitmap_size;
|
||||||
if ((entry->bitmap = malloc(entry->bitmap_size)))
|
if ((entry->bitmap = malloc(entry->bitmap_size)))
|
||||||
memcpy(entry->bitmap, bitmap->buf, entry->bitmap_size);
|
memcpy(entry->bitmap, bitmap->buf, entry->bitmap_size);
|
||||||
|
entry->is_1bpp = !!_1bpp;
|
||||||
entry->has_bitmap = 1;
|
entry->has_bitmap = 1;
|
||||||
}
|
}
|
||||||
*is_1bpp = entry->is_1bpp;
|
*is_1bpp = entry->is_1bpp;
|
||||||
|
@ -797,6 +827,7 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface)
|
||||||
{
|
{
|
||||||
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
|
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
|
||||||
ULONG refcount = InterlockedDecrement(&fontface->refcount);
|
ULONG refcount = InterlockedDecrement(&fontface->refcount);
|
||||||
|
struct release_font_object_params params = { fontface->font_object };
|
||||||
|
|
||||||
TRACE("%p, refcount %u.\n", iface, refcount);
|
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++)
|
for (i = 0; i < ARRAY_SIZE(fontface->glyphs); i++)
|
||||||
free(fontface->glyphs[i]);
|
free(fontface->glyphs[i]);
|
||||||
|
|
||||||
font_funcs->release_font_object(fontface->font_object);
|
UNIX_CALL(release_font_object, ¶ms);
|
||||||
if (fontface->stream)
|
if (fontface->stream)
|
||||||
{
|
{
|
||||||
IDWriteFontFileStream_ReleaseFileFragment(fontface->stream, fontface->data_context);
|
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)
|
static UINT16 WINAPI dwritefontface_GetGlyphCount(IDWriteFontFace5 *iface)
|
||||||
{
|
{
|
||||||
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
|
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
|
||||||
|
struct get_glyph_count_params params;
|
||||||
|
unsigned int count;
|
||||||
|
|
||||||
TRACE("%p.\n", iface);
|
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,
|
static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace5 *iface,
|
||||||
UINT16 const *glyphs, UINT32 glyph_count, DWRITE_GLYPH_METRICS *ret, BOOL is_sideways)
|
UINT16 const *glyphs, UINT32 glyph_count, DWRITE_GLYPH_METRICS *ret, BOOL is_sideways)
|
||||||
{
|
{
|
||||||
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
|
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
|
||||||
|
struct get_design_glyph_metrics_params params;
|
||||||
|
DWRITE_GLYPH_METRICS metrics;
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
@ -945,16 +984,20 @@ static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace5 *ifa
|
||||||
if (is_sideways)
|
if (is_sideways)
|
||||||
FIXME("sideways metrics are not supported.\n");
|
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);
|
EnterCriticalSection(&fontface->cs);
|
||||||
for (i = 0; i < glyph_count; ++i)
|
for (i = 0; i < glyph_count; ++i)
|
||||||
{
|
{
|
||||||
DWRITE_GLYPH_METRICS metrics;
|
|
||||||
|
|
||||||
if (get_cached_glyph_metrics(fontface, glyphs[i], &metrics) != S_OK)
|
if (get_cached_glyph_metrics(fontface, glyphs[i], &metrics) != S_OK)
|
||||||
{
|
{
|
||||||
font_funcs->get_design_glyph_metrics(fontface->get_font_object(fontface),
|
params.glyph = glyphs[i];
|
||||||
fontface->metrics.designUnitsPerEm, fontface->typo_metrics.ascent,
|
UNIX_CALL(get_design_glyph_metrics, ¶ms);
|
||||||
fontface->simulations, glyphs[i], &metrics);
|
|
||||||
if (FAILED(hr = set_cached_glyph_metrics(fontface, glyphs[i], &metrics))) break;
|
if (FAILED(hr = set_cached_glyph_metrics(fontface, glyphs[i], &metrics))) break;
|
||||||
}
|
}
|
||||||
ret[i] = metrics;
|
ret[i] = metrics;
|
||||||
|
@ -1024,12 +1067,13 @@ static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace5 *iface,
|
||||||
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
|
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
|
||||||
D2D1_POINT_2F *origins, baseline_origin = { 0 };
|
D2D1_POINT_2F *origins, baseline_origin = { 0 };
|
||||||
struct dwrite_outline outline, outline_size;
|
struct dwrite_outline outline, outline_size;
|
||||||
|
struct get_glyph_outline_params params;
|
||||||
D2D1_BEZIER_SEGMENT segment;
|
D2D1_BEZIER_SEGMENT segment;
|
||||||
D2D1_POINT_2F point;
|
D2D1_POINT_2F point;
|
||||||
DWRITE_GLYPH_RUN run;
|
DWRITE_GLYPH_RUN run;
|
||||||
unsigned int i, j, p;
|
unsigned int i, j, p;
|
||||||
|
NTSTATUS status;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
int ret;
|
|
||||||
|
|
||||||
TRACE("%p, %.8e, %p, %p, %p, %u, %d, %d, %p.\n", iface, emSize, glyphs, advances, offsets,
|
TRACE("%p, %.8e, %p, %p, %p, %u, %d, %d, %p.\n", iface, emSize, glyphs, advances, offsets,
|
||||||
count, is_sideways, is_rtl, sink);
|
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_size, 0, sizeof(outline_size));
|
||||||
memset(&outline, 0, sizeof(outline));
|
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)
|
for (i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
outline.tags.count = outline.points.count = 0;
|
outline.tags.count = outline.points.count = 0;
|
||||||
|
|
||||||
EnterCriticalSection(&fontface->cs);
|
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,
|
dwrite_array_reserve((void **)&outline.tags.values, &outline.tags.size, outline_size.tags.count,
|
||||||
sizeof(*outline.tags.values));
|
sizeof(*outline.tags.values));
|
||||||
dwrite_array_reserve((void **)&outline.points.values, &outline.points.size, outline_size.points.count,
|
dwrite_array_reserve((void **)&outline.points.values, &outline.points.size, outline_size.points.count,
|
||||||
sizeof(*outline.points.values));
|
sizeof(*outline.points.values));
|
||||||
|
|
||||||
if ((ret = font_funcs->get_glyph_outline(fontface->get_font_object(fontface), emSize, fontface->simulations,
|
params.outline = &outline;
|
||||||
glyphs[i], &outline)))
|
if ((status = UNIX_CALL(get_glyph_outline, ¶ms)))
|
||||||
{
|
{
|
||||||
WARN("Failed to get glyph outline for glyph %u.\n", glyphs[i]);
|
WARN("Failed to get glyph outline for glyph %u.\n", glyphs[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&fontface->cs);
|
LeaveCriticalSection(&fontface->cs);
|
||||||
|
|
||||||
if (ret)
|
if (status)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (j = 0, p = 0; j < outline.tags.count; ++j)
|
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;
|
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;
|
const void *data_ptr;
|
||||||
void *data_context;
|
void *data_context;
|
||||||
UINT64 size;
|
|
||||||
|
|
||||||
if (!fontface->font_object && SUCCEEDED(IDWriteFontFileStream_GetFileSize(fontface->stream, &size)))
|
if (!fontface->font_object && SUCCEEDED(IDWriteFontFileStream_GetFileSize(fontface->stream, &size)))
|
||||||
{
|
{
|
||||||
if (SUCCEEDED(IDWriteFontFileStream_ReadFileFragment(fontface->stream, &data_ptr, 0, size, &data_context)))
|
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");
|
WARN("Backend failed to create font object.\n");
|
||||||
IDWriteFontFileStream_ReleaseFileFragment(fontface->stream, data_context);
|
IDWriteFontFileStream_ReleaseFileFragment(fontface->stream, data_context);
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InterlockedCompareExchangePointer((void **)&fontface->font_object, font_object, NULL))
|
if (InterlockedCompareExchange64((LONGLONG *)&fontface->font_object, font_object, 0))
|
||||||
font_funcs->release_font_object(font_object);
|
{
|
||||||
|
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;
|
BYTE *src = glyph_bitmap.buf, *dst;
|
||||||
int x, y, width, height;
|
int x, y, width, height;
|
||||||
BOOL is_1bpp;
|
unsigned int is_1bpp;
|
||||||
|
|
||||||
glyph_bitmap.glyph = analysis->run.glyphIndices[i];
|
glyph_bitmap.glyph = analysis->run.glyphIndices[i];
|
||||||
dwrite_fontface_get_glyph_bbox(analysis->run.fontFace, &glyph_bitmap);
|
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);
|
glyph_bitmap.pitch = get_glyph_bitmap_pitch(analysis->rendering_mode, width);
|
||||||
memset(src, 0, height * glyph_bitmap.pitch);
|
memset(src, 0, height * glyph_bitmap.pitch);
|
||||||
|
|
||||||
if (FAILED(dwrite_fontface_get_glyph_bitmap(fontface, analysis->rendering_mode, &is_1bpp, &glyph_bitmap)))
|
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);
|
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;
|
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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#define WIN32_NO_STATUS
|
#define WIN32_NO_STATUS
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
#include "unixlib.h"
|
||||||
|
|
||||||
#include "dwrite_private.h"
|
#include "dwrite_private.h"
|
||||||
|
|
||||||
|
@ -88,6 +89,8 @@ MAKE_FUNCPTR(FT_Set_Pixel_Sizes);
|
||||||
#undef MAKE_FUNCPTR
|
#undef MAKE_FUNCPTR
|
||||||
static FT_Error (*pFT_Outline_EmboldenXY)(FT_Outline *, FT_Pos, FT_Pos);
|
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)
|
static FT_Size freetype_set_face_size(FT_Face face, FT_UInt emsize)
|
||||||
{
|
{
|
||||||
FT_Size size;
|
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;
|
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;
|
FT_Version_t FT_Version;
|
||||||
|
|
||||||
|
@ -118,7 +121,7 @@ static BOOL init_freetype(void)
|
||||||
if (!ft_handle)
|
if (!ft_handle)
|
||||||
{
|
{
|
||||||
WINE_MESSAGE("Wine cannot find the FreeType font library.\n");
|
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;}
|
#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
|
#undef LOAD_FUNCPTR
|
||||||
pFT_Outline_EmboldenXY = dlsym(ft_handle, "FT_Outline_EmboldenXY");
|
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");
|
ERR("Can't init FreeType library\n");
|
||||||
dlclose(ft_handle);
|
dlclose(ft_handle);
|
||||||
ft_handle = NULL;
|
ft_handle = NULL;
|
||||||
return FALSE;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
pFT_Library_Version(library, &FT_Version.major, &FT_Version.minor, &FT_Version.patch);
|
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);
|
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:
|
sym_not_found:
|
||||||
WINE_MESSAGE("Wine cannot find certain functions that it needs from FreeType library.\n");
|
WINE_MESSAGE("Wine cannot find certain functions that it needs from FreeType library.\n");
|
||||||
dlclose(ft_handle);
|
dlclose(ft_handle);
|
||||||
ft_handle = NULL;
|
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_Face face = NULL;
|
||||||
FT_Error fterror;
|
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)
|
if (fterror != FT_Err_Ok)
|
||||||
|
{
|
||||||
WARN("Failed to create a face object, error %d.\n", fterror);
|
WARN("Failed to create a face object, error %d.\n", fterror);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
return face;
|
*params->object = (ULONG_PTR)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,
|
static NTSTATUS get_design_glyph_metrics(void *args)
|
||||||
unsigned int simulations, UINT16 glyph, DWRITE_GLYPH_METRICS *ret)
|
|
||||||
{
|
{
|
||||||
FT_Face face = object;
|
struct get_design_glyph_metrics_params *params = args;
|
||||||
|
FT_Face face = FaceFromObject(params->object);
|
||||||
FT_Size size;
|
FT_Size size;
|
||||||
|
|
||||||
if (!(size = freetype_set_face_size(face, upem)))
|
if (!(size = freetype_set_face_size(face, params->upem)))
|
||||||
return;
|
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;
|
FT_Glyph_Metrics *metrics = &face->glyph->metrics;
|
||||||
|
|
||||||
ret->leftSideBearing = metrics->horiBearingX;
|
params->metrics->leftSideBearing = metrics->horiBearingX;
|
||||||
ret->advanceWidth = metrics->horiAdvance;
|
params->metrics->advanceWidth = metrics->horiAdvance;
|
||||||
ret->rightSideBearing = metrics->horiAdvance - metrics->horiBearingX - metrics->width;
|
params->metrics->rightSideBearing = metrics->horiAdvance - metrics->horiBearingX - metrics->width;
|
||||||
|
|
||||||
ret->advanceHeight = metrics->vertAdvance;
|
params->metrics->advanceHeight = metrics->vertAdvance;
|
||||||
ret->verticalOriginY = ascent;
|
params->metrics->verticalOriginY = params->ascent;
|
||||||
ret->topSideBearing = ascent - metrics->horiBearingY;
|
params->metrics->topSideBearing = params->ascent - metrics->horiBearingY;
|
||||||
ret->bottomSideBearing = metrics->vertAdvance - metrics->height - ret->topSideBearing;
|
params->metrics->bottomSideBearing = metrics->vertAdvance - metrics->height - params->metrics->topSideBearing;
|
||||||
|
|
||||||
/* Adjust in case of bold simulation, glyphs without contours are ignored. */
|
/* 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)
|
if (params->metrics->advanceWidth)
|
||||||
ret->advanceWidth += (upem + 49) / 50;
|
params->metrics->advanceWidth += (params->upem + 49) / 50;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pFT_Done_Size(size);
|
pFT_Done_Size(size);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct decompose_context
|
struct decompose_context
|
||||||
|
@ -425,52 +445,55 @@ static void embolden_glyph(FT_Glyph glyph, FLOAT emsize)
|
||||||
embolden_glyph_outline(&outline_glyph->outline, emsize);
|
embolden_glyph_outline(&outline_glyph->outline, emsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CDECL freetype_get_glyph_outline(font_object_handle object, float emsize, unsigned int simulations,
|
static NTSTATUS get_glyph_outline(void *args)
|
||||||
UINT16 glyph, struct dwrite_outline *outline)
|
|
||||||
{
|
{
|
||||||
FT_Face face = object;
|
struct get_glyph_outline_params *params = args;
|
||||||
|
FT_Face face = FaceFromObject(params->object);
|
||||||
FT_Size size;
|
FT_Size size;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (!(size = freetype_set_face_size(face, emsize)))
|
if (!(size = freetype_set_face_size(face, params->emsize)))
|
||||||
return 0;
|
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_Outline *ft_outline = &face->glyph->outline;
|
||||||
FT_Matrix m;
|
FT_Matrix m;
|
||||||
|
|
||||||
if (outline->points.values)
|
if (params->outline->points.values)
|
||||||
{
|
{
|
||||||
if (simulations & DWRITE_FONT_SIMULATIONS_BOLD)
|
if (params->simulations & DWRITE_FONT_SIMULATIONS_BOLD)
|
||||||
embolden_glyph_outline(ft_outline, emsize);
|
embolden_glyph_outline(ft_outline, params->emsize);
|
||||||
|
|
||||||
m.xx = 1 << 16;
|
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.yx = 0;
|
||||||
m.yy = -(1 << 16); /* flip Y axis */
|
m.yy = -(1 << 16); /* flip Y axis */
|
||||||
|
|
||||||
pFT_Outline_Transform(ft_outline, &m);
|
pFT_Outline_Transform(ft_outline, &m);
|
||||||
|
|
||||||
ret = decompose_outline(ft_outline, outline);
|
decompose_outline(ft_outline, params->outline);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Intentionally overestimate numbers to keep it simple. */
|
/* Intentionally overestimate numbers to keep it simple. */
|
||||||
outline->points.count = ft_outline->n_points * 3;
|
params->outline->points.count = ft_outline->n_points * 3;
|
||||||
outline->tags.count = ft_outline->n_points + ft_outline->n_contours * 2;
|
params->outline->tags.count = ft_outline->n_points + ft_outline->n_contours * 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pFT_Done_Size(size);
|
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;
|
struct get_glyph_count_params *params = args;
|
||||||
return face ? face->num_glyphs : 0;
|
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)
|
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;
|
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->xx = 1 << 16;
|
||||||
ret->xy = 0;
|
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.
|
/* Some fonts provide mostly bitmaps and very few outlines, for example for .notdef.
|
||||||
Disable transform if that's the case. */
|
Disable transform if that's the case. */
|
||||||
if (!bitmap->m && !bitmap->simulations)
|
if (!memcmp(m, &identity, sizeof(*m)) && !simulations)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (bitmap->simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE) {
|
if (simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE)
|
||||||
m.xx = 1 << 16;
|
{
|
||||||
m.xy = (1 << 16) / 3;
|
ftm.xx = 1 << 16;
|
||||||
m.yx = 0;
|
ftm.xy = (1 << 16) / 3;
|
||||||
m.yy = 1 << 16;
|
ftm.yx = 0;
|
||||||
pFT_Matrix_Multiply(&m, ret);
|
ftm.yy = 1 << 16;
|
||||||
|
pFT_Matrix_Multiply(&ftm, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bitmap->m) {
|
ft_matrix_from_dwrite_matrix(m, &ftm);
|
||||||
ft_matrix_from_dwrite_matrix(bitmap->m, &m);
|
pFT_Matrix_Multiply(&ftm, ret);
|
||||||
pFT_Matrix_Multiply(&m, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
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_Glyph glyph = NULL;
|
||||||
FT_BBox bbox = { 0 };
|
FT_BBox bbox = { 0 };
|
||||||
BOOL needs_transform;
|
BOOL needs_transform;
|
||||||
FT_Matrix m;
|
FT_Matrix m;
|
||||||
FT_Size size;
|
FT_Size size;
|
||||||
|
|
||||||
SetRectEmpty(&bitmap->bbox);
|
SetRectEmpty(params->bbox);
|
||||||
|
|
||||||
if (!(size = freetype_set_face_size(face, bitmap->emsize)))
|
if (!(size = freetype_set_face_size(face, params->emsize)))
|
||||||
return;
|
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);
|
pFT_Done_Size(size);
|
||||||
return;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pFT_Get_Glyph(face->glyph, &glyph);
|
pFT_Get_Glyph(face->glyph, &glyph);
|
||||||
if (needs_transform)
|
if (needs_transform)
|
||||||
{
|
{
|
||||||
if (bitmap->simulations & DWRITE_FONT_SIMULATIONS_BOLD)
|
if (params->simulations & DWRITE_FONT_SIMULATIONS_BOLD)
|
||||||
embolden_glyph(glyph, bitmap->emsize);
|
embolden_glyph(glyph, params->emsize);
|
||||||
|
|
||||||
/* Includes oblique and user transform. */
|
/* Includes oblique and user transform. */
|
||||||
pFT_Glyph_Transform(glyph, &m, NULL);
|
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);
|
pFT_Done_Size(size);
|
||||||
|
|
||||||
/* flip Y axis */
|
/* 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 width = bbox->right - bbox->left;
|
||||||
int height = bbox->bottom - bbox->top;
|
int height = bbox->bottom - bbox->top;
|
||||||
|
|
||||||
|
*params->is_1bpp = 1;
|
||||||
|
|
||||||
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
|
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
|
||||||
FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
|
FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
|
||||||
const FT_Outline *src = &outline->outline;
|
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.width = width;
|
||||||
ft_bitmap.rows = height;
|
ft_bitmap.rows = height;
|
||||||
ft_bitmap.pitch = bitmap->pitch;
|
ft_bitmap.pitch = params->pitch;
|
||||||
ft_bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
|
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. */
|
/* Note: FreeType will only set 'black' bits for us. */
|
||||||
if (pFT_Outline_New(library, src->n_points, src->n_contours, ©) == 0) {
|
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) {
|
else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
|
||||||
FT_Bitmap *ft_bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
|
FT_Bitmap *ft_bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
|
||||||
BYTE *src = ft_bitmap->buffer, *dst = bitmap->buf;
|
BYTE *src = ft_bitmap->buffer, *dst = params->bitmap;
|
||||||
int w = min(bitmap->pitch, (ft_bitmap->width + 7) >> 3);
|
int w = min(params->pitch, (ft_bitmap->width + 7) >> 3);
|
||||||
int h = min(height, ft_bitmap->rows);
|
int h = min(height, ft_bitmap->rows);
|
||||||
|
|
||||||
while (h--) {
|
while (h--) {
|
||||||
memcpy(dst, src, w);
|
memcpy(dst, src, w);
|
||||||
src += ft_bitmap->pitch;
|
src += ft_bitmap->pitch;
|
||||||
dst += bitmap->pitch;
|
dst += params->pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
FIXME("format %x not handled\n", glyph->format);
|
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 width = bbox->right - bbox->left;
|
||||||
int height = bbox->bottom - bbox->top;
|
int height = bbox->bottom - bbox->top;
|
||||||
BOOL ret = FALSE;
|
|
||||||
|
*params->is_1bpp = 0;
|
||||||
|
|
||||||
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
|
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
|
||||||
FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
|
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.width = width;
|
||||||
ft_bitmap.rows = height;
|
ft_bitmap.rows = height;
|
||||||
ft_bitmap.pitch = bitmap->pitch;
|
ft_bitmap.pitch = params->pitch;
|
||||||
ft_bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
|
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. */
|
/* Note: FreeType will only set 'black' bits for us. */
|
||||||
if (pFT_Outline_New(library, src->n_points, src->n_contours, ©) == 0) {
|
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) {
|
else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
|
||||||
FT_Bitmap *ft_bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
|
FT_Bitmap *ft_bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
|
||||||
BYTE *src = ft_bitmap->buffer, *dst = bitmap->buf;
|
BYTE *src = ft_bitmap->buffer, *dst = params->bitmap;
|
||||||
int w = min(bitmap->pitch, (ft_bitmap->width + 7) >> 3);
|
int w = min(params->pitch, (ft_bitmap->width + 7) >> 3);
|
||||||
int h = min(height, ft_bitmap->rows);
|
int h = min(height, ft_bitmap->rows);
|
||||||
|
|
||||||
while (h--) {
|
while (h--) {
|
||||||
memcpy(dst, src, w);
|
memcpy(dst, src, w);
|
||||||
src += ft_bitmap->pitch;
|
src += ft_bitmap->pitch;
|
||||||
dst += bitmap->pitch;
|
dst += params->pitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = TRUE;
|
*params->is_1bpp = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
FIXME("format %x not handled\n", glyph->format);
|
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 needs_transform;
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
FT_Glyph glyph;
|
FT_Glyph glyph;
|
||||||
FT_Size size;
|
FT_Size size;
|
||||||
FT_Matrix m;
|
FT_Matrix m;
|
||||||
|
|
||||||
if (!(size = freetype_set_face_size(face, bitmap->emsize)))
|
*params->is_1bpp = 0;
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
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);
|
pFT_Get_Glyph(face->glyph, &glyph);
|
||||||
|
|
||||||
if (needs_transform)
|
if (needs_transform)
|
||||||
{
|
{
|
||||||
if (bitmap->simulations & DWRITE_FONT_SIMULATIONS_BOLD)
|
if (params->simulations & DWRITE_FONT_SIMULATIONS_BOLD)
|
||||||
embolden_glyph(glyph, bitmap->emsize);
|
embolden_glyph(glyph, params->emsize);
|
||||||
|
|
||||||
/* Includes oblique and user transform. */
|
/* Includes oblique and user transform. */
|
||||||
pFT_Glyph_Transform(glyph, &m, NULL);
|
pFT_Glyph_Transform(glyph, &m, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bitmap->aliased)
|
if (params->mode == DWRITE_RENDERING_MODE1_ALIASED)
|
||||||
ret = freetype_get_aliased_glyph_bitmap(bitmap, glyph);
|
ret = freetype_get_aliased_glyph_bitmap(params, glyph);
|
||||||
else
|
else
|
||||||
ret = freetype_get_aa_glyph_bitmap(bitmap, glyph);
|
ret = freetype_get_aa_glyph_bitmap(params, glyph);
|
||||||
|
|
||||||
pFT_Done_Glyph(glyph);
|
pFT_Done_Glyph(glyph);
|
||||||
}
|
}
|
||||||
|
@ -683,128 +717,100 @@ static BOOL CDECL freetype_get_glyph_bitmap(font_object_handle object, struct dw
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INT32 CDECL freetype_get_glyph_advance(font_object_handle object, float emsize, UINT16 glyph,
|
static NTSTATUS get_glyph_advance(void *args)
|
||||||
DWRITE_MEASURING_MODE mode, BOOL *has_contours)
|
|
||||||
{
|
{
|
||||||
FT_Face face = object;
|
struct get_glyph_advance_params *params = args;
|
||||||
INT32 advance = 0;
|
FT_Face face = FaceFromObject(params->object);
|
||||||
FT_Size size;
|
FT_Size size;
|
||||||
|
|
||||||
*has_contours = FALSE;
|
*params->advance = 0;
|
||||||
|
*params->has_contours = FALSE;
|
||||||
|
|
||||||
if (!(size = freetype_set_face_size(face, emsize)))
|
if (!(size = freetype_set_face_size(face, params->emsize)))
|
||||||
return 0;
|
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;
|
*params->advance = face->glyph->advance.x >> 6;
|
||||||
*has_contours = freetype_glyph_has_contours(face);
|
*params->has_contours = freetype_glyph_has_contours(face);
|
||||||
}
|
}
|
||||||
|
|
||||||
pFT_Done_Size(size);
|
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;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* HAVE_FREETYPE */
|
#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,
|
static NTSTATUS create_font_object(void *args)
|
||||||
UINT16 glyph, struct dwrite_outline *outline)
|
|
||||||
{
|
{
|
||||||
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,
|
static NTSTATUS get_glyph_outline(void *args)
|
||||||
DWRITE_MEASURING_MODE mode, BOOL *has_contours)
|
|
||||||
{
|
{
|
||||||
*has_contours = FALSE;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
*params->has_contours = 0;
|
||||||
|
*params->advance = 0;
|
||||||
|
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CDECL null_get_design_glyph_metrics(font_object_handle object, UINT16 upem, UINT16 ascent, unsigned int simulations,
|
static NTSTATUS get_glyph_bbox(void *args)
|
||||||
UINT16 glyph, DWRITE_GLYPH_METRICS *metrics)
|
|
||||||
{
|
{
|
||||||
|
struct get_glyph_bbox_params *params = args;
|
||||||
|
SetRectEmpty(params->bbox);
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
const static struct font_backend_funcs null_funcs =
|
static NTSTATUS get_glyph_bitmap(void *args)
|
||||||
{
|
{
|
||||||
null_create_font_object,
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
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,
|
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 */
|
#endif /* HAVE_FREETYPE */
|
||||||
|
|
||||||
NTSTATUS CDECL __wine_init_unix_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out)
|
const unixlib_entry_t __wine_unix_call_funcs[] =
|
||||||
{
|
{
|
||||||
if (reason == DLL_PROCESS_ATTACH)
|
process_attach,
|
||||||
return init_freetype_lib(module, reason, ptr_in, ptr_out);
|
process_detach,
|
||||||
else if (reason == DLL_PROCESS_DETACH)
|
create_font_object,
|
||||||
return release_freetype_lib();
|
release_font_object,
|
||||||
return STATUS_SUCCESS;
|
get_glyph_outline,
|
||||||
}
|
get_glyph_count,
|
||||||
|
get_glyph_advance,
|
||||||
|
get_glyph_bbox,
|
||||||
|
get_glyph_bitmap,
|
||||||
|
get_design_glyph_metrics,
|
||||||
|
};
|
||||||
|
|
|
@ -30,11 +30,13 @@
|
||||||
#include "initguid.h"
|
#include "initguid.h"
|
||||||
|
|
||||||
#include "dwrite_private.h"
|
#include "dwrite_private.h"
|
||||||
|
#include "unixlib.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
|
WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
|
||||||
|
|
||||||
HMODULE dwrite_module = 0;
|
HMODULE dwrite_module = 0;
|
||||||
|
unixlib_handle_t unixlib_handle = 0;
|
||||||
static IDWriteFactory7 *shared_factory;
|
static IDWriteFactory7 *shared_factory;
|
||||||
static void release_shared_factory(IDWriteFactory7 *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:
|
case DLL_PROCESS_ATTACH:
|
||||||
dwrite_module = hinstDLL;
|
dwrite_module = hinstDLL;
|
||||||
DisableThreadLibraryCalls( 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();
|
init_local_fontfile_loader();
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
if (reserved) break;
|
if (reserved) break;
|
||||||
release_shared_factory(shared_factory);
|
release_shared_factory(shared_factory);
|
||||||
release_font_backend();
|
if (unixlib_handle) UNIX_CALL(process_detach, NULL);
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 )
|
Loading…
Reference in New Issue