d2d1: Properly test which side of a bezier curve is the inside.
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3d51a7164b
commit
e9fc8c7c52
|
@ -46,15 +46,24 @@ enum d2d_cdt_edge_next
|
||||||
D2D_EDGE_NEXT_TOR = 3,
|
D2D_EDGE_NEXT_TOR = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum d2d_vertex_type
|
||||||
|
{
|
||||||
|
D2D_VERTEX_TYPE_NONE,
|
||||||
|
D2D_VERTEX_TYPE_LINE,
|
||||||
|
D2D_VERTEX_TYPE_BEZIER,
|
||||||
|
};
|
||||||
|
|
||||||
struct d2d_figure
|
struct d2d_figure
|
||||||
{
|
{
|
||||||
D2D1_POINT_2F *vertices;
|
D2D1_POINT_2F *vertices;
|
||||||
size_t vertices_size;
|
size_t vertices_size;
|
||||||
|
enum d2d_vertex_type *vertex_types;
|
||||||
|
size_t vertex_types_size;
|
||||||
size_t vertex_count;
|
size_t vertex_count;
|
||||||
|
|
||||||
struct d2d_bezier *beziers;
|
D2D1_POINT_2F *bezier_controls;
|
||||||
size_t beziers_size;
|
size_t bezier_controls_size;
|
||||||
size_t bezier_count;
|
size_t bezier_control_count;
|
||||||
|
|
||||||
D2D1_RECT_F bounds;
|
D2D1_RECT_F bounds;
|
||||||
};
|
};
|
||||||
|
@ -460,9 +469,19 @@ static BOOL d2d_figure_insert_vertex(struct d2d_figure *figure, size_t idx, D2D1
|
||||||
return FALSE;
|
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],
|
memmove(&figure->vertices[idx + 1], &figure->vertices[idx],
|
||||||
(figure->vertex_count - idx) * sizeof(*figure->vertices));
|
(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->vertices[idx] = vertex;
|
||||||
|
figure->vertex_types[idx] = D2D_VERTEX_TYPE_NONE;
|
||||||
d2d_figure_update_bounds(figure, vertex);
|
d2d_figure_update_bounds(figure, vertex);
|
||||||
++figure->vertex_count;
|
++figure->vertex_count;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -477,58 +496,31 @@ static BOOL d2d_figure_add_vertex(struct d2d_figure *figure, D2D1_POINT_2F verte
|
||||||
return FALSE;
|
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->vertices[figure->vertex_count] = vertex;
|
||||||
|
figure->vertex_types[figure->vertex_count] = D2D_VERTEX_TYPE_NONE;
|
||||||
d2d_figure_update_bounds(figure, vertex);
|
d2d_figure_update_bounds(figure, vertex);
|
||||||
++figure->vertex_count;
|
++figure->vertex_count;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: No inside/outside testing is done for beziers. */
|
static BOOL d2d_figure_add_bezier_control(struct d2d_figure *figure, const D2D1_POINT_2F *p)
|
||||||
static BOOL d2d_figure_add_bezier(struct d2d_figure *figure, D2D1_POINT_2F p0, D2D1_POINT_2F p1, D2D1_POINT_2F p2)
|
|
||||||
{
|
{
|
||||||
struct d2d_bezier *b;
|
if (!d2d_array_reserve((void **)&figure->bezier_controls, &figure->bezier_controls_size,
|
||||||
unsigned int idx1, idx2;
|
figure->bezier_control_count + 1, sizeof(*figure->bezier_controls)))
|
||||||
float sign;
|
|
||||||
|
|
||||||
if (!d2d_array_reserve((void **)&figure->beziers, &figure->beziers_size,
|
|
||||||
figure->bezier_count + 1, sizeof(*figure->beziers)))
|
|
||||||
{
|
{
|
||||||
ERR("Failed to grow beziers array.\n");
|
ERR("Failed to grow bezier controls array.\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d2d_point_ccw(&p0, &p1, &p2) > 0.0f)
|
figure->bezier_controls[figure->bezier_control_count++] = *p;
|
||||||
{
|
|
||||||
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;
|
|
||||||
return TRUE;
|
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
|
/* Determine whether a given point is inside the geometry, using the current
|
||||||
* fill mode rule. */
|
* 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;
|
const D2D1_POINT_2F *p0, *p1;
|
||||||
D2D1_POINT_2F v_p, v_probe;
|
D2D1_POINT_2F v_p, v_probe;
|
||||||
|
@ -1190,8 +1183,11 @@ static BOOL d2d_path_geometry_point_inside(const struct d2d_geometry *geometry,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
p0 = &figure->vertices[figure->vertex_count - 1];
|
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];
|
p1 = &figure->vertices[j];
|
||||||
d2d_point_subtract(&v_p, p1, p0);
|
d2d_point_subtract(&v_p, p1, p0);
|
||||||
d2d_point_subtract(&v_probe, probe, 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
|
else
|
||||||
--score;
|
--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.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;
|
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;
|
++geometry->face_count;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1791,6 +1789,7 @@ static void STDMETHODCALLTYPE d2d_geometry_sink_AddLines(ID2D1GeometrySink *ifac
|
||||||
const D2D1_POINT_2F *points, UINT32 count)
|
const D2D1_POINT_2F *points, UINT32 count)
|
||||||
{
|
{
|
||||||
struct d2d_geometry *geometry = impl_from_ID2D1GeometrySink(iface);
|
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;
|
unsigned int i;
|
||||||
|
|
||||||
TRACE("iface %p, points %p, count %u.\n", iface, points, count);
|
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)
|
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");
|
ERR("Failed to add vertex.\n");
|
||||||
return;
|
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.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.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;
|
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;
|
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)
|
static void STDMETHODCALLTYPE d2d_geometry_sink_EndFigure(ID2D1GeometrySink *iface, D2D1_FIGURE_END figure_end)
|
||||||
{
|
{
|
||||||
struct d2d_geometry *geometry = impl_from_ID2D1GeometrySink(iface);
|
struct d2d_geometry *geometry = impl_from_ID2D1GeometrySink(iface);
|
||||||
|
struct d2d_figure *figure;
|
||||||
|
|
||||||
TRACE("iface %p, figure_end %#x.\n", iface, figure_end);
|
TRACE("iface %p, figure_end %#x.\n", iface, figure_end);
|
||||||
|
|
||||||
|
@ -1858,6 +1869,8 @@ static void STDMETHODCALLTYPE d2d_geometry_sink_EndFigure(ID2D1GeometrySink *ifa
|
||||||
return;
|
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)
|
if (figure_end != D2D1_FIGURE_END_CLOSED)
|
||||||
FIXME("Ignoring figure_end %#x.\n", figure_end);
|
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)
|
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[i].vertices);
|
||||||
}
|
}
|
||||||
HeapFree(GetProcessHeap(), 0, geometry->u.path.figures);
|
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;
|
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)
|
static HRESULT STDMETHODCALLTYPE d2d_geometry_sink_Close(ID2D1GeometrySink *iface)
|
||||||
{
|
{
|
||||||
struct d2d_geometry *geometry = impl_from_ID2D1GeometrySink(iface);
|
struct d2d_geometry *geometry = impl_from_ID2D1GeometrySink(iface);
|
||||||
HRESULT hr = E_FAIL;
|
HRESULT hr = E_FAIL;
|
||||||
size_t i, start;
|
|
||||||
|
|
||||||
TRACE("iface %p.\n", iface);
|
TRACE("iface %p.\n", iface);
|
||||||
|
|
||||||
|
@ -1899,37 +1982,16 @@ static HRESULT STDMETHODCALLTYPE d2d_geometry_sink_Close(ID2D1GeometrySink *ifac
|
||||||
|
|
||||||
if (!d2d_geometry_intersect_self(geometry))
|
if (!d2d_geometry_intersect_self(geometry))
|
||||||
goto done;
|
goto done;
|
||||||
|
if (FAILED(hr = d2d_geometry_resolve_beziers(geometry)))
|
||||||
|
goto done;
|
||||||
if (FAILED(hr = d2d_path_geometry_triangulate(geometry)))
|
if (FAILED(hr = d2d_path_geometry_triangulate(geometry)))
|
||||||
goto done;
|
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;
|
|
||||||
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:
|
done:
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, geometry->beziers);
|
||||||
|
geometry->bezier_count = 0;
|
||||||
d2d_path_geometry_free_figures(geometry);
|
d2d_path_geometry_free_figures(geometry);
|
||||||
geometry->u.path.state = D2D_GEOMETRY_STATE_ERROR;
|
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)
|
for (i = 0; i < bezier_count; ++i)
|
||||||
{
|
{
|
||||||
if (!d2d_figure_add_bezier(figure, figure->vertices[figure->vertex_count - 1],
|
figure->vertex_types[figure->vertex_count - 1] = D2D_VERTEX_TYPE_BEZIER;
|
||||||
beziers[i].point1, beziers[i].point2))
|
if (!d2d_figure_add_bezier_control(figure, &beziers[i].point1))
|
||||||
{
|
{
|
||||||
ERR("Failed to add bezier.\n");
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2131,7 +2201,7 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_FillContainsPoint(ID2D1PathGe
|
||||||
d2d_point_transform(&point, &g_i, point.x, point.y);
|
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);
|
TRACE("-> %#x.\n", *contains);
|
||||||
|
|
||||||
|
|
|
@ -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,
|
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)
|
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_size = 64;
|
||||||
figure.spans = HeapAlloc(GetProcessHeap(), 0, figure.spans_size * sizeof(*figure.spans));
|
figure.spans = HeapAlloc(GetProcessHeap(), 0, figure.spans_size * sizeof(*figure.spans));
|
||||||
|
|
||||||
for (i = 0, span = 0; i < h; ++i)
|
read_figure(&figure, mapped_texture.pData, mapped_texture.RowPitch, x, y, w, h, prev);
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
deserialize_figure(&ref_figure, (BYTE *)ref);
|
deserialize_figure(&ref_figure, (BYTE *)ref);
|
||||||
span = w * h;
|
span = w * h;
|
||||||
|
@ -449,7 +458,10 @@ static BOOL compare_figure(IDXGISurface *surface, unsigned int x, unsigned int y
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (diff > max_diff)
|
if (diff > max_diff)
|
||||||
|
{
|
||||||
|
read_figure(&figure, mapped_texture.pData, mapped_texture.RowPitch, x, y, w, h, prev);
|
||||||
serialize_figure(&figure);
|
serialize_figure(&figure);
|
||||||
|
}
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, ref_figure.spans);
|
HeapFree(GetProcessHeap(), 0, ref_figure.spans);
|
||||||
HeapFree(GetProcessHeap(), 0, 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, 60.0f, 240.0f, 40.0f, 240.0f);
|
||||||
quadratic_to(sink, 20.0f, 240.0f, 20.0f, 160.0f);
|
quadratic_to(sink, 20.0f, 240.0f, 20.0f, 160.0f);
|
||||||
ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
|
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)
|
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);
|
ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
|
||||||
hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
|
hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
|
||||||
ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
|
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);
|
hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
|
||||||
ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
|
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);
|
ID2D1GeometrySink_Release(sink);
|
||||||
|
|
||||||
set_matrix_identity(&matrix);
|
set_matrix_identity(&matrix);
|
||||||
scale_matrix(&matrix, 0.5f, 2.0f);
|
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);
|
rotate_matrix(&matrix, M_PI / 4.0f);
|
||||||
scale_matrix(&matrix, 2.0f, 0.5f);
|
scale_matrix(&matrix, 2.0f, 0.5f);
|
||||||
hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
|
hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
|
||||||
|
@ -1617,8 +1645,18 @@ static void test_path_geometry(void)
|
||||||
"EBVnFBAUaRQOFGsTDhJvEgwSchAMEHYPCg96DQoMggEICgiLAQQIBJQBCJgBCJkBBpoBBpoBBpoB"
|
"EBVnFBAUaRQOFGsTDhJvEgwSchAMEHYPCg96DQoMggEICgiLAQQIBJQBCJgBCJkBBpoBBpoBBpoB"
|
||||||
"BpsBBJwBBJwBBJwBBJwBBJ0BAp4BAp4BAp4BAp4BAp4BAp4BAp4BAgAA");
|
"BpsBBJwBBJwBBJwBBJwBBJ0BAp4BAp4BAp4BAp4BAp4BAp4BAp4BAgAA");
|
||||||
todo_wine ok(match, "Figure does not match.\n");
|
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,
|
match = compare_figure(surface, 160, 0, 320, 160, 0xff652e89, 64,
|
||||||
"4VIBwAIBWgHlAQFYAecBAVYB6QEBVAHrAQEjDCMB7AECHhQeAu0BAxoYGgPvAQMWHhYD8QEDFCAU"
|
"gVQBwAIBWgHlAQFYAecBAVYB6QEBVAHrAQEjDCMB7AECHhQeAu0BAxoYGgPvAQMWHhYD8QEDFCAU"
|
||||||
"A/MBBBAkEAT0AQUOJw0F9QEGCioKBvcBBggsCAb4AQgFLgUI+QEJATIBCfsBCAIwAgj8AQcFLAUH"
|
"A/MBBBAkEAT0AQUOJw0F9QEGCioKBvcBBggsCAb4AQgFLgUI+QEJATIBCfsBCAIwAgj8AQcFLAUH"
|
||||||
"/QEFCCgIBf4BBAwiDAT/AQIQHBAClwISlwIBPgGAAgI8Av8BAzwD/QEEPAT7AQY6BvkBBzoH+AEI"
|
"/QEFCCgIBf4BBAwiDAT/AQIQHBAClwISlwIBPgGAAgI8Av8BAzwD/QEEPAT7AQY6BvkBBzoH+AEI"
|
||||||
"OAj3AQk4CfYBCTgK9AELNgvzAQw2DPIBDDYM8QEONA7wAQ40DvABDjQO7wEPNA/uAQ80D+4BEDIQ"
|
"OAj3AQk4CfYBCTgK9AELNgvzAQw2DPIBDDYM8QEONA7wAQ40DvABDjQO7wEPNA/uAQ80D+4BEDIQ"
|
||||||
|
@ -1627,7 +1665,19 @@ static void test_path_geometry(void)
|
||||||
"C/QBCzcK9QEJOAn3AQg4CfcBBzoH+QEGOgb7AQU6BfwBBDwE/QEDPAP/AQE+AZkCDpkCAhIYEgKA"
|
"C/QBCzcK9QEJOAn3AQg4CfcBBzoH+QEGOgb7AQU6BfwBBDwE/QEDPAP/AQE+AZkCDpkCAhIYEgKA"
|
||||||
"AgMNIA0D/wEFCSYJBf4BBgYqBgf8AQgDLgMI+wFG+gEIAzADCPkBBwYuBgf3AQYKKgoG9gEFDCgM"
|
"AgMNIA0D/wEFCSYJBf4BBgYqBgf8AQgDLgMI+wFG+gEIAzADCPkBBwYuBgf3AQYKKgoG9gEFDCgM"
|
||||||
"BfUBBBAlDwTzAQQSIhIE8QEDFh4WA/ABAhkaGQLvAQIcFhwC7QECIBAgAusBASgEKAHpAQFWAecB"
|
"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");
|
todo_wine ok(match, "Figure does not match.\n");
|
||||||
ID2D1TransformedGeometry_Release(transformed_geometry);
|
ID2D1TransformedGeometry_Release(transformed_geometry);
|
||||||
ID2D1PathGeometry_Release(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);
|
ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
|
||||||
hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
|
hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
|
||||||
ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
|
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);
|
hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
|
||||||
ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
|
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);
|
ID2D1GeometrySink_Release(sink);
|
||||||
|
|
||||||
set_matrix_identity(&matrix);
|
set_matrix_identity(&matrix);
|
||||||
|
@ -1669,6 +1719,13 @@ static void test_path_geometry(void)
|
||||||
"TFRMVEtWSlZKV0hYSFlGWkZbRFxDXkJfQGE+YzxlOmc4aTZrM28wcix2KHojggEaiwEQlAEImAEI"
|
"TFRMVEtWSlZKV0hYSFlGWkZbRFxDXkJfQGE+YzxlOmc4aTZrM28wcix2KHojggEaiwEQlAEImAEI"
|
||||||
"mQEGmgEGmgEGmgEGmwEEnAEEnAEEnAEEnAEEnQECngECngECngECngECngECngECngEC");
|
"mQEGmgEGmgEGmgEGmwEEnAEEnAEEnAEEnAEEnQECngECngECngECngECngECngECngEC");
|
||||||
ok(match, "Figure does not match.\n");
|
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,
|
match = compare_figure(surface, 160, 0, 320, 160, 0xff652e89, 64,
|
||||||
"4VIBwAIBWgHlAQFYAecBAVYB6QEBVAHrAQIhDiIB7QECHRUdAu4BAhkaGQPvAQMWHhYD8QEEEyET"
|
"4VIBwAIBWgHlAQFYAecBAVYB6QEBVAHrAQIhDiIB7QECHRUdAu4BAhkaGQPvAQMWHhYD8QEEEyET"
|
||||||
"A/MBBBAkEAT1AQUMKA0F9QEGCioKBvcBBwctBwb5AQgELwQI+QEJATIBCfsBRP0BQ/0BQv8BQf8B"
|
"A/MBBBAkEAT1AQUMKA0F9QEGCioKBvcBBwctBwb5AQgELwQI+QEJATIBCfsBRP0BQ/0BQv8BQf8B"
|
||||||
|
@ -1678,6 +1735,15 @@ static void test_path_geometry(void)
|
||||||
"RPsBCQEyAQn6AQgELwQI+AEHBy0GB/cBBgoqCgb2AQUMKA0F9AEEECUPBPMBBBIiEwPxAQMWHhYD"
|
"RPsBCQEyAQn6AQgELwQI+AEHBy0GB/cBBgoqCgb2AQUMKA0F9AEEECUPBPMBBBIiEwPxAQMWHhYD"
|
||||||
"8AECGRoZA+4BAh0VHQLsAQIhDiIB6wEBVAHpAQFWAecBAVgB5QEBWgHAAgEA");
|
"8AECGRoZA+4BAh0VHQLsAQIhDiIB6wEBVAHpAQFWAecBAVgB5QEBWgHAAgEA");
|
||||||
ok(match, "Figure does not match.\n");
|
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);
|
ID2D1TransformedGeometry_Release(transformed_geometry);
|
||||||
ID2D1PathGeometry_Release(geometry);
|
ID2D1PathGeometry_Release(geometry);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue