Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
In preparation to remove user callbacks from freetype integration code. Also this reuses currently duplicated code for origins.
dlls/dwrite/dwrite_private.h | 5 +-- dlls/dwrite/font.c | 39 ++++++++++++++++-- dlls/dwrite/freetype.c | 79 +++++++++--------------------------- 3 files changed, 57 insertions(+), 66 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 8c09a315f54..fe1a16c8899 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -463,9 +463,8 @@ extern void release_freetype(void) DECLSPEC_HIDDEN; extern HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph, DWRITE_GLYPH_METRICS *metrics) DECLSPEC_HIDDEN; extern void freetype_notify_cacheremove(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN; -extern HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *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 HRESULT freetype_get_glyph_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 glyph, + D2D1_POINT_2F origin, IDWriteGeometrySink *sink) DECLSPEC_HIDDEN; extern UINT16 freetype_get_glyphcount(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN; extern void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap_desc) DECLSPEC_HIDDEN; extern BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index e5050476938..0167878e912 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -827,16 +827,49 @@ static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace5 *iface, UINT16 const *glyphs, FLOAT const* advances, DWRITE_GLYPH_OFFSET const *offsets, UINT32 count, BOOL is_sideways, BOOL is_rtl, IDWriteGeometrySink *sink) { + D2D1_POINT_2F *origins, baseline_origin = { 0 }; + DWRITE_GLYPH_RUN run; + unsigned int i; + HRESULT hr; + TRACE("%p, %.8e, %p, %p, %p, %u, %d, %d, %p.\n", iface, emSize, glyphs, advances, offsets, count, is_sideways, is_rtl, sink);
if (!glyphs || !sink) return E_INVALIDARG;
- if (is_sideways) - FIXME("sideways mode is not supported.\n"); + if (!count) + return S_OK;
- return freetype_get_glyphrun_outline(iface, emSize, glyphs, advances, offsets, count, is_rtl, sink); + run.fontFace = (IDWriteFontFace *)iface; + run.fontEmSize = emSize; + run.glyphCount = count; + run.glyphIndices = glyphs; + run.glyphAdvances = advances; + run.glyphOffsets = offsets; + run.isSideways = is_sideways; + run.bidiLevel = is_rtl ? 1 : 0; + + if (!(origins = heap_alloc(sizeof(*origins) * count))) + return E_OUTOFMEMORY; + + if (FAILED(hr = compute_glyph_origins(&run, DWRITE_MEASURING_MODE_NATURAL, baseline_origin, NULL, origins))) + { + heap_free(origins); + return hr; + } + + ID2D1SimplifiedGeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING); + + for (i = 0; i < count; ++i) + { + if (FAILED(hr = freetype_get_glyph_outline(iface, emSize, glyphs[i], origins[i], sink))) + WARN("Failed to get glyph outline for glyph %u.\n", glyphs[i]); + } + + heap_free(origins); + + return S_OK; }
static DWRITE_RENDERING_MODE fontface_renderingmode_from_measuringmode(DWRITE_MEASURING_MODE measuring, diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index b770caac479..83b2ae1bc88 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -464,20 +464,14 @@ static void embolden_glyph(FT_Glyph glyph, FLOAT emsize) embolden_glyph_outline(&outline_glyph->outline, emsize); }
-HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 const *glyphs, - float const *advances, DWRITE_GLYPH_OFFSET const *offsets, unsigned int count, BOOL is_rtl, - IDWriteGeometrySink *sink) +HRESULT freetype_get_glyph_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 glyph, + D2D1_POINT_2F origin, IDWriteGeometrySink *sink) { FTC_ScalerRec scaler; USHORT simulations; HRESULT hr = S_OK; FT_Size size;
- if (!count) - return S_OK; - - ID2D1SimplifiedGeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING); - simulations = IDWriteFontFace5_GetSimulations(fontface);
scaler.face_id = fontface; @@ -490,56 +484,22 @@ HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emSize, EnterCriticalSection(&freetype_cs); if (pFTC_Manager_LookupSize(cache_manager, &scaler, &size) == 0) { - 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, glyph, FT_LOAD_NO_BITMAP) == 0) { - 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; - D2D1_POINT_2F glyph_origin; - FT_Matrix m; - - if (simulations & DWRITE_FONT_SIMULATIONS_BOLD) - embolden_glyph_outline(outline, emSize); - - m.xx = 1 << 16; - m.xy = simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE ? (1 << 16) / 3 : 0; - m.yx = 0; - m.yy = -(1 << 16); /* flip Y axis */ - - pFT_Outline_Transform(outline, &m); - - glyph_origin = origin; - - if (is_rtl) - { - glyph_origin.x -= ft_advance; - - if (offsets) - { - glyph_origin.x -= offsets[i].advanceOffset; - glyph_origin.y -= offsets[i].ascenderOffset; - } - - origin.x -= advances ? advances[i] : ft_advance; - } - else - { - if (offsets) - { - glyph_origin.x += offsets[i].advanceOffset; - glyph_origin.y -= offsets[i].ascenderOffset; - } - - origin.x += advances ? advances[i] : ft_advance; - } - - decompose_outline(outline, glyph_origin, sink); - } + FT_Outline *outline = &size->face->glyph->outline; + FT_Matrix m; + + if (simulations & DWRITE_FONT_SIMULATIONS_BOLD) + embolden_glyph_outline(outline, emSize); + + m.xx = 1 << 16; + m.xy = simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE ? (1 << 16) / 3 : 0; + m.yx = 0; + m.yy = -(1 << 16); /* flip Y axis */ + + pFT_Outline_Transform(outline, &m); + + decompose_outline(outline, origin, sink); } } else @@ -837,9 +797,8 @@ HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT return E_NOTIMPL; }
-HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 const *glyphs, - float const *advances, DWRITE_GLYPH_OFFSET const *offsets, unsigned int count, BOOL is_rtl, - IDWriteGeometrySink *sink) +HRESULT freetype_get_glyph_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 glyph, + D2D1_POINT_2F origin, IDWriteGeometrySink *sink) { return E_NOTIMPL; }