diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c index 341710983ca..62893e66b52 100644 --- a/dlls/dwrite/analyzer.c +++ b/dlls/dwrite/analyzer.c @@ -21,6 +21,8 @@ #define COBJMACROS +#include + #include "dwrite_private.h" #include "scripts.h" @@ -1066,7 +1068,7 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphPlacements(IDWriteTextAnalyzer2 static HRESULT WINAPI dwritetextanalyzer_GetGdiCompatibleGlyphPlacements(IDWriteTextAnalyzer2 *iface, WCHAR const* text, UINT16 const* clustermap, DWRITE_SHAPING_TEXT_PROPERTIES* props, UINT32 text_len, UINT16 const* glyphs, DWRITE_SHAPING_GLYPH_PROPERTIES const* glyph_props, - UINT32 glyph_count, IDWriteFontFace *fontface, FLOAT emSize, FLOAT pixels_per_dip, + UINT32 glyph_count, IDWriteFontFace *fontface, FLOAT emSize, FLOAT ppdip, DWRITE_MATRIX const* transform, BOOL use_gdi_natural, BOOL is_sideways, BOOL is_rtl, DWRITE_SCRIPT_ANALYSIS const* analysis, WCHAR const* locale, DWRITE_TYPOGRAPHIC_FEATURES const** features, UINT32 const* feature_range_lengths, UINT32 feature_ranges, FLOAT *advances, DWRITE_GLYPH_OFFSET *offsets) @@ -1077,7 +1079,7 @@ static HRESULT WINAPI dwritetextanalyzer_GetGdiCompatibleGlyphPlacements(IDWrite UINT32 i; TRACE("(%s %p %p %u %p %p %u %p %.2f %.2f %p %d %d %d %p %s %p %p %u %p %p)\n", debugstr_wn(text, text_len), - clustermap, props, text_len, glyphs, glyph_props, glyph_count, fontface, emSize, pixels_per_dip, + clustermap, props, text_len, glyphs, glyph_props, glyph_count, fontface, emSize, ppdip, transform, use_gdi_natural, is_sideways, is_rtl, analysis, debugstr_w(locale), features, feature_range_lengths, feature_ranges, advances, offsets); @@ -1090,7 +1092,7 @@ static HRESULT WINAPI dwritetextanalyzer_GetGdiCompatibleGlyphPlacements(IDWrite return hr; } - hr = IDWriteFontFace_GetGdiCompatibleMetrics(fontface, emSize, pixels_per_dip, transform, &metrics); + hr = IDWriteFontFace_GetGdiCompatibleMetrics(fontface, emSize, ppdip, transform, &metrics); if (FAILED(hr)) { IDWriteFontFace1_Release(fontface1); WARN("failed to get compat metrics, 0x%08x\n", hr); @@ -1099,12 +1101,12 @@ static HRESULT WINAPI dwritetextanalyzer_GetGdiCompatibleGlyphPlacements(IDWrite for (i = 0; i < glyph_count; i++) { INT32 a; - hr = IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1, emSize, pixels_per_dip, + hr = IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1, emSize, ppdip, transform, use_gdi_natural, is_sideways, 1, &glyphs[i], &a); if (FAILED(hr)) - a = 0; - - advances[i] = get_scaled_advance_width(a, emSize, &metrics); + advances[i] = 0.0; + else + advances[i] = floorf(a * emSize * ppdip / metrics.designUnitsPerEm + 0.5f) / ppdip; offsets[i].advanceOffset = 0.0; offsets[i].ascenderOffset = 0.0; } diff --git a/dlls/dwrite/tests/analyzer.c b/dlls/dwrite/tests/analyzer.c index a3eaa38a87a..402787fbd97 100644 --- a/dlls/dwrite/tests/analyzer.c +++ b/dlls/dwrite/tests/analyzer.c @@ -22,6 +22,8 @@ #include #include +#include +#include #include "initguid.h" #include "windows.h" @@ -1878,6 +1880,93 @@ todo_wine { IDWriteTextAnalyzer1_Release(analyzer1); } +static inline BOOL float_eq(FLOAT left, FLOAT right) +{ + int x = *(int *)&left; + int y = *(int *)&right; + + if (x < 0) + x = INT_MIN - x; + if (y < 0) + y = INT_MIN - y; + + return abs(x - y) <= 8; +} + +static void test_GetGdiCompatibleGlyphPlacements(void) +{ + static const WCHAR strW[] = {'A',0}; + DWRITE_SHAPING_GLYPH_PROPERTIES glyphprops[1]; + DWRITE_SHAPING_TEXT_PROPERTIES textprops[1]; + DWRITE_SCRIPT_ANALYSIS sa = { 0 }; + IDWriteTextAnalyzer *analyzer; + IDWriteFontFace *fontface; + UINT16 clustermap[1]; + HRESULT hr; + UINT32 count; + UINT16 glyphs[1]; + FLOAT advance; + DWRITE_GLYPH_OFFSET offsets[1]; + DWRITE_FONT_METRICS fontmetrics; + FLOAT emsize; + + hr = IDWriteFactory_CreateTextAnalyzer(factory, &analyzer); + ok(hr == S_OK, "got 0x%08x\n", hr); + + fontface = create_fontface(); + + IDWriteFontFace_GetMetrics(fontface, &fontmetrics); + + count = 0; + hr = IDWriteTextAnalyzer_GetGlyphs(analyzer, strW, 1, fontface, + FALSE, FALSE, &sa, NULL, NULL, NULL, NULL, 0, 1, clustermap, + textprops, glyphs, glyphprops, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 1, "got %u\n", count); + + for (emsize = 12.0; emsize <= 20.0; emsize += 1.0) { + FLOAT compatadvance, expected, ppdip; + DWRITE_GLYPH_METRICS metrics; + + hr = IDWriteTextAnalyzer_GetGlyphPlacements(analyzer, strW, clustermap, + textprops, 1, glyphs, glyphprops, count, fontface, emsize, FALSE, FALSE, + &sa, NULL, NULL, NULL, 0, &advance, offsets); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(advance > 0.0, "got %f\n", advance); + + /* 1 ppdip, no transform */ + ppdip = 1.0; + hr = IDWriteFontFace_GetGdiCompatibleGlyphMetrics(fontface, emsize, ppdip, NULL, FALSE, + glyphs, 1, &metrics, FALSE); + ok(hr == S_OK, "got 0x%08x\n", hr); + + expected = floorf(metrics.advanceWidth * emsize * ppdip / fontmetrics.designUnitsPerEm + 0.5f) / ppdip; + hr = IDWriteTextAnalyzer_GetGdiCompatibleGlyphPlacements(analyzer, strW, + clustermap, textprops, 1, glyphs, glyphprops, count, fontface, emsize, + ppdip, NULL, FALSE, FALSE, FALSE, &sa, NULL, NULL, NULL, 0, &compatadvance, offsets); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(compatadvance == expected, "%.0f: got advance %f, expected %f, natural %f\n", emsize, + compatadvance, expected, advance); + + /* 1.2 ppdip, no transform */ + ppdip = 1.2; + hr = IDWriteFontFace_GetGdiCompatibleGlyphMetrics(fontface, emsize, ppdip, NULL, FALSE, + glyphs, 1, &metrics, FALSE); + ok(hr == S_OK, "got 0x%08x\n", hr); + + expected = floorf(metrics.advanceWidth * emsize * ppdip / fontmetrics.designUnitsPerEm + 0.5f) / ppdip; + hr = IDWriteTextAnalyzer_GetGdiCompatibleGlyphPlacements(analyzer, strW, + clustermap, textprops, 1, glyphs, glyphprops, count, fontface, emsize, + ppdip, NULL, FALSE, FALSE, FALSE, &sa, NULL, NULL, NULL, 0, &compatadvance, offsets); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(float_eq(compatadvance, expected), "%.0f: got advance %f, expected %f, natural %f\n", emsize, + compatadvance, expected, advance); + } + + IDWriteFontFace_Release(fontface); + IDWriteTextAnalyzer_Release(analyzer); +} + START_TEST(analyzer) { HRESULT hr; @@ -1904,6 +1993,7 @@ START_TEST(analyzer) test_ApplyCharacterSpacing(); test_GetGlyphOrientationTransform(); test_GetBaseline(); + test_GetGdiCompatibleGlyphPlacements(); IDWriteFactory_Release(factory); }