[PATCH 1/2] dwrite/tests: Some tests for GetRecommendedRenderingMode()

Nikolay Sivov nsivov at codeweavers.com
Mon Jul 27 03:10:04 CDT 2015


---
-------------- next part --------------
>From 9282dd04fdaed474cb0bc7d92f064d951095f5c6 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov at codeweavers.com>
Date: Sat, 25 Jul 2015 01:31:55 +0300
Subject: [PATCH 1/2] dwrite/tests: Some tests for
 GetRecommendedRenderingMode()

---
 dlls/dwrite/tests/font.c | 269 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 269 insertions(+)

diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index 0565e09..485b978 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -37,6 +37,7 @@
 
 #define MS_CMAP_TAG MS_MAKE_TAG('c','m','a','p')
 #define MS_VDMX_TAG MS_MAKE_TAG('V','D','M','X')
+#define MS_GASP_TAG MS_MAKE_TAG('g','a','s','p')
 
 #define EXPECT_HR(hr,hr_exp) \
     ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
@@ -3368,6 +3369,7 @@ static void test_CreateRenderingParams(void)
     IDWriteRenderingParams2 *params2;
     IDWriteRenderingParams1 *params1;
     IDWriteRenderingParams *params;
+    DWRITE_RENDERING_MODE mode;
     IDWriteFactory *factory;
     HRESULT hr;
 
@@ -3403,6 +3405,14 @@ static void test_CreateRenderingParams(void)
         win_skip("IDWriteRenderingParams1 not supported.\n");
 
     IDWriteRenderingParams_Release(params);
+
+    hr = IDWriteFactory_CreateRenderingParams(factory, &params);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    mode = IDWriteRenderingParams_GetRenderingMode(params);
+    ok(mode == DWRITE_RENDERING_MODE_DEFAULT, "got %d\n", mode);
+    IDWriteRenderingParams_Release(params);
+
     IDWriteFactory_Release(factory);
 }
 
@@ -4080,6 +4090,264 @@ static void test_GetGdiCompatibleGlyphAdvances(void)
     IDWriteFactory_Release(factory);
 }
 
+static WORD get_gasp_flags(IDWriteFontFace *fontface, FLOAT emsize)
+{
+    WORD num_recs, version;
+    const WORD *ptr;
+    WORD flags = 0;
+    UINT32 size;
+    BOOL exists;
+    void *ctxt;
+    HRESULT hr;
+
+    exists = FALSE;
+    hr = IDWriteFontFace_TryGetFontTable(fontface, MS_GASP_TAG,
+        (const void**)&ptr, &size, &ctxt, &exists);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    if (!exists)
+        goto done;
+
+    version  = GET_BE_WORD( *ptr++ );
+    num_recs = GET_BE_WORD( *ptr++ );
+    if (version > 1 || size < (num_recs * 2 + 2) * sizeof(WORD)) {
+        ok(0, "unsupported gasp table: ver %d size %d recs %d\n", version, size, num_recs);
+        goto done;
+    }
+
+    while (num_recs--)
+    {
+        flags = GET_BE_WORD( *(ptr + 1) );
+        if (emsize <= GET_BE_WORD( *ptr )) break;
+        ptr += 2;
+    }
+
+done:
+    IDWriteFontFace_ReleaseFontTable(fontface, ctxt);
+    return flags;
+}
+
+#define GASP_GRIDFIT             0x0001
+#define GASP_DOGRAY              0x0002
+#define GASP_SYMMETRIC_GRIDFIT   0x0004
+#define GASP_SYMMETRIC_SMOOTHING 0x0008
+
+static BOOL g_is_vista;
+static DWRITE_RENDERING_MODE get_expected_rendering_mode(FLOAT emsize, WORD gasp, DWRITE_MEASURING_MODE mode,
+    DWRITE_OUTLINE_THRESHOLD threshold)
+{
+    static const FLOAT aa_threshold = 100.0f;
+    static const FLOAT a_threshold = 350.0f;
+    static const FLOAT naturalemsize = 20.0f;
+    FLOAT v;
+
+    /* outline threshold */
+    if (g_is_vista)
+        v = mode == DWRITE_MEASURING_MODE_NATURAL ? aa_threshold : a_threshold;
+    else
+        v = threshold == DWRITE_OUTLINE_THRESHOLD_ANTIALIASED ? aa_threshold : a_threshold;
+
+    if (emsize >= v)
+        return DWRITE_RENDERING_MODE_OUTLINE;
+
+    switch (mode)
+    {
+    case DWRITE_MEASURING_MODE_NATURAL:
+        if (!(gasp & GASP_SYMMETRIC_SMOOTHING) && (emsize <= naturalemsize))
+            return DWRITE_RENDERING_MODE_NATURAL;
+        else
+            return DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC;
+    case DWRITE_MEASURING_MODE_GDI_CLASSIC:
+        return DWRITE_RENDERING_MODE_GDI_CLASSIC;
+    case DWRITE_MEASURING_MODE_GDI_NATURAL:
+        return DWRITE_RENDERING_MODE_GDI_NATURAL;
+    default:
+        ;
+    }
+
+    /* should be unreachable */
+    return DWRITE_RENDERING_MODE_DEFAULT;
+}
+
+static DWRITE_GRID_FIT_MODE get_expected_gridfit_mode(FLOAT emsize, WORD gasp, DWRITE_MEASURING_MODE mode,
+    DWRITE_OUTLINE_THRESHOLD threshold)
+{
+    static const FLOAT aa_threshold = 100.0f;
+    static const FLOAT a_threshold = 350.0f;
+    FLOAT v;
+
+    v = threshold == DWRITE_OUTLINE_THRESHOLD_ANTIALIASED ? aa_threshold : a_threshold;
+    if (emsize >= v)
+        return DWRITE_GRID_FIT_MODE_DISABLED;
+
+    if (mode == DWRITE_MEASURING_MODE_GDI_CLASSIC || mode == DWRITE_MEASURING_MODE_GDI_NATURAL)
+        return DWRITE_GRID_FIT_MODE_ENABLED;
+
+    return (gasp & (GASP_GRIDFIT|GASP_SYMMETRIC_GRIDFIT)) ? DWRITE_GRID_FIT_MODE_ENABLED : DWRITE_GRID_FIT_MODE_DISABLED;
+}
+
+struct recommendedmode_test
+{
+    DWRITE_MEASURING_MODE measuring;
+    DWRITE_OUTLINE_THRESHOLD threshold;
+};
+
+static const struct recommendedmode_test recmode_tests[] = {
+    { DWRITE_MEASURING_MODE_NATURAL,     DWRITE_OUTLINE_THRESHOLD_ANTIALIASED },
+    { DWRITE_MEASURING_MODE_GDI_CLASSIC, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED },
+    { DWRITE_MEASURING_MODE_GDI_NATURAL, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED },
+};
+
+static const struct recommendedmode_test recmode_tests1[] = {
+    { DWRITE_MEASURING_MODE_NATURAL,     DWRITE_OUTLINE_THRESHOLD_ANTIALIASED },
+    { DWRITE_MEASURING_MODE_GDI_CLASSIC, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED },
+    { DWRITE_MEASURING_MODE_GDI_NATURAL, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED },
+    { DWRITE_MEASURING_MODE_NATURAL,     DWRITE_OUTLINE_THRESHOLD_ALIASED },
+    { DWRITE_MEASURING_MODE_GDI_CLASSIC, DWRITE_OUTLINE_THRESHOLD_ALIASED },
+    { DWRITE_MEASURING_MODE_GDI_NATURAL, DWRITE_OUTLINE_THRESHOLD_ALIASED },
+};
+
+static void test_GetRecommendedRenderingMode(void)
+{
+    IDWriteRenderingParams *params;
+    IDWriteFontFace2 *fontface2;
+    IDWriteFontFace1 *fontface1;
+    IDWriteFontFace  *fontface;
+    DWRITE_RENDERING_MODE mode;
+    IDWriteFactory *factory;
+    FLOAT emsize;
+    HRESULT hr;
+
+    factory = create_factory();
+    fontface = create_fontface(factory);
+
+    fontface1 = NULL;
+    hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace1, (void**)&fontface1);
+    if (hr != S_OK)
+        win_skip("IDWriteFontFace1::GetRecommendedRenderingMode() is not supported.\n");
+
+    fontface2 = NULL;
+    hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace2, (void**)&fontface2);
+    if (hr != S_OK)
+        win_skip("IDWriteFontFace2::GetRecommendedRenderingMode() is not supported.\n");
+
+if (0) /* crashes on native */
+    hr = IDWriteFontFace_GetRecommendedRenderingMode(fontface, 3.0, 1.0,
+        DWRITE_MEASURING_MODE_GDI_CLASSIC, NULL, NULL);
+
+    mode = 10;
+    hr = IDWriteFontFace_GetRecommendedRenderingMode(fontface, 3.0, 1.0,
+        DWRITE_MEASURING_MODE_GDI_CLASSIC, NULL, &mode);
+todo_wine {
+    ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+    ok(mode == DWRITE_RENDERING_MODE_DEFAULT, "got %d\n", mode);
+}
+    hr = IDWriteFactory_CreateRenderingParams(factory, &params);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    /* detect old dwrite version, that is using higher threshold value */
+    g_is_vista = fontface1 == NULL;
+
+    for (emsize = 1.0; emsize < 500.0; emsize += 1.0) {
+        WORD gasp = get_gasp_flags(fontface, emsize);
+        DWRITE_RENDERING_MODE expected;
+        int i, skiptest = 0;
+
+        for (i = 0; i < sizeof(recmode_tests)/sizeof(recmode_tests[0]); i++) {
+            mode = 10;
+            expected = get_expected_rendering_mode(emsize, gasp, recmode_tests[i].measuring, recmode_tests[i].threshold);
+            hr = IDWriteFontFace_GetRecommendedRenderingMode(fontface, emsize, 1.0, recmode_tests[i].measuring, params, &mode);
+        todo_wine
+            ok(hr == S_OK, "got 0x%08x\n", hr);
+            if (hr != S_OK) {
+                skiptest = 1;
+                break;
+            }
+            ok(mode == expected, "%.2f/%d: got %d, flags 0x%04x, expected %d\n", emsize, i, mode, gasp, expected);
+        }
+
+        if (skiptest)
+            break;
+
+        /* IDWriteFontFace1 offers another variant of this method */
+        if (fontface1) {
+            for (i = 0; i < sizeof(recmode_tests1)/sizeof(recmode_tests1[0]); i++) {
+                mode = 10;
+                expected = get_expected_rendering_mode(emsize, gasp, recmode_tests1[i].measuring, recmode_tests1[i].threshold);
+                hr = IDWriteFontFace1_GetRecommendedRenderingMode(fontface1, emsize, 96.0, 96.0,
+                    NULL, FALSE, recmode_tests1[i].threshold, recmode_tests1[i].measuring, &mode);
+                ok(hr == S_OK, "got 0x%08x\n", hr);
+                ok(mode == expected, "%.2f/%d: got %d, flags 0x%04x, expected %d\n", emsize, i, mode, gasp, expected);
+            }
+        }
+
+        /* IDWriteFontFace2 - another one */
+        if (fontface2) {
+            DWRITE_GRID_FIT_MODE gridfit, expected_gridfit;
+
+            for (i = 0; i < sizeof(recmode_tests1)/sizeof(recmode_tests1[0]); i++) {
+                mode = 10;
+                expected = get_expected_rendering_mode(emsize, gasp, recmode_tests1[0].measuring, recmode_tests1[0].threshold);
+                expected_gridfit = get_expected_gridfit_mode(emsize, gasp, recmode_tests1[0].measuring, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED);
+                hr = IDWriteFontFace2_GetRecommendedRenderingMode(fontface2, emsize, 96.0, 96.0,
+                    NULL, FALSE, recmode_tests1[0].threshold, recmode_tests1[0].measuring, params, &mode, &gridfit);
+                ok(hr == S_OK, "got 0x%08x\n", hr);
+                ok(mode == expected, "%.2f: got %d, flags 0x%04x, expected %d\n", emsize, mode, gasp, expected);
+                ok(gridfit == expected_gridfit, "%.2f/%d: gridfit: got %d, flags 0x%04x, expected %d\n", emsize, i, gridfit,
+                    gasp, expected_gridfit);
+            }
+        }
+    }
+
+    IDWriteRenderingParams_Release(params);
+
+    /* test how parameters override returned modes */
+    hr = IDWriteFactory_CreateCustomRenderingParams(factory, 1.0, 0.0, 0.0, DWRITE_PIXEL_GEOMETRY_FLAT,
+        DWRITE_RENDERING_MODE_GDI_CLASSIC, &params);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    mode = 10;
+    hr = IDWriteFontFace_GetRecommendedRenderingMode(fontface, 500.0, 1.0, DWRITE_MEASURING_MODE_NATURAL, params, &mode);
+todo_wine {
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(mode == DWRITE_RENDERING_MODE_GDI_CLASSIC, "got %d\n", mode);
+}
+    IDWriteRenderingParams_Release(params);
+
+    if (fontface2) {
+        IDWriteRenderingParams2 *params2;
+        IDWriteFactory2 *factory2;
+        DWRITE_GRID_FIT_MODE gridfit;
+
+        hr = IDWriteFactory_QueryInterface(factory, &IID_IDWriteFactory2, (void**)&factory2);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+
+        hr = IDWriteFactory2_CreateCustomRenderingParams(factory2, 1.0, 0.0, 0.0, 0.5, DWRITE_PIXEL_GEOMETRY_FLAT,
+            DWRITE_RENDERING_MODE_OUTLINE, DWRITE_GRID_FIT_MODE_ENABLED, &params2);
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+
+        mode = 10;
+        gridfit = 10;
+        hr = IDWriteFontFace2_GetRecommendedRenderingMode(fontface2, 5.0, 96.0, 96.0,
+            NULL, FALSE, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED, DWRITE_MEASURING_MODE_GDI_CLASSIC,
+            (IDWriteRenderingParams*)params2, &mode, &gridfit);
+todo_wine {
+        ok(hr == S_OK, "got 0x%08x\n", hr);
+        ok(mode == DWRITE_RENDERING_MODE_OUTLINE, "got %d\n", mode);
+        ok(gridfit == DWRITE_GRID_FIT_MODE_ENABLED, "got %d\n", gridfit);
+}
+        IDWriteRenderingParams2_Release(params2);
+        IDWriteFactory2_Release(factory2);
+    }
+
+    if (fontface2)
+        IDWriteFontFace2_Release(fontface2);
+    if (fontface1)
+        IDWriteFontFace1_Release(fontface1);
+    IDWriteFontFace_Release(fontface);
+    IDWriteFactory_Release(factory);
+}
+
 START_TEST(font)
 {
     IDWriteFactory *factory;
@@ -4126,6 +4394,7 @@ START_TEST(font)
     test_GetGdiCompatibleMetrics();
     test_GetPanose();
     test_GetGdiCompatibleGlyphAdvances();
+    test_GetRecommendedRenderingMode();
 
     IDWriteFactory_Release(factory);
 }
-- 
2.1.4



More information about the wine-patches mailing list