Nikolay Sivov : d2d1: Implement FillContainsPoint() for rectangle geometry.

Alexandre Julliard julliard at winehq.org
Thu Nov 3 14:26:20 CDT 2016


Module: wine
Branch: master
Commit: 97e52ab67312a565f3d8c31288ea9bb94edf212a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=97e52ab67312a565f3d8c31288ea9bb94edf212a

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Nov  2 16:12:39 2016 +0300

d2d1: Implement FillContainsPoint() for rectangle geometry.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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,




More information about the wine-cvs mailing list