d2d1: Implement linear gradient brushes.

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Henri Verbeet 2017-09-26 12:22:39 +02:00 committed by Alexandre Julliard
parent 24814f8f4a
commit e29e627064
4 changed files with 451 additions and 67 deletions

View File

@ -217,6 +217,14 @@ HRESULT d2d_gradient_create(ID2D1Factory *factory, ID3D10Device *device, const D
return S_OK;
}
static struct d2d_gradient *unsafe_impl_from_ID2D1GradientStopCollection(ID2D1GradientStopCollection *iface)
{
if (!iface)
return NULL;
assert(iface->lpVtbl == &d2d_gradient_vtbl);
return CONTAINING_RECORD(iface, struct d2d_gradient, ID2D1GradientStopCollection_iface);
}
static void d2d_brush_destroy(struct d2d_brush *brush)
{
ID2D1Factory_Release(brush->factory);
@ -429,7 +437,7 @@ static ULONG STDMETHODCALLTYPE d2d_linear_gradient_brush_Release(ID2D1LinearGrad
if (!refcount)
{
ID2D1GradientStopCollection_Release(brush->u.linear.gradient);
ID2D1GradientStopCollection_Release(&brush->u.linear.gradient->ID2D1GradientStopCollection_iface);
d2d_brush_destroy(brush);
}
@ -491,7 +499,7 @@ static void STDMETHODCALLTYPE d2d_linear_gradient_brush_SetStartPoint(ID2D1Linea
TRACE("iface %p, start_point {%.8e, %.8e}.\n", iface, start_point.x, start_point.y);
brush->u.linear.desc.startPoint = start_point;
brush->u.linear.start = start_point;
}
static void STDMETHODCALLTYPE d2d_linear_gradient_brush_SetEndPoint(ID2D1LinearGradientBrush *iface,
@ -501,7 +509,7 @@ static void STDMETHODCALLTYPE d2d_linear_gradient_brush_SetEndPoint(ID2D1LinearG
TRACE("iface %p, end_point {%.8e, %.8e}.\n", iface, end_point.x, end_point.y);
brush->u.linear.desc.endPoint = end_point;
brush->u.linear.end = end_point;
}
static D2D1_POINT_2F * STDMETHODCALLTYPE d2d_linear_gradient_brush_GetStartPoint(ID2D1LinearGradientBrush *iface,
@ -511,7 +519,7 @@ static D2D1_POINT_2F * STDMETHODCALLTYPE d2d_linear_gradient_brush_GetStartPoint
TRACE("iface %p, point %p.\n", iface, point);
*point = brush->u.linear.desc.startPoint;
*point = brush->u.linear.start;
return point;
}
@ -522,7 +530,7 @@ static D2D1_POINT_2F * STDMETHODCALLTYPE d2d_linear_gradient_brush_GetEndPoint(I
TRACE("iface %p, point %p.\n", iface, point);
*point = brush->u.linear.desc.endPoint;
*point = brush->u.linear.end;
return point;
}
@ -533,7 +541,7 @@ static void STDMETHODCALLTYPE d2d_linear_gradient_brush_GetGradientStopCollectio
TRACE("iface %p, gradient %p.\n", iface, gradient);
ID2D1GradientStopCollection_AddRef(*gradient = brush->u.linear.gradient);
ID2D1GradientStopCollection_AddRef(*gradient = &brush->u.linear.gradient->ID2D1GradientStopCollection_iface);
}
static const struct ID2D1LinearGradientBrushVtbl d2d_linear_gradient_brush_vtbl =
@ -561,8 +569,10 @@ HRESULT d2d_linear_gradient_brush_create(ID2D1Factory *factory, const D2D1_LINEA
d2d_brush_init(*brush, factory, D2D_BRUSH_TYPE_LINEAR, brush_desc,
(ID2D1BrushVtbl *)&d2d_linear_gradient_brush_vtbl);
(*brush)->u.linear.desc = *gradient_brush_desc;
ID2D1GradientStopCollection_AddRef((*brush)->u.linear.gradient = gradient);
(*brush)->u.linear.gradient = unsafe_impl_from_ID2D1GradientStopCollection(gradient);
ID2D1GradientStopCollection_AddRef(&(*brush)->u.linear.gradient->ID2D1GradientStopCollection_iface);
(*brush)->u.linear.start = gradient_brush_desc->startPoint;
(*brush)->u.linear.end = gradient_brush_desc->endPoint;
TRACE("Created brush %p.\n", *brush);
return S_OK;
@ -866,6 +876,14 @@ static BOOL d2d_brush_fill_cb(const struct d2d_brush *brush,
return TRUE;
case D2D_BRUSH_TYPE_LINEAR:
b = brush->transform;
d2d_point_transform(&cb->u.linear.start, &b, brush->u.linear.start.x, brush->u.linear.start.y);
d2d_point_transform(&cb->u.linear.end, &b, brush->u.linear.end.x, brush->u.linear.end.y);
cb->u.linear.stop_count = brush->u.linear.gradient->stop_count;
return TRUE;
case D2D_BRUSH_TYPE_BITMAP:
bitmap = brush->u.bitmap.bitmap;
@ -932,6 +950,11 @@ HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_b
return hr;
}
static void d2d_brush_bind_gradient(struct d2d_brush *brush, ID3D10Device *device, unsigned int brush_idx)
{
ID3D10Device_PSSetShaderResources(device, 2 + brush_idx, 1, &brush->u.linear.gradient->view);
}
static void d2d_brush_bind_bitmap(struct d2d_brush *brush, ID3D10Device *device, unsigned int brush_idx)
{
HRESULT hr;
@ -967,8 +990,21 @@ static void d2d_brush_bind_bitmap(struct d2d_brush *brush, ID3D10Device *device,
void d2d_brush_bind_resources(struct d2d_brush *brush, ID3D10Device *device, unsigned int brush_idx)
{
if (brush->type == D2D_BRUSH_TYPE_BITMAP)
d2d_brush_bind_bitmap(brush, device, brush_idx);
else if (brush->type != D2D_BRUSH_TYPE_SOLID)
FIXME("Unhandled brush type %#x.\n", brush->type);
switch (brush->type)
{
case D2D_BRUSH_TYPE_SOLID:
break;
case D2D_BRUSH_TYPE_LINEAR:
d2d_brush_bind_gradient(brush, device, brush_idx);
break;
case D2D_BRUSH_TYPE_BITMAP:
d2d_brush_bind_bitmap(brush, device, brush_idx);
break;
default:
FIXME("Unhandled brush type %#x.\n", brush->type);
break;
}
}

View File

@ -82,6 +82,12 @@ struct d2d_brush_cb
D2D1_COLOR_F colour;
} solid;
struct
{
D2D1_POINT_2F start;
D2D1_POINT_2F end;
unsigned int stop_count;
} linear;
struct
{
float _11, _21, _31, pad;
float _12, _22, _32;
@ -227,6 +233,12 @@ struct d2d_brush
D2D1_COLOR_F color;
} solid;
struct
{
struct d2d_gradient *gradient;
D2D1_POINT_2F start;
D2D1_POINT_2F end;
} linear;
struct
{
struct d2d_bitmap *bitmap;
D2D1_EXTEND_MODE extend_mode_x;
@ -234,11 +246,6 @@ struct d2d_brush
D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode;
ID3D10SamplerState *sampler_state;
} bitmap;
struct
{
D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES desc;
ID2D1GradientStopCollection *gradient;
} linear;
} u;
};

View File

@ -2578,6 +2578,7 @@ static HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_t
SamplerState s0, s1;
Texture2D t0, t1;
Buffer<float4> b0, b1;
struct input
{
@ -2586,6 +2587,43 @@ static HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_t
nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM;
};
float4 brush_linear(struct brush brush, Buffer<float4> b, float2 position)
{
float2 start, end, v_p, v_q;
float p, p_low, p_high;
float4 c_low, c_high;
uint stop_count, i;
start = brush.data[0].xy;
end = brush.data[0].zw;
stop_count = asuint(brush.data[1].x);
v_p = position - start;
v_q = end - start;
p = dot(v_q, v_p) / dot(v_q, v_q);
p_low = b.Load(0).x;
c_low = b.Load(1);
c_high = c_low;
if (p < p_low)
return c_low;
for (i = 1; i < stop_count; ++i)
{
p_high = b.Load(i * 2).x;
c_high = b.Load(i * 2 + 1);
if (p >= p_low && p <= p_high)
return lerp(c_low, c_high, (p - p_low) / (p_high - p_low));
p_low = p_high;
c_low = c_high;
}
return c_high;
}
float4 brush_bitmap(struct brush brush, Texture2D t, SamplerState s, float2 position)
{
float3 transform[2];
@ -2605,10 +2643,12 @@ static HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_t
return colour;
}
float4 sample_brush(struct brush brush, Texture2D t, SamplerState s, float2 position)
float4 sample_brush(struct brush brush, Texture2D t, SamplerState s, Buffer<float4> b, float2 position)
{
if (brush.type == BRUSH_TYPE_SOLID)
return brush.data[0] * brush.opacity;
if (brush.type == BRUSH_TYPE_LINEAR)
return brush_linear(brush, b, position) * brush.opacity;
if (brush.type == BRUSH_TYPE_BITMAP)
return brush_bitmap(brush, t, s, position) * brush.opacity;
return float4(0.0, 0.0, 0.0, brush.opacity);
@ -2618,9 +2658,9 @@ static HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_t
{
float4 colour;
colour = sample_brush(colour_brush, t0, s0, i.p);
colour = sample_brush(colour_brush, t0, s0, b0, i.p);
if (opacity_brush.type < BRUSH_TYPE_COUNT)
colour *= sample_brush(opacity_brush, t1, s1, i.p).a;
colour *= sample_brush(opacity_brush, t1, s1, b1, i.p).a;
if (outline)
{
@ -2654,66 +2694,139 @@ static HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_t
return colour;
}
#endif
0x43425844, 0x52e10ec7, 0xa7dbaa25, 0xb255a016, 0xf301e644, 0x00000001, 0x00000778, 0x00000003,
0x43425844, 0x8b6abf47, 0x898d4cd7, 0x0052859f, 0x209737c6, 0x00000001, 0x00001094, 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, 0x00000678,
0x00000040, 0x0000019e, 0x04000059, 0x00208e46, 0x00000000, 0x00000007, 0x0300005a, 0x00106000,
0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000f94,
0x00000040, 0x000003e5, 0x04000059, 0x00208e46, 0x00000000, 0x00000007, 0x0300005a, 0x00106000,
0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555,
0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x03001062, 0x00101032, 0x00000000, 0x03001062,
0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04000858, 0x00107000, 0x00000002, 0x00005555,
0x04000858, 0x00107000, 0x00000003, 0x00005555, 0x03001062, 0x00101032, 0x00000000, 0x03001062,
0x001010f2, 0x00000001, 0x03000862, 0x00101032, 0x00000002, 0x03000862, 0x00101032, 0x00000003,
0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000003, 0x09000038, 0x001000f2, 0x00000000,
0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x0000000a, 0x09000038, 0x001000f2, 0x00000000,
0x00208556, 0x00000000, 0x00000001, 0x00208e46, 0x00000000, 0x00000002, 0x0404001f, 0x0020800a,
0x00000000, 0x00000001, 0x08000020, 0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000001,
0x00004001, 0x00000002, 0x0304001f, 0x0010000a, 0x00000001, 0x0800000f, 0x00100022, 0x00000001,
0x00101046, 0x00000000, 0x00208046, 0x00000000, 0x00000002, 0x08000000, 0x00100012, 0x00000002,
0x0010001a, 0x00000001, 0x0020802a, 0x00000000, 0x00000002, 0x0800000f, 0x00100022, 0x00000001,
0x00101046, 0x00000000, 0x00208046, 0x00000000, 0x00000003, 0x08000000, 0x00100022, 0x00000002,
0x0010001a, 0x00000001, 0x0020802a, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000002,
0x00100046, 0x00000002, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000037, 0x00100082,
0x00000002, 0x0020803a, 0x00000000, 0x00000003, 0x00004001, 0x3f800000, 0x0010003a, 0x00000002,
0x08000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000002, 0x00208556, 0x00000000, 0x00000001,
0x01000015, 0x05000036, 0x00100012, 0x00000002, 0x00004001, 0x00000000, 0x06000036, 0x00100082,
0x00000002, 0x0020801a, 0x00000000, 0x00000001, 0x09000037, 0x001000f2, 0x00000000, 0x00100006,
0x00000001, 0x00100e46, 0x00000000, 0x00100c06, 0x00000002, 0x01000015, 0x0800004f, 0x00100012,
0x00004001, 0x00000001, 0x0304001f, 0x0010000a, 0x00000001, 0x09000000, 0x00100062, 0x00000001,
0x00101106, 0x00000000, 0x80208106, 0x00000041, 0x00000000, 0x00000002, 0x0a000000, 0x00100032,
0x00000002, 0x80208046, 0x00000041, 0x00000000, 0x00000002, 0x00208ae6, 0x00000000, 0x00000002,
0x0700000f, 0x00100022, 0x00000001, 0x00100046, 0x00000002, 0x00100596, 0x00000001, 0x0700000f,
0x00100042, 0x00000001, 0x00100046, 0x00000002, 0x00100046, 0x00000002, 0x0700000e, 0x00100022,
0x00000001, 0x0010001a, 0x00000001, 0x0010002a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000002,
0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000002, 0x0a00002d,
0x001000f2, 0x00000003, 0x00004002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00107e46,
0x00000002, 0x0700001d, 0x00100042, 0x00000001, 0x0010001a, 0x00000001, 0x0010000a, 0x00000002,
0x0304001f, 0x0010002a, 0x00000001, 0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000003,
0x05000036, 0x001000f2, 0x00000005, 0x00100e46, 0x00000003, 0x05000036, 0x001000f2, 0x00000006,
0x00100e46, 0x00000003, 0x05000036, 0x00100042, 0x00000001, 0x0010000a, 0x00000002, 0x05000036,
0x00100082, 0x00000001, 0x00004001, 0x00000001, 0x05000036, 0x00100022, 0x00000002, 0x00004001,
0x00000000, 0x01000030, 0x08000050, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x0020800a,
0x00000000, 0x00000003, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0x00000000, 0x03040003,
0x0010002a, 0x00000002, 0x07000029, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x00004001,
0x00000001, 0x0700002d, 0x001000f2, 0x00000007, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002,
0x0700001e, 0x00100042, 0x00000002, 0x0010002a, 0x00000002, 0x00004001, 0x00000001, 0x0700002d,
0x001000f2, 0x00000008, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002, 0x0700001d, 0x00100042,
0x00000002, 0x0010001a, 0x00000001, 0x0010002a, 0x00000001, 0x0700001d, 0x00100082, 0x00000002,
0x0010000a, 0x00000007, 0x0010001a, 0x00000001, 0x07000001, 0x00100042, 0x00000002, 0x0010003a,
0x00000002, 0x0010002a, 0x00000002, 0x0304001f, 0x0010002a, 0x00000002, 0x08000000, 0x00100082,
0x00000002, 0x8010002a, 0x00000041, 0x00000001, 0x0010001a, 0x00000001, 0x08000000, 0x00100022,
0x00000007, 0x8010002a, 0x00000041, 0x00000001, 0x0010000a, 0x00000007, 0x0700000e, 0x00100082,
0x00000002, 0x0010003a, 0x00000002, 0x0010001a, 0x00000007, 0x08000000, 0x001000f2, 0x00000009,
0x80100e46, 0x00000041, 0x00000005, 0x00100e46, 0x00000008, 0x09000032, 0x001000f2, 0x00000009,
0x00100ff6, 0x00000002, 0x00100e46, 0x00000009, 0x00100e46, 0x00000005, 0x05000036, 0x001000f2,
0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0xffffffff,
0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000009, 0x01000002, 0x01000015, 0x05000036,
0x001000f2, 0x00000005, 0x00100e46, 0x00000008, 0x05000036, 0x00100042, 0x00000001, 0x0010000a,
0x00000007, 0x0700001e, 0x00100082, 0x00000001, 0x0010003a, 0x00000001, 0x00004001, 0x00000001,
0x05000036, 0x001000f2, 0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002,
0x0010002a, 0x00000002, 0x01000016, 0x09000037, 0x001000f2, 0x00000003, 0x00100556, 0x00000002,
0x00100e46, 0x00000004, 0x00100e46, 0x00000006, 0x01000015, 0x08000038, 0x001000f2, 0x00000000,
0x00100e46, 0x00000003, 0x00208556, 0x00000000, 0x00000001, 0x01000015, 0x0300001f, 0x0010000a,
0x00000001, 0x08000020, 0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000001, 0x00004001,
0x00000002, 0x0304001f, 0x0010000a, 0x00000001, 0x0800000f, 0x00100022, 0x00000001, 0x00101046,
0x00000000, 0x00208046, 0x00000000, 0x00000002, 0x08000000, 0x00100012, 0x00000002, 0x0010001a,
0x00000001, 0x0020802a, 0x00000000, 0x00000002, 0x0800000f, 0x00100022, 0x00000001, 0x00101046,
0x00000000, 0x00208046, 0x00000000, 0x00000003, 0x08000000, 0x00100022, 0x00000002, 0x0010001a,
0x00000001, 0x0020802a, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000002, 0x00100046,
0x00000002, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000037, 0x00100082, 0x00000002,
0x0020803a, 0x00000000, 0x00000003, 0x00004001, 0x3f800000, 0x0010003a, 0x00000002, 0x08000038,
0x001000f2, 0x00000000, 0x00100e46, 0x00000002, 0x00208556, 0x00000000, 0x00000001, 0x01000015,
0x05000036, 0x00100012, 0x00000002, 0x00004001, 0x00000000, 0x06000036, 0x00100082, 0x00000002,
0x0020801a, 0x00000000, 0x00000001, 0x09000037, 0x001000f2, 0x00000000, 0x00100006, 0x00000001,
0x00100e46, 0x00000000, 0x00100c06, 0x00000002, 0x01000015, 0x01000015, 0x0800004f, 0x00100012,
0x00000001, 0x0020800a, 0x00000000, 0x00000004, 0x00004001, 0x00000003, 0x0304001f, 0x0010000a,
0x00000001, 0x09000038, 0x00100012, 0x00000001, 0x0020801a, 0x00000000, 0x00000004, 0x0020803a,
0x00000000, 0x00000005, 0x0404001f, 0x0020800a, 0x00000000, 0x00000004, 0x08000020, 0x00100022,
0x00000001, 0x0020800a, 0x00000000, 0x00000004, 0x00004001, 0x00000002, 0x0304001f, 0x0010001a,
0x00000001, 0x0800000f, 0x00100042, 0x00000001, 0x00101046, 0x00000000, 0x00208046, 0x00000000,
0x00000005, 0x08000000, 0x00100012, 0x00000002, 0x0010002a, 0x00000001, 0x0020802a, 0x00000000,
0x00000005, 0x0800000f, 0x00100042, 0x00000001, 0x00101046, 0x00000000, 0x00208046, 0x00000000,
0x00000006, 0x08000000, 0x00100022, 0x00000002, 0x0010002a, 0x00000001, 0x0020802a, 0x00000000,
0x00000006, 0x09000045, 0x001000f2, 0x00000002, 0x00100046, 0x00000002, 0x00107e46, 0x00000001,
0x00106000, 0x00000001, 0x0a000037, 0x00100042, 0x00000001, 0x0020803a, 0x00000000, 0x00000006,
0x00004001, 0x3f800000, 0x0010003a, 0x00000002, 0x08000038, 0x00100012, 0x00000001, 0x0010002a,
0x00000001, 0x0020801a, 0x00000000, 0x00000004, 0x01000015, 0x0a000037, 0x00100012, 0x00000001,
0x0010001a, 0x00000001, 0x0010000a, 0x00000001, 0x0020801a, 0x00000000, 0x00000004, 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,
0x00000001, 0x0020800a, 0x00000000, 0x00000004, 0x00004001, 0x00000001, 0x0304001f, 0x0010001a,
0x00000001, 0x09000000, 0x001000c2, 0x00000001, 0x00101406, 0x00000000, 0x80208406, 0x00000041,
0x00000000, 0x00000005, 0x0a000000, 0x00100032, 0x00000002, 0x80208046, 0x00000041, 0x00000000,
0x00000005, 0x00208ae6, 0x00000000, 0x00000005, 0x0700000f, 0x00100042, 0x00000001, 0x00100046,
0x00000002, 0x00100ae6, 0x00000001, 0x0700000f, 0x00100082, 0x00000001, 0x00100046, 0x00000002,
0x00100046, 0x00000002, 0x0700000e, 0x00100042, 0x00000001, 0x0010002a, 0x00000001, 0x0010003a,
0x00000001, 0x0a00002d, 0x001000f2, 0x00000002, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00107e46, 0x00000003, 0x0a00002d, 0x001000f2, 0x00000003, 0x00004002, 0x00000001,
0x00000001, 0x00000001, 0x00000001, 0x00107e46, 0x00000003, 0x0700001d, 0x00100082, 0x00000001,
0x0010002a, 0x00000001, 0x0010000a, 0x00000002, 0x0304001f, 0x0010003a, 0x00000001, 0x05000036,
0x00100082, 0x00000001, 0x0010003a, 0x00000003, 0x05000036, 0x00100022, 0x00000002, 0x0010000a,
0x00000002, 0x05000036, 0x001000c2, 0x00000002, 0x00100ff6, 0x00000003, 0x08000036, 0x00100032,
0x00000003, 0x00004002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x01000030, 0x08000050,
0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x0020800a, 0x00000000, 0x00000006, 0x05000036,
0x00100022, 0x00000003, 0x00004001, 0x00000000, 0x03040003, 0x0010002a, 0x00000003, 0x07000029,
0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d, 0x001000f2,
0x00000004, 0x00100aa6, 0x00000003, 0x00107e46, 0x00000003, 0x0700001e, 0x00100042, 0x00000003,
0x0010002a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d, 0x001000f2, 0x00000005, 0x00100aa6,
0x00000003, 0x00107e46, 0x00000003, 0x0700001d, 0x00100042, 0x00000003, 0x0010002a, 0x00000001,
0x0010001a, 0x00000002, 0x0700001d, 0x00100022, 0x00000004, 0x0010000a, 0x00000004, 0x0010002a,
0x00000001, 0x07000001, 0x00100042, 0x00000003, 0x0010002a, 0x00000003, 0x0010001a, 0x00000004,
0x0304001f, 0x0010002a, 0x00000003, 0x08000000, 0x00100022, 0x00000004, 0x0010002a, 0x00000001,
0x8010001a, 0x00000041, 0x00000002, 0x08000000, 0x00100042, 0x00000004, 0x8010001a, 0x00000041,
0x00000002, 0x0010000a, 0x00000004, 0x0700000e, 0x00100022, 0x00000004, 0x0010001a, 0x00000004,
0x0010002a, 0x00000004, 0x08000000, 0x00100042, 0x00000004, 0x8010002a, 0x00000041, 0x00000002,
0x0010003a, 0x00000005, 0x09000032, 0x00100022, 0x00000004, 0x0010001a, 0x00000004, 0x0010002a,
0x00000004, 0x0010002a, 0x00000002, 0x05000036, 0x00100082, 0x00000002, 0x0010003a, 0x00000005,
0x05000036, 0x00100022, 0x00000003, 0x00004001, 0xffffffff, 0x05000036, 0x00100082, 0x00000001,
0x0010001a, 0x00000004, 0x01000002, 0x01000015, 0x05000036, 0x00100022, 0x00000002, 0x0010000a,
0x00000004, 0x05000036, 0x00100042, 0x00000002, 0x0010003a, 0x00000005, 0x0700001e, 0x00100012,
0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x05000036, 0x00100082, 0x00000002,
0x0010003a, 0x00000005, 0x05000036, 0x00100032, 0x00000003, 0x00100086, 0x00000003, 0x01000016,
0x09000037, 0x00100042, 0x00000001, 0x0010001a, 0x00000003, 0x0010003a, 0x00000001, 0x0010003a,
0x00000002, 0x01000012, 0x05000036, 0x00100042, 0x00000001, 0x0010003a, 0x00000003, 0x01000015,
0x08000038, 0x00100012, 0x00000001, 0x0010002a, 0x00000001, 0x0020801a, 0x00000000, 0x00000004,
0x01000015, 0x0300001f, 0x0010001a, 0x00000001, 0x08000020, 0x00100022, 0x00000001, 0x0020800a,
0x00000000, 0x00000004, 0x00004001, 0x00000002, 0x0304001f, 0x0010001a, 0x00000001, 0x0800000f,
0x00100042, 0x00000001, 0x00101046, 0x00000000, 0x00208046, 0x00000000, 0x00000005, 0x08000000,
0x00100012, 0x00000002, 0x0010002a, 0x00000001, 0x0020802a, 0x00000000, 0x00000005, 0x0800000f,
0x00100042, 0x00000001, 0x00101046, 0x00000000, 0x00208046, 0x00000000, 0x00000006, 0x08000000,
0x00100022, 0x00000002, 0x0010002a, 0x00000001, 0x0020802a, 0x00000000, 0x00000006, 0x09000045,
0x001000f2, 0x00000002, 0x00100046, 0x00000002, 0x00107e46, 0x00000001, 0x00106000, 0x00000001,
0x0a000037, 0x00100042, 0x00000001, 0x0020803a, 0x00000000, 0x00000006, 0x00004001, 0x3f800000,
0x0010003a, 0x00000002, 0x08000038, 0x00100012, 0x00000001, 0x0010002a, 0x00000001, 0x0020801a,
0x00000000, 0x00000004, 0x01000015, 0x0a000037, 0x00100012, 0x00000001, 0x0010001a, 0x00000001,
0x0010000a, 0x00000001, 0x0020801a, 0x00000000, 0x00000004, 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,
};
static const struct shape_info
{

View File

@ -274,6 +274,27 @@ static void release_resource_readback(struct resource_readback *rb)
ID3D10Resource_Release(rb->resource);
}
static DWORD get_readback_colour(struct resource_readback *rb, unsigned int x, unsigned int y)
{
return ((DWORD *)((BYTE *)rb->map_desc.pData + y * rb->map_desc.RowPitch))[x];
}
static BOOL compare_colour(DWORD c1, DWORD c2, BYTE max_diff)
{
if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff)
return FALSE;
c1 >>= 8; c2 >>= 8;
if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff)
return FALSE;
c1 >>= 8; c2 >>= 8;
if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff)
return FALSE;
c1 >>= 8; c2 >>= 8;
if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff)
return FALSE;
return TRUE;
}
static BOOL compare_float(float f, float g, unsigned int ulps)
{
int x = *(int *)&f;
@ -1674,6 +1695,212 @@ static void test_bitmap_brush(void)
DestroyWindow(window);
}
static void test_linear_brush(void)
{
D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES gradient_properties;
ID2D1GradientStopCollection *gradient, *tmp_gradient;
ID2D1TransformedGeometry *transformed_geometry;
ID2D1RectangleGeometry *rectangle_geometry;
D2D1_MATRIX_3X2_F matrix, tmp_matrix;
ID2D1LinearGradientBrush *brush;
struct resource_readback rb;
IDXGISwapChain *swapchain;
ID2D1RenderTarget *rt;
ID3D10Device1 *device;
IDXGISurface *surface;
ID2D1Factory *factory;
D2D1_COLOR_F colour;
D2D1_POINT_2F p;
unsigned int i;
ULONG refcount;
D2D1_RECT_F r;
float opacity;
HWND window;
HRESULT hr;
static const D2D1_GRADIENT_STOP stops[] =
{
{0.0f, {1.0f, 0.0f, 0.0f, 1.0f}},
{0.5f, {0.0f, 1.0f, 0.0f, 1.0f}},
{1.0f, {0.0f, 0.0f, 1.0f, 1.0f}},
};
static const struct
{
unsigned int x, y;
DWORD colour;
}
test1[] =
{
{80, 80, 0xff857a00}, {240, 80, 0xff926d00}, {400, 80, 0xff9f6000}, {560, 80, 0xffac5300},
{80, 240, 0xff00eb14}, {240, 240, 0xff00f807}, {400, 240, 0xff06f900}, {560, 240, 0xff13ec00},
{80, 400, 0xff0053ac}, {240, 400, 0xff005fa0}, {400, 400, 0xff006c93}, {560, 400, 0xff007986},
},
test2[] =
{
{ 40, 30, 0xff005ba4}, {120, 30, 0xffffffff}, { 40, 60, 0xffffffff}, { 80, 60, 0xff00b44b},
{120, 60, 0xff006c93}, {200, 60, 0xffffffff}, { 40, 90, 0xffffffff}, {120, 90, 0xff0ef100},
{160, 90, 0xff00c53a}, {200, 90, 0xffffffff}, { 80, 120, 0xffffffff}, {120, 120, 0xffaf5000},
{160, 120, 0xff679800}, {200, 120, 0xff1fe000}, {240, 120, 0xffffffff}, {160, 150, 0xffffffff},
{200, 150, 0xffc03e00}, {240, 150, 0xffffffff}, {280, 150, 0xffffffff}, {320, 150, 0xffffffff},
{240, 180, 0xffffffff}, {280, 180, 0xffff4040}, {320, 180, 0xffff4040}, {380, 180, 0xffffffff},
{200, 210, 0xffffffff}, {240, 210, 0xffa99640}, {280, 210, 0xffb28d40}, {320, 210, 0xffbb8440},
{360, 210, 0xffc47b40}, {400, 210, 0xffffffff}, {200, 240, 0xffffffff}, {280, 240, 0xff41fd40},
{320, 240, 0xff49f540}, {360, 240, 0xff52ec40}, {440, 240, 0xffffffff}, {240, 270, 0xffffffff},
{280, 270, 0xff408eb0}, {320, 270, 0xff4097a7}, {360, 270, 0xff40a19e}, {440, 270, 0xffffffff},
{280, 300, 0xffffffff}, {320, 300, 0xff4040ff}, {360, 300, 0xff4040ff}, {400, 300, 0xff406ad4},
{440, 300, 0xff4061de}, {480, 300, 0xff4057e7}, {520, 300, 0xff404ef1}, {280, 330, 0xffffffff},
{360, 330, 0xffffffff}, {400, 330, 0xff40c17e}, {440, 330, 0xff40b788}, {480, 330, 0xff40ae91},
{520, 330, 0xff40a49b}, {400, 360, 0xff57e740}, {440, 360, 0xff4ef140}, {480, 360, 0xff44fb40},
{520, 360, 0xff40fa45}, {400, 390, 0xffae9140}, {440, 390, 0xffa49b40}, {480, 390, 0xff9aa540},
{520, 390, 0xff90ae40},
};
if (!(device = create_device()))
{
skip("Failed to create device, skipping tests.\n");
return;
}
window = create_window();
swapchain = create_swapchain(device, window, TRUE);
hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
rt = create_render_target(surface);
ok(!!rt, "Failed to create render target.\n");
ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops, sizeof(stops) / sizeof(*stops),
D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, &gradient);
ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
set_point(&gradient_properties.startPoint, 320.0f, 0.0f);
set_point(&gradient_properties.endPoint, 0.0f, 960.0f);
hr = ID2D1RenderTarget_CreateLinearGradientBrush(rt, &gradient_properties, NULL, gradient, &brush);
ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
opacity = ID2D1LinearGradientBrush_GetOpacity(brush);
ok(opacity == 1.0f, "Got unexpected opacity %.8e.\n", opacity);
set_matrix_identity(&matrix);
ID2D1LinearGradientBrush_GetTransform(brush, &tmp_matrix);
ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
"Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
p = ID2D1LinearGradientBrush_GetStartPoint(brush);
ok(compare_point(&p, 320.0f, 0.0f, 0), "Got unexpected start point {%.8e, %.8e}.\n", p.x, p.y);
p = ID2D1LinearGradientBrush_GetEndPoint(brush);
ok(compare_point(&p, 0.0f, 960.0f, 0), "Got unexpected end point {%.8e, %.8e}.\n", p.x, p.y);
ID2D1LinearGradientBrush_GetGradientStopCollection(brush, &tmp_gradient);
ok(tmp_gradient == gradient, "Got unexpected gradient %p, expected %p.\n", tmp_gradient, gradient);
ID2D1GradientStopCollection_Release(tmp_gradient);
ID2D1RenderTarget_BeginDraw(rt);
set_color(&colour, 1.0f, 1.0f, 1.0f, 1.0f);
ID2D1RenderTarget_Clear(rt, &colour);
set_rect(&r, 0.0f, 0.0f, 320.0f, 960.0f);
ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
get_surface_readback(surface, &rb);
for (i = 0; i < sizeof(test1) / sizeof(*test1); ++i)
{
DWORD colour;
colour = get_readback_colour(&rb, test1[i].x, test1[i].y);
ok(compare_colour(colour, test1[i].colour, 1),
"Got unexpected colour 0x%08x at position {%u, %u}.\n",
colour, test1[i].x, test1[i].y);
}
release_resource_readback(&rb);
ID2D1RenderTarget_BeginDraw(rt);
ID2D1RenderTarget_Clear(rt, &colour);
set_matrix_identity(&matrix);
skew_matrix(&matrix, 0.2146f, 1.575f);
ID2D1RenderTarget_SetTransform(rt, &matrix);
set_matrix_identity(&matrix);
translate_matrix(&matrix, 0.0f, 240.0f);
scale_matrix(&matrix, 0.25f, -0.25f);
ID2D1LinearGradientBrush_SetTransform(brush, &matrix);
set_rect(&r, 0.0f, 0.0f, 80.0f, 240.0f);
ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
set_matrix_identity(&matrix);
scale_matrix(&matrix, 0.5f, 2.0f);
translate_matrix(&matrix, 320.0f, 240.0f);
rotate_matrix(&matrix, M_PI / 4.0f);
ID2D1RenderTarget_SetTransform(rt, &matrix);
set_matrix_identity(&matrix);
translate_matrix(&matrix, 0.0f, -50.0f);
scale_matrix(&matrix, 0.1f, 0.1f);
rotate_matrix(&matrix, -M_PI / 3.0f);
ID2D1LinearGradientBrush_SetTransform(brush, &matrix);
ID2D1LinearGradientBrush_SetOpacity(brush, 0.75f);
set_rect(&r, -80.0f, -60.0f, 80.0f, 60.0f);
ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
ID2D1RenderTarget_GetFactory(rt, &factory);
set_rect(&r, -1.0f, -1.0f, 1.0f, 1.0f);
hr = ID2D1Factory_CreateRectangleGeometry(factory, &r, &rectangle_geometry);
ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
set_matrix_identity(&matrix);
translate_matrix(&matrix, 228.5f, 714.0f);
scale_matrix(&matrix, 40.0f, 120.0f);
hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)rectangle_geometry,
&matrix, &transformed_geometry);
ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
ID2D1RectangleGeometry_Release(rectangle_geometry);
set_matrix_identity(&matrix);
ID2D1RenderTarget_SetTransform(rt, &matrix);
ID2D1LinearGradientBrush_SetTransform(brush, &matrix);
set_point(&p, 188.5f, 834.0f);
ID2D1LinearGradientBrush_SetStartPoint(brush, p);
set_point(&p, 268.5f, 594.0f);
ID2D1LinearGradientBrush_SetEndPoint(brush, p);
ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
ID2D1TransformedGeometry_Release(transformed_geometry);
ID2D1Factory_Release(factory);
hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
get_surface_readback(surface, &rb);
for (i = 0; i < sizeof(test2) / sizeof(*test2); ++i)
{
DWORD colour;
colour = get_readback_colour(&rb, test2[i].x, test2[i].y);
ok(compare_colour(colour, test2[i].colour, 1),
"Got unexpected colour 0x%08x at position {%u, %u}.\n",
colour, test2[i].x, test2[i].y);
}
release_resource_readback(&rb);
ID2D1LinearGradientBrush_Release(brush);
refcount = ID2D1GradientStopCollection_Release(gradient);
ok(!refcount, "Gradient has %u references left.\n", refcount);
ID2D1RenderTarget_Release(rt);
IDXGISurface_Release(surface);
IDXGISwapChain_Release(swapchain);
ID3D10Device1_Release(device);
DestroyWindow(window);
}
static void fill_geometry_sink(ID2D1GeometrySink *sink)
{
D2D1_POINT_2F point;
@ -5949,6 +6176,7 @@ START_TEST(d2d1)
test_state_block();
test_color_brush();
test_bitmap_brush();
test_linear_brush();
test_path_geometry();
test_rectangle_geometry();
test_rounded_rectangle_geometry();