[PATCH 1/3] dwrite: Improve rendering parameters validation

Nikolay Sivov nsivov at codeweavers.com
Mon Jul 17 07:27:22 CDT 2017


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/dwrite/font.c       |  11 ++++-
 dlls/dwrite/main.c       |  27 ++++++++++-
 dlls/dwrite/tests/font.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 149 insertions(+), 3 deletions(-)

diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 114833a077..5e72aeac90 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -5163,12 +5163,21 @@ HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc *desc, IDWrit
 
     *ret = NULL;
 
-    /* check for valid rendering mode */
+    /* Check rendering, antialising, measuring, and grid fitting modes. */
     if ((UINT32)desc->rendering_mode >= DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC_DOWNSAMPLED ||
             desc->rendering_mode == DWRITE_RENDERING_MODE1_OUTLINE ||
             desc->rendering_mode == DWRITE_RENDERING_MODE1_DEFAULT)
         return E_INVALIDARG;
 
+    if ((UINT32)desc->aa_mode > DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE)
+        return E_INVALIDARG;
+
+    if ((UINT32)desc->gridfit_mode > DWRITE_GRID_FIT_MODE_ENABLED)
+        return E_INVALIDARG;
+
+    if ((UINT32)desc->measuring_mode > DWRITE_MEASURING_MODE_GDI_NATURAL)
+        return E_INVALIDARG;
+
     analysis = heap_alloc(sizeof(*analysis));
     if (!analysis)
         return E_OUTOFMEMORY;
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 5143c34e7d..c822781f7a 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -210,6 +210,12 @@ static HRESULT create_renderingparams(FLOAT gamma, FLOAT contrast, FLOAT graysca
 
     *params = NULL;
 
+    if (gamma <= 0.0f || contrast < 0.0f || grayscalecontrast < 0.0f || cleartype_level < 0.0f)
+        return E_INVALIDARG;
+
+    if ((UINT32)gridfit > DWRITE_GRID_FIT_MODE_ENABLED || (UINT32)geometry > DWRITE_PIXEL_GEOMETRY_BGR)
+        return E_INVALIDARG;
+
     This = heap_alloc(sizeof(struct renderingparams));
     if (!This) return E_OUTOFMEMORY;
 
@@ -984,7 +990,8 @@ static HRESULT WINAPI dwritefactory_CreateMonitorRenderingParams(IDWriteFactory5
     if (!fixme_once++)
         FIXME("(%p): monitor setting ignored\n", monitor);
 
-    hr = IDWriteFactory5_CreateCustomRenderingParams(iface, 0.0f, 0.0f, 1.0f, 0.0f, DWRITE_PIXEL_GEOMETRY_FLAT,
+    /* FIXME: use actual per-monitor gamma factor */
+    hr = IDWriteFactory5_CreateCustomRenderingParams(iface, 2.0f, 0.0f, 1.0f, 0.0f, DWRITE_PIXEL_GEOMETRY_FLAT,
         DWRITE_RENDERING_MODE1_DEFAULT, DWRITE_GRID_FIT_MODE_DEFAULT, &params3);
     *params = (IDWriteRenderingParams*)params3;
     return hr;
@@ -1000,8 +1007,13 @@ static HRESULT WINAPI dwritefactory_CreateCustomRenderingParams(IDWriteFactory5
 
     TRACE("(%p)->(%f %f %f %d %d %p)\n", This, gamma, enhancedContrast, cleartype_level, geometry, mode, params);
 
+    if ((UINT32)mode > DWRITE_RENDERING_MODE_OUTLINE) {
+        *params = NULL;
+        return E_INVALIDARG;
+    }
+
     hr = IDWriteFactory5_CreateCustomRenderingParams(iface, gamma, enhancedContrast, 1.0f, cleartype_level, geometry,
-        (DWRITE_RENDERING_MODE1)mode, DWRITE_GRID_FIT_MODE_DEFAULT, &params3);
+            (DWRITE_RENDERING_MODE1)mode, DWRITE_GRID_FIT_MODE_DEFAULT, &params3);
     *params = (IDWriteRenderingParams*)params3;
     return hr;
 }
@@ -1228,6 +1240,12 @@ static HRESULT WINAPI dwritefactory1_CreateCustomRenderingParams(IDWriteFactory5
 
     TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %p)\n", This, gamma, enhcontrast, enhcontrast_grayscale,
         cleartype_level, geometry, mode, params);
+
+    if ((UINT32)mode > DWRITE_RENDERING_MODE_OUTLINE) {
+        *params = NULL;
+        return E_INVALIDARG;
+    }
+
     hr = IDWriteFactory5_CreateCustomRenderingParams(iface, gamma, enhcontrast, enhcontrast_grayscale,
         cleartype_level, geometry, (DWRITE_RENDERING_MODE1)mode, DWRITE_GRID_FIT_MODE_DEFAULT, &params3);
     *params = (IDWriteRenderingParams1*)params3;
@@ -1282,6 +1300,11 @@ static HRESULT WINAPI dwritefactory2_CreateCustomRenderingParams(IDWriteFactory5
     TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %d %p)\n", This, gamma, contrast, grayscalecontrast, cleartype_level,
         geometry, mode, gridfit, params);
 
