On Tue, 21 Jan 2020 at 15:40, Giovanni Mascellani gio@debian.org wrote:
+static inline const char *debug_d2d_rounded_rect(const D2D1_ROUNDED_RECT *rounded_rect) +{
- if (!rounded_rect) return "(null)";
- return wine_dbg_sprintf("(%.8e,%.8e)-(%.8e,%.8e)[%.8e,%.8e]", rounded_rect->rect.left, rounded_rect->rect.top, rounded_rect->rect.right, rounded_rect->rect.bottom, rounded_rect->radiusX, rounded_rect->radiusY );
This line seems a bit on the long side. For reference, we try to stick to 100-120 columns.
+HRESULT d2d_rounded_rectangle_geometry_init(struct d2d_geometry *geometry, ID2D1Factory *factory, const D2D1_ROUNDED_RECT *rounded_rect) +{
- struct d2d_face *f;
- struct d2d_bezier_vertex *bv;
- D2D1_POINT_2F *v, v1, v2, v3, v4;
- float l, r, t, b;
- float rX, rY;
- d2d_geometry_init(geometry, factory, &identity, (ID2D1GeometryVtbl *)&d2d_rounded_rectangle_geometry_vtbl);
- geometry->u.rounded_rectangle.rounded_rect = *rounded_rect;
- if (!(geometry->fill.vertices = heap_alloc(8 * sizeof(*geometry->fill.vertices))))
goto fail;
- if (!d2d_array_reserve((void **)&geometry->fill.faces,
&geometry->fill.faces_size, 6, sizeof(*geometry->fill.faces)))
goto fail;
- if (!(geometry->fill.bezier_vertices = heap_alloc(12 * sizeof(*geometry->fill.bezier_vertices))))
goto fail;
- l = min(rounded_rect->rect.left, rounded_rect->rect.right);
- r = max(rounded_rect->rect.left, rounded_rect->rect.right);
- t = min(rounded_rect->rect.top, rounded_rect->rect.bottom);
- b = max(rounded_rect->rect.top, rounded_rect->rect.bottom);
- rX = min(rounded_rect->radiusX, 0.5f*(r-l));
- rY = min(rounded_rect->radiusY, 0.5f*(b-t));
- d2d_point_set(&v1, r, t);
- d2d_point_set(&v2, r, b);
- d2d_point_set(&v3, l, b);
- d2d_point_set(&v4, l, t);
- v = geometry->fill.vertices;
- d2d_point_set(&v[0], l+rX, t);
- d2d_point_set(&v[1], r-rX, t);
- d2d_point_set(&v[2], r, t+rY);
- d2d_point_set(&v[3], r, b-rY);
- d2d_point_set(&v[4], r-rX, b);
- d2d_point_set(&v[5], l+rX, b);
- d2d_point_set(&v[6], l, b-rY);
- d2d_point_set(&v[7], l, t+rY);
- geometry->fill.vertex_count = 8;
- f = geometry->fill.faces;
- d2d_face_set(&f[0], 0, 7, 6);
- d2d_face_set(&f[1], 0, 6, 5);
- d2d_face_set(&f[2], 0, 5, 4);
- d2d_face_set(&f[3], 0, 4, 1);
- d2d_face_set(&f[4], 1, 4, 3);
- d2d_face_set(&f[5], 1, 3, 2);
- geometry->fill.face_count = 6;
- bv = geometry->fill.bezier_vertices;
- d2d_bezier_vertex_set(&bv[0], &v[1], 0.0f, 0.0f, -1.0f);
- d2d_bezier_vertex_set(&bv[1], &v1, 0.5f, 0.0f, -1.0f);
- d2d_bezier_vertex_set(&bv[2], &v[2], 1.0f, 1.0f, -1.0f);
- d2d_bezier_vertex_set(&bv[3], &v[3], 0.0f, 0.0f, -1.0f);
- d2d_bezier_vertex_set(&bv[4], &v2, 0.5f, 0.0f, -1.0f);
- d2d_bezier_vertex_set(&bv[5], &v[4], 1.0f, 1.0f, -1.0f);
- d2d_bezier_vertex_set(&bv[6], &v[5], 0.0f, 0.0f, -1.0f);
- d2d_bezier_vertex_set(&bv[7], &v3, 0.5f, 0.0f, -1.0f);
- d2d_bezier_vertex_set(&bv[8], &v[6], 1.0f, 1.0f, -1.0f);
- d2d_bezier_vertex_set(&bv[9], &v[7], 0.0f, 0.0f, -1.0f);
- d2d_bezier_vertex_set(&bv[10], &v4, 0.5f, 0.0f, -1.0f);
- d2d_bezier_vertex_set(&bv[11], &v[0], 1.0f, 1.0f, -1.0f);
- geometry->fill.bezier_vertex_count = 12;
- if (!d2d_geometry_outline_add_line_segment(geometry, &v[0], &v[1]))
goto fail;
- if (!d2d_geometry_outline_add_bezier_segment(geometry, &v[1], &v1, &v[2]))
goto fail;
- if (!d2d_geometry_outline_add_line_segment(geometry, &v[2], &v[3]))
goto fail;
- if (!d2d_geometry_outline_add_bezier_segment(geometry, &v[3], &v2, &v[4]))
goto fail;
- if (!d2d_geometry_outline_add_line_segment(geometry, &v[4], &v[5]))
goto fail;
- if (!d2d_geometry_outline_add_bezier_segment(geometry, &v[5], &v3, &v[6]))
goto fail;
- if (!d2d_geometry_outline_add_line_segment(geometry, &v[6], &v[7]))
goto fail;
- if (!d2d_geometry_outline_add_bezier_segment(geometry, &v[7], &v4, &v[0]))
goto fail;
- return S_OK;
+fail:
- d2d_geometry_cleanup(geometry);
- return E_OUTOFMEMORY;
+}
It seems tempting to first approximate arc primitives on top of beziers, and to then use those primitives here, instead of directly using beziers here. Any reason not to?