Nikolay Sivov : dwrite: Correct return glyph origins for RTL runs.

Alexandre Julliard julliard at winehq.org
Mon Feb 22 15:43:22 CST 2021


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Mon Feb 22 21:29:35 2021 +0300

dwrite: Correct return glyph origins for RTL runs.

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

---

 dlls/dwrite/main.c       | 84 ++++++++++++++++--------------------------------
 dlls/dwrite/tests/font.c |  1 -
 2 files changed, 28 insertions(+), 57 deletions(-)

diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 40c82b6cd05..3b0505231bf 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -1551,76 +1551,48 @@ static HRESULT WINAPI dwritefactory4_TranslateColorGlyphRun(IDWriteFactory7 *ifa
 }
 
 static HRESULT compute_glyph_origins(DWRITE_GLYPH_RUN const *run, DWRITE_MEASURING_MODE measuring_mode,
-    D2D1_POINT_2F baseline_origin, DWRITE_MATRIX const *transform,  D2D1_POINT_2F *origins)
+    D2D1_POINT_2F baseline_origin, DWRITE_MATRIX const *transform, D2D1_POINT_2F *origins)
 {
-    IDWriteFontFace1 *fontface1 = NULL;
-    DWRITE_FONT_METRICS metrics;
-    FLOAT rtl_factor;
-    HRESULT hr;
-    UINT32 i;
+    struct dwrite_fontface *font_obj;
+    unsigned int i;
+    float advance;
 
-    rtl_factor = run->bidiLevel & 1 ? -1.0f : 1.0f;
+    font_obj = unsafe_impl_from_IDWriteFontFace(run->fontFace);
 
-    if (run->fontFace) {
-        IDWriteFontFace_GetMetrics(run->fontFace, &metrics);
-        if (FAILED(hr = IDWriteFontFace_QueryInterface(run->fontFace, &IID_IDWriteFontFace1, (void **)&fontface1)))
-            WARN("Failed to get IDWriteFontFace1, %#x.\n", hr);
-    }
+    for (i = 0; i < run->glyphCount; ++i)
+    {
+        origins[i] = baseline_origin;
 
-    for (i = 0; i < run->glyphCount; i++) {
-        FLOAT advance;
+        if (run->bidiLevel & 1)
+        {
+            advance = fontface_get_scaled_design_advance(font_obj, measuring_mode, run->fontEmSize,
+                    1.0f, transform, run->glyphIndices[i], run->isSideways);
 
-        /* Use nominal advances if not provided by caller. */
-        if (run->glyphAdvances)
-            advance = rtl_factor * run->glyphAdvances[i];
-        else {
-            INT32 a;
+            origins[i].x -= advance;
 
-            advance = 0.0f;
-            switch (measuring_mode)
+            if (run->glyphOffsets)
             {
-            case DWRITE_MEASURING_MODE_NATURAL:
-                if (SUCCEEDED(IDWriteFontFace1_GetDesignGlyphAdvances(fontface1, 1, run->glyphIndices + i, &a,
-                        run->isSideways)))
-                    advance = rtl_factor * get_scaled_advance_width(a, run->fontEmSize, &metrics);
-                break;
-            case DWRITE_MEASURING_MODE_GDI_CLASSIC:
-            case DWRITE_MEASURING_MODE_GDI_NATURAL:
-                if (SUCCEEDED(IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1, run->fontEmSize,
-                        1.0f, transform, measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL,
-                        run->isSideways, 1, run->glyphIndices + i, &a)))
-                    advance = rtl_factor * floorf(a * run->fontEmSize / metrics.designUnitsPerEm + 0.5f);
-                break;
-            default:
-                ;
+                origins[i].x -= run->glyphOffsets[i].advanceOffset;
+                origins[i].y -= run->glyphOffsets[i].ascenderOffset;
             }
-        }
 
-        origins[i] = baseline_origin;
+            baseline_origin.x -= run->glyphAdvances ? run->glyphAdvances[i] : advance;
+        }
+        else
+        {
+            if (run->glyphOffsets)
+            {
+                origins[i].x += run->glyphOffsets[i].advanceOffset;
+                origins[i].y -= run->glyphOffsets[i].ascenderOffset;
+            }
 
-        /* Apply offsets. */
-        if (run->glyphOffsets) {
-            FLOAT advanceoffset = rtl_factor * run->glyphOffsets[i].advanceOffset;
-            FLOAT ascenderoffset = -run->glyphOffsets[i].ascenderOffset;
+            baseline_origin.x += run->glyphAdvances ? run->glyphAdvances[i] :
+                    fontface_get_scaled_design_advance(font_obj, measuring_mode, run->fontEmSize, 1.0f, transform,
+                            run->glyphIndices[i], run->isSideways);
 
-            if (run->isSideways) {
-                origins[i].x += ascenderoffset;
-                origins[i].y += advanceoffset;
-            }
-            else {
-                origins[i].x += advanceoffset;
-                origins[i].y += ascenderoffset;
-            }
         }
-
-        if (run->isSideways)
-            baseline_origin.y += advance;
-        else
-            baseline_origin.x += advance;
     }
 
-    if (fontface1)
-        IDWriteFontFace1_Release(fontface1);
     return S_OK;
 }
 
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index 872405b1639..d7ced109a2f 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -8468,7 +8468,6 @@ static void test_ComputeGlyphOrigins(void)
         ok(hr == S_OK, "%u: failed to compute glyph origins, hr %#x.\n", i, hr);
         for (j = 0; j < run.glyphCount; ++j)
         {
-        todo_wine_if(run.bidiLevel & 1)
             ok(!memcmp(&origins[j], &expected_origins[j], sizeof(origins[j])),
                     "%u: unexpected origin[%u] (%f, %f) - (%f, %f).\n", i, j, origins[j].x, origins[j].y,
                     expected_origins[j].x, expected_origins[j].y);




More information about the wine-cvs mailing list