+    if ((UINT32)mode > DWRITE_RENDERING_MODE_OUTLINE) {
+        *params = NULL;
+        return E_INVALIDARG;
+    }
+
     hr = IDWriteFactory5_CreateCustomRenderingParams(iface, gamma, contrast, grayscalecontrast,
         cleartype_level, geometry, (DWRITE_RENDERING_MODE1)mode, DWRITE_GRID_FIT_MODE_DEFAULT, &params3);
     *params = (IDWriteRenderingParams2*)params3;
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index 997e9bef37..241a2754e7 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -4624,6 +4624,8 @@ static void test_CreateGlyphRunAnalysis(void)
     };
 
     IDWriteGlyphRunAnalysis *analysis, *analysis2;
+    IDWriteRenderingParams *params;
+    IDWriteFactory2 *factory2;
     IDWriteFactory *factory;
     DWRITE_GLYPH_RUN run;
     IDWriteFontFace *face;
@@ -4921,6 +4923,53 @@ static void test_CreateGlyphRunAnalysis(void)
 
     IDWriteGlyphRunAnalysis_Release(analysis);
 
+    if (IDWriteFactory_QueryInterface(factory, &IID_IDWriteFactory2, (void **)&factory2) == S_OK) {
+        FLOAT gamma, contrast, cleartype_level;
+
+        /* Invalid antialias mode. */
+        hr = IDWriteFactory2_CreateGlyphRunAnalysis(factory2, &run, NULL, DWRITE_RENDERING_MODE_ALIASED,
+                DWRITE_MEASURING_MODE_NATURAL, DWRITE_GRID_FIT_MODE_DEFAULT, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE + 1,
+                0.0f, 0.0f, &analysis);
+        ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+        /* Invalid grid fit mode. */
+        hr = IDWriteFactory2_CreateGlyphRunAnalysis(factory2, &run, NULL, DWRITE_RENDERING_MODE_ALIASED,
+                DWRITE_MEASURING_MODE_NATURAL, DWRITE_GRID_FIT_MODE_ENABLED + 1, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE,
+                0.0f, 0.0f, &analysis);
+        ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+        /* Invalid rendering mode. */
+        hr = IDWriteFactory2_CreateGlyphRunAnalysis(factory2, &run, NULL, DWRITE_RENDERING_MODE_OUTLINE,
+                DWRITE_MEASURING_MODE_NATURAL, DWRITE_GRID_FIT_MODE_ENABLED, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE,
+                0.0f, 0.0f, &analysis);
+        ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+        /* Invalid measuring mode. */
+        hr = IDWriteFactory2_CreateGlyphRunAnalysis(factory2, &run, NULL, DWRITE_RENDERING_MODE_ALIASED,
+                DWRITE_MEASURING_MODE_GDI_NATURAL + 1, DWRITE_GRID_FIT_MODE_ENABLED, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE,
+                0.0f, 0.0f, &analysis);
+        ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+        /* Natural mode, grayscale antialiased. */
+        hr = IDWriteFactory2_CreateGlyphRunAnalysis(factory2, &run, NULL, DWRITE_RENDERING_MODE_NATURAL,
+                DWRITE_MEASURING_MODE_NATURAL, DWRITE_GRID_FIT_MODE_DEFAULT, DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE,
+                0.0f, 0.0f, &analysis);
+        ok(hr == S_OK, "Failed to create glyph run analysis, hr %#x.\n", hr);
+
+        hr = IDWriteFactory_CreateCustomRenderingParams(factory, 0.1f, 0.0f, 1.0f, DWRITE_PIXEL_GEOMETRY_FLAT,
+                DWRITE_RENDERING_MODE_NATURAL, &params);
+        ok(hr == S_OK, "Failed to create custom parameters, hr %#x.\n", hr);
+
+        hr = IDWriteGlyphRunAnalysis_GetAlphaBlendParams(analysis, params, &gamma, &contrast, &cleartype_level);
+        ok(hr == S_OK, "Failed to get alpha blend params, hr %#x.\n", hr);
+    todo_wine
+        ok(cleartype_level == 0.0f, "Unexpected cleartype level %f.\n", cleartype_level);
+
+        IDWriteRenderingParams_Release(params);
+        IDWriteGlyphRunAnalysis_Release(analysis);
+        IDWriteFactory2_Release(factory2);
+    }
+
     IDWriteFontFace_Release(face);
     ref = IDWriteFactory_Release(factory);
     ok(ref == 0, "factory not released, %u\n", ref);
@@ -7633,6 +7682,70 @@ static void test_GetGlyphImageFormats(void)
     ok(ref == 0, "factory not released, %u\n", ref);
 }
 
