Andrew Eikum : d2d1: Implement d2d_path_geometry_FillContainsPoint().

Alexandre Julliard julliard at winehq.org
Wed Oct 26 14:50:09 CDT 2016


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

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Wed Oct 26 15:20:22 2016 +0200

d2d1: Implement d2d_path_geometry_FillContainsPoint().

Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/d2d1/d2d1_private.h  | 23 +++++++++++++++++++++++
 dlls/d2d1/geometry.c      | 22 +++++++++++++++++++---
 dlls/d2d1/render_target.c |  6 ------
 3 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index b49fce4..8497ea8 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -357,4 +357,27 @@ static inline void d2d_matrix_multiply(D2D_MATRIX_3X2_F *a, const D2D_MATRIX_3X2
     a->_32 = tmp._31 * b->_12 + tmp._32 * b->_22 + b->_32;
 }
 
+/* Dst must be different from src. */
+static inline BOOL d2d_matrix_invert(D2D_MATRIX_3X2_F *dst, const D2D_MATRIX_3X2_F *src)
+{
+    float d = src->_11 * src->_22 - src->_21 * src->_12;
+
+    if (d == 0.0f)
+        return FALSE;
+    dst->_11 = src->_22 / d;
+    dst->_21 = -src->_21 / d;
+    dst->_31 = (src->_21 * src->_32 - src->_31 * src->_22) / d;
+    dst->_12 = -src->_12 / d;
+    dst->_22 = src->_11 / d;
+    dst->_32 = -(src->_11 * src->_32 - src->_31 * src->_12) / d;
+
+    return TRUE;
+}
+
+static inline void d2d_point_transform(D2D1_POINT_2F *dst, const D2D1_MATRIX_3X2_F *matrix, float x, float y)
+{
+    dst->x = x * matrix->_11 + y * matrix->_21 + matrix->_31;
+    dst->y = x * matrix->_12 + y * matrix->_22 + matrix->_32;
+}
+
 #endif /* __WINE_D2D1_PRIVATE_H */
diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c
index 57dcce2..385e171 100644
--- a/dlls/d2d1/geometry.c
+++ b/dlls/d2d1/geometry.c
@@ -1924,9 +1924,11 @@ static HRESULT STDMETHODCALLTYPE d2d_geometry_sink_Close(ID2D1GeometrySink *ifac
     }
 
 done:
-    d2d_path_geometry_free_figures(geometry);
     if (FAILED(hr))
+    {
+        d2d_path_geometry_free_figures(geometry);
         geometry->u.path.state = D2D_GEOMETRY_STATE_ERROR;
+    }
     return hr;
 }
 
@@ -2112,10 +2114,24 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_StrokeContainsPoint(ID2D1Path
 static HRESULT STDMETHODCALLTYPE d2d_path_geometry_FillContainsPoint(ID2D1PathGeometry *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_ID2D1PathGeometry(iface);
+    D2D1_MATRIX_3X2_F g_i;
+
+    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)
+    {
+        if (!d2d_matrix_invert(&g_i, transform))
+            return D2DERR_UNSUPPORTED_OPERATION;
+        d2d_point_transform(&point, &g_i, point.x, point.y);
+    }
+
+    *contains = !!d2d_path_geometry_point_inside(geometry, &point);
+
+    TRACE("-> %#x.\n", *contains);
+
+    return S_OK;
 }
 
 static HRESULT STDMETHODCALLTYPE d2d_path_geometry_CompareWithGeometry(ID2D1PathGeometry *iface,
diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c
index bc31f4d..798dd0d 100644
--- a/dlls/d2d1/render_target.c
+++ b/dlls/d2d1/render_target.c
@@ -48,12 +48,6 @@ static void d2d_point_set(D2D1_POINT_2F *dst, float x, float y)
     dst->y = y;
 }
 
-static void d2d_point_transform(D2D1_POINT_2F *dst, const D2D1_MATRIX_3X2_F *matrix, float x, float y)
-{
-    dst->x = x * matrix->_11 + y * matrix->_21 + matrix->_31;
-    dst->y = x * matrix->_12 + y * matrix->_22 + matrix->_32;
-}
-
 static void d2d_rect_expand(D2D1_RECT_F *dst, const D2D1_POINT_2F *point)
 {
     if (point->x < dst->left)




More information about the wine-cvs mailing list