Commit e29e6270 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

d2d1: Implement linear gradient brushes.

parent 24814f8f
...@@ -217,6 +217,14 @@ HRESULT d2d_gradient_create(ID2D1Factory *factory, ID3D10Device *device, const D ...@@ -217,6 +217,14 @@ HRESULT d2d_gradient_create(ID2D1Factory *factory, ID3D10Device *device, const D
return S_OK; 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) static void d2d_brush_destroy(struct d2d_brush *brush)
{ {
ID2D1Factory_Release(brush->factory); ID2D1Factory_Release(brush->factory);
...@@ -429,7 +437,7 @@ static ULONG STDMETHODCALLTYPE d2d_linear_gradient_brush_Release(ID2D1LinearGrad ...@@ -429,7 +437,7 @@ static ULONG STDMETHODCALLTYPE d2d_linear_gradient_brush_Release(ID2D1LinearGrad
if (!refcount) if (!refcount)
{ {
ID2D1GradientStopCollection_Release(brush->u.linear.gradient); ID2D1GradientStopCollection_Release(&brush->u.linear.gradient->ID2D1GradientStopCollection_iface);
d2d_brush_destroy(brush); d2d_brush_destroy(brush);
} }
...@@ -491,7 +499,7 @@ static void STDMETHODCALLTYPE d2d_linear_gradient_brush_SetStartPoint(ID2D1Linea ...@@ -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); 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, static void STDMETHODCALLTYPE d2d_linear_gradient_brush_SetEndPoint(ID2D1LinearGradientBrush *iface,
...@@ -501,7 +509,7 @@ static void STDMETHODCALLTYPE d2d_linear_gradient_brush_SetEndPoint(ID2D1LinearG ...@@ -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); 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, 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 ...@@ -511,7 +519,7 @@ static D2D1_POINT_2F * STDMETHODCALLTYPE d2d_linear_gradient_brush_GetStartPoint
TRACE("iface %p, point %p.\n", iface, point); TRACE("iface %p, point %p.\n", iface, point);
*point = brush->u.linear.desc.startPoint; *point = brush->u.linear.start;
return point; return point;
} }
...@@ -522,7 +530,7 @@ static D2D1_POINT_2F * STDMETHODCALLTYPE d2d_linear_gradient_brush_GetEndPoint(I ...@@ -522,7 +530,7 @@ static D2D1_POINT_2F * STDMETHODCALLTYPE d2d_linear_gradient_brush_GetEndPoint(I
TRACE("iface %p, point %p.\n", iface, point); TRACE("iface %p, point %p.\n", iface, point);
*point = brush->u.linear.desc.endPoint; *point = brush->u.linear.end;
return point; return point;
} }
...@@ -533,7 +541,7 @@ static void STDMETHODCALLTYPE d2d_linear_gradient_brush_GetGradientStopCollectio ...@@ -533,7 +541,7 @@ static void STDMETHODCALLTYPE d2d_linear_gradient_brush_GetGradientStopCollectio
TRACE("iface %p, gradient %p.\n", iface, gradient); 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 = static const struct ID2D1LinearGradientBrushVtbl d2d_linear_gradient_brush_vtbl =
...@@ -561,8 +569,10 @@ HRESULT d2d_linear_gradient_brush_create(ID2D1Factory *factory, const D2D1_LINEA ...@@ -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, d2d_brush_init(*brush, factory, D2D_BRUSH_TYPE_LINEAR, brush_desc,
(ID2D1BrushVtbl *)&d2d_linear_gradient_brush_vtbl); (ID2D1BrushVtbl *)&d2d_linear_gradient_brush_vtbl);
(*brush)->u.linear.desc = *gradient_brush_desc; (*brush)->u.linear.gradient = unsafe_impl_from_ID2D1GradientStopCollection(gradient);
ID2D1GradientStopCollection_AddRef((*brush)->u.linear.gradient = 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); TRACE("Created brush %p.\n", *brush);
return S_OK; return S_OK;
...@@ -866,6 +876,14 @@ static BOOL d2d_brush_fill_cb(const struct d2d_brush *brush, ...@@ -866,6 +876,14 @@ static BOOL d2d_brush_fill_cb(const struct d2d_brush *brush,
return TRUE; 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: case D2D_BRUSH_TYPE_BITMAP:
bitmap = brush->u.bitmap.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 ...@@ -932,6 +950,11 @@ HRESULT d2d_brush_get_ps_cb(struct d2d_brush *brush, struct d2d_brush *opacity_b
return hr; 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) static void d2d_brush_bind_bitmap(struct d2d_brush *brush, ID3D10Device *device, unsigned int brush_idx)
{ {
HRESULT hr; HRESULT hr;
...@@ -967,8 +990,21 @@ static void d2d_brush_bind_bitmap(struct d2d_brush *brush, ID3D10Device *device, ...@@ -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) void d2d_brush_bind_resources(struct d2d_brush *brush, ID3D10Device *device, unsigned int brush_idx)
{ {
if (brush->type == D2D_BRUSH_TYPE_BITMAP) switch (brush->type)
d2d_brush_bind_bitmap(brush, device, brush_idx); {
else if (brush->type != D2D_BRUSH_TYPE_SOLID) case D2D_BRUSH_TYPE_SOLID:
FIXME("Unhandled brush type %#x.\n", brush->type); 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;
}
} }
...@@ -83,6 +83,12 @@ struct d2d_brush_cb ...@@ -83,6 +83,12 @@ struct d2d_brush_cb
} solid; } solid;
struct struct
{ {
D2D1_POINT_2F start;
D2D1_POINT_2F end;
unsigned int stop_count;
} linear;
struct
{
float _11, _21, _31, pad; float _11, _21, _31, pad;
float _12, _22, _32; float _12, _22, _32;
BOOL ignore_alpha; BOOL ignore_alpha;
...@@ -228,17 +234,18 @@ struct d2d_brush ...@@ -228,17 +234,18 @@ struct d2d_brush
} solid; } solid;
struct struct
{ {
struct d2d_gradient *gradient;
D2D1_POINT_2F start;
D2D1_POINT_2F end;
} linear;
struct
{
struct d2d_bitmap *bitmap; struct d2d_bitmap *bitmap;
D2D1_EXTEND_MODE extend_mode_x; D2D1_EXTEND_MODE extend_mode_x;
D2D1_EXTEND_MODE extend_mode_y; D2D1_EXTEND_MODE extend_mode_y;
D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode; D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode;
ID3D10SamplerState *sampler_state; ID3D10SamplerState *sampler_state;
} bitmap; } bitmap;
struct
{
D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES desc;
ID2D1GradientStopCollection *gradient;
} linear;
} u; } u;
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment