dwrite/tests: Some tests for GetRecommendedRenderingMode().

This commit is contained in:
Nikolay Sivov 2015-07-27 11:10:04 +03:00 committed by Alexandre Julliard
parent 7b1332d3f5
commit aac3a069e4
1 changed files with 269 additions and 0 deletions

View File

@ -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);
}