Nikolay Sivov : dwrite: Request one glyph outline at a time in GetGlyphRunOutline().

Alexandre Julliard julliard at winehq.org
Mon Mar 15 16:59:12 CDT 2021


Module: wine
Branch: master
Commit: 0ed0fd05c3364bb78a1ccb6ff0cb63c00283c697
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=0ed0fd05c3364bb78a1ccb6ff0cb63c00283c697

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Mon Mar 15 10:36:51 2021 +0300

dwrite: Request one glyph outline at a time in GetGlyphRunOutline().

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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;
 }




More information about the wine-cvs mailing list