d2d1: Introduce a separate structure for fill specific geometry fields.

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Henri Verbeet 2016-12-08 14:31:58 +01:00 committed by Alexandre Julliard
parent ad18f7fe81
commit ad40557103
3 changed files with 72 additions and 73 deletions

View File

@ -311,15 +311,18 @@ struct d2d_geometry
D2D_MATRIX_3X2_F transform;
D2D1_POINT_2F *vertices;
size_t vertex_count;
struct
{
D2D1_POINT_2F *vertices;
size_t vertex_count;
struct d2d_face *faces;
size_t faces_size;
size_t face_count;
struct d2d_face *faces;
size_t faces_size;
size_t face_count;
struct d2d_bezier *beziers;
size_t bezier_count;
struct d2d_bezier *beziers;
size_t bezier_count;
} fill;
union
{

View File

@ -1207,7 +1207,7 @@ static BOOL d2d_path_geometry_point_inside(const struct d2d_geometry *geometry,
return geometry->u.path.fill_mode == D2D1_FILL_MODE_ALTERNATE ? score & 1 : score;
}
static BOOL d2d_path_geometry_add_face(struct d2d_geometry *geometry, const struct d2d_cdt *cdt,
static BOOL d2d_path_geometry_add_fill_face(struct d2d_geometry *geometry, const struct d2d_cdt *cdt,
const struct d2d_cdt_edge_ref *base_edge)
{
struct d2d_cdt_edge_ref tmp;
@ -1217,14 +1217,14 @@ static BOOL d2d_path_geometry_add_face(struct d2d_geometry *geometry, const stru
if (cdt->edges[base_edge->idx].flags & D2D_CDT_EDGE_FLAG_VISITED(base_edge->r))
return TRUE;
if (!d2d_array_reserve((void **)&geometry->faces, &geometry->faces_size,
geometry->face_count + 1, sizeof(*geometry->faces)))
if (!d2d_array_reserve((void **)&geometry->fill.faces, &geometry->fill.faces_size,
geometry->fill.face_count + 1, sizeof(*geometry->fill.faces)))
{
ERR("Failed to grow faces array.\n");
return FALSE;
}
face = &geometry->faces[geometry->face_count];
face = &geometry->fill.faces[geometry->fill.face_count];
/* It may seem tempting to use the center of the face as probe origin, but
* multiplying by powers of two works much better for preserving accuracy. */
@ -1248,7 +1248,7 @@ static BOOL d2d_path_geometry_add_face(struct d2d_geometry *geometry, const stru
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, TRUE))
++geometry->face_count;
++geometry->fill.face_count;
return TRUE;
}
@ -1265,20 +1265,20 @@ static BOOL d2d_cdt_generate_faces(const struct d2d_cdt *cdt, struct d2d_geometr
base_edge.idx = i;
base_edge.r = 0;
if (!d2d_path_geometry_add_face(geometry, cdt, &base_edge))
if (!d2d_path_geometry_add_fill_face(geometry, cdt, &base_edge))
goto fail;
d2d_cdt_edge_sym(&base_edge, &base_edge);
if (!d2d_path_geometry_add_face(geometry, cdt, &base_edge))
if (!d2d_path_geometry_add_fill_face(geometry, cdt, &base_edge))
goto fail;
}
return TRUE;
fail:
HeapFree(GetProcessHeap(), 0, geometry->faces);
geometry->faces = NULL;
geometry->faces_size = 0;
geometry->face_count = 0;
HeapFree(GetProcessHeap(), 0, geometry->fill.faces);
geometry->fill.faces = NULL;
geometry->fill.faces_size = 0;
geometry->fill.face_count = 0;
return FALSE;
}
@ -1423,7 +1423,7 @@ static BOOL d2d_cdt_insert_segments(struct d2d_cdt *cdt, struct d2d_geometry *ge
figure = &geometry->u.path.figures[i];
p = bsearch(&figure->vertices[figure->vertex_count - 1], cdt->vertices,
geometry->vertex_count, sizeof(*p), d2d_cdt_compare_vertices);
geometry->fill.vertex_count, sizeof(*p), d2d_cdt_compare_vertices);
start_vertex = p - cdt->vertices;
for (k = 0, found = FALSE; k < cdt->edge_count; ++k)
@ -1456,7 +1456,7 @@ static BOOL d2d_cdt_insert_segments(struct d2d_cdt *cdt, struct d2d_geometry *ge
for (j = 0; j < figure->vertex_count; start_vertex = end_vertex, ++j)
{
p = bsearch(&figure->vertices[j], cdt->vertices,
geometry->vertex_count, sizeof(*p), d2d_cdt_compare_vertices);
geometry->fill.vertex_count, sizeof(*p), d2d_cdt_compare_vertices);
end_vertex = p - cdt->vertices;
if (start_vertex == end_vertex)
@ -1632,8 +1632,8 @@ static HRESULT d2d_path_geometry_triangulate(struct d2d_geometry *geometry)
}
}
geometry->vertices = vertices;
geometry->vertex_count = vertex_count;
geometry->fill.vertices = vertices;
geometry->fill.vertex_count = vertex_count;
cdt.free_edge = ~0u;
cdt.vertices = vertices;
@ -1648,8 +1648,8 @@ static HRESULT d2d_path_geometry_triangulate(struct d2d_geometry *geometry)
return S_OK;
fail:
geometry->vertices = NULL;
geometry->vertex_count = 0;
geometry->fill.vertices = NULL;
geometry->fill.vertex_count = 0;
HeapFree(GetProcessHeap(), 0, vertices);
HeapFree(GetProcessHeap(), 0, cdt.edges);
return E_FAIL;
@ -1679,9 +1679,9 @@ static BOOL d2d_path_geometry_add_figure(struct d2d_geometry *geometry)
static void d2d_geometry_cleanup(struct d2d_geometry *geometry)
{
HeapFree(GetProcessHeap(), 0, geometry->beziers);
HeapFree(GetProcessHeap(), 0, geometry->faces);
HeapFree(GetProcessHeap(), 0, geometry->vertices);
HeapFree(GetProcessHeap(), 0, geometry->fill.beziers);
HeapFree(GetProcessHeap(), 0, geometry->fill.faces);
HeapFree(GetProcessHeap(), 0, geometry->fill.vertices);
ID2D1Factory_Release(geometry->factory);
}
@ -1900,14 +1900,14 @@ static HRESULT d2d_geometry_resolve_beziers(struct d2d_geometry *geometry)
for (i = 0; i < geometry->u.path.figure_count; ++i)
{
geometry->bezier_count += geometry->u.path.figures[i].bezier_control_count;
geometry->fill.bezier_count += geometry->u.path.figures[i].bezier_control_count;
}
if (!(geometry->beziers = HeapAlloc(GetProcessHeap(), 0,
geometry->bezier_count * sizeof(*geometry->beziers))))
if (!(geometry->fill.beziers = HeapAlloc(GetProcessHeap(), 0,
geometry->fill.bezier_count * sizeof(*geometry->fill.beziers))))
{
ERR("Failed to allocate beziers array.\n");
geometry->bezier_count = 0;
geometry->fill.bezier_count = 0;
return E_OUTOFMEMORY;
}
@ -1924,7 +1924,7 @@ static HRESULT d2d_geometry_resolve_beziers(struct d2d_geometry *geometry)
if (figure->vertex_types[j] != D2D_VERTEX_TYPE_BEZIER)
continue;
b = &geometry->beziers[bezier_idx];
b = &geometry->fill.beziers[bezier_idx];
p0 = &figure->vertices[j];
p1 = &figure->bezier_controls[control_idx++];
if (j == figure->vertex_count - 1)
@ -1990,8 +1990,8 @@ static HRESULT STDMETHODCALLTYPE d2d_geometry_sink_Close(ID2D1GeometrySink *ifac
done:
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, geometry->beziers);
geometry->bezier_count = 0;
HeapFree(GetProcessHeap(), 0, geometry->fill.beziers);
geometry->fill.bezier_count = 0;
d2d_path_geometry_free_figures(geometry);
geometry->u.path.state = D2D_GEOMETRY_STATE_ERROR;
}
@ -2607,34 +2607,35 @@ HRESULT d2d_rectangle_geometry_init(struct d2d_geometry *geometry, ID2D1Factory
d2d_geometry_init(geometry, factory, &identity, (ID2D1GeometryVtbl *)&d2d_rectangle_geometry_vtbl);
geometry->u.rectangle.rect = *rect;
if (!(geometry->vertices = HeapAlloc(GetProcessHeap(), 0, 4 * sizeof(*geometry->vertices))))
if (!(geometry->fill.vertices = HeapAlloc(GetProcessHeap(), 0, 4 * sizeof(*geometry->fill.vertices))))
{
d2d_geometry_cleanup(geometry);
return E_OUTOFMEMORY;
}
geometry->vertex_count = 4;
if (!d2d_array_reserve((void **)&geometry->faces, &geometry->faces_size, 2, sizeof(*geometry->faces)))
geometry->fill.vertex_count = 4;
if (!d2d_array_reserve((void **)&geometry->fill.faces,
&geometry->fill.faces_size, 2, sizeof(*geometry->fill.faces)))
{
d2d_geometry_cleanup(geometry);
return E_OUTOFMEMORY;
}
geometry->face_count = 2;
geometry->fill.face_count = 2;
geometry->vertices[0].x = min(rect->left, rect->right);
geometry->vertices[0].y = min(rect->top, rect->bottom);
geometry->vertices[1].x = min(rect->left, rect->right);
geometry->vertices[1].y = max(rect->top, rect->bottom);
geometry->vertices[2].x = max(rect->left, rect->right);
geometry->vertices[2].y = min(rect->top, rect->bottom);
geometry->vertices[3].x = max(rect->left, rect->right);
geometry->vertices[3].y = max(rect->top, rect->bottom);
geometry->fill.vertices[0].x = min(rect->left, rect->right);
geometry->fill.vertices[0].y = min(rect->top, rect->bottom);
geometry->fill.vertices[1].x = min(rect->left, rect->right);
geometry->fill.vertices[1].y = max(rect->top, rect->bottom);
geometry->fill.vertices[2].x = max(rect->left, rect->right);
geometry->fill.vertices[2].y = min(rect->top, rect->bottom);
geometry->fill.vertices[3].x = max(rect->left, rect->right);
geometry->fill.vertices[3].y = max(rect->top, rect->bottom);
geometry->faces[0].v[0] = 0;
geometry->faces[0].v[1] = 2;
geometry->faces[0].v[2] = 1;
geometry->faces[1].v[0] = 1;
geometry->faces[1].v[1] = 2;
geometry->faces[1].v[2] = 3;
geometry->fill.faces[0].v[0] = 0;
geometry->fill.faces[0].v[1] = 2;
geometry->fill.faces[0].v[2] = 1;
geometry->fill.faces[1].v[0] = 1;
geometry->fill.faces[1].v[1] = 2;
geometry->fill.faces[1].v[2] = 3;
return S_OK;
}
@ -2684,9 +2685,9 @@ static ULONG STDMETHODCALLTYPE d2d_transformed_geometry_Release(ID2D1Transformed
if (!refcount)
{
geometry->beziers = NULL;
geometry->faces = NULL;
geometry->vertices = NULL;
geometry->fill.beziers = NULL;
geometry->fill.faces = NULL;
geometry->fill.vertices = NULL;
ID2D1Geometry_Release(geometry->u.transformed.src_geometry);
d2d_geometry_cleanup(geometry);
HeapFree(GetProcessHeap(), 0, geometry);
@ -2890,12 +2891,7 @@ void d2d_transformed_geometry_init(struct d2d_geometry *geometry, ID2D1Factory *
d2d_geometry_init(geometry, factory, transform, (ID2D1GeometryVtbl *)&d2d_transformed_geometry_vtbl);
ID2D1Geometry_AddRef(geometry->u.transformed.src_geometry = src_geometry);
src_impl = unsafe_impl_from_ID2D1Geometry(src_geometry);
geometry->vertices = src_impl->vertices;
geometry->vertex_count = src_impl->vertex_count;
geometry->faces = src_impl->faces;
geometry->face_count = src_impl->face_count;
geometry->beziers = src_impl->beziers;
geometry->bezier_count = src_impl->bezier_count;
geometry->fill = src_impl->fill;
}
struct d2d_geometry *unsafe_impl_from_ID2D1Geometry(ID2D1Geometry *iface)

View File

@ -687,11 +687,11 @@ static void d2d_rt_fill_geometry(struct d2d_d3d_render_target *render_target,
return;
}
if (geometry->face_count)
if (geometry->fill.face_count)
{
buffer_desc.ByteWidth = geometry->face_count * sizeof(*geometry->faces);
buffer_desc.ByteWidth = geometry->fill.face_count * sizeof(*geometry->fill.faces);
buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
buffer_data.pSysMem = geometry->faces;
buffer_data.pSysMem = geometry->fill.faces;
if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &ib)))
{
@ -699,9 +699,9 @@ static void d2d_rt_fill_geometry(struct d2d_d3d_render_target *render_target,
goto done;
}
buffer_desc.ByteWidth = geometry->vertex_count * sizeof(*geometry->vertices);
buffer_desc.ByteWidth = geometry->fill.vertex_count * sizeof(*geometry->fill.vertices);
buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
buffer_data.pSysMem = geometry->vertices;
buffer_data.pSysMem = geometry->fill.vertices;
if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &vb)))
{
@ -710,17 +710,17 @@ static void d2d_rt_fill_geometry(struct d2d_d3d_render_target *render_target,
goto done;
}
d2d_rt_draw(render_target, D2D_SHAPE_TYPE_TRIANGLE, ib, 3 * geometry->face_count, vb,
sizeof(*geometry->vertices), vs_cb, ps_cb, brush, opacity_brush);
d2d_rt_draw(render_target, D2D_SHAPE_TYPE_TRIANGLE, ib, 3 * geometry->fill.face_count, vb,
sizeof(*geometry->fill.vertices), vs_cb, ps_cb, brush, opacity_brush);
ID3D10Buffer_Release(vb);
ID3D10Buffer_Release(ib);
}
if (geometry->bezier_count)
if (geometry->fill.bezier_count)
{
buffer_desc.ByteWidth = geometry->bezier_count * sizeof(*geometry->beziers);
buffer_data.pSysMem = geometry->beziers;
buffer_desc.ByteWidth = geometry->fill.bezier_count * sizeof(*geometry->fill.beziers);
buffer_data.pSysMem = geometry->fill.beziers;
if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &vb)))
{
@ -728,8 +728,8 @@ static void d2d_rt_fill_geometry(struct d2d_d3d_render_target *render_target,
goto done;
}
d2d_rt_draw(render_target, D2D_SHAPE_TYPE_BEZIER, NULL, 3 * geometry->bezier_count, vb,
sizeof(*geometry->beziers->v), vs_cb, ps_cb, brush, opacity_brush);
d2d_rt_draw(render_target, D2D_SHAPE_TYPE_BEZIER, NULL, 3 * geometry->fill.bezier_count, vb,
sizeof(*geometry->fill.beziers->v), vs_cb, ps_cb, brush, opacity_brush);
ID3D10Buffer_Release(vb);
}