Commit 1a8d6f55 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

dwrite: Allocate outline buffers on PE side.

parent 6356717c
...@@ -742,7 +742,7 @@ struct font_backend_funcs ...@@ -742,7 +742,7 @@ struct font_backend_funcs
font_object_handle (CDECL *create_font_object)(const void *data_ptr, UINT64 data_size, unsigned int index); 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); void (CDECL *release_font_object)(font_object_handle object);
void (CDECL *notify_release)(void *key); void (CDECL *notify_release)(void *key);
int (CDECL *get_glyph_outline)(void *key, float em_size, unsigned int simulations, UINT16 glyph, int (CDECL *get_glyph_outline)(font_object_handle object, float emsize, unsigned int simulations, UINT16 glyph,
struct dwrite_outline *outline); struct dwrite_outline *outline);
UINT16 (CDECL *get_glyph_count)(font_object_handle object); UINT16 (CDECL *get_glyph_count)(font_object_handle object);
INT32 (CDECL *get_glyph_advance)(void *key, float em_size, UINT16 index, DWRITE_MEASURING_MODE measuring_mode, INT32 (CDECL *get_glyph_advance)(void *key, float em_size, UINT16 index, DWRITE_MEASURING_MODE measuring_mode,
......
...@@ -835,12 +835,13 @@ static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace5 *iface, ...@@ -835,12 +835,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 = {{ 0 }}; struct dwrite_outline outline, outline_size;
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;
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);
...@@ -871,14 +872,32 @@ static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace5 *iface, ...@@ -871,14 +872,32 @@ static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace5 *iface,
ID2D1SimplifiedGeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING); ID2D1SimplifiedGeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING);
memset(&outline_size, 0, sizeof(outline_size));
memset(&outline, 0, sizeof(outline));
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;
if (font_funcs->get_glyph_outline(iface, emSize, fontface->simulations, glyphs[i], &outline))
EnterCriticalSection(&fontface->cs);
if (!(ret = font_funcs->get_glyph_outline(fontface->get_font_object(fontface), emSize, fontface->simulations,
glyphs[i], &outline_size)))
{
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)))
{ {
WARN("Failed to get glyph outline for glyph %u.\n", glyphs[i]); WARN("Failed to get glyph outline for glyph %u.\n", glyphs[i]);
continue;
} }
}
LeaveCriticalSection(&fontface->cs);
if (ret)
continue;
for (j = 0, p = 0; j < outline.tags.count; ++j) for (j = 0, p = 0; j < outline.tags.count; ++j)
{ {
......
...@@ -318,11 +318,8 @@ static inline void ft_vector_to_d2d_point(const FT_Vector *v, D2D1_POINT_2F *p) ...@@ -318,11 +318,8 @@ static inline void ft_vector_to_d2d_point(const FT_Vector *v, D2D1_POINT_2F *p)
static int dwrite_outline_push_tag(struct dwrite_outline *outline, unsigned char tag) static int dwrite_outline_push_tag(struct dwrite_outline *outline, unsigned char tag)
{ {
if (!dwrite_array_reserve((void **)&outline->tags.values, &outline->tags.size, outline->tags.count + 1, if (outline->tags.size < outline->tags.count + 1)
sizeof(*outline->tags.values)))
{
return 1; return 1;
}
outline->tags.values[outline->tags.count++] = tag; outline->tags.values[outline->tags.count++] = tag;
...@@ -331,11 +328,8 @@ static int dwrite_outline_push_tag(struct dwrite_outline *outline, unsigned char ...@@ -331,11 +328,8 @@ static int dwrite_outline_push_tag(struct dwrite_outline *outline, unsigned char
static int dwrite_outline_push_points(struct dwrite_outline *outline, const D2D1_POINT_2F *points, unsigned int count) static int dwrite_outline_push_points(struct dwrite_outline *outline, const D2D1_POINT_2F *points, unsigned int count)
{ {
if (!dwrite_array_reserve((void **)&outline->points.values, &outline->points.size, outline->points.count + count, if (outline->points.size < outline->points.count + count)
sizeof(*outline->points.values)))
{
return 1; return 1;
}
memcpy(&outline->points.values[outline->points.count], points, sizeof(*points) * count); memcpy(&outline->points.values[outline->points.count], points, sizeof(*points) * count);
outline->points.count += count; outline->points.count += count;
...@@ -512,30 +506,25 @@ static void embolden_glyph(FT_Glyph glyph, FLOAT emsize) ...@@ -512,30 +506,25 @@ 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(void *key, float emSize, unsigned int simulations, static int CDECL freetype_get_glyph_outline(font_object_handle object, float emsize, unsigned int simulations,
UINT16 glyph, struct dwrite_outline *outline) UINT16 glyph, struct dwrite_outline *outline)
{ {
FTC_ScalerRec scaler; FT_Face face = object;
FT_Size size; FT_Size size;
int ret; int ret = 0;
scaler.face_id = key; if (!(size = freetype_set_face_size(face, emsize)))
scaler.width = emSize; return 0;
scaler.height = emSize;
scaler.pixel = 1;
scaler.x_res = 0;
scaler.y_res = 0;
RtlEnterCriticalSection(&freetype_cs); if (!pFT_Load_Glyph(face, glyph, FT_LOAD_NO_BITMAP))
if (!(ret = pFTC_Manager_LookupSize(cache_manager, &scaler, &size)))
{ {
if (pFT_Load_Glyph(size->face, glyph, FT_LOAD_NO_BITMAP) == 0) FT_Outline *ft_outline = &face->glyph->outline;
{
FT_Outline *ft_outline = &size->face->glyph->outline;
FT_Matrix m; FT_Matrix m;
if (outline->points.values)
{
if (simulations & DWRITE_FONT_SIMULATIONS_BOLD) if (simulations & DWRITE_FONT_SIMULATIONS_BOLD)
embolden_glyph_outline(ft_outline, emSize); embolden_glyph_outline(ft_outline, emsize);
m.xx = 1 << 16; m.xx = 1 << 16;
m.xy = simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE ? (1 << 16) / 3 : 0; m.xy = simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE ? (1 << 16) / 3 : 0;
...@@ -546,8 +535,15 @@ static int CDECL freetype_get_glyph_outline(void *key, float emSize, unsigned in ...@@ -546,8 +535,15 @@ static int CDECL freetype_get_glyph_outline(void *key, float emSize, unsigned in
ret = decompose_outline(ft_outline, outline); ret = decompose_outline(ft_outline, 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;
}
} }
RtlLeaveCriticalSection(&freetype_cs);
pFT_Done_Size(size);
return ret; return ret;
} }
...@@ -856,7 +852,7 @@ static void CDECL null_notify_release(void *key) ...@@ -856,7 +852,7 @@ static void CDECL null_notify_release(void *key)
{ {
} }
static int CDECL null_get_glyph_outline(void *key, float emSize, unsigned int simulations, static int CDECL null_get_glyph_outline(font_object_handle object, float emSize, unsigned int simulations,
UINT16 glyph, struct dwrite_outline *outline) UINT16 glyph, struct dwrite_outline *outline)
{ {
return 1; return 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment