diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 114833a0773..5e72aeac900 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 5143c34e7d3..c822781f7a8 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, ¶ms3); *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, ¶ms3); + (DWRITE_RENDERING_MODE1)mode, DWRITE_GRID_FIT_MODE_DEFAULT, ¶ms3); *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, ¶ms3); *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, ¶ms3); *params = (IDWriteRenderingParams2*)params3; diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 997e9bef371..dc88e2c5fe2 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,56 @@ 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 || broken(hr == E_INVALIDARG) /* Win8 */, "Failed to create glyph run analysis, hr %#x.\n", hr); + + if (hr == S_OK) { + hr = IDWriteFactory_CreateCustomRenderingParams(factory, 0.1f, 0.0f, 1.0f, DWRITE_PIXEL_GEOMETRY_FLAT, + DWRITE_RENDERING_MODE_NATURAL, ¶ms); + 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 +7685,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, ¶ms); + 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 +7812,7 @@ START_TEST(font) test_ComputeGlyphOrigins(); test_inmemory_file_loader(); test_GetGlyphImageFormats(); + test_CreateCustomRenderingParams(); IDWriteFactory_Release(factory); }