diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 3cd178c6d02..b625f7ace46 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -1130,14 +1130,64 @@ static BOOL WINAPI dwritefontface3_HasCharacter(IDWriteFontFace3 *iface, UINT32 return index != 0; } -static HRESULT WINAPI dwritefontface3_GetRecommendedRenderingMode(IDWriteFontFace3 *iface, FLOAT emsize, FLOAT dpi_x, FLOAT dpi_y, - DWRITE_MATRIX const *transform, BOOL is_sideways, DWRITE_OUTLINE_THRESHOLD threshold, DWRITE_MEASURING_MODE measuring_mode, +static HRESULT WINAPI dwritefontface3_GetRecommendedRenderingMode(IDWriteFontFace3 *iface, FLOAT emSize, FLOAT dpiX, FLOAT dpiY, + DWRITE_MATRIX const *m, BOOL is_sideways, DWRITE_OUTLINE_THRESHOLD threshold, DWRITE_MEASURING_MODE measuring_mode, IDWriteRenderingParams *params, DWRITE_RENDERING_MODE1 *rendering_mode, DWRITE_GRID_FIT_MODE *gridfit_mode) { struct dwrite_fontface *This = impl_from_IDWriteFontFace3(iface); - FIXME("(%p)->(%f %f %f %p %d %u %u %p %p %p): stub\n", This, emsize, dpi_x, dpi_y, transform, is_sideways, threshold, + FLOAT emthreshold; + WORD gasp, *ptr; + UINT32 size; + + TRACE("(%p)->(%.2f %.2f %.2f %p %d %d %d %p %p %p)\n", This, emSize, dpiX, dpiY, m, is_sideways, threshold, measuring_mode, params, rendering_mode, gridfit_mode); - return E_NOTIMPL; + + if (m) + FIXME("transform not supported %s\n", debugstr_matrix(m)); + + if (is_sideways) + FIXME("sideways mode not supported\n"); + + emSize *= max(dpiX, dpiY) / 96.0f; + + *rendering_mode = DWRITE_RENDERING_MODE_DEFAULT; + *gridfit_mode = DWRITE_GRID_FIT_MODE_DEFAULT; + if (params) { + IDWriteRenderingParams3 *params3; + HRESULT hr; + + hr = IDWriteRenderingParams_QueryInterface(params, &IID_IDWriteRenderingParams3, (void**)¶ms3); + if (hr == S_OK) { + *rendering_mode = IDWriteRenderingParams3_GetRenderingMode1(params3); + *gridfit_mode = IDWriteRenderingParams3_GetGridFitMode(params3); + IDWriteRenderingParams3_Release(params3); + } + else + *rendering_mode = IDWriteRenderingParams_GetRenderingMode(params); + } + + emthreshold = threshold == DWRITE_OUTLINE_THRESHOLD_ANTIALIASED ? RECOMMENDED_OUTLINE_AA_THRESHOLD : RECOMMENDED_OUTLINE_A_THRESHOLD; + + ptr = get_fontface_gasp(This, &size); + gasp = opentype_get_gasp_flags(ptr, size, emSize); + + if (*rendering_mode == DWRITE_RENDERING_MODE1_DEFAULT) { + if (emSize >= emthreshold) + *rendering_mode = DWRITE_RENDERING_MODE1_OUTLINE; + else + *rendering_mode = fontface_renderingmode_from_measuringmode(measuring_mode, emSize, gasp); + } + + if (*gridfit_mode == DWRITE_GRID_FIT_MODE_DEFAULT) { + if (emSize >= emthreshold) + *gridfit_mode = DWRITE_GRID_FIT_MODE_DISABLED; + else if (measuring_mode == DWRITE_MEASURING_MODE_GDI_CLASSIC || measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL) + *gridfit_mode = DWRITE_GRID_FIT_MODE_ENABLED; + else + *gridfit_mode = (gasp & (GASP_GRIDFIT|GASP_SYMMETRIC_GRIDFIT)) ? DWRITE_GRID_FIT_MODE_ENABLED : DWRITE_GRID_FIT_MODE_DISABLED; + } + + return S_OK; } static BOOL WINAPI dwritefontface3_IsCharacterLocal(IDWriteFontFace3 *iface, UINT32 ch) diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index aa57d8182cf..163b4812b68 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -5081,6 +5081,7 @@ static const struct recommendedmode_test recmode_tests1[] = { static void test_GetRecommendedRenderingMode(void) { IDWriteRenderingParams *params; + IDWriteFontFace3 *fontface3; IDWriteFontFace2 *fontface2; IDWriteFontFace1 *fontface1; IDWriteFontFace *fontface; @@ -5102,6 +5103,11 @@ static void test_GetRecommendedRenderingMode(void) if (hr != S_OK) win_skip("IDWriteFontFace2::GetRecommendedRenderingMode() is not supported.\n"); + fontface3 = NULL; + hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace3, (void**)&fontface3); + if (hr != S_OK) + win_skip("IDWriteFontFace3::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); @@ -5252,16 +5258,35 @@ if (0) /* crashes on native */ gasp = get_gasp_flags(fontface, emsize, 1.0f); 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); + expected = get_expected_rendering_mode(emsize, gasp, recmode_tests1[i].measuring, recmode_tests1[i].threshold); + expected_gridfit = get_expected_gridfit_mode(emsize, gasp, recmode_tests1[i].measuring, recmode_tests1[i].threshold); + hr = IDWriteFontFace2_GetRecommendedRenderingMode(fontface2, emsize, 96.0f, 96.0f, + NULL, FALSE, recmode_tests1[i].threshold, recmode_tests1[i].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); } } + + /* IDWriteFontFace3 - and another one */ + if (fontface3) { + DWRITE_GRID_FIT_MODE gridfit, expected_gridfit; + DWRITE_RENDERING_MODE1 mode1, expected1; + + gasp = get_gasp_flags(fontface, emsize, 1.0f); + for (i = 0; i < sizeof(recmode_tests1)/sizeof(recmode_tests1[0]); i++) { + mode1 = 10; + expected1 = get_expected_rendering_mode(emsize, gasp, recmode_tests1[i].measuring, recmode_tests1[i].threshold); + expected_gridfit = get_expected_gridfit_mode(emsize, gasp, recmode_tests1[i].measuring, recmode_tests1[i].threshold); + hr = IDWriteFontFace3_GetRecommendedRenderingMode(fontface3, emsize, 96.0f, 96.0f, + NULL, FALSE, recmode_tests1[i].threshold, recmode_tests1[i].measuring, params, &mode1, &gridfit); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(mode1 == expected1, "%.2f: got %d, flags 0x%04x, expected %d\n", emsize, mode1, gasp, expected1); + ok(gridfit == expected_gridfit, "%.2f/%d: gridfit: got %d, flags 0x%04x, expected %d\n", emsize, i, gridfit, + gasp, expected_gridfit); + } + } } IDWriteRenderingParams_Release(params); @@ -5312,6 +5337,65 @@ if (0) /* crashes on native */ IDWriteFactory2_Release(factory2); } + if (fontface3) { + IDWriteRenderingParams3 *params3; + IDWriteRenderingParams2 *params2; + IDWriteRenderingParams *params; + IDWriteFactory3 *factory3; + DWRITE_GRID_FIT_MODE gridfit; + DWRITE_RENDERING_MODE1 mode1; + + hr = IDWriteFactory_QueryInterface(factory, &IID_IDWriteFactory3, (void**)&factory3); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDWriteFactory3_CreateCustomRenderingParams(factory3, 1.0f, 0.0f, 0.0f, 0.5f, DWRITE_PIXEL_GEOMETRY_FLAT, + DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC_DOWNSAMPLED, DWRITE_GRID_FIT_MODE_ENABLED, ¶ms3); + ok(hr == S_OK, "got 0x%08x\n", hr); + + mode1 = IDWriteRenderingParams3_GetRenderingMode1(params3); + ok(mode1 == DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC_DOWNSAMPLED, "got %d\n", mode1); + + mode1 = IDWriteRenderingParams3_GetRenderingMode(params3); + ok(mode1 == DWRITE_RENDERING_MODE1_NATURAL_SYMMETRIC, "got %d\n", mode1); + + hr = IDWriteRenderingParams3_QueryInterface(params3, &IID_IDWriteRenderingParams, (void**)¶ms); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(params == (IDWriteRenderingParams*)params3, "got %p, %p\n", params3, params); + mode = IDWriteRenderingParams_GetRenderingMode(params); + ok(mode == DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC, "got %d\n", mode); + IDWriteRenderingParams_Release(params); + + hr = IDWriteRenderingParams3_QueryInterface(params3, &IID_IDWriteRenderingParams2, (void**)¶ms2); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(params2 == (IDWriteRenderingParams2*)params3, "got %p, %p\n", params3, params2); + mode = IDWriteRenderingParams2_GetRenderingMode(params2); + ok(mode == DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC, "got %d\n", mode); + IDWriteRenderingParams2_Release(params2); + + mode = 10; + gridfit = 10; + hr = IDWriteFontFace2_GetRecommendedRenderingMode(fontface2, 5.0f, 96.0f, 96.0f, + NULL, FALSE, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED, DWRITE_MEASURING_MODE_GDI_CLASSIC, + NULL, &mode, &gridfit); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(mode == DWRITE_RENDERING_MODE_GDI_CLASSIC, "got %d\n", mode); + ok(gridfit == DWRITE_GRID_FIT_MODE_ENABLED, "got %d\n", gridfit); + + mode = 10; + gridfit = 10; + hr = IDWriteFontFace2_GetRecommendedRenderingMode(fontface2, 5.0f, 96.0f, 96.0f, + NULL, FALSE, DWRITE_OUTLINE_THRESHOLD_ANTIALIASED, DWRITE_MEASURING_MODE_GDI_CLASSIC, + (IDWriteRenderingParams*)params3, &mode, &gridfit); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(mode == DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC, "got %d\n", mode); + ok(gridfit == DWRITE_GRID_FIT_MODE_ENABLED, "got %d\n", gridfit); + + IDWriteRenderingParams3_Release(params3); + IDWriteFactory3_Release(factory3); + } + + if (fontface3) + IDWriteFontFace3_Release(fontface3); if (fontface2) IDWriteFontFace2_Release(fontface2); if (fontface1)