From: David White dwhite@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- dlls/d2d1/geometry.c | 69 ++++++++++++++++++++++++++++++++++++++++-- dlls/d2d1/tests/d2d1.c | 57 ++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 3 deletions(-)
diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c index af92df4f6c5..d5a430e1f74 100644 --- a/dlls/d2d1/geometry.c +++ b/dlls/d2d1/geometry.c @@ -3409,11 +3409,74 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_StrokeContainsPoint(ID2D1Path D2D1_POINT_2F point, float stroke_width, ID2D1StrokeStyle *stroke_style, const D2D1_MATRIX_3X2_F *transform, float tolerance, BOOL *contains) { - FIXME("iface %p, point %s, stroke_width %.8e, stroke_style %p, " - "transform %p, tolerance %.8e, contains %p stub!\n", + struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry(iface); + enum d2d_vertex_type type = D2D_VERTEX_TYPE_NONE; + D2D1_POINT_2F p, p1; + unsigned int i, j; + + TRACE("iface %p, point %s, stroke_width %.8e, stroke_style %p, transform %p, tolerance %.8e, contains %p.\n", iface, debug_d2d_point_2f(&point), stroke_width, stroke_style, transform, tolerance, contains);
- return E_NOTIMPL; + if (stroke_style) + FIXME("Ignoring stroke style %p.\n", stroke_style); + + if (!transform) + transform = &identity; + + if (tolerance <= 0.0f) + tolerance = D2D1_DEFAULT_FLATTENING_TOLERANCE; + + *contains = FALSE; + for (i = 0; i < geometry->u.path.figure_count; ++i) + { + const struct d2d_figure *figure = &geometry->u.path.figures[i]; + + for (j = 0; j < figure->vertex_count; ++j) + { + if (figure->vertex_types[j] == D2D_VERTEX_TYPE_NONE) + continue; + + p = figure->vertices[j]; + type = figure->vertex_types[j]; + break; + } + + for (++j; j < figure->vertex_count; ++j) + { + if (figure->vertex_types[j] == D2D_VERTEX_TYPE_NONE + || d2d_vertex_type_is_split_bezier(figure->vertex_types[j])) + continue; + + switch (type) + { + case D2D_VERTEX_TYPE_LINE: + p1 = figure->vertices[j]; + *contains = d2d_point_on_line_segment(&point, &p, &p1, transform, stroke_width * 0.5f, tolerance); + p = p1; + break; + + default: + FIXME("Unhandled vertex type %#x.\n", type); + p = figure->vertices[j]; + break; + } + if (*contains) + return S_OK; + type = figure->vertex_types[j]; + } + + if (figure->flags & D2D_FIGURE_FLAG_CLOSED && (!*contains) && type == D2D_VERTEX_TYPE_LINE) + { + p1 = figure->vertices[0]; + *contains = d2d_point_on_line_segment(&point, &p, &p1, transform, stroke_width * 0.5f, tolerance); + p = p1; + } + + if (*contains) + return S_OK; + } + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d2d_path_geometry_FillContainsPoint(ID2D1PathGeometry *iface, diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 22381ca3782..15088d679df 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -10137,7 +10137,10 @@ static void test_effect_crop(BOOL d3d11) static void test_stroke_contains_point(BOOL d3d11) { ID2D1RectangleGeometry *rectangle; + ID2D1GeometrySink *sink; + ID2D1PathGeometry *path; ID2D1Factory *factory; + D2D1_POINT_2F point; D2D1_RECT_F rect; unsigned int i; BOOL contains; @@ -10220,6 +10223,27 @@ static void test_stroke_contains_point(BOOL d3d11) {{{{1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 21.0f}}}, {10.0f, 31.0f}, 0.0f, 1.0f, TRUE, TRUE}, {{{{1.0f, 0.0f, 0.0f, 1.0f, 11.0f, 0.0f}}}, {16.0f, 0.0f}, 0.0f, 1.0f, TRUE, TRUE}, {{{{1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -21.0f}}}, { 0.0f, -11.0f}, 0.0f, 1.0f, TRUE, TRUE}, + }, + path_tests[] = + { + /* 0. Stroked area hittesting. Edge. */ + {{{{0.0f}}}, {160.0f, 600.0f}, 0.0f, 1.0f, FALSE, FALSE}, + {{{{0.0f}}}, {239.24f, 600.0f}, 0.0f, 1.0f, FALSE, FALSE}, + {{{{0.0f}}}, {239.26f, 600.0f}, 0.0f, 1.0f, FALSE, TRUE}, + {{{{0.0f}}}, {240.74f, 600.0f}, 0.0f, 1.0f, FALSE, TRUE}, + {{{{0.0f}}}, {240.76f, 600.0f}, 0.0f, 1.0f, FALSE, FALSE}, + + /* 5. Negative tolerance. */ + {{{{0.0f}}}, {239.24f, 600.0f}, -1.0f, 1.0f, FALSE, FALSE}, + {{{{0.0f}}}, {239.26f, 600.0f}, -1.0f, 1.0f, FALSE, TRUE}, + {{{{0.0f}}}, {240.74f, 600.0f}, -1.0f, 1.0f, FALSE, TRUE}, + {{{{0.0f}}}, {240.76f, 600.0f}, -1.0f, 1.0f, FALSE, FALSE}, + + /* 9. Less than default tolerance. */ + {{{{0.0f}}}, {239.39f, 600.0f}, 0.1f, 1.0f, FALSE, FALSE}, + {{{{0.0f}}}, {239.41f, 600.0f}, 0.1f, 1.0f, FALSE, TRUE}, + {{{{0.0f}}}, {240.59f, 600.0f}, 0.1f, 1.0f, FALSE, TRUE}, + {{{{0.0f}}}, {240.61f, 600.0f}, 0.1f, 1.0f, FALSE, FALSE}, };
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory); @@ -10244,6 +10268,39 @@ static void test_stroke_contains_point(BOOL d3d11) } ID2D1RectangleGeometry_Release(rectangle);
+ hr = ID2D1Factory_CreatePathGeometry(factory, &path); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + hr = ID2D1PathGeometry_Open(path, &sink); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + + set_point(&point, 160.0f, 240.0f); + ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED); + line_to(sink, 240.0f, 240.0f); + line_to(sink, 240.0f, 720.0f); + line_to(sink, 160.0f, 720.0f); + ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN); + + hr = ID2D1GeometrySink_Close(sink); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ID2D1GeometrySink_Release(sink); + + for (i = 0; i < ARRAY_SIZE(path_tests); ++i) + { + const struct contains_point_test *test = &path_tests[i]; + + winetest_push_context("Test %u", i); + + contains = !test->contains; + hr = ID2D1PathGeometry_StrokeContainsPoint(path, test->point, test->stroke_width, + NULL, test->matrix ? &test->transform : NULL, test->tolerance, &contains); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + ok(contains == test->contains, "Got unexpected result %#x.\n", contains); + + winetest_pop_context(); + } + + ID2D1PathGeometry_Release(path); + ID2D1Factory_Release(factory); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=103673
Your paranoid android.
=== debiant2 (64 bit WoW report) ===
d2d1: d2d1.c:6688: Test failed: d2d1.c:9776: Test marked todo: Test 1: Got unexpected hr 0x88990029.