d2d1: Check the vertex count again after duplicate removal in d2d_path_geometry_triangulate().

As the test shows, we can create geometries that have less than two vertices
after eliminating duplicates. Calling d2d_cdt_triangulate() on those would
lead to infinite recursion. In principle we could now get rid of the original
vertex count check, but it seems cheap enough that it's worth keeping in order
to avoid some unnecessary work in the somewhat more common case that we have
less than three vertices before duplicate removal.

Based on a patch by Changsheng Chen.

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Henri Verbeet 2021-09-16 16:01:51 +02:00 committed by Alexandre Julliard
parent c33618ffdd
commit 8718a23b2e
2 changed files with 29 additions and 0 deletions

View file

@ -2061,6 +2061,13 @@ static HRESULT d2d_path_geometry_triangulate(struct d2d_geometry *geometry)
}
}
if (vertex_count < 3)
{
WARN("Geometry has %lu vertices after eliminating duplicates.\n", (long)vertex_count);
heap_free(vertices);
return S_OK;
}
geometry->fill.vertices = vertices;
geometry->fill.vertex_count = vertex_count;

View file

@ -3268,6 +3268,28 @@ static void test_path_geometry(BOOL d3d11)
ID2D1PathGeometry_Release(geometry);
/* Degenerate figure. */
hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
hr = ID2D1PathGeometry_Open(geometry, &sink);
ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
set_point(&point, 123.0f, 456.0f);
ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
quadratic_to(sink, 123.0f, 456.0f, 123.0f, 456.0f);
quadratic_to(sink, 123.0f, 456.0f, 123.0f, 456.0f);
quadratic_to(sink, 123.0f, 456.0f, 123.0f, 456.0f);
ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
hr = ID2D1GeometrySink_Close(sink);
ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
ID2D1GeometrySink_Release(sink);
hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
ok(count == 1, "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 == 4, "Got unexpected segment count %u.\n", count);
ID2D1PathGeometry_Release(geometry);
/* Close right after Open(). */
hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);