From: Philipp Knechtges philipp-dev@knechtges.com
Drawing of ID2D1GeometryGroup was so far unimplemented and resulted in blank drawing buffers. This partially fixes the rendering issues mentioned in the bug below.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51139 --- dlls/d2d1/geometry.c | 236 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 235 insertions(+), 1 deletion(-)
diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c index 3da3ad2e65b..93925408077 100644 --- a/dlls/d2d1/geometry.c +++ b/dlls/d2d1/geometry.c @@ -5497,8 +5497,13 @@ static const struct ID2D1GeometryGroupVtbl d2d_geometry_group_vtbl = HRESULT d2d_geometry_group_init(struct d2d_geometry *geometry, ID2D1Factory *factory, D2D1_FILL_MODE fill_mode, ID2D1Geometry **geometries, unsigned int geometry_count) { - unsigned int i; + unsigned int i, j; + struct d2d_geometry *other_geom; + D2D_MATRIX_3X2_F g, gplain; + size_t f_vertex_count, f_face_count, f_bezier_vertex_count, f_arc_vertex_count; + size_t o_vertex_count, o_face_count, o_bezier_count, o_bezier_face_count, o_arc_count, o_arc_face_count;
+ FIXME("Ignoring fill_mode=%#x!\n", fill_mode); d2d_geometry_init(geometry, factory, &identity, (ID2D1GeometryVtbl *)&d2d_geometry_group_vtbl);
if (!(geometry->u.group.src_geometries = calloc(geometry_count, sizeof(*geometries)))) @@ -5507,13 +5512,242 @@ HRESULT d2d_geometry_group_init(struct d2d_geometry *geometry, ID2D1Factory *fac return E_OUTOFMEMORY; }
+ geometry->fill.vertex_count = 0; + geometry->fill.face_count = 0; + geometry->fill.bezier_vertex_count = 0; + geometry->fill.arc_vertex_count = 0; + geometry->outline.vertex_count = 0; + geometry->outline.face_count = 0; + geometry->outline.bezier_count = 0; + geometry->outline.bezier_face_count = 0; + geometry->outline.arc_count = 0; + geometry->outline.arc_face_count = 0; for (i = 0; i < geometry_count; ++i) { ID2D1Geometry_AddRef(geometry->u.group.src_geometries[i] = geometries[i]); + other_geom = unsafe_impl_from_ID2D1Geometry(geometries[i]); + geometry->fill.vertex_count += other_geom->fill.vertex_count; + geometry->fill.face_count += other_geom->fill.face_count; + geometry->fill.bezier_vertex_count += other_geom->fill.bezier_vertex_count; + geometry->fill.arc_vertex_count += other_geom->fill.arc_vertex_count; + geometry->outline.vertex_count += other_geom->outline.vertex_count; + geometry->outline.face_count += other_geom->outline.face_count; + geometry->outline.bezier_count += other_geom->outline.bezier_count; + geometry->outline.bezier_face_count += other_geom->outline.bezier_face_count; + geometry->outline.arc_count += other_geom->outline.arc_count; + geometry->outline.arc_face_count += other_geom->outline.arc_face_count; } geometry->u.group.geometry_count = geometry_count; geometry->u.group.fill_mode = fill_mode;
+ if (!(geometry->fill.vertices = calloc(geometry->fill.vertex_count, sizeof(D2D1_POINT_2F)))) + { + for (i = 0; i < geometry->u.group.geometry_count; ++i) + ID2D1Geometry_Release(geometry->u.group.src_geometries[i]); + d2d_geometry_cleanup(geometry); + return E_OUTOFMEMORY; + } + if (!(geometry->fill.faces = calloc(geometry->fill.face_count, sizeof(struct d2d_face)))) + { + for (i = 0; i < geometry->u.group.geometry_count; ++i) + ID2D1Geometry_Release(geometry->u.group.src_geometries[i]); + d2d_geometry_cleanup(geometry); + return E_OUTOFMEMORY; + } + geometry->fill.faces_size = geometry->fill.face_count; + if (!(geometry->fill.bezier_vertices = calloc(geometry->fill.bezier_vertex_count, sizeof(struct d2d_curve_vertex)))) + { + for (i = 0; i < geometry->u.group.geometry_count; ++i) + ID2D1Geometry_Release(geometry->u.group.src_geometries[i]); + d2d_geometry_cleanup(geometry); + return E_OUTOFMEMORY; + } + geometry->fill.bezier_vertices_size = geometry->fill.bezier_vertex_count; + if (!(geometry->fill.arc_vertices = calloc(geometry->fill.arc_vertex_count, sizeof(struct d2d_curve_vertex)))) + { + for (i = 0; i < geometry->u.group.geometry_count; ++i) + ID2D1Geometry_Release(geometry->u.group.src_geometries[i]); + d2d_geometry_cleanup(geometry); + return E_OUTOFMEMORY; + } + geometry->fill.arc_vertices_size = geometry->fill.arc_vertex_count; + if (!(geometry->outline.vertices = calloc(geometry->outline.vertex_count, sizeof(struct d2d_outline_vertex)))) + { + for (i = 0; i < geometry->u.group.geometry_count; ++i) + ID2D1Geometry_Release(geometry->u.group.src_geometries[i]); + d2d_geometry_cleanup(geometry); + return E_OUTOFMEMORY; + } + geometry->outline.vertices_size = geometry->outline.vertex_count; + if (!(geometry->outline.faces = calloc(geometry->outline.face_count, sizeof(struct d2d_face)))) + { + for (i = 0; i < geometry->u.group.geometry_count; ++i) + ID2D1Geometry_Release(geometry->u.group.src_geometries[i]); + d2d_geometry_cleanup(geometry); + return E_OUTOFMEMORY; + } + geometry->outline.faces_size = geometry->outline.face_count; + if (!(geometry->outline.beziers = calloc(geometry->outline.bezier_count, sizeof(struct d2d_curve_outline_vertex)))) + { + for (i = 0; i < geometry->u.group.geometry_count; ++i) + ID2D1Geometry_Release(geometry->u.group.src_geometries[i]); + d2d_geometry_cleanup(geometry); + return E_OUTOFMEMORY; + } + geometry->outline.beziers_size = geometry->outline.bezier_count; + if (!(geometry->outline.bezier_faces = calloc(geometry->outline.bezier_face_count, sizeof(struct d2d_face)))) + { + for (i = 0; i < geometry->u.group.geometry_count; ++i) + ID2D1Geometry_Release(geometry->u.group.src_geometries[i]); + d2d_geometry_cleanup(geometry); + return E_OUTOFMEMORY; + } + geometry->outline.bezier_faces_size = geometry->outline.bezier_face_count; + if (!(geometry->outline.arcs = calloc(geometry->outline.arc_count, sizeof(struct d2d_curve_outline_vertex)))) + { + for (i = 0; i < geometry->u.group.geometry_count; ++i) + ID2D1Geometry_Release(geometry->u.group.src_geometries[i]); + d2d_geometry_cleanup(geometry); + return E_OUTOFMEMORY; + } + geometry->outline.arcs_size = geometry->outline.arc_count; + if (!(geometry->outline.arc_faces = calloc(geometry->outline.arc_face_count, sizeof(struct d2d_face)))) + { + for (i = 0; i < geometry->u.group.geometry_count; ++i) + ID2D1Geometry_Release(geometry->u.group.src_geometries[i]); + d2d_geometry_cleanup(geometry); + return E_OUTOFMEMORY; + } + geometry->outline.arc_faces_size = geometry->outline.arc_face_count; + + f_vertex_count = 0; + f_face_count = 0; + f_bezier_vertex_count = 0; + f_arc_vertex_count = 0; + o_vertex_count = 0; + o_face_count = 0; + o_bezier_count = 0; + o_bezier_face_count = 0; + o_arc_count = 0; + o_arc_face_count = 0; + for (i = 0; i < geometry_count; ++i) + { + other_geom = unsafe_impl_from_ID2D1Geometry(geometries[i]); + g = other_geom->transform; + gplain = g; + gplain.dx = 0.0f; + gplain.dy = 0.0f; + + for (j = 0; j < other_geom->fill.vertex_count; ++j) { + d2d_point_transform(&geometry->fill.vertices[j+f_vertex_count], &g, + other_geom->fill.vertices[j].x, other_geom->fill.vertices[j].y); + } + for (j = 0; j < other_geom->fill.face_count; ++j) { + geometry->fill.faces[f_face_count+j].v[0] = other_geom->fill.faces[j].v[0] + + (UINT16) f_vertex_count; + geometry->fill.faces[f_face_count+j].v[1] = other_geom->fill.faces[j].v[1] + + (UINT16) f_vertex_count; + geometry->fill.faces[f_face_count+j].v[2] = other_geom->fill.faces[j].v[2] + + (UINT16) f_vertex_count; + } + f_vertex_count += other_geom->fill.vertex_count; + f_face_count += other_geom->fill.face_count; + + for (j = 0; j < other_geom->fill.bezier_vertex_count; ++j) { + d2d_point_transform(&geometry->fill.bezier_vertices[j+f_bezier_vertex_count].position, + &g, other_geom->fill.bezier_vertices[j].position.x, + other_geom->fill.bezier_vertices[j].position.y); + geometry->fill.bezier_vertices[j+f_bezier_vertex_count].texcoord + = other_geom->fill.bezier_vertices[j].texcoord; + } + f_bezier_vertex_count += other_geom->fill.bezier_vertex_count; + + for (j = 0; j < other_geom->fill.arc_vertex_count; ++j) { + d2d_point_transform(&geometry->fill.arc_vertices[j+f_arc_vertex_count].position, + &g, other_geom->fill.arc_vertices[j].position.x, + other_geom->fill.arc_vertices[j].position.y); + geometry->fill.arc_vertices[j+f_arc_vertex_count].texcoord + = other_geom->fill.arc_vertices[j].texcoord; + + } + f_arc_vertex_count += other_geom->fill.arc_vertex_count; + + for (j = 0; j < other_geom->outline.vertex_count; ++j) { + d2d_point_transform(&geometry->outline.vertices[j+o_vertex_count].position, &g, + other_geom->outline.vertices[j].position.x, other_geom->outline.vertices[j].position.y); + d2d_point_transform(&geometry->outline.vertices[j+o_vertex_count].prev, &gplain, + other_geom->outline.vertices[j].prev.x, other_geom->outline.vertices[j].prev.y); + d2d_point_normalise(&geometry->outline.vertices[j+o_vertex_count].prev); + d2d_point_transform(&geometry->outline.vertices[j+o_vertex_count].next, &gplain, + other_geom->outline.vertices[j].next.x, other_geom->outline.vertices[j].next.y); + d2d_point_normalise(&geometry->outline.vertices[j+o_vertex_count].next); + } + for (j = 0; j < other_geom->outline.face_count; ++j) { + geometry->outline.faces[o_face_count+j].v[0] = other_geom->outline.faces[j].v[0] + + (UINT16) o_vertex_count; + geometry->outline.faces[o_face_count+j].v[1] = other_geom->outline.faces[j].v[1] + + (UINT16) o_vertex_count; + geometry->outline.faces[o_face_count+j].v[2] = other_geom->outline.faces[j].v[2] + + (UINT16) o_vertex_count; + } + o_vertex_count += other_geom->outline.vertex_count; + o_face_count += other_geom->outline.face_count; + + for (j = 0; j < other_geom->outline.bezier_count; ++j) { + d2d_point_transform(&geometry->outline.beziers[j+o_bezier_count].position, &g, + other_geom->outline.beziers[j].position.x, other_geom->outline.beziers[j].position.y); + d2d_point_transform(&geometry->outline.beziers[j+o_bezier_count].prev, &gplain, + other_geom->outline.beziers[j].prev.x, other_geom->outline.beziers[j].prev.y); + d2d_point_normalise(&geometry->outline.beziers[j+o_bezier_count].prev); + d2d_point_transform(&geometry->outline.beziers[j+o_bezier_count].next, &gplain, + other_geom->outline.beziers[j].next.x, other_geom->outline.beziers[j].next.y); + d2d_point_normalise(&geometry->outline.beziers[j+o_bezier_count].next); + d2d_point_transform(&geometry->outline.beziers[j+o_bezier_count].p0, &g, + other_geom->outline.beziers[j].p0.x, other_geom->outline.beziers[j].p0.y); + d2d_point_transform(&geometry->outline.beziers[j+o_bezier_count].p1, &g, + other_geom->outline.beziers[j].p1.x, other_geom->outline.beziers[j].p1.y); + d2d_point_transform(&geometry->outline.beziers[j+o_bezier_count].p2, &g, + other_geom->outline.beziers[j].p2.x, other_geom->outline.beziers[j].p2.y); + } + for (j = 0; j < other_geom->outline.bezier_face_count; ++j) { + geometry->outline.bezier_faces[o_bezier_face_count+j].v[0] + = other_geom->outline.bezier_faces[j].v[0] + (UINT16) o_bezier_count; + geometry->outline.bezier_faces[o_bezier_face_count+j].v[1] + = other_geom->outline.bezier_faces[j].v[1] + (UINT16) o_bezier_count; + geometry->outline.bezier_faces[o_bezier_face_count+j].v[2] + = other_geom->outline.bezier_faces[j].v[2] + (UINT16) o_bezier_count; + } + o_bezier_count += other_geom->outline.bezier_count; + o_bezier_face_count += other_geom->outline.bezier_face_count; + + for (j = 0; j < other_geom->outline.arc_count; ++j) { + d2d_point_transform(&geometry->outline.arcs[j+o_arc_count].position, &g, + other_geom->outline.arcs[j].position.x, other_geom->outline.arcs[j].position.y); + d2d_point_transform(&geometry->outline.arcs[j+o_arc_count].prev, &gplain, + other_geom->outline.arcs[j].prev.x, other_geom->outline.arcs[j].prev.y); + d2d_point_normalise(&geometry->outline.arcs[j+o_arc_count].prev); + d2d_point_transform(&geometry->outline.arcs[j+o_arc_count].next, &gplain, + other_geom->outline.arcs[j].next.x, other_geom->outline.arcs[j].next.y); + d2d_point_normalise(&geometry->outline.arcs[j+o_arc_count].next); + d2d_point_transform(&geometry->outline.arcs[j+o_arc_count].p0, &g, + other_geom->outline.arcs[j].p0.x, other_geom->outline.arcs[j].p0.y); + d2d_point_transform(&geometry->outline.arcs[j+o_arc_count].p1, &g, + other_geom->outline.arcs[j].p1.x, other_geom->outline.arcs[j].p1.y); + d2d_point_transform(&geometry->outline.arcs[j+o_arc_count].p2, &g, + other_geom->outline.arcs[j].p2.x, other_geom->outline.arcs[j].p2.y); + } + for (j = 0; j < other_geom->outline.arc_face_count; ++j) { + geometry->outline.arc_faces[o_arc_face_count+j].v[0] + = other_geom->outline.arc_faces[j].v[0] + (UINT16) o_arc_count; + geometry->outline.arc_faces[o_arc_face_count+j].v[1] + = other_geom->outline.arc_faces[j].v[1] + (UINT16) o_arc_count; + geometry->outline.arc_faces[o_arc_face_count+j].v[2] + = other_geom->outline.arc_faces[j].v[2] + (UINT16) o_arc_count; + } + o_arc_count += other_geom->outline.arc_count; + o_arc_face_count += other_geom->outline.arc_face_count; + } + return S_OK; }