Module: wine Branch: master Commit: 97e52ab67312a565f3d8c31288ea9bb94edf212a URL: http://source.winehq.org/git/wine.git/?a=commit;h=97e52ab67312a565f3d8c31288...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Wed Nov 2 16:12:39 2016 +0300
d2d1: Implement FillContainsPoint() for rectangle geometry.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/d2d1/geometry.c | 24 +++++++++++++++++-- dlls/d2d1/tests/d2d1.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++-- include/d2d1.idl | 2 ++ 3 files changed, 86 insertions(+), 4 deletions(-)
diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c index 4abe9bc..afbf339 100644 --- a/dlls/d2d1/geometry.c +++ b/dlls/d2d1/geometry.c @@ -2390,10 +2390,30 @@ static HRESULT STDMETHODCALLTYPE d2d_rectangle_geometry_StrokeContainsPoint(ID2D static HRESULT STDMETHODCALLTYPE d2d_rectangle_geometry_FillContainsPoint(ID2D1RectangleGeometry *iface, D2D1_POINT_2F point, const D2D1_MATRIX_3X2_F *transform, float tolerance, BOOL *contains) { - FIXME("iface %p, point {%.8e, %.8e}, transform %p, tolerance %.8e, contains %p stub!\n", + struct d2d_geometry *geometry = impl_from_ID2D1RectangleGeometry(iface); + D2D1_RECT_F *rect = &geometry->u.rectangle.rect; + float dx, dy; + + TRACE("iface %p, point {%.8e, %.8e}, transform %p, tolerance %.8e, contains %p.\n", iface, point.x, point.y, transform, tolerance, contains);
- return E_NOTIMPL; + if (transform) + { + D2D1_MATRIX_3X2_F g_i; + + if (!d2d_matrix_invert(&g_i, transform)) + return D2DERR_UNSUPPORTED_OPERATION; + d2d_point_transform(&point, &g_i, point.x, point.y); + } + + if (tolerance == 0.0f) + tolerance = D2D1_DEFAULT_FLATTENING_TOLERANCE; + + dx = max(fabsf((rect->right + rect->left) / 2.0f - point.x) - (rect->right - rect->left) / 2.0f, 0.0f); + dy = max(fabsf((rect->bottom + rect->top) / 2.0f - point.y) - (rect->bottom - rect->top) / 2.0f, 0.0f); + + *contains = tolerance * tolerance > (dx * dx + dy * dy); + return S_OK; }
static HRESULT STDMETHODCALLTYPE d2d_rectangle_geometry_CompareWithGeometry(ID2D1RectangleGeometry *iface, diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 4409bb8..721afa4 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -1749,6 +1749,66 @@ static void test_path_geometry(void) DestroyWindow(window); }
+static void test_rectangle_geometry(void) +{ + ID2D1RectangleGeometry *geometry; + ID2D1Factory *factory; + D2D1_POINT_2F point; + D2D1_RECT_F rect; + BOOL contains; + HRESULT hr; + + hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory); + ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr); + + set_rect(&rect, 0.0f, 0.0f, 10.0f, 20.0f); + hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry); + ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr); + + /* Edge. */ + contains = FALSE; + set_point(&point, 0.0f, 0.0f); + hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains); + ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr); + ok(!!contains, "Got wrong hit test result %d.\n", contains); + + /* Within tolerance limit around corner. */ + contains = TRUE; + set_point(&point, -D2D1_DEFAULT_FLATTENING_TOLERANCE, 0.0f); + hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains); + ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr); + ok(!contains, "Got wrong hit test result %d.\n", contains); + + contains = FALSE; + set_point(&point, -D2D1_DEFAULT_FLATTENING_TOLERANCE + 0.01f, 0.0f); + hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains); + ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr); + ok(!!contains, "Got wrong hit test result %d.\n", contains); + + contains = TRUE; + set_point(&point, -D2D1_DEFAULT_FLATTENING_TOLERANCE - 0.01f, 0.0f); + hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains); + ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr); + ok(!contains, "Got wrong hit test result %d.\n", contains); + + contains = TRUE; + set_point(&point, -D2D1_DEFAULT_FLATTENING_TOLERANCE, -D2D1_DEFAULT_FLATTENING_TOLERANCE); + hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains); + ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr); + ok(!contains, "Got wrong hit test result %d.\n", contains); + + /* Inside. */ + contains = FALSE; + set_point(&point, 5.0f, 5.0f); + hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains); + ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr); + ok(!!contains, "Got wrong hit test result %d.\n", contains); + + ID2D1RectangleGeometry_Release(geometry); + + ID2D1Factory_Release(factory); +} + static void test_bitmap_formats(void) { D2D1_BITMAP_PROPERTIES bitmap_desc; @@ -2705,8 +2765,7 @@ todo_wine ok(hr == D2DERR_WRONG_FACTORY, "EndDraw failure expected, hr %#x.\n", hr);
/* Effect is d2d resource, but not a brush. */ - rect.left = rect.top = 0.0f; - rect.right = rect.bottom = 10.0f; + set_rect(&rect, 0.0f, 0.0f, 10.0f, 10.0f); hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry); ok(SUCCEEDED(hr), "Failed to geometry, hr %#x.\n", hr);
@@ -3189,6 +3248,7 @@ START_TEST(d2d1) test_color_brush(); test_bitmap_brush(); test_path_geometry(); + test_rectangle_geometry(); test_bitmap_formats(); test_alpha_mode(); test_shared_bitmap(); diff --git a/include/d2d1.idl b/include/d2d1.idl index 6d39e88..cb07cfa 100644 --- a/include/d2d1.idl +++ b/include/d2d1.idl @@ -50,6 +50,8 @@ typedef D2D_POINT_2U D2D1_POINT_2U; typedef D2D_RECT_U D2D1_RECT_U; typedef D2D_COLOR_F D2D1_COLOR_F;
+cpp_quote("#define D2D1_DEFAULT_FLATTENING_TOLERANCE (0.25f)") + enum { D2D1_INTERPOLATION_MODE_DEFINITION_NEAREST_NEIGHBOR = 0,