+static void test_CreateCustomRenderingParams(void)
+{
+    static const struct custom_params_test
+    {
+        FLOAT gamma;
+        FLOAT contrast;
+        FLOAT cleartype_level;
+        DWRITE_PIXEL_GEOMETRY geometry;
+        DWRITE_RENDERING_MODE rendering_mode;
+        HRESULT hr;
+    } params_tests[] =
+    {
+        {  0.0f,  0.0f,  0.0f, DWRITE_PIXEL_GEOMETRY_FLAT, DWRITE_RENDERING_MODE_NATURAL, E_INVALIDARG },
+        {  0.0f,  0.1f,  0.0f, DWRITE_PIXEL_GEOMETRY_FLAT, DWRITE_RENDERING_MODE_NATURAL, E_INVALIDARG },
+        {  0.0f,  0.0f,  0.1f, DWRITE_PIXEL_GEOMETRY_FLAT, DWRITE_RENDERING_MODE_NATURAL, E_INVALIDARG },
+        { -0.1f,  0.0f,  0.0f, DWRITE_PIXEL_GEOMETRY_FLAT, DWRITE_RENDERING_MODE_NATURAL, E_INVALIDARG },
+        {  0.1f, -0.1f,  0.0f, DWRITE_PIXEL_GEOMETRY_FLAT, DWRITE_RENDERING_MODE_NATURAL, E_INVALIDARG },
+        {  0.1f,  0.0f, -0.1f, DWRITE_PIXEL_GEOMETRY_FLAT, DWRITE_RENDERING_MODE_NATURAL, E_INVALIDARG },
+        {  0.1f,  0.0f,  0.0f, DWRITE_PIXEL_GEOMETRY_FLAT, DWRITE_RENDERING_MODE_NATURAL },
+        {  0.01f, 0.0f,  0.0f, DWRITE_PIXEL_GEOMETRY_FLAT, DWRITE_RENDERING_MODE_NATURAL },
+        {  0.1f,  0.0f,  0.0f, DWRITE_PIXEL_GEOMETRY_BGR + 1, DWRITE_RENDERING_MODE_NATURAL, E_INVALIDARG },
+        {  0.1f,  0.0f,  0.0f, DWRITE_PIXEL_GEOMETRY_BGR, DWRITE_RENDERING_MODE_OUTLINE + 1, E_INVALIDARG },
+        {  0.1f,  0.0f,  2.0f, DWRITE_PIXEL_GEOMETRY_BGR, DWRITE_RENDERING_MODE_NATURAL },
+    };
+    IDWriteFactory *factory;
+    unsigned int i;
+    HRESULT hr;
+    ULONG ref;
+
+    factory = create_factory();
+
+    for (i = 0; i < sizeof(params_tests)/sizeof(*params_tests); i++) {
+        IDWriteRenderingParams *params;
+
+        params = (void *)0xdeadbeef;
+        hr = IDWriteFactory_CreateCustomRenderingParams(factory, params_tests[i].gamma, params_tests[i].contrast,
+                params_tests[i].cleartype_level, params_tests[i].geometry, params_tests[i].rendering_mode, &params);
+        ok(hr == params_tests[i].hr, "%u: unexpected hr %#x, expected %#x.\n", i, hr, params_tests[i].hr);
+
+        if (hr == S_OK) {
+            ok(params_tests[i].gamma == IDWriteRenderingParams_GetGamma(params), "%u: unexpected gamma %f, expected %f.\n",
+                    i, IDWriteRenderingParams_GetGamma(params), params_tests[i].gamma);
+            ok(params_tests[i].contrast == IDWriteRenderingParams_GetEnhancedContrast(params),
+                    "%u: unexpected contrast %f, expected %f.\n",
+                    i, IDWriteRenderingParams_GetEnhancedContrast(params), params_tests[i].contrast);
+            ok(params_tests[i].cleartype_level == IDWriteRenderingParams_GetClearTypeLevel(params),
+                    "%u: unexpected ClearType level %f, expected %f.\n",
+                    i, IDWriteRenderingParams_GetClearTypeLevel(params), params_tests[i].cleartype_level);
+            ok(params_tests[i].geometry == IDWriteRenderingParams_GetPixelGeometry(params),
+                    "%u: unexpected pixel geometry %u, expected %u.\n", i, IDWriteRenderingParams_GetPixelGeometry(params),
+                    params_tests[i].geometry);
+            ok(params_tests[i].rendering_mode == IDWriteRenderingParams_GetRenderingMode(params),
+                    "%u: unexpected rendering mode %u, expected %u.\n", i, IDWriteRenderingParams_GetRenderingMode(params),
+                    params_tests[i].rendering_mode);
+            IDWriteRenderingParams_Release(params);
+        }
+        else
+            ok(params == NULL, "%u: expected NULL interface pointer on failure.\n", i);
+    }
+
+    ref = IDWriteFactory_Release(factory);
+    ok(ref == 0, "factory not released, %u\n", ref);
+}
+
 START_TEST(font)
 {
     IDWriteFactory *factory;
@@ -7696,6 +7809,7 @@ START_TEST(font)
     test_ComputeGlyphOrigins();
     test_inmemory_file_loader();
     test_GetGlyphImageFormats();
+    test_CreateCustomRenderingParams();
 
     IDWriteFactory_Release(factory);
 }
-- 
2.13.2




More information about the wine-patches mailing list