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 brush
->ID2D1Brush_iface
.lpVtbl
= vtbl
;
152 brush
->opacity
= desc
? desc
->opacity
: 1.0f
;
156 static inline struct d2d_brush
*impl_from_ID2D1SolidColorBrush(ID2D1SolidColorBrush
*iface
)
158 return CONTAINING_RECORD(iface
, struct d2d_brush
, ID2D1Brush_iface
);
161 static HRESULT STDMETHODCALLTYPE
d2d_solid_color_brush_QueryInterface(ID2D1SolidColorBrush
*iface
,
162 REFIID iid
, void **out
)
164 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
166 if (IsEqualGUID(iid
, &IID_ID2D1SolidColorBrush
)
167 || IsEqualGUID(iid
, &IID_ID2D1Brush
)
168 || IsEqualGUID(iid
, &IID_ID2D1Resource
)
169 || IsEqualGUID(iid
, &IID_IUnknown
))
171 ID2D1SolidColorBrush_AddRef(iface
);
176 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
179 return E_NOINTERFACE
;
182 static ULONG STDMETHODCALLTYPE
d2d_solid_color_brush_AddRef(ID2D1SolidColorBrush
*iface
)
184 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
185 ULONG refcount
= InterlockedIncrement(&brush
->refcount
);
187 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
192 static ULONG STDMETHODCALLTYPE
d2d_solid_color_brush_Release(ID2D1SolidColorBrush
*iface
)
194 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
195 ULONG refcount
= InterlockedDecrement(&brush
->refcount
);
197 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
200 HeapFree(GetProcessHeap(), 0, brush
);
205 static void STDMETHODCALLTYPE
d2d_solid_color_brush_GetFactory(ID2D1SolidColorBrush
*iface
, ID2D1Factory
**factory
)
207 FIXME("iface %p, factory %p stub!\n", iface
, factory
);
212 static void STDMETHODCALLTYPE
d2d_solid_color_brush_SetOpacity(ID2D1SolidColorBrush
*iface
, float opacity
)
214 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
216 TRACE("iface %p, opacity %.8e.\n", iface
, opacity
);
218 brush
->opacity
= opacity
;
221 static void STDMETHODCALLTYPE
d2d_solid_color_brush_SetTransform(ID2D1SolidColorBrush
*iface
,
222 const D2D1_MATRIX_3X2_F
*transform
)
224 FIXME("iface %p, transform %p stub!\n", iface
, transform
);
227 static float STDMETHODCALLTYPE
d2d_solid_color_brush_GetOpacity(ID2D1SolidColorBrush
*iface
)
229 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
231 TRACE("iface %p.\n", iface
);
233 return brush
->opacity
;
236 static void STDMETHODCALLTYPE
d2d_solid_color_brush_GetTransform(ID2D1SolidColorBrush
*iface
,
237 D2D1_MATRIX_3X2_F
*transform
)
239 static const D2D1_MATRIX_3X2_F identity
=
246 FIXME("iface %p, transform %p stub!\n", iface
, transform
);
248 *transform
= identity
;
251 static void STDMETHODCALLTYPE
d2d_solid_color_brush_SetColor(ID2D1SolidColorBrush
*iface
, const D2D1_COLOR_F
*color
)
253 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
255 TRACE("iface %p, color %p.\n", iface
, color
);
257 brush
->u
.solid
.color
= *color
;
260 static D2D1_COLOR_F
* STDMETHODCALLTYPE
d2d_solid_color_brush_GetColor(ID2D1SolidColorBrush
*iface
, D2D1_COLOR_F
*color
)
262 struct d2d_brush
*brush
= impl_from_ID2D1SolidColorBrush(iface
);
264 TRACE("iface %p, color %p.\n", iface
, color
);
266 *color
= brush
->u
.solid
.color
;
270 static const struct ID2D1SolidColorBrushVtbl d2d_solid_color_brush_vtbl
=
272 d2d_solid_color_brush_QueryInterface
,
273 d2d_solid_color_brush_AddRef
,
274 d2d_solid_color_brush_Release
,
275 d2d_solid_color_brush_GetFactory
,
276 d2d_solid_color_brush_SetOpacity
,
277 d2d_solid_color_brush_SetTransform
,
278 d2d_solid_color_brush_GetOpacity
,
279 d2d_solid_color_brush_GetTransform
,
280 d2d_solid_color_brush_SetColor
,
281 d2d_solid_color_brush_GetColor
,
284 void d2d_solid_color_brush_init(struct d2d_brush
*brush
, ID2D1RenderTarget
*render_target
,
285 const D2D1_COLOR_F
*color
, const D2D1_BRUSH_PROPERTIES
*desc
)
287 FIXME("Ignoring brush properties.\n");
289 d2d_brush_init(brush
, render_target
, D2D_BRUSH_TYPE_SOLID
, desc
,
290 (ID2D1BrushVtbl
*)&d2d_solid_color_brush_vtbl
);
291 brush
->u
.solid
.color
= *color
;
294 static inline struct d2d_brush
*impl_from_ID2D1LinearGradientBrush(ID2D1LinearGradientBrush
*iface
)
296 return CONTAINING_RECORD(iface
, struct d2d_brush
, ID2D1Brush_iface
);
299 static HRESULT STDMETHODCALLTYPE
d2d_linear_gradient_brush_QueryInterface(ID2D1LinearGradientBrush
*iface
,
300 REFIID iid
, void **out
)
302 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
304 if (IsEqualGUID(iid
, &IID_ID2D1LinearGradientBrush
)
305 || IsEqualGUID(iid
, &IID_ID2D1Brush
)
306 || IsEqualGUID(iid
, &IID_ID2D1Resource
)
307 || IsEqualGUID(iid
, &IID_IUnknown
))
309 ID2D1LinearGradientBrush_AddRef(iface
);
314 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
317 return E_NOINTERFACE
;
320 static ULONG STDMETHODCALLTYPE
d2d_linear_gradient_brush_AddRef(ID2D1LinearGradientBrush
*iface
)
322 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
323 ULONG refcount
= InterlockedIncrement(&brush
->refcount
);
325 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
330 static ULONG STDMETHODCALLTYPE
d2d_linear_gradient_brush_Release(ID2D1LinearGradientBrush
*iface
)
332 struct d2d_brush
*brush
= impl_from_ID2D1LinearGradientBrush(iface
);
333 ULONG refcount
= InterlockedDecrement(&brush
->refcount
);
335 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
338 HeapFree(GetProcessHeap(), 0, brush
);
343 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetFactory(ID2D1LinearGradientBrush
*iface
,
344 ID2D1Factory
**factory
)
346 FIXME("iface %p, factory %p stub!\n", iface
, factory
);
351 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_SetOpacity(ID2D1LinearGradientBrush
*iface
, float opacity
)
353 FIXME("iface %p, opacity %.8e stub!\n", iface
, opacity
);
356 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_SetTransform(ID2D1LinearGradientBrush
*iface
,
357 const D2D1_MATRIX_3X2_F
*transform
)
359 FIXME("iface %p, transform %p stub!\n", iface
, transform
);
362 static float STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetOpacity(ID2D1LinearGradientBrush
*iface
)
364 FIXME("iface %p stub!\n", iface
);
369 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetTransform(ID2D1LinearGradientBrush
*iface
,
370 D2D1_MATRIX_3X2_F
*transform
)
372 static const D2D1_MATRIX_3X2_F identity
=
379 FIXME("iface %p, transform %p stub!\n", iface
, transform
);
381 *transform
= identity
;
384 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_SetStartPoint(ID2D1LinearGradientBrush
*iface
,
385 D2D1_POINT_2F start_point
)
387 FIXME("iface %p, start_point {%.8e, %.8e} stub!\n", iface
, start_point
.x
, start_point
.y
);
390 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_SetEndPoint(ID2D1LinearGradientBrush
*iface
,
391 D2D1_POINT_2F end_point
)
393 FIXME("iface %p, end_point {%.8e, %.8e} stub!\n", iface
, end_point
.x
, end_point
.y
);
396 static D2D1_POINT_2F
* STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetStartPoint(ID2D1LinearGradientBrush
*iface
,
397 D2D1_POINT_2F
*point
)
399 FIXME("iface %p, point %p stub!\n", iface
, point
);
406 static D2D1_POINT_2F
* STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetEndPoint(ID2D1LinearGradientBrush
*iface
,
407 D2D1_POINT_2F
*point
)
409 FIXME("iface %p, point %p stub!\n", iface
, point
);
416 static void STDMETHODCALLTYPE
d2d_linear_gradient_brush_GetGradientStopCollection(ID2D1LinearGradientBrush
*iface
,
417 ID2D1GradientStopCollection
**gradient
)
419 FIXME("iface %p, gradient %p stub!\n", iface
, gradient
);
424 static const struct ID2D1LinearGradientBrushVtbl d2d_linear_gradient_brush_vtbl
=
426 d2d_linear_gradient_brush_QueryInterface
,
427 d2d_linear_gradient_brush_AddRef
,
428 d2d_linear_gradient_brush_Release
,
429 d2d_linear_gradient_brush_GetFactory
,
430 d2d_linear_gradient_brush_SetOpacity
,
431 d2d_linear_gradient_brush_SetTransform
,
432 d2d_linear_gradient_brush_GetOpacity
,
433 d2d_linear_gradient_brush_GetTransform
,
434 d2d_linear_gradient_brush_SetStartPoint
,
435 d2d_linear_gradient_brush_SetEndPoint
,
436 d2d_linear_gradient_brush_GetStartPoint
,
437 d2d_linear_gradient_brush_GetEndPoint
,
438 d2d_linear_gradient_brush_GetGradientStopCollection
,
441 void d2d_linear_gradient_brush_init(struct d2d_brush
*brush
, ID2D1RenderTarget
*render_target
,
442 const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES
*gradient_brush_desc
, const D2D1_BRUSH_PROPERTIES
*brush_desc
,
443 ID2D1GradientStopCollection
*gradient
)
445 FIXME("Ignoring brush properties.\n");
447 d2d_brush_init(brush
, render_target
, D2D_BRUSH_TYPE_LINEAR
, brush_desc
,
448 (ID2D1BrushVtbl
*)&d2d_linear_gradient_brush_vtbl
);
451 struct d2d_brush
*unsafe_impl_from_ID2D1Brush(ID2D1Brush
*iface
)
455 assert(iface
->lpVtbl
== (const ID2D1BrushVtbl
*)&d2d_solid_color_brush_vtbl
456 || iface
->lpVtbl
== (const ID2D1BrushVtbl
*)&d2d_linear_gradient_brush_vtbl
);
457 return CONTAINING_RECORD(iface
, struct d2d_brush
, ID2D1Brush_iface
);