Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 5 +-- dlls/dwrite/freetype.c | 61 +++++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 28 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 0451a7e3f0..e2aa2131a1 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -320,8 +320,9 @@ extern void release_freetype(void) DECLSPEC_HIDDEN; extern HRESULT freetype_get_design_glyph_metrics(IDWriteFontFace4*,UINT16,UINT16,DWRITE_GLYPH_METRICS*) DECLSPEC_HIDDEN; extern void freetype_notify_cacheremove(IDWriteFontFace4*) DECLSPEC_HIDDEN; extern BOOL freetype_is_monospaced(IDWriteFontFace4*) DECLSPEC_HIDDEN; -extern HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4*,FLOAT,UINT16 const*,FLOAT const*, DWRITE_GLYPH_OFFSET const*, - UINT32,BOOL,IDWriteGeometrySink*) DECLSPEC_HIDDEN; +extern HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4 *fontface, float emsize, UINT16 const *glyphs, + float const *advances, DWRITE_GLYPH_OFFSET const *offsets, unsigned int count, BOOL is_rtl, + IDWriteGeometrySink *sink) DECLSPEC_HIDDEN; extern UINT16 freetype_get_glyphcount(IDWriteFontFace4*) DECLSPEC_HIDDEN; extern void freetype_get_glyphs(IDWriteFontFace4*,INT,UINT32 const*,UINT32,UINT16*) DECLSPEC_HIDDEN; extern BOOL freetype_has_kerning_pairs(IDWriteFontFace4*) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index d3036537f0..29acb5e0de 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -438,7 +438,7 @@ static int decompose_cubic_to(const FT_Vector *control1, const FT_Vector *contro return 0; }
-static void decompose_outline(FT_Outline *outline, FLOAT xoffset, FLOAT yoffset, IDWriteGeometrySink *sink) +static void decompose_outline(FT_Outline *outline, D2D1_POINT_2F offset, IDWriteGeometrySink *sink) { static const FT_Outline_Funcs decompose_funcs = { decompose_move_to, @@ -451,8 +451,8 @@ static void decompose_outline(FT_Outline *outline, FLOAT xoffset, FLOAT yoffset, struct decompose_context context;
context.sink = sink; - context.xoffset = xoffset; - context.yoffset = yoffset; + context.xoffset = offset.x; + context.yoffset = offset.y; context.figure_started = FALSE; context.move_to = FALSE; context.origin.x = 0; @@ -485,8 +485,9 @@ static void embolden_glyph(FT_Glyph glyph, FLOAT emsize) embolden_glyph_outline(&outline_glyph->outline, emsize); }
-HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4 *fontface, FLOAT emSize, UINT16 const *glyphs, - FLOAT const *advances, DWRITE_GLYPH_OFFSET const *offsets, UINT32 count, BOOL is_rtl, IDWriteGeometrySink *sink) +HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4 *fontface, float emSize, UINT16 const *glyphs, + float const *advances, DWRITE_GLYPH_OFFSET const *offsets, unsigned int count, BOOL is_rtl, + IDWriteGeometrySink *sink) { FTC_ScalerRec scaler; USHORT simulations; @@ -509,14 +510,19 @@ HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4 *fontface, FLOAT emSize,
EnterCriticalSection(&freetype_cs); if (pFTC_Manager_LookupSize(cache_manager, &scaler, &size) == 0) { - FLOAT advance = 0.0f; - UINT32 g; - - for (g = 0; g < count; g++) { - if (pFT_Load_Glyph(size->face, glyphs[g], FT_LOAD_NO_BITMAP) == 0) { + float rtl_factor = is_rtl ? -1.0f : 1.0f; + D2D1_POINT_2F origin; + unsigned int i; + + origin.x = origin.y = 0.0f; + for (i = 0; i < count; ++i) + { + if (pFT_Load_Glyph(size->face, glyphs[i], FT_LOAD_NO_BITMAP) == 0) + { FLOAT ft_advance = size->face->glyph->metrics.horiAdvance >> 6; FT_Outline *outline = &size->face->glyph->outline; - FLOAT xoffset = 0.0f, yoffset = 0.0f; + D2D1_POINT_2F glyph_origin; + float advance; FT_Matrix m;
if (simulations & DWRITE_FONT_SIMULATIONS_BOLD) @@ -529,23 +535,25 @@ HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4 *fontface, FLOAT emSize,
pFT_Outline_Transform(outline, &m);
+ if (advances) + advance = rtl_factor * advances[i]; + else + advance = rtl_factor * ft_advance; + + glyph_origin = origin; + if (is_rtl) + glyph_origin.x += advance; + /* glyph offsets act as current glyph adjustment */ - if (offsets) { - xoffset += is_rtl ? -offsets[g].advanceOffset : offsets[g].advanceOffset; - yoffset -= offsets[g].ascenderOffset; + if (offsets) + { + glyph_origin.x += rtl_factor * offsets[i].advanceOffset; + glyph_origin.y -= offsets[i].ascenderOffset; }
- if (g == 0 && is_rtl) - advance = advances ? -advances[g] : -ft_advance; - - xoffset += advance; - decompose_outline(outline, xoffset, yoffset, sink); + decompose_outline(outline, glyph_origin, sink);
- /* update advance to next glyph */ - if (advances) - advance += is_rtl ? -advances[g] : advances[g]; - else - advance += is_rtl ? -ft_advance : ft_advance; + origin.x += advance; } } } @@ -959,8 +967,9 @@ BOOL freetype_is_monospaced(IDWriteFontFace4 *fontface) return FALSE; }
-HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4 *fontface, FLOAT emSize, UINT16 const *glyphs, FLOAT const *advances, - DWRITE_GLYPH_OFFSET const *offsets, UINT32 count, BOOL is_rtl, IDWriteGeometrySink *sink) +HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4 *fontface, float emSize, UINT16 const *glyphs, + float const *advances, DWRITE_GLYPH_OFFSET const *offsets, unsigned int count, BOOL is_rtl, + IDWriteGeometrySink *sink) { return E_NOTIMPL; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/freetype.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index 29acb5e0de..58cad41340 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -317,17 +317,16 @@ BOOL freetype_is_monospaced(IDWriteFontFace4 *fontface)
struct decompose_context { IDWriteGeometrySink *sink; - FLOAT xoffset; - FLOAT yoffset; + D2D1_POINT_2F offset; BOOL figure_started; BOOL move_to; /* last call was 'move_to' */ FT_Vector origin; /* 'pen' position from last call */ };
-static inline void ft_vector_to_d2d_point(const FT_Vector *v, FLOAT xoffset, FLOAT yoffset, D2D1_POINT_2F *p) +static inline void ft_vector_to_d2d_point(const FT_Vector *v, D2D1_POINT_2F offset, D2D1_POINT_2F *p) { - p->x = (v->x / 64.0f) + xoffset; - p->y = (v->y / 64.0f) + yoffset; + p->x = (v->x / 64.0f) + offset.x; + p->y = (v->y / 64.0f) + offset.y; }
static void decompose_beginfigure(struct decompose_context *ctxt) @@ -337,7 +336,7 @@ static void decompose_beginfigure(struct decompose_context *ctxt) if (!ctxt->move_to) return;
- ft_vector_to_d2d_point(&ctxt->origin, ctxt->xoffset, ctxt->yoffset, &point); + ft_vector_to_d2d_point(&ctxt->origin, ctxt->offset, &point); ID2D1SimplifiedGeometrySink_BeginFigure(ctxt->sink, point, D2D1_FIGURE_BEGIN_FILLED);
ctxt->figure_started = TRUE; @@ -369,7 +368,7 @@ static int decompose_line_to(const FT_Vector *to, void *user)
decompose_beginfigure(ctxt);
- ft_vector_to_d2d_point(to, ctxt->xoffset, ctxt->yoffset, &point); + ft_vector_to_d2d_point(to, ctxt->offset, &point); ID2D1SimplifiedGeometrySink_AddLines(ctxt->sink, &point, 1);
ctxt->origin = *to; @@ -414,9 +413,9 @@ static int decompose_conic_to(const FT_Vector *control, const FT_Vector *to, voi cubic[1].y += (to->y + 1) / 3; cubic[2] = *to;
- ft_vector_to_d2d_point(cubic, ctxt->xoffset, ctxt->yoffset, points); - ft_vector_to_d2d_point(cubic + 1, ctxt->xoffset, ctxt->yoffset, points + 1); - ft_vector_to_d2d_point(cubic + 2, ctxt->xoffset, ctxt->yoffset, points + 2); + ft_vector_to_d2d_point(cubic, ctxt->offset, points); + ft_vector_to_d2d_point(cubic + 1, ctxt->offset, points + 1); + ft_vector_to_d2d_point(cubic + 2, ctxt->offset, points + 2); ID2D1SimplifiedGeometrySink_AddBeziers(ctxt->sink, (D2D1_BEZIER_SEGMENT*)points, 1); ctxt->origin = *to; return 0; @@ -430,9 +429,9 @@ static int decompose_cubic_to(const FT_Vector *control1, const FT_Vector *contro
decompose_beginfigure(ctxt);
- ft_vector_to_d2d_point(control1, ctxt->xoffset, ctxt->yoffset, points); - ft_vector_to_d2d_point(control2, ctxt->xoffset, ctxt->yoffset, points + 1); - ft_vector_to_d2d_point(to, ctxt->xoffset, ctxt->yoffset, points + 2); + ft_vector_to_d2d_point(control1, ctxt->offset, points); + ft_vector_to_d2d_point(control2, ctxt->offset, points + 1); + ft_vector_to_d2d_point(to, ctxt->offset, points + 2); ID2D1SimplifiedGeometrySink_AddBeziers(ctxt->sink, (D2D1_BEZIER_SEGMENT*)points, 1); ctxt->origin = *to; return 0; @@ -451,8 +450,7 @@ static void decompose_outline(FT_Outline *outline, D2D1_POINT_2F offset, IDWrite struct decompose_context context;
context.sink = sink; - context.xoffset = offset.x; - context.yoffset = offset.y; + context.offset = offset; context.figure_started = FALSE; context.move_to = FALSE; context.origin.x = 0;