Nikolay Sivov : dwrite: Round advances returned from GetGdiCompatibleGlyphPlacements().

Alexandre Julliard julliard at wine.codeweavers.com
Thu Jul 16 08:37:19 CDT 2015


Module: wine
Branch: master
Commit: 2132a060ead591ee2ce70296282e2076ec2de214
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2132a060ead591ee2ce70296282e2076ec2de214

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Thu Jul 16 13:11:54 2015 +0300

dwrite: Round advances returned from GetGdiCompatibleGlyphPlacements().

---

 dlls/dwrite/analyzer.c       | 16 ++++----
 dlls/dwrite/tests/analyzer.c | 90 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 99 insertions(+), 7 deletions(-)

diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c
index 3417109..62893e6 100644
--- a/dlls/dwrite/analyzer.c
+++ b/dlls/dwrite/analyzer.c
@@ -21,6 +21,8 @@
 
 #define COBJMACROS
 
+#include <math.h>
+
 #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 a3eaa38..402787f 100644
--- a/dlls/dwrite/tests/analyzer.c
+++ b/dlls/dwrite/tests/analyzer.c
@@ -22,6 +22,8 @@
 
 #include <assert.h>
 #include <stdio.h>
+#include <limits.h>
+#include <math.h>
 
 #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);
 }




More information about the wine-cvs mailing list