d2d1: Implement rectangle geometry outlines.

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Henri Verbeet 2017-02-03 13:37:11 +01:00 committed by Alexandre Julliard
parent 39406039c0
commit 7ed032a014
2 changed files with 144 additions and 22 deletions

View File

@ -2816,45 +2816,59 @@ static const struct ID2D1RectangleGeometryVtbl d2d_rectangle_geometry_vtbl =
HRESULT d2d_rectangle_geometry_init(struct d2d_geometry *geometry, ID2D1Factory *factory, const D2D1_RECT_F *rect)
{
D2D1_POINT_2F *fv;
struct d2d_face *f;
D2D1_POINT_2F *v;
float l, r, t, b;
d2d_geometry_init(geometry, factory, &identity, (ID2D1GeometryVtbl *)&d2d_rectangle_geometry_vtbl);
geometry->u.rectangle.rect = *rect;
if (!(geometry->fill.vertices = HeapAlloc(GetProcessHeap(), 0, 4 * sizeof(*geometry->fill.vertices))))
{
d2d_geometry_cleanup(geometry);
return E_OUTOFMEMORY;
}
geometry->fill.vertex_count = 4;
goto fail;
if (!d2d_array_reserve((void **)&geometry->fill.faces,
&geometry->fill.faces_size, 2, sizeof(*geometry->fill.faces)))
{
d2d_geometry_cleanup(geometry);
return E_OUTOFMEMORY;
}
geometry->fill.face_count = 2;
goto fail;
l = min(rect->left, rect->right);
r = max(rect->left, rect->right);
t = min(rect->top, rect->bottom);
b = max(rect->top, rect->bottom);
fv = geometry->fill.vertices;
d2d_point_set(&fv[0], l, t);
d2d_point_set(&fv[1], l, b);
d2d_point_set(&fv[2], r, t);
d2d_point_set(&fv[3], r, b);
v = geometry->fill.vertices;
d2d_point_set(&v[0], l, t);
d2d_point_set(&v[1], l, b);
d2d_point_set(&v[2], r, b);
d2d_point_set(&v[3], r, t);
geometry->fill.vertex_count = 4;
geometry->fill.faces[0].v[0] = 0;
geometry->fill.faces[0].v[1] = 2;
geometry->fill.faces[0].v[2] = 1;
geometry->fill.faces[1].v[0] = 1;
geometry->fill.faces[1].v[1] = 2;
geometry->fill.faces[1].v[2] = 3;
f = geometry->fill.faces;
d2d_face_set(&f[0], 1, 2, 0);
d2d_face_set(&f[1], 0, 2, 3);
geometry->fill.face_count = 2;
if (!d2d_geometry_outline_add_line_segment(geometry, &v[0], &v[1]))
goto fail;
if (!d2d_geometry_outline_add_line_segment(geometry, &v[1], &v[2]))
goto fail;
if (!d2d_geometry_outline_add_line_segment(geometry, &v[2], &v[3]))
goto fail;
if (!d2d_geometry_outline_add_line_segment(geometry, &v[3], &v[0]))
goto fail;
if (!d2d_geometry_outline_add_join(geometry, &v[3], &v[0], &v[1]))
goto fail;
if (!d2d_geometry_outline_add_join(geometry, &v[0], &v[1], &v[2]))
goto fail;
if (!d2d_geometry_outline_add_join(geometry, &v[1], &v[2], &v[3]))
goto fail;
if (!d2d_geometry_outline_add_join(geometry, &v[2], &v[3], &v[0]))
goto fail;
return S_OK;
fail:
d2d_geometry_cleanup(geometry);
return E_OUTOFMEMORY;
}
static inline struct d2d_geometry *impl_from_ID2D1TransformedGeometry(ID2D1TransformedGeometry *iface)

View File

@ -3569,16 +3569,20 @@ static void test_gradient(void)
static void test_draw_geometry(void)
{
ID2D1TransformedGeometry *transformed_geometry[3];
ID2D1RectangleGeometry *rect_geometry[2];
D2D1_POINT_2F point = {0.0f, 0.0f};
ID2D1SolidColorBrush *brush;
ID2D1PathGeometry *geometry;
IDXGISwapChain *swapchain;
D2D1_MATRIX_3X2_F matrix;
ID2D1GeometrySink *sink;
ID2D1RenderTarget *rt;
ID3D10Device1 *device;
IDXGISurface *surface;
ID2D1Factory *factory;
D2D1_COLOR_F color;
D2D1_RECT_F rect;
ULONG refcount;
HWND window;
HRESULT hr;
@ -3753,6 +3757,110 @@ static void test_draw_geometry(void)
"nQECngECrycA");
ok(match, "Figure does not match.\n");
set_rect(&rect, 20.0f, 80.0f, 60.0f, 240.0f);
hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &rect_geometry[0]);
ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &rect_geometry[1]);
ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
set_matrix_identity(&matrix);
translate_matrix(&matrix, 160.0f, 640.0f);
scale_matrix(&matrix, 40.0f, 160.0f);
rotate_matrix(&matrix, M_PI / -5.0f);
hr = ID2D1Factory_CreateTransformedGeometry(factory,
(ID2D1Geometry *)rect_geometry[1], &matrix, &transformed_geometry[0]);
ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
set_matrix_identity(&matrix);
scale_matrix(&matrix, 0.5f, 1.0f);
translate_matrix(&matrix, -80.0f, 0.0f);
hr = ID2D1Factory_CreateTransformedGeometry(factory,
(ID2D1Geometry *)transformed_geometry[0], &matrix, &transformed_geometry[1]);
ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
set_matrix_identity(&matrix);
rotate_matrix(&matrix, M_PI / 2.0f);
translate_matrix(&matrix, 80.0f, -320.0f);
scale_matrix(&matrix, 2.0f, 0.25f);
hr = ID2D1Factory_CreateTransformedGeometry(factory,
(ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
ID2D1RenderTarget_BeginDraw(rt);
ID2D1RenderTarget_Clear(rt, &color);
ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)rect_geometry[0], (ID2D1Brush *)brush, 10.0f, NULL);
ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[0], (ID2D1Brush *)brush, 10.0f, NULL);
ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[1], (ID2D1Brush *)brush, 5.0f, NULL);
ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[2], (ID2D1Brush *)brush, 15.0f, NULL);
hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
ID2D1TransformedGeometry_Release(transformed_geometry[2]);
ID2D1TransformedGeometry_Release(transformed_geometry[1]);
ID2D1TransformedGeometry_Release(transformed_geometry[0]);
ID2D1RectangleGeometry_Release(rect_geometry[1]);
ID2D1RectangleGeometry_Release(rect_geometry[0]);
match = compare_figure(surface, 0, 0, 160, 160, 0xff652e89, 0,
"vi5kPGQ8ZDxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
"PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
"FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
"PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
"FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
"PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
ok(match, "Figure does not match.\n");
match = compare_figure(surface, 160, 0, 320, 160, 0xff652e89, 32,
"8XYGtQIOrAIXpAIfmwIokwIwigI4gwJA+gFJ8gFR6QEzAiXhATMKJdgBMxMl0AEzGyXHATMkJb8B"
"MysmtgEzNCWvATM8JaYBM0UlngEzTSWVATNWJY0BM14lhAEzZyV8M28lczN4JWszgAElYjOIASZa"
"M5ABJVgtmQElWCWhASVYJaEBJVgloQElWCWhASVYJaEBJVgloQElWCWhASVYJaEBJVglmQEtWCWQ"
"ATNaJogBM2IlgAEzayV4M3MlbzN8JWczhAElXjONASVWM5UBJU0zngElRTOmASU8M68BJTQztgEm"
"KzO/ASUkM8cBJRsz0AElEzPYASUKM+EBJQIz6QFR8gFJ+gFAgwI4igIwkwIomwIfpAIXrAIOtQIG"
"8XYA");
todo_wine ok(match, "Figure does not match.\n");
match = compare_figure(surface, 0, 160, 160, 320, 0xff652e89, 32,
"ujEBngECnQEDnQEEmwEFmgEHmQEHmAEIlwEKlgEKlQELlAENkwENkgEOkQEQjwERjwESjQETjAEU"
"jAEKAQqKAQoCCokBCgMKiQEKBAqHAQoFCoYBCgYKhgEKBwqEAQoICoMBCgkKgwEKCgqBAQoLCoAB"
"Cg0KfgsNCn4KDgp9ChAKewsQCnsKEQp6ChMKeAoUCngKFAp3ChYKdQoXCnUKGApzChkKcgoaCnIK"
"GwpwChwKbwodCm4LHgptCh8KbAogCmsLIQpqCiIKaQokCmcKJQpnCiUKZgonCmQKKApkCigKYwoq"
"CmEKKwphCisKYAotCl4KLgpdCy8KXAowClsKMQpaCzIKWQozClgKNApXCjYKVgo2ClUKNwpUCjkK"
"Uwo5ClIKOwpQCjwKTws8Ck8KPgpNCj8KTAs/CkwKQQpKCkIKSQtCCkkKRApHCkUKRgpHCkUKRwpE"
"CkgKQwpKCkIKSgpBCksKQApNCj4LTQo+Ck4KPQpQCjsLUAo7ClIKOQpTCjgLUwo4ClUKNgpWCjUK"
"Vwo1ClgKMwpZCjQKWAo0ClkKMwpZCjQKWQozClkKMwpZCjQKWQozClkKMwpZCjQKWQozClkKNApY"
"CjQKWQozClkKNApZCjMKWQozClkKNApZCjMKWQozClkKNApZCjMKWQo0ClgKNApZCjMKWQo0ClkK"
"MwpZCjMKWQo0ClkKMwpZCjMKWQo0ClkKMwpZCjQKWAo0ClkKMwpYCjUKVwo1ClYKNgpVCjgKUws4"
"ClMKOQpSCjsKUAs7ClAKPQpOCj4KTQs+Ck0KQApLCkEKSgpCCkoKQwpICkQKRwpFCkcKRgpFCkcK"
"RApJCkILSQpCCkoKQQpMCj8LTAo/Ck0KPgpPCjwLTwo8ClAKOwpSCjkKUwo5ClQKNwpVCjYKVgo2"
"ClcKNApYCjMKWQoyC1oKMQpbCjAKXAovC10KLgpeCi0KYAorCmEKKwphCioKYwooCmQKKApkCicK"
"ZgolCmcKJQpnCiQKaQoiCmoKIQtrCiAKbAofCm0KHgtuCh0KbwocCnAKGwpyChoKcgoZCnMKGAp1"
"ChcKdQoWCncKFAp4ChQKeAoTCnoKEQp7ChALewoQCn0KDgp+Cg0LfgoNCoABCgsKgQEKCgqDAQoJ"
"CoMBCggKhAEKBwqGAQoGCoYBCgUKhwEKBAqJAQoDCokBCgIKigEKAQqMARSMARONARKPARGPARCR"
"AQ6SAQ2TAQ2UAQuVAQqWAQqXAQiYAQeZAQeaAQWbAQSdAQOdAQKeAQG6MQAA");
todo_wine ok(match, "Figure does not match.\n");
match = compare_figure(surface, 160, 160, 320, 320, 0xff652e89, 64,
"82ICvQIEugIHuAIJtgIKtAINsgIPsAIRrQITrAIVqQIYpwIZpgIbowIeoQIgnwIhnQIkmwImmAIp"
"lgIVARSVAhUDFJICFQUVkAIVBxSPAhUJFIwCFQwUigIVDRWHAhYPFIYCFRIUhAIVFBSBAhUWFf8B"
"FRgU/gEVGhT7ARUcFfkBFR4U9wEWIBT1ARUjFPMBFSQV8AEVJxTvARUpFOwBFisU6gEVLRXoARUv"
"FOYBFjEU5AEVMxXiARU1FOABFTgU3gEVOhTbARY7FdkBFT4U2AEVQBTVARZCFNMBFUQV0QEVRhTP"
"ARVJFM0BFUoVygEWTBTJARVPFMcBFVEUxAEVUxXCARVVFMEBFVcUvgEVWRW8ARVbFbkBFl0UuAEV"
"YBS2ARVhFbMBFWQUsgEVZhSwARVoFK0BFWoVqwEVbBSpARZuFKcBFXAVpQEVchWiARV1FKEBFXcU"
"nwEVeBWcARV7FJsBFX0UmAEWfxSWARWBARWUARWDARSSARWGARSQARWHARWOARWJARWLARWMARSK"
"ARWOARSHARaPARWFARWSARSEARWUARSBARWXARR/FZgBFX0VmgEUexWdARR5FZ4BFXYWoAEVdBWj"
"ARRzFaUBFHAVpwEVbhWpARRtFasBFGoVrgEUaBWvARVmFbEBFGcUsgEUZxSxARVmFbEBFWYUsgEU"
"ZxSyARRnFLEBFWYVsQEUZxSyARRnFLIBFGcUsQEVZhWxARRnFLIBFGcUsQEVZhWxARVmFLIBFGcU"
"sgEUZxSxARVmFbEBFGcUsgEUZxSyARRmFbEBFWYVsQEUZxSyARRnFLEBFWYVsQEUZxSyARRnFLIB"
"FGcUsQEVZhWxARRnFLIBFGcUsgEUZhWxARVmFbEBFGcUsgEUZxSxARVmFa8BFWgUrgEVahSrARVt"
"FKkBFW4VpwEVcBSlARVzFKMBFXQVoAEWdhWeARV5FJ0BFXsUmgEVfRWYARV/FJcBFYEBFJQBFYQB"
"FJIBFYUBFY8BFocBFI4BFYoBFIwBFYsBFYkBFY4BFYcBFZABFIYBFZIBFIMBFZQBFYEBFZYBFH8W"
"mAEUfRWbARR7FZwBFXgVnwEUdxWhARR1FaIBFXIVpQEVcBWnARRuFqkBFGwVqwEVahWtARRoFbAB"
"FGYVsgEUZBWzARVhFbYBFGAVuAEUXRa5ARVbFbwBFVkVvgEUVxXBARRVFcIBFVMVxAEUURXHARRP"
"FckBFEwWygEVShXNARRJFc8BFEYV0QEVRBXTARRCFtUBFEAV2AEUPhXZARU7FtsBFDoV3gEUOBXg"
"ARQ1FeIBFTMV5AEUMRbmARQvFegBFS0V6gEUKxbsARQpFe8BFCcV8AEVJBXzARQjFfUBFCAW9wEU"
"HhX5ARUcFfsBFBoV/gEUGBX/ARUWFYECFBQVhAIUEhWGAhQPFocCFQ0VigIUDBWMAhQJFY8CFAcV"
"kAIVBRWSAhQDFZUCFAEVlgIpmAImmwIknQIhnwIgoQIeowIbpgIZpwIYqQIVrAITrQIRsAIPsgIN"
"tAIKtgIJuAIHugIEvQIC82IA");
ok(match, "Figure does not match.\n");
ID2D1SolidColorBrush_Release(brush);
ID2D1RenderTarget_Release(rt);
refcount = ID2D1Factory_Release(factory);