Signed-off-by: Giovanni Mascellani gio@debian.org --- dlls/d2d1/brush.c | 3 +- dlls/d2d1/d2d1_private.h | 15 ++++-- dlls/d2d1/device.c | 111 +++++++++++++++++++++++++++------------ dlls/d2d1/geometry.c | 30 +++++------ dlls/d2d1/tests/d2d1.c | 14 ++--- 5 files changed, 110 insertions(+), 63 deletions(-)
diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c index 80fc0f5331..cc557ea9ef 100644 --- a/dlls/d2d1/brush.c +++ b/dlls/d2d1/brush.c @@ -1262,7 +1262,7 @@ static BOOL d2d_brush_fill_cb(const struct d2d_brush *brush, }
HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_brush, - BOOL outline, struct d2d_device_context *render_target, ID3D10Buffer **ps_cb) + BOOL outline, BOOL is_arc, struct d2d_device_context *render_target, ID3D10Buffer **ps_cb) { D3D10_SUBRESOURCE_DATA buffer_data; struct d2d_ps_cb cb_data = {0}; @@ -1270,6 +1270,7 @@ HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_b HRESULT hr;
cb_data.outline = outline; + cb_data.is_arc = is_arc; if (!d2d_brush_fill_cb(brush, render_target, &cb_data.colour_brush)) return E_NOTIMPL; if (!d2d_brush_fill_cb(opacity_brush, render_target, &cb_data.opacity_brush)) diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 62c9d222fa..0b3af7ba84 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -46,7 +46,7 @@ enum d2d_shape_type D2D_SHAPE_TYPE_OUTLINE, D2D_SHAPE_TYPE_BEZIER_OUTLINE, D2D_SHAPE_TYPE_TRIANGLE, - D2D_SHAPE_TYPE_BEZIER, + D2D_SHAPE_TYPE_CURVE, D2D_SHAPE_TYPE_COUNT, };
@@ -113,7 +113,8 @@ struct d2d_brush_cb struct d2d_ps_cb { BOOL outline; - BOOL pad[3]; + BOOL is_arc; + BOOL pad[2]; struct d2d_brush_cb colour_brush; struct d2d_brush_cb opacity_brush; }; @@ -301,7 +302,7 @@ HRESULT d2d_bitmap_brush_create(ID2D1Factory *factory, ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES1 *bitmap_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc, struct d2d_brush **brush) DECLSPEC_HIDDEN; void d2d_brush_bind_resources(struct d2d_brush *brush, ID3D10Device *device, unsigned int brush_idx) DECLSPEC_HIDDEN; -HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_brush, BOOL outline, +HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_brush, BOOL outline, BOOL is_arc, struct d2d_device_context *render_target, ID3D10Buffer **ps_cb) DECLSPEC_HIDDEN; struct d2d_brush *unsafe_impl_from_ID2D1Brush(ID2D1Brush *iface) DECLSPEC_HIDDEN;
@@ -388,7 +389,7 @@ enum d2d_geometry_state D2D_GEOMETRY_STATE_FIGURE, };
-struct d2d_bezier_vertex +struct d2d_curve_vertex { D2D1_POINT_2F position; struct @@ -439,9 +440,13 @@ struct d2d_geometry size_t faces_size; size_t face_count;
- struct d2d_bezier_vertex *bezier_vertices; + struct d2d_curve_vertex *bezier_vertices; size_t bezier_vertices_size; size_t bezier_vertex_count; + + struct d2d_curve_vertex *arc_vertices; + size_t arc_vertices_size; + size_t arc_vertex_count; } fill;
struct diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index 0ab6e53f5f..cf5153142a 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -754,7 +754,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t return; }
- if (FAILED(hr = d2d_brush_get_ps_cb(brush, NULL, TRUE, render_target, &ps_cb))) + if (FAILED(hr = d2d_brush_get_ps_cb(brush, NULL, TRUE, FALSE, render_target, &ps_cb))) { WARN("Failed to get ps constant buffer, hr %#x.\n", hr); ID3D10Buffer_Release(vs_cb); @@ -846,7 +846,7 @@ static void STDMETHODCALLTYPE d2d_device_context_DrawGeometry(ID2D1DeviceContext static void d2d_device_context_fill_geometry(struct d2d_device_context *render_target, const struct d2d_geometry *geometry, struct d2d_brush *brush, struct d2d_brush *opacity_brush) { - ID3D10Buffer *ib, *vb, *vs_cb, *ps_cb; + ID3D10Buffer *ib, *vb, *vs_cb, *ps_cb_bezier, *ps_cb_arc; D3D10_SUBRESOURCE_DATA buffer_data; D3D10_BUFFER_DESC buffer_desc; D2D1_MATRIX_3X2_F *w; @@ -902,10 +902,18 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t return; }
- if (FAILED(hr = d2d_brush_get_ps_cb(brush, opacity_brush, FALSE, render_target, &ps_cb))) + if (FAILED(hr = d2d_brush_get_ps_cb(brush, opacity_brush, FALSE, FALSE, render_target, &ps_cb_bezier))) + { + WARN("Failed to get ps constant buffer, hr %#x.\n", hr); + ID3D10Buffer_Release(vs_cb); + return; + } + + if (FAILED(hr = d2d_brush_get_ps_cb(brush, opacity_brush, FALSE, TRUE, render_target, &ps_cb_arc))) { WARN("Failed to get ps constant buffer, hr %#x.\n", hr); ID3D10Buffer_Release(vs_cb); + ID3D10Buffer_Release(ps_cb_bezier); return; }
@@ -933,7 +941,7 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t }
d2d_device_context_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); + sizeof(*geometry->fill.vertices), vs_cb, ps_cb_bezier, brush, opacity_brush);
ID3D10Buffer_Release(vb); ID3D10Buffer_Release(ib); @@ -951,14 +959,32 @@ static void d2d_device_context_fill_geometry(struct d2d_device_context *render_t goto done; }
- d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_BEZIER, NULL, geometry->fill.bezier_vertex_count, vb, - sizeof(*geometry->fill.bezier_vertices), vs_cb, ps_cb, brush, opacity_brush); + d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_CURVE, NULL, geometry->fill.bezier_vertex_count, vb, + sizeof(*geometry->fill.bezier_vertices), vs_cb, ps_cb_bezier, brush, opacity_brush); + + ID3D10Buffer_Release(vb); + } + + if (geometry->fill.arc_vertex_count) + { + buffer_desc.ByteWidth = geometry->fill.arc_vertex_count * sizeof(*geometry->fill.arc_vertices); + buffer_data.pSysMem = geometry->fill.arc_vertices; + + if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) + { + ERR("Failed to create arc vertex buffer, hr %#x.\n", hr); + goto done; + } + + d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_CURVE, NULL, geometry->fill.arc_vertex_count, vb, + sizeof(*geometry->fill.arc_vertices), vs_cb, ps_cb_arc, brush, opacity_brush);
ID3D10Buffer_Release(vb); }
done: - ID3D10Buffer_Release(ps_cb); + ID3D10Buffer_Release(ps_cb_arc); + ID3D10Buffer_Release(ps_cb_bezier); ID3D10Buffer_Release(vs_cb); }
@@ -2743,7 +2769,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, { {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, }; - static const D3D10_INPUT_ELEMENT_DESC il_desc_bezier[] = + static const D3D10_INPUT_ELEMENT_DESC il_desc_curve[] = { {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 8, D3D10_INPUT_PER_VERTEX_DATA, 0}, @@ -3073,7 +3099,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, 0x00000000, 0x00000000, 0x08000036, 0x001020c2, 0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e, }; - static const DWORD vs_code_bezier[] = + static const DWORD vs_code_curve[] = { #if 0 float3x2 transform_geometry; @@ -3137,6 +3163,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, #define BRUSH_TYPE_COUNT 4
bool outline; + bool is_arc; struct brush { uint type; @@ -3299,21 +3326,28 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, { /* Evaluate the implicit form of the curve in texture space. * "i.b.z" determines which side of the curve is shaded. */ - clip((i.b.x * i.b.x - i.b.y) * i.b.z); + if (!is_arc) + { + clip((i.b.x * i.b.x - i.b.y) * i.b.z); + } + else + { + clip((i.b.x * i.b.x + i.b.y * i.b.y - 1.0) * i.b.z); + } }
return colour; } #endif - 0x43425844, 0xf3cbb8bd, 0x5f286454, 0x139976a7, 0x6817e876, 0x00000001, 0x00001d18, 0x00000003, + 0x43425844, 0x9b22fd36, 0xa300dd1c, 0x99947c91, 0x774ecf4b, 0x00000001, 0x00001df4, 0x00000003, 0x0000002c, 0x000000c4, 0x000000f8, 0x4e475349, 0x00000090, 0x00000004, 0x00000008, 0x00000068, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x00000077, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000f0f, 0x0000007e, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000303, 0x0000007e, 0x00000001, 0x00000000, 0x00000003, 0x00000003, 0x00000303, 0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, 0x54530052, 0x454b4f52, 0x4152545f, 0x4f46534e, 0xab004d52, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, - 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00001c18, - 0x00000040, 0x00000706, 0x04000059, 0x00208e46, 0x00000000, 0x00000009, 0x0300005a, 0x00106000, + 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00001cf4, + 0x00000040, 0x0000073d, 0x04000059, 0x00208e46, 0x00000000, 0x00000009, 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04000858, 0x00107000, 0x00000002, 0x00005555, 0x04000858, 0x00107000, 0x00000003, 0x00005555, 0x03001062, 0x00101032, 0x00000000, 0x03001062, @@ -3518,26 +3552,33 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, 0x00000000, 0x00000005, 0x01000015, 0x0a000037, 0x00100012, 0x00000001, 0x0010001a, 0x00000001, 0x0010000a, 0x00000001, 0x0020801a, 0x00000000, 0x00000005, 0x01000015, 0x01000015, 0x01000015, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100006, 0x00000001, 0x01000012, - 0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x01000015, 0x08000027, 0x00100012, - 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x00004001, 0x00000000, 0x0500003b, 0x00100022, - 0x00000000, 0x0010000a, 0x00000000, 0x0500000b, 0x00100032, 0x00000001, 0x00101046, 0x00000001, - 0x0500000c, 0x001000c2, 0x00000001, 0x00101406, 0x00000001, 0x07000000, 0x00100042, 0x00000000, - 0x0010100a, 0x00000001, 0x0010100a, 0x00000001, 0x0a000032, 0x001000c2, 0x00000000, 0x00100aa6, - 0x00000000, 0x00100806, 0x00000001, 0x80100d56, 0x00000041, 0x00000001, 0x0700000f, 0x00100012, - 0x00000001, 0x00100ae6, 0x00000000, 0x00101ae6, 0x00000001, 0x07000031, 0x00100012, 0x00000001, - 0x0010000a, 0x00000001, 0x00004001, 0x00000000, 0x07000001, 0x00100012, 0x00000001, 0x0010000a, - 0x00000000, 0x0010000a, 0x00000001, 0x0304000d, 0x0010000a, 0x00000001, 0x07000038, 0x00100032, - 0x00000001, 0x00100ff6, 0x00000000, 0x00101046, 0x00000003, 0x09000032, 0x001000c2, 0x00000000, - 0x00101406, 0x00000002, 0x00100aa6, 0x00000000, 0x00100406, 0x00000001, 0x0700000f, 0x00100042, - 0x00000000, 0x00100ae6, 0x00000000, 0x00100ae6, 0x00000000, 0x0500004b, 0x00100042, 0x00000000, - 0x0010002a, 0x00000000, 0x0a000032, 0x00100082, 0x00000000, 0x0010100a, 0x00000001, 0x0010100a, - 0x00000001, 0x8010101a, 0x00000041, 0x00000001, 0x08000000, 0x00100042, 0x00000000, 0x8010003a, - 0x000000c1, 0x00000000, 0x0010002a, 0x00000000, 0x07000031, 0x00100042, 0x00000000, 0x0010002a, - 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, - 0x0010002a, 0x00000000, 0x0304000d, 0x0010000a, 0x00000000, 0x07000038, 0x00100012, 0x00000000, - 0x0010003a, 0x00000000, 0x0010102a, 0x00000001, 0x07000031, 0x00100012, 0x00000000, 0x0010000a, - 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100012, 0x00000000, 0x0010001a, 0x00000000, - 0x0010000a, 0x00000000, 0x0304000d, 0x0010000a, 0x00000000, 0x0100003e, + 0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x01000015, 0x0b000027, 0x00100032, + 0x00000000, 0x00208046, 0x00000000, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x0500000b, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x0500000c, 0x001000c2, + 0x00000001, 0x00101406, 0x00000001, 0x07000000, 0x00100042, 0x00000000, 0x0010100a, 0x00000001, + 0x0010100a, 0x00000001, 0x0a000032, 0x001000c2, 0x00000000, 0x00100aa6, 0x00000000, 0x00100806, + 0x00000001, 0x80100d56, 0x00000041, 0x00000001, 0x0700000f, 0x00100012, 0x00000001, 0x00100ae6, + 0x00000000, 0x00101ae6, 0x00000001, 0x07000031, 0x00100012, 0x00000001, 0x0010000a, 0x00000001, + 0x00004001, 0x00000000, 0x07000001, 0x00100012, 0x00000001, 0x0010000a, 0x00000000, 0x0010000a, + 0x00000001, 0x0304000d, 0x0010000a, 0x00000001, 0x07000038, 0x00100032, 0x00000001, 0x00100ff6, + 0x00000000, 0x00101046, 0x00000003, 0x09000032, 0x001000c2, 0x00000000, 0x00101406, 0x00000002, + 0x00100aa6, 0x00000000, 0x00100406, 0x00000001, 0x0700000f, 0x00100042, 0x00000000, 0x00100ae6, + 0x00000000, 0x00100ae6, 0x00000000, 0x0500004b, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, + 0x07000038, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00101046, 0x00000001, 0x0a000032, + 0x00100082, 0x00000000, 0x0010100a, 0x00000001, 0x0010100a, 0x00000001, 0x8010101a, 0x00000041, + 0x00000001, 0x08000000, 0x00100042, 0x00000000, 0x8010003a, 0x000000c1, 0x00000000, 0x0010002a, + 0x00000000, 0x07000031, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x00004001, 0x00000000, + 0x07000001, 0x00100042, 0x00000000, 0x0010000a, 0x00000000, 0x0010002a, 0x00000000, 0x0304000d, + 0x0010002a, 0x00000000, 0x0500003b, 0x00100052, 0x00000000, 0x00100106, 0x00000000, 0x07000001, + 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x0010000a, 0x00000000, 0x07000038, 0x00100082, + 0x00000000, 0x0010003a, 0x00000000, 0x0010102a, 0x00000001, 0x07000031, 0x00100082, 0x00000000, + 0x0010003a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100052, 0x00000000, 0x00100656, + 0x00000000, 0x00100306, 0x00000000, 0x0304000d, 0x0010002a, 0x00000000, 0x07000000, 0x00100022, + 0x00000000, 0x0010001a, 0x00000001, 0x0010000a, 0x00000001, 0x07000000, 0x00100022, 0x00000000, + 0x0010001a, 0x00000000, 0x00004001, 0xbf800000, 0x07000038, 0x00100022, 0x00000000, 0x0010001a, + 0x00000000, 0x0010102a, 0x00000001, 0x07000031, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, + 0x00004001, 0x00000000, 0x07000001, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010001a, + 0x00000000, 0x0304000d, 0x0010000a, 0x00000000, 0x0100003e, }; static const struct shape_info { @@ -3555,8 +3596,8 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, vs_code_bezier_outline, sizeof(vs_code_bezier_outline)}, {D2D_SHAPE_TYPE_TRIANGLE, il_desc_triangle, ARRAY_SIZE(il_desc_triangle), vs_code_triangle, sizeof(vs_code_triangle)}, - {D2D_SHAPE_TYPE_BEZIER, il_desc_bezier, ARRAY_SIZE(il_desc_bezier), - vs_code_bezier, sizeof(vs_code_bezier)}, + {D2D_SHAPE_TYPE_CURVE, il_desc_curve, ARRAY_SIZE(il_desc_curve), + vs_code_curve, sizeof(vs_code_curve)}, }; static const struct { diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c index e7bb809359..a6a026aa21 100644 --- a/dlls/d2d1/geometry.c +++ b/dlls/d2d1/geometry.c @@ -129,7 +129,7 @@ struct d2d_fp_fin size_t length; };
-static void d2d_bezier_vertex_set(struct d2d_bezier_vertex *b, +static void d2d_curve_vertex_set(struct d2d_curve_vertex *b, const D2D1_POINT_2F *p, float u, float v, float sign) { b->position = *p; @@ -2351,19 +2351,17 @@ static BOOL d2d_geometry_add_figure_outline(struct d2d_geometry *geometry, static BOOL d2d_geometry_fill_add_arc_triangle(struct d2d_geometry *geometry, const D2D1_POINT_2F *p0, const D2D1_POINT_2F *p1, const D2D1_POINT_2F *p2) { - struct d2d_bezier_vertex *b; + struct d2d_curve_vertex *a;
- FIXME("Approximating arc triangle with Bezier triangle.\n"); - - if (!d2d_array_reserve((void **)&geometry->fill.bezier_vertices, &geometry->fill.bezier_vertices_size, - geometry->fill.bezier_vertex_count + 3, sizeof(*geometry->fill.bezier_vertices))) + if (!d2d_array_reserve((void **)&geometry->fill.arc_vertices, &geometry->fill.arc_vertices_size, + geometry->fill.arc_vertex_count + 3, sizeof(*geometry->fill.arc_vertices))) return FALSE;
- b = &geometry->fill.bezier_vertices[geometry->fill.bezier_vertex_count]; - d2d_bezier_vertex_set(&b[0], p0, 0.0f, 0.0f, -1.0f); - d2d_bezier_vertex_set(&b[1], p1, 0.5f, 0.0f, -1.0f); - d2d_bezier_vertex_set(&b[2], p2, 1.0f, 1.0f, -1.0f); - geometry->fill.bezier_vertex_count += 3; + a = &geometry->fill.arc_vertices[geometry->fill.arc_vertex_count]; + d2d_curve_vertex_set(&a[0], p0, 0.0f, 1.0f, -1.0f); + d2d_curve_vertex_set(&a[1], p1, 1.0f, 1.0f, -1.0f); + d2d_curve_vertex_set(&a[2], p2, 1.0f, 0.0f, -1.0f); + geometry->fill.arc_vertex_count += 3;
return TRUE; } @@ -2374,6 +2372,7 @@ static void d2d_geometry_cleanup(struct d2d_geometry *geometry) heap_free(geometry->outline.beziers); heap_free(geometry->outline.faces); heap_free(geometry->outline.vertices); + heap_free(geometry->fill.arc_vertices); heap_free(geometry->fill.bezier_vertices); heap_free(geometry->fill.faces); heap_free(geometry->fill.vertices); @@ -2782,7 +2781,7 @@ static BOOL d2d_geometry_split_bezier(struct d2d_geometry *geometry, const struc static HRESULT d2d_geometry_resolve_beziers(struct d2d_geometry *geometry) { struct d2d_segment_idx idx_p, idx_q; - struct d2d_bezier_vertex *b; + struct d2d_curve_vertex *b; const D2D1_POINT_2F *p[3]; struct d2d_figure *figure; size_t bezier_idx, i; @@ -2858,9 +2857,9 @@ static HRESULT d2d_geometry_resolve_beziers(struct d2d_geometry *geometry) p[2] = &figure->vertices[i];
b = &geometry->fill.bezier_vertices[bezier_idx * 3]; - d2d_bezier_vertex_set(&b[0], p[0], 0.0f, 0.0f, sign); - d2d_bezier_vertex_set(&b[1], p[1], 0.5f, 0.0f, sign); - d2d_bezier_vertex_set(&b[2], p[2], 1.0f, 1.0f, sign); + d2d_curve_vertex_set(&b[0], p[0], 0.0f, 0.0f, sign); + d2d_curve_vertex_set(&b[1], p[1], 0.5f, 0.0f, sign); + d2d_curve_vertex_set(&b[2], p[2], 1.0f, 1.0f, sign);
if (!d2d_geometry_get_next_bezier_segment_idx(geometry, &idx_p)) break; @@ -4524,6 +4523,7 @@ static ULONG STDMETHODCALLTYPE d2d_transformed_geometry_Release(ID2D1Transformed geometry->outline.beziers = NULL; geometry->outline.faces = NULL; geometry->outline.vertices = NULL; + geometry->fill.arc_vertices = NULL; geometry->fill.bezier_vertices = NULL; geometry->fill.faces = NULL; geometry->fill.vertices = NULL; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 319246a0bc..1d4db386ab 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -6846,7 +6846,7 @@ static void test_fill_geometry(void) "yjIMjwEWhwEcggEgfiR6KHYscy5xMG40azZpOGc6ZTxjPmI+YUBfQl1EXERbRlpGWUhYSFdKVkpV" "TFRMVExTTlJOUk5STlJOUVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUU5STlJOUk5STlNMVExUTFVK" "VkpXSFhIWUZaRltEXERdQl9AYT5iPmM8ZTpnOGk2azRuMHEucyx2KHokfiCCARyHARaPAQzKMgAA"); - todo_wine ok(match, "Figure does not match.\n"); + ok(match, "Figure does not match.\n");
ID2D1RenderTarget_BeginDraw(rt); set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f); @@ -6892,7 +6892,7 @@ static void test_fill_geometry(void) "szI6YURZSlROUVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ" "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ" "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUU5USllEYTqzMgAA"); - todo_wine ok(match, "Figure does not match.\n"); + ok(match, "Figure does not match.\n");
match = compare_figure(surface, 0, 160, 160, 160, 0xff652e89, 0, "gMgB"); ok(match, "Figure does not match.\n"); @@ -6904,7 +6904,7 @@ static void test_fill_geometry(void) "tjI0aDxhQlxGWEpVTFNOUk5RUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ" "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ" "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFFOUk5TTFVKWEZcQmA+ZzS2MgAA"); - todo_wine ok(match, "Figure does not match.\n"); + ok(match, "Figure does not match.\n");
match = compare_figure(surface, 0, 320, 160, 160, 0xff652e89, 0, "gMgB"); ok(match, "Figure does not match.\n"); @@ -6916,7 +6916,7 @@ static void test_fill_geometry(void) "sDJAWkxSUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ" "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ" "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFJMWkCwMgAA"); - todo_wine ok(match, "Figure does not match.\n"); + ok(match, "Figure does not match.\n");
ID2D1RenderTarget_BeginDraw(rt); set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f); @@ -6962,7 +6962,7 @@ static void test_fill_geometry(void) "yjIMjwEWhwEcggEgfiR6KHYscy5xMG40azZpOGc6ZTxjPmI+YUBfQl1EXERbRlpGWUhYSFdKVkpV" "TFRMVExTTlJOUk5STlJOUVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUU5STlJOUk5STlNMVExUTFVK" "VkpXSFhIWUZaRltEXERdQl9AYT5iPmM8ZTpnOGk2azRuMHEucyx2KHokfiCCARyHARaPAQzKMgAA"); - todo_wine ok(match, "Figure does not match.\n"); + ok(match, "Figure does not match.\n");
match = compare_figure(surface, 0, 160, 160, 160, 0xff652e89, 0, "gMgB"); ok(match, "Figure does not match.\n"); @@ -6974,7 +6974,7 @@ static void test_fill_geometry(void) "uTIucDJsNmk4ZzplPGM+YUBgQF9CXkJdRFxEW0ZaRllIWEhXSlZKVkpWSlVMVExUTFRMU05STlJO" "Uk5STlJOUk9QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFFPUU5STlJOUk5STlJOU0xU" "TFRMVExVSlZKVkpWSldIWEhZRlpGW0RcRF1CXkJfQGBAYT5jPGU6ZzhpNmwycC65MgAA"); - todo_wine ok(match, "Figure does not match.\n"); + ok(match, "Figure does not match.\n");
match = compare_figure(surface, 0, 320, 160, 160, 0xff652e89, 0, "gMgB"); ok(match, "Figure does not match.\n"); @@ -6986,7 +6986,7 @@ static void test_fill_geometry(void) "vzIiczhhRldMUlBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ" "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ" "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUkxXRmA6cSS+MgAA"); - todo_wine ok(match, "Figure does not match.\n"); + ok(match, "Figure does not match.\n");
hr = ID2D1Factory_CreatePathGeometry(factory, &geometry); ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
Signed-off-by: Giovanni Mascellani gio@debian.org --- dlls/d2d1/d2d1_private.h | 13 +- dlls/d2d1/device.c | 313 +++++++++++++++++++++++++++++++++------ dlls/d2d1/geometry.c | 82 +++++++--- 3 files changed, 345 insertions(+), 63 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 0b3af7ba84..a2546a5b1c 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -45,6 +45,7 @@ enum d2d_shape_type { D2D_SHAPE_TYPE_OUTLINE, D2D_SHAPE_TYPE_BEZIER_OUTLINE, + D2D_SHAPE_TYPE_ARC_OUTLINE, D2D_SHAPE_TYPE_TRIANGLE, D2D_SHAPE_TYPE_CURVE, D2D_SHAPE_TYPE_COUNT, @@ -415,7 +416,7 @@ struct d2d_outline_vertex D2D1_POINT_2F next; };
-struct d2d_bezier_outline_vertex +struct d2d_curve_outline_vertex { D2D1_POINT_2F position; D2D1_POINT_2F p0, p1, p2; @@ -459,13 +460,21 @@ struct d2d_geometry size_t faces_size; size_t face_count;
- struct d2d_bezier_outline_vertex *beziers; + struct d2d_curve_outline_vertex *beziers; size_t beziers_size; size_t bezier_count;
struct d2d_face *bezier_faces; size_t bezier_faces_size; size_t bezier_face_count; + + struct d2d_curve_outline_vertex *arcs; + size_t arcs_size; + size_t arc_count; + + struct d2d_face *arc_faces; + size_t arc_faces_size; + size_t arc_face_count; } outline;
union diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index cf5153142a..c3decf6fbd 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -698,7 +698,7 @@ static void STDMETHODCALLTYPE d2d_device_context_FillEllipse(ID2D1DeviceContext static void d2d_device_context_draw_geometry(struct d2d_device_context *render_target, const struct d2d_geometry *geometry, struct d2d_brush *brush, float stroke_width) { - ID3D10Buffer *ib, *vb, *vs_cb, *ps_cb; + ID3D10Buffer *ib, *vb, *vs_cb, *ps_cb_bezier, *ps_cb_arc; D3D10_SUBRESOURCE_DATA buffer_data; D3D10_BUFFER_DESC buffer_desc; const D2D1_MATRIX_3X2_F *w; @@ -754,13 +754,21 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t return; }
- if (FAILED(hr = d2d_brush_get_ps_cb(brush, NULL, TRUE, FALSE, render_target, &ps_cb))) + if (FAILED(hr = d2d_brush_get_ps_cb(brush, NULL, TRUE, FALSE, render_target, &ps_cb_bezier))) { WARN("Failed to get ps constant buffer, hr %#x.\n", hr); ID3D10Buffer_Release(vs_cb); return; }
+ if (FAILED(hr = d2d_brush_get_ps_cb(brush, NULL, TRUE, TRUE, render_target, &ps_cb_arc))) + { + WARN("Failed to get ps constant buffer, hr %#x.\n", hr); + ID3D10Buffer_Release(vs_cb); + ID3D10Buffer_Release(ps_cb_bezier); + return; + } + if (geometry->outline.face_count) { buffer_desc.ByteWidth = geometry->outline.face_count * sizeof(*geometry->outline.faces); @@ -785,7 +793,7 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t }
d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_OUTLINE, ib, 3 * geometry->outline.face_count, vb, - sizeof(*geometry->outline.vertices), vs_cb, ps_cb, brush, NULL); + sizeof(*geometry->outline.vertices), vs_cb, ps_cb_bezier, brush, NULL);
ID3D10Buffer_Release(vb); ID3D10Buffer_Release(ib); @@ -816,14 +824,46 @@ static void d2d_device_context_draw_geometry(struct d2d_device_context *render_t
d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_BEZIER_OUTLINE, ib, 3 * geometry->outline.bezier_face_count, vb, - sizeof(*geometry->outline.beziers), vs_cb, ps_cb, brush, NULL); + sizeof(*geometry->outline.beziers), vs_cb, ps_cb_bezier, brush, NULL); + + ID3D10Buffer_Release(vb); + ID3D10Buffer_Release(ib); + } + + if (geometry->outline.arc_face_count) + { + buffer_desc.ByteWidth = geometry->outline.arc_face_count * sizeof(*geometry->outline.arc_faces); + buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER; + buffer_data.pSysMem = geometry->outline.arc_faces; + + if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib))) + { + WARN("Failed to create arcs index buffer, hr %#x.\n", hr); + goto done; + } + + buffer_desc.ByteWidth = geometry->outline.arc_count * sizeof(*geometry->outline.arcs); + buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; + buffer_data.pSysMem = geometry->outline.arcs; + + if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb))) + { + ERR("Failed to create arcs vertex buffer, hr %#x.\n", hr); + ID3D10Buffer_Release(ib); + goto done; + } + + d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_ARC_OUTLINE, ib, + 3 * geometry->outline.arc_face_count, vb, + sizeof(*geometry->outline.arcs), vs_cb, ps_cb_arc, brush, NULL);
ID3D10Buffer_Release(vb); ID3D10Buffer_Release(ib); }
done: - ID3D10Buffer_Release(ps_cb); + ID3D10Buffer_Release(ps_cb_arc); + ID3D10Buffer_Release(ps_cb_bezier); ID3D10Buffer_Release(vs_cb); }
@@ -2756,7 +2796,7 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, {"PREV", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D10_INPUT_PER_VERTEX_DATA, 0}, {"NEXT", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0}, }; - static const D3D10_INPUT_ELEMENT_DESC il_desc_bezier_outline[] = + static const D3D10_INPUT_ELEMENT_DESC il_desc_curve_outline[] = { {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0}, {"P", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D10_INPUT_PER_VERTEX_DATA, 0}, @@ -3046,6 +3086,154 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, 0x00000001, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000, 0x00000000, 0x08000036, 0x001020c2, 0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e, }; + /* ⎡p0.x p0.y 1⎤ + * A = ⎢p1.x p1.y 1⎥ + * ⎣p2.x p2.y 1⎦ + * + * ⎡1 0⎤ + * B = ⎢1 1⎥ + * ⎣0 1⎦ + * + * A' = ⎡p1.x-p0.x p1.y-p0.y⎤ + * ⎣p2.x-p0.x p2.y-p0.y⎦ + * + * B' = ⎡ 0 1⎤ + * ⎣-1 1⎦ + * + * A'T = B' + * T = A'⁻¹B' = (B'⁻¹A')⁻¹ + */ + static const DWORD vs_code_arc_outline[] = + { +#if 0 + float3x2 transform_geometry; + float stroke_width; + float4 transform_rtx; + float4 transform_rty; + + struct output + { + float2 p : WORLD_POSITION; + float4 b : BEZIER; + nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM; + float4 position : SV_POSITION; + }; + + void main(float2 position : POSITION, float2 p0 : P0, float2 p1 : P1, float2 p2 : P2, + float2 prev : PREV, float2 next : NEXT, out struct output o) + { + float2 q_prev, q_next, v_p, q_i, p; + float2x2 geom, rt, p_inv; + float l; + float a; + float2 bc; + + geom = float2x2(transform_geometry._11_21, transform_geometry._12_22); + rt = float2x2(transform_rtx.xy, transform_rty.xy); + o.stroke_transform = rt * stroke_width * 0.5f; + + p = mul(geom, position); + p0 = mul(geom, p0); + p1 = mul(geom, p1); + p2 = mul(geom, p2); + + p -= p0; + p1 -= p0; + p2 -= p0; + + q_prev = normalize(mul(geom, prev)); + q_next = normalize(mul(geom, next)); + + v_p = float2(-q_prev.y, q_prev.x); + l = -dot(v_p, q_next) / (1.0f + dot(q_prev, q_next)); + q_i = l * q_prev + v_p; + p += 0.5f * stroke_width * q_i; + + p_inv = float2x2(p1.y, -p1.x, p2.y - p1.y, p1.x - p2.x) / (p1.x * p2.y - p2.x * p1.y); + o.b.xy = mul(p_inv, p) + float2(1.0f, 0.0f); + o.b.zw = 0.0f; + + o.p = mul(float3(position, 1.0f), transform_geometry) + 0.5f * stroke_width * q_i; + position = mul(float2x3(transform_rtx.xyz, transform_rty.xyz), float3(o.p, 1.0f)) + * float2(transform_rtx.w, transform_rty.w); + o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f); + } +#endif + 0x43425844, 0xde1911bf, 0xfff8c893, 0xb0bfc24d, 0x78c9bbc4, 0x00000001, 0x00000924, 0x00000003, + 0x0000002c, 0x000000e4, 0x000001a0, 0x4e475349, 0x000000b0, 0x00000006, 0x00000008, 0x00000098, + 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x000000a1, 0x00000000, 0x00000000, + 0x00000003, 0x00000001, 0x00000303, 0x000000a1, 0x00000001, 0x00000000, 0x00000003, 0x00000002, + 0x00000303, 0x000000a1, 0x00000002, 0x00000000, 0x00000003, 0x00000003, 0x00000303, 0x000000a3, + 0x00000000, 0x00000000, 0x00000003, 0x00000004, 0x00000303, 0x000000a8, 0x00000000, 0x00000000, + 0x00000003, 0x00000005, 0x00000303, 0x49534f50, 0x4e4f4954, 0x50005000, 0x00564552, 0x5458454e, + 0xababab00, 0x4e47534f, 0x000000b4, 0x00000005, 0x00000008, 0x00000080, 0x00000000, 0x00000000, + 0x00000003, 0x00000000, 0x00000c03, 0x0000008f, 0x00000000, 0x00000000, 0x00000003, 0x00000001, + 0x0000000f, 0x00000096, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x00000096, + 0x00000001, 0x00000000, 0x00000003, 0x00000003, 0x00000c03, 0x000000a7, 0x00000000, 0x00000001, + 0x00000003, 0x00000004, 0x0000000f, 0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, + 0x54530052, 0x454b4f52, 0x4152545f, 0x4f46534e, 0x53004d52, 0x4f505f56, 0x49544953, 0xab004e4f, + 0x52444853, 0x0000077c, 0x00010040, 0x000001df, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, + 0x0300005f, 0x00101032, 0x00000000, 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x00101032, + 0x00000002, 0x0300005f, 0x00101032, 0x00000003, 0x0300005f, 0x00101032, 0x00000004, 0x0300005f, + 0x00101032, 0x00000005, 0x03000065, 0x00102032, 0x00000000, 0x03000065, 0x001020f2, 0x00000001, + 0x03000065, 0x00102032, 0x00000002, 0x03000065, 0x00102032, 0x00000003, 0x04000067, 0x001020f2, + 0x00000004, 0x00000001, 0x02000068, 0x00000004, 0x0800000f, 0x00100012, 0x00000000, 0x00208046, + 0x00000000, 0x00000000, 0x00101046, 0x00000005, 0x0800000f, 0x00100022, 0x00000000, 0x00208046, + 0x00000000, 0x00000001, 0x00101046, 0x00000005, 0x0700000f, 0x00100042, 0x00000000, 0x00100046, + 0x00000000, 0x00100046, 0x00000000, 0x05000044, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, + 0x07000038, 0x00100032, 0x00000000, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x0800000f, + 0x00100012, 0x00000001, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000004, 0x0800000f, + 0x00100022, 0x00000001, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000004, 0x0700000f, + 0x00100042, 0x00000000, 0x00100046, 0x00000001, 0x00100046, 0x00000001, 0x05000044, 0x00100042, + 0x00000000, 0x0010002a, 0x00000000, 0x07000038, 0x00100032, 0x00000001, 0x00100aa6, 0x00000000, + 0x00100046, 0x00000001, 0x06000036, 0x001000c2, 0x00000001, 0x80100556, 0x00000041, 0x00000001, + 0x0700000f, 0x00100042, 0x00000000, 0x00100a26, 0x00000001, 0x00100046, 0x00000000, 0x0700000f, + 0x00100012, 0x00000000, 0x00100046, 0x00000001, 0x00100046, 0x00000000, 0x07000000, 0x00100012, + 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0800000e, 0x00100012, 0x00000000, + 0x8010002a, 0x00000041, 0x00000000, 0x0010000a, 0x00000000, 0x09000032, 0x00100032, 0x00000000, + 0x00100006, 0x00000000, 0x00100046, 0x00000001, 0x00100f36, 0x00000001, 0x05000036, 0x00100032, + 0x00000001, 0x00101046, 0x00000000, 0x05000036, 0x00100042, 0x00000001, 0x00004001, 0x3f800000, + 0x08000010, 0x00100012, 0x00000002, 0x00100246, 0x00000001, 0x00208246, 0x00000000, 0x00000000, + 0x08000010, 0x00100022, 0x00000002, 0x00100246, 0x00000001, 0x00208246, 0x00000000, 0x00000001, + 0x08000038, 0x00100042, 0x00000000, 0x0020803a, 0x00000000, 0x00000001, 0x00004001, 0x3f000000, + 0x09000032, 0x00100032, 0x00000001, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x00100046, + 0x00000002, 0x05000036, 0x00102032, 0x00000000, 0x00100046, 0x00000001, 0x0800000f, 0x00100012, + 0x00000002, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000000, 0x0800000f, 0x00100022, + 0x00000002, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000000, 0x0800000f, 0x00100022, + 0x00000003, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000001, 0x0800000f, 0x00100012, + 0x00000003, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000001, 0x08000000, 0x00100032, + 0x00000002, 0x00100046, 0x00000002, 0x80100516, 0x00000041, 0x00000003, 0x09000032, 0x00100032, + 0x00000000, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000002, 0x0800000f, + 0x00100022, 0x00000002, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000003, 0x0800000f, + 0x00100012, 0x00000002, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000003, 0x08000000, + 0x001000c2, 0x00000000, 0x80100406, 0x00000041, 0x00000003, 0x00100406, 0x00000002, 0x0800000f, + 0x00100022, 0x00000002, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000002, 0x0800000f, + 0x00100012, 0x00000002, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000002, 0x08000000, + 0x00100032, 0x00000002, 0x80100046, 0x00000041, 0x00000003, 0x00100046, 0x00000002, 0x07000038, + 0x00100082, 0x00000001, 0x0010003a, 0x00000000, 0x0010000a, 0x00000002, 0x0a000032, 0x00100082, + 0x00000001, 0x0010001a, 0x00000002, 0x0010002a, 0x00000000, 0x8010003a, 0x00000041, 0x00000001, + 0x08000000, 0x00100042, 0x00000003, 0x0010002a, 0x00000000, 0x8010000a, 0x00000041, 0x00000002, + 0x08000000, 0x00100082, 0x00000003, 0x8010003a, 0x00000041, 0x00000000, 0x0010001a, 0x00000002, + 0x0a000038, 0x00100032, 0x00000003, 0x00100046, 0x00000002, 0x00004002, 0x3f800000, 0xbf800000, + 0x00000000, 0x00000000, 0x0700000e, 0x001000f2, 0x00000002, 0x00100e46, 0x00000003, 0x00100ff6, + 0x00000001, 0x0700000f, 0x00100012, 0x00000002, 0x00100046, 0x00000002, 0x00100046, 0x00000000, + 0x0700000f, 0x00100022, 0x00000002, 0x00100ae6, 0x00000002, 0x00100046, 0x00000000, 0x0a000000, + 0x00102032, 0x00000001, 0x00100046, 0x00000002, 0x00004002, 0x3f800000, 0x00000000, 0x00000000, + 0x00000000, 0x08000036, 0x001020c2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x06000036, 0x00100032, 0x00000000, 0x00208046, 0x00000000, 0x00000002, 0x06000036, + 0x001000c2, 0x00000000, 0x00208406, 0x00000000, 0x00000003, 0x08000038, 0x001000f2, 0x00000000, + 0x00100e46, 0x00000000, 0x00208ff6, 0x00000000, 0x00000001, 0x0a000038, 0x001000f2, 0x00000000, + 0x00100e46, 0x00000000, 0x00004002, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x05000036, + 0x00102032, 0x00000002, 0x00100086, 0x00000000, 0x05000036, 0x00102032, 0x00000003, 0x001005d6, + 0x00000000, 0x05000036, 0x00100042, 0x00000001, 0x00004001, 0x3f800000, 0x08000010, 0x00100012, + 0x00000000, 0x00208246, 0x00000000, 0x00000002, 0x00100246, 0x00000001, 0x08000010, 0x00100022, + 0x00000000, 0x00208246, 0x00000000, 0x00000003, 0x00100246, 0x00000001, 0x08000038, 0x00100022, + 0x00000001, 0x0010001a, 0x00000000, 0x0020803a, 0x00000000, 0x00000003, 0x08000038, 0x00100012, + 0x00000001, 0x0010000a, 0x00000000, 0x0020803a, 0x00000000, 0x00000002, 0x0a000000, 0x00102032, + 0x00000004, 0x00100046, 0x00000001, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000, 0x00000000, + 0x08000036, 0x001020c2, 0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, + 0x0100003e, + }; static const DWORD vs_code_triangle[] = { #if 0 @@ -3305,22 +3493,41 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, float2 du, dv, df; float4 uv;
- /* Evaluate the implicit form of the curve (u² - v = 0) in texture space, - * using the screen-space partial derivatives to convert the calculated - * distance to object space. + /* Evaluate the implicit form of the curve (u² - v = 0 + * for Béziers, u² + v² - 1 = 0 for arcs) in texture + * space, using the screen-space partial derivatives + * to convert the calculated distance to object space. * * d(x, y) = |f(x, y)| / ‖∇f(x, y)‖ * = |f(x, y)| / √((∂f/∂x)² + (∂f/∂y)²) + * + * For Béziers: * f(x, y) = u(x, y)² - v(x, y) * ∂f/∂x = 2u · ∂u/∂x - ∂v/∂x - * ∂f/∂y = 2u · ∂u/∂y - ∂v/∂y */ + * ∂f/∂y = 2u · ∂u/∂y - ∂v/∂y + * + * For arcs: + * f(x, y) = u(x, y)² + v(x, y)² - 1 + * ∂f/∂x = 2u · ∂u/∂x + 2v · ∂v/∂x + * ∂f/∂y = 2u · ∂u/∂y + 2v · ∂v/∂y */ uv = i.b; du = float2(ddx(uv.x), ddy(uv.x)); dv = float2(ddx(uv.y), ddy(uv.y)); - df = 2.0f * uv.x * du - dv;
- clip(dot(df, uv.zw)); - clip(length(mul(i.stroke_transform, df)) - abs(uv.x * uv.x - uv.y)); + if (!is_arc) + { + df = 2.0f * uv.x * du - dv; + + clip(dot(df, uv.zw)); + clip(length(mul(i.stroke_transform, df)) - abs(uv.x * uv.x - uv.y)); + } + else + { + df = 2.0f * uv.x * du + 2.0f * uv.y * dv; + + clip(dot(df, uv.zw)); + clip(length(mul(i.stroke_transform, df)) - abs(uv.x * uv.x + uv.y * uv.y - 1.0f)); + } } else { @@ -3339,15 +3546,15 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, return colour; } #endif - 0x43425844, 0x9b22fd36, 0xa300dd1c, 0x99947c91, 0x774ecf4b, 0x00000001, 0x00001df4, 0x00000003, + 0x43425844, 0xa8fee730, 0x92fa2196, 0xaf9f3eff, 0x888d4048, 0x00000001, 0x00002000, 0x00000003, 0x0000002c, 0x000000c4, 0x000000f8, 0x4e475349, 0x00000090, 0x00000004, 0x00000008, 0x00000068, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x00000077, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000f0f, 0x0000007e, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000303, 0x0000007e, 0x00000001, 0x00000000, 0x00000003, 0x00000003, 0x00000303, 0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, 0x54530052, 0x454b4f52, 0x4152545f, 0x4f46534e, 0xab004d52, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, - 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00001cf4, - 0x00000040, 0x0000073d, 0x04000059, 0x00208e46, 0x00000000, 0x00000009, 0x0300005a, 0x00106000, + 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00001f00, + 0x00000040, 0x000007c0, 0x04000059, 0x00208e46, 0x00000000, 0x00000009, 0x0300005a, 0x00106000, 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04000858, 0x00107000, 0x00000002, 0x00005555, 0x04000858, 0x00107000, 0x00000003, 0x00005555, 0x03001062, 0x00101032, 0x00000000, 0x03001062, @@ -3552,33 +3759,49 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, 0x00000000, 0x00000005, 0x01000015, 0x0a000037, 0x00100012, 0x00000001, 0x0010001a, 0x00000001, 0x0010000a, 0x00000001, 0x0020801a, 0x00000000, 0x00000005, 0x01000015, 0x01000015, 0x01000015, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100006, 0x00000001, 0x01000012, - 0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x01000015, 0x0b000027, 0x00100032, - 0x00000000, 0x00208046, 0x00000000, 0x00000000, 0x00004002, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x0500000b, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x0500000c, 0x001000c2, - 0x00000001, 0x00101406, 0x00000001, 0x07000000, 0x00100042, 0x00000000, 0x0010100a, 0x00000001, - 0x0010100a, 0x00000001, 0x0a000032, 0x001000c2, 0x00000000, 0x00100aa6, 0x00000000, 0x00100806, - 0x00000001, 0x80100d56, 0x00000041, 0x00000001, 0x0700000f, 0x00100012, 0x00000001, 0x00100ae6, - 0x00000000, 0x00101ae6, 0x00000001, 0x07000031, 0x00100012, 0x00000001, 0x0010000a, 0x00000001, - 0x00004001, 0x00000000, 0x07000001, 0x00100012, 0x00000001, 0x0010000a, 0x00000000, 0x0010000a, - 0x00000001, 0x0304000d, 0x0010000a, 0x00000001, 0x07000038, 0x00100032, 0x00000001, 0x00100ff6, - 0x00000000, 0x00101046, 0x00000003, 0x09000032, 0x001000c2, 0x00000000, 0x00101406, 0x00000002, - 0x00100aa6, 0x00000000, 0x00100406, 0x00000001, 0x0700000f, 0x00100042, 0x00000000, 0x00100ae6, - 0x00000000, 0x00100ae6, 0x00000000, 0x0500004b, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, - 0x07000038, 0x00100032, 0x00000001, 0x00101046, 0x00000001, 0x00101046, 0x00000001, 0x0a000032, - 0x00100082, 0x00000000, 0x0010100a, 0x00000001, 0x0010100a, 0x00000001, 0x8010101a, 0x00000041, - 0x00000001, 0x08000000, 0x00100042, 0x00000000, 0x8010003a, 0x000000c1, 0x00000000, 0x0010002a, - 0x00000000, 0x07000031, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x00004001, 0x00000000, - 0x07000001, 0x00100042, 0x00000000, 0x0010000a, 0x00000000, 0x0010002a, 0x00000000, 0x0304000d, - 0x0010002a, 0x00000000, 0x0500003b, 0x00100052, 0x00000000, 0x00100106, 0x00000000, 0x07000001, - 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x0010000a, 0x00000000, 0x07000038, 0x00100082, - 0x00000000, 0x0010003a, 0x00000000, 0x0010102a, 0x00000001, 0x07000031, 0x00100082, 0x00000000, - 0x0010003a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100052, 0x00000000, 0x00100656, - 0x00000000, 0x00100306, 0x00000000, 0x0304000d, 0x0010002a, 0x00000000, 0x07000000, 0x00100022, - 0x00000000, 0x0010001a, 0x00000001, 0x0010000a, 0x00000001, 0x07000000, 0x00100022, 0x00000000, - 0x0010001a, 0x00000000, 0x00004001, 0xbf800000, 0x07000038, 0x00100022, 0x00000000, 0x0010001a, - 0x00000000, 0x0010102a, 0x00000001, 0x07000031, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, - 0x00004001, 0x00000000, 0x07000001, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x0010001a, - 0x00000000, 0x0304000d, 0x0010000a, 0x00000000, 0x0100003e, + 0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x01000015, 0x0404001f, 0x0020800a, + 0x00000000, 0x00000000, 0x0500000b, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x0500000c, + 0x001000c2, 0x00000000, 0x00101406, 0x00000001, 0x08000027, 0x00100012, 0x00000001, 0x0020801a, + 0x00000000, 0x00000000, 0x00004001, 0x00000000, 0x0500003b, 0x00100022, 0x00000001, 0x0010000a, + 0x00000001, 0x07000000, 0x001000c2, 0x00000001, 0x00101406, 0x00000001, 0x00101406, 0x00000001, + 0x07000038, 0x001000f2, 0x00000002, 0x00100d86, 0x00000000, 0x00100fa6, 0x00000001, 0x0a000032, + 0x00100032, 0x00000000, 0x00100aa6, 0x00000001, 0x00100086, 0x00000000, 0x801005d6, 0x00000041, + 0x00000000, 0x0700000f, 0x00100042, 0x00000000, 0x00100046, 0x00000000, 0x00101ae6, 0x00000001, + 0x07000031, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, + 0x00100042, 0x00000000, 0x0010001a, 0x00000001, 0x0010002a, 0x00000000, 0x0304000d, 0x0010002a, + 0x00000000, 0x07000038, 0x00100062, 0x00000000, 0x00100556, 0x00000000, 0x00101106, 0x00000003, + 0x09000032, 0x00100032, 0x00000000, 0x00101046, 0x00000002, 0x00100006, 0x00000000, 0x00100596, + 0x00000000, 0x0700000f, 0x00100012, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000000, + 0x0500004b, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x07000038, 0x00100062, 0x00000000, + 0x00101106, 0x00000001, 0x00101106, 0x00000001, 0x0a000032, 0x00100082, 0x00000000, 0x0010100a, + 0x00000001, 0x0010100a, 0x00000001, 0x8010101a, 0x00000041, 0x00000001, 0x08000000, 0x00100012, + 0x00000000, 0x8010003a, 0x000000c1, 0x00000000, 0x0010000a, 0x00000000, 0x07000031, 0x00100012, + 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100012, 0x00000000, + 0x0010001a, 0x00000001, 0x0010000a, 0x00000000, 0x0304000d, 0x0010000a, 0x00000000, 0x07000000, + 0x00100092, 0x00000000, 0x00100ea6, 0x00000002, 0x00100406, 0x00000002, 0x0700000f, 0x00100022, + 0x00000001, 0x001000c6, 0x00000000, 0x00101ae6, 0x00000001, 0x07000031, 0x00100022, 0x00000001, + 0x0010001a, 0x00000001, 0x00004001, 0x00000000, 0x07000001, 0x00100022, 0x00000001, 0x0010000a, + 0x00000001, 0x0010001a, 0x00000001, 0x0304000d, 0x0010001a, 0x00000001, 0x07000038, 0x00100062, + 0x00000001, 0x00100ff6, 0x00000000, 0x00101106, 0x00000003, 0x09000032, 0x00100092, 0x00000000, + 0x00101406, 0x00000002, 0x00100006, 0x00000000, 0x00100956, 0x00000001, 0x0700000f, 0x00100012, + 0x00000000, 0x001000c6, 0x00000000, 0x001000c6, 0x00000000, 0x0500004b, 0x00100012, 0x00000000, + 0x0010000a, 0x00000000, 0x07000000, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a, + 0x00000000, 0x07000000, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0xbf800000, + 0x08000000, 0x00100012, 0x00000000, 0x8010001a, 0x000000c1, 0x00000000, 0x0010000a, 0x00000000, + 0x07000031, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, + 0x00100012, 0x00000000, 0x0010000a, 0x00000001, 0x0010000a, 0x00000000, 0x0304000d, 0x0010000a, + 0x00000000, 0x01000012, 0x08000027, 0x00100012, 0x00000000, 0x0020801a, 0x00000000, 0x00000000, + 0x00004001, 0x00000000, 0x0500003b, 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x07000038, + 0x001000c2, 0x00000000, 0x00101406, 0x00000001, 0x00101406, 0x00000001, 0x0a000032, 0x00100012, + 0x00000001, 0x0010100a, 0x00000001, 0x0010100a, 0x00000001, 0x8010101a, 0x00000041, 0x00000001, + 0x07000038, 0x00100012, 0x00000001, 0x0010000a, 0x00000001, 0x0010102a, 0x00000001, 0x07000031, + 0x00100012, 0x00000001, 0x0010000a, 0x00000001, 0x00004001, 0x00000000, 0x07000001, 0x00100022, + 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000001, 0x0304000d, 0x0010001a, 0x00000000, + 0x07000000, 0x00100022, 0x00000000, 0x0010003a, 0x00000000, 0x0010002a, 0x00000000, 0x07000000, + 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0xbf800000, 0x07000038, 0x00100022, + 0x00000000, 0x0010001a, 0x00000000, 0x0010102a, 0x00000001, 0x07000031, 0x00100022, 0x00000000, + 0x0010001a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100012, 0x00000000, 0x0010000a, + 0x00000000, 0x0010001a, 0x00000000, 0x0304000d, 0x0010000a, 0x00000000, 0x01000015, 0x0100003e, }; static const struct shape_info { @@ -3592,8 +3815,10 @@ static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, { {D2D_SHAPE_TYPE_OUTLINE, il_desc_outline, ARRAY_SIZE(il_desc_outline), vs_code_outline, sizeof(vs_code_outline)}, - {D2D_SHAPE_TYPE_BEZIER_OUTLINE, il_desc_bezier_outline, ARRAY_SIZE(il_desc_bezier_outline), + {D2D_SHAPE_TYPE_BEZIER_OUTLINE, il_desc_curve_outline, ARRAY_SIZE(il_desc_curve_outline), vs_code_bezier_outline, sizeof(vs_code_bezier_outline)}, + {D2D_SHAPE_TYPE_ARC_OUTLINE, il_desc_curve_outline, ARRAY_SIZE(il_desc_curve_outline), + vs_code_arc_outline, sizeof(vs_code_arc_outline)}, {D2D_SHAPE_TYPE_TRIANGLE, il_desc_triangle, ARRAY_SIZE(il_desc_triangle), vs_code_triangle, sizeof(vs_code_triangle)}, {D2D_SHAPE_TYPE_CURVE, il_desc_curve, ARRAY_SIZE(il_desc_curve), diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c index a6a026aa21..c18b648aef 100644 --- a/dlls/d2d1/geometry.c +++ b/dlls/d2d1/geometry.c @@ -153,16 +153,16 @@ static void d2d_outline_vertex_set(struct d2d_outline_vertex *v, float x, float d2d_point_set(&v->next, next_x, next_y); }
-static void d2d_bezier_outline_vertex_set(struct d2d_bezier_outline_vertex *b, const D2D1_POINT_2F *position, +static void d2d_curve_outline_vertex_set(struct d2d_curve_outline_vertex *a, const D2D1_POINT_2F *position, const D2D1_POINT_2F *p0, const D2D1_POINT_2F *p1, const D2D1_POINT_2F *p2, float prev_x, float prev_y, float next_x, float next_y) { - b->position = *position; - b->p0 = *p0; - b->p1 = *p1; - b->p2 = *p2; - d2d_point_set(&b->prev, prev_x, prev_y); - d2d_point_set(&b->next, next_x, next_y); + a->position = *position; + a->p0 = *p0; + a->p1 = *p1; + a->p2 = *p2; + d2d_point_set(&a->prev, prev_x, prev_y); + d2d_point_set(&a->next, next_x, next_y); }
static void d2d_fp_two_sum(float *out, float a, float b) @@ -2197,7 +2197,7 @@ static BOOL d2d_geometry_outline_add_line_segment(struct d2d_geometry *geometry, static BOOL d2d_geometry_outline_add_bezier_segment(struct d2d_geometry *geometry, const D2D1_POINT_2F *p0, const D2D1_POINT_2F *p1, const D2D1_POINT_2F *p2) { - struct d2d_bezier_outline_vertex *b; + struct d2d_curve_outline_vertex *b; D2D1_POINT_2F r0, r1, r2; D2D1_POINT_2F q0, q1, q2; struct d2d_face *f; @@ -2239,13 +2239,13 @@ static BOOL d2d_geometry_outline_add_bezier_segment(struct d2d_geometry *geometr d2d_point_scale(&r2, -1.0f); }
- d2d_bezier_outline_vertex_set(&b[0], p0, p0, p1, p2, r0.x, r0.y, r0.x, r0.y); - d2d_bezier_outline_vertex_set(&b[1], p0, p0, p1, p2, -r0.x, -r0.y, -r0.x, -r0.y); - d2d_bezier_outline_vertex_set(&b[2], &q0, p0, p1, p2, r0.x, r0.y, r1.x, r1.y); - d2d_bezier_outline_vertex_set(&b[3], &q2, p0, p1, p2, -r1.x, -r1.y, -r1.x, -r1.y); - d2d_bezier_outline_vertex_set(&b[4], &q1, p0, p1, p2, r1.x, r1.y, r2.x, r2.y); - d2d_bezier_outline_vertex_set(&b[5], p2, p0, p1, p2, -r2.x, -r2.y, -r2.x, -r2.y); - d2d_bezier_outline_vertex_set(&b[6], p2, p0, p1, p2, r2.x, r2.y, r2.x, r2.y); + d2d_curve_outline_vertex_set(&b[0], p0, p0, p1, p2, r0.x, r0.y, r0.x, r0.y); + d2d_curve_outline_vertex_set(&b[1], p0, p0, p1, p2, -r0.x, -r0.y, -r0.x, -r0.y); + d2d_curve_outline_vertex_set(&b[2], &q0, p0, p1, p2, r0.x, r0.y, r1.x, r1.y); + d2d_curve_outline_vertex_set(&b[3], &q2, p0, p1, p2, -r1.x, -r1.y, -r1.x, -r1.y); + d2d_curve_outline_vertex_set(&b[4], &q1, p0, p1, p2, r1.x, r1.y, r2.x, r2.y); + d2d_curve_outline_vertex_set(&b[5], p2, p0, p1, p2, -r2.x, -r2.y, -r2.x, -r2.y); + d2d_curve_outline_vertex_set(&b[6], p2, p0, p1, p2, r2.x, r2.y, r2.x, r2.y); geometry->outline.bezier_count += 7;
d2d_face_set(&f[0], base_idx + 0, base_idx + 1, base_idx + 2); @@ -2261,9 +2261,53 @@ static BOOL d2d_geometry_outline_add_bezier_segment(struct d2d_geometry *geometr static BOOL d2d_geometry_outline_add_arc_quadrant(struct d2d_geometry *geometry, const D2D1_POINT_2F *p0, const D2D1_POINT_2F *p1, const D2D1_POINT_2F *p2) { - FIXME("Approximating arc quadrant with Bezier curve.\n"); + struct d2d_curve_outline_vertex *a; + D2D1_POINT_2F r0, r1; + struct d2d_face *f; + size_t base_idx; + + if (!d2d_array_reserve((void **)&geometry->outline.arcs, &geometry->outline.arcs_size, + geometry->outline.arc_count + 5, sizeof(*geometry->outline.arcs))) + { + ERR("Failed to grow outline arcs array.\n"); + return FALSE; + } + base_idx = geometry->outline.arc_count; + a = &geometry->outline.arcs[base_idx]; + + if (!d2d_array_reserve((void **)&geometry->outline.arc_faces, &geometry->outline.arc_faces_size, + geometry->outline.arc_face_count + 3, sizeof(*geometry->outline.arc_faces))) + { + ERR("Failed to grow outline faces array.\n"); + return FALSE; + } + f = &geometry->outline.arc_faces[geometry->outline.arc_face_count]; + + d2d_point_subtract(&r0, p1, p0); + d2d_point_subtract(&r1, p2, p1); + + d2d_point_normalise(&r0); + d2d_point_normalise(&r1);
- return d2d_geometry_outline_add_bezier_segment(geometry, p0, p1, p2); + if (d2d_point_ccw(p0, p1, p2) > 0.0f) + { + d2d_point_scale(&r0, -1.0f); + d2d_point_scale(&r1, -1.0f); + } + + d2d_curve_outline_vertex_set(&a[0], p0, p0, p1, p2, r0.x, r0.y, r0.x, r0.y); + d2d_curve_outline_vertex_set(&a[1], p0, p0, p1, p2, -r0.x, -r0.y, -r0.x, -r0.y); + d2d_curve_outline_vertex_set(&a[2], p1, p0, p1, p2, r0.x, r0.y, r1.x, r1.y); + d2d_curve_outline_vertex_set(&a[3], p2, p0, p1, p2, -r1.x, -r1.y, -r1.x, -r1.y); + d2d_curve_outline_vertex_set(&a[4], p2, p0, p1, p2, r1.x, r1.y, r1.x, r1.y); + geometry->outline.arc_count += 5; + + d2d_face_set(&f[0], base_idx + 0, base_idx + 1, base_idx + 2); + d2d_face_set(&f[1], base_idx + 2, base_idx + 1, base_idx + 3); + d2d_face_set(&f[2], base_idx + 2, base_idx + 4, base_idx + 3); + geometry->outline.arc_face_count += 3; + + return TRUE; }
static BOOL d2d_geometry_add_figure_outline(struct d2d_geometry *geometry, @@ -2368,6 +2412,8 @@ static BOOL d2d_geometry_fill_add_arc_triangle(struct d2d_geometry *geometry,
static void d2d_geometry_cleanup(struct d2d_geometry *geometry) { + heap_free(geometry->outline.arc_faces); + heap_free(geometry->outline.arcs); heap_free(geometry->outline.bezier_faces); heap_free(geometry->outline.beziers); heap_free(geometry->outline.faces); @@ -4519,6 +4565,8 @@ static ULONG STDMETHODCALLTYPE d2d_transformed_geometry_Release(ID2D1Transformed
if (!refcount) { + geometry->outline.arc_faces = NULL; + geometry->outline.arcs = NULL; geometry->outline.bezier_faces = NULL; geometry->outline.beziers = NULL; geometry->outline.faces = NULL;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com