[PATCH 5/5] d2d1: Properly test which side of a bezier curve is the inside.
Henri Verbeet
hverbeet at codeweavers.com
Mon Dec 5 06:16:06 CST 2016
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
dlls/d2d1/geometry.c | 230 ++++++++++++++++++++++++++++++++-----------------
dlls/d2d1/tests/d2d1.c | 110 ++++++++++++++++++-----
2 files changed, 238 insertions(+), 102 deletions(-)
diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c
index cb6fab8..522432f 100644
--- a/dlls/d2d1/geometry.c
+++ b/dlls/d2d1/geometry.c
@@ -46,15 +46,24 @@ enum d2d_cdt_edge_next
D2D_EDGE_NEXT_TOR = 3,
};
+enum d2d_vertex_type
+{
+ D2D_VERTEX_TYPE_NONE,
+ D2D_VERTEX_TYPE_LINE,
+ D2D_VERTEX_TYPE_BEZIER,
+};
+
struct d2d_figure
{
D2D1_POINT_2F *vertices;
size_t vertices_size;
+ enum d2d_vertex_type *vertex_types;
+ size_t vertex_types_size;
size_t vertex_count;
- struct d2d_bezier *beziers;
- size_t beziers_size;
- size_t bezier_count;
+ D2D1_POINT_2F *bezier_controls;
+ size_t bezier_controls_size;
+ size_t bezier_control_count;
D2D1_RECT_F bounds;
};
@@ -460,9 +469,19 @@ static BOOL d2d_figure_insert_vertex(struct d2d_figure *figure, size_t idx, D2D1
return FALSE;
}
+ if (!d2d_array_reserve((void **)&figure->vertex_types, &figure->vertex_types_size,
+ figure->vertex_count + 1, sizeof(*figure->vertex_types)))
+ {
+ ERR("Failed to grow vertex types array.\n");
+ return FALSE;
+ }
+
memmove(&figure->vertices[idx + 1], &figure->vertices[idx],
(figure->vertex_count - idx) * sizeof(*figure->vertices));
+ memmove(&figure->vertex_types[idx + 1], &figure->vertex_types[idx],
+ (figure->vertex_count - idx) * sizeof(*figure->vertex_types));
figure->vertices[idx] = vertex;
+ figure->vertex_types[idx] = D2D_VERTEX_TYPE_NONE;
d2d_figure_update_bounds(figure, vertex);
++figure->vertex_count;
return TRUE;
@@ -477,58 +496,31 @@ static BOOL d2d_figure_add_vertex(struct d2d_figure *figure, D2D1_POINT_2F verte
return FALSE;
}
+ if (!d2d_array_reserve((void **)&figure->vertex_types, &figure->vertex_types_size,
+ figure->vertex_count + 1, sizeof(*figure->vertex_types)))
+ {
+ ERR("Failed to grow vertex types array.\n");
+ return FALSE;
+ }
+
figure->vertices[figure->vertex_count] = vertex;
+ figure->vertex_types[figure->vertex_count] = D2D_VERTEX_TYPE_NONE;
d2d_figure_update_bounds(figure, vertex);
++figure->vertex_count;
return TRUE;
}
-/* FIXME: No inside/outside testing is done for beziers. */
-static BOOL d2d_figure_add_bezier(struct d2d_figure *figure, D2D1_POINT_2F p0, D2D1_POINT_2F p1, D2D1_POINT_2F p2)
+static BOOL d2d_figure_add_bezier_control(struct d2d_figure *figure, const D2D1_POINT_2F *p)
{
- struct d2d_bezier *b;
- unsigned int idx1, idx2;
- float sign;
-
- if (!d2d_array_reserve((void **)&figure->beziers, &figure->beziers_size,
- figure->bezier_count + 1, sizeof(*figure->beziers)))
+ if (!d2d_array_reserve((void **)&figure->bezier_controls, &figure->bezier_controls_size,
+ figure->bezier_control_count + 1, sizeof(*figure->bezier_controls)))
{
- ERR("Failed to grow beziers array.\n");
+ ERR("Failed to grow bezier controls array.\n");
return FALSE;
}
- if (d2d_point_ccw(&p0, &p1, &p2) > 0.0f)
- {
- sign = -1.0f;
- idx1 = 1;
- idx2 = 2;
- }
- else
- {
- sign = 1.0f;
- idx1 = 2;
- idx2 = 1;
- }
-
- b = &figure->beziers[figure->bezier_count];
- b->v[0].position = p0;
- b->v[0].texcoord.u = 0.0f;
- b->v[0].texcoord.v = 0.0f;
- b->v[0].texcoord.sign = sign;
- b->v[idx1].position = p1;
- b->v[idx1].texcoord.u = 0.5f;
- b->v[idx1].texcoord.v = 0.0f;
- b->v[idx1].texcoord.sign = sign;
- b->v[idx2].position = p2;
- b->v[idx2].texcoord.u = 1.0f;
- b->v[idx2].texcoord.v = 1.0f;
- b->v[idx2].texcoord.sign = sign;
- ++figure->bezier_count;
-
- if (sign > 0.0f && !d2d_figure_add_vertex(figure, p1))
- return FALSE;
- if (!d2d_figure_add_vertex(figure, p2))
- return FALSE;
+ figure->bezier_controls[figure->bezier_control_count++] = *p;
+
return TRUE;
}
@@ -1174,7 +1166,8 @@ static int d2d_cdt_compare_vertices(const void *a, const void *b)
/* Determine whether a given point is inside the geometry, using the current
* fill mode rule. */
-static BOOL d2d_path_geometry_point_inside(const struct d2d_geometry *geometry, const D2D1_POINT_2F *probe)
+static BOOL d2d_path_geometry_point_inside(const struct d2d_geometry *geometry,
+ const D2D1_POINT_2F *probe, BOOL triangles_only)
{
const D2D1_POINT_2F *p0, *p1;
D2D1_POINT_2F v_p, v_probe;
@@ -1190,8 +1183,11 @@ static BOOL d2d_path_geometry_point_inside(const struct d2d_geometry *geometry,
continue;
p0 = &figure->vertices[figure->vertex_count - 1];
- for (j = 0; j < figure->vertex_count; p0 = p1, ++j)
+ for (j = 0; j < figure->vertex_count; ++j)
{
+ if (!triangles_only && figure->vertex_types[j] == D2D_VERTEX_TYPE_NONE)
+ continue;
+
p1 = &figure->vertices[j];
d2d_point_subtract(&v_p, p1, p0);
d2d_point_subtract(&v_probe, probe, p0);
@@ -1203,6 +1199,8 @@ static BOOL d2d_path_geometry_point_inside(const struct d2d_geometry *geometry,
else
--score;
}
+
+ p0 = p1;
}
}
@@ -1249,7 +1247,7 @@ static BOOL d2d_path_geometry_add_face(struct d2d_geometry *geometry, const stru
probe.x += cdt->vertices[d2d_cdt_edge_origin(cdt, &tmp)].x * 0.50f;
probe.y += cdt->vertices[d2d_cdt_edge_origin(cdt, &tmp)].y * 0.50f;
- if (d2d_cdt_leftof(cdt, face->v[2], base_edge) && d2d_path_geometry_point_inside(geometry, &probe))
+ if (d2d_cdt_leftof(cdt, face->v[2], base_edge) && d2d_path_geometry_point_inside(geometry, &probe, TRUE))
++geometry->face_count;
return TRUE;
@@ -1791,6 +1789,7 @@ static void STDMETHODCALLTYPE d2d_geometry_sink_AddLines(ID2D1GeometrySink *ifac
const D2D1_POINT_2F *points, UINT32 count)
{
struct d2d_geometry *geometry = impl_from_ID2D1GeometrySink(iface);
+ struct d2d_figure *figure = &geometry->u.path.figures[geometry->u.path.figure_count - 1];
unsigned int i;
TRACE("iface %p, points %p, count %u.\n", iface, points, count);
@@ -1803,7 +1802,8 @@ static void STDMETHODCALLTYPE d2d_geometry_sink_AddLines(ID2D1GeometrySink *ifac
for (i = 0; i < count; ++i)
{
- if (!d2d_figure_add_vertex(&geometry->u.path.figures[geometry->u.path.figure_count - 1], points[i]))
+ figure->vertex_types[figure->vertex_count - 1] = D2D_VERTEX_TYPE_LINE;
+ if (!d2d_figure_add_vertex(figure, points[i]))
{
ERR("Failed to add vertex.\n");
return;
@@ -1836,9 +1836,19 @@ static void STDMETHODCALLTYPE d2d_geometry_sink_AddBeziers(ID2D1GeometrySink *if
p.y = (beziers[i].point1.y + beziers[i].point2.y) * 0.75f;
p.x -= (figure->vertices[figure->vertex_count - 1].x + beziers[i].point3.x) * 0.25f;
p.y -= (figure->vertices[figure->vertex_count - 1].y + beziers[i].point3.y) * 0.25f;
- if (!d2d_figure_add_bezier(figure, figure->vertices[figure->vertex_count - 1], p, beziers[i].point3))
+ figure->vertex_types[figure->vertex_count - 1] = D2D_VERTEX_TYPE_BEZIER;
+
+ if (!d2d_figure_add_bezier_control(figure, &p))
{
- ERR("Failed to add bezier.\n");
+ ERR("Failed to add bezier control.\n");
+ geometry->u.path.state = D2D_GEOMETRY_STATE_ERROR;
+ return;
+ }
+
+ if (!d2d_figure_add_vertex(figure, beziers[i].point3))
+ {
+ ERR("Failed to add bezier vertex.\n");
+ geometry->u.path.state = D2D_GEOMETRY_STATE_ERROR;
return;
}
}
@@ -1849,6 +1859,7 @@ static void STDMETHODCALLTYPE d2d_geometry_sink_AddBeziers(ID2D1GeometrySink *if
static void STDMETHODCALLTYPE d2d_geometry_sink_EndFigure(ID2D1GeometrySink *iface, D2D1_FIGURE_END figure_end)
{
struct d2d_geometry *geometry = impl_from_ID2D1GeometrySink(iface);
+ struct d2d_figure *figure;
TRACE("iface %p, figure_end %#x.\n", iface, figure_end);
@@ -1858,6 +1869,8 @@ static void STDMETHODCALLTYPE d2d_geometry_sink_EndFigure(ID2D1GeometrySink *ifa
return;
}
+ figure = &geometry->u.path.figures[geometry->u.path.figure_count - 1];
+ figure->vertex_types[figure->vertex_count - 1] = D2D_VERTEX_TYPE_LINE;
if (figure_end != D2D1_FIGURE_END_CLOSED)
FIXME("Ignoring figure_end %#x.\n", figure_end);
@@ -1873,7 +1886,7 @@ static void d2d_path_geometry_free_figures(struct d2d_geometry *geometry)
for (i = 0; i < geometry->u.path.figure_count; ++i)
{
- HeapFree(GetProcessHeap(), 0, geometry->u.path.figures[i].beziers);
+ HeapFree(GetProcessHeap(), 0, geometry->u.path.figures[i].bezier_controls);
HeapFree(GetProcessHeap(), 0, geometry->u.path.figures[i].vertices);
}
HeapFree(GetProcessHeap(), 0, geometry->u.path.figures);
@@ -1881,11 +1894,81 @@ static void d2d_path_geometry_free_figures(struct d2d_geometry *geometry)
geometry->u.path.figures_size = 0;
}
+static HRESULT d2d_geometry_resolve_beziers(struct d2d_geometry *geometry)
+{
+ size_t bezier_idx, control_idx, i, j;
+
+ for (i = 0; i < geometry->u.path.figure_count; ++i)
+ {
+ geometry->bezier_count += geometry->u.path.figures[i].bezier_control_count;
+ }
+
+ if (!(geometry->beziers = HeapAlloc(GetProcessHeap(), 0,
+ geometry->bezier_count * sizeof(*geometry->beziers))))
+ {
+ ERR("Failed to allocate beziers array.\n");
+ geometry->bezier_count = 0;
+ return E_OUTOFMEMORY;
+ }
+
+ for (i = 0, bezier_idx = 0; i < geometry->u.path.figure_count; ++i)
+ {
+ struct d2d_figure *figure = &geometry->u.path.figures[i];
+ if (figure->bezier_control_count)
+ {
+ for (j = 0, control_idx = 0; j < figure->vertex_count; ++j)
+ {
+ const D2D1_POINT_2F *p0, *p1, *p2;
+ struct d2d_bezier *b;
+
+ if (figure->vertex_types[j] != D2D_VERTEX_TYPE_BEZIER)
+ continue;
+
+ b = &geometry->beziers[bezier_idx];
+ p0 = &figure->vertices[j];
+ p1 = &figure->bezier_controls[control_idx++];
+ if (j == figure->vertex_count - 1)
+ p2 = &figure->vertices[0];
+ else
+ p2 = &figure->vertices[j + 1];
+
+ b->v[0].position = *p0;
+ b->v[0].texcoord.u = 0.0f;
+ b->v[0].texcoord.v = 0.0f;
+ b->v[1].position = *p1;
+ b->v[1].texcoord.u = 0.5f;
+ b->v[1].texcoord.v = 0.0f;
+ b->v[2].position = *p2;
+ b->v[2].texcoord.u = 1.0f;
+ b->v[2].texcoord.v = 1.0f;
+
+ if (d2d_path_geometry_point_inside(geometry, p1, FALSE))
+ {
+ b->v[0].texcoord.sign = 1.0f;
+ b->v[1].texcoord.sign = 1.0f;
+ b->v[2].texcoord.sign = 1.0f;
+ d2d_figure_insert_vertex(figure, j + 1, *p1);
+ ++j;
+ }
+ else
+ {
+ b->v[0].texcoord.sign = -1.0f;
+ b->v[1].texcoord.sign = -1.0f;
+ b->v[2].texcoord.sign = -1.0f;
+ }
+
+ ++bezier_idx;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
static HRESULT STDMETHODCALLTYPE d2d_geometry_sink_Close(ID2D1GeometrySink *iface)
{
struct d2d_geometry *geometry = impl_from_ID2D1GeometrySink(iface);
HRESULT hr = E_FAIL;
- size_t i, start;
TRACE("iface %p.\n", iface);
@@ -1899,37 +1982,16 @@ static HRESULT STDMETHODCALLTYPE d2d_geometry_sink_Close(ID2D1GeometrySink *ifac
if (!d2d_geometry_intersect_self(geometry))
goto done;
- if (FAILED(hr = d2d_path_geometry_triangulate(geometry)))
+ if (FAILED(hr = d2d_geometry_resolve_beziers(geometry)))
goto done;
-
- for (i = 0; i < geometry->u.path.figure_count; ++i)
- {
- geometry->bezier_count += geometry->u.path.figures[i].bezier_count;
- }
-
- if (!(geometry->beziers = HeapAlloc(GetProcessHeap(), 0,
- geometry->bezier_count * sizeof(*geometry->beziers))))
- {
- ERR("Failed to allocate beziers array.\n");
- geometry->bezier_count = 0;
- hr = E_OUTOFMEMORY;
+ if (FAILED(hr = d2d_path_geometry_triangulate(geometry)))
goto done;
- }
-
- for (i = 0, start = 0; i < geometry->u.path.figure_count; ++i)
- {
- struct d2d_figure *figure = &geometry->u.path.figures[i];
- if (figure->bezier_count)
- {
- memcpy(&geometry->beziers[start], figure->beziers,
- figure->bezier_count * sizeof(*figure->beziers));
- start += figure->bezier_count;
- }
- }
done:
if (FAILED(hr))
{
+ HeapFree(GetProcessHeap(), 0, geometry->beziers);
+ geometry->bezier_count = 0;
d2d_path_geometry_free_figures(geometry);
geometry->u.path.state = D2D_GEOMETRY_STATE_ERROR;
}
@@ -1975,10 +2037,18 @@ static void STDMETHODCALLTYPE d2d_geometry_sink_AddQuadraticBeziers(ID2D1Geometr
for (i = 0; i < bezier_count; ++i)
{
- if (!d2d_figure_add_bezier(figure, figure->vertices[figure->vertex_count - 1],
- beziers[i].point1, beziers[i].point2))
+ figure->vertex_types[figure->vertex_count - 1] = D2D_VERTEX_TYPE_BEZIER;
+ if (!d2d_figure_add_bezier_control(figure, &beziers[i].point1))
{
ERR("Failed to add bezier.\n");
+ geometry->u.path.state = D2D_GEOMETRY_STATE_ERROR;
+ return;
+ }
+
+ if (!d2d_figure_add_vertex(figure, beziers[i].point2))
+ {
+ ERR("Failed to add bezier vertex.\n");
+ geometry->u.path.state = D2D_GEOMETRY_STATE_ERROR;
return;
}
}
@@ -2131,7 +2201,7 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_FillContainsPoint(ID2D1PathGe
d2d_point_transform(&point, &g_i, point.x, point.y);
}
- *contains = !!d2d_path_geometry_point_inside(geometry, &point);
+ *contains = !!d2d_path_geometry_point_inside(geometry, &point, FALSE);
TRACE("-> %#x.\n", *contains);
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index f271103..941a43a 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -358,6 +358,29 @@ static void deserialize_figure(struct figure *figure, const BYTE *s)
}
}
+static void read_figure(struct figure *figure, BYTE *data, unsigned int pitch,
+ unsigned int x, unsigned int y, unsigned int w, unsigned int h, DWORD prev)
+{
+ unsigned int i, j, span;
+
+ figure->span_count = 0;
+ for (i = 0, span = 0; i < h; ++i)
+ {
+ const DWORD *row = (DWORD *)&data[(y + i) * pitch + x * 4];
+ for (j = 0; j < w; ++j, ++span)
+ {
+ if ((i || j) && prev != row[j])
+ {
+ figure_add_span(figure, span);
+ prev = row[j];
+ span = 0;
+ }
+ }
+ }
+ if (span)
+ figure_add_span(figure, span);
+}
+
static BOOL compare_figure(IDXGISurface *surface, unsigned int x, unsigned int y,
unsigned int w, unsigned int h, DWORD prev, unsigned int max_diff, const char *ref)
{
@@ -399,21 +422,7 @@ static BOOL compare_figure(IDXGISurface *surface, unsigned int x, unsigned int y
figure.spans_size = 64;
figure.spans = HeapAlloc(GetProcessHeap(), 0, figure.spans_size * sizeof(*figure.spans));
- for (i = 0, span = 0; i < h; ++i)
- {
- const DWORD *row = (DWORD *)((BYTE *)mapped_texture.pData + (y + i) * mapped_texture.RowPitch + x * 4);
- for (j = 0; j < w; ++j, ++span)
- {
- if ((i || j) && prev != row[j])
- {
- figure_add_span(&figure, span);
- prev = row[j];
- span = 0;
- }
- }
- }
- if (span)
- figure_add_span(&figure, span);
+ read_figure(&figure, mapped_texture.pData, mapped_texture.RowPitch, x, y, w, h, prev);
deserialize_figure(&ref_figure, (BYTE *)ref);
span = w * h;
@@ -449,7 +458,10 @@ static BOOL compare_figure(IDXGISurface *surface, unsigned int x, unsigned int y
}
}
if (diff > max_diff)
+ {
+ read_figure(&figure, mapped_texture.pData, mapped_texture.RowPitch, x, y, w, h, prev);
serialize_figure(&figure);
+ }
HeapFree(GetProcessHeap(), 0, ref_figure.spans);
HeapFree(GetProcessHeap(), 0, figure.spans);
@@ -1280,6 +1292,22 @@ static void fill_geometry_sink_bezier(ID2D1GeometrySink *sink)
quadratic_to(sink, 60.0f, 240.0f, 40.0f, 240.0f);
quadratic_to(sink, 20.0f, 240.0f, 20.0f, 160.0f);
ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
+
+ set_point(&point, 5.0f, 612.0f);
+ ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
+ quadratic_to(sink, 40.0f, 612.0f, 40.0f, 752.0f);
+ quadratic_to(sink, 40.0f, 612.0f, 75.0f, 612.0f);
+ quadratic_to(sink, 40.0f, 612.0f, 40.0f, 472.0f);
+ quadratic_to(sink, 40.0f, 612.0f, 5.0f, 612.0f);
+ ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
+
+ set_point(&point, 20.0f, 612.0f);
+ ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
+ quadratic_to(sink, 20.0f, 692.0f, 40.0f, 692.0f);
+ quadratic_to(sink, 60.0f, 692.0f, 60.0f, 612.0f);
+ quadratic_to(sink, 60.0f, 532.0f, 40.0f, 532.0f);
+ quadratic_to(sink, 20.0f, 532.0f, 20.0f, 612.0f);
+ ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
}
static void test_path_geometry(void)
@@ -1587,15 +1615,15 @@ static void test_path_geometry(void)
ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
- ok(count == 2, "Got unexpected figure count %u.\n", count);
+ ok(count == 4, "Got unexpected figure count %u.\n", count);
hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
- ok(count == 10, "Got unexpected segment count %u.\n", count);
+ ok(count == 20, "Got unexpected segment count %u.\n", count);
ID2D1GeometrySink_Release(sink);
set_matrix_identity(&matrix);
scale_matrix(&matrix, 0.5f, 2.0f);
- translate_matrix(&matrix, 240.0f, -33.0f);
+ translate_matrix(&matrix, 400.0f, -33.0f);
rotate_matrix(&matrix, M_PI / 4.0f);
scale_matrix(&matrix, 2.0f, 0.5f);
hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
@@ -1617,8 +1645,18 @@ static void test_path_geometry(void)
"EBVnFBAUaRQOFGsTDhJvEgwSchAMEHYPCg96DQoMggEICgiLAQQIBJQBCJgBCJkBBpoBBpoBBpoB"
"BpsBBJwBBJwBBJwBBJwBBJ0BAp4BAp4BAp4BAp4BAp4BAp4BAp4BAgAA");
todo_wine ok(match, "Figure does not match.\n");
+ match = compare_figure(surface, 0, 226, 160, 160, 0xff652e89, 64,
+ "7xoCngECngECngECngECngECngECngECnQEEnAEEnAEEnAEEnAEEmwEGmgEGmgEGmgEGmQEImAEI"
+ "lAEECASLAQgKCIEBDQoMew8KD3YQDBByEgwSbhMOEmwUDhRpFBAUZxUQFWUVEhVjFhIWYRYUFl8X"
+ "FBddFxYWXRYYFlsXGBdaFhoWWRYcFlgVHhVXFSAVVhQiFFUUIxRVEyYTVBIoElQRKhFUECwQUxAu"
+ "EFIOMg5SDTQNUgs4C1IJPAlRCEAIUAZEBlAESARQAU4BTgJQAkgGUAY/C1ALMhNQEyoTUBMyC1AL"
+ "PwZQBkgCUAJOAU4BUARIBFAGRAZQCEAIUQk8CVILOAtSDTQNUg4yDlIQLhBTECwQVBEqEVQSKBJU"
+ "EyYTVBQjFFYUIhRWFSAVVxUeFVgWHBZZFhoWWhcYF1sWGBZcFxYWXhcUF18WFBZhFhIWYxUSFWUV"
+ "EBVnFBAUaRQOFGsTDhJvEgwSchAMEHYPCg96DQoMggEICgiLAQQIBJQBCJgBCJkBBpoBBpoBBpoB"
+ "BpsBBJwBBJwBBJwBBJwBBJ0BAp4BAp4BAp4BAp4BAp4BAp4BAp4BAgAA");
+ todo_wine ok(match, "Figure does not match.\n");
match = compare_figure(surface, 160, 0, 320, 160, 0xff652e89, 64,
- "4VIBwAIBWgHlAQFYAecBAVYB6QEBVAHrAQEjDCMB7AECHhQeAu0BAxoYGgPvAQMWHhYD8QEDFCAU"
+ "gVQBwAIBWgHlAQFYAecBAVYB6QEBVAHrAQEjDCMB7AECHhQeAu0BAxoYGgPvAQMWHhYD8QEDFCAU"
"A/MBBBAkEAT0AQUOJw0F9QEGCioKBvcBBggsCAb4AQgFLgUI+QEJATIBCfsBCAIwAgj8AQcFLAUH"
"/QEFCCgIBf4BBAwiDAT/AQIQHBAClwISlwIBPgGAAgI8Av8BAzwD/QEEPAT7AQY6BvkBBzoH+AEI"
"OAj3AQk4CfYBCTgK9AELNgvzAQw2DPIBDDYM8QEONA7wAQ40DvABDjQO7wEPNA/uAQ80D+4BEDIQ"
@@ -1627,7 +1665,19 @@ static void test_path_geometry(void)
"C/QBCzcK9QEJOAn3AQg4CfcBBzoH+QEGOgb7AQU6BfwBBDwE/QEDPAP/AQE+AZkCDpkCAhIYEgKA"
"AgMNIA0D/wEFCSYJBf4BBgYqBgf8AQgDLgMI+wFG+gEIAzADCPkBBwYuBgf3AQYKKgoG9gEFDCgM"
"BfUBBBAlDwTzAQQSIhIE8QEDFh4WA/ABAhkaGQLvAQIcFhwC7QECIBAgAusBASgEKAHpAQFWAecB"
- "AVgB5QEBWgHAAgEA");
+ "AVgB5QEBWgHAAgHhUgAA");
+ todo_wine ok(match, "Figure does not match.\n");
+ match = compare_figure(surface, 160, 160, 320, 160, 0xff652e89, 64,
+ "/VUB5QEBWAHnAQFWAekBAVQB6wECIQ8hAe0BAh0VHQLuAQIZGhkD7wEDFh4WA/EBBBMhEwPzAQQQ"
+ "JQ8F9AEFDCgNBfUBBgoqCgb3AQcHLQcG+QEIBC8ECPkBPAEJ+wEIAy8CCP0BBgYrBQf9AQUJJgkF"
+ "/wEDDSANBP8BAhEaEQKYAhAXAYACAT4BgAICPQL+AQM8BPwBBTsE+wEGOgb6AQc5B/gBCDgJ9gEJ"
+ "OAn2AQo3CvQBCzcK8wEMNgzyAQ01DPIBDTUN8AEONA7wAQ40D+4BDzQP7gEQMw/uARAzEO0BEDIR"
+ "7AERMhHsAREyEewBETIR7AERMhLrAREyEusBETIS6wERMhLrAREyEusBETIS6wERMhHsAREyEewB"
+ "ETIR7QEQMhHtARAzEO0BEDMP7gEPNA/vAQ40D+8BDjQO8QENNQ3xAQ01DPMBCzYM8wELNwr1AQo3"
+ "CvUBCTgJ9wEIOAn4AQc5B/kBBjoG+wEFOwT9AQM8BP4BAj0C/wEBPgGYAhAXAYACAhEaEQKAAgMN"
+ "IA0E/gEFCSYJBf4BBgYrBQf8AQgDLwII+wE8AQn6AQgELwQI+AEHBy0HBvcBBgoqCgb2AQUNJw0F"
+ "9AEEECQQBfIBBBMhEwPxAQMWHhYD8AECGRoZA+4BAh0VHQLsAQIhDiIB6wEBVAHpAQFWAecBAVgB"
+ "wAIBwlYA");
todo_wine ok(match, "Figure does not match.\n");
ID2D1TransformedGeometry_Release(transformed_geometry);
ID2D1PathGeometry_Release(geometry);
@@ -1642,10 +1692,10 @@ static void test_path_geometry(void)
ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
- ok(count == 2, "Got unexpected figure count %u.\n", count);
+ ok(count == 4, "Got unexpected figure count %u.\n", count);
hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
- ok(count == 10, "Got unexpected segment count %u.\n", count);
+ ok(count == 20, "Got unexpected segment count %u.\n", count);
ID2D1GeometrySink_Release(sink);
set_matrix_identity(&matrix);
@@ -1669,6 +1719,13 @@ static void test_path_geometry(void)
"TFRMVEtWSlZKV0hYSFlGWkZbRFxDXkJfQGE+YzxlOmc4aTZrM28wcix2KHojggEaiwEQlAEImAEI"
"mQEGmgEGmgEGmgEGmwEEnAEEnAEEnAEEnAEEnQECngECngECngECngECngECngECngEC");
ok(match, "Figure does not match.\n");
+ match = compare_figure(surface, 0, 226, 160, 160, 0xff652e89, 64,
+ "7xoCngECngECngECngECngECngECngECnQEEnAEEnAEEnAEEnAEEmwEGmgEGmgEGmgEGmQEImAEI"
+ "lAEQiwEagQEjeyh2LHIwbjNsNmk4ZzplPGM+YUBfQl1DXURbRlpGWUhYSFdKVkpVS1VMVExUTFRM"
+ "U05STlJOUk5STlFQUFBQUFBQTlRIXD9mMnYqdjJmP1xIVE5QUFBQUFBQUU5STlJOUk5STlNMVExU"
+ "TFRMVEtWSlZKV0hYSFlGWkZbRFxDXkJfQGE+YzxlOmc4aTZrM28wcix2KHojggEaiwEQlAEImAEI"
+ "mQEGmgEGmgEGmgEGmwEEnAEEnAEEnAEEnAEEnQECngECngECngECngECngECngECngEC");
+ ok(match, "Figure does not match.\n");
match = compare_figure(surface, 160, 0, 320, 160, 0xff652e89, 64,
"4VIBwAIBWgHlAQFYAecBAVYB6QEBVAHrAQIhDiIB7QECHRUdAu4BAhkaGQPvAQMWHhYD8QEEEyET"
"A/MBBBAkEAT1AQUMKA0F9QEGCioKBvcBBwctBwb5AQgELwQI+QEJATIBCfsBRP0BQ/0BQv8BQf8B"
@@ -1678,6 +1735,15 @@ static void test_path_geometry(void)
"RPsBCQEyAQn6AQgELwQI+AEHBy0GB/cBBgoqCgb2AQUMKA0F9AEEECUPBPMBBBIiEwPxAQMWHhYD"
"8AECGRoZA+4BAh0VHQLsAQIhDiIB6wEBVAHpAQFWAecBAVgB5QEBWgHAAgEA");
ok(match, "Figure does not match.\n");
+ match = compare_figure(surface, 160, 160, 320, 160, 0xff652e89, 64,
+ "gVQBXAHjAQFaAeUBAVgB5wEBVgHpAQEpAikB6wECIBAgAu0BAhwWHALvAQIZGhkC8AEDFh4WA/EB"
+ "BBIiEgTzAQQPJRAE9QEFDCgMBfYBBgoqCgb3AQcGLgYH+QEIAzADCPoBRvsBRPwBRP0BQv8BQIAC"
+ "QIECPoECQP8BQv0BRPwBRPsBRvkBSPgBSPcBSvUBTPQBTPMBTvIBTvEBUPABUO8BUu4BUu4BUu4B"
+ "Uu0BVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVO0BUu4BUu4BUu8BUPAB"
+ "UPABUPEBTvIBTvMBTPQBS/YBSvcBSPgBSPkBRvsBRP0BQv8BQIACQIECPoECQP8BQv4BQv0BRPwB"
+ "RPsBCQEyAQn5AQgFLgUI+AEGCCwIBvcBBgoqCgb1AQUNJw4F9AEEECQQBPMBAxQgFAPxAQMWHhYD"
+ "7wEDGhgaA+0BAh4UHgLsAQEjDCMB6wEBVAHpAQFWAecBAVgB5QEBWgGiVQAA");
+ ok(match, "Figure does not match.\n");
ID2D1TransformedGeometry_Release(transformed_geometry);
ID2D1PathGeometry_Release(geometry);
--
2.1.4
More information about the wine-patches
mailing list