2 * Copyright 2014 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "wine/port.h"
22 #include "d2d1_private.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(d2d
);
26 static inline struct d2d_gradient
*impl_from_ID2D1GradientStopCollection(ID2D1GradientStopCollection
*iface
)
28 return CONTAINING_RECORD(iface
, struct d2d_gradient
, ID2D1GradientStopCollection_iface
);
31 static HRESULT STDMETHODCALLTYPE
d2d_gradient_QueryInterface(ID2D1GradientStopCollection
*iface
,
32 REFIID iid
, void **out
)
34 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
36 if (IsEqualGUID(iid
, &IID_ID2D1GradientStopCollection
)
37 || IsEqualGUID(iid
, &IID_ID2D1Resource
)
38 || IsEqualGUID(iid
, &IID_IUnknown
))
40 ID2D1GradientStopCollection_AddRef(iface
);
45 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
51 static ULONG STDMETHODCALLTYPE
d2d_gradient_AddRef(ID2D1GradientStopCollection
*iface
)
53 struct d2d_gradient
*gradient
= impl_from_ID2D1GradientStopCollection(iface
);
54 ULONG refcount
= InterlockedIncrement(&gradient
->refcount
);
56 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
61 static ULONG STDMETHODCALLTYPE
d2d_gradient_Release(ID2D1GradientStopCollection
*iface
)
63 struct d2d_gradient
*gradient
= impl_from_ID2D1GradientStopCollection(iface
);
64 ULONG refcount
= InterlockedDecrement(&gradient
->refcount
);
66 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
70 HeapFree(GetProcessHeap(), 0, gradient
->stops
);
71 ID3D10ShaderResourceView_Release(gradient
->view
);
72 ID2D1Factory_Release(gradient
->factory
);
73 HeapFree(GetProcessHeap(), 0, gradient
);
79 static void STDMETHODCALLTYPE
d2d_gradient_GetFactory(ID2D1GradientStopCollection
*iface
, ID2D1Factory
**factory
)
81 struct d2d_gradient
*gradient
= impl_from_ID2D1GradientStopCollection(iface
);
83 TRACE("iface %p, factory %p.\n", iface
, factory
);
85 ID2D1Factory_AddRef(*factory
= gradient
->factory
);
88 static UINT32 STDMETHODCALLTYPE
d2d_gradient_GetGradientStopCount(ID2D1GradientStopCollection
*iface
)
90 struct d2d_gradient
*gradient
= impl_from_ID2D1GradientStopCollection(iface
);
92 TRACE("iface %p.\n", iface
);
94 return gradient
->stop_count
;
97 static void STDMETHODCALLTYPE
d2d_gradient_GetGradientStops(ID2D1GradientStopCollection
*iface
,
98 D2D1_GRADIENT_STOP
*stops
, UINT32 stop_count
)
100 struct d2d_gradient
*gradient
= impl_from_ID2D1GradientStopCollection(iface
);
102 TRACE("iface %p, stops %p, stop_count %u.\n", iface
, stops
, stop_count
);
104 memcpy(stops
, gradient
->stops
, min(gradient
->stop_count
, stop_count
) * sizeof(*stops
));
107 static D2D1_GAMMA STDMETHODCALLTYPE
d2d_gradient_GetColorInterpolationGamma(ID2D1GradientStopCollection
*iface
)
109 FIXME("iface %p stub!\n", iface
);
111 return D2D1_GAMMA_1_0
;
114 static D2D1_EXTEND_MODE STDMETHODCALLTYPE
d2d_gradient_GetExtendMode(ID2D1GradientStopCollection
*iface
)
116 FIXME("iface %p stub!\n", iface
);
118 return D2D1_EXTEND_MODE_CLAMP
;
121 static const struct ID2D1GradientStopCollectionVtbl d2d_gradient_vtbl
=
123 d2d_gradient_QueryInterface
,
125 d2d_gradient_Release
,
126 d2d_gradient_GetFactory
,
127 d2d_gradient_GetGradientStopCount
,
128 d2d_gradient_GetGradientStops
,
129 d2d_gradient_GetColorInterpolationGamma
,
130 d2d_gradient_GetExtendMode
,
133 HRESULT
d2d_gradient_create(ID2D1Factory
*factory
, ID3D10Device
*device
, const D2D1_GRADIENT_STOP
*stops
,
134 UINT32 stop_count
, D2D1_GAMMA gamma
, D2D1_EXTEND_MODE extend_mode
, struct d2d_gradient
**gradient
)
136 D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc
;
137 D3D10_SUBRESOURCE_DATA buffer_data
;
138 ID3D10ShaderResourceView
*view
;
139 D3D10_BUFFER_DESC buffer_desc
;
140 struct d2d_vec4
*data
;
141 ID3D10Buffer
*buffer
;
145 if (!(data
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, 2 * stop_count
* sizeof(*data
))))
147 ERR("Failed to allocate data.\n");
148 return E_OUTOFMEMORY
;
151 for (i
= 0; i
< stop_count
; ++i
)
153 data
[i
* 2].x
= stops
[i
].position
;
154 data
[i
* 2 + 1].x
= stops
[i
].color
.r
;
155 data
[i
* 2 + 1].y
= stops
[i
].color
.g
;
156 data
[i
* 2 + 1].z
= stops
[i
].color
.b
;
157 data
[i
* 2 + 1].w
= stops
[i
].color
.a
;
160 buffer_desc
.ByteWidth
= 2 * stop_count
* sizeof(*data
);
161 buffer_desc
.Usage
= D3D10_USAGE_DEFAULT
;
162 buffer_desc
.BindFlags
= D3D10_BIND_SHADER_RESOURCE
;
163 buffer_desc
.CPUAccessFlags
= 0;
164 buffer_desc
.MiscFlags
= 0;
166 buffer_data
.pSysMem
= data
;
167 buffer_data
.SysMemPitch
= 0;
168 buffer_data
.SysMemSlicePitch
= 0;
170 hr
= ID3D10Device_CreateBuffer(device
, &buffer_desc
, &buffer_data
, &buffer
);
171 HeapFree(GetProcessHeap(), 0, data
);
174 ERR("Failed to create buffer, hr %#x.\n", hr
);
178 srv_desc
.Format
= DXGI_FORMAT_R32G32B32A32_FLOAT
;
179 srv_desc
.ViewDimension
= D3D10_SRV_DIMENSION_BUFFER
;
180 srv_desc
.Buffer
.ElementOffset
= 0;
181 srv_desc
.Buffer
.ElementWidth
= 2 * stop_count
;
183 hr
= ID3D10Device_CreateShaderResourceView(device
, (ID3D10Resource
*)buffer
, &srv_desc
, &view
);
184 ID3D10Buffer_Release(buffer
);
187 ERR("Failed to create view, hr %#x.\n", hr
);
191 if (!(*gradient
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(**gradient
))))
193 ID3D10ShaderResourceView_Release(view
);
194 return E_OUTOFMEMORY
;
197 if (gamma
!= D2D1_GAMMA_2_2
)
198 FIXME("Ignoring gamma %#x.\n", gamma
);
199 if (extend_mode
!= D2D1_EXTEND_MODE_CLAMP
)
200 FIXME("Ignoring extend mode %#x.\n", extend_mode
);
202 (*gradient
)->ID2D1GradientStopCollection_iface
.lpVtbl
= &d2d_gradient_vtbl
;
203 (*gradient
)->refcount
= 1;
204 ID2D1Factory_AddRef((*gradient
)->factory
= factory
);
205 (*gradient
)->view
= view
;
207 (*gradient
)->stop_count
= stop_count
;
208 if (!((*gradient
)->stops
= HeapAlloc(GetProcessHeap(), 0, stop_count
* sizeof(*stops
))))
210 ID3D10ShaderResourceView_Release(view
);
211 HeapFree(GetProcessHeap(), 0, *gradient
);
212 return E_OUTOFMEMORY
;
214 memcpy((*gradient
)->stops
, stops
, stop_count
* sizeof(*stops
));
216 TRACE("Created gradient %p.\n", *gradient
);
220 static struct d2d_gradient
*unsafe_impl_from_ID2D1GradientStopCollection(ID2D1GradientStopCollection
*iface
)
224 assert(iface
->lpVtbl
== &d2d_gradient_vtbl
);
225 return CONTAINING_RECORD(iface
, struct d2d_gradient
, ID2D1GradientStopCollection_iface
);
228 static void d2d_brush_destroy(struct d2d_brush
*brush
)
230 ID2D1Factory_Release(brush
->factory
);
231 HeapFree(GetProcessHeap(), 0, brush
);
234 static void d2d_brush_init(struct d2d_brush
*brush
, ID2D1Factory
*factory
,
235 enum d2d_brush_type type
, const D2D1_BRUSH_PROPERTIES
*desc
, const struct ID2D1BrushVtbl
*vtbl
)
237 static const D2D1_MATRIX_3X2_F identity
=
244 brush
->ID2D1Brush_iface
.lpVtbl
= vtbl
;
246 ID2D1Factory_AddRef(brush
->factory
= factory
);
247 brush
->opacity
= desc
? desc
->opacity
: 1.0f
;
248 brush
->transform
= desc
? desc
->transform
: identity
;
252 static inline struct d2d_brush
*impl_from_ID2D1SolidColorBrush(ID2D1SolidColorBrush
*iface
)
254 return CONTAINING_RECORD(iface
, struct d2d_brush
, ID2D1Brush_iface
);
257 static HRESULT STDMETHODCALLTYPE
d2d_solid_color_brush_QueryInterface(ID2D1SolidColorBrush
*iface
,
258 REFIID iid
, void **out
)
260 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
262 if (IsEqualGUID(iid
, &IID_ID2D1SolidColorBrush
)
263 || IsEqualGUID(iid
, &IID_ID2D1Brush
)
264 || IsEqualGUID(iid
, &IID_ID2D1Resource
)
265 || IsEqualGUID(iid
, &IID_IUnknown
))
267 ID2D1SolidColorBrush_AddRef(iface
);
272 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
275 return E_NOINTERFACE
;
278 static ULONG STDMETHODCALLTYPE
d2d_solid_color_brush_AddRef(ID2D1SolidColorBrush
*iface
)
280 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
281 ULONG refcount
= InterlockedIncrement(&brush
->refcount
);
283 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
288 static ULONG STDMETHODCALLTYPE
d2d_solid_color_brush_Release(ID2D1SolidColorBrush
*iface
)
290 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
291 ULONG refcount
= InterlockedDecrement(&brush
->refcount
);
293 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
296 d2d_brush_destroy(brush
);
301 static void STDMETHODCALLTYPE
d2d_solid_color_brush_GetFactory(ID2D1SolidColorBrush
*iface
, ID2D1Factory
**factory
)
303 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
305 TRACE("iface %p, factory %p.\n", iface
, factory
);
307 ID2D1Factory_AddRef(*factory
= brush
->factory
);
310 static void STDMETHODCALLTYPE
d2d_solid_color_brush_SetOpacity(ID2D1SolidColorBrush
*iface
, float opacity
)
312 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
314 TRACE("iface %p, opacity %.8e.\n", iface
, opacity
);
316 brush
->opacity
= opacity
;
319 static void STDMETHODCALLTYPE
d2d_solid_color_brush_SetTransform(ID2D1SolidColorBrush
*iface
,
320 const D2D1_MATRIX_3X2_F
*transform
)
322 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
324 TRACE("iface %p, transform %p.\n", iface
, transform
);
326 brush
->transform
= *transform
;
329 static float STDMETHODCALLTYPE
d2d_solid_color_brush_GetOpacity(ID2D1SolidColorBrush
*iface
)
331 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
333 TRACE("iface %p.\n", iface
);
335 return brush
->opacity
;
338 static void STDMETHODCALLTYPE
d2d_solid_color_brush_GetTransform(ID2D1SolidColorBrush
*iface
,
339 D2D1_MATRIX_3X2_F
*transform
)
341 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
343 TRACE("iface %p, transform %p.\n", iface
, transform
);
345 *transform
= brush
->transform
;
348 static void STDMETHODCALLTYPE
d2d_solid_color_brush_SetColor(ID2D1SolidColorBrush
*iface
, const D2D1_COLOR_F
*color
)
350 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
352 TRACE("iface %p, color %p.\n", iface
, color
);
354 brush
->u
.solid
.color
= *color
;
357 static D2D1_COLOR_F
* STDMETHODCALLTYPE
d2d_solid_color_brush_GetColor(ID2D1SolidColorBrush
*iface
, D2D1_COLOR_F
*color
)
359 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
361 TRACE("iface %p, color %p.\n", iface
, color
);
363 *color
= brush
->u
.solid
.color
;
367 static const struct ID2D1SolidColorBrushVtbl d2d_solid_color_brush_vtbl
=
369 d2d_solid_color_brush_QueryInterface
,
370 d2d_solid_color_brush_AddRef
,
371 d2d_solid_color_brush_Release
,
372 d2d_solid_color_brush_GetFactory
,
373 d2d_solid_color_brush_SetOpacity
,
374 d2d_solid_color_brush_SetTransform
,
375 d2d_solid_color_brush_GetOpacity
,
376 d2d_solid_color_brush_GetTransform
,
377 d2d_solid_color_brush_SetColor
,
378 d2d_solid_color_brush_GetColor
,
381 HRESULT
d2d_solid_color_brush_create(ID2D1Factory
*factory
, const D2D1_COLOR_F
*color
,
382 const D2D1_BRUSH_PROPERTIES
*desc
, struct d2d_brush
**brush
)
384 if (!(*brush
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(**brush
))))
385 return E_OUTOFMEMORY
;
387 d2d_brush_init(*brush
, factory
, D2D_BRUSH_TYPE_SOLID
, desc
,
388 (ID2D1BrushVtbl
*)&d2d_solid_color_brush_vtbl
);
389 (*brush
)->u
.solid
.color
= *color
;
391 TRACE("Created brush %p.\n", *brush
);
395 static inline struct d2d_brush
*impl_from_ID2D1LinearGradientBrush(ID2D1LinearGradientBrush
*iface
)
397 return CONTAINING_RECORD(iface
, struct d2d_brush
, ID2D1Brush_iface
);
400 static HRESULT STDMETHODCALLTYPE
d2d_linear_gradient_brush_QueryInterface(ID2D1LinearGradientBrush
*iface
,
401 REFIID iid
, void **out
)
403 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
405 if (IsEqualGUID(iid
, &IID_ID2D1LinearGradientBrush
)
406 || IsEqualGUID(iid
, &IID_ID2D1Brush
)
407 || IsEqualGUID(iid
, &IID_ID2D1Resource
)
408 || IsEqualGUID(iid
, &IID_IUnknown
))
410 ID2D1LinearGradientBrush_AddRef(iface
);
415 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
418 return E_NOINTERFACE
;
421 static ULONG STDMETHODCALLTYPE
d2d_linear_gradient_brush_AddRef(ID2D1LinearGradientBrush
*iface
)
423 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
424 ULONG refcount
= InterlockedIncrement(&brush
->refcount
);
426 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
431 static ULONG STDMETHODCALLTYPE
d2d_linear_gradient_brush_Release(ID2D1LinearGradientBrush
*iface
)
433 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
434 ULONG refcount
= InterlockedDecrement(&brush
->refcount
);
436 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
440 ID2D1GradientStopCollection_Release(&brush
->u
.linear
.gradient
->ID2D1GradientStopCollection_iface
);
441 d2d_brush_destroy(brush
);
447 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetFactory(ID2D1LinearGradientBrush
*iface
,
448 ID2D1Factory
**factory
)
450 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
452 TRACE("iface %p, factory %p.\n", iface
, factory
);
454 ID2D1Factory_AddRef(*factory
= brush
->factory
);
457 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_SetOpacity(ID2D1LinearGradientBrush
*iface
, float opacity
)
459 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
461 TRACE("iface %p, opacity %.8e.\n", iface
, opacity
);
463 brush
->opacity
= opacity
;
466 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_SetTransform(ID2D1LinearGradientBrush
*iface
,
467 const D2D1_MATRIX_3X2_F
*transform
)
469 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
471 TRACE("iface %p, transform %p.\n", iface
, transform
);
473 brush
->transform
= *transform
;
476 static float STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetOpacity(ID2D1LinearGradientBrush
*iface
)
478 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
480 TRACE("iface %p.\n", iface
);
482 return brush
->opacity
;
485 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetTransform(ID2D1LinearGradientBrush
*iface
,
486 D2D1_MATRIX_3X2_F
*transform
)
488 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
490 TRACE("iface %p, transform %p.\n", iface
, transform
);
492 *transform
= brush
->transform
;
495 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_SetStartPoint(ID2D1LinearGradientBrush
*iface
,
496 D2D1_POINT_2F start_point
)
498 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
500 TRACE("iface %p, start_point {%.8e, %.8e}.\n", iface
, start_point
.x
, start_point
.y
);
502 brush
->u
.linear
.start
= start_point
;
505 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_SetEndPoint(ID2D1LinearGradientBrush
*iface
,
506 D2D1_POINT_2F end_point
)
508 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
510 TRACE("iface %p, end_point {%.8e, %.8e}.\n", iface
, end_point
.x
, end_point
.y
);
512 brush
->u
.linear
.end
= end_point
;
515 static D2D1_POINT_2F
* STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetStartPoint(ID2D1LinearGradientBrush
*iface
,
516 D2D1_POINT_2F
*point
)
518 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
520 TRACE("iface %p, point %p.\n", iface
, point
);
522 *point
= brush
->u
.linear
.start
;
526 static D2D1_POINT_2F
* STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetEndPoint(ID2D1LinearGradientBrush
*iface
,
527 D2D1_POINT_2F
*point
)
529 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
531 TRACE("iface %p, point %p.\n", iface
, point
);
533 *point
= brush
->u
.linear
.end
;
537 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetGradientStopCollection(ID2D1LinearGradientBrush
*iface
,
538 ID2D1GradientStopCollection
**gradient
)
540 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
542 TRACE("iface %p, gradient %p.\n", iface
, gradient
);
544 ID2D1GradientStopCollection_AddRef(*gradient
= &brush
->u
.linear
.gradient
->ID2D1GradientStopCollection_iface
);
547 static const struct ID2D1LinearGradientBrushVtbl d2d_linear_gradient_brush_vtbl
=
549 d2d_linear_gradient_brush_QueryInterface
,
550 d2d_linear_gradient_brush_AddRef
,
551 d2d_linear_gradient_brush_Release
,
552 d2d_linear_gradient_brush_GetFactory
,
553 d2d_linear_gradient_brush_SetOpacity
,
554 d2d_linear_gradient_brush_SetTransform
,
555 d2d_linear_gradient_brush_GetOpacity
,
556 d2d_linear_gradient_brush_GetTransform
,
557 d2d_linear_gradient_brush_SetStartPoint
,
558 d2d_linear_gradient_brush_SetEndPoint
,
559 d2d_linear_gradient_brush_GetStartPoint
,
560 d2d_linear_gradient_brush_GetEndPoint
,
561 d2d_linear_gradient_brush_GetGradientStopCollection
,
564 HRESULT
d2d_linear_gradient_brush_create(ID2D1Factory
*factory
, const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES
*gradient_brush_desc
,
565 const D2D1_BRUSH_PROPERTIES
*brush_desc
, ID2D1GradientStopCollection
*gradient
, struct d2d_brush
**brush
)
567 if (!(*brush
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(**brush
))))
568 return E_OUTOFMEMORY
;
570 d2d_brush_init(*brush
, factory
, D2D_BRUSH_TYPE_LINEAR
, brush_desc
,
571 (ID2D1BrushVtbl
*)&d2d_linear_gradient_brush_vtbl
);
572 (*brush
)->u
.linear
.gradient
= unsafe_impl_from_ID2D1GradientStopCollection(gradient
);
573 ID2D1GradientStopCollection_AddRef(&(*brush
)->u
.linear
.gradient
->ID2D1GradientStopCollection_iface
);
574 (*brush
)->u
.linear
.start
= gradient_brush_desc
->startPoint
;
575 (*brush
)->u
.linear
.end
= gradient_brush_desc
->endPoint
;
577 TRACE("Created brush %p.\n", *brush
);
581 static inline struct d2d_brush
*impl_from_ID2D1RadialGradientBrush(ID2D1RadialGradientBrush
*iface
)
583 return CONTAINING_RECORD(iface
, struct d2d_brush
, ID2D1Brush_iface
);
586 static HRESULT STDMETHODCALLTYPE
d2d_radial_gradient_brush_QueryInterface(ID2D1RadialGradientBrush
*iface
,
587 REFIID iid
, void **out
)
589 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
591 if (IsEqualGUID(iid
, &IID_ID2D1RadialGradientBrush
)
592 || IsEqualGUID(iid
, &IID_ID2D1Brush
)
593 || IsEqualGUID(iid
, &IID_ID2D1Resource
)
594 || IsEqualGUID(iid
, &IID_IUnknown
))
596 ID2D1RadialGradientBrush_AddRef(iface
);
601 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
604 return E_NOINTERFACE
;
607 static ULONG STDMETHODCALLTYPE
d2d_radial_gradient_brush_AddRef(ID2D1RadialGradientBrush
*iface
)
609 struct d2d_brush
*brush
= impl_from_ID2D1RadialGradientBrush(iface
);
610 ULONG refcount
= InterlockedIncrement(&brush
->refcount
);
612 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
617 static ULONG STDMETHODCALLTYPE
d2d_radial_gradient_brush_Release(ID2D1RadialGradientBrush
*iface
)
619 struct d2d_brush
*brush
= impl_from_ID2D1RadialGradientBrush(iface
);
620 ULONG refcount
= InterlockedDecrement(&brush
->refcount
);
622 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
626 ID2D1GradientStopCollection_Release(&brush
->u
.radial
.gradient
->ID2D1GradientStopCollection_iface
);
627 d2d_brush_destroy(brush
);
633 static void STDMETHODCALLTYPE
d2d_radial_gradient_brush_GetFactory(ID2D1RadialGradientBrush
*iface
,
634 ID2D1Factory
**factory
)
636 struct d2d_brush
*brush
= impl_from_ID2D1RadialGradientBrush(iface
);
638 TRACE("iface %p, factory %p.\n", iface
, factory
);
640 ID2D1Factory_AddRef(*factory
= brush
->factory
);
643 static void STDMETHODCALLTYPE
d2d_radial_gradient_brush_SetOpacity(ID2D1RadialGradientBrush
*iface
, float opacity
)
645 struct d2d_brush
*brush
= impl_from_ID2D1RadialGradientBrush(iface
);
647 TRACE("iface %p, opacity %.8e.\n", iface
, opacity
);
649 brush
->opacity
= opacity
;
652 static void STDMETHODCALLTYPE
d2d_radial_gradient_brush_SetTransform(ID2D1RadialGradientBrush
*iface
,
653 const D2D1_MATRIX_3X2_F
*transform
)
655 struct d2d_brush
*brush
= impl_from_ID2D1RadialGradientBrush(iface
);
657 TRACE("iface %p, transform %p.\n", iface
, transform
);
659 brush
->transform
= *transform
;
662 static float STDMETHODCALLTYPE
d2d_radial_gradient_brush_GetOpacity(ID2D1RadialGradientBrush
*iface
)
664 struct d2d_brush
*brush
= impl_from_ID2D1RadialGradientBrush(iface
);
666 TRACE("iface %p.\n", iface
);
668 return brush
->opacity
;
671 static void STDMETHODCALLTYPE
d2d_radial_gradient_brush_GetTransform(ID2D1RadialGradientBrush
*iface
,
672 D2D1_MATRIX_3X2_F
*transform
)
674 struct d2d_brush
*brush
= impl_from_ID2D1RadialGradientBrush(iface
);
676 TRACE("iface %p, transform %p.\n", iface
, transform
);
678 *transform
= brush
->transform
;
681 static void STDMETHODCALLTYPE
d2d_radial_gradient_brush_SetCenter(ID2D1RadialGradientBrush
*iface
,
682 D2D1_POINT_2F centre
)
684 struct d2d_brush
*brush
= impl_from_ID2D1RadialGradientBrush(iface
);
686 TRACE("iface %p, centre {%.8e, %.8e}.\n", iface
, centre
.x
, centre
.y
);
688 brush
->u
.radial
.centre
= centre
;
691 static void STDMETHODCALLTYPE
d2d_radial_gradient_brush_SetGradientOriginOffset(ID2D1RadialGradientBrush
*iface
,
692 D2D1_POINT_2F offset
)
694 struct d2d_brush
*brush
= impl_from_ID2D1RadialGradientBrush(iface
);
696 TRACE("iface %p, offset {%.8e, %.8e}.\n", iface
, offset
.x
, offset
.y
);
698 brush
->u
.radial
.offset
= offset
;
701 static void STDMETHODCALLTYPE
d2d_radial_gradient_brush_SetRadiusX(ID2D1RadialGradientBrush
*iface
, float radius
)
703 FIXME("iface %p, radius %.8e stub!\n", iface
, radius
);
706 static void STDMETHODCALLTYPE
d2d_radial_gradient_brush_SetRadiusY(ID2D1RadialGradientBrush
*iface
, float radius
)
708 FIXME("iface %p, radius %.8e stub!\n", iface
, radius
);
711 static D2D1_POINT_2F
* STDMETHODCALLTYPE
d2d_radial_gradient_brush_GetCenter(ID2D1RadialGradientBrush
*iface
,
712 D2D1_POINT_2F
*centre
)
714 struct d2d_brush
*brush
= impl_from_ID2D1RadialGradientBrush(iface
);
716 TRACE("iface %p, centre %p.\n", iface
, centre
);
718 *centre
= brush
->u
.radial
.centre
;
722 static D2D1_POINT_2F
* STDMETHODCALLTYPE
d2d_radial_gradient_brush_GetGradientOriginOffset(
723 ID2D1RadialGradientBrush
*iface
, D2D1_POINT_2F
*offset
)
725 struct d2d_brush
*brush
= impl_from_ID2D1RadialGradientBrush(iface
);
727 TRACE("iface %p, offset %p.\n", iface
, offset
);
729 *offset
= brush
->u
.radial
.offset
;
733 static float STDMETHODCALLTYPE
d2d_radial_gradient_brush_GetRadiusX(ID2D1RadialGradientBrush
*iface
)
735 FIXME("iface %p stub!\n", iface
);
740 static float STDMETHODCALLTYPE
d2d_radial_gradient_brush_GetRadiusY(ID2D1RadialGradientBrush
*iface
)
742 FIXME("iface %p stub!\n", iface
);
747 static void STDMETHODCALLTYPE
d2d_radial_gradient_brush_GetGradientStopCollection(ID2D1RadialGradientBrush
*iface
,
748 ID2D1GradientStopCollection
**gradient
)
750 struct d2d_brush
*brush
= impl_from_ID2D1RadialGradientBrush(iface
);
752 TRACE("iface %p, gradient %p.\n", iface
, gradient
);
754 ID2D1GradientStopCollection_AddRef(*gradient
= &brush
->u
.radial
.gradient
->ID2D1GradientStopCollection_iface
);
757 static const struct ID2D1RadialGradientBrushVtbl d2d_radial_gradient_brush_vtbl
=
759 d2d_radial_gradient_brush_QueryInterface
,
760 d2d_radial_gradient_brush_AddRef
,
761 d2d_radial_gradient_brush_Release
,
762 d2d_radial_gradient_brush_GetFactory
,
763 d2d_radial_gradient_brush_SetOpacity
,
764 d2d_radial_gradient_brush_SetTransform
,
765 d2d_radial_gradient_brush_GetOpacity
,
766 d2d_radial_gradient_brush_GetTransform
,
767 d2d_radial_gradient_brush_SetCenter
,
768 d2d_radial_gradient_brush_SetGradientOriginOffset
,
769 d2d_radial_gradient_brush_SetRadiusX
,
770 d2d_radial_gradient_brush_SetRadiusY
,
771 d2d_radial_gradient_brush_GetCenter
,
772 d2d_radial_gradient_brush_GetGradientOriginOffset
,
773 d2d_radial_gradient_brush_GetRadiusX
,
774 d2d_radial_gradient_brush_GetRadiusY
,
775 d2d_radial_gradient_brush_GetGradientStopCollection
,
778 HRESULT
d2d_radial_gradient_brush_create(ID2D1Factory
*factory
,
779 const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES
*gradient_desc
, const D2D1_BRUSH_PROPERTIES
*brush_desc
,
780 ID2D1GradientStopCollection
*gradient
, struct d2d_brush
**brush
)
784 if (!(b
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*b
))))
785 return E_OUTOFMEMORY
;
787 d2d_brush_init(b
, factory
, D2D_BRUSH_TYPE_RADIAL
, brush_desc
, (ID2D1BrushVtbl
*)&d2d_radial_gradient_brush_vtbl
);
788 b
->u
.radial
.gradient
= unsafe_impl_from_ID2D1GradientStopCollection(gradient
);
789 ID2D1GradientStopCollection_AddRef(&b
->u
.radial
.gradient
->ID2D1GradientStopCollection_iface
);
790 b
->u
.radial
.centre
= gradient_desc
->center
;
791 b
->u
.radial
.offset
= gradient_desc
->gradientOriginOffset
;
793 TRACE("Created brush %p.\n", b
);
799 static inline struct d2d_brush
*impl_from_ID2D1BitmapBrush(ID2D1BitmapBrush
*iface
)
801 return CONTAINING_RECORD(iface
, struct d2d_brush
, ID2D1Brush_iface
);
804 static HRESULT STDMETHODCALLTYPE
d2d_bitmap_brush_QueryInterface(ID2D1BitmapBrush
*iface
,
805 REFIID iid
, void **out
)
807 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
809 if (IsEqualGUID(iid
, &IID_ID2D1BitmapBrush
)
810 || IsEqualGUID(iid
, &IID_ID2D1Brush
)
811 || IsEqualGUID(iid
, &IID_ID2D1Resource
)
812 || IsEqualGUID(iid
, &IID_IUnknown
))
814 ID2D1BitmapBrush_AddRef(iface
);
819 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
822 return E_NOINTERFACE
;
825 static ULONG STDMETHODCALLTYPE
d2d_bitmap_brush_AddRef(ID2D1BitmapBrush
*iface
)
827 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
828 ULONG refcount
= InterlockedIncrement(&brush
->refcount
);
830 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
835 static ULONG STDMETHODCALLTYPE
d2d_bitmap_brush_Release(ID2D1BitmapBrush
*iface
)
837 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
838 ULONG refcount
= InterlockedDecrement(&brush
->refcount
);
840 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
844 if (brush
->u
.bitmap
.sampler_state
)
845 ID3D10SamplerState_Release(brush
->u
.bitmap
.sampler_state
);
846 if (brush
->u
.bitmap
.bitmap
)
847 ID2D1Bitmap_Release(&brush
->u
.bitmap
.bitmap
->ID2D1Bitmap_iface
);
848 d2d_brush_destroy(brush
);
854 static void STDMETHODCALLTYPE
d2d_bitmap_brush_GetFactory(ID2D1BitmapBrush
*iface
,
855 ID2D1Factory
**factory
)
857 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
859 TRACE("iface %p, factory %p.\n", iface
, factory
);
861 ID2D1Factory_AddRef(*factory
= brush
->factory
);
864 static void STDMETHODCALLTYPE
d2d_bitmap_brush_SetOpacity(ID2D1BitmapBrush
*iface
, float opacity
)
866 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
868 TRACE("iface %p, opacity %.8e.\n", iface
, opacity
);
870 brush
->opacity
= opacity
;
873 static void STDMETHODCALLTYPE
d2d_bitmap_brush_SetTransform(ID2D1BitmapBrush
*iface
,
874 const D2D1_MATRIX_3X2_F
*transform
)
876 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
878 TRACE("iface %p, transform %p.\n", iface
, transform
);
880 brush
->transform
= *transform
;
883 static float STDMETHODCALLTYPE
d2d_bitmap_brush_GetOpacity(ID2D1BitmapBrush
*iface
)
885 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
887 TRACE("iface %p.\n", iface
);
889 return brush
->opacity
;
892 static void STDMETHODCALLTYPE
d2d_bitmap_brush_GetTransform(ID2D1BitmapBrush
*iface
,
893 D2D1_MATRIX_3X2_F
*transform
)
895 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
897 TRACE("iface %p, transform %p.\n", iface
, transform
);
899 *transform
= brush
->transform
;
902 static void STDMETHODCALLTYPE
d2d_bitmap_brush_SetExtendModeX(ID2D1BitmapBrush
*iface
, D2D1_EXTEND_MODE mode
)
904 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
906 TRACE("iface %p, mode %#x.\n", iface
, mode
);
908 brush
->u
.bitmap
.extend_mode_x
= mode
;
909 if (brush
->u
.bitmap
.sampler_state
)
911 ID3D10SamplerState_Release(brush
->u
.bitmap
.sampler_state
);
912 brush
->u
.bitmap
.sampler_state
= NULL
;
916 static void STDMETHODCALLTYPE
d2d_bitmap_brush_SetExtendModeY(ID2D1BitmapBrush
*iface
, D2D1_EXTEND_MODE mode
)
918 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
920 TRACE("iface %p, mode %#x.\n", iface
, mode
);
922 brush
->u
.bitmap
.extend_mode_y
= mode
;
923 if (brush
->u
.bitmap
.sampler_state
)
925 ID3D10SamplerState_Release(brush
->u
.bitmap
.sampler_state
);
926 brush
->u
.bitmap
.sampler_state
= NULL
;
930 static void STDMETHODCALLTYPE
d2d_bitmap_brush_SetInterpolationMode(ID2D1BitmapBrush
*iface
,
931 D2D1_BITMAP_INTERPOLATION_MODE mode
)
933 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
935 TRACE("iface %p, mode %#x.\n", iface
, mode
);
937 brush
->u
.bitmap
.interpolation_mode
= mode
;
938 if (brush
->u
.bitmap
.sampler_state
)
940 ID3D10SamplerState_Release(brush
->u
.bitmap
.sampler_state
);
941 brush
->u
.bitmap
.sampler_state
= NULL
;
945 static void STDMETHODCALLTYPE
d2d_bitmap_brush_SetBitmap(ID2D1BitmapBrush
*iface
, ID2D1Bitmap
*bitmap
)
947 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
949 TRACE("iface %p, bitmap %p.\n", iface
, bitmap
);
952 ID2D1Bitmap_AddRef(bitmap
);
953 if (brush
->u
.bitmap
.bitmap
)
954 ID2D1Bitmap_Release(&brush
->u
.bitmap
.bitmap
->ID2D1Bitmap_iface
);
955 brush
->u
.bitmap
.bitmap
= unsafe_impl_from_ID2D1Bitmap(bitmap
);
958 static D2D1_EXTEND_MODE STDMETHODCALLTYPE
d2d_bitmap_brush_GetExtendModeX(ID2D1BitmapBrush
*iface
)
960 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
962 TRACE("iface %p.\n", iface
);
964 return brush
->u
.bitmap
.extend_mode_x
;
967 static D2D1_EXTEND_MODE STDMETHODCALLTYPE
d2d_bitmap_brush_GetExtendModeY(ID2D1BitmapBrush
*iface
)
969 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
971 TRACE("iface %p.\n", iface
);
973 return brush
->u
.bitmap
.extend_mode_y
;
976 static D2D1_BITMAP_INTERPOLATION_MODE STDMETHODCALLTYPE
d2d_bitmap_brush_GetInterpolationMode(ID2D1BitmapBrush
*iface
)
978 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
980 TRACE("iface %p.\n", iface
);
982 return brush
->u
.bitmap
.interpolation_mode
;
985 static void STDMETHODCALLTYPE
d2d_bitmap_brush_GetBitmap(ID2D1BitmapBrush
*iface
, ID2D1Bitmap
**bitmap
)
987 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
989 TRACE("iface %p, bitmap %p.\n", iface
, bitmap
);
991 if ((*bitmap
= &brush
->u
.bitmap
.bitmap
->ID2D1Bitmap_iface
))
992 ID2D1Bitmap_AddRef(*bitmap
);
995 static const struct ID2D1BitmapBrushVtbl d2d_bitmap_brush_vtbl
=
997 d2d_bitmap_brush_QueryInterface
,
998 d2d_bitmap_brush_AddRef
,
999 d2d_bitmap_brush_Release
,
1000 d2d_bitmap_brush_GetFactory
,
1001 d2d_bitmap_brush_SetOpacity
,
1002 d2d_bitmap_brush_SetTransform
,
1003 d2d_bitmap_brush_GetOpacity
,
1004 d2d_bitmap_brush_GetTransform
,
1005 d2d_bitmap_brush_SetExtendModeX
,
1006 d2d_bitmap_brush_SetExtendModeY
,
1007 d2d_bitmap_brush_SetInterpolationMode
,
1008 d2d_bitmap_brush_SetBitmap
,
1009 d2d_bitmap_brush_GetExtendModeX
,
1010 d2d_bitmap_brush_GetExtendModeY
,
1011 d2d_bitmap_brush_GetInterpolationMode
,
1012 d2d_bitmap_brush_GetBitmap
,
1015 HRESULT
d2d_bitmap_brush_create(ID2D1Factory
*factory
, ID2D1Bitmap
*bitmap
, const D2D1_BITMAP_BRUSH_PROPERTIES
*bitmap_brush_desc
,
1016 const D2D1_BRUSH_PROPERTIES
*brush_desc
, struct d2d_brush
**brush
)
1018 if (!(*brush
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(**brush
))))
1019 return E_OUTOFMEMORY
;
1021 d2d_brush_init(*brush
, factory
, D2D_BRUSH_TYPE_BITMAP
,
1022 brush_desc
, (ID2D1BrushVtbl
*)&d2d_bitmap_brush_vtbl
);
1023 if (((*brush
)->u
.bitmap
.bitmap
= unsafe_impl_from_ID2D1Bitmap(bitmap
)))
1024 ID2D1Bitmap_AddRef(&(*brush
)->u
.bitmap
.bitmap
->ID2D1Bitmap_iface
);
1025 if (bitmap_brush_desc
)
1027 (*brush
)->u
.bitmap
.extend_mode_x
= bitmap_brush_desc
->extendModeX
;
1028 (*brush
)->u
.bitmap
.extend_mode_y
= bitmap_brush_desc
->extendModeY
;
1029 (*brush
)->u
.bitmap
.interpolation_mode
= bitmap_brush_desc
->interpolationMode
;
1033 (*brush
)->u
.bitmap
.extend_mode_x
= D2D1_EXTEND_MODE_CLAMP
;
1034 (*brush
)->u
.bitmap
.extend_mode_y
= D2D1_EXTEND_MODE_CLAMP
;
1035 (*brush
)->u
.bitmap
.interpolation_mode
= D2D1_BITMAP_INTERPOLATION_MODE_LINEAR
;
1038 TRACE("Created brush %p.\n", *brush
);
1042 struct d2d_brush
*unsafe_impl_from_ID2D1Brush(ID2D1Brush
*iface
)
1046 assert(iface
->lpVtbl
== (const ID2D1BrushVtbl
*)&d2d_solid_color_brush_vtbl
1047 || iface
->lpVtbl
== (const ID2D1BrushVtbl
*)&d2d_linear_gradient_brush_vtbl
1048 || iface
->lpVtbl
== (const ID2D1BrushVtbl
*)&d2d_radial_gradient_brush_vtbl
1049 || iface
->lpVtbl
== (const ID2D1BrushVtbl
*)&d2d_bitmap_brush_vtbl
);
1050 return CONTAINING_RECORD(iface
, struct d2d_brush
, ID2D1Brush_iface
);
1053 static D3D10_TEXTURE_ADDRESS_MODE
texture_address_mode_from_extend_mode(D2D1_EXTEND_MODE mode
)
1057 case D2D1_EXTEND_MODE_CLAMP
:
1058 return D3D10_TEXTURE_ADDRESS_CLAMP
;
1059 case D2D1_EXTEND_MODE_WRAP
:
1060 return D3D10_TEXTURE_ADDRESS_WRAP
;
1061 case D2D1_EXTEND_MODE_MIRROR
:
1062 return D3D10_TEXTURE_ADDRESS_MIRROR
;
1064 FIXME("Unhandled extend mode %#x.\n", mode
);
1065 return D3D10_TEXTURE_ADDRESS_CLAMP
;
1069 static BOOL
d2d_brush_fill_cb(const struct d2d_brush
*brush
,
1070 const struct d2d_d3d_render_target
*render_target
, struct d2d_brush_cb
*cb
)
1072 struct d2d_bitmap
*bitmap
;
1073 D2D1_COLOR_F
*colour
;
1079 cb
->type
= D2D_BRUSH_TYPE_COUNT
;
1083 cb
->type
= brush
->type
;
1084 cb
->opacity
= brush
->opacity
;
1086 switch (brush
->type
)
1088 case D2D_BRUSH_TYPE_SOLID
:
1089 colour
= &cb
->u
.solid
.colour
;
1091 *colour
= brush
->u
.solid
.color
;
1092 colour
->r
*= colour
->a
;
1093 colour
->g
*= colour
->a
;
1094 colour
->b
*= colour
->a
;
1098 case D2D_BRUSH_TYPE_LINEAR
:
1099 b
= brush
->transform
;
1100 d2d_point_transform(&cb
->u
.linear
.start
, &b
, brush
->u
.linear
.start
.x
, brush
->u
.linear
.start
.y
);
1101 d2d_point_transform(&cb
->u
.linear
.end
, &b
, brush
->u
.linear
.end
.x
, brush
->u
.linear
.end
.y
);
1102 cb
->u
.linear
.stop_count
= brush
->u
.linear
.gradient
->stop_count
;
1106 case D2D_BRUSH_TYPE_BITMAP
:
1107 bitmap
= brush
->u
.bitmap
.bitmap
;
1109 /* Scale for bitmap size and dpi. */
1110 b
= brush
->transform
;
1111 dpi_scale
= bitmap
->pixel_size
.width
* (96.0f
/ bitmap
->dpi_x
);
1114 dpi_scale
= bitmap
->pixel_size
.height
* (96.0f
/ bitmap
->dpi_y
);
1118 /* Invert the matrix. (Because the matrix is applied to the
1119 * sampling coordinates. I.e., to scale the bitmap by 2 we need to
1120 * divide the coordinates by 2.) */
1121 d
= b
._11
* b
._22
- b
._21
* b
._12
;
1124 cb
->u
.bitmap
._11
= b
._22
/ d
;
1125 cb
->u
.bitmap
._21
= -b
._21
/ d
;
1126 cb
->u
.bitmap
._31
= (b
._21
* b
._32
- b
._31
* b
._22
) / d
;
1127 cb
->u
.bitmap
._12
= -b
._12
/ d
;
1128 cb
->u
.bitmap
._22
= b
._11
/ d
;
1129 cb
->u
.bitmap
._32
= -(b
._11
* b
._32
- b
._31
* b
._12
) / d
;
1132 cb
->u
.bitmap
.ignore_alpha
= bitmap
->format
.alphaMode
== D2D1_ALPHA_MODE_IGNORE
;
1137 FIXME("Unhandled brush type %#x.\n", brush
->type
);
1142 HRESULT
d2d_brush_get_ps_cb(struct d2d_brush
*brush
, struct d2d_brush
*opacity_brush
,
1143 BOOL outline
, struct d2d_d3d_render_target
*render_target
, ID3D10Buffer
**ps_cb
)
1145 D3D10_SUBRESOURCE_DATA buffer_data
;
1146 struct d2d_ps_cb cb_data
= {0};
1147 D3D10_BUFFER_DESC buffer_desc
;
1150 cb_data
.outline
= outline
;
1151 if (!d2d_brush_fill_cb(brush
, render_target
, &cb_data
.colour_brush
))
1153 if (!d2d_brush_fill_cb(opacity_brush
, render_target
, &cb_data
.opacity_brush
))
1156 buffer_desc
.ByteWidth
= sizeof(cb_data
);
1157 buffer_desc
.Usage
= D3D10_USAGE_DEFAULT
;
1158 buffer_desc
.BindFlags
= D3D10_BIND_CONSTANT_BUFFER
;
1159 buffer_desc
.CPUAccessFlags
= 0;
1160 buffer_desc
.MiscFlags
= 0;
1162 buffer_data
.pSysMem
= &cb_data
;
1163 buffer_data
.SysMemPitch
= 0;
1164 buffer_data
.SysMemSlicePitch
= 0;
1166 if (FAILED(hr
= ID3D10Device_CreateBuffer(render_target
->device
, &buffer_desc
, &buffer_data
, ps_cb
)))
1167 ERR("Failed to create constant buffer, hr %#x.\n", hr
);
1172 static void d2d_brush_bind_gradient(struct d2d_brush
*brush
, ID3D10Device
*device
, unsigned int brush_idx
)
1174 ID3D10Device_PSSetShaderResources(device
, 2 + brush_idx
, 1, &brush
->u
.linear
.gradient
->view
);
1177 static void d2d_brush_bind_bitmap(struct d2d_brush
*brush
, ID3D10Device
*device
, unsigned int brush_idx
)
1181 ID3D10Device_PSSetShaderResources(device
, brush_idx
, 1, &brush
->u
.bitmap
.bitmap
->view
);
1182 if (!brush
->u
.bitmap
.sampler_state
)
1184 D3D10_SAMPLER_DESC sampler_desc
;
1186 if (brush
->u
.bitmap
.interpolation_mode
== D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR
)
1187 sampler_desc
.Filter
= D3D10_FILTER_MIN_MAG_MIP_POINT
;
1189 sampler_desc
.Filter
= D3D10_FILTER_MIN_MAG_MIP_LINEAR
;
1190 sampler_desc
.AddressU
= texture_address_mode_from_extend_mode(brush
->u
.bitmap
.extend_mode_x
);
1191 sampler_desc
.AddressV
= texture_address_mode_from_extend_mode(brush
->u
.bitmap
.extend_mode_y
);
1192 sampler_desc
.AddressW
= D3D10_TEXTURE_ADDRESS_CLAMP
;
1193 sampler_desc
.MipLODBias
= 0.0f
;
1194 sampler_desc
.MaxAnisotropy
= 0;
1195 sampler_desc
.ComparisonFunc
= D3D10_COMPARISON_NEVER
;
1196 sampler_desc
.BorderColor
[0] = 0.0f
;
1197 sampler_desc
.BorderColor
[1] = 0.0f
;
1198 sampler_desc
.BorderColor
[2] = 0.0f
;
1199 sampler_desc
.BorderColor
[3] = 0.0f
;
1200 sampler_desc
.MinLOD
= 0.0f
;
1201 sampler_desc
.MaxLOD
= 0.0f
;
1203 if (FAILED(hr
= ID3D10Device_CreateSamplerState(device
,
1204 &sampler_desc
, &brush
->u
.bitmap
.sampler_state
)))
1205 ERR("Failed to create sampler state, hr %#x.\n", hr
);
1207 ID3D10Device_PSSetSamplers(device
, brush_idx
, 1, &brush
->u
.bitmap
.sampler_state
);
1210 void d2d_brush_bind_resources(struct d2d_brush
*brush
, ID3D10Device
*device
, unsigned int brush_idx
)
1212 switch (brush
->type
)
1214 case D2D_BRUSH_TYPE_SOLID
:
1217 case D2D_BRUSH_TYPE_LINEAR
:
1218 d2d_brush_bind_gradient(brush
, device
, brush_idx
);
1221 case D2D_BRUSH_TYPE_BITMAP
:
1222 d2d_brush_bind_bitmap(brush
, device
, brush_idx
);
1226 FIXME("Unhandled brush type %#x.\n", brush
->type
);