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 HeapFree(GetProcessHeap(), 0, gradient
);
77 static void STDMETHODCALLTYPE
d2d_gradient_GetFactory(ID2D1GradientStopCollection
*iface
, ID2D1Factory
**factory
)
79 FIXME("iface %p, factory %p stub!\n", iface
, factory
);
84 static UINT32 STDMETHODCALLTYPE
d2d_gradient_GetGradientStopCount(ID2D1GradientStopCollection
*iface
)
86 struct d2d_gradient
*gradient
= impl_from_ID2D1GradientStopCollection(iface
);
88 TRACE("iface %p.\n", iface
);
90 return gradient
->stop_count
;
93 static void STDMETHODCALLTYPE
d2d_gradient_GetGradientStops(ID2D1GradientStopCollection
*iface
,
94 D2D1_GRADIENT_STOP
*stops
, UINT32 stop_count
)
96 struct d2d_gradient
*gradient
= impl_from_ID2D1GradientStopCollection(iface
);
98 TRACE("iface %p, stops %p, stop_count %u.\n", iface
, stops
, stop_count
);
100 memcpy(stops
, gradient
->stops
, min(gradient
->stop_count
, stop_count
) * sizeof(*stops
));
101 if (stop_count
> gradient
->stop_count
)
102 memset(stops
, 0, (stop_count
- gradient
->stop_count
) * sizeof(*stops
));
105 static D2D1_GAMMA STDMETHODCALLTYPE
d2d_gradient_GetColorInterpolationGamma(ID2D1GradientStopCollection
*iface
)
107 FIXME("iface %p stub!\n", iface
);
109 return D2D1_GAMMA_1_0
;
112 static D2D1_EXTEND_MODE STDMETHODCALLTYPE
d2d_gradient_GetExtendMode(ID2D1GradientStopCollection
*iface
)
114 FIXME("iface %p stub!\n", iface
);
116 return D2D1_EXTEND_MODE_CLAMP
;
119 static const struct ID2D1GradientStopCollectionVtbl d2d_gradient_vtbl
=
121 d2d_gradient_QueryInterface
,
123 d2d_gradient_Release
,
124 d2d_gradient_GetFactory
,
125 d2d_gradient_GetGradientStopCount
,
126 d2d_gradient_GetGradientStops
,
127 d2d_gradient_GetColorInterpolationGamma
,
128 d2d_gradient_GetExtendMode
,
131 HRESULT
d2d_gradient_init(struct d2d_gradient
*gradient
, ID2D1RenderTarget
*render_target
,
132 const D2D1_GRADIENT_STOP
*stops
, UINT32 stop_count
, D2D1_GAMMA gamma
, D2D1_EXTEND_MODE extend_mode
)
134 FIXME("Ignoring gradient properties.\n");
136 gradient
->ID2D1GradientStopCollection_iface
.lpVtbl
= &d2d_gradient_vtbl
;
137 gradient
->refcount
= 1;
139 gradient
->stop_count
= stop_count
;
140 if (!(gradient
->stops
= HeapAlloc(GetProcessHeap(), 0, stop_count
* sizeof(*stops
))))
141 return E_OUTOFMEMORY
;
142 memcpy(gradient
->stops
, stops
, stop_count
* sizeof(*stops
));
147 static void d2d_brush_init(struct d2d_brush
*brush
, ID2D1RenderTarget
*render_target
,
148 enum d2d_brush_type type
, const D2D1_BRUSH_PROPERTIES
*desc
, const struct ID2D1BrushVtbl
*vtbl
)
150 static const D2D1_MATRIX_3X2_F identity
=
157 brush
->ID2D1Brush_iface
.lpVtbl
= vtbl
;
159 brush
->opacity
= desc
? desc
->opacity
: 1.0f
;
160 brush
->transform
= desc
? desc
->transform
: identity
;
164 static inline struct d2d_brush
*impl_from_ID2D1SolidColorBrush(ID2D1SolidColorBrush
*iface
)
166 return CONTAINING_RECORD(iface
, struct d2d_brush
, ID2D1Brush_iface
);
169 static HRESULT STDMETHODCALLTYPE
d2d_solid_color_brush_QueryInterface(ID2D1SolidColorBrush
*iface
,
170 REFIID iid
, void **out
)
172 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
174 if (IsEqualGUID(iid
, &IID_ID2D1SolidColorBrush
)
175 || IsEqualGUID(iid
, &IID_ID2D1Brush
)
176 || IsEqualGUID(iid
, &IID_ID2D1Resource
)
177 || IsEqualGUID(iid
, &IID_IUnknown
))
179 ID2D1SolidColorBrush_AddRef(iface
);
184 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
187 return E_NOINTERFACE
;
190 static ULONG STDMETHODCALLTYPE
d2d_solid_color_brush_AddRef(ID2D1SolidColorBrush
*iface
)
192 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
193 ULONG refcount
= InterlockedIncrement(&brush
->refcount
);
195 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
200 static ULONG STDMETHODCALLTYPE
d2d_solid_color_brush_Release(ID2D1SolidColorBrush
*iface
)
202 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
203 ULONG refcount
= InterlockedDecrement(&brush
->refcount
);
205 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
208 HeapFree(GetProcessHeap(), 0, brush
);
213 static void STDMETHODCALLTYPE
d2d_solid_color_brush_GetFactory(ID2D1SolidColorBrush
*iface
, ID2D1Factory
**factory
)
215 FIXME("iface %p, factory %p stub!\n", iface
, factory
);
220 static void STDMETHODCALLTYPE
d2d_solid_color_brush_SetOpacity(ID2D1SolidColorBrush
*iface
, float opacity
)
222 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
224 TRACE("iface %p, opacity %.8e.\n", iface
, opacity
);
226 brush
->opacity
= opacity
;
229 static void STDMETHODCALLTYPE
d2d_solid_color_brush_SetTransform(ID2D1SolidColorBrush
*iface
,
230 const D2D1_MATRIX_3X2_F
*transform
)
232 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
234 TRACE("iface %p, transform %p.\n", iface
, transform
);
236 brush
->transform
= *transform
;
239 static float STDMETHODCALLTYPE
d2d_solid_color_brush_GetOpacity(ID2D1SolidColorBrush
*iface
)
241 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
243 TRACE("iface %p.\n", iface
);
245 return brush
->opacity
;
248 static void STDMETHODCALLTYPE
d2d_solid_color_brush_GetTransform(ID2D1SolidColorBrush
*iface
,
249 D2D1_MATRIX_3X2_F
*transform
)
251 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
253 TRACE("iface %p, transform %p.\n", iface
, transform
);
255 *transform
= brush
->transform
;
258 static void STDMETHODCALLTYPE
d2d_solid_color_brush_SetColor(ID2D1SolidColorBrush
*iface
, const D2D1_COLOR_F
*color
)
260 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
262 TRACE("iface %p, color %p.\n", iface
, color
);
264 brush
->u
.solid
.color
= *color
;
267 static D2D1_COLOR_F
* STDMETHODCALLTYPE
d2d_solid_color_brush_GetColor(ID2D1SolidColorBrush
*iface
, D2D1_COLOR_F
*color
)
269 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
271 TRACE("iface %p, color %p.\n", iface
, color
);
273 *color
= brush
->u
.solid
.color
;
277 static const struct ID2D1SolidColorBrushVtbl d2d_solid_color_brush_vtbl
=
279 d2d_solid_color_brush_QueryInterface
,
280 d2d_solid_color_brush_AddRef
,
281 d2d_solid_color_brush_Release
,
282 d2d_solid_color_brush_GetFactory
,
283 d2d_solid_color_brush_SetOpacity
,
284 d2d_solid_color_brush_SetTransform
,
285 d2d_solid_color_brush_GetOpacity
,
286 d2d_solid_color_brush_GetTransform
,
287 d2d_solid_color_brush_SetColor
,
288 d2d_solid_color_brush_GetColor
,
291 void d2d_solid_color_brush_init(struct d2d_brush
*brush
, ID2D1RenderTarget
*render_target
,
292 const D2D1_COLOR_F
*color
, const D2D1_BRUSH_PROPERTIES
*desc
)
294 FIXME("Ignoring brush properties.\n");
296 d2d_brush_init(brush
, render_target
, D2D_BRUSH_TYPE_SOLID
, desc
,
297 (ID2D1BrushVtbl
*)&d2d_solid_color_brush_vtbl
);
298 brush
->u
.solid
.color
= *color
;
301 static inline struct d2d_brush
*impl_from_ID2D1LinearGradientBrush(ID2D1LinearGradientBrush
*iface
)
303 return CONTAINING_RECORD(iface
, struct d2d_brush
, ID2D1Brush_iface
);
306 static HRESULT STDMETHODCALLTYPE
d2d_linear_gradient_brush_QueryInterface(ID2D1LinearGradientBrush
*iface
,
307 REFIID iid
, void **out
)
309 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
311 if (IsEqualGUID(iid
, &IID_ID2D1LinearGradientBrush
)
312 || IsEqualGUID(iid
, &IID_ID2D1Brush
)
313 || IsEqualGUID(iid
, &IID_ID2D1Resource
)
314 || IsEqualGUID(iid
, &IID_IUnknown
))
316 ID2D1LinearGradientBrush_AddRef(iface
);
321 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
324 return E_NOINTERFACE
;
327 static ULONG STDMETHODCALLTYPE
d2d_linear_gradient_brush_AddRef(ID2D1LinearGradientBrush
*iface
)
329 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
330 ULONG refcount
= InterlockedIncrement(&brush
->refcount
);
332 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
337 static ULONG STDMETHODCALLTYPE
d2d_linear_gradient_brush_Release(ID2D1LinearGradientBrush
*iface
)
339 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
340 ULONG refcount
= InterlockedDecrement(&brush
->refcount
);
342 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
345 HeapFree(GetProcessHeap(), 0, brush
);
350 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetFactory(ID2D1LinearGradientBrush
*iface
,
351 ID2D1Factory
**factory
)
353 FIXME("iface %p, factory %p stub!\n", iface
, factory
);
358 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_SetOpacity(ID2D1LinearGradientBrush
*iface
, float opacity
)
360 FIXME("iface %p, opacity %.8e stub!\n", iface
, opacity
);
363 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_SetTransform(ID2D1LinearGradientBrush
*iface
,
364 const D2D1_MATRIX_3X2_F
*transform
)
366 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
368 TRACE("iface %p, transform %p.\n", iface
, transform
);
370 brush
->transform
= *transform
;
373 static float STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetOpacity(ID2D1LinearGradientBrush
*iface
)
375 FIXME("iface %p stub!\n", iface
);
380 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetTransform(ID2D1LinearGradientBrush
*iface
,
381 D2D1_MATRIX_3X2_F
*transform
)
383 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
385 TRACE("iface %p, transform %p.\n", iface
, transform
);
387 *transform
= brush
->transform
;
390 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_SetStartPoint(ID2D1LinearGradientBrush
*iface
,
391 D2D1_POINT_2F start_point
)
393 FIXME("iface %p, start_point {%.8e, %.8e} stub!\n", iface
, start_point
.x
, start_point
.y
);
396 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_SetEndPoint(ID2D1LinearGradientBrush
*iface
,
397 D2D1_POINT_2F end_point
)
399 FIXME("iface %p, end_point {%.8e, %.8e} stub!\n", iface
, end_point
.x
, end_point
.y
);
402 static D2D1_POINT_2F
* STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetStartPoint(ID2D1LinearGradientBrush
*iface
,
403 D2D1_POINT_2F
*point
)
405 FIXME("iface %p, point %p stub!\n", iface
, point
);
412 static D2D1_POINT_2F
* STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetEndPoint(ID2D1LinearGradientBrush
*iface
,
413 D2D1_POINT_2F
*point
)
415 FIXME("iface %p, point %p stub!\n", iface
, point
);
422 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetGradientStopCollection(ID2D1LinearGradientBrush
*iface
,
423 ID2D1GradientStopCollection
**gradient
)
425 FIXME("iface %p, gradient %p stub!\n", iface
, gradient
);
430 static const struct ID2D1LinearGradientBrushVtbl d2d_linear_gradient_brush_vtbl
=
432 d2d_linear_gradient_brush_QueryInterface
,
433 d2d_linear_gradient_brush_AddRef
,
434 d2d_linear_gradient_brush_Release
,
435 d2d_linear_gradient_brush_GetFactory
,
436 d2d_linear_gradient_brush_SetOpacity
,
437 d2d_linear_gradient_brush_SetTransform
,
438 d2d_linear_gradient_brush_GetOpacity
,
439 d2d_linear_gradient_brush_GetTransform
,
440 d2d_linear_gradient_brush_SetStartPoint
,
441 d2d_linear_gradient_brush_SetEndPoint
,
442 d2d_linear_gradient_brush_GetStartPoint
,
443 d2d_linear_gradient_brush_GetEndPoint
,
444 d2d_linear_gradient_brush_GetGradientStopCollection
,
447 void d2d_linear_gradient_brush_init(struct d2d_brush
*brush
, ID2D1RenderTarget
*render_target
,
448 const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES
*gradient_brush_desc
, const D2D1_BRUSH_PROPERTIES
*brush_desc
,
449 ID2D1GradientStopCollection
*gradient
)
451 FIXME("Ignoring brush properties.\n");
453 d2d_brush_init(brush
, render_target
, D2D_BRUSH_TYPE_LINEAR
, brush_desc
,
454 (ID2D1BrushVtbl
*)&d2d_linear_gradient_brush_vtbl
);
457 static inline struct d2d_brush
*impl_from_ID2D1BitmapBrush(ID2D1BitmapBrush
*iface
)
459 return CONTAINING_RECORD(iface
, struct d2d_brush
, ID2D1Brush_iface
);
462 static HRESULT STDMETHODCALLTYPE
d2d_bitmap_brush_QueryInterface(ID2D1BitmapBrush
*iface
,
463 REFIID iid
, void **out
)
465 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
467 if (IsEqualGUID(iid
, &IID_ID2D1BitmapBrush
)
468 || IsEqualGUID(iid
, &IID_ID2D1Brush
)
469 || IsEqualGUID(iid
, &IID_ID2D1Resource
)
470 || IsEqualGUID(iid
, &IID_IUnknown
))
472 ID2D1BitmapBrush_AddRef(iface
);
477 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
480 return E_NOINTERFACE
;
483 static ULONG STDMETHODCALLTYPE
d2d_bitmap_brush_AddRef(ID2D1BitmapBrush
*iface
)
485 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
486 ULONG refcount
= InterlockedIncrement(&brush
->refcount
);
488 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
493 static ULONG STDMETHODCALLTYPE
d2d_bitmap_brush_Release(ID2D1BitmapBrush
*iface
)
495 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
496 ULONG refcount
= InterlockedDecrement(&brush
->refcount
);
498 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
502 if (brush
->u
.bitmap
.sampler_state
)
503 ID3D10SamplerState_Release(brush
->u
.bitmap
.sampler_state
);
504 HeapFree(GetProcessHeap(), 0, brush
);
510 static void STDMETHODCALLTYPE
d2d_bitmap_brush_GetFactory(ID2D1BitmapBrush
*iface
,
511 ID2D1Factory
**factory
)
513 FIXME("iface %p, factory %p stub!\n", iface
, factory
);
518 static void STDMETHODCALLTYPE
d2d_bitmap_brush_SetOpacity(ID2D1BitmapBrush
*iface
, float opacity
)
520 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
522 TRACE("iface %p, opacity %.8e.\n", iface
, opacity
);
524 brush
->opacity
= opacity
;
527 static void STDMETHODCALLTYPE
d2d_bitmap_brush_SetTransform(ID2D1BitmapBrush
*iface
,
528 const D2D1_MATRIX_3X2_F
*transform
)
530 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
532 TRACE("iface %p, transform %p.\n", iface
, transform
);
534 brush
->transform
= *transform
;
537 static float STDMETHODCALLTYPE
d2d_bitmap_brush_GetOpacity(ID2D1BitmapBrush
*iface
)
539 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
541 TRACE("iface %p.\n", iface
);
543 return brush
->opacity
;
546 static void STDMETHODCALLTYPE
d2d_bitmap_brush_GetTransform(ID2D1BitmapBrush
*iface
,
547 D2D1_MATRIX_3X2_F
*transform
)
549 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
551 TRACE("iface %p, transform %p.\n", iface
, transform
);
553 *transform
= brush
->transform
;
556 static void STDMETHODCALLTYPE
d2d_bitmap_brush_SetExtendModeX(ID2D1BitmapBrush
*iface
, D2D1_EXTEND_MODE mode
)
558 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
560 TRACE("iface %p, mode %#x.\n", iface
, mode
);
562 brush
->u
.bitmap
.extend_mode_x
= mode
;
563 if (brush
->u
.bitmap
.sampler_state
)
565 ID3D10SamplerState_Release(brush
->u
.bitmap
.sampler_state
);
566 brush
->u
.bitmap
.sampler_state
= NULL
;
570 static void STDMETHODCALLTYPE
d2d_bitmap_brush_SetExtendModeY(ID2D1BitmapBrush
*iface
, D2D1_EXTEND_MODE mode
)
572 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
574 TRACE("iface %p, mode %#x.\n", iface
, mode
);
576 brush
->u
.bitmap
.extend_mode_y
= mode
;
577 if (brush
->u
.bitmap
.sampler_state
)
579 ID3D10SamplerState_Release(brush
->u
.bitmap
.sampler_state
);
580 brush
->u
.bitmap
.sampler_state
= NULL
;
584 static void STDMETHODCALLTYPE
d2d_bitmap_brush_SetInterpolationMode(ID2D1BitmapBrush
*iface
,
585 D2D1_BITMAP_INTERPOLATION_MODE mode
)
587 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
589 TRACE("iface %p, mode %#x.\n", iface
, mode
);
591 brush
->u
.bitmap
.interpolation_mode
= mode
;
592 if (brush
->u
.bitmap
.sampler_state
)
594 ID3D10SamplerState_Release(brush
->u
.bitmap
.sampler_state
);
595 brush
->u
.bitmap
.sampler_state
= NULL
;
599 static void STDMETHODCALLTYPE
d2d_bitmap_brush_SetBitmap(ID2D1BitmapBrush
*iface
, ID2D1Bitmap
*bitmap
)
601 FIXME("iface %p, bitmap %p stub!\n", iface
, bitmap
);
604 static D2D1_EXTEND_MODE STDMETHODCALLTYPE
d2d_bitmap_brush_GetExtendModeX(ID2D1BitmapBrush
*iface
)
606 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
608 TRACE("iface %p.\n", iface
);
610 return brush
->u
.bitmap
.extend_mode_x
;
613 static D2D1_EXTEND_MODE STDMETHODCALLTYPE
d2d_bitmap_brush_GetExtendModeY(ID2D1BitmapBrush
*iface
)
615 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
617 TRACE("iface %p.\n", iface
);
619 return brush
->u
.bitmap
.extend_mode_y
;
622 static D2D1_BITMAP_INTERPOLATION_MODE STDMETHODCALLTYPE
d2d_bitmap_brush_GetInterpolationMode(ID2D1BitmapBrush
*iface
)
624 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
626 TRACE("iface %p.\n", iface
);
628 return brush
->u
.bitmap
.interpolation_mode
;
631 static void STDMETHODCALLTYPE
d2d_bitmap_brush_GetBitmap(ID2D1BitmapBrush
*iface
, ID2D1Bitmap
**bitmap
)
633 struct d2d_brush
*brush
= impl_from_ID2D1BitmapBrush(iface
);
635 TRACE("iface %p, bitmap %p.\n", iface
, bitmap
);
637 if ((*bitmap
= &brush
->u
.bitmap
.bitmap
->ID2D1Bitmap_iface
))
638 ID2D1Bitmap_AddRef(*bitmap
);
641 static const struct ID2D1BitmapBrushVtbl d2d_bitmap_brush_vtbl
=
643 d2d_bitmap_brush_QueryInterface
,
644 d2d_bitmap_brush_AddRef
,
645 d2d_bitmap_brush_Release
,
646 d2d_bitmap_brush_GetFactory
,
647 d2d_bitmap_brush_SetOpacity
,
648 d2d_bitmap_brush_SetTransform
,
649 d2d_bitmap_brush_GetOpacity
,
650 d2d_bitmap_brush_GetTransform
,
651 d2d_bitmap_brush_SetExtendModeX
,
652 d2d_bitmap_brush_SetExtendModeY
,
653 d2d_bitmap_brush_SetInterpolationMode
,
654 d2d_bitmap_brush_SetBitmap
,
655 d2d_bitmap_brush_GetExtendModeX
,
656 d2d_bitmap_brush_GetExtendModeY
,
657 d2d_bitmap_brush_GetInterpolationMode
,
658 d2d_bitmap_brush_GetBitmap
,
661 HRESULT
d2d_bitmap_brush_init(struct d2d_brush
*brush
, struct d2d_d3d_render_target
*render_target
, ID2D1Bitmap
*bitmap
,
662 const D2D1_BITMAP_BRUSH_PROPERTIES
*bitmap_brush_desc
, const D2D1_BRUSH_PROPERTIES
*brush_desc
)
665 FIXME("Ignoring brush properties.\n");
667 d2d_brush_init(brush
, &render_target
->ID2D1RenderTarget_iface
, D2D_BRUSH_TYPE_BITMAP
,
668 brush_desc
, (ID2D1BrushVtbl
*)&d2d_bitmap_brush_vtbl
);
669 brush
->u
.bitmap
.bitmap
= unsafe_impl_from_ID2D1Bitmap(bitmap
);
670 if (bitmap_brush_desc
)
672 brush
->u
.bitmap
.extend_mode_x
= bitmap_brush_desc
->extendModeX
;
673 brush
->u
.bitmap
.extend_mode_y
= bitmap_brush_desc
->extendModeY
;
674 brush
->u
.bitmap
.interpolation_mode
= bitmap_brush_desc
->interpolationMode
;
678 brush
->u
.bitmap
.extend_mode_x
= D2D1_EXTEND_MODE_CLAMP
;
679 brush
->u
.bitmap
.extend_mode_y
= D2D1_EXTEND_MODE_CLAMP
;
680 brush
->u
.bitmap
.interpolation_mode
= D2D1_BITMAP_INTERPOLATION_MODE_LINEAR
;
686 struct d2d_brush
*unsafe_impl_from_ID2D1Brush(ID2D1Brush
*iface
)
690 assert(iface
->lpVtbl
== (const ID2D1BrushVtbl
*)&d2d_solid_color_brush_vtbl
691 || iface
->lpVtbl
== (const ID2D1BrushVtbl
*)&d2d_linear_gradient_brush_vtbl
692 || iface
->lpVtbl
== (const ID2D1BrushVtbl
*)&d2d_bitmap_brush_vtbl
);
693 return CONTAINING_RECORD(iface
, struct d2d_brush
, ID2D1Brush_iface
);
696 static D3D10_TEXTURE_ADDRESS_MODE
texture_addres_mode_from_extend_mode(D2D1_EXTEND_MODE mode
)
700 case D2D1_EXTEND_MODE_CLAMP
:
701 return D3D10_TEXTURE_ADDRESS_CLAMP
;
702 case D2D1_EXTEND_MODE_WRAP
:
703 return D3D10_TEXTURE_ADDRESS_WRAP
;
704 case D2D1_EXTEND_MODE_MIRROR
:
705 return D3D10_TEXTURE_ADDRESS_MIRROR
;
707 FIXME("Unhandled extend mode %#x.\n", mode
);
708 return D3D10_TEXTURE_ADDRESS_CLAMP
;
712 void d2d_brush_bind_resources(struct d2d_brush
*brush
, ID3D10Device
*device
)
716 if (brush
->type
== D2D_BRUSH_TYPE_BITMAP
)
718 ID3D10Device_PSSetShaderResources(device
, 0, 1, &brush
->u
.bitmap
.bitmap
->view
);
719 if (!brush
->u
.bitmap
.sampler_state
)
721 D3D10_SAMPLER_DESC sampler_desc
;
723 if (brush
->u
.bitmap
.interpolation_mode
== D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR
)
724 sampler_desc
.Filter
= D3D10_FILTER_MIN_MAG_MIP_POINT
;
726 sampler_desc
.Filter
= D3D10_FILTER_MIN_MAG_MIP_LINEAR
;
727 sampler_desc
.AddressU
= texture_addres_mode_from_extend_mode(brush
->u
.bitmap
.extend_mode_x
);
728 sampler_desc
.AddressV
= texture_addres_mode_from_extend_mode(brush
->u
.bitmap
.extend_mode_y
);
729 sampler_desc
.AddressW
= D3D10_TEXTURE_ADDRESS_CLAMP
;
730 sampler_desc
.MipLODBias
= 0.0f
;
731 sampler_desc
.MaxAnisotropy
= 0;
732 sampler_desc
.ComparisonFunc
= D3D10_COMPARISON_NEVER
;
733 sampler_desc
.BorderColor
[0] = 0.0f
;
734 sampler_desc
.BorderColor
[1] = 0.0f
;
735 sampler_desc
.BorderColor
[2] = 0.0f
;
736 sampler_desc
.BorderColor
[3] = 0.0f
;
737 sampler_desc
.MinLOD
= 0.0f
;
738 sampler_desc
.MaxLOD
= 0.0f
;
740 if (FAILED(hr
= ID3D10Device_CreateSamplerState(device
,
741 &sampler_desc
, &brush
->u
.bitmap
.sampler_state
)))
742 ERR("Failed to create sampler state, hr %#x.\n", hr
);
744 ID3D10Device_PSSetSamplers(device
, 0, 1, &brush
->u
.bitmap
.sampler_state
);