dwrite: Implement CreateFontFaceFromHdc().
[wine.git] / dlls / d2d1 / render_target.c
bloba50f4733eaa1d9e77d77b282fce7fcdcda1b494a
1 /*
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
19 #include "config.h"
20 #include "wine/port.h"
22 #include "d2d1_private.h"
23 #include "wincodec.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d2d);
27 #define INITIAL_CLIP_STACK_SIZE 4
29 struct d2d_draw_text_layout_ctx
31 ID2D1Brush *brush;
32 D2D1_DRAW_TEXT_OPTIONS options;
35 static void d2d_point_transform(D2D1_POINT_2F *dst, const D2D1_MATRIX_3X2_F *matrix, float x, float y)
37 dst->x = x * matrix->_11 + y * matrix->_21 + matrix->_31;
38 dst->y = x * matrix->_12 + y * matrix->_22 + matrix->_32;
41 static void d2d_rect_expand(D2D1_RECT_F *dst, const D2D1_POINT_2F *point)
43 if (point->x < dst->left)
44 dst->left = point->x;
45 if (point->y < dst->top)
46 dst->top = point->y;
47 if (point->x > dst->right)
48 dst->right = point->x;
49 if (point->y > dst->bottom)
50 dst->bottom = point->y;
53 static void d2d_rect_intersect(D2D1_RECT_F *dst, const D2D1_RECT_F *src)
55 if (src->left > dst->left)
56 dst->left = src->left;
57 if (src->top > dst->top)
58 dst->top = src->top;
59 if (src->right < dst->right)
60 dst->right = src->right;
61 if (src->bottom < dst->bottom)
62 dst->bottom = src->bottom;
65 static void d2d_rect_set(D2D1_RECT_F *dst, float left, float top, float right, float bottom)
67 dst->left = left;
68 dst->top = top;
69 dst->right = right;
70 dst->bottom = bottom;
73 static BOOL d2d_clip_stack_init(struct d2d_clip_stack *stack)
75 if (!(stack->stack = HeapAlloc(GetProcessHeap(), 0, INITIAL_CLIP_STACK_SIZE * sizeof(*stack->stack))))
76 return FALSE;
78 stack->size = INITIAL_CLIP_STACK_SIZE;
79 stack->count = 0;
81 return TRUE;
84 static void d2d_clip_stack_cleanup(struct d2d_clip_stack *stack)
86 HeapFree(GetProcessHeap(), 0, stack->stack);
89 static BOOL d2d_clip_stack_push(struct d2d_clip_stack *stack, const D2D1_RECT_F *rect)
91 D2D1_RECT_F r;
93 if (stack->count == stack->size)
95 D2D1_RECT_F *new_stack;
96 unsigned int new_size;
98 if (stack->size > UINT_MAX / 2)
99 return FALSE;
101 new_size = stack->size * 2;
102 if (!(new_stack = HeapReAlloc(GetProcessHeap(), 0, stack->stack, new_size * sizeof(*stack->stack))))
103 return FALSE;
105 stack->stack = new_stack;
106 stack->size = new_size;
109 r = *rect;
110 if (stack->count)
111 d2d_rect_intersect(&r, &stack->stack[stack->count - 1]);
112 stack->stack[stack->count++] = r;
114 return TRUE;
117 static void d2d_clip_stack_pop(struct d2d_clip_stack *stack)
119 if (!stack->count)
120 return;
121 --stack->count;
124 static inline struct d2d_d3d_render_target *impl_from_ID2D1RenderTarget(ID2D1RenderTarget *iface)
126 return CONTAINING_RECORD(iface, struct d2d_d3d_render_target, ID2D1RenderTarget_iface);
129 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_QueryInterface(ID2D1RenderTarget *iface, REFIID iid, void **out)
131 TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
133 if (IsEqualGUID(iid, &IID_ID2D1RenderTarget)
134 || IsEqualGUID(iid, &IID_ID2D1Resource)
135 || IsEqualGUID(iid, &IID_IUnknown))
137 ID2D1RenderTarget_AddRef(iface);
138 *out = iface;
139 return S_OK;
142 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
144 *out = NULL;
145 return E_NOINTERFACE;
148 static ULONG STDMETHODCALLTYPE d2d_d3d_render_target_AddRef(ID2D1RenderTarget *iface)
150 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
151 ULONG refcount = InterlockedIncrement(&render_target->refcount);
153 TRACE("%p increasing refcount to %u.\n", iface, refcount);
155 return refcount;
158 static ULONG STDMETHODCALLTYPE d2d_d3d_render_target_Release(ID2D1RenderTarget *iface)
160 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
161 ULONG refcount = InterlockedDecrement(&render_target->refcount);
163 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
165 if (!refcount)
167 d2d_clip_stack_cleanup(&render_target->clip_stack);
168 ID3D10RenderTargetView_Release(render_target->view);
169 ID3D10RasterizerState_Release(render_target->clear_rs);
170 ID3D10PixelShader_Release(render_target->clear_ps);
171 ID3D10VertexShader_Release(render_target->clear_vs);
172 ID3D10Buffer_Release(render_target->clear_vb);
173 ID3D10InputLayout_Release(render_target->clear_il);
174 render_target->stateblock->lpVtbl->Release(render_target->stateblock);
175 ID3D10Device_Release(render_target->device);
176 HeapFree(GetProcessHeap(), 0, render_target);
179 return refcount;
182 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetFactory(ID2D1RenderTarget *iface, ID2D1Factory **factory)
184 FIXME("iface %p, factory %p stub!\n", iface, factory);
186 *factory = NULL;
189 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmap(ID2D1RenderTarget *iface,
190 D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
192 struct d2d_bitmap *object;
194 TRACE("iface %p, size {%u, %u}, src_data %p, pitch %u, desc %p, bitmap %p.\n",
195 iface, size.width, size.height, src_data, pitch, desc, bitmap);
197 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
198 return E_OUTOFMEMORY;
200 d2d_bitmap_init(object, size, src_data, pitch, desc);
202 TRACE("Created bitmap %p.\n", object);
203 *bitmap = &object->ID2D1Bitmap_iface;
205 return S_OK;
208 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmapFromWicBitmap(ID2D1RenderTarget *iface,
209 IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
211 D2D1_BITMAP_PROPERTIES bitmap_desc;
212 unsigned int bpp, data_size;
213 D2D1_SIZE_U size;
214 WICRect rect;
215 UINT32 pitch;
216 HRESULT hr;
217 void *data;
219 TRACE("iface %p, bitmap_source %p, desc %p, bitmap %p.\n",
220 iface, bitmap_source, desc, bitmap);
222 if (FAILED(hr = IWICBitmapSource_GetSize(bitmap_source, &size.width, &size.height)))
224 WARN("Failed to get bitmap size, hr %#x.\n", hr);
225 return hr;
228 if (!desc)
230 bitmap_desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
231 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_UNKNOWN;
232 bitmap_desc.dpiX = 0.0f;
233 bitmap_desc.dpiY = 0.0f;
235 else
237 bitmap_desc = *desc;
240 if (bitmap_desc.pixelFormat.format == DXGI_FORMAT_UNKNOWN)
242 WICPixelFormatGUID wic_format;
244 if (FAILED(hr = IWICBitmapSource_GetPixelFormat(bitmap_source, &wic_format)))
246 WARN("Failed to get bitmap format, hr %#x.\n", hr);
247 return hr;
250 if (IsEqualGUID(&wic_format, &GUID_WICPixelFormat32bppPBGRA)
251 || IsEqualGUID(&wic_format, &GUID_WICPixelFormat32bppBGR))
253 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
255 else
257 WARN("Unsupported WIC bitmap format %s.\n", debugstr_guid(&wic_format));
258 return D2DERR_UNSUPPORTED_PIXEL_FORMAT;
262 switch (bitmap_desc.pixelFormat.format)
264 case DXGI_FORMAT_B8G8R8A8_UNORM:
265 bpp = 4;
266 break;
268 default:
269 FIXME("Unhandled format %#x.\n", bitmap_desc.pixelFormat.format);
270 return D2DERR_UNSUPPORTED_PIXEL_FORMAT;
273 pitch = ((bpp * size.width) + 15) & ~15;
274 data_size = pitch * size.height;
275 if (!(data = HeapAlloc(GetProcessHeap(), 0, data_size)))
276 return E_OUTOFMEMORY;
278 rect.X = 0;
279 rect.Y = 0;
280 rect.Width = size.width;
281 rect.Height = size.height;
282 if (FAILED(hr = IWICBitmapSource_CopyPixels(bitmap_source, &rect, pitch, data_size, data)))
284 WARN("Failed to copy bitmap pixels, hr %#x.\n", hr);
285 HeapFree(GetProcessHeap(), 0, data);
286 return hr;
289 hr = d2d_d3d_render_target_CreateBitmap(iface, size, data, pitch, &bitmap_desc, bitmap);
291 HeapFree(GetProcessHeap(), 0, data);
293 return hr;
296 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateSharedBitmap(ID2D1RenderTarget *iface,
297 REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
299 FIXME("iface %p, iid %s, data %p, desc %p, bitmap %p stub!\n",
300 iface, debugstr_guid(iid), data, desc, bitmap);
302 return E_NOTIMPL;
305 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmapBrush(ID2D1RenderTarget *iface,
306 ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES *bitmap_brush_desc,
307 const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1BitmapBrush **brush)
309 FIXME("iface %p, bitmap %p, bitmap_brush_desc %p, brush_desc %p, brush %p stub!\n",
310 iface, bitmap, bitmap_brush_desc, brush_desc, brush);
312 return E_NOTIMPL;
315 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateSolidColorBrush(ID2D1RenderTarget *iface,
316 const D2D1_COLOR_F *color, const D2D1_BRUSH_PROPERTIES *desc, ID2D1SolidColorBrush **brush)
318 struct d2d_brush *object;
320 TRACE("iface %p, color %p, desc %p, brush %p.\n", iface, color, desc, brush);
322 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
323 return E_OUTOFMEMORY;
325 d2d_solid_color_brush_init(object, iface, color, desc);
327 TRACE("Created brush %p.\n", object);
328 *brush = (ID2D1SolidColorBrush *)&object->ID2D1Brush_iface;
330 return S_OK;
333 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateGradientStopCollection(ID2D1RenderTarget *iface,
334 const D2D1_GRADIENT_STOP *stops, UINT32 stop_count, D2D1_GAMMA gamma, D2D1_EXTEND_MODE extend_mode,
335 ID2D1GradientStopCollection **gradient)
337 struct d2d_gradient *object;
339 TRACE("iface %p, stops %p, stop_count %u, gamma %#x, extend_mode %#x, gradient %p.\n",
340 iface, stops, stop_count, gamma, extend_mode, gradient);
342 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
343 return E_OUTOFMEMORY;
345 d2d_gradient_init(object, iface, stops, stop_count, gamma, extend_mode);
347 TRACE("Created gradient %p.\n", object);
348 *gradient = &object->ID2D1GradientStopCollection_iface;
350 return S_OK;
353 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateLinearGradientBrush(ID2D1RenderTarget *iface,
354 const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc,
355 ID2D1GradientStopCollection *gradient, ID2D1LinearGradientBrush **brush)
357 struct d2d_brush *object;
359 TRACE("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n",
360 iface, gradient_brush_desc, brush_desc, gradient, brush);
362 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
363 return E_OUTOFMEMORY;
365 d2d_linear_gradient_brush_init(object, iface, gradient_brush_desc, brush_desc, gradient);
367 TRACE("Created brush %p.\n", object);
368 *brush = (ID2D1LinearGradientBrush *)&object->ID2D1Brush_iface;
370 return S_OK;
373 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateRadialGradientBrush(ID2D1RenderTarget *iface,
374 const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc,
375 ID2D1GradientStopCollection *gradient, ID2D1RadialGradientBrush **brush)
377 FIXME("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p stub!\n",
378 iface, gradient_brush_desc, brush_desc, gradient, brush);
380 return E_NOTIMPL;
383 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateCompatibleRenderTarget(ID2D1RenderTarget *iface,
384 const D2D1_SIZE_F *size, const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *format,
385 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, ID2D1BitmapRenderTarget **render_target)
387 FIXME("iface %p, size %p, pixel_size %p, format %p, options %#x, render_target %p stub!\n",
388 iface, size, pixel_size, format, options, render_target);
390 return E_NOTIMPL;
393 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateLayer(ID2D1RenderTarget *iface,
394 const D2D1_SIZE_F *size, ID2D1Layer **layer)
396 FIXME("iface %p, size %p, layer %p stub!\n", iface, size, layer);
398 return E_NOTIMPL;
401 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateMesh(ID2D1RenderTarget *iface, ID2D1Mesh **mesh)
403 struct d2d_mesh *object;
405 TRACE("iface %p, mesh %p.\n", iface, mesh);
407 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
408 return E_OUTOFMEMORY;
410 d2d_mesh_init(object);
412 TRACE("Created mesh %p.\n", object);
413 *mesh = &object->ID2D1Mesh_iface;
415 return S_OK;
418 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawLine(ID2D1RenderTarget *iface,
419 D2D1_POINT_2F p0, D2D1_POINT_2F p1, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
421 FIXME("iface %p, p0 {%.8e, %.8e}, p1 {%.8e, %.8e}, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
422 iface, p0.x, p0.y, p1.x, p1.y, brush, stroke_width, stroke_style);
425 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawRectangle(ID2D1RenderTarget *iface,
426 const D2D1_RECT_F *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
428 FIXME("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
429 iface, rect, brush, stroke_width, stroke_style);
432 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRectangle(ID2D1RenderTarget *iface,
433 const D2D1_RECT_F *rect, ID2D1Brush *brush)
435 FIXME("iface %p, rect %p, brush %p stub!\n", iface, rect, brush);
438 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawRoundedRectangle(ID2D1RenderTarget *iface,
439 const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
441 FIXME("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
442 iface, rect, brush, stroke_width, stroke_style);
445 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRoundedRectangle(ID2D1RenderTarget *iface,
446 const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush)
448 FIXME("iface %p, rect %p, brush %p stub!\n", iface, rect, brush);
451 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawEllipse(ID2D1RenderTarget *iface,
452 const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
454 FIXME("iface %p, ellipse %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
455 iface, ellipse, brush, stroke_width, stroke_style);
458 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillEllipse(ID2D1RenderTarget *iface,
459 const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush)
461 FIXME("iface %p, ellipse %p, brush %p stub!\n", iface, ellipse, brush);
464 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGeometry(ID2D1RenderTarget *iface,
465 ID2D1Geometry *geometry, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
467 FIXME("iface %p, geometry %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
468 iface, geometry, brush, stroke_width, stroke_style);
471 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillGeometry(ID2D1RenderTarget *iface,
472 ID2D1Geometry *geometry, ID2D1Brush *brush, ID2D1Brush *opacity_brush)
474 FIXME("iface %p, geometry %p, brush %p, opacity_brush %p stub!\n", iface, geometry, brush, opacity_brush);
477 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillMesh(ID2D1RenderTarget *iface,
478 ID2D1Mesh *mesh, ID2D1Brush *brush)
480 FIXME("iface %p, mesh %p, brush %p stub!\n", iface, mesh, brush);
483 static void STDMETHODCALLTYPE d2d_d3d_render_target_FillOpacityMask(ID2D1RenderTarget *iface,
484 ID2D1Bitmap *mask, ID2D1Brush *brush, D2D1_OPACITY_MASK_CONTENT content,
485 const D2D1_RECT_F *dst_rect, const D2D1_RECT_F *src_rect)
487 FIXME("iface %p, mask %p, brush %p, content %#x, dst_rect %p, src_rect %p stub!\n",
488 iface, mask, brush, content, dst_rect, src_rect);
491 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawBitmap(ID2D1RenderTarget *iface,
492 ID2D1Bitmap *bitmap, const D2D1_RECT_F *dst_rect, float opacity,
493 D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode, const D2D1_RECT_F *src_rect)
495 FIXME("iface %p, bitmap %p, dst_rect %p, opacity %.8e, interpolation_mode %#x, src_rect %p stub!\n",
496 iface, bitmap, dst_rect, opacity, interpolation_mode, src_rect);
499 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawText(ID2D1RenderTarget *iface,
500 const WCHAR *string, UINT32 string_len, IDWriteTextFormat *text_format, const D2D1_RECT_F *layout_rect,
501 ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options, DWRITE_MEASURING_MODE measuring_mode)
503 FIXME("iface %p, string %s, string_len %u, text_format %p, layout_rect %p, "
504 "brush %p, options %#x, measuring_mode %#x stub!\n",
505 iface, debugstr_wn(string, string_len), string_len, text_format, layout_rect,
506 brush, options, measuring_mode);
509 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawTextLayout(ID2D1RenderTarget *iface,
510 D2D1_POINT_2F origin, IDWriteTextLayout *layout, ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options)
512 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
513 struct d2d_draw_text_layout_ctx ctx;
514 HRESULT hr;
516 TRACE("iface %p, origin {%.8e, %.8e}, layout %p, brush %p, options %#x.\n",
517 iface, origin.x, origin.y, layout, brush, options);
519 ctx.brush = brush;
520 ctx.options = options;
522 if (FAILED(hr = IDWriteTextLayout_Draw(layout,
523 &ctx, &render_target->IDWriteTextRenderer_iface, origin.x, origin.y)))
524 FIXME("Failed to draw text layout, hr %#x.\n", hr);
527 static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGlyphRun(ID2D1RenderTarget *iface,
528 D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush,
529 DWRITE_MEASURING_MODE measuring_mode)
531 FIXME("iface %p, baseline_origin {%.8e, %.8e}, glyph_run %p, brush %p, measuring_mode %#x stub!\n",
532 iface, baseline_origin.x, baseline_origin.y, glyph_run, brush, measuring_mode);
535 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTransform(ID2D1RenderTarget *iface,
536 const D2D1_MATRIX_3X2_F *transform)
538 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
540 TRACE("iface %p, transform %p.\n", iface, transform);
542 render_target->transform = *transform;
545 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetTransform(ID2D1RenderTarget *iface,
546 D2D1_MATRIX_3X2_F *transform)
548 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
550 TRACE("iface %p, transform %p.\n", iface, transform);
552 *transform = render_target->transform;
555 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetAntialiasMode(ID2D1RenderTarget *iface,
556 D2D1_ANTIALIAS_MODE antialias_mode)
558 FIXME("iface %p, antialias_mode %#x stub!\n", iface, antialias_mode);
561 static D2D1_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_d3d_render_target_GetAntialiasMode(ID2D1RenderTarget *iface)
563 FIXME("iface %p stub!\n", iface);
565 return D2D1_ANTIALIAS_MODE_PER_PRIMITIVE;
568 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTextAntialiasMode(ID2D1RenderTarget *iface,
569 D2D1_TEXT_ANTIALIAS_MODE antialias_mode)
571 FIXME("iface %p, antialias_mode %#x stub!\n", iface, antialias_mode);
574 static D2D1_TEXT_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_d3d_render_target_GetTextAntialiasMode(ID2D1RenderTarget *iface)
576 FIXME("iface %p stub!\n", iface);
578 return D2D1_TEXT_ANTIALIAS_MODE_DEFAULT;
581 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTextRenderingParams(ID2D1RenderTarget *iface,
582 IDWriteRenderingParams *text_rendering_params)
584 FIXME("iface %p, text_rendering_params %p stub!\n", iface, text_rendering_params);
587 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetTextRenderingParams(ID2D1RenderTarget *iface,
588 IDWriteRenderingParams **text_rendering_params)
590 FIXME("iface %p, text_rendering_params %p stub!\n", iface, text_rendering_params);
592 *text_rendering_params = NULL;
595 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTags(ID2D1RenderTarget *iface, D2D1_TAG tag1, D2D1_TAG tag2)
597 FIXME("iface %p, tag1 %s, tag2 %s stub!\n", iface, wine_dbgstr_longlong(tag1), wine_dbgstr_longlong(tag2));
600 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetTags(ID2D1RenderTarget *iface, D2D1_TAG *tag1, D2D1_TAG *tag2)
602 FIXME("iface %p, tag1 %p, tag2 %p stub!\n", iface, tag1, tag2);
604 *tag1 = 0;
605 *tag2 = 0;
608 static void STDMETHODCALLTYPE d2d_d3d_render_target_PushLayer(ID2D1RenderTarget *iface,
609 const D2D1_LAYER_PARAMETERS *layer_parameters, ID2D1Layer *layer)
611 FIXME("iface %p, layer_parameters %p, layer %p stub!\n", iface, layer_parameters, layer);
614 static void STDMETHODCALLTYPE d2d_d3d_render_target_PopLayer(ID2D1RenderTarget *iface)
616 FIXME("iface %p stub!\n", iface);
619 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_Flush(ID2D1RenderTarget *iface, D2D1_TAG *tag1, D2D1_TAG *tag2)
621 FIXME("iface %p, tag1 %p, tag2 %p stub!\n", iface, tag1, tag2);
623 return E_NOTIMPL;
626 static void STDMETHODCALLTYPE d2d_d3d_render_target_SaveDrawingState(ID2D1RenderTarget *iface,
627 ID2D1DrawingStateBlock *state_block)
629 FIXME("iface %p, state_block %p stub!\n", iface, state_block);
632 static void STDMETHODCALLTYPE d2d_d3d_render_target_RestoreDrawingState(ID2D1RenderTarget *iface,
633 ID2D1DrawingStateBlock *state_block)
635 FIXME("iface %p, state_block %p stub!\n", iface, state_block);
638 static void STDMETHODCALLTYPE d2d_d3d_render_target_PushAxisAlignedClip(ID2D1RenderTarget *iface,
639 const D2D1_RECT_F *clip_rect, D2D1_ANTIALIAS_MODE antialias_mode)
641 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
642 D2D1_RECT_F transformed_rect;
643 float x_scale, y_scale;
644 D2D1_POINT_2F point;
646 TRACE("iface %p, clip_rect %p, antialias_mode %#x.\n", iface, clip_rect, antialias_mode);
648 if (antialias_mode != D2D1_ANTIALIAS_MODE_ALIASED)
649 FIXME("Ignoring antialias_mode %#x.\n", antialias_mode);
651 x_scale = render_target->dpi_x / 96.0f;
652 y_scale = render_target->dpi_y / 96.0f;
653 d2d_point_transform(&point, &render_target->transform, clip_rect->left * x_scale, clip_rect->top * y_scale);
654 d2d_rect_set(&transformed_rect, point.x, point.y, point.x, point.y);
655 d2d_point_transform(&point, &render_target->transform, clip_rect->left * x_scale, clip_rect->bottom * y_scale);
656 d2d_rect_expand(&transformed_rect, &point);
657 d2d_point_transform(&point, &render_target->transform, clip_rect->right * x_scale, clip_rect->top * y_scale);
658 d2d_rect_expand(&transformed_rect, &point);
659 d2d_point_transform(&point, &render_target->transform, clip_rect->right * x_scale, clip_rect->bottom * y_scale);
660 d2d_rect_expand(&transformed_rect, &point);
662 if (!d2d_clip_stack_push(&render_target->clip_stack, &transformed_rect))
663 WARN("Failed to push clip rect.\n");
666 static void STDMETHODCALLTYPE d2d_d3d_render_target_PopAxisAlignedClip(ID2D1RenderTarget *iface)
668 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
670 TRACE("iface %p.\n", iface);
672 d2d_clip_stack_pop(&render_target->clip_stack);
675 static void STDMETHODCALLTYPE d2d_d3d_render_target_Clear(ID2D1RenderTarget *iface, const D2D1_COLOR_F *color)
677 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
678 D3D10_SUBRESOURCE_DATA buffer_data;
679 D3D10_BUFFER_DESC buffer_desc;
680 unsigned int offset;
681 D3D10_VIEWPORT vp;
682 ID3D10Buffer *cb;
683 HRESULT hr;
685 TRACE("iface %p, color %p.\n", iface, color);
687 buffer_desc.ByteWidth = sizeof(*color);
688 buffer_desc.Usage = D3D10_USAGE_DEFAULT;
689 buffer_desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
690 buffer_desc.CPUAccessFlags = 0;
691 buffer_desc.MiscFlags = 0;
693 buffer_data.pSysMem = color;
694 buffer_data.SysMemPitch = 0;
695 buffer_data.SysMemSlicePitch = 0;
697 if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &cb)))
699 WARN("Failed to create constant buffer, hr %#x.\n", hr);
700 return;
703 vp.TopLeftX = 0;
704 vp.TopLeftY = 0;
705 vp.Width = render_target->pixel_size.width;
706 vp.Height = render_target->pixel_size.height;
707 vp.MinDepth = 0.0f;
708 vp.MaxDepth = 1.0f;
710 if (FAILED(hr = render_target->stateblock->lpVtbl->Capture(render_target->stateblock)))
712 WARN("Failed to capture stateblock, hr %#x.\n", hr);
713 ID3D10Buffer_Release(cb);
714 return;
717 ID3D10Device_ClearState(render_target->device);
719 ID3D10Device_IASetInputLayout(render_target->device, render_target->clear_il);
720 ID3D10Device_IASetPrimitiveTopology(render_target->device, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
721 offset = 0;
722 ID3D10Device_IASetVertexBuffers(render_target->device, 0, 1,
723 &render_target->clear_vb, &render_target->clear_vb_stride, &offset);
724 ID3D10Device_VSSetShader(render_target->device, render_target->clear_vs);
725 ID3D10Device_PSSetConstantBuffers(render_target->device, 0, 1, &cb);
726 ID3D10Device_PSSetShader(render_target->device, render_target->clear_ps);
727 ID3D10Device_RSSetViewports(render_target->device, 1, &vp);
728 if (render_target->clip_stack.count)
730 const D2D1_RECT_F *clip_rect;
731 D3D10_RECT scissor_rect;
733 clip_rect = &render_target->clip_stack.stack[render_target->clip_stack.count - 1];
734 scissor_rect.left = clip_rect->left + 0.5f;
735 scissor_rect.top = clip_rect->top + 0.5f;
736 scissor_rect.right = clip_rect->right + 0.5f;
737 scissor_rect.bottom = clip_rect->bottom + 0.5f;
738 ID3D10Device_RSSetScissorRects(render_target->device, 1, &scissor_rect);
739 ID3D10Device_RSSetState(render_target->device, render_target->clear_rs);
741 ID3D10Device_OMSetRenderTargets(render_target->device, 1, &render_target->view, NULL);
743 ID3D10Device_Draw(render_target->device, 4, 0);
745 if (FAILED(hr = render_target->stateblock->lpVtbl->Apply(render_target->stateblock)))
746 WARN("Failed to apply stateblock, hr %#x.\n", hr);
748 ID3D10Buffer_Release(cb);
751 static void STDMETHODCALLTYPE d2d_d3d_render_target_BeginDraw(ID2D1RenderTarget *iface)
753 TRACE("iface %p.\n", iface);
756 static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_EndDraw(ID2D1RenderTarget *iface,
757 D2D1_TAG *tag1, D2D1_TAG *tag2)
759 TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2);
761 if (tag1)
762 *tag1 = 0;
763 if (tag2)
764 *tag2 = 0;
766 return S_OK;
769 static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_d3d_render_target_GetPixelFormat(ID2D1RenderTarget *iface,
770 D2D1_PIXEL_FORMAT *format)
772 FIXME("iface %p, format %p stub!\n", iface, format);
774 format->format = DXGI_FORMAT_UNKNOWN;
775 format->alphaMode = D2D1_ALPHA_MODE_UNKNOWN;
776 return format;
779 static void STDMETHODCALLTYPE d2d_d3d_render_target_SetDpi(ID2D1RenderTarget *iface, float dpi_x, float dpi_y)
781 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
783 TRACE("iface %p, dpi_x %.8e, dpi_y %.8e.\n", iface, dpi_x, dpi_y);
785 if (dpi_x == 0.0f && dpi_y == 0.0f)
787 dpi_x = 96.0f;
788 dpi_y = 96.0f;
791 render_target->dpi_x = dpi_x;
792 render_target->dpi_y = dpi_y;
795 static void STDMETHODCALLTYPE d2d_d3d_render_target_GetDpi(ID2D1RenderTarget *iface, float *dpi_x, float *dpi_y)
797 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
799 TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface, dpi_x, dpi_y);
801 *dpi_x = render_target->dpi_x;
802 *dpi_y = render_target->dpi_y;
805 static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_d3d_render_target_GetSize(ID2D1RenderTarget *iface, D2D1_SIZE_F *size)
807 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
809 TRACE("iface %p, size %p.\n", iface, size);
811 size->width = render_target->pixel_size.width / (render_target->dpi_x / 96.0f);
812 size->height = render_target->pixel_size.height / (render_target->dpi_y / 96.0f);
813 return size;
816 static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_d3d_render_target_GetPixelSize(ID2D1RenderTarget *iface,
817 D2D1_SIZE_U *pixel_size)
819 struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
821 TRACE("iface %p, pixel_size %p.\n", iface, pixel_size);
823 *pixel_size = render_target->pixel_size;
824 return pixel_size;
827 static UINT32 STDMETHODCALLTYPE d2d_d3d_render_target_GetMaximumBitmapSize(ID2D1RenderTarget *iface)
829 FIXME("iface %p stub!\n", iface);
831 return 0;
834 static BOOL STDMETHODCALLTYPE d2d_d3d_render_target_IsSupported(ID2D1RenderTarget *iface,
835 const D2D1_RENDER_TARGET_PROPERTIES *desc)
837 FIXME("iface %p, desc %p stub!\n", iface, desc);
839 return FALSE;
842 static const struct ID2D1RenderTargetVtbl d2d_d3d_render_target_vtbl =
844 d2d_d3d_render_target_QueryInterface,
845 d2d_d3d_render_target_AddRef,
846 d2d_d3d_render_target_Release,
847 d2d_d3d_render_target_GetFactory,
848 d2d_d3d_render_target_CreateBitmap,
849 d2d_d3d_render_target_CreateBitmapFromWicBitmap,
850 d2d_d3d_render_target_CreateSharedBitmap,
851 d2d_d3d_render_target_CreateBitmapBrush,
852 d2d_d3d_render_target_CreateSolidColorBrush,
853 d2d_d3d_render_target_CreateGradientStopCollection,
854 d2d_d3d_render_target_CreateLinearGradientBrush,
855 d2d_d3d_render_target_CreateRadialGradientBrush,
856 d2d_d3d_render_target_CreateCompatibleRenderTarget,
857 d2d_d3d_render_target_CreateLayer,
858 d2d_d3d_render_target_CreateMesh,
859 d2d_d3d_render_target_DrawLine,
860 d2d_d3d_render_target_DrawRectangle,
861 d2d_d3d_render_target_FillRectangle,
862 d2d_d3d_render_target_DrawRoundedRectangle,
863 d2d_d3d_render_target_FillRoundedRectangle,
864 d2d_d3d_render_target_DrawEllipse,
865 d2d_d3d_render_target_FillEllipse,
866 d2d_d3d_render_target_DrawGeometry,
867 d2d_d3d_render_target_FillGeometry,
868 d2d_d3d_render_target_FillMesh,
869 d2d_d3d_render_target_FillOpacityMask,
870 d2d_d3d_render_target_DrawBitmap,
871 d2d_d3d_render_target_DrawText,
872 d2d_d3d_render_target_DrawTextLayout,
873 d2d_d3d_render_target_DrawGlyphRun,
874 d2d_d3d_render_target_SetTransform,
875 d2d_d3d_render_target_GetTransform,
876 d2d_d3d_render_target_SetAntialiasMode,
877 d2d_d3d_render_target_GetAntialiasMode,
878 d2d_d3d_render_target_SetTextAntialiasMode,
879 d2d_d3d_render_target_GetTextAntialiasMode,
880 d2d_d3d_render_target_SetTextRenderingParams,
881 d2d_d3d_render_target_GetTextRenderingParams,
882 d2d_d3d_render_target_SetTags,
883 d2d_d3d_render_target_GetTags,
884 d2d_d3d_render_target_PushLayer,
885 d2d_d3d_render_target_PopLayer,
886 d2d_d3d_render_target_Flush,
887 d2d_d3d_render_target_SaveDrawingState,
888 d2d_d3d_render_target_RestoreDrawingState,
889 d2d_d3d_render_target_PushAxisAlignedClip,
890 d2d_d3d_render_target_PopAxisAlignedClip,
891 d2d_d3d_render_target_Clear,
892 d2d_d3d_render_target_BeginDraw,
893 d2d_d3d_render_target_EndDraw,
894 d2d_d3d_render_target_GetPixelFormat,
895 d2d_d3d_render_target_SetDpi,
896 d2d_d3d_render_target_GetDpi,
897 d2d_d3d_render_target_GetSize,
898 d2d_d3d_render_target_GetPixelSize,
899 d2d_d3d_render_target_GetMaximumBitmapSize,
900 d2d_d3d_render_target_IsSupported,
903 static inline struct d2d_d3d_render_target *impl_from_IDWriteTextRenderer(IDWriteTextRenderer *iface)
905 return CONTAINING_RECORD(iface, struct d2d_d3d_render_target, IDWriteTextRenderer_iface);
908 static HRESULT STDMETHODCALLTYPE d2d_text_renderer_QueryInterface(IDWriteTextRenderer *iface, REFIID iid, void **out)
910 TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
912 if (IsEqualGUID(iid, &IID_IDWriteTextRenderer)
913 || IsEqualGUID(iid, &IID_IDWritePixelSnapping)
914 || IsEqualGUID(iid, &IID_IUnknown))
916 IDWriteTextRenderer_AddRef(iface);
917 *out = iface;
918 return S_OK;
921 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
923 *out = NULL;
924 return E_NOINTERFACE;
927 static ULONG STDMETHODCALLTYPE d2d_text_renderer_AddRef(IDWriteTextRenderer *iface)
929 struct d2d_d3d_render_target *render_target = impl_from_IDWriteTextRenderer(iface);
931 TRACE("iface %p.\n", iface);
933 return d2d_d3d_render_target_AddRef(&render_target->ID2D1RenderTarget_iface);
936 static ULONG STDMETHODCALLTYPE d2d_text_renderer_Release(IDWriteTextRenderer *iface)
938 struct d2d_d3d_render_target *render_target = impl_from_IDWriteTextRenderer(iface);
940 TRACE("iface %p.\n", iface);
942 return d2d_d3d_render_target_Release(&render_target->ID2D1RenderTarget_iface);
945 static HRESULT STDMETHODCALLTYPE d2d_text_renderer_IsPixelSnappingDisabled(IDWriteTextRenderer *iface,
946 void *ctx, BOOL *disabled)
948 FIXME("iface %p, ctx %p, disabled %p stub!\n", iface, ctx, disabled);
950 return E_NOTIMPL;
953 static HRESULT STDMETHODCALLTYPE d2d_text_renderer_GetCurrentTransform(IDWriteTextRenderer *iface,
954 void *ctx, DWRITE_MATRIX *transform)
956 FIXME("iface %p, ctx %p, transform %p stub!\n", iface, ctx, transform);
958 return E_NOTIMPL;
961 static HRESULT STDMETHODCALLTYPE d2d_text_renderer_GetPixelsPerDip(IDWriteTextRenderer *iface, void *ctx, float *ppd)
963 FIXME("iface %p, ctx %p, ppd %p stub!\n", iface, ctx, ppd);
965 return E_NOTIMPL;
968 static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawGlyphRun(IDWriteTextRenderer *iface, void *ctx,
969 float baseline_origin_x, float baseline_origin_y, DWRITE_MEASURING_MODE measuring_mode,
970 const DWRITE_GLYPH_RUN *glyph_run, const DWRITE_GLYPH_RUN_DESCRIPTION *desc, IUnknown *effect)
972 FIXME("iface %p, ctx %p, baseline_origin_x %.8e, baseline_origin_y %.8e, "
973 "measuring_mode %#x, glyph_run %p, desc %p, effect %p stub!\n",
974 iface, ctx, baseline_origin_x, baseline_origin_y,
975 measuring_mode, glyph_run, desc, effect);
977 return E_NOTIMPL;
980 static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawUnderline(IDWriteTextRenderer *iface, void *ctx,
981 float baseline_origin_x, float baseline_origin_y, const DWRITE_UNDERLINE *underline, IUnknown *effect)
983 FIXME("iface %p, ctx %p, baseline_origin_x %.8e, baseline_origin_y %.8e, underline %p, effect %p stub!\n",
984 iface, ctx, baseline_origin_x, baseline_origin_y, underline, effect);
986 return E_NOTIMPL;
989 static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawStrikethrough(IDWriteTextRenderer *iface, void *ctx,
990 float baseline_origin_x, float baseline_origin_y, const DWRITE_STRIKETHROUGH *strikethrough, IUnknown *effect)
992 FIXME("iface %p, ctx %p, baseline_origin_x %.8e, baseline_origin_y %.8e, strikethrough %p, effect %p stub!\n",
993 iface, ctx, baseline_origin_x, baseline_origin_y, strikethrough, effect);
995 return E_NOTIMPL;
998 static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawInlineObject(IDWriteTextRenderer *iface, void *ctx,
999 float origin_x, float origin_y, IDWriteInlineObject *object, BOOL is_sideways, BOOL is_rtl, IUnknown *effect)
1001 FIXME("iface %p, ctx %p, origin_x %.8e, origin_y %.8e, object %p, is_sideways %#x, is_rtl %#x, effect %p stub!\n",
1002 iface, ctx, origin_x, origin_y, object, is_sideways, is_rtl, effect);
1004 return E_NOTIMPL;
1007 static const struct IDWriteTextRendererVtbl d2d_text_renderer_vtbl =
1009 d2d_text_renderer_QueryInterface,
1010 d2d_text_renderer_AddRef,
1011 d2d_text_renderer_Release,
1012 d2d_text_renderer_IsPixelSnappingDisabled,
1013 d2d_text_renderer_GetCurrentTransform,
1014 d2d_text_renderer_GetPixelsPerDip,
1015 d2d_text_renderer_DrawGlyphRun,
1016 d2d_text_renderer_DrawUnderline,
1017 d2d_text_renderer_DrawStrikethrough,
1018 d2d_text_renderer_DrawInlineObject,
1021 HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory,
1022 IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc)
1024 D3D10_SUBRESOURCE_DATA buffer_data;
1025 D3D10_STATE_BLOCK_MASK state_mask;
1026 DXGI_SURFACE_DESC surface_desc;
1027 D3D10_RASTERIZER_DESC rs_desc;
1028 D3D10_BUFFER_DESC buffer_desc;
1029 ID3D10Resource *resource;
1030 HRESULT hr;
1032 static const D3D10_INPUT_ELEMENT_DESC clear_il_desc[] =
1034 {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
1036 static const DWORD clear_vs_code[] =
1038 /* float4 main(float4 position : POSITION) : SV_POSITION
1040 * return position;
1041 * } */
1042 0x43425844, 0x1fa8c27f, 0x52d2f21d, 0xc196fdb7, 0x376f283a, 0x00000001, 0x000001b4, 0x00000005,
1043 0x00000034, 0x0000008c, 0x000000c0, 0x000000f4, 0x00000138, 0x46454452, 0x00000050, 0x00000000,
1044 0x00000000, 0x00000000, 0x0000001c, 0xfffe0400, 0x00000100, 0x0000001c, 0x7263694d, 0x666f736f,
1045 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e30332e,
1046 0x30303239, 0x3336312e, 0xab003438, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
1047 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00,
1048 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
1049 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x52444853, 0x0000003c, 0x00010040,
1050 0x0000000f, 0x0300005f, 0x001010f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
1051 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453, 0x00000074,
1052 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
1053 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1054 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1055 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1057 static const DWORD clear_ps_code[] =
1059 /* float4 color;
1061 * float4 main(float4 position : SV_POSITION) : SV_Target
1063 * return color;
1064 * } */
1065 0x43425844, 0xecd3cc9d, 0x0025bc77, 0x7a333165, 0x5b04c7e4, 0x00000001, 0x0000022c, 0x00000005,
1066 0x00000034, 0x00000100, 0x00000134, 0x00000168, 0x000001b0, 0x46454452, 0x000000c4, 0x00000001,
1067 0x00000048, 0x00000001, 0x0000001c, 0xffff0400, 0x00000100, 0x00000090, 0x0000003c, 0x00000000,
1068 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x6f6c4724, 0x736c6162,
1069 0xababab00, 0x0000003c, 0x00000001, 0x00000060, 0x00000010, 0x00000000, 0x00000000, 0x00000078,
1070 0x00000000, 0x00000010, 0x00000002, 0x00000080, 0x00000000, 0x6f6c6f63, 0xabab0072, 0x00030001,
1071 0x00040001, 0x00000000, 0x00000000, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53,
1072 0x65646168, 0x6f432072, 0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438,
1073 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
1074 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4e47534f, 0x0000002c, 0x00000001,
1075 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653,
1076 0x65677261, 0xabab0074, 0x52444853, 0x00000040, 0x00000040, 0x00000010, 0x04000059, 0x00208e46,
1077 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x06000036, 0x001020f2, 0x00000000,
1078 0x00208e46, 0x00000000, 0x00000000, 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000,
1079 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000,
1080 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1081 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1082 0x00000000, 0x00000000, 0x00000000,
1084 static const struct
1086 float x, y;
1088 clear_quad[] =
1090 {-1.0f, -1.0f},
1091 {-1.0f, 1.0f},
1092 { 1.0f, -1.0f},
1093 { 1.0f, 1.0f},
1095 static const D2D1_MATRIX_3X2_F identity =
1097 1.0f, 0.0f,
1098 0.0f, 1.0f,
1099 0.0f, 0.0f,
1102 FIXME("Ignoring render target properties.\n");
1104 render_target->ID2D1RenderTarget_iface.lpVtbl = &d2d_d3d_render_target_vtbl;
1105 render_target->IDWriteTextRenderer_iface.lpVtbl = &d2d_text_renderer_vtbl;
1106 render_target->refcount = 1;
1108 if (FAILED(hr = IDXGISurface_GetDevice(surface, &IID_ID3D10Device, (void **)&render_target->device)))
1110 WARN("Failed to get device interface, hr %#x.\n", hr);
1111 return hr;
1114 if (FAILED(hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource)))
1116 WARN("Failed to get ID3D10Resource interface, hr %#x.\n", hr);
1117 goto err;
1120 hr = ID3D10Device_CreateRenderTargetView(render_target->device, resource, NULL, &render_target->view);
1121 ID3D10Resource_Release(resource);
1122 if (FAILED(hr))
1124 WARN("Failed to create rendertarget view, hr %#x.\n", hr);
1125 goto err;
1128 if (FAILED(hr = D3D10StateBlockMaskEnableAll(&state_mask)))
1130 WARN("Failed to create stateblock mask, hr %#x.\n", hr);
1131 goto err;
1134 if (FAILED(hr = D3D10CreateStateBlock(render_target->device, &state_mask, &render_target->stateblock)))
1136 WARN("Failed to create stateblock, hr %#x.\n", hr);
1137 goto err;
1140 if (FAILED(hr = ID3D10Device_CreateInputLayout(render_target->device, clear_il_desc,
1141 sizeof(clear_il_desc) / sizeof(*clear_il_desc), clear_vs_code, sizeof(clear_vs_code),
1142 &render_target->clear_il)))
1144 WARN("Failed to create clear input layout, hr %#x.\n", hr);
1145 goto err;
1148 buffer_desc.ByteWidth = sizeof(clear_quad);
1149 buffer_desc.Usage = D3D10_USAGE_DEFAULT;
1150 buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
1151 buffer_desc.CPUAccessFlags = 0;
1152 buffer_desc.MiscFlags = 0;
1154 buffer_data.pSysMem = clear_quad;
1155 buffer_data.SysMemPitch = 0;
1156 buffer_data.SysMemSlicePitch = 0;
1158 render_target->clear_vb_stride = sizeof(*clear_quad);
1159 if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device,
1160 &buffer_desc, &buffer_data, &render_target->clear_vb)))
1162 WARN("Failed to create clear vertex buffer, hr %#x.\n", hr);
1163 goto err;
1166 if (FAILED(hr = ID3D10Device_CreateVertexShader(render_target->device,
1167 clear_vs_code, sizeof(clear_vs_code), &render_target->clear_vs)))
1169 WARN("Failed to create clear vertex shader, hr %#x.\n", hr);
1170 goto err;
1173 if (FAILED(hr = ID3D10Device_CreatePixelShader(render_target->device,
1174 clear_ps_code, sizeof(clear_ps_code), &render_target->clear_ps)))
1176 WARN("Failed to create clear pixel shader, hr %#x.\n", hr);
1177 goto err;
1180 rs_desc.FillMode = D3D10_FILL_SOLID;
1181 rs_desc.CullMode = D3D10_CULL_BACK;
1182 rs_desc.FrontCounterClockwise = FALSE;
1183 rs_desc.DepthBias = 0;
1184 rs_desc.DepthBiasClamp = 0.0f;
1185 rs_desc.SlopeScaledDepthBias = 0.0f;
1186 rs_desc.DepthClipEnable = TRUE;
1187 rs_desc.ScissorEnable = TRUE;
1188 rs_desc.MultisampleEnable = FALSE;
1189 rs_desc.AntialiasedLineEnable = FALSE;
1190 if (FAILED(hr = ID3D10Device_CreateRasterizerState(render_target->device, &rs_desc, &render_target->clear_rs)))
1192 WARN("Failed to create clear rasterizer state, hr %#x.\n", hr);
1193 goto err;
1196 if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc)))
1198 WARN("Failed to get surface desc, hr %#x.\n", hr);
1199 goto err;
1202 render_target->pixel_size.width = surface_desc.Width;
1203 render_target->pixel_size.height = surface_desc.Height;
1204 render_target->transform = identity;
1206 if (!d2d_clip_stack_init(&render_target->clip_stack))
1208 WARN("Failed to initialize clip stack.\n");
1209 hr = E_FAIL;
1210 goto err;
1213 render_target->dpi_x = desc->dpiX;
1214 render_target->dpi_y = desc->dpiY;
1216 if (render_target->dpi_x == 0.0f && render_target->dpi_y == 0.0f)
1218 render_target->dpi_x = 96.0f;
1219 render_target->dpi_y = 96.0f;
1222 return S_OK;
1224 err:
1225 if (render_target->view)
1226 ID3D10RenderTargetView_Release(render_target->view);
1227 if (render_target->clear_rs)
1228 ID3D10RasterizerState_Release(render_target->clear_rs);
1229 if (render_target->clear_ps)
1230 ID3D10PixelShader_Release(render_target->clear_ps);
1231 if (render_target->clear_vs)
1232 ID3D10VertexShader_Release(render_target->clear_vs);
1233 if (render_target->clear_vb)
1234 ID3D10Buffer_Release(render_target->clear_vb);
1235 if (render_target->clear_il)
1236 ID3D10InputLayout_Release(render_target->clear_il);
1237 if (render_target->stateblock)
1238 render_target->stateblock->lpVtbl->Release(render_target->stateblock);
1239 if (render_target->device)
1240 ID3D10Device_Release(render_target->device);
1241 return hr;