From 87bc6aac205cf3091e0b6ea91aeb1a8b5f05e710 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 22 Feb 2021 21:29:35 +0300 Subject: [PATCH] dwrite: Correct return glyph origins for RTL runs. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/dwrite/main.c | 90 ++++++++++++++-------------------------- dlls/dwrite/tests/font.c | 1 - 2 files changed, 31 insertions(+), 60 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; - - 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++) { - FLOAT advance; - - /* Use nominal advances if not provided by caller. */ - if (run->glyphAdvances) - advance = rtl_factor * run->glyphAdvances[i]; - else { - INT32 a; - - advance = 0.0f; - switch (measuring_mode) - { - 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: - ; - } - } + font_obj = unsafe_impl_from_IDWriteFontFace(run->fontFace); + for (i = 0; i < run->glyphCount; ++i) + { origins[i] = baseline_origin; - /* Apply offsets. */ - if (run->glyphOffsets) { - FLOAT advanceoffset = rtl_factor * run->glyphOffsets[i].advanceOffset; - FLOAT ascenderoffset = -run->glyphOffsets[i].ascenderOffset; + if (run->bidiLevel & 1) + { + advance = 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; + origins[i].x -= advance; + + if (run->glyphOffsets) + { + origins[i].x -= run->glyphOffsets[i].advanceOffset; + origins[i].y -= run->glyphOffsets[i].ascenderOffset; } + + baseline_origin.x -= run->glyphAdvances ? run->glyphAdvances[i] : advance; } - - if (run->isSideways) - baseline_origin.y += advance; else - baseline_origin.x += advance; + { + if (run->glyphOffsets) + { + origins[i].x += run->glyphOffsets[i].advanceOffset; + origins[i].y -= 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 (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);