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 "d2d1_private.h"
21 WINE_DEFAULT_DEBUG_CHANNEL(d2d
);
23 #define INITIAL_CLIP_STACK_SIZE 4
25 static const D2D1_MATRIX_3X2_F identity
=
32 struct d2d_draw_text_layout_ctx
35 D2D1_DRAW_TEXT_OPTIONS options
;
38 static inline struct d2d_device
*impl_from_ID2D1Device(ID2D1Device
*iface
)
40 return CONTAINING_RECORD(iface
, struct d2d_device
, ID2D1Device_iface
);
43 static struct d2d_device
*unsafe_impl_from_ID2D1Device(ID2D1Device
*iface
);
45 static ID2D1Brush
*d2d_draw_get_text_brush(struct d2d_draw_text_layout_ctx
*context
, IUnknown
*effect
)
47 ID2D1Brush
*brush
= NULL
;
49 if (effect
&& SUCCEEDED(IUnknown_QueryInterface(effect
, &IID_ID2D1Brush
, (void**)&brush
)))
52 ID2D1Brush_AddRef(context
->brush
);
53 return context
->brush
;
56 static void d2d_rect_intersect(D2D1_RECT_F
*dst
, const D2D1_RECT_F
*src
)
58 if (src
->left
> dst
->left
)
59 dst
->left
= src
->left
;
60 if (src
->top
> dst
->top
)
62 if (src
->right
< dst
->right
)
63 dst
->right
= src
->right
;
64 if (src
->bottom
< dst
->bottom
)
65 dst
->bottom
= src
->bottom
;
68 static void d2d_rect_set(D2D1_RECT_F
*dst
, float left
, float top
, float right
, float bottom
)
76 static void d2d_size_set(D2D1_SIZE_U
*dst
, float width
, float height
)
82 static BOOL
d2d_clip_stack_init(struct d2d_clip_stack
*stack
)
84 if (!(stack
->stack
= heap_alloc(INITIAL_CLIP_STACK_SIZE
* sizeof(*stack
->stack
))))
87 stack
->size
= INITIAL_CLIP_STACK_SIZE
;
93 static void d2d_clip_stack_cleanup(struct d2d_clip_stack
*stack
)
95 heap_free(stack
->stack
);
98 static BOOL
d2d_clip_stack_push(struct d2d_clip_stack
*stack
, const D2D1_RECT_F
*rect
)
102 if (!d2d_array_reserve((void **)&stack
->stack
, &stack
->size
, stack
->count
+ 1, sizeof(*stack
->stack
)))
107 d2d_rect_intersect(&r
, &stack
->stack
[stack
->count
- 1]);
108 stack
->stack
[stack
->count
++] = r
;
113 static void d2d_clip_stack_pop(struct d2d_clip_stack
*stack
)
120 static void d2d_device_context_draw(struct d2d_device_context
*render_target
, enum d2d_shape_type shape_type
,
121 ID3D10Buffer
*ib
, unsigned int index_count
, ID3D10Buffer
*vb
, unsigned int vb_stride
,
122 ID3D10Buffer
*vs_cb
, ID3D10Buffer
*ps_cb
, struct d2d_brush
*brush
, struct d2d_brush
*opacity_brush
)
124 struct d2d_shape_resources
*shape_resources
= &render_target
->shape_resources
[shape_type
];
125 ID3D10Device
*device
= render_target
->d3d_device
;
126 D3D10_RECT scissor_rect
;
133 vp
.Width
= render_target
->pixel_size
.width
;
134 vp
.Height
= render_target
->pixel_size
.height
;
138 if (FAILED(hr
= render_target
->stateblock
->lpVtbl
->Capture(render_target
->stateblock
)))
140 WARN("Failed to capture stateblock, hr %#x.\n", hr
);
144 ID3D10Device_ClearState(device
);
146 ID3D10Device_IASetInputLayout(device
, shape_resources
->il
);
147 ID3D10Device_IASetPrimitiveTopology(device
, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST
);
148 ID3D10Device_IASetIndexBuffer(device
, ib
, DXGI_FORMAT_R16_UINT
, 0);
150 ID3D10Device_IASetVertexBuffers(device
, 0, 1, &vb
, &vb_stride
, &offset
);
151 ID3D10Device_VSSetConstantBuffers(device
, 0, 1, &vs_cb
);
152 ID3D10Device_VSSetShader(device
, shape_resources
->vs
);
153 ID3D10Device_PSSetConstantBuffers(device
, 0, 1, &ps_cb
);
154 ID3D10Device_PSSetShader(device
, render_target
->ps
);
155 ID3D10Device_RSSetViewports(device
, 1, &vp
);
156 if (render_target
->clip_stack
.count
)
158 const D2D1_RECT_F
*clip_rect
;
160 clip_rect
= &render_target
->clip_stack
.stack
[render_target
->clip_stack
.count
- 1];
161 scissor_rect
.left
= ceilf(clip_rect
->left
- 0.5f
);
162 scissor_rect
.top
= ceilf(clip_rect
->top
- 0.5f
);
163 scissor_rect
.right
= ceilf(clip_rect
->right
- 0.5f
);
164 scissor_rect
.bottom
= ceilf(clip_rect
->bottom
- 0.5f
);
168 scissor_rect
.left
= 0.0f
;
169 scissor_rect
.top
= 0.0f
;
170 scissor_rect
.right
= render_target
->pixel_size
.width
;
171 scissor_rect
.bottom
= render_target
->pixel_size
.height
;
173 ID3D10Device_RSSetScissorRects(device
, 1, &scissor_rect
);
174 ID3D10Device_RSSetState(device
, render_target
->rs
);
175 ID3D10Device_OMSetRenderTargets(device
, 1, &render_target
->target
->rtv
, NULL
);
178 ID3D10Device_OMSetBlendState(device
, render_target
->bs
, NULL
, D3D10_DEFAULT_SAMPLE_MASK
);
179 d2d_brush_bind_resources(brush
, device
, 0);
182 d2d_brush_bind_resources(opacity_brush
, device
, 1);
185 ID3D10Device_DrawIndexed(device
, index_count
, 0, 0);
187 ID3D10Device_Draw(device
, index_count
, 0);
189 if (FAILED(hr
= render_target
->stateblock
->lpVtbl
->Apply(render_target
->stateblock
)))
190 WARN("Failed to apply stateblock, hr %#x.\n", hr
);
193 static void d2d_device_context_set_error(struct d2d_device_context
*context
, HRESULT code
)
195 context
->error
.code
= code
;
196 context
->error
.tag1
= context
->drawing_state
.tag1
;
197 context
->error
.tag2
= context
->drawing_state
.tag2
;
200 static inline struct d2d_device_context
*impl_from_IUnknown(IUnknown
*iface
)
202 return CONTAINING_RECORD(iface
, struct d2d_device_context
, IUnknown_iface
);
205 static inline struct d2d_device_context
*impl_from_ID2D1DeviceContext(ID2D1DeviceContext
*iface
)
207 return CONTAINING_RECORD(iface
, struct d2d_device_context
, ID2D1DeviceContext_iface
);
210 static HRESULT STDMETHODCALLTYPE
d2d_device_context_inner_QueryInterface(IUnknown
*iface
, REFIID iid
, void **out
)
212 struct d2d_device_context
*context
= impl_from_IUnknown(iface
);
214 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
216 if (IsEqualGUID(iid
, &IID_ID2D1DeviceContext
)
217 || IsEqualGUID(iid
, &IID_ID2D1RenderTarget
)
218 || IsEqualGUID(iid
, &IID_ID2D1Resource
)
219 || IsEqualGUID(iid
, &IID_IUnknown
))
221 ID2D1DeviceContext_AddRef(&context
->ID2D1DeviceContext_iface
);
222 *out
= &context
->ID2D1DeviceContext_iface
;
225 else if (IsEqualGUID(iid
, &IID_ID2D1GdiInteropRenderTarget
))
227 ID2D1GdiInteropRenderTarget_AddRef(&context
->ID2D1GdiInteropRenderTarget_iface
);
228 *out
= &context
->ID2D1GdiInteropRenderTarget_iface
;
232 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
235 return E_NOINTERFACE
;
238 static ULONG STDMETHODCALLTYPE
d2d_device_context_inner_AddRef(IUnknown
*iface
)
240 struct d2d_device_context
*context
= impl_from_IUnknown(iface
);
241 ULONG refcount
= InterlockedIncrement(&context
->refcount
);
243 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
248 static ULONG STDMETHODCALLTYPE
d2d_device_context_inner_Release(IUnknown
*iface
)
250 struct d2d_device_context
*context
= impl_from_IUnknown(iface
);
251 ULONG refcount
= InterlockedDecrement(&context
->refcount
);
253 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
259 d2d_clip_stack_cleanup(&context
->clip_stack
);
260 IDWriteRenderingParams_Release(context
->default_text_rendering_params
);
261 if (context
->text_rendering_params
)
262 IDWriteRenderingParams_Release(context
->text_rendering_params
);
264 ID3D10BlendState_Release(context
->bs
);
265 ID3D10RasterizerState_Release(context
->rs
);
266 ID3D10Buffer_Release(context
->vb
);
267 ID3D10Buffer_Release(context
->ib
);
268 ID3D10PixelShader_Release(context
->ps
);
269 for (i
= 0; i
< D2D_SHAPE_TYPE_COUNT
; ++i
)
271 ID3D10VertexShader_Release(context
->shape_resources
[i
].vs
);
272 ID3D10InputLayout_Release(context
->shape_resources
[i
].il
);
274 context
->stateblock
->lpVtbl
->Release(context
->stateblock
);
276 ID2D1Bitmap1_Release(&context
->target
->ID2D1Bitmap1_iface
);
277 ID3D10Device_Release(context
->d3d_device
);
278 ID2D1Factory_Release(context
->factory
);
279 ID2D1Device_Release(context
->device
);
286 static const struct IUnknownVtbl d2d_device_context_inner_unknown_vtbl
=
288 d2d_device_context_inner_QueryInterface
,
289 d2d_device_context_inner_AddRef
,
290 d2d_device_context_inner_Release
,
293 static HRESULT STDMETHODCALLTYPE
d2d_device_context_QueryInterface(ID2D1DeviceContext
*iface
, REFIID iid
, void **out
)
295 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
297 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
299 return IUnknown_QueryInterface(context
->outer_unknown
, iid
, out
);
302 static ULONG STDMETHODCALLTYPE
d2d_device_context_AddRef(ID2D1DeviceContext
*iface
)
304 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
306 TRACE("iface %p.\n", iface
);
308 return IUnknown_AddRef(context
->outer_unknown
);
311 static ULONG STDMETHODCALLTYPE
d2d_device_context_Release(ID2D1DeviceContext
*iface
)
313 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
315 TRACE("iface %p.\n", iface
);
317 return IUnknown_Release(context
->outer_unknown
);
320 static void STDMETHODCALLTYPE
d2d_device_context_GetFactory(ID2D1DeviceContext
*iface
, ID2D1Factory
**factory
)
322 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
324 TRACE("iface %p, factory %p.\n", iface
, factory
);
326 *factory
= render_target
->factory
;
327 ID2D1Factory_AddRef(*factory
);
330 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateBitmap(ID2D1DeviceContext
*iface
,
331 D2D1_SIZE_U size
, const void *src_data
, UINT32 pitch
, const D2D1_BITMAP_PROPERTIES
*desc
, ID2D1Bitmap
**bitmap
)
333 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
334 D2D1_BITMAP_PROPERTIES1 bitmap_desc
;
335 struct d2d_bitmap
*object
;
338 TRACE("iface %p, size {%u, %u}, src_data %p, pitch %u, desc %p, bitmap %p.\n",
339 iface
, size
.width
, size
.height
, src_data
, pitch
, desc
, bitmap
);
343 memcpy(&bitmap_desc
, desc
, sizeof(*desc
));
344 bitmap_desc
.bitmapOptions
= 0;
345 bitmap_desc
.colorContext
= NULL
;
348 if (SUCCEEDED(hr
= d2d_bitmap_create(context
, size
, src_data
, pitch
, desc
? &bitmap_desc
: NULL
, &object
)))
349 *bitmap
= (ID2D1Bitmap
*)&object
->ID2D1Bitmap1_iface
;
354 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateBitmapFromWicBitmap(ID2D1DeviceContext
*iface
,
355 IWICBitmapSource
*bitmap_source
, const D2D1_BITMAP_PROPERTIES
*desc
, ID2D1Bitmap
**bitmap
)
357 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
358 D2D1_BITMAP_PROPERTIES1 bitmap_desc
;
359 struct d2d_bitmap
*object
;
362 TRACE("iface %p, bitmap_source %p, desc %p, bitmap %p.\n",
363 iface
, bitmap_source
, desc
, bitmap
);
367 memcpy(&bitmap_desc
, desc
, sizeof(*desc
));
368 bitmap_desc
.bitmapOptions
= 0;
369 bitmap_desc
.colorContext
= NULL
;
372 if (SUCCEEDED(hr
= d2d_bitmap_create_from_wic_bitmap(context
, bitmap_source
, desc
? &bitmap_desc
: NULL
, &object
)))
373 *bitmap
= (ID2D1Bitmap
*)&object
->ID2D1Bitmap1_iface
;
378 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateSharedBitmap(ID2D1DeviceContext
*iface
,
379 REFIID iid
, void *data
, const D2D1_BITMAP_PROPERTIES
*desc
, ID2D1Bitmap
**bitmap
)
381 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
382 D2D1_BITMAP_PROPERTIES1 bitmap_desc
;
383 struct d2d_bitmap
*object
;
386 TRACE("iface %p, iid %s, data %p, desc %p, bitmap %p.\n",
387 iface
, debugstr_guid(iid
), data
, desc
, bitmap
);
391 memcpy(&bitmap_desc
, desc
, sizeof(*desc
));
392 bitmap_desc
.bitmapOptions
= D2D1_BITMAP_OPTIONS_TARGET
| D2D1_BITMAP_OPTIONS_CANNOT_DRAW
;
393 bitmap_desc
.colorContext
= NULL
;
396 if (SUCCEEDED(hr
= d2d_bitmap_create_shared(context
, iid
, data
, desc
? &bitmap_desc
: NULL
, &object
)))
397 *bitmap
= (ID2D1Bitmap
*)&object
->ID2D1Bitmap1_iface
;
402 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateBitmapBrush(ID2D1DeviceContext
*iface
,
403 ID2D1Bitmap
*bitmap
, const D2D1_BITMAP_BRUSH_PROPERTIES
*bitmap_brush_desc
,
404 const D2D1_BRUSH_PROPERTIES
*brush_desc
, ID2D1BitmapBrush
**brush
)
406 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
407 struct d2d_brush
*object
;
410 TRACE("iface %p, bitmap %p, bitmap_brush_desc %p, brush_desc %p, brush %p.\n",
411 iface
, bitmap
, bitmap_brush_desc
, brush_desc
, brush
);
413 if (SUCCEEDED(hr
= d2d_bitmap_brush_create(context
->factory
, bitmap
, (const D2D1_BITMAP_BRUSH_PROPERTIES1
*)bitmap_brush_desc
,
414 brush_desc
, &object
)))
415 *brush
= (ID2D1BitmapBrush
*)&object
->ID2D1Brush_iface
;
420 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateSolidColorBrush(ID2D1DeviceContext
*iface
,
421 const D2D1_COLOR_F
*color
, const D2D1_BRUSH_PROPERTIES
*desc
, ID2D1SolidColorBrush
**brush
)
423 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
424 struct d2d_brush
*object
;
427 TRACE("iface %p, color %p, desc %p, brush %p.\n", iface
, color
, desc
, brush
);
429 if (SUCCEEDED(hr
= d2d_solid_color_brush_create(render_target
->factory
, color
, desc
, &object
)))
430 *brush
= (ID2D1SolidColorBrush
*)&object
->ID2D1Brush_iface
;
435 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateGradientStopCollection(ID2D1DeviceContext
*iface
,
436 const D2D1_GRADIENT_STOP
*stops
, UINT32 stop_count
, D2D1_GAMMA gamma
, D2D1_EXTEND_MODE extend_mode
,
437 ID2D1GradientStopCollection
**gradient
)
439 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
440 struct d2d_gradient
*object
;
443 TRACE("iface %p, stops %p, stop_count %u, gamma %#x, extend_mode %#x, gradient %p.\n",
444 iface
, stops
, stop_count
, gamma
, extend_mode
, gradient
);
446 if (SUCCEEDED(hr
= d2d_gradient_create(render_target
->factory
, render_target
->d3d_device
,
447 stops
, stop_count
, gamma
, extend_mode
, &object
)))
448 *gradient
= &object
->ID2D1GradientStopCollection_iface
;
453 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateLinearGradientBrush(ID2D1DeviceContext
*iface
,
454 const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES
*gradient_brush_desc
, const D2D1_BRUSH_PROPERTIES
*brush_desc
,
455 ID2D1GradientStopCollection
*gradient
, ID2D1LinearGradientBrush
**brush
)
457 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
458 struct d2d_brush
*object
;
461 TRACE("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n",
462 iface
, gradient_brush_desc
, brush_desc
, gradient
, brush
);
464 if (SUCCEEDED(hr
= d2d_linear_gradient_brush_create(render_target
->factory
, gradient_brush_desc
, brush_desc
,
466 *brush
= (ID2D1LinearGradientBrush
*)&object
->ID2D1Brush_iface
;
471 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateRadialGradientBrush(ID2D1DeviceContext
*iface
,
472 const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES
*gradient_brush_desc
, const D2D1_BRUSH_PROPERTIES
*brush_desc
,
473 ID2D1GradientStopCollection
*gradient
, ID2D1RadialGradientBrush
**brush
)
475 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
476 struct d2d_brush
*object
;
479 TRACE("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n",
480 iface
, gradient_brush_desc
, brush_desc
, gradient
, brush
);
482 if (SUCCEEDED(hr
= d2d_radial_gradient_brush_create(render_target
->factory
,
483 gradient_brush_desc
, brush_desc
, gradient
, &object
)))
484 *brush
= (ID2D1RadialGradientBrush
*)&object
->ID2D1Brush_iface
;
489 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateCompatibleRenderTarget(ID2D1DeviceContext
*iface
,
490 const D2D1_SIZE_F
*size
, const D2D1_SIZE_U
*pixel_size
, const D2D1_PIXEL_FORMAT
*format
,
491 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options
, ID2D1BitmapRenderTarget
**rt
)
493 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
494 struct d2d_bitmap_render_target
*object
;
497 TRACE("iface %p, size %p, pixel_size %p, format %p, options %#x, render_target %p.\n",
498 iface
, size
, pixel_size
, format
, options
, rt
);
500 if (!(object
= heap_alloc_zero(sizeof(*object
))))
501 return E_OUTOFMEMORY
;
503 if (FAILED(hr
= d2d_bitmap_render_target_init(object
, render_target
, size
, pixel_size
,
506 WARN("Failed to initialize render target, hr %#x.\n", hr
);
511 TRACE("Created render target %p.\n", object
);
512 *rt
= &object
->ID2D1BitmapRenderTarget_iface
;
517 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateLayer(ID2D1DeviceContext
*iface
,
518 const D2D1_SIZE_F
*size
, ID2D1Layer
**layer
)
520 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
521 struct d2d_layer
*object
;
524 TRACE("iface %p, size %p, layer %p.\n", iface
, size
, layer
);
526 if (SUCCEEDED(hr
= d2d_layer_create(render_target
->factory
, size
, &object
)))
527 *layer
= &object
->ID2D1Layer_iface
;
532 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateMesh(ID2D1DeviceContext
*iface
, ID2D1Mesh
**mesh
)
534 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
535 struct d2d_mesh
*object
;
538 TRACE("iface %p, mesh %p.\n", iface
, mesh
);
540 if (SUCCEEDED(hr
= d2d_mesh_create(render_target
->factory
, &object
)))
541 *mesh
= &object
->ID2D1Mesh_iface
;
546 static void STDMETHODCALLTYPE
d2d_device_context_DrawLine(ID2D1DeviceContext
*iface
,
547 D2D1_POINT_2F p0
, D2D1_POINT_2F p1
, ID2D1Brush
*brush
, float stroke_width
, ID2D1StrokeStyle
*stroke_style
)
549 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
550 ID2D1PathGeometry
*geometry
;
551 ID2D1GeometrySink
*sink
;
554 TRACE("iface %p, p0 %s, p1 %s, brush %p, stroke_width %.8e, stroke_style %p.\n",
555 iface
, debug_d2d_point_2f(&p0
), debug_d2d_point_2f(&p1
), brush
, stroke_width
, stroke_style
);
557 if (FAILED(hr
= ID2D1Factory_CreatePathGeometry(render_target
->factory
, &geometry
)))
559 WARN("Failed to create path geometry, %#x.\n", hr
);
563 if (FAILED(hr
= ID2D1PathGeometry_Open(geometry
, &sink
)))
565 WARN("Open() failed, %#x.\n", hr
);
566 ID2D1PathGeometry_Release(geometry
);
570 ID2D1GeometrySink_BeginFigure(sink
, p0
, D2D1_FIGURE_BEGIN_HOLLOW
);
571 ID2D1GeometrySink_AddLine(sink
, p1
);
572 ID2D1GeometrySink_EndFigure(sink
, D2D1_FIGURE_END_OPEN
);
573 if (FAILED(hr
= ID2D1GeometrySink_Close(sink
)))
574 WARN("Close() failed, %#x.\n", hr
);
575 ID2D1GeometrySink_Release(sink
);
577 ID2D1DeviceContext_DrawGeometry(iface
, (ID2D1Geometry
*)geometry
, brush
, stroke_width
, stroke_style
);
578 ID2D1PathGeometry_Release(geometry
);
581 static void STDMETHODCALLTYPE
d2d_device_context_DrawRectangle(ID2D1DeviceContext
*iface
,
582 const D2D1_RECT_F
*rect
, ID2D1Brush
*brush
, float stroke_width
, ID2D1StrokeStyle
*stroke_style
)
584 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
585 ID2D1RectangleGeometry
*geometry
;
588 TRACE("iface %p, rect %s, brush %p, stroke_width %.8e, stroke_style %p.\n",
589 iface
, debug_d2d_rect_f(rect
), brush
, stroke_width
, stroke_style
);
591 if (FAILED(hr
= ID2D1Factory_CreateRectangleGeometry(render_target
->factory
, rect
, &geometry
)))
593 ERR("Failed to create geometry, hr %#x.\n", hr
);
597 ID2D1DeviceContext_DrawGeometry(iface
, (ID2D1Geometry
*)geometry
, brush
, stroke_width
, stroke_style
);
598 ID2D1RectangleGeometry_Release(geometry
);
601 static void STDMETHODCALLTYPE
d2d_device_context_FillRectangle(ID2D1DeviceContext
*iface
,
602 const D2D1_RECT_F
*rect
, ID2D1Brush
*brush
)
604 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
605 ID2D1RectangleGeometry
*geometry
;
608 TRACE("iface %p, rect %s, brush %p.\n", iface
, debug_d2d_rect_f(rect
), brush
);
610 if (FAILED(hr
= ID2D1Factory_CreateRectangleGeometry(render_target
->factory
, rect
, &geometry
)))
612 ERR("Failed to create geometry, hr %#x.\n", hr
);
616 ID2D1DeviceContext_FillGeometry(iface
, (ID2D1Geometry
*)geometry
, brush
, NULL
);
617 ID2D1RectangleGeometry_Release(geometry
);
620 static void STDMETHODCALLTYPE
d2d_device_context_DrawRoundedRectangle(ID2D1DeviceContext
*iface
,
621 const D2D1_ROUNDED_RECT
*rect
, ID2D1Brush
*brush
, float stroke_width
, ID2D1StrokeStyle
*stroke_style
)
623 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
624 ID2D1RoundedRectangleGeometry
*geometry
;
627 TRACE("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p.\n",
628 iface
, rect
, brush
, stroke_width
, stroke_style
);
630 if (FAILED(hr
= ID2D1Factory_CreateRoundedRectangleGeometry(render_target
->factory
, rect
, &geometry
)))
632 ERR("Failed to create geometry, hr %#x.\n", hr
);
636 ID2D1DeviceContext_DrawGeometry(iface
, (ID2D1Geometry
*)geometry
, brush
, stroke_width
, stroke_style
);
637 ID2D1RoundedRectangleGeometry_Release(geometry
);
640 static void STDMETHODCALLTYPE
d2d_device_context_FillRoundedRectangle(ID2D1DeviceContext
*iface
,
641 const D2D1_ROUNDED_RECT
*rect
, ID2D1Brush
*brush
)
643 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
644 ID2D1RoundedRectangleGeometry
*geometry
;
647 TRACE("iface %p, rect %p, brush %p.\n", iface
, rect
, brush
);
649 if (FAILED(hr
= ID2D1Factory_CreateRoundedRectangleGeometry(render_target
->factory
, rect
, &geometry
)))
651 ERR("Failed to create geometry, hr %#x.\n", hr
);
655 ID2D1DeviceContext_FillGeometry(iface
, (ID2D1Geometry
*)geometry
, brush
, NULL
);
656 ID2D1RoundedRectangleGeometry_Release(geometry
);
659 static void STDMETHODCALLTYPE
d2d_device_context_DrawEllipse(ID2D1DeviceContext
*iface
,
660 const D2D1_ELLIPSE
*ellipse
, ID2D1Brush
*brush
, float stroke_width
, ID2D1StrokeStyle
*stroke_style
)
662 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
663 ID2D1EllipseGeometry
*geometry
;
666 TRACE("iface %p, ellipse %p, brush %p, stroke_width %.8e, stroke_style %p.\n",
667 iface
, ellipse
, brush
, stroke_width
, stroke_style
);
669 if (FAILED(hr
= ID2D1Factory_CreateEllipseGeometry(render_target
->factory
, ellipse
, &geometry
)))
671 ERR("Failed to create geometry, hr %#x.\n", hr
);
675 ID2D1DeviceContext_DrawGeometry(iface
, (ID2D1Geometry
*)geometry
, brush
, stroke_width
, stroke_style
);
676 ID2D1EllipseGeometry_Release(geometry
);
679 static void STDMETHODCALLTYPE
d2d_device_context_FillEllipse(ID2D1DeviceContext
*iface
,
680 const D2D1_ELLIPSE
*ellipse
, ID2D1Brush
*brush
)
682 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
683 ID2D1EllipseGeometry
*geometry
;
686 TRACE("iface %p, ellipse %p, brush %p.\n", iface
, ellipse
, brush
);
688 if (FAILED(hr
= ID2D1Factory_CreateEllipseGeometry(render_target
->factory
, ellipse
, &geometry
)))
690 ERR("Failed to create geometry, hr %#x.\n", hr
);
694 ID2D1DeviceContext_FillGeometry(iface
, (ID2D1Geometry
*)geometry
, brush
, NULL
);
695 ID2D1EllipseGeometry_Release(geometry
);
698 static void d2d_device_context_draw_geometry(struct d2d_device_context
*render_target
,
699 const struct d2d_geometry
*geometry
, struct d2d_brush
*brush
, float stroke_width
)
701 ID3D10Buffer
*ib
, *vb
, *vs_cb
, *ps_cb_bezier
, *ps_cb_arc
;
702 D3D10_SUBRESOURCE_DATA buffer_data
;
703 D3D10_BUFFER_DESC buffer_desc
;
704 const D2D1_MATRIX_3X2_F
*w
;
711 float _11
, _21
, _31
, pad0
;
712 float _12
, _22
, _32
, stroke_width
;
713 } transform_geometry
;
714 struct d2d_vec4 transform_rtx
;
715 struct d2d_vec4 transform_rty
;
718 vs_cb_data
.transform_geometry
._11
= geometry
->transform
._11
;
719 vs_cb_data
.transform_geometry
._21
= geometry
->transform
._21
;
720 vs_cb_data
.transform_geometry
._31
= geometry
->transform
._31
;
721 vs_cb_data
.transform_geometry
.pad0
= 0.0f
;
722 vs_cb_data
.transform_geometry
._12
= geometry
->transform
._12
;
723 vs_cb_data
.transform_geometry
._22
= geometry
->transform
._22
;
724 vs_cb_data
.transform_geometry
._32
= geometry
->transform
._32
;
725 vs_cb_data
.transform_geometry
.stroke_width
= stroke_width
;
727 w
= &render_target
->drawing_state
.transform
;
729 tmp_x
= render_target
->desc
.dpiX
/ 96.0f
;
730 vs_cb_data
.transform_rtx
.x
= w
->_11
* tmp_x
;
731 vs_cb_data
.transform_rtx
.y
= w
->_21
* tmp_x
;
732 vs_cb_data
.transform_rtx
.z
= w
->_31
* tmp_x
;
733 vs_cb_data
.transform_rtx
.w
= 2.0f
/ render_target
->pixel_size
.width
;
735 tmp_y
= render_target
->desc
.dpiY
/ 96.0f
;
736 vs_cb_data
.transform_rty
.x
= w
->_12
* tmp_y
;
737 vs_cb_data
.transform_rty
.y
= w
->_22
* tmp_y
;
738 vs_cb_data
.transform_rty
.z
= w
->_32
* tmp_y
;
739 vs_cb_data
.transform_rty
.w
= -2.0f
/ render_target
->pixel_size
.height
;
741 buffer_desc
.ByteWidth
= sizeof(vs_cb_data
);
742 buffer_desc
.Usage
= D3D10_USAGE_DEFAULT
;
743 buffer_desc
.BindFlags
= D3D10_BIND_CONSTANT_BUFFER
;
744 buffer_desc
.CPUAccessFlags
= 0;
745 buffer_desc
.MiscFlags
= 0;
747 buffer_data
.pSysMem
= &vs_cb_data
;
748 buffer_data
.SysMemPitch
= 0;
749 buffer_data
.SysMemSlicePitch
= 0;
751 if (FAILED(hr
= ID3D10Device_CreateBuffer(render_target
->d3d_device
, &buffer_desc
, &buffer_data
, &vs_cb
)))
753 WARN("Failed to create constant buffer, hr %#x.\n", hr
);
757 if (FAILED(hr
= d2d_brush_get_ps_cb(brush
, NULL
, TRUE
, FALSE
, render_target
, &ps_cb_bezier
)))
759 WARN("Failed to get ps constant buffer, hr %#x.\n", hr
);
760 ID3D10Buffer_Release(vs_cb
);
764 if (FAILED(hr
= d2d_brush_get_ps_cb(brush
, NULL
, TRUE
, TRUE
, render_target
, &ps_cb_arc
)))
766 WARN("Failed to get ps constant buffer, hr %#x.\n", hr
);
767 ID3D10Buffer_Release(vs_cb
);
768 ID3D10Buffer_Release(ps_cb_bezier
);
772 if (geometry
->outline
.face_count
)
774 buffer_desc
.ByteWidth
= geometry
->outline
.face_count
* sizeof(*geometry
->outline
.faces
);
775 buffer_desc
.BindFlags
= D3D10_BIND_INDEX_BUFFER
;
776 buffer_data
.pSysMem
= geometry
->outline
.faces
;
778 if (FAILED(hr
= ID3D10Device_CreateBuffer(render_target
->d3d_device
, &buffer_desc
, &buffer_data
, &ib
)))
780 WARN("Failed to create index buffer, hr %#x.\n", hr
);
784 buffer_desc
.ByteWidth
= geometry
->outline
.vertex_count
* sizeof(*geometry
->outline
.vertices
);
785 buffer_desc
.BindFlags
= D3D10_BIND_VERTEX_BUFFER
;
786 buffer_data
.pSysMem
= geometry
->outline
.vertices
;
788 if (FAILED(hr
= ID3D10Device_CreateBuffer(render_target
->d3d_device
, &buffer_desc
, &buffer_data
, &vb
)))
790 ERR("Failed to create vertex buffer, hr %#x.\n", hr
);
791 ID3D10Buffer_Release(ib
);
795 d2d_device_context_draw(render_target
, D2D_SHAPE_TYPE_OUTLINE
, ib
, 3 * geometry
->outline
.face_count
, vb
,
796 sizeof(*geometry
->outline
.vertices
), vs_cb
, ps_cb_bezier
, brush
, NULL
);
798 ID3D10Buffer_Release(vb
);
799 ID3D10Buffer_Release(ib
);
802 if (geometry
->outline
.bezier_face_count
)
804 buffer_desc
.ByteWidth
= geometry
->outline
.bezier_face_count
* sizeof(*geometry
->outline
.bezier_faces
);
805 buffer_desc
.BindFlags
= D3D10_BIND_INDEX_BUFFER
;
806 buffer_data
.pSysMem
= geometry
->outline
.bezier_faces
;
808 if (FAILED(hr
= ID3D10Device_CreateBuffer(render_target
->d3d_device
, &buffer_desc
, &buffer_data
, &ib
)))
810 WARN("Failed to create beziers index buffer, hr %#x.\n", hr
);
814 buffer_desc
.ByteWidth
= geometry
->outline
.bezier_count
* sizeof(*geometry
->outline
.beziers
);
815 buffer_desc
.BindFlags
= D3D10_BIND_VERTEX_BUFFER
;
816 buffer_data
.pSysMem
= geometry
->outline
.beziers
;
818 if (FAILED(hr
= ID3D10Device_CreateBuffer(render_target
->d3d_device
, &buffer_desc
, &buffer_data
, &vb
)))
820 ERR("Failed to create beziers vertex buffer, hr %#x.\n", hr
);
821 ID3D10Buffer_Release(ib
);
825 d2d_device_context_draw(render_target
, D2D_SHAPE_TYPE_BEZIER_OUTLINE
, ib
,
826 3 * geometry
->outline
.bezier_face_count
, vb
,
827 sizeof(*geometry
->outline
.beziers
), vs_cb
, ps_cb_bezier
, brush
, NULL
);
829 ID3D10Buffer_Release(vb
);
830 ID3D10Buffer_Release(ib
);
833 if (geometry
->outline
.arc_face_count
)
835 buffer_desc
.ByteWidth
= geometry
->outline
.arc_face_count
* sizeof(*geometry
->outline
.arc_faces
);
836 buffer_desc
.BindFlags
= D3D10_BIND_INDEX_BUFFER
;
837 buffer_data
.pSysMem
= geometry
->outline
.arc_faces
;
839 if (FAILED(hr
= ID3D10Device_CreateBuffer(render_target
->d3d_device
, &buffer_desc
, &buffer_data
, &ib
)))
841 WARN("Failed to create arcs index buffer, hr %#x.\n", hr
);
845 buffer_desc
.ByteWidth
= geometry
->outline
.arc_count
* sizeof(*geometry
->outline
.arcs
);
846 buffer_desc
.BindFlags
= D3D10_BIND_VERTEX_BUFFER
;
847 buffer_data
.pSysMem
= geometry
->outline
.arcs
;
849 if (FAILED(hr
= ID3D10Device_CreateBuffer(render_target
->d3d_device
, &buffer_desc
, &buffer_data
, &vb
)))
851 ERR("Failed to create arcs vertex buffer, hr %#x.\n", hr
);
852 ID3D10Buffer_Release(ib
);
856 d2d_device_context_draw(render_target
, D2D_SHAPE_TYPE_ARC_OUTLINE
, ib
,
857 3 * geometry
->outline
.arc_face_count
, vb
,
858 sizeof(*geometry
->outline
.arcs
), vs_cb
, ps_cb_arc
, brush
, NULL
);
860 ID3D10Buffer_Release(vb
);
861 ID3D10Buffer_Release(ib
);
865 ID3D10Buffer_Release(ps_cb_arc
);
866 ID3D10Buffer_Release(ps_cb_bezier
);
867 ID3D10Buffer_Release(vs_cb
);
870 static void STDMETHODCALLTYPE
d2d_device_context_DrawGeometry(ID2D1DeviceContext
*iface
,
871 ID2D1Geometry
*geometry
, ID2D1Brush
*brush
, float stroke_width
, ID2D1StrokeStyle
*stroke_style
)
873 const struct d2d_geometry
*geometry_impl
= unsafe_impl_from_ID2D1Geometry(geometry
);
874 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
875 struct d2d_brush
*brush_impl
= unsafe_impl_from_ID2D1Brush(brush
);
877 TRACE("iface %p, geometry %p, brush %p, stroke_width %.8e, stroke_style %p.\n",
878 iface
, geometry
, brush
, stroke_width
, stroke_style
);
881 FIXME("Ignoring stroke style %p.\n", stroke_style
);
883 d2d_device_context_draw_geometry(render_target
, geometry_impl
, brush_impl
, stroke_width
);
886 static void d2d_device_context_fill_geometry(struct d2d_device_context
*render_target
,
887 const struct d2d_geometry
*geometry
, struct d2d_brush
*brush
, struct d2d_brush
*opacity_brush
)
889 ID3D10Buffer
*ib
, *vb
, *vs_cb
, *ps_cb_bezier
, *ps_cb_arc
;
890 D3D10_SUBRESOURCE_DATA buffer_data
;
891 D3D10_BUFFER_DESC buffer_desc
;
892 D2D1_MATRIX_3X2_F
*w
;
899 float _11
, _21
, _31
, pad0
;
900 float _12
, _22
, _32
, pad1
;
901 } transform_geometry
;
902 struct d2d_vec4 transform_rtx
;
903 struct d2d_vec4 transform_rty
;
906 vs_cb_data
.transform_geometry
._11
= geometry
->transform
._11
;
907 vs_cb_data
.transform_geometry
._21
= geometry
->transform
._21
;
908 vs_cb_data
.transform_geometry
._31
= geometry
->transform
._31
;
909 vs_cb_data
.transform_geometry
.pad0
= 0.0f
;
910 vs_cb_data
.transform_geometry
._12
= geometry
->transform
._12
;
911 vs_cb_data
.transform_geometry
._22
= geometry
->transform
._22
;
912 vs_cb_data
.transform_geometry
._32
= geometry
->transform
._32
;
913 vs_cb_data
.transform_geometry
.pad1
= 0.0f
;
915 w
= &render_target
->drawing_state
.transform
;
917 tmp_x
= render_target
->desc
.dpiX
/ 96.0f
;
918 vs_cb_data
.transform_rtx
.x
= w
->_11
* tmp_x
;
919 vs_cb_data
.transform_rtx
.y
= w
->_21
* tmp_x
;
920 vs_cb_data
.transform_rtx
.z
= w
->_31
* tmp_x
;
921 vs_cb_data
.transform_rtx
.w
= 2.0f
/ render_target
->pixel_size
.width
;
923 tmp_y
= render_target
->desc
.dpiY
/ 96.0f
;
924 vs_cb_data
.transform_rty
.x
= w
->_12
* tmp_y
;
925 vs_cb_data
.transform_rty
.y
= w
->_22
* tmp_y
;
926 vs_cb_data
.transform_rty
.z
= w
->_32
* tmp_y
;
927 vs_cb_data
.transform_rty
.w
= -2.0f
/ render_target
->pixel_size
.height
;
929 buffer_desc
.ByteWidth
= sizeof(vs_cb_data
);
930 buffer_desc
.Usage
= D3D10_USAGE_DEFAULT
;
931 buffer_desc
.BindFlags
= D3D10_BIND_CONSTANT_BUFFER
;
932 buffer_desc
.CPUAccessFlags
= 0;
933 buffer_desc
.MiscFlags
= 0;
935 buffer_data
.pSysMem
= &vs_cb_data
;
936 buffer_data
.SysMemPitch
= 0;
937 buffer_data
.SysMemSlicePitch
= 0;
939 if (FAILED(hr
= ID3D10Device_CreateBuffer(render_target
->d3d_device
, &buffer_desc
, &buffer_data
, &vs_cb
)))
941 WARN("Failed to create constant buffer, hr %#x.\n", hr
);
945 if (FAILED(hr
= d2d_brush_get_ps_cb(brush
, opacity_brush
, FALSE
, FALSE
, render_target
, &ps_cb_bezier
)))
947 WARN("Failed to get ps constant buffer, hr %#x.\n", hr
);
948 ID3D10Buffer_Release(vs_cb
);
952 if (FAILED(hr
= d2d_brush_get_ps_cb(brush
, opacity_brush
, FALSE
, TRUE
, render_target
, &ps_cb_arc
)))
954 WARN("Failed to get ps constant buffer, hr %#x.\n", hr
);
955 ID3D10Buffer_Release(vs_cb
);
956 ID3D10Buffer_Release(ps_cb_bezier
);
960 if (geometry
->fill
.face_count
)
962 buffer_desc
.ByteWidth
= geometry
->fill
.face_count
* sizeof(*geometry
->fill
.faces
);
963 buffer_desc
.BindFlags
= D3D10_BIND_INDEX_BUFFER
;
964 buffer_data
.pSysMem
= geometry
->fill
.faces
;
966 if (FAILED(hr
= ID3D10Device_CreateBuffer(render_target
->d3d_device
, &buffer_desc
, &buffer_data
, &ib
)))
968 WARN("Failed to create index buffer, hr %#x.\n", hr
);
972 buffer_desc
.ByteWidth
= geometry
->fill
.vertex_count
* sizeof(*geometry
->fill
.vertices
);
973 buffer_desc
.BindFlags
= D3D10_BIND_VERTEX_BUFFER
;
974 buffer_data
.pSysMem
= geometry
->fill
.vertices
;
976 if (FAILED(hr
= ID3D10Device_CreateBuffer(render_target
->d3d_device
, &buffer_desc
, &buffer_data
, &vb
)))
978 ERR("Failed to create vertex buffer, hr %#x.\n", hr
);
979 ID3D10Buffer_Release(ib
);
983 d2d_device_context_draw(render_target
, D2D_SHAPE_TYPE_TRIANGLE
, ib
, 3 * geometry
->fill
.face_count
, vb
,
984 sizeof(*geometry
->fill
.vertices
), vs_cb
, ps_cb_bezier
, brush
, opacity_brush
);
986 ID3D10Buffer_Release(vb
);
987 ID3D10Buffer_Release(ib
);
990 if (geometry
->fill
.bezier_vertex_count
)
992 buffer_desc
.ByteWidth
= geometry
->fill
.bezier_vertex_count
* sizeof(*geometry
->fill
.bezier_vertices
);
993 buffer_desc
.BindFlags
= D3D10_BIND_VERTEX_BUFFER
;
994 buffer_data
.pSysMem
= geometry
->fill
.bezier_vertices
;
996 if (FAILED(hr
= ID3D10Device_CreateBuffer(render_target
->d3d_device
, &buffer_desc
, &buffer_data
, &vb
)))
998 ERR("Failed to create beziers vertex buffer, hr %#x.\n", hr
);
1002 d2d_device_context_draw(render_target
, D2D_SHAPE_TYPE_CURVE
, NULL
, geometry
->fill
.bezier_vertex_count
, vb
,
1003 sizeof(*geometry
->fill
.bezier_vertices
), vs_cb
, ps_cb_bezier
, brush
, opacity_brush
);
1005 ID3D10Buffer_Release(vb
);
1008 if (geometry
->fill
.arc_vertex_count
)
1010 buffer_desc
.ByteWidth
= geometry
->fill
.arc_vertex_count
* sizeof(*geometry
->fill
.arc_vertices
);
1011 buffer_data
.pSysMem
= geometry
->fill
.arc_vertices
;
1013 if (FAILED(hr
= ID3D10Device_CreateBuffer(render_target
->d3d_device
, &buffer_desc
, &buffer_data
, &vb
)))
1015 ERR("Failed to create arc vertex buffer, hr %#x.\n", hr
);
1019 d2d_device_context_draw(render_target
, D2D_SHAPE_TYPE_CURVE
, NULL
, geometry
->fill
.arc_vertex_count
, vb
,
1020 sizeof(*geometry
->fill
.arc_vertices
), vs_cb
, ps_cb_arc
, brush
, opacity_brush
);
1022 ID3D10Buffer_Release(vb
);
1026 ID3D10Buffer_Release(ps_cb_arc
);
1027 ID3D10Buffer_Release(ps_cb_bezier
);
1028 ID3D10Buffer_Release(vs_cb
);
1031 static void STDMETHODCALLTYPE
d2d_device_context_FillGeometry(ID2D1DeviceContext
*iface
,
1032 ID2D1Geometry
*geometry
, ID2D1Brush
*brush
, ID2D1Brush
*opacity_brush
)
1034 const struct d2d_geometry
*geometry_impl
= unsafe_impl_from_ID2D1Geometry(geometry
);
1035 struct d2d_brush
*opacity_brush_impl
= unsafe_impl_from_ID2D1Brush(opacity_brush
);
1036 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
1037 struct d2d_brush
*brush_impl
= unsafe_impl_from_ID2D1Brush(brush
);
1039 TRACE("iface %p, geometry %p, brush %p, opacity_brush %p.\n", iface
, geometry
, brush
, opacity_brush
);
1041 if (FAILED(context
->error
.code
))
1044 if (opacity_brush
&& brush_impl
->type
!= D2D_BRUSH_TYPE_BITMAP
)
1046 d2d_device_context_set_error(context
, D2DERR_INCOMPATIBLE_BRUSH_TYPES
);
1050 d2d_device_context_fill_geometry(context
, geometry_impl
, brush_impl
, opacity_brush_impl
);
1053 static void STDMETHODCALLTYPE
d2d_device_context_FillMesh(ID2D1DeviceContext
*iface
,
1054 ID2D1Mesh
*mesh
, ID2D1Brush
*brush
)
1056 FIXME("iface %p, mesh %p, brush %p stub!\n", iface
, mesh
, brush
);
1059 static void STDMETHODCALLTYPE
d2d_device_context_FillOpacityMask(ID2D1DeviceContext
*iface
,
1060 ID2D1Bitmap
*mask
, ID2D1Brush
*brush
, D2D1_OPACITY_MASK_CONTENT content
,
1061 const D2D1_RECT_F
*dst_rect
, const D2D1_RECT_F
*src_rect
)
1063 FIXME("iface %p, mask %p, brush %p, content %#x, dst_rect %s, src_rect %s stub!\n",
1064 iface
, mask
, brush
, content
, debug_d2d_rect_f(dst_rect
), debug_d2d_rect_f(src_rect
));
1067 static void d2d_device_context_draw_bitmap(struct d2d_device_context
*context
, ID2D1Bitmap
*bitmap
,
1068 const D2D1_RECT_F
*dst_rect
, float opacity
, D2D1_INTERPOLATION_MODE interpolation_mode
,
1069 const D2D1_RECT_F
*src_rect
, const D2D1_MATRIX_4X4_F
*perspective_transform
)
1071 D2D1_BITMAP_BRUSH_PROPERTIES1 bitmap_brush_desc
;
1072 D2D1_BRUSH_PROPERTIES brush_desc
;
1073 struct d2d_brush
*brush
;
1077 if (perspective_transform
)
1078 FIXME("Perspective transform is ignored.\n");
1088 size
= ID2D1Bitmap_GetSize(bitmap
);
1091 s
.right
= size
.width
;
1092 s
.bottom
= size
.height
;
1103 d
.right
= s
.right
- s
.left
;
1104 d
.bottom
= s
.bottom
- s
.top
;
1107 bitmap_brush_desc
.extendModeX
= D2D1_EXTEND_MODE_CLAMP
;
1108 bitmap_brush_desc
.extendModeY
= D2D1_EXTEND_MODE_CLAMP
;
1109 bitmap_brush_desc
.interpolationMode
= interpolation_mode
;
1111 brush_desc
.opacity
= opacity
;
1112 brush_desc
.transform
._11
= fabsf((d
.right
- d
.left
) / (s
.right
- s
.left
));
1113 brush_desc
.transform
._21
= 0.0f
;
1114 brush_desc
.transform
._31
= min(d
.left
, d
.right
) - min(s
.left
, s
.right
) * brush_desc
.transform
._11
;
1115 brush_desc
.transform
._12
= 0.0f
;
1116 brush_desc
.transform
._22
= fabsf((d
.bottom
- d
.top
) / (s
.bottom
- s
.top
));
1117 brush_desc
.transform
._32
= min(d
.top
, d
.bottom
) - min(s
.top
, s
.bottom
) * brush_desc
.transform
._22
;
1119 if (FAILED(hr
= d2d_bitmap_brush_create(context
->factory
, bitmap
, &bitmap_brush_desc
, &brush_desc
, &brush
)))
1121 ERR("Failed to create bitmap brush, hr %#x.\n", hr
);
1125 d2d_device_context_FillRectangle(&context
->ID2D1DeviceContext_iface
, &d
, &brush
->ID2D1Brush_iface
);
1126 ID2D1Brush_Release(&brush
->ID2D1Brush_iface
);
1129 static void STDMETHODCALLTYPE
d2d_device_context_DrawBitmap(ID2D1DeviceContext
*iface
,
1130 ID2D1Bitmap
*bitmap
, const D2D1_RECT_F
*dst_rect
, float opacity
,
1131 D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode
, const D2D1_RECT_F
*src_rect
)
1133 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
1135 TRACE("iface %p, bitmap %p, dst_rect %s, opacity %.8e, interpolation_mode %#x, src_rect %s.\n",
1136 iface
, bitmap
, debug_d2d_rect_f(dst_rect
), opacity
, interpolation_mode
, debug_d2d_rect_f(src_rect
));
1138 if (interpolation_mode
!= D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR
1139 && interpolation_mode
!= D2D1_BITMAP_INTERPOLATION_MODE_LINEAR
)
1141 d2d_device_context_set_error(context
, E_INVALIDARG
);
1145 d2d_device_context_draw_bitmap(context
, bitmap
, dst_rect
, opacity
, interpolation_mode
, src_rect
, NULL
);
1148 static void STDMETHODCALLTYPE
d2d_device_context_DrawText(ID2D1DeviceContext
*iface
,
1149 const WCHAR
*string
, UINT32 string_len
, IDWriteTextFormat
*text_format
, const D2D1_RECT_F
*layout_rect
,
1150 ID2D1Brush
*brush
, D2D1_DRAW_TEXT_OPTIONS options
, DWRITE_MEASURING_MODE measuring_mode
)
1152 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1153 IDWriteTextLayout
*text_layout
;
1154 IDWriteFactory
*dwrite_factory
;
1155 D2D1_POINT_2F origin
;
1158 TRACE("iface %p, string %s, string_len %u, text_format %p, layout_rect %s, "
1159 "brush %p, options %#x, measuring_mode %#x.\n",
1160 iface
, debugstr_wn(string
, string_len
), string_len
, text_format
, debug_d2d_rect_f(layout_rect
),
1161 brush
, options
, measuring_mode
);
1163 if (FAILED(hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
,
1164 &IID_IDWriteFactory
, (IUnknown
**)&dwrite_factory
)))
1166 ERR("Failed to create dwrite factory, hr %#x.\n", hr
);
1170 if (measuring_mode
== DWRITE_MEASURING_MODE_NATURAL
)
1171 hr
= IDWriteFactory_CreateTextLayout(dwrite_factory
, string
, string_len
, text_format
,
1172 layout_rect
->right
- layout_rect
->left
, layout_rect
->bottom
- layout_rect
->top
, &text_layout
);
1174 hr
= IDWriteFactory_CreateGdiCompatibleTextLayout(dwrite_factory
, string
, string_len
, text_format
,
1175 layout_rect
->right
- layout_rect
->left
, layout_rect
->bottom
- layout_rect
->top
, render_target
->desc
.dpiX
/ 96.0f
,
1176 (DWRITE_MATRIX
*)&render_target
->drawing_state
.transform
, measuring_mode
== DWRITE_MEASURING_MODE_GDI_NATURAL
, &text_layout
);
1177 IDWriteFactory_Release(dwrite_factory
);
1180 ERR("Failed to create text layout, hr %#x.\n", hr
);
1184 d2d_point_set(&origin
, layout_rect
->left
, layout_rect
->top
);
1185 ID2D1DeviceContext_DrawTextLayout(iface
, origin
, text_layout
, brush
, options
);
1186 IDWriteTextLayout_Release(text_layout
);
1189 static void STDMETHODCALLTYPE
d2d_device_context_DrawTextLayout(ID2D1DeviceContext
*iface
,
1190 D2D1_POINT_2F origin
, IDWriteTextLayout
*layout
, ID2D1Brush
*brush
, D2D1_DRAW_TEXT_OPTIONS options
)
1192 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1193 struct d2d_draw_text_layout_ctx ctx
;
1196 TRACE("iface %p, origin %s, layout %p, brush %p, options %#x.\n",
1197 iface
, debug_d2d_point_2f(&origin
), layout
, brush
, options
);
1200 ctx
.options
= options
;
1202 if (FAILED(hr
= IDWriteTextLayout_Draw(layout
,
1203 &ctx
, &render_target
->IDWriteTextRenderer_iface
, origin
.x
, origin
.y
)))
1204 FIXME("Failed to draw text layout, hr %#x.\n", hr
);
1207 static D2D1_ANTIALIAS_MODE
d2d_device_context_set_aa_mode_from_text_aa_mode(struct d2d_device_context
*rt
)
1209 D2D1_ANTIALIAS_MODE prev_antialias_mode
= rt
->drawing_state
.antialiasMode
;
1210 rt
->drawing_state
.antialiasMode
= rt
->drawing_state
.textAntialiasMode
== D2D1_TEXT_ANTIALIAS_MODE_ALIASED
?
1211 D2D1_ANTIALIAS_MODE_ALIASED
: D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
;
1212 return prev_antialias_mode
;
1215 static void d2d_device_context_draw_glyph_run_outline(struct d2d_device_context
*render_target
,
1216 D2D1_POINT_2F baseline_origin
, const DWRITE_GLYPH_RUN
*glyph_run
, ID2D1Brush
*brush
)
1218 D2D1_MATRIX_3X2_F
*transform
, prev_transform
;
1219 D2D1_ANTIALIAS_MODE prev_antialias_mode
;
1220 ID2D1PathGeometry
*geometry
;
1221 ID2D1GeometrySink
*sink
;
1224 if (FAILED(hr
= ID2D1Factory_CreatePathGeometry(render_target
->factory
, &geometry
)))
1226 ERR("Failed to create geometry, hr %#x.\n", hr
);
1230 if (FAILED(hr
= ID2D1PathGeometry_Open(geometry
, &sink
)))
1232 ERR("Failed to open geometry sink, hr %#x.\n", hr
);
1233 ID2D1PathGeometry_Release(geometry
);
1237 if (FAILED(hr
= IDWriteFontFace_GetGlyphRunOutline(glyph_run
->fontFace
, glyph_run
->fontEmSize
,
1238 glyph_run
->glyphIndices
, glyph_run
->glyphAdvances
, glyph_run
->glyphOffsets
, glyph_run
->glyphCount
,
1239 glyph_run
->isSideways
, glyph_run
->bidiLevel
& 1, (IDWriteGeometrySink
*)sink
)))
1241 ERR("Failed to get glyph run outline, hr %#x.\n", hr
);
1242 ID2D1GeometrySink_Release(sink
);
1243 ID2D1PathGeometry_Release(geometry
);
1247 if (FAILED(hr
= ID2D1GeometrySink_Close(sink
)))
1248 ERR("Failed to close geometry sink, hr %#x.\n", hr
);
1249 ID2D1GeometrySink_Release(sink
);
1251 transform
= &render_target
->drawing_state
.transform
;
1252 prev_transform
= *transform
;
1253 transform
->_31
+= baseline_origin
.x
* transform
->_11
+ baseline_origin
.y
* transform
->_21
;
1254 transform
->_32
+= baseline_origin
.x
* transform
->_12
+ baseline_origin
.y
* transform
->_22
;
1255 prev_antialias_mode
= d2d_device_context_set_aa_mode_from_text_aa_mode(render_target
);
1256 d2d_device_context_fill_geometry(render_target
, unsafe_impl_from_ID2D1Geometry((ID2D1Geometry
*)geometry
),
1257 unsafe_impl_from_ID2D1Brush(brush
), NULL
);
1258 render_target
->drawing_state
.antialiasMode
= prev_antialias_mode
;
1259 *transform
= prev_transform
;
1261 ID2D1PathGeometry_Release(geometry
);
1264 static void d2d_device_context_draw_glyph_run_bitmap(struct d2d_device_context
*render_target
,
1265 D2D1_POINT_2F baseline_origin
, const DWRITE_GLYPH_RUN
*glyph_run
, ID2D1Brush
*brush
,
1266 DWRITE_RENDERING_MODE rendering_mode
, DWRITE_MEASURING_MODE measuring_mode
,
1267 DWRITE_TEXT_ANTIALIAS_MODE antialias_mode
)
1269 ID2D1RectangleGeometry
*geometry
= NULL
;
1270 ID2D1BitmapBrush
*opacity_brush
= NULL
;
1271 D2D1_BITMAP_PROPERTIES bitmap_desc
;
1272 ID2D1Bitmap
*opacity_bitmap
= NULL
;
1273 IDWriteGlyphRunAnalysis
*analysis
;
1274 DWRITE_TEXTURE_TYPE texture_type
;
1275 D2D1_BRUSH_PROPERTIES brush_desc
;
1276 IDWriteFactory2
*dwrite_factory
;
1277 D2D1_MATRIX_3X2_F
*transform
, m
;
1278 void *opacity_values
= NULL
;
1279 size_t opacity_values_size
;
1280 D2D1_SIZE_U bitmap_size
;
1281 float scale_x
, scale_y
;
1282 D2D1_RECT_F run_rect
;
1286 if (FAILED(hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
,
1287 &IID_IDWriteFactory2
, (IUnknown
**)&dwrite_factory
)))
1289 ERR("Failed to create dwrite factory, hr %#x.\n", hr
);
1293 transform
= &render_target
->drawing_state
.transform
;
1295 scale_x
= render_target
->desc
.dpiX
/ 96.0f
;
1296 m
._11
= transform
->_11
* scale_x
;
1297 m
._21
= transform
->_21
* scale_x
;
1298 m
._31
= transform
->_31
* scale_x
;
1300 scale_y
= render_target
->desc
.dpiY
/ 96.0f
;
1301 m
._12
= transform
->_12
* scale_y
;
1302 m
._22
= transform
->_22
* scale_y
;
1303 m
._32
= transform
->_32
* scale_y
;
1305 hr
= IDWriteFactory2_CreateGlyphRunAnalysis(dwrite_factory
, glyph_run
, (DWRITE_MATRIX
*)&m
,
1306 rendering_mode
, measuring_mode
, DWRITE_GRID_FIT_MODE_DEFAULT
, antialias_mode
,
1307 baseline_origin
.x
, baseline_origin
.y
, &analysis
);
1308 IDWriteFactory2_Release(dwrite_factory
);
1311 ERR("Failed to create glyph run analysis, hr %#x.\n", hr
);
1315 if (rendering_mode
== DWRITE_RENDERING_MODE_ALIASED
|| antialias_mode
== DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE
)
1316 texture_type
= DWRITE_TEXTURE_ALIASED_1x1
;
1318 texture_type
= DWRITE_TEXTURE_CLEARTYPE_3x1
;
1320 if (FAILED(hr
= IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis
, texture_type
, &bounds
)))
1322 ERR("Failed to get alpha texture bounds, hr %#x.\n", hr
);
1326 d2d_size_set(&bitmap_size
, bounds
.right
- bounds
.left
, bounds
.bottom
- bounds
.top
);
1327 if (!bitmap_size
.width
|| !bitmap_size
.height
)
1329 /* Empty run, nothing to do. */
1333 if (texture_type
== DWRITE_TEXTURE_CLEARTYPE_3x1
)
1334 bitmap_size
.width
*= 3;
1335 if (!(opacity_values
= heap_calloc(bitmap_size
.height
, bitmap_size
.width
)))
1337 ERR("Failed to allocate opacity values.\n");
1340 opacity_values_size
= bitmap_size
.height
* bitmap_size
.width
;
1342 if (FAILED(hr
= IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis
,
1343 texture_type
, &bounds
, opacity_values
, opacity_values_size
)))
1345 ERR("Failed to create alpha texture, hr %#x.\n", hr
);
1349 bitmap_desc
.pixelFormat
.format
= DXGI_FORMAT_A8_UNORM
;
1350 bitmap_desc
.pixelFormat
.alphaMode
= D2D1_ALPHA_MODE_PREMULTIPLIED
;
1351 bitmap_desc
.dpiX
= render_target
->desc
.dpiX
;
1352 if (texture_type
== DWRITE_TEXTURE_CLEARTYPE_3x1
)
1353 bitmap_desc
.dpiX
*= 3.0f
;
1354 bitmap_desc
.dpiY
= render_target
->desc
.dpiY
;
1355 if (FAILED(hr
= d2d_device_context_CreateBitmap(&render_target
->ID2D1DeviceContext_iface
,
1356 bitmap_size
, opacity_values
, bitmap_size
.width
, &bitmap_desc
, &opacity_bitmap
)))
1358 ERR("Failed to create opacity bitmap, hr %#x.\n", hr
);
1362 d2d_rect_set(&run_rect
, bounds
.left
/ scale_x
, bounds
.top
/ scale_y
,
1363 bounds
.right
/ scale_x
, bounds
.bottom
/ scale_y
);
1365 brush_desc
.opacity
= 1.0f
;
1366 brush_desc
.transform
._11
= 1.0f
;
1367 brush_desc
.transform
._12
= 0.0f
;
1368 brush_desc
.transform
._21
= 0.0f
;
1369 brush_desc
.transform
._22
= 1.0f
;
1370 brush_desc
.transform
._31
= run_rect
.left
;
1371 brush_desc
.transform
._32
= run_rect
.top
;
1372 if (FAILED(hr
= d2d_device_context_CreateBitmapBrush(&render_target
->ID2D1DeviceContext_iface
,
1373 opacity_bitmap
, NULL
, &brush_desc
, &opacity_brush
)))
1375 ERR("Failed to create opacity bitmap brush, hr %#x.\n", hr
);
1379 if (FAILED(hr
= ID2D1Factory_CreateRectangleGeometry(render_target
->factory
, &run_rect
, &geometry
)))
1381 ERR("Failed to create geometry, hr %#x.\n", hr
);
1386 *transform
= identity
;
1387 d2d_device_context_fill_geometry(render_target
, unsafe_impl_from_ID2D1Geometry((ID2D1Geometry
*)geometry
),
1388 unsafe_impl_from_ID2D1Brush(brush
), unsafe_impl_from_ID2D1Brush((ID2D1Brush
*)opacity_brush
));
1393 ID2D1RectangleGeometry_Release(geometry
);
1395 ID2D1BitmapBrush_Release(opacity_brush
);
1397 ID2D1Bitmap_Release(opacity_bitmap
);
1398 heap_free(opacity_values
);
1399 IDWriteGlyphRunAnalysis_Release(analysis
);
1402 static void STDMETHODCALLTYPE
d2d_device_context_DrawGlyphRun(ID2D1DeviceContext
*iface
,
1403 D2D1_POINT_2F baseline_origin
, const DWRITE_GLYPH_RUN
*glyph_run
, ID2D1Brush
*brush
,
1404 DWRITE_MEASURING_MODE measuring_mode
)
1406 TRACE("iface %p, baseline_origin %s, glyph_run %p, brush %p, measuring_mode %#x.\n",
1407 iface
, debug_d2d_point_2f(&baseline_origin
), glyph_run
, brush
, measuring_mode
);
1409 ID2D1DeviceContext_DrawGlyphRun(iface
, baseline_origin
, glyph_run
, NULL
, brush
, measuring_mode
);
1412 static void STDMETHODCALLTYPE
d2d_device_context_SetTransform(ID2D1DeviceContext
*iface
,
1413 const D2D1_MATRIX_3X2_F
*transform
)
1415 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1417 TRACE("iface %p, transform %p.\n", iface
, transform
);
1419 render_target
->drawing_state
.transform
= *transform
;
1422 static void STDMETHODCALLTYPE
d2d_device_context_GetTransform(ID2D1DeviceContext
*iface
,
1423 D2D1_MATRIX_3X2_F
*transform
)
1425 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1427 TRACE("iface %p, transform %p.\n", iface
, transform
);
1429 *transform
= render_target
->drawing_state
.transform
;
1432 static void STDMETHODCALLTYPE
d2d_device_context_SetAntialiasMode(ID2D1DeviceContext
*iface
,
1433 D2D1_ANTIALIAS_MODE antialias_mode
)
1435 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1437 TRACE("iface %p, antialias_mode %#x stub!\n", iface
, antialias_mode
);
1439 render_target
->drawing_state
.antialiasMode
= antialias_mode
;
1442 static D2D1_ANTIALIAS_MODE STDMETHODCALLTYPE
d2d_device_context_GetAntialiasMode(ID2D1DeviceContext
*iface
)
1444 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1446 TRACE("iface %p.\n", iface
);
1448 return render_target
->drawing_state
.antialiasMode
;
1451 static void STDMETHODCALLTYPE
d2d_device_context_SetTextAntialiasMode(ID2D1DeviceContext
*iface
,
1452 D2D1_TEXT_ANTIALIAS_MODE antialias_mode
)
1454 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1456 TRACE("iface %p, antialias_mode %#x.\n", iface
, antialias_mode
);
1458 render_target
->drawing_state
.textAntialiasMode
= antialias_mode
;
1461 static D2D1_TEXT_ANTIALIAS_MODE STDMETHODCALLTYPE
d2d_device_context_GetTextAntialiasMode(ID2D1DeviceContext
*iface
)
1463 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1465 TRACE("iface %p.\n", iface
);
1467 return render_target
->drawing_state
.textAntialiasMode
;
1470 static void STDMETHODCALLTYPE
d2d_device_context_SetTextRenderingParams(ID2D1DeviceContext
*iface
,
1471 IDWriteRenderingParams
*text_rendering_params
)
1473 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1475 TRACE("iface %p, text_rendering_params %p.\n", iface
, text_rendering_params
);
1477 if (text_rendering_params
)
1478 IDWriteRenderingParams_AddRef(text_rendering_params
);
1479 if (render_target
->text_rendering_params
)
1480 IDWriteRenderingParams_Release(render_target
->text_rendering_params
);
1481 render_target
->text_rendering_params
= text_rendering_params
;
1484 static void STDMETHODCALLTYPE
d2d_device_context_GetTextRenderingParams(ID2D1DeviceContext
*iface
,
1485 IDWriteRenderingParams
**text_rendering_params
)
1487 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1489 TRACE("iface %p, text_rendering_params %p.\n", iface
, text_rendering_params
);
1491 if ((*text_rendering_params
= render_target
->text_rendering_params
))
1492 IDWriteRenderingParams_AddRef(*text_rendering_params
);
1495 static void STDMETHODCALLTYPE
d2d_device_context_SetTags(ID2D1DeviceContext
*iface
, D2D1_TAG tag1
, D2D1_TAG tag2
)
1497 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1499 TRACE("iface %p, tag1 %s, tag2 %s.\n", iface
, wine_dbgstr_longlong(tag1
), wine_dbgstr_longlong(tag2
));
1501 render_target
->drawing_state
.tag1
= tag1
;
1502 render_target
->drawing_state
.tag2
= tag2
;
1505 static void STDMETHODCALLTYPE
d2d_device_context_GetTags(ID2D1DeviceContext
*iface
, D2D1_TAG
*tag1
, D2D1_TAG
*tag2
)
1507 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1509 TRACE("iface %p, tag1 %p, tag2 %p.\n", iface
, tag1
, tag2
);
1511 *tag1
= render_target
->drawing_state
.tag1
;
1512 *tag2
= render_target
->drawing_state
.tag2
;
1515 static void STDMETHODCALLTYPE
d2d_device_context_PushLayer(ID2D1DeviceContext
*iface
,
1516 const D2D1_LAYER_PARAMETERS
*layer_parameters
, ID2D1Layer
*layer
)
1518 FIXME("iface %p, layer_parameters %p, layer %p stub!\n", iface
, layer_parameters
, layer
);
1521 static void STDMETHODCALLTYPE
d2d_device_context_PopLayer(ID2D1DeviceContext
*iface
)
1523 FIXME("iface %p stub!\n", iface
);
1526 static HRESULT STDMETHODCALLTYPE
d2d_device_context_Flush(ID2D1DeviceContext
*iface
, D2D1_TAG
*tag1
, D2D1_TAG
*tag2
)
1528 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
1530 FIXME("iface %p, tag1 %p, tag2 %p stub!\n", iface
, tag1
, tag2
);
1532 if (context
->ops
&& context
->ops
->device_context_present
)
1533 context
->ops
->device_context_present(context
->outer_unknown
);
1538 static void STDMETHODCALLTYPE
d2d_device_context_SaveDrawingState(ID2D1DeviceContext
*iface
,
1539 ID2D1DrawingStateBlock
*state_block
)
1541 struct d2d_state_block
*state_block_impl
= unsafe_impl_from_ID2D1DrawingStateBlock(state_block
);
1542 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1544 TRACE("iface %p, state_block %p.\n", iface
, state_block
);
1546 state_block_impl
->drawing_state
= render_target
->drawing_state
;
1547 if (render_target
->text_rendering_params
)
1548 IDWriteRenderingParams_AddRef(render_target
->text_rendering_params
);
1549 if (state_block_impl
->text_rendering_params
)
1550 IDWriteRenderingParams_Release(state_block_impl
->text_rendering_params
);
1551 state_block_impl
->text_rendering_params
= render_target
->text_rendering_params
;
1554 static void STDMETHODCALLTYPE
d2d_device_context_RestoreDrawingState(ID2D1DeviceContext
*iface
,
1555 ID2D1DrawingStateBlock
*state_block
)
1557 struct d2d_state_block
*state_block_impl
= unsafe_impl_from_ID2D1DrawingStateBlock(state_block
);
1558 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1560 TRACE("iface %p, state_block %p.\n", iface
, state_block
);
1562 render_target
->drawing_state
= state_block_impl
->drawing_state
;
1563 if (state_block_impl
->text_rendering_params
)
1564 IDWriteRenderingParams_AddRef(state_block_impl
->text_rendering_params
);
1565 if (render_target
->text_rendering_params
)
1566 IDWriteRenderingParams_Release(render_target
->text_rendering_params
);
1567 render_target
->text_rendering_params
= state_block_impl
->text_rendering_params
;
1570 static void STDMETHODCALLTYPE
d2d_device_context_PushAxisAlignedClip(ID2D1DeviceContext
*iface
,
1571 const D2D1_RECT_F
*clip_rect
, D2D1_ANTIALIAS_MODE antialias_mode
)
1573 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1574 D2D1_RECT_F transformed_rect
;
1575 float x_scale
, y_scale
;
1576 D2D1_POINT_2F point
;
1578 TRACE("iface %p, clip_rect %s, antialias_mode %#x.\n", iface
, debug_d2d_rect_f(clip_rect
), antialias_mode
);
1580 if (antialias_mode
!= D2D1_ANTIALIAS_MODE_ALIASED
)
1581 FIXME("Ignoring antialias_mode %#x.\n", antialias_mode
);
1583 x_scale
= render_target
->desc
.dpiX
/ 96.0f
;
1584 y_scale
= render_target
->desc
.dpiY
/ 96.0f
;
1585 d2d_point_transform(&point
, &render_target
->drawing_state
.transform
,
1586 clip_rect
->left
* x_scale
, clip_rect
->top
* y_scale
);
1587 d2d_rect_set(&transformed_rect
, point
.x
, point
.y
, point
.x
, point
.y
);
1588 d2d_point_transform(&point
, &render_target
->drawing_state
.transform
,
1589 clip_rect
->left
* x_scale
, clip_rect
->bottom
* y_scale
);
1590 d2d_rect_expand(&transformed_rect
, &point
);
1591 d2d_point_transform(&point
, &render_target
->drawing_state
.transform
,
1592 clip_rect
->right
* x_scale
, clip_rect
->top
* y_scale
);
1593 d2d_rect_expand(&transformed_rect
, &point
);
1594 d2d_point_transform(&point
, &render_target
->drawing_state
.transform
,
1595 clip_rect
->right
* x_scale
, clip_rect
->bottom
* y_scale
);
1596 d2d_rect_expand(&transformed_rect
, &point
);
1598 if (!d2d_clip_stack_push(&render_target
->clip_stack
, &transformed_rect
))
1599 WARN("Failed to push clip rect.\n");
1602 static void STDMETHODCALLTYPE
d2d_device_context_PopAxisAlignedClip(ID2D1DeviceContext
*iface
)
1604 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1606 TRACE("iface %p.\n", iface
);
1608 d2d_clip_stack_pop(&render_target
->clip_stack
);
1611 static void STDMETHODCALLTYPE
d2d_device_context_Clear(ID2D1DeviceContext
*iface
, const D2D1_COLOR_F
*colour
)
1613 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1614 D3D10_SUBRESOURCE_DATA buffer_data
;
1615 struct d2d_ps_cb ps_cb_data
= {0};
1616 D3D10_BUFFER_DESC buffer_desc
;
1617 ID3D10Buffer
*vs_cb
, *ps_cb
;
1625 float _11
, _21
, _31
, pad0
;
1626 float _12
, _22
, _32
, pad1
;
1627 } transform_geometry
;
1628 struct d2d_vec4 transform_rtx
;
1629 struct d2d_vec4 transform_rty
;
1633 {1.0f
, 0.0f
, 0.0f
, 0.0f
,
1634 0.0f
, 1.0f
, 0.0f
, 0.0f
},
1635 {1.0f
, 0.0f
, 1.0f
, 1.0f
},
1636 {0.0f
, 1.0f
, 1.0f
, -1.0f
},
1639 TRACE("iface %p, colour %p.\n", iface
, colour
);
1641 buffer_desc
.ByteWidth
= sizeof(vs_cb_data
);
1642 buffer_desc
.Usage
= D3D10_USAGE_DEFAULT
;
1643 buffer_desc
.BindFlags
= D3D10_BIND_CONSTANT_BUFFER
;
1644 buffer_desc
.CPUAccessFlags
= 0;
1645 buffer_desc
.MiscFlags
= 0;
1647 buffer_data
.pSysMem
= &vs_cb_data
;
1648 buffer_data
.SysMemPitch
= 0;
1649 buffer_data
.SysMemSlicePitch
= 0;
1651 if (FAILED(hr
= ID3D10Device_CreateBuffer(render_target
->d3d_device
, &buffer_desc
, &buffer_data
, &vs_cb
)))
1653 WARN("Failed to create constant buffer, hr %#x.\n", hr
);
1657 ps_cb_data
.outline
= FALSE
;
1658 ps_cb_data
.colour_brush
.type
= D2D_BRUSH_TYPE_SOLID
;
1659 ps_cb_data
.colour_brush
.opacity
= 1.0f
;
1660 c
= &ps_cb_data
.colour_brush
.u
.solid
.colour
;
1663 if (render_target
->desc
.pixelFormat
.alphaMode
== D2D1_ALPHA_MODE_IGNORE
)
1669 ps_cb_data
.opacity_brush
.type
= D2D_BRUSH_TYPE_COUNT
;
1671 buffer_desc
.ByteWidth
= sizeof(ps_cb_data
);
1672 buffer_data
.pSysMem
= &ps_cb_data
;
1674 if (FAILED(hr
= ID3D10Device_CreateBuffer(render_target
->d3d_device
, &buffer_desc
, &buffer_data
, &ps_cb
)))
1676 WARN("Failed to create constant buffer, hr %#x.\n", hr
);
1677 ID3D10Buffer_Release(vs_cb
);
1681 d2d_device_context_draw(render_target
, D2D_SHAPE_TYPE_TRIANGLE
, render_target
->ib
, 6,
1682 render_target
->vb
, render_target
->vb_stride
, vs_cb
, ps_cb
, NULL
, NULL
);
1684 ID3D10Buffer_Release(ps_cb
);
1685 ID3D10Buffer_Release(vs_cb
);
1688 static void STDMETHODCALLTYPE
d2d_device_context_BeginDraw(ID2D1DeviceContext
*iface
)
1690 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1692 TRACE("iface %p.\n", iface
);
1694 memset(&render_target
->error
, 0, sizeof(render_target
->error
));
1697 static HRESULT STDMETHODCALLTYPE
d2d_device_context_EndDraw(ID2D1DeviceContext
*iface
,
1698 D2D1_TAG
*tag1
, D2D1_TAG
*tag2
)
1700 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
1703 TRACE("iface %p, tag1 %p, tag2 %p.\n", iface
, tag1
, tag2
);
1706 *tag1
= context
->error
.tag1
;
1708 *tag2
= context
->error
.tag2
;
1710 if (context
->ops
&& context
->ops
->device_context_present
)
1712 if (FAILED(hr
= context
->ops
->device_context_present(context
->outer_unknown
)))
1713 context
->error
.code
= hr
;
1716 return context
->error
.code
;
1719 static D2D1_PIXEL_FORMAT
* STDMETHODCALLTYPE
d2d_device_context_GetPixelFormat(ID2D1DeviceContext
*iface
,
1720 D2D1_PIXEL_FORMAT
*format
)
1722 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1724 TRACE("iface %p, format %p.\n", iface
, format
);
1726 *format
= render_target
->desc
.pixelFormat
;
1730 static void STDMETHODCALLTYPE
d2d_device_context_SetDpi(ID2D1DeviceContext
*iface
, float dpi_x
, float dpi_y
)
1732 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1734 TRACE("iface %p, dpi_x %.8e, dpi_y %.8e.\n", iface
, dpi_x
, dpi_y
);
1736 if (dpi_x
== 0.0f
&& dpi_y
== 0.0f
)
1741 else if (dpi_x
<= 0.0f
|| dpi_y
<= 0.0f
)
1744 render_target
->desc
.dpiX
= dpi_x
;
1745 render_target
->desc
.dpiY
= dpi_y
;
1748 static void STDMETHODCALLTYPE
d2d_device_context_GetDpi(ID2D1DeviceContext
*iface
, float *dpi_x
, float *dpi_y
)
1750 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1752 TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface
, dpi_x
, dpi_y
);
1754 *dpi_x
= render_target
->desc
.dpiX
;
1755 *dpi_y
= render_target
->desc
.dpiY
;
1758 static D2D1_SIZE_F
* STDMETHODCALLTYPE
d2d_device_context_GetSize(ID2D1DeviceContext
*iface
, D2D1_SIZE_F
*size
)
1760 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1762 TRACE("iface %p, size %p.\n", iface
, size
);
1764 size
->width
= render_target
->pixel_size
.width
/ (render_target
->desc
.dpiX
/ 96.0f
);
1765 size
->height
= render_target
->pixel_size
.height
/ (render_target
->desc
.dpiY
/ 96.0f
);
1769 static D2D1_SIZE_U
* STDMETHODCALLTYPE
d2d_device_context_GetPixelSize(ID2D1DeviceContext
*iface
,
1770 D2D1_SIZE_U
*pixel_size
)
1772 struct d2d_device_context
*render_target
= impl_from_ID2D1DeviceContext(iface
);
1774 TRACE("iface %p, pixel_size %p.\n", iface
, pixel_size
);
1776 *pixel_size
= render_target
->pixel_size
;
1780 static UINT32 STDMETHODCALLTYPE
d2d_device_context_GetMaximumBitmapSize(ID2D1DeviceContext
*iface
)
1782 TRACE("iface %p.\n", iface
);
1784 return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION
;
1787 static BOOL STDMETHODCALLTYPE
d2d_device_context_IsSupported(ID2D1DeviceContext
*iface
,
1788 const D2D1_RENDER_TARGET_PROPERTIES
*desc
)
1790 FIXME("iface %p, desc %p stub!\n", iface
, desc
);
1795 static HRESULT STDMETHODCALLTYPE
d2d_device_context_ID2D1DeviceContext_CreateBitmap(ID2D1DeviceContext
*iface
,
1796 D2D1_SIZE_U size
, const void *src_data
, UINT32 pitch
,
1797 const D2D1_BITMAP_PROPERTIES1
*desc
, ID2D1Bitmap1
**bitmap
)
1799 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
1800 struct d2d_bitmap
*object
;
1803 TRACE("iface %p, size {%u, %u}, src_data %p, pitch %u, desc %p, bitmap %p.\n",
1804 iface
, size
.width
, size
.height
, src_data
, pitch
, desc
, bitmap
);
1806 if (SUCCEEDED(hr
= d2d_bitmap_create(context
, size
, src_data
, pitch
, desc
, &object
)))
1807 *bitmap
= &object
->ID2D1Bitmap1_iface
;
1812 static HRESULT STDMETHODCALLTYPE
d2d_device_context_ID2D1DeviceContext_CreateBitmapFromWicBitmap(
1813 ID2D1DeviceContext
*iface
, IWICBitmapSource
*bitmap_source
,
1814 const D2D1_BITMAP_PROPERTIES1
*desc
, ID2D1Bitmap1
**bitmap
)
1816 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
1817 struct d2d_bitmap
*object
;
1820 TRACE("iface %p, bitmap_source %p, desc %p, bitmap %p.\n", iface
, bitmap_source
, desc
, bitmap
);
1822 if (SUCCEEDED(hr
= d2d_bitmap_create_from_wic_bitmap(context
, bitmap_source
, desc
, &object
)))
1823 *bitmap
= &object
->ID2D1Bitmap1_iface
;
1828 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateColorContext(ID2D1DeviceContext
*iface
,
1829 D2D1_COLOR_SPACE space
, const BYTE
*profile
, UINT32 profile_size
, ID2D1ColorContext
**color_context
)
1831 FIXME("iface %p, space %#x, profile %p, profile_size %u, color_context %p stub!\n",
1832 iface
, space
, profile
, profile_size
, color_context
);
1837 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateColorContextFromFilename(ID2D1DeviceContext
*iface
,
1838 const WCHAR
*filename
, ID2D1ColorContext
**color_context
)
1840 FIXME("iface %p, filename %s, color_context %p stub!\n", iface
, debugstr_w(filename
), color_context
);
1845 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateColorContextFromWicColorContext(ID2D1DeviceContext
*iface
,
1846 IWICColorContext
*wic_color_context
, ID2D1ColorContext
**color_context
)
1848 FIXME("iface %p, wic_color_context %p, color_context %p stub!\n", iface
, wic_color_context
, color_context
);
1853 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateBitmapFromDxgiSurface(ID2D1DeviceContext
*iface
,
1854 IDXGISurface
*surface
, const D2D1_BITMAP_PROPERTIES1
*desc
, ID2D1Bitmap1
**bitmap
)
1856 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
1857 D2D1_BITMAP_PROPERTIES1 bitmap_desc
;
1858 struct d2d_bitmap
*object
;
1861 TRACE("iface %p, surface %p, desc %p, bitmap %p.\n", iface
, surface
, desc
, bitmap
);
1865 DXGI_SURFACE_DESC surface_desc
;
1867 if (FAILED(hr
= IDXGISurface_GetDesc(surface
, &surface_desc
)))
1869 WARN("Failed to get surface desc, hr %#x.\n", hr
);
1873 memset(&bitmap_desc
, 0, sizeof(bitmap_desc
));
1874 bitmap_desc
.pixelFormat
.format
= surface_desc
.Format
;
1875 bitmap_desc
.pixelFormat
.alphaMode
= D2D1_ALPHA_MODE_PREMULTIPLIED
;
1876 bitmap_desc
.bitmapOptions
= D2D1_BITMAP_OPTIONS_TARGET
| D2D1_BITMAP_OPTIONS_CANNOT_DRAW
;
1877 desc
= &bitmap_desc
;
1880 if (SUCCEEDED(hr
= d2d_bitmap_create_shared(context
, &IID_IDXGISurface
, surface
, desc
, &object
)))
1881 *bitmap
= &object
->ID2D1Bitmap1_iface
;
1886 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateEffect(ID2D1DeviceContext
*iface
,
1887 REFCLSID effect_id
, ID2D1Effect
**effect
)
1889 struct d2d_effect
*object
;
1891 FIXME("iface %p, effect_id %s, effect %p stub!\n", iface
, debugstr_guid(effect_id
), effect
);
1893 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1894 return E_OUTOFMEMORY
;
1896 d2d_effect_init(object
);
1898 TRACE("Created effect %p.\n", object
);
1899 *effect
= &object
->ID2D1Effect_iface
;
1904 static HRESULT STDMETHODCALLTYPE
d2d_device_context_ID2D1DeviceContext_CreateGradientStopCollection(
1905 ID2D1DeviceContext
*iface
, const D2D1_GRADIENT_STOP
*stops
, UINT32 stop_count
,
1906 D2D1_COLOR_SPACE preinterpolation_space
, D2D1_COLOR_SPACE postinterpolation_space
,
1907 D2D1_BUFFER_PRECISION buffer_precision
, D2D1_EXTEND_MODE extend_mode
,
1908 D2D1_COLOR_INTERPOLATION_MODE color_interpolation_mode
, ID2D1GradientStopCollection1
**gradient
)
1910 FIXME("iface %p, stops %p, stop_count %u, preinterpolation_space %#x, postinterpolation_space %#x, "
1911 "buffer_precision %#x, extend_mode %#x, color_interpolation_mode %#x, gradient %p stub!\n",
1912 iface
, stops
, stop_count
, preinterpolation_space
, postinterpolation_space
,
1913 buffer_precision
, extend_mode
, color_interpolation_mode
, gradient
);
1918 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateImageBrush(ID2D1DeviceContext
*iface
,
1919 ID2D1Image
*image
, const D2D1_IMAGE_BRUSH_PROPERTIES
*image_brush_desc
,
1920 const D2D1_BRUSH_PROPERTIES
*brush_desc
, ID2D1ImageBrush
**brush
)
1922 FIXME("iface %p, image %p, image_brush_desc %p, brush_desc %p, brush %p stub!\n",
1923 iface
, image
, image_brush_desc
, brush_desc
, brush
);
1928 static HRESULT STDMETHODCALLTYPE
d2d_device_context_ID2D1DeviceContext_CreateBitmapBrush(ID2D1DeviceContext
*iface
,
1929 ID2D1Bitmap
*bitmap
, const D2D1_BITMAP_BRUSH_PROPERTIES1
*bitmap_brush_desc
,
1930 const D2D1_BRUSH_PROPERTIES
*brush_desc
, ID2D1BitmapBrush1
**brush
)
1932 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
1933 struct d2d_brush
*object
;
1936 TRACE("iface %p, bitmap %p, bitmap_brush_desc %p, brush_desc %p, brush %p.\n", iface
, bitmap
, bitmap_brush_desc
,
1939 if (SUCCEEDED(hr
= d2d_bitmap_brush_create(context
->factory
, bitmap
, bitmap_brush_desc
, brush_desc
, &object
)))
1940 *brush
= (ID2D1BitmapBrush1
*)&object
->ID2D1Brush_iface
;
1945 static HRESULT STDMETHODCALLTYPE
d2d_device_context_CreateCommandList(ID2D1DeviceContext
*iface
,
1946 ID2D1CommandList
**command_list
)
1948 FIXME("iface %p, command_list %p stub!\n", iface
, command_list
);
1953 static BOOL STDMETHODCALLTYPE
d2d_device_context_IsDxgiFormatSupported(ID2D1DeviceContext
*iface
, DXGI_FORMAT format
)
1955 FIXME("iface %p, format %#x stub!\n", iface
, format
);
1960 static BOOL STDMETHODCALLTYPE
d2d_device_context_IsBufferPrecisionSupported(ID2D1DeviceContext
*iface
,
1961 D2D1_BUFFER_PRECISION buffer_precision
)
1963 FIXME("iface %p, buffer_precision %#x stub!\n", iface
, buffer_precision
);
1968 static void STDMETHODCALLTYPE
d2d_device_context_GetImageLocalBounds(ID2D1DeviceContext
*iface
,
1969 ID2D1Image
*image
, D2D1_RECT_F
*local_bounds
)
1971 FIXME("iface %p, image %p, local_bounds %p stub!\n", iface
, image
, local_bounds
);
1974 static HRESULT STDMETHODCALLTYPE
d2d_device_context_GetImageWorldBounds(ID2D1DeviceContext
*iface
,
1975 ID2D1Image
*image
, D2D1_RECT_F
*world_bounds
)
1977 FIXME("iface %p, image %p, world_bounds %p stub!\n", iface
, image
, world_bounds
);
1982 static HRESULT STDMETHODCALLTYPE
d2d_device_context_GetGlyphRunWorldBounds(ID2D1DeviceContext
*iface
,
1983 D2D1_POINT_2F baseline_origin
, const DWRITE_GLYPH_RUN
*glyph_run
,
1984 DWRITE_MEASURING_MODE measuring_mode
, D2D1_RECT_F
*bounds
)
1986 FIXME("iface %p, baseline_origin %s, glyph_run %p, measuring_mode %#x, bounds %p stub!\n",
1987 iface
, debug_d2d_point_2f(&baseline_origin
), glyph_run
, measuring_mode
, bounds
);
1992 static void STDMETHODCALLTYPE
d2d_device_context_GetDevice(ID2D1DeviceContext
*iface
, ID2D1Device
**device
)
1994 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
1996 TRACE("iface %p, device %p.\n", iface
, device
);
1998 *device
= context
->device
;
1999 ID2D1Device_AddRef(*device
);
2002 static void d2d_device_context_reset_target(struct d2d_device_context
*context
)
2004 if (!context
->target
)
2007 ID2D1Bitmap1_Release(&context
->target
->ID2D1Bitmap1_iface
);
2008 context
->target
= NULL
;
2010 /* Note that DPI settings are kept. */
2011 memset(&context
->desc
.pixelFormat
, 0, sizeof(context
->desc
.pixelFormat
));
2012 memset(&context
->pixel_size
, 0, sizeof(context
->pixel_size
));
2014 ID3D10BlendState_Release(context
->bs
);
2018 static void STDMETHODCALLTYPE
d2d_device_context_SetTarget(ID2D1DeviceContext
*iface
, ID2D1Image
*target
)
2020 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
2021 struct d2d_bitmap
*bitmap_impl
;
2022 D3D10_BLEND_DESC blend_desc
;
2023 ID2D1Bitmap
*bitmap
;
2026 TRACE("iface %p, target %p.\n", iface
, target
);
2030 d2d_device_context_reset_target(context
);
2034 if (FAILED(ID2D1Image_QueryInterface(target
, &IID_ID2D1Bitmap
, (void **)&bitmap
)))
2036 FIXME("Only bitmap targets are supported.\n");
2040 bitmap_impl
= unsafe_impl_from_ID2D1Bitmap(bitmap
);
2042 if (!(bitmap_impl
->options
& D2D1_BITMAP_OPTIONS_TARGET
))
2044 d2d_device_context_set_error(context
, D2DERR_INVALID_TARGET
);
2048 d2d_device_context_reset_target(context
);
2050 /* Set sizes and pixel format. */
2051 context
->pixel_size
= bitmap_impl
->pixel_size
;
2052 context
->desc
.pixelFormat
= bitmap_impl
->format
;
2053 context
->target
= bitmap_impl
;
2055 memset(&blend_desc
, 0, sizeof(blend_desc
));
2056 blend_desc
.BlendEnable
[0] = TRUE
;
2057 blend_desc
.SrcBlend
= D3D10_BLEND_ONE
;
2058 blend_desc
.DestBlend
= D3D10_BLEND_INV_SRC_ALPHA
;
2059 blend_desc
.BlendOp
= D3D10_BLEND_OP_ADD
;
2060 if (context
->desc
.pixelFormat
.alphaMode
== D2D1_ALPHA_MODE_IGNORE
)
2062 blend_desc
.SrcBlendAlpha
= D3D10_BLEND_ZERO
;
2063 blend_desc
.DestBlendAlpha
= D3D10_BLEND_ONE
;
2067 blend_desc
.SrcBlendAlpha
= D3D10_BLEND_ONE
;
2068 blend_desc
.DestBlendAlpha
= D3D10_BLEND_INV_SRC_ALPHA
;
2070 blend_desc
.BlendOpAlpha
= D3D10_BLEND_OP_ADD
;
2071 blend_desc
.RenderTargetWriteMask
[0] = D3D10_COLOR_WRITE_ENABLE_ALL
;
2072 if (FAILED(hr
= ID3D10Device_CreateBlendState(context
->d3d_device
, &blend_desc
, &context
->bs
)))
2073 WARN("Failed to create blend state, hr %#x.\n", hr
);
2076 static void STDMETHODCALLTYPE
d2d_device_context_GetTarget(ID2D1DeviceContext
*iface
, ID2D1Image
**target
)
2078 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
2080 TRACE("iface %p, target %p.\n", iface
, target
);
2082 *target
= context
->target
? (ID2D1Image
*)&context
->target
->ID2D1Bitmap1_iface
: NULL
;
2084 ID2D1Image_AddRef(*target
);
2087 static void STDMETHODCALLTYPE
d2d_device_context_SetRenderingControls(ID2D1DeviceContext
*iface
,
2088 const D2D1_RENDERING_CONTROLS
*rendering_controls
)
2090 FIXME("iface %p, rendering_controls %p stub!\n", iface
, rendering_controls
);
2093 static void STDMETHODCALLTYPE
d2d_device_context_GetRenderingControls(ID2D1DeviceContext
*iface
,
2094 D2D1_RENDERING_CONTROLS
*rendering_controls
)
2096 FIXME("iface %p, rendering_controls %p stub!\n", iface
, rendering_controls
);
2099 static void STDMETHODCALLTYPE
d2d_device_context_SetPrimitiveBlend(ID2D1DeviceContext
*iface
,
2100 D2D1_PRIMITIVE_BLEND primitive_blend
)
2102 FIXME("iface %p, primitive_blend %#x stub!\n", iface
, primitive_blend
);
2105 static D2D1_PRIMITIVE_BLEND STDMETHODCALLTYPE
d2d_device_context_GetPrimitiveBlend(ID2D1DeviceContext
*iface
)
2107 FIXME("iface %p stub!\n", iface
);
2109 return D2D1_PRIMITIVE_BLEND_SOURCE_OVER
;
2112 static void STDMETHODCALLTYPE
d2d_device_context_SetUnitMode(ID2D1DeviceContext
*iface
, D2D1_UNIT_MODE unit_mode
)
2114 FIXME("iface %p, unit_mode %#x stub!\n", iface
, unit_mode
);
2117 static D2D1_UNIT_MODE STDMETHODCALLTYPE
d2d_device_context_GetUnitMode(ID2D1DeviceContext
*iface
)
2119 FIXME("iface %p stub!\n", iface
);
2121 return D2D1_UNIT_MODE_DIPS
;
2124 static void STDMETHODCALLTYPE
d2d_device_context_ID2D1DeviceContext_DrawGlyphRun(ID2D1DeviceContext
*iface
,
2125 D2D1_POINT_2F baseline_origin
, const DWRITE_GLYPH_RUN
*glyph_run
,
2126 const DWRITE_GLYPH_RUN_DESCRIPTION
*glyph_run_desc
, ID2D1Brush
*brush
, DWRITE_MEASURING_MODE measuring_mode
)
2128 DWRITE_TEXT_ANTIALIAS_MODE antialias_mode
= DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE
;
2129 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
2130 IDWriteRenderingParams
*rendering_params
;
2131 DWRITE_RENDERING_MODE rendering_mode
;
2134 TRACE("iface %p, baseline_origin %s, glyph_run %p, glyph_run_desc %p, brush %p, measuring_mode %#x.\n",
2135 iface
, debug_d2d_point_2f(&baseline_origin
), glyph_run
, glyph_run_desc
, brush
, measuring_mode
);
2137 if (FAILED(context
->error
.code
))
2140 rendering_params
= context
->text_rendering_params
? context
->text_rendering_params
2141 : context
->default_text_rendering_params
;
2143 rendering_mode
= IDWriteRenderingParams_GetRenderingMode(rendering_params
);
2145 switch (context
->drawing_state
.textAntialiasMode
)
2147 case D2D1_TEXT_ANTIALIAS_MODE_ALIASED
:
2148 if (rendering_mode
== DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL
2149 || rendering_mode
== DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC
2150 || rendering_mode
== DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL
2151 || rendering_mode
== DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC
)
2152 d2d_device_context_set_error(context
, E_INVALIDARG
);
2155 case D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE
:
2156 if (rendering_mode
== DWRITE_RENDERING_MODE_ALIASED
2157 || rendering_mode
== DWRITE_RENDERING_MODE_OUTLINE
)
2158 d2d_device_context_set_error(context
, E_INVALIDARG
);
2161 case D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE
:
2162 if (rendering_mode
== DWRITE_RENDERING_MODE_ALIASED
)
2163 d2d_device_context_set_error(context
, E_INVALIDARG
);
2170 if (FAILED(context
->error
.code
))
2173 rendering_mode
= DWRITE_RENDERING_MODE_DEFAULT
;
2174 switch (context
->drawing_state
.textAntialiasMode
)
2176 case D2D1_TEXT_ANTIALIAS_MODE_DEFAULT
:
2177 if (IDWriteRenderingParams_GetClearTypeLevel(rendering_params
) > 0.0f
)
2178 antialias_mode
= DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE
;
2181 case D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE
:
2182 antialias_mode
= DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE
;
2185 case D2D1_TEXT_ANTIALIAS_MODE_ALIASED
:
2186 rendering_mode
= DWRITE_RENDERING_MODE_ALIASED
;
2193 if (rendering_mode
== DWRITE_RENDERING_MODE_DEFAULT
)
2195 if (FAILED(hr
= IDWriteFontFace_GetRecommendedRenderingMode(glyph_run
->fontFace
, glyph_run
->fontEmSize
,
2196 max(context
->desc
.dpiX
, context
->desc
.dpiY
) / 96.0f
,
2197 measuring_mode
, rendering_params
, &rendering_mode
)))
2199 ERR("Failed to get recommended rendering mode, hr %#x.\n", hr
);
2200 rendering_mode
= DWRITE_RENDERING_MODE_OUTLINE
;
2204 if (rendering_mode
== DWRITE_RENDERING_MODE_OUTLINE
)
2205 d2d_device_context_draw_glyph_run_outline(context
, baseline_origin
, glyph_run
, brush
);
2207 d2d_device_context_draw_glyph_run_bitmap(context
, baseline_origin
, glyph_run
, brush
,
2208 rendering_mode
, measuring_mode
, antialias_mode
);
2211 static void STDMETHODCALLTYPE
d2d_device_context_DrawImage(ID2D1DeviceContext
*iface
, ID2D1Image
*image
,
2212 const D2D1_POINT_2F
*target_offset
, const D2D1_RECT_F
*image_rect
, D2D1_INTERPOLATION_MODE interpolation_mode
,
2213 D2D1_COMPOSITE_MODE composite_mode
)
2215 FIXME("iface %p, image %p, target_offset %s, image_rect %s, interpolation_mode %#x, composite_mode %#x stub!\n",
2216 iface
, image
, debug_d2d_point_2f(target_offset
), debug_d2d_rect_f(image_rect
),
2217 interpolation_mode
, composite_mode
);
2220 static void STDMETHODCALLTYPE
d2d_device_context_DrawGdiMetafile(ID2D1DeviceContext
*iface
,
2221 ID2D1GdiMetafile
*metafile
, const D2D1_POINT_2F
*target_offset
)
2223 FIXME("iface %p, metafile %p, target_offset %s stub!\n",
2224 iface
, metafile
, debug_d2d_point_2f(target_offset
));
2227 static void STDMETHODCALLTYPE
d2d_device_context_ID2D1DeviceContext_DrawBitmap(ID2D1DeviceContext
*iface
,
2228 ID2D1Bitmap
*bitmap
, const D2D1_RECT_F
*dst_rect
, float opacity
, D2D1_INTERPOLATION_MODE interpolation_mode
,
2229 const D2D1_RECT_F
*src_rect
, const D2D1_MATRIX_4X4_F
*perspective_transform
)
2231 struct d2d_device_context
*context
= impl_from_ID2D1DeviceContext(iface
);
2233 TRACE("iface %p, bitmap %p, dst_rect %s, opacity %.8e, interpolation_mode %#x, "
2234 "src_rect %s, perspective_transform %p.\n",
2235 iface
, bitmap
, debug_d2d_rect_f(dst_rect
), opacity
, interpolation_mode
,
2236 debug_d2d_rect_f(src_rect
), perspective_transform
);
2238 d2d_device_context_draw_bitmap(context
, bitmap
, dst_rect
, opacity
, interpolation_mode
, src_rect
,
2239 perspective_transform
);
2242 static void STDMETHODCALLTYPE
d2d_device_context_ID2D1DeviceContext_PushLayer(ID2D1DeviceContext
*iface
,
2243 const D2D1_LAYER_PARAMETERS1
*layer_parameters
, ID2D1Layer
*layer
)
2245 FIXME("iface %p, layer_parameters %p, layer %p stub!\n", iface
, layer_parameters
, layer
);
2248 static HRESULT STDMETHODCALLTYPE
d2d_device_context_InvalidateEffectInputRectangle(ID2D1DeviceContext
*iface
,
2249 ID2D1Effect
*effect
, UINT32 input
, const D2D1_RECT_F
*input_rect
)
2251 FIXME("iface %p, effect %p, input %u, input_rect %s stub!\n",
2252 iface
, effect
, input
, debug_d2d_rect_f(input_rect
));
2257 static HRESULT STDMETHODCALLTYPE
d2d_device_context_GetEffectInvalidRectangleCount(ID2D1DeviceContext
*iface
,
2258 ID2D1Effect
*effect
, UINT32
*rect_count
)
2260 FIXME("iface %p, effect %p, rect_count %p stub!\n", iface
, effect
, rect_count
);
2265 static HRESULT STDMETHODCALLTYPE
d2d_device_context_GetEffectInvalidRectangles(ID2D1DeviceContext
*iface
,
2266 ID2D1Effect
*effect
, D2D1_RECT_F
*rectangles
, UINT32 rect_count
)
2268 FIXME("iface %p, effect %p, rectangles %p, rect_count %u stub!\n", iface
, effect
, rectangles
, rect_count
);
2273 static HRESULT STDMETHODCALLTYPE
d2d_device_context_GetEffectRequiredInputRectangles(ID2D1DeviceContext
*iface
,
2274 ID2D1Effect
*effect
, const D2D1_RECT_F
*image_rect
, const D2D1_EFFECT_INPUT_DESCRIPTION
*desc
,
2275 D2D1_RECT_F
*input_rect
, UINT32 input_count
)
2277 FIXME("iface %p, effect %p, image_rect %s, desc %p, input_rect %p, input_count %u stub!\n",
2278 iface
, effect
, debug_d2d_rect_f(image_rect
), desc
, input_rect
, input_count
);
2283 static void STDMETHODCALLTYPE
d2d_device_context_ID2D1DeviceContext_FillOpacityMask(ID2D1DeviceContext
*iface
,
2284 ID2D1Bitmap
*mask
, ID2D1Brush
*brush
, const D2D1_RECT_F
*dst_rect
, const D2D1_RECT_F
*src_rect
)
2286 FIXME("iface %p, mask %p, brush %p, dst_rect %s, src_rect %s stub!\n",
2287 iface
, mask
, brush
, debug_d2d_rect_f(dst_rect
), debug_d2d_rect_f(src_rect
));
2290 static const struct ID2D1DeviceContextVtbl d2d_device_context_vtbl
=
2292 d2d_device_context_QueryInterface
,
2293 d2d_device_context_AddRef
,
2294 d2d_device_context_Release
,
2295 d2d_device_context_GetFactory
,
2296 d2d_device_context_CreateBitmap
,
2297 d2d_device_context_CreateBitmapFromWicBitmap
,
2298 d2d_device_context_CreateSharedBitmap
,
2299 d2d_device_context_CreateBitmapBrush
,
2300 d2d_device_context_CreateSolidColorBrush
,
2301 d2d_device_context_CreateGradientStopCollection
,
2302 d2d_device_context_CreateLinearGradientBrush
,
2303 d2d_device_context_CreateRadialGradientBrush
,
2304 d2d_device_context_CreateCompatibleRenderTarget
,
2305 d2d_device_context_CreateLayer
,
2306 d2d_device_context_CreateMesh
,
2307 d2d_device_context_DrawLine
,
2308 d2d_device_context_DrawRectangle
,
2309 d2d_device_context_FillRectangle
,
2310 d2d_device_context_DrawRoundedRectangle
,
2311 d2d_device_context_FillRoundedRectangle
,
2312 d2d_device_context_DrawEllipse
,
2313 d2d_device_context_FillEllipse
,
2314 d2d_device_context_DrawGeometry
,
2315 d2d_device_context_FillGeometry
,
2316 d2d_device_context_FillMesh
,
2317 d2d_device_context_FillOpacityMask
,
2318 d2d_device_context_DrawBitmap
,
2319 d2d_device_context_DrawText
,
2320 d2d_device_context_DrawTextLayout
,
2321 d2d_device_context_DrawGlyphRun
,
2322 d2d_device_context_SetTransform
,
2323 d2d_device_context_GetTransform
,
2324 d2d_device_context_SetAntialiasMode
,
2325 d2d_device_context_GetAntialiasMode
,
2326 d2d_device_context_SetTextAntialiasMode
,
2327 d2d_device_context_GetTextAntialiasMode
,
2328 d2d_device_context_SetTextRenderingParams
,
2329 d2d_device_context_GetTextRenderingParams
,
2330 d2d_device_context_SetTags
,
2331 d2d_device_context_GetTags
,
2332 d2d_device_context_PushLayer
,
2333 d2d_device_context_PopLayer
,
2334 d2d_device_context_Flush
,
2335 d2d_device_context_SaveDrawingState
,
2336 d2d_device_context_RestoreDrawingState
,
2337 d2d_device_context_PushAxisAlignedClip
,
2338 d2d_device_context_PopAxisAlignedClip
,
2339 d2d_device_context_Clear
,
2340 d2d_device_context_BeginDraw
,
2341 d2d_device_context_EndDraw
,
2342 d2d_device_context_GetPixelFormat
,
2343 d2d_device_context_SetDpi
,
2344 d2d_device_context_GetDpi
,
2345 d2d_device_context_GetSize
,
2346 d2d_device_context_GetPixelSize
,
2347 d2d_device_context_GetMaximumBitmapSize
,
2348 d2d_device_context_IsSupported
,
2349 d2d_device_context_ID2D1DeviceContext_CreateBitmap
,
2350 d2d_device_context_ID2D1DeviceContext_CreateBitmapFromWicBitmap
,
2351 d2d_device_context_CreateColorContext
,
2352 d2d_device_context_CreateColorContextFromFilename
,
2353 d2d_device_context_CreateColorContextFromWicColorContext
,
2354 d2d_device_context_CreateBitmapFromDxgiSurface
,
2355 d2d_device_context_CreateEffect
,
2356 d2d_device_context_ID2D1DeviceContext_CreateGradientStopCollection
,
2357 d2d_device_context_CreateImageBrush
,
2358 d2d_device_context_ID2D1DeviceContext_CreateBitmapBrush
,
2359 d2d_device_context_CreateCommandList
,
2360 d2d_device_context_IsDxgiFormatSupported
,
2361 d2d_device_context_IsBufferPrecisionSupported
,
2362 d2d_device_context_GetImageLocalBounds
,
2363 d2d_device_context_GetImageWorldBounds
,
2364 d2d_device_context_GetGlyphRunWorldBounds
,
2365 d2d_device_context_GetDevice
,
2366 d2d_device_context_SetTarget
,
2367 d2d_device_context_GetTarget
,
2368 d2d_device_context_SetRenderingControls
,
2369 d2d_device_context_GetRenderingControls
,
2370 d2d_device_context_SetPrimitiveBlend
,
2371 d2d_device_context_GetPrimitiveBlend
,
2372 d2d_device_context_SetUnitMode
,
2373 d2d_device_context_GetUnitMode
,
2374 d2d_device_context_ID2D1DeviceContext_DrawGlyphRun
,
2375 d2d_device_context_DrawImage
,
2376 d2d_device_context_DrawGdiMetafile
,
2377 d2d_device_context_ID2D1DeviceContext_DrawBitmap
,
2378 d2d_device_context_ID2D1DeviceContext_PushLayer
,
2379 d2d_device_context_InvalidateEffectInputRectangle
,
2380 d2d_device_context_GetEffectInvalidRectangleCount
,
2381 d2d_device_context_GetEffectInvalidRectangles
,
2382 d2d_device_context_GetEffectRequiredInputRectangles
,
2383 d2d_device_context_ID2D1DeviceContext_FillOpacityMask
,
2386 static inline struct d2d_device_context
*impl_from_IDWriteTextRenderer(IDWriteTextRenderer
*iface
)
2388 return CONTAINING_RECORD(iface
, struct d2d_device_context
, IDWriteTextRenderer_iface
);
2391 static HRESULT STDMETHODCALLTYPE
d2d_text_renderer_QueryInterface(IDWriteTextRenderer
*iface
, REFIID iid
, void **out
)
2393 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
2395 if (IsEqualGUID(iid
, &IID_IDWriteTextRenderer
)
2396 || IsEqualGUID(iid
, &IID_IDWritePixelSnapping
)
2397 || IsEqualGUID(iid
, &IID_IUnknown
))
2399 IDWriteTextRenderer_AddRef(iface
);
2404 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
2407 return E_NOINTERFACE
;
2410 static ULONG STDMETHODCALLTYPE
d2d_text_renderer_AddRef(IDWriteTextRenderer
*iface
)
2412 struct d2d_device_context
*render_target
= impl_from_IDWriteTextRenderer(iface
);
2414 TRACE("iface %p.\n", iface
);
2416 return d2d_device_context_AddRef(&render_target
->ID2D1DeviceContext_iface
);
2419 static ULONG STDMETHODCALLTYPE
d2d_text_renderer_Release(IDWriteTextRenderer
*iface
)
2421 struct d2d_device_context
*render_target
= impl_from_IDWriteTextRenderer(iface
);
2423 TRACE("iface %p.\n", iface
);
2425 return d2d_device_context_Release(&render_target
->ID2D1DeviceContext_iface
);
2428 static HRESULT STDMETHODCALLTYPE
d2d_text_renderer_IsPixelSnappingDisabled(IDWriteTextRenderer
*iface
,
2429 void *ctx
, BOOL
*disabled
)
2431 struct d2d_draw_text_layout_ctx
*context
= ctx
;
2433 TRACE("iface %p, ctx %p, disabled %p.\n", iface
, ctx
, disabled
);
2435 *disabled
= context
->options
& D2D1_DRAW_TEXT_OPTIONS_NO_SNAP
;
2440 static HRESULT STDMETHODCALLTYPE
d2d_text_renderer_GetCurrentTransform(IDWriteTextRenderer
*iface
,
2441 void *ctx
, DWRITE_MATRIX
*transform
)
2443 struct d2d_device_context
*render_target
= impl_from_IDWriteTextRenderer(iface
);
2445 TRACE("iface %p, ctx %p, transform %p.\n", iface
, ctx
, transform
);
2447 d2d_device_context_GetTransform(&render_target
->ID2D1DeviceContext_iface
, (D2D1_MATRIX_3X2_F
*)transform
);
2452 static HRESULT STDMETHODCALLTYPE
d2d_text_renderer_GetPixelsPerDip(IDWriteTextRenderer
*iface
, void *ctx
, float *ppd
)
2454 struct d2d_device_context
*render_target
= impl_from_IDWriteTextRenderer(iface
);
2456 TRACE("iface %p, ctx %p, ppd %p.\n", iface
, ctx
, ppd
);
2458 *ppd
= render_target
->desc
.dpiY
/ 96.0f
;
2463 static HRESULT STDMETHODCALLTYPE
d2d_text_renderer_DrawGlyphRun(IDWriteTextRenderer
*iface
, void *ctx
,
2464 float baseline_origin_x
, float baseline_origin_y
, DWRITE_MEASURING_MODE measuring_mode
,
2465 const DWRITE_GLYPH_RUN
*glyph_run
, const DWRITE_GLYPH_RUN_DESCRIPTION
*desc
, IUnknown
*effect
)
2467 struct d2d_device_context
*render_target
= impl_from_IDWriteTextRenderer(iface
);
2468 D2D1_POINT_2F baseline_origin
= {baseline_origin_x
, baseline_origin_y
};
2469 struct d2d_draw_text_layout_ctx
*context
= ctx
;
2470 BOOL color_font
= FALSE
;
2473 TRACE("iface %p, ctx %p, baseline_origin_x %.8e, baseline_origin_y %.8e, "
2474 "measuring_mode %#x, glyph_run %p, desc %p, effect %p.\n",
2475 iface
, ctx
, baseline_origin_x
, baseline_origin_y
,
2476 measuring_mode
, glyph_run
, desc
, effect
);
2479 WARN("Ignoring glyph run description %p.\n", desc
);
2480 if (context
->options
& ~(D2D1_DRAW_TEXT_OPTIONS_NO_SNAP
| D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT
))
2481 FIXME("Ignoring options %#x.\n", context
->options
);
2483 brush
= d2d_draw_get_text_brush(context
, effect
);
2485 TRACE("%s\n", debugstr_wn(desc
->string
, desc
->stringLength
));
2487 if (context
->options
& D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT
)
2489 IDWriteFontFace2
*fontface
;
2491 if (SUCCEEDED(IDWriteFontFace_QueryInterface(glyph_run
->fontFace
,
2492 &IID_IDWriteFontFace2
, (void **)&fontface
)))
2494 color_font
= IDWriteFontFace2_IsColorFont(fontface
);
2495 IDWriteFontFace2_Release(fontface
);
2501 IDWriteColorGlyphRunEnumerator
*layers
;
2502 IDWriteFactory2
*dwrite_factory
;
2505 if (FAILED(hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory2
,
2506 (IUnknown
**)&dwrite_factory
)))
2508 ERR("Failed to create dwrite factory, hr %#x.\n", hr
);
2509 ID2D1Brush_Release(brush
);
2513 hr
= IDWriteFactory2_TranslateColorGlyphRun(dwrite_factory
, baseline_origin_x
, baseline_origin_y
,
2514 glyph_run
, desc
, measuring_mode
, (DWRITE_MATRIX
*)&render_target
->drawing_state
.transform
, 0, &layers
);
2515 IDWriteFactory2_Release(dwrite_factory
);
2518 ERR("Failed to create color glyph run enumerator, hr %#x.\n", hr
);
2519 ID2D1Brush_Release(brush
);
2525 const DWRITE_COLOR_GLYPH_RUN
*color_run
;
2526 ID2D1Brush
*color_brush
;
2527 D2D1_POINT_2F origin
;
2528 BOOL has_run
= FALSE
;
2530 if (FAILED(hr
= IDWriteColorGlyphRunEnumerator_MoveNext(layers
, &has_run
)))
2532 ERR("Failed to switch color glyph layer, hr %#x.\n", hr
);
2539 if (FAILED(hr
= IDWriteColorGlyphRunEnumerator_GetCurrentRun(layers
, &color_run
)))
2541 ERR("Failed to get current color run, hr %#x.\n", hr
);
2545 if (color_run
->paletteIndex
== 0xffff)
2546 color_brush
= brush
;
2549 if (FAILED(hr
= d2d_device_context_CreateSolidColorBrush(&render_target
->ID2D1DeviceContext_iface
,
2550 &color_run
->runColor
, NULL
, (ID2D1SolidColorBrush
**)&color_brush
)))
2552 ERR("Failed to create solid color brush, hr %#x.\n", hr
);
2557 origin
.x
= color_run
->baselineOriginX
;
2558 origin
.y
= color_run
->baselineOriginY
;
2559 d2d_device_context_DrawGlyphRun(&render_target
->ID2D1DeviceContext_iface
,
2560 origin
, &color_run
->glyphRun
, color_brush
, measuring_mode
);
2562 if (color_brush
!= brush
)
2563 ID2D1Brush_Release(color_brush
);
2566 IDWriteColorGlyphRunEnumerator_Release(layers
);
2569 d2d_device_context_DrawGlyphRun(&render_target
->ID2D1DeviceContext_iface
,
2570 baseline_origin
, glyph_run
, brush
, measuring_mode
);
2572 ID2D1Brush_Release(brush
);
2577 static HRESULT STDMETHODCALLTYPE
d2d_text_renderer_DrawUnderline(IDWriteTextRenderer
*iface
, void *ctx
,
2578 float baseline_origin_x
, float baseline_origin_y
, const DWRITE_UNDERLINE
*underline
, IUnknown
*effect
)
2580 struct d2d_device_context
*render_target
= impl_from_IDWriteTextRenderer(iface
);
2581 const D2D1_MATRIX_3X2_F
*m
= &render_target
->drawing_state
.transform
;
2582 struct d2d_draw_text_layout_ctx
*context
= ctx
;
2583 D2D1_ANTIALIAS_MODE prev_antialias_mode
;
2584 D2D1_POINT_2F start
, end
;
2588 TRACE("iface %p, ctx %p, baseline_origin_x %.8e, baseline_origin_y %.8e, underline %p, effect %p\n",
2589 iface
, ctx
, baseline_origin_x
, baseline_origin_y
, underline
, effect
);
2591 /* minimal thickness in DIPs that will result in at least 1 pixel thick line */
2592 thickness
= max(96.0f
/ (render_target
->desc
.dpiY
* sqrtf(m
->_21
* m
->_21
+ m
->_22
* m
->_22
)),
2593 underline
->thickness
);
2595 brush
= d2d_draw_get_text_brush(context
, effect
);
2597 start
.x
= baseline_origin_x
;
2598 start
.y
= baseline_origin_y
+ underline
->offset
+ thickness
/ 2.0f
;
2599 end
.x
= start
.x
+ underline
->width
;
2601 prev_antialias_mode
= d2d_device_context_set_aa_mode_from_text_aa_mode(render_target
);
2602 d2d_device_context_DrawLine(&render_target
->ID2D1DeviceContext_iface
, start
, end
, brush
, thickness
, NULL
);
2603 render_target
->drawing_state
.antialiasMode
= prev_antialias_mode
;
2605 ID2D1Brush_Release(brush
);
2610 static HRESULT STDMETHODCALLTYPE
d2d_text_renderer_DrawStrikethrough(IDWriteTextRenderer
*iface
, void *ctx
,
2611 float baseline_origin_x
, float baseline_origin_y
, const DWRITE_STRIKETHROUGH
*strikethrough
, IUnknown
*effect
)
2613 struct d2d_device_context
*render_target
= impl_from_IDWriteTextRenderer(iface
);
2614 const D2D1_MATRIX_3X2_F
*m
= &render_target
->drawing_state
.transform
;
2615 struct d2d_draw_text_layout_ctx
*context
= ctx
;
2616 D2D1_ANTIALIAS_MODE prev_antialias_mode
;
2617 D2D1_POINT_2F start
, end
;
2621 TRACE("iface %p, ctx %p, baseline_origin_x %.8e, baseline_origin_y %.8e, strikethrough %p, effect %p.\n",
2622 iface
, ctx
, baseline_origin_x
, baseline_origin_y
, strikethrough
, effect
);
2624 /* minimal thickness in DIPs that will result in at least 1 pixel thick line */
2625 thickness
= max(96.0f
/ (render_target
->desc
.dpiY
* sqrtf(m
->_21
* m
->_21
+ m
->_22
* m
->_22
)),
2626 strikethrough
->thickness
);
2628 brush
= d2d_draw_get_text_brush(context
, effect
);
2630 start
.x
= baseline_origin_x
;
2631 start
.y
= baseline_origin_y
+ strikethrough
->offset
+ thickness
/ 2.0f
;
2632 end
.x
= start
.x
+ strikethrough
->width
;
2634 prev_antialias_mode
= d2d_device_context_set_aa_mode_from_text_aa_mode(render_target
);
2635 d2d_device_context_DrawLine(&render_target
->ID2D1DeviceContext_iface
, start
, end
, brush
, thickness
, NULL
);
2636 render_target
->drawing_state
.antialiasMode
= prev_antialias_mode
;
2638 ID2D1Brush_Release(brush
);
2643 static HRESULT STDMETHODCALLTYPE
d2d_text_renderer_DrawInlineObject(IDWriteTextRenderer
*iface
, void *ctx
,
2644 float origin_x
, float origin_y
, IDWriteInlineObject
*object
, BOOL is_sideways
, BOOL is_rtl
, IUnknown
*effect
)
2646 struct d2d_draw_text_layout_ctx
*context
= ctx
;
2650 TRACE("iface %p, ctx %p, origin_x %.8e, origin_y %.8e, object %p, is_sideways %#x, is_rtl %#x, effect %p.\n",
2651 iface
, ctx
, origin_x
, origin_y
, object
, is_sideways
, is_rtl
, effect
);
2653 /* Inline objects may not pass effects all the way down, when using layout object internally for example.
2654 This is how default trimming sign object in DirectWrite works - it does not use effect passed to Draw(),
2655 and resulting DrawGlyphRun() is always called with NULL effect, however original effect is used and correct
2656 brush is selected at Direct2D level. */
2657 brush
= context
->brush
;
2658 context
->brush
= d2d_draw_get_text_brush(context
, effect
);
2660 hr
= IDWriteInlineObject_Draw(object
, ctx
, iface
, origin_x
, origin_y
, is_sideways
, is_rtl
, effect
);
2662 ID2D1Brush_Release(context
->brush
);
2663 context
->brush
= brush
;
2668 static const struct IDWriteTextRendererVtbl d2d_text_renderer_vtbl
=
2670 d2d_text_renderer_QueryInterface
,
2671 d2d_text_renderer_AddRef
,
2672 d2d_text_renderer_Release
,
2673 d2d_text_renderer_IsPixelSnappingDisabled
,
2674 d2d_text_renderer_GetCurrentTransform
,
2675 d2d_text_renderer_GetPixelsPerDip
,
2676 d2d_text_renderer_DrawGlyphRun
,
2677 d2d_text_renderer_DrawUnderline
,
2678 d2d_text_renderer_DrawStrikethrough
,
2679 d2d_text_renderer_DrawInlineObject
,
2682 static inline struct d2d_device_context
*impl_from_ID2D1GdiInteropRenderTarget(ID2D1GdiInteropRenderTarget
*iface
)
2684 return CONTAINING_RECORD(iface
, struct d2d_device_context
, ID2D1GdiInteropRenderTarget_iface
);
2687 static HRESULT STDMETHODCALLTYPE
d2d_gdi_interop_render_target_QueryInterface(ID2D1GdiInteropRenderTarget
*iface
,
2688 REFIID iid
, void **out
)
2690 struct d2d_device_context
*render_target
= impl_from_ID2D1GdiInteropRenderTarget(iface
);
2692 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
2694 return IUnknown_QueryInterface(render_target
->outer_unknown
, iid
, out
);
2697 static ULONG STDMETHODCALLTYPE
d2d_gdi_interop_render_target_AddRef(ID2D1GdiInteropRenderTarget
*iface
)
2699 struct d2d_device_context
*render_target
= impl_from_ID2D1GdiInteropRenderTarget(iface
);
2701 TRACE("iface %p.\n", iface
);
2703 return IUnknown_AddRef(render_target
->outer_unknown
);
2706 static ULONG STDMETHODCALLTYPE
d2d_gdi_interop_render_target_Release(ID2D1GdiInteropRenderTarget
*iface
)
2708 struct d2d_device_context
*render_target
= impl_from_ID2D1GdiInteropRenderTarget(iface
);
2710 TRACE("iface %p.\n", iface
);
2712 return IUnknown_Release(render_target
->outer_unknown
);
2715 static HRESULT
d2d_device_context_get_surface(struct d2d_device_context
*render_target
, IDXGISurface1
**surface
)
2717 ID3D10Resource
*resource
;
2720 ID3D10RenderTargetView_GetResource(render_target
->target
->rtv
, &resource
);
2721 hr
= ID3D10Resource_QueryInterface(resource
, &IID_IDXGISurface1
, (void **)surface
);
2722 ID3D10Resource_Release(resource
);
2726 WARN("Failed to get DXGI surface, %#x.\n", hr
);
2733 static HRESULT STDMETHODCALLTYPE
d2d_gdi_interop_render_target_GetDC(ID2D1GdiInteropRenderTarget
*iface
,
2734 D2D1_DC_INITIALIZE_MODE mode
, HDC
*dc
)
2736 struct d2d_device_context
*render_target
= impl_from_ID2D1GdiInteropRenderTarget(iface
);
2737 IDXGISurface1
*surface
;
2740 TRACE("iface %p, mode %d, dc %p.\n", iface
, mode
, dc
);
2742 if (FAILED(hr
= d2d_device_context_get_surface(render_target
, &surface
)))
2745 hr
= IDXGISurface1_GetDC(surface
, mode
!= D2D1_DC_INITIALIZE_MODE_COPY
, dc
);
2746 IDXGISurface1_Release(surface
);
2751 static HRESULT STDMETHODCALLTYPE
d2d_gdi_interop_render_target_ReleaseDC(ID2D1GdiInteropRenderTarget
*iface
,
2754 struct d2d_device_context
*render_target
= impl_from_ID2D1GdiInteropRenderTarget(iface
);
2755 IDXGISurface1
*surface
;
2759 TRACE("iface %p, update rect %s.\n", iface
, wine_dbgstr_rect(update
));
2761 if (FAILED(hr
= d2d_device_context_get_surface(render_target
, &surface
)))
2765 update_rect
= *update
;
2766 hr
= IDXGISurface1_ReleaseDC(surface
, update
? &update_rect
: NULL
);
2767 IDXGISurface1_Release(surface
);
2772 static const struct ID2D1GdiInteropRenderTargetVtbl d2d_gdi_interop_render_target_vtbl
=
2774 d2d_gdi_interop_render_target_QueryInterface
,
2775 d2d_gdi_interop_render_target_AddRef
,
2776 d2d_gdi_interop_render_target_Release
,
2777 d2d_gdi_interop_render_target_GetDC
,
2778 d2d_gdi_interop_render_target_ReleaseDC
,
2781 static HRESULT
d2d_device_context_init(struct d2d_device_context
*render_target
, ID2D1Device
*device
,
2782 IUnknown
*outer_unknown
, const struct d2d_device_context_ops
*ops
)
2784 D3D10_SUBRESOURCE_DATA buffer_data
;
2785 D3D10_STATE_BLOCK_MASK state_mask
;
2786 struct d2d_device
*device_impl
;
2787 IDWriteFactory
*dwrite_factory
;
2788 D3D10_RASTERIZER_DESC rs_desc
;
2789 D3D10_BUFFER_DESC buffer_desc
;
2793 static const D3D10_INPUT_ELEMENT_DESC il_desc_outline
[] =
2795 {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT
, 0, 0, D3D10_INPUT_PER_VERTEX_DATA
, 0},
2796 {"PREV", 0, DXGI_FORMAT_R32G32_FLOAT
, 0, 8, D3D10_INPUT_PER_VERTEX_DATA
, 0},
2797 {"NEXT", 0, DXGI_FORMAT_R32G32_FLOAT
, 0, 16, D3D10_INPUT_PER_VERTEX_DATA
, 0},
2799 static const D3D10_INPUT_ELEMENT_DESC il_desc_curve_outline
[] =
2801 {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT
, 0, 0, D3D10_INPUT_PER_VERTEX_DATA
, 0},
2802 {"P", 0, DXGI_FORMAT_R32G32_FLOAT
, 0, 8, D3D10_INPUT_PER_VERTEX_DATA
, 0},
2803 {"P", 1, DXGI_FORMAT_R32G32_FLOAT
, 0, 16, D3D10_INPUT_PER_VERTEX_DATA
, 0},
2804 {"P", 2, DXGI_FORMAT_R32G32_FLOAT
, 0, 24, D3D10_INPUT_PER_VERTEX_DATA
, 0},
2805 {"PREV", 0, DXGI_FORMAT_R32G32_FLOAT
, 0, 32, D3D10_INPUT_PER_VERTEX_DATA
, 0},
2806 {"NEXT", 0, DXGI_FORMAT_R32G32_FLOAT
, 0, 40, D3D10_INPUT_PER_VERTEX_DATA
, 0},
2808 static const D3D10_INPUT_ELEMENT_DESC il_desc_triangle
[] =
2810 {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT
, 0, 0, D3D10_INPUT_PER_VERTEX_DATA
, 0},
2812 static const D3D10_INPUT_ELEMENT_DESC il_desc_curve
[] =
2814 {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT
, 0, 0, D3D10_INPUT_PER_VERTEX_DATA
, 0},
2815 {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT
, 0, 8, D3D10_INPUT_PER_VERTEX_DATA
, 0},
2817 static const DWORD vs_code_outline
[] =
2820 float3x2 transform_geometry
;
2822 float4 transform_rtx
;
2823 float4 transform_rty
;
2827 float2 p
: WORLD_POSITION
;
2829 nointerpolation float2x2 stroke_transform
: STROKE_TRANSFORM
;
2830 float4 position
: SV_POSITION
;
2833 /* The lines PₚᵣₑᵥP₀ and P₀Pₙₑₓₜ, both offset by ±½w, intersect each other at:
2835 * Pᵢ = P₀ ± w · ½q⃑ᵢ.
2839 * q⃑ᵢ = q̂ₚᵣₑᵥ⊥ + tan(½θ) · -q̂ₚᵣₑᵥ
2841 * q⃑ₚᵣₑᵥ = P₀ - Pₚᵣₑᵥ */
2842 void main(float2 position
: POSITION
, float2 prev
: PREV
, float2 next
: NEXT
, out
struct output o
)
2844 float2 q_prev
, q_next
, v_p
, q_i
;
2848 o
.stroke_transform
= float2x2(transform_rtx
.xy
, transform_rty
.xy
) * stroke_width
* 0.5f
;
2850 geom
= float2x2(transform_geometry
._11_21
, transform_geometry
._12_22
);
2851 q_prev
= normalize(mul(geom
, prev
));
2852 q_next
= normalize(mul(geom
, next
));
2854 /* tan(½θ) = sin(θ) / (1 + cos(θ))
2855 * = (q̂ₚᵣₑᵥ⊥ · q̂ₙₑₓₜ) / (1 + (q̂ₚᵣₑᵥ · q̂ₙₑₓₜ)) */
2856 v_p
= float2(-q_prev
.y
, q_prev
.x
);
2857 l
= -dot(v_p
, q_next
) / (1.0f
+ dot(q_prev
, q_next
));
2858 q_i
= l
* q_prev
+ v_p
;
2860 o
.b
= float4(0.0, 0.0, 0.0, 0.0);
2862 o
.p
= mul(float3(position
, 1.0f
), transform_geometry
) + stroke_width
* 0.5f
* q_i
;
2863 position
= mul(float2x3(transform_rtx
.xyz
, transform_rty
.xyz
), float3(o
.p
, 1.0f
))
2864 * float2(transform_rtx
.w
, transform_rty
.w
);
2865 o
.position
= float4(position
+ float2(-1.0f
, 1.0f
), 0.0f
, 1.0f
);
2868 0x43425844, 0xfb16cd75, 0xf5ec3e80, 0xceacf250, 0x91d29d18, 0x00000001, 0x00000608, 0x00000003,
2869 0x0000002c, 0x00000098, 0x00000154, 0x4e475349, 0x00000064, 0x00000003, 0x00000008, 0x00000050,
2870 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x00000059, 0x00000000, 0x00000000,
2871 0x00000003, 0x00000001, 0x00000303, 0x0000005e, 0x00000000, 0x00000000, 0x00000003, 0x00000002,
2872 0x00000303, 0x49534f50, 0x4e4f4954, 0x45525000, 0x454e0056, 0xab005458, 0x4e47534f, 0x000000b4,
2873 0x00000005, 0x00000008, 0x00000080, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000c03,
2874 0x0000008f, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x00000096, 0x00000000,
2875 0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x00000096, 0x00000001, 0x00000000, 0x00000003,
2876 0x00000003, 0x00000c03, 0x000000a7, 0x00000000, 0x00000001, 0x00000003, 0x00000004, 0x0000000f,
2877 0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, 0x54530052, 0x454b4f52, 0x4152545f,
2878 0x4f46534e, 0x53004d52, 0x4f505f56, 0x49544953, 0xab004e4f, 0x52444853, 0x000004ac, 0x00010040,
2879 0x0000012b, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, 0x0300005f, 0x00101032, 0x00000000,
2880 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x00101032, 0x00000002, 0x03000065, 0x00102032,
2881 0x00000000, 0x03000065, 0x001020f2, 0x00000001, 0x03000065, 0x00102032, 0x00000002, 0x03000065,
2882 0x00102032, 0x00000003, 0x04000067, 0x001020f2, 0x00000004, 0x00000001, 0x02000068, 0x00000003,
2883 0x0800000f, 0x00100012, 0x00000000, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000002,
2884 0x0800000f, 0x00100022, 0x00000000, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000002,
2885 0x0700000f, 0x00100042, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000000, 0x05000044,
2886 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x07000038, 0x00100032, 0x00000000, 0x00100aa6,
2887 0x00000000, 0x00100046, 0x00000000, 0x0800000f, 0x00100012, 0x00000001, 0x00208046, 0x00000000,
2888 0x00000000, 0x00101046, 0x00000001, 0x0800000f, 0x00100022, 0x00000001, 0x00208046, 0x00000000,
2889 0x00000001, 0x00101046, 0x00000001, 0x0700000f, 0x00100042, 0x00000000, 0x00100046, 0x00000001,
2890 0x00100046, 0x00000001, 0x05000044, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x07000038,
2891 0x00100032, 0x00000001, 0x00100aa6, 0x00000000, 0x00100046, 0x00000001, 0x06000036, 0x001000c2,
2892 0x00000001, 0x80100556, 0x00000041, 0x00000001, 0x0700000f, 0x00100042, 0x00000000, 0x00100a26,
2893 0x00000001, 0x00100046, 0x00000000, 0x0700000f, 0x00100012, 0x00000000, 0x00100046, 0x00000001,
2894 0x00100046, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001,
2895 0x3f800000, 0x0800000e, 0x00100012, 0x00000000, 0x8010002a, 0x00000041, 0x00000000, 0x0010000a,
2896 0x00000000, 0x09000032, 0x00100032, 0x00000000, 0x00100006, 0x00000000, 0x00100046, 0x00000001,
2897 0x00100f36, 0x00000001, 0x08000038, 0x00100042, 0x00000000, 0x0020803a, 0x00000000, 0x00000001,
2898 0x00004001, 0x3f000000, 0x05000036, 0x00100032, 0x00000001, 0x00101046, 0x00000000, 0x05000036,
2899 0x00100042, 0x00000001, 0x00004001, 0x3f800000, 0x08000010, 0x00100012, 0x00000002, 0x00100246,
2900 0x00000001, 0x00208246, 0x00000000, 0x00000000, 0x08000010, 0x00100022, 0x00000002, 0x00100246,
2901 0x00000001, 0x00208246, 0x00000000, 0x00000001, 0x09000032, 0x00100032, 0x00000000, 0x00100aa6,
2902 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000002, 0x05000036, 0x00102032, 0x00000000,
2903 0x00100046, 0x00000000, 0x08000036, 0x001020f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000,
2904 0x00000000, 0x00000000, 0x06000036, 0x00100032, 0x00000001, 0x00208046, 0x00000000, 0x00000002,
2905 0x06000036, 0x001000c2, 0x00000001, 0x00208406, 0x00000000, 0x00000003, 0x08000038, 0x001000f2,
2906 0x00000001, 0x00100e46, 0x00000001, 0x00208ff6, 0x00000000, 0x00000001, 0x0a000038, 0x001000f2,
2907 0x00000001, 0x00100e46, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000,
2908 0x05000036, 0x00102032, 0x00000002, 0x00100086, 0x00000001, 0x05000036, 0x00102032, 0x00000003,
2909 0x001005d6, 0x00000001, 0x05000036, 0x00100042, 0x00000000, 0x00004001, 0x3f800000, 0x08000010,
2910 0x00100082, 0x00000000, 0x00208246, 0x00000000, 0x00000002, 0x00100246, 0x00000000, 0x08000010,
2911 0x00100012, 0x00000000, 0x00208246, 0x00000000, 0x00000003, 0x00100246, 0x00000000, 0x08000038,
2912 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x0020803a, 0x00000000, 0x00000003, 0x08000038,
2913 0x00100012, 0x00000000, 0x0010003a, 0x00000000, 0x0020803a, 0x00000000, 0x00000002, 0x0a000000,
2914 0x00102032, 0x00000004, 0x00100046, 0x00000000, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000,
2915 0x00000000, 0x08000036, 0x001020c2, 0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
2916 0x3f800000, 0x0100003e,
2926 * A' = ⎡p1.x-p0.x p1.y-p0.y⎤
2927 * ⎣p2.x-p0.x p2.y-p0.y⎦
2935 static const DWORD vs_code_bezier_outline
[] =
2938 float3x2 transform_geometry
;
2940 float4 transform_rtx
;
2941 float4 transform_rty
;
2945 float2 p
: WORLD_POSITION
;
2947 nointerpolation float2x2 stroke_transform
: STROKE_TRANSFORM
;
2948 float4 position
: SV_POSITION
;
2951 void main(float2 position
: POSITION
, float2 p0
: P0
, float2 p1
: P1
, float2 p2
: P2
,
2952 float2 prev
: PREV
, float2 next
: NEXT
, out
struct output o
)
2954 float2 q_prev
, q_next
, v_p
, q_i
, p
;
2958 geom
= float2x2(transform_geometry
._11_21
, transform_geometry
._12_22
);
2959 rt
= float2x2(transform_rtx
.xy
, transform_rty
.xy
);
2960 o
.stroke_transform
= rt
* stroke_width
* 0.5f
;
2962 p
= mul(geom
, position
);
2971 q_prev
= normalize(mul(geom
, prev
));
2972 q_next
= normalize(mul(geom
, next
));
2974 v_p
= float2(-q_prev
.y
, q_prev
.x
);
2975 l
= -dot(v_p
, q_next
) / (1.0f
+ dot(q_prev
, q_next
));
2976 q_i
= l
* q_prev
+ v_p
;
2977 p
+= 0.5f
* stroke_width
* q_i
;
2980 v_p
= normalize(float2(-v_p
.y
, v_p
.x
));
2981 if (abs(dot(mul(rt
, p1
), v_p
)) < 1.0f
)
2983 o
.b
.xzw
= float3(0.0f
, 0.0f
, 0.0f
);
2984 o
.b
.y
= dot(mul(rt
, p
), v_p
);
2988 o
.b
.zw
= sign(dot(mul(rt
, p1
), v_p
)) * v_p
;
2989 v_p
= -float2(-p
.y
, p
.x
) / dot(float2(-p1
.y
, p1
.x
), p2
);
2990 o
.b
.x
= dot(v_p
, p1
- 0.5f
* p2
);
2991 o
.b
.y
= dot(v_p
, p1
);
2994 o
.p
= mul(float3(position
, 1.0f
), transform_geometry
) + 0.5f
* stroke_width
* q_i
;
2995 position
= mul(float2x3(transform_rtx
.xyz
, transform_rty
.xyz
), float3(o
.p
, 1.0f
))
2996 * float2(transform_rtx
.w
, transform_rty
.w
);
2997 o
.position
= float4(position
+ float2(-1.0f
, 1.0f
), 0.0f
, 1.0f
);
3000 0x43425844, 0x356a0c5f, 0x8e4ba153, 0xe52cf793, 0xa6b774ea, 0x00000001, 0x00000afc, 0x00000003,
3001 0x0000002c, 0x000000e4, 0x000001a0, 0x4e475349, 0x000000b0, 0x00000006, 0x00000008, 0x00000098,
3002 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x000000a1, 0x00000000, 0x00000000,
3003 0x00000003, 0x00000001, 0x00000303, 0x000000a1, 0x00000001, 0x00000000, 0x00000003, 0x00000002,
3004 0x00000303, 0x000000a1, 0x00000002, 0x00000000, 0x00000003, 0x00000003, 0x00000303, 0x000000a3,
3005 0x00000000, 0x00000000, 0x00000003, 0x00000004, 0x00000303, 0x000000a8, 0x00000000, 0x00000000,
3006 0x00000003, 0x00000005, 0x00000303, 0x49534f50, 0x4e4f4954, 0x50005000, 0x00564552, 0x5458454e,
3007 0xababab00, 0x4e47534f, 0x000000b4, 0x00000005, 0x00000008, 0x00000080, 0x00000000, 0x00000000,
3008 0x00000003, 0x00000000, 0x00000c03, 0x0000008f, 0x00000000, 0x00000000, 0x00000003, 0x00000001,
3009 0x0000000f, 0x00000096, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x00000096,
3010 0x00000001, 0x00000000, 0x00000003, 0x00000003, 0x00000c03, 0x000000a7, 0x00000000, 0x00000001,
3011 0x00000003, 0x00000004, 0x0000000f, 0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45,
3012 0x54530052, 0x454b4f52, 0x4152545f, 0x4f46534e, 0x53004d52, 0x4f505f56, 0x49544953, 0xab004e4f,
3013 0x52444853, 0x00000954, 0x00010040, 0x00000255, 0x04000059, 0x00208e46, 0x00000000, 0x00000004,
3014 0x0300005f, 0x00101032, 0x00000000, 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x00101032,
3015 0x00000002, 0x0300005f, 0x00101032, 0x00000003, 0x0300005f, 0x00101032, 0x00000004, 0x0300005f,
3016 0x00101032, 0x00000005, 0x03000065, 0x00102032, 0x00000000, 0x03000065, 0x001020f2, 0x00000001,
3017 0x03000065, 0x00102032, 0x00000002, 0x03000065, 0x00102032, 0x00000003, 0x04000067, 0x001020f2,
3018 0x00000004, 0x00000001, 0x02000068, 0x00000006, 0x0800000f, 0x00100012, 0x00000000, 0x00208046,
3019 0x00000000, 0x00000000, 0x00101046, 0x00000005, 0x0800000f, 0x00100022, 0x00000000, 0x00208046,
3020 0x00000000, 0x00000001, 0x00101046, 0x00000005, 0x0700000f, 0x00100042, 0x00000000, 0x00100046,
3021 0x00000000, 0x00100046, 0x00000000, 0x05000044, 0x00100042, 0x00000000, 0x0010002a, 0x00000000,
3022 0x07000038, 0x00100032, 0x00000000, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x0800000f,
3023 0x00100012, 0x00000001, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000004, 0x0800000f,
3024 0x00100022, 0x00000001, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000004, 0x0700000f,
3025 0x00100042, 0x00000000, 0x00100046, 0x00000001, 0x00100046, 0x00000001, 0x05000044, 0x00100042,
3026 0x00000000, 0x0010002a, 0x00000000, 0x07000038, 0x00100032, 0x00000001, 0x00100aa6, 0x00000000,
3027 0x00100046, 0x00000001, 0x06000036, 0x001000c2, 0x00000001, 0x80100556, 0x00000041, 0x00000001,
3028 0x0700000f, 0x00100042, 0x00000000, 0x00100a26, 0x00000001, 0x00100046, 0x00000000, 0x0700000f,
3029 0x00100012, 0x00000000, 0x00100046, 0x00000001, 0x00100046, 0x00000000, 0x07000000, 0x00100012,
3030 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0800000e, 0x00100012, 0x00000000,
3031 0x8010002a, 0x00000041, 0x00000000, 0x0010000a, 0x00000000, 0x09000032, 0x00100032, 0x00000000,
3032 0x00100006, 0x00000000, 0x00100046, 0x00000001, 0x00100f36, 0x00000001, 0x05000036, 0x00100032,
3033 0x00000001, 0x00101046, 0x00000000, 0x05000036, 0x00100042, 0x00000001, 0x00004001, 0x3f800000,
3034 0x08000010, 0x00100012, 0x00000002, 0x00100246, 0x00000001, 0x00208246, 0x00000000, 0x00000000,
3035 0x08000010, 0x00100022, 0x00000002, 0x00100246, 0x00000001, 0x00208246, 0x00000000, 0x00000001,
3036 0x08000038, 0x00100042, 0x00000000, 0x0020803a, 0x00000000, 0x00000001, 0x00004001, 0x3f000000,
3037 0x09000032, 0x00100032, 0x00000001, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x00100046,
3038 0x00000002, 0x05000036, 0x00102032, 0x00000000, 0x00100046, 0x00000001, 0x0800000f, 0x00100012,
3039 0x00000002, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000000, 0x0800000f, 0x00100022,
3040 0x00000002, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000000, 0x0800000f, 0x00100012,
3041 0x00000003, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000001, 0x0800000f, 0x00100022,
3042 0x00000003, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000001, 0x08000000, 0x00100032,
3043 0x00000002, 0x00100046, 0x00000002, 0x80100046, 0x00000041, 0x00000003, 0x09000032, 0x00100032,
3044 0x00000000, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000002, 0x0800000f,
3045 0x00100012, 0x00000002, 0x00208046, 0x00000000, 0x00000002, 0x00100046, 0x00000000, 0x0800000f,
3046 0x00100022, 0x00000002, 0x00208046, 0x00000000, 0x00000003, 0x00100046, 0x00000000, 0x0800000f,
3047 0x00100012, 0x00000004, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000003, 0x0800000f,
3048 0x00100022, 0x00000004, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000003, 0x08000000,
3049 0x001000c2, 0x00000002, 0x80100406, 0x00000041, 0x00000003, 0x00100406, 0x00000004, 0x0800000f,
3050 0x00100082, 0x00000000, 0x00208046, 0x00000000, 0x00000003, 0x00100ae6, 0x00000002, 0x06000036,
3051 0x00100042, 0x00000003, 0x8010003a, 0x00000041, 0x00000000, 0x0800000f, 0x00100082, 0x00000003,
3052 0x00208046, 0x00000000, 0x00000002, 0x00100ae6, 0x00000002, 0x0700000f, 0x00100082, 0x00000000,
3053 0x00100ae6, 0x00000003, 0x00100ae6, 0x00000003, 0x05000044, 0x00100082, 0x00000000, 0x0010003a,
3054 0x00000000, 0x07000038, 0x001000c2, 0x00000003, 0x00100ff6, 0x00000000, 0x00100ea6, 0x00000003,
3055 0x0700000f, 0x00100022, 0x00000004, 0x00100046, 0x00000002, 0x00100ae6, 0x00000003, 0x06000036,
3056 0x00100042, 0x00000000, 0x8010001a, 0x00000041, 0x00000000, 0x0800000f, 0x00100012, 0x00000002,
3057 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000002, 0x0800000f, 0x00100022, 0x00000002,
3058 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000002, 0x08000000, 0x00100032, 0x00000005,
3059 0x80100046, 0x00000041, 0x00000003, 0x00100046, 0x00000002, 0x06000036, 0x00100042, 0x00000005,
3060 0x8010001a, 0x00000041, 0x00000005, 0x0700000f, 0x00100022, 0x00000000, 0x00100a26, 0x00000005,
3061 0x00100ae6, 0x00000002, 0x0d000032, 0x00100032, 0x00000002, 0x80100ae6, 0x00000041, 0x00000002,
3062 0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00100046, 0x00000005, 0x0800000e,
3063 0x00100032, 0x00000000, 0x80100a26, 0x00000041, 0x00000000, 0x00100556, 0x00000000, 0x0700000f,
3064 0x00100012, 0x00000002, 0x00100046, 0x00000000, 0x00100046, 0x00000002, 0x0700000f, 0x00100022,
3065 0x00000002, 0x00100046, 0x00000000, 0x00100046, 0x00000005, 0x0800000f, 0x00100012, 0x00000000,
3066 0x00208046, 0x00000000, 0x00000002, 0x00100046, 0x00000005, 0x0800000f, 0x00100022, 0x00000000,
3067 0x00208046, 0x00000000, 0x00000003, 0x00100046, 0x00000005, 0x0700000f, 0x00100012, 0x00000000,
3068 0x00100046, 0x00000000, 0x00100ae6, 0x00000003, 0x07000031, 0x00100022, 0x00000000, 0x00004001,
3069 0x00000000, 0x0010000a, 0x00000000, 0x07000031, 0x00100042, 0x00000000, 0x0010000a, 0x00000000,
3070 0x00004001, 0x00000000, 0x08000031, 0x00100012, 0x00000000, 0x8010000a, 0x00000081, 0x00000000,
3071 0x00004001, 0x3f800000, 0x0800001e, 0x00100022, 0x00000000, 0x8010001a, 0x00000041, 0x00000000,
3072 0x0010002a, 0x00000000, 0x0500002b, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x07000038,
3073 0x001000c2, 0x00000002, 0x00100ea6, 0x00000003, 0x00100556, 0x00000000, 0x08000036, 0x001000d2,
3074 0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x09000037, 0x001020f2,
3075 0x00000001, 0x00100006, 0x00000000, 0x00100e46, 0x00000004, 0x00100e46, 0x00000002, 0x06000036,
3076 0x00100032, 0x00000000, 0x00208046, 0x00000000, 0x00000002, 0x06000036, 0x001000c2, 0x00000000,
3077 0x00208406, 0x00000000, 0x00000003, 0x08000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000,
3078 0x00208ff6, 0x00000000, 0x00000001, 0x0a000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000,
3079 0x00004002, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x05000036, 0x00102032, 0x00000002,
3080 0x00100086, 0x00000000, 0x05000036, 0x00102032, 0x00000003, 0x001005d6, 0x00000000, 0x05000036,
3081 0x00100042, 0x00000001, 0x00004001, 0x3f800000, 0x08000010, 0x00100012, 0x00000000, 0x00208246,
3082 0x00000000, 0x00000002, 0x00100246, 0x00000001, 0x08000010, 0x00100022, 0x00000000, 0x00208246,
3083 0x00000000, 0x00000003, 0x00100246, 0x00000001, 0x08000038, 0x00100022, 0x00000001, 0x0010001a,
3084 0x00000000, 0x0020803a, 0x00000000, 0x00000003, 0x08000038, 0x00100012, 0x00000001, 0x0010000a,
3085 0x00000000, 0x0020803a, 0x00000000, 0x00000002, 0x0a000000, 0x00102032, 0x00000004, 0x00100046,
3086 0x00000001, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000, 0x00000000, 0x08000036, 0x001020c2,
3087 0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e,
3097 * A' = ⎡p1.x-p0.x p1.y-p0.y⎤
3098 * ⎣p2.x-p0.x p2.y-p0.y⎦
3104 * T = A'⁻¹B' = (B'⁻¹A')⁻¹
3106 static const DWORD vs_code_arc_outline
[] =
3109 float3x2 transform_geometry
;
3111 float4 transform_rtx
;
3112 float4 transform_rty
;
3116 float2 p
: WORLD_POSITION
;
3118 nointerpolation float2x2 stroke_transform
: STROKE_TRANSFORM
;
3119 float4 position
: SV_POSITION
;
3122 void main(float2 position
: POSITION
, float2 p0
: P0
, float2 p1
: P1
, float2 p2
: P2
,
3123 float2 prev
: PREV
, float2 next
: NEXT
, out
struct output o
)
3125 float2 q_prev
, q_next
, v_p
, q_i
, p
;
3126 float2x2 geom
, rt
, p_inv
;
3131 geom
= float2x2(transform_geometry
._11_21
, transform_geometry
._12_22
);
3132 rt
= float2x2(transform_rtx
.xy
, transform_rty
.xy
);
3133 o
.stroke_transform
= rt
* stroke_width
* 0.5f
;
3135 p
= mul(geom
, position
);
3144 q_prev
= normalize(mul(geom
, prev
));
3145 q_next
= normalize(mul(geom
, next
));
3147 v_p
= float2(-q_prev
.y
, q_prev
.x
);
3148 l
= -dot(v_p
, q_next
) / (1.0f
+ dot(q_prev
, q_next
));
3149 q_i
= l
* q_prev
+ v_p
;
3150 p
+= 0.5f
* stroke_width
* q_i
;
3152 p_inv
= float2x2(p1
.y
, -p1
.x
, p2
.y
- p1
.y
, p1
.x
- p2
.x
) / (p1
.x
* p2
.y
- p2
.x
* p1
.y
);
3153 o
.b
.xy
= mul(p_inv
, p
) + float2(1.0f
, 0.0f
);
3156 o
.p
= mul(float3(position
, 1.0f
), transform_geometry
) + 0.5f
* stroke_width
* q_i
;
3157 position
= mul(float2x3(transform_rtx
.xyz
, transform_rty
.xyz
), float3(o
.p
, 1.0f
))
3158 * float2(transform_rtx
.w
, transform_rty
.w
);
3159 o
.position
= float4(position
+ float2(-1.0f
, 1.0f
), 0.0f
, 1.0f
);
3162 0x43425844, 0xde1911bf, 0xfff8c893, 0xb0bfc24d, 0x78c9bbc4, 0x00000001, 0x00000924, 0x00000003,
3163 0x0000002c, 0x000000e4, 0x000001a0, 0x4e475349, 0x000000b0, 0x00000006, 0x00000008, 0x00000098,
3164 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x000000a1, 0x00000000, 0x00000000,
3165 0x00000003, 0x00000001, 0x00000303, 0x000000a1, 0x00000001, 0x00000000, 0x00000003, 0x00000002,
3166 0x00000303, 0x000000a1, 0x00000002, 0x00000000, 0x00000003, 0x00000003, 0x00000303, 0x000000a3,
3167 0x00000000, 0x00000000, 0x00000003, 0x00000004, 0x00000303, 0x000000a8, 0x00000000, 0x00000000,
3168 0x00000003, 0x00000005, 0x00000303, 0x49534f50, 0x4e4f4954, 0x50005000, 0x00564552, 0x5458454e,
3169 0xababab00, 0x4e47534f, 0x000000b4, 0x00000005, 0x00000008, 0x00000080, 0x00000000, 0x00000000,
3170 0x00000003, 0x00000000, 0x00000c03, 0x0000008f, 0x00000000, 0x00000000, 0x00000003, 0x00000001,
3171 0x0000000f, 0x00000096, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x00000096,
3172 0x00000001, 0x00000000, 0x00000003, 0x00000003, 0x00000c03, 0x000000a7, 0x00000000, 0x00000001,
3173 0x00000003, 0x00000004, 0x0000000f, 0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45,
3174 0x54530052, 0x454b4f52, 0x4152545f, 0x4f46534e, 0x53004d52, 0x4f505f56, 0x49544953, 0xab004e4f,
3175 0x52444853, 0x0000077c, 0x00010040, 0x000001df, 0x04000059, 0x00208e46, 0x00000000, 0x00000004,
3176 0x0300005f, 0x00101032, 0x00000000, 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x00101032,
3177 0x00000002, 0x0300005f, 0x00101032, 0x00000003, 0x0300005f, 0x00101032, 0x00000004, 0x0300005f,
3178 0x00101032, 0x00000005, 0x03000065, 0x00102032, 0x00000000, 0x03000065, 0x001020f2, 0x00000001,
3179 0x03000065, 0x00102032, 0x00000002, 0x03000065, 0x00102032, 0x00000003, 0x04000067, 0x001020f2,
3180 0x00000004, 0x00000001, 0x02000068, 0x00000004, 0x0800000f, 0x00100012, 0x00000000, 0x00208046,
3181 0x00000000, 0x00000000, 0x00101046, 0x00000005, 0x0800000f, 0x00100022, 0x00000000, 0x00208046,
3182 0x00000000, 0x00000001, 0x00101046, 0x00000005, 0x0700000f, 0x00100042, 0x00000000, 0x00100046,
3183 0x00000000, 0x00100046, 0x00000000, 0x05000044, 0x00100042, 0x00000000, 0x0010002a, 0x00000000,
3184 0x07000038, 0x00100032, 0x00000000, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x0800000f,
3185 0x00100012, 0x00000001, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000004, 0x0800000f,
3186 0x00100022, 0x00000001, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000004, 0x0700000f,
3187 0x00100042, 0x00000000, 0x00100046, 0x00000001, 0x00100046, 0x00000001, 0x05000044, 0x00100042,
3188 0x00000000, 0x0010002a, 0x00000000, 0x07000038, 0x00100032, 0x00000001, 0x00100aa6, 0x00000000,
3189 0x00100046, 0x00000001, 0x06000036, 0x001000c2, 0x00000001, 0x80100556, 0x00000041, 0x00000001,
3190 0x0700000f, 0x00100042, 0x00000000, 0x00100a26, 0x00000001, 0x00100046, 0x00000000, 0x0700000f,
3191 0x00100012, 0x00000000, 0x00100046, 0x00000001, 0x00100046, 0x00000000, 0x07000000, 0x00100012,
3192 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0800000e, 0x00100012, 0x00000000,
3193 0x8010002a, 0x00000041, 0x00000000, 0x0010000a, 0x00000000, 0x09000032, 0x00100032, 0x00000000,
3194 0x00100006, 0x00000000, 0x00100046, 0x00000001, 0x00100f36, 0x00000001, 0x05000036, 0x00100032,
3195 0x00000001, 0x00101046, 0x00000000, 0x05000036, 0x00100042, 0x00000001, 0x00004001, 0x3f800000,
3196 0x08000010, 0x00100012, 0x00000002, 0x00100246, 0x00000001, 0x00208246, 0x00000000, 0x00000000,
3197 0x08000010, 0x00100022, 0x00000002, 0x00100246, 0x00000001, 0x00208246, 0x00000000, 0x00000001,
3198 0x08000038, 0x00100042, 0x00000000, 0x0020803a, 0x00000000, 0x00000001, 0x00004001, 0x3f000000,
3199 0x09000032, 0x00100032, 0x00000001, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x00100046,
3200 0x00000002, 0x05000036, 0x00102032, 0x00000000, 0x00100046, 0x00000001, 0x0800000f, 0x00100012,
3201 0x00000002, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000000, 0x0800000f, 0x00100022,
3202 0x00000002, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000000, 0x0800000f, 0x00100022,
3203 0x00000003, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000001, 0x0800000f, 0x00100012,
3204 0x00000003, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000001, 0x08000000, 0x00100032,
3205 0x00000002, 0x00100046, 0x00000002, 0x80100516, 0x00000041, 0x00000003, 0x09000032, 0x00100032,
3206 0x00000000, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000002, 0x0800000f,
3207 0x00100022, 0x00000002, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000003, 0x0800000f,
3208 0x00100012, 0x00000002, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000003, 0x08000000,
3209 0x001000c2, 0x00000000, 0x80100406, 0x00000041, 0x00000003, 0x00100406, 0x00000002, 0x0800000f,
3210 0x00100022, 0x00000002, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000002, 0x0800000f,
3211 0x00100012, 0x00000002, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000002, 0x08000000,
3212 0x00100032, 0x00000002, 0x80100046, 0x00000041, 0x00000003, 0x00100046, 0x00000002, 0x07000038,
3213 0x00100082, 0x00000001, 0x0010003a, 0x00000000, 0x0010000a, 0x00000002, 0x0a000032, 0x00100082,
3214 0x00000001, 0x0010001a, 0x00000002, 0x0010002a, 0x00000000, 0x8010003a, 0x00000041, 0x00000001,
3215 0x08000000, 0x00100042, 0x00000003, 0x0010002a, 0x00000000, 0x8010000a, 0x00000041, 0x00000002,
3216 0x08000000, 0x00100082, 0x00000003, 0x8010003a, 0x00000041, 0x00000000, 0x0010001a, 0x00000002,
3217 0x0a000038, 0x00100032, 0x00000003, 0x00100046, 0x00000002, 0x00004002, 0x3f800000, 0xbf800000,
3218 0x00000000, 0x00000000, 0x0700000e, 0x001000f2, 0x00000002, 0x00100e46, 0x00000003, 0x00100ff6,
3219 0x00000001, 0x0700000f, 0x00100012, 0x00000002, 0x00100046, 0x00000002, 0x00100046, 0x00000000,
3220 0x0700000f, 0x00100022, 0x00000002, 0x00100ae6, 0x00000002, 0x00100046, 0x00000000, 0x0a000000,
3221 0x00102032, 0x00000001, 0x00100046, 0x00000002, 0x00004002, 0x3f800000, 0x00000000, 0x00000000,
3222 0x00000000, 0x08000036, 0x001020c2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
3223 0x00000000, 0x06000036, 0x00100032, 0x00000000, 0x00208046, 0x00000000, 0x00000002, 0x06000036,
3224 0x001000c2, 0x00000000, 0x00208406, 0x00000000, 0x00000003, 0x08000038, 0x001000f2, 0x00000000,
3225 0x00100e46, 0x00000000, 0x00208ff6, 0x00000000, 0x00000001, 0x0a000038, 0x001000f2, 0x00000000,
3226 0x00100e46, 0x00000000, 0x00004002, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x05000036,
3227 0x00102032, 0x00000002, 0x00100086, 0x00000000, 0x05000036, 0x00102032, 0x00000003, 0x001005d6,
3228 0x00000000, 0x05000036, 0x00100042, 0x00000001, 0x00004001, 0x3f800000, 0x08000010, 0x00100012,
3229 0x00000000, 0x00208246, 0x00000000, 0x00000002, 0x00100246, 0x00000001, 0x08000010, 0x00100022,
3230 0x00000000, 0x00208246, 0x00000000, 0x00000003, 0x00100246, 0x00000001, 0x08000038, 0x00100022,
3231 0x00000001, 0x0010001a, 0x00000000, 0x0020803a, 0x00000000, 0x00000003, 0x08000038, 0x00100012,
3232 0x00000001, 0x0010000a, 0x00000000, 0x0020803a, 0x00000000, 0x00000002, 0x0a000000, 0x00102032,
3233 0x00000004, 0x00100046, 0x00000001, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000, 0x00000000,
3234 0x08000036, 0x001020c2, 0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,
3237 static const DWORD vs_code_triangle
[] =
3240 float3x2 transform_geometry
;
3241 float4 transform_rtx
;
3242 float4 transform_rty
;
3246 float2 p
: WORLD_POSITION
;
3248 nointerpolation float2x2 stroke_transform
: STROKE_TRANSFORM
;
3249 float4 position
: SV_POSITION
;
3252 void main(float2 position
: POSITION
, out
struct output o
)
3254 o
.p
= mul(float3(position
, 1.0f
), transform_geometry
);
3255 o
.b
= float4(1.0, 0.0, 1.0, 1.0);
3256 o
.stroke_transform
= float2x2(1.0, 0.0, 0.0, 1.0);
3257 position
= mul(float2x3(transform_rtx
.xyz
, transform_rty
.xyz
), float3(o
.p
, 1.0f
))
3258 * float2(transform_rtx
.w
, transform_rty
.w
);
3259 o
.position
= float4(position
+ float2(-1.0f
, 1.0f
), 0.0f
, 1.0f
);
3262 0x43425844, 0xda43bf17, 0x06e6d155, 0xdbce2ae5, 0x8aed6fd8, 0x00000001, 0x0000034c, 0x00000003,
3263 0x0000002c, 0x00000060, 0x0000011c, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
3264 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x49534f50, 0x4e4f4954, 0xababab00,
3265 0x4e47534f, 0x000000b4, 0x00000005, 0x00000008, 0x00000080, 0x00000000, 0x00000000, 0x00000003,
3266 0x00000000, 0x00000c03, 0x0000008f, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f,
3267 0x00000096, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x00000096, 0x00000001,
3268 0x00000000, 0x00000003, 0x00000003, 0x00000c03, 0x000000a7, 0x00000000, 0x00000001, 0x00000003,
3269 0x00000004, 0x0000000f, 0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, 0x54530052,
3270 0x454b4f52, 0x4152545f, 0x4f46534e, 0x53004d52, 0x4f505f56, 0x49544953, 0xab004e4f, 0x52444853,
3271 0x00000228, 0x00010040, 0x0000008a, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, 0x0300005f,
3272 0x00101032, 0x00000000, 0x03000065, 0x00102032, 0x00000000, 0x03000065, 0x001020f2, 0x00000001,
3273 0x03000065, 0x00102032, 0x00000002, 0x03000065, 0x00102032, 0x00000003, 0x04000067, 0x001020f2,
3274 0x00000004, 0x00000001, 0x02000068, 0x00000002, 0x05000036, 0x00100032, 0x00000000, 0x00101046,
3275 0x00000000, 0x05000036, 0x00100042, 0x00000000, 0x00004001, 0x3f800000, 0x08000010, 0x00100012,
3276 0x00000001, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x08000010, 0x00100022,
3277 0x00000001, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000001, 0x05000036, 0x00102032,
3278 0x00000000, 0x00100046, 0x00000001, 0x08000036, 0x001020f2, 0x00000001, 0x00004002, 0x3f800000,
3279 0x00000000, 0x3f800000, 0x3f800000, 0x08000036, 0x00102032, 0x00000002, 0x00004002, 0x3f800000,
3280 0x00000000, 0x00000000, 0x00000000, 0x08000036, 0x00102032, 0x00000003, 0x00004002, 0x00000000,
3281 0x3f800000, 0x00000000, 0x00000000, 0x05000036, 0x00100042, 0x00000001, 0x00004001, 0x3f800000,
3282 0x08000010, 0x00100012, 0x00000000, 0x00208246, 0x00000000, 0x00000002, 0x00100246, 0x00000001,
3283 0x08000010, 0x00100022, 0x00000000, 0x00208246, 0x00000000, 0x00000003, 0x00100246, 0x00000001,
3284 0x08000038, 0x00100022, 0x00000001, 0x0010001a, 0x00000000, 0x0020803a, 0x00000000, 0x00000003,
3285 0x08000038, 0x00100012, 0x00000001, 0x0010000a, 0x00000000, 0x0020803a, 0x00000000, 0x00000002,
3286 0x0a000000, 0x00102032, 0x00000004, 0x00100046, 0x00000001, 0x00004002, 0xbf800000, 0x3f800000,
3287 0x00000000, 0x00000000, 0x08000036, 0x001020c2, 0x00000004, 0x00004002, 0x00000000, 0x00000000,
3288 0x00000000, 0x3f800000, 0x0100003e,
3290 static const DWORD vs_code_curve
[] =
3293 float3x2 transform_geometry
;
3294 float4 transform_rtx
;
3295 float4 transform_rty
;
3299 float2 p
: WORLD_POSITION
;
3301 nointerpolation float2x2 stroke_transform
: STROKE_TRANSFORM
;
3302 float4 position
: SV_POSITION
;
3305 void main(float2 position
: POSITION
, float3 texcoord
: TEXCOORD0
, out
struct output o
)
3307 o
.p
= mul(float3(position
, 1.0f
), transform_geometry
);
3308 o
.b
= float4(texcoord
, 1.0);
3309 o
.stroke_transform
= float2x2(1.0, 0.0, 0.0, 1.0);
3310 position
= mul(float2x3(transform_rtx
.xyz
, transform_rty
.xyz
), float3(o
.p
, 1.0f
))
3311 * float2(transform_rtx
.w
, transform_rty
.w
);
3312 o
.position
= float4(position
+ float2(-1.0f
, 1.0f
), 0.0f
, 1.0f
);
3315 0x43425844, 0xedb7472a, 0x2c2ea147, 0x36710079, 0xffc2e907, 0x00000001, 0x00000380, 0x00000003,
3316 0x0000002c, 0x00000080, 0x0000013c, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
3317 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x00000041, 0x00000000, 0x00000000,
3318 0x00000003, 0x00000001, 0x00000707, 0x49534f50, 0x4e4f4954, 0x58455400, 0x524f4f43, 0xabab0044,
3319 0x4e47534f, 0x000000b4, 0x00000005, 0x00000008, 0x00000080, 0x00000000, 0x00000000, 0x00000003,
3320 0x00000000, 0x00000c03, 0x0000008f, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f,
3321 0x00000096, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x00000096, 0x00000001,
3322 0x00000000, 0x00000003, 0x00000003, 0x00000c03, 0x000000a7, 0x00000000, 0x00000001, 0x00000003,
3323 0x00000004, 0x0000000f, 0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, 0x54530052,
3324 0x454b4f52, 0x4152545f, 0x4f46534e, 0x53004d52, 0x4f505f56, 0x49544953, 0xab004e4f, 0x52444853,
3325 0x0000023c, 0x00010040, 0x0000008f, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, 0x0300005f,
3326 0x00101032, 0x00000000, 0x0300005f, 0x00101072, 0x00000001, 0x03000065, 0x00102032, 0x00000000,
3327 0x03000065, 0x001020f2, 0x00000001, 0x03000065, 0x00102032, 0x00000002, 0x03000065, 0x00102032,
3328 0x00000003, 0x04000067, 0x001020f2, 0x00000004, 0x00000001, 0x02000068, 0x00000002, 0x05000036,
3329 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x05000036, 0x00100042, 0x00000000, 0x00004001,
3330 0x3f800000, 0x08000010, 0x00100012, 0x00000001, 0x00100246, 0x00000000, 0x00208246, 0x00000000,
3331 0x00000000, 0x08000010, 0x00100022, 0x00000001, 0x00100246, 0x00000000, 0x00208246, 0x00000000,
3332 0x00000001, 0x05000036, 0x00102032, 0x00000000, 0x00100046, 0x00000001, 0x05000036, 0x00102072,
3333 0x00000001, 0x00101246, 0x00000001, 0x05000036, 0x00102082, 0x00000001, 0x00004001, 0x3f800000,
3334 0x08000036, 0x00102032, 0x00000002, 0x00004002, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,
3335 0x08000036, 0x00102032, 0x00000003, 0x00004002, 0x00000000, 0x3f800000, 0x00000000, 0x00000000,
3336 0x05000036, 0x00100042, 0x00000001, 0x00004001, 0x3f800000, 0x08000010, 0x00100012, 0x00000000,
3337 0x00208246, 0x00000000, 0x00000002, 0x00100246, 0x00000001, 0x08000010, 0x00100022, 0x00000000,
3338 0x00208246, 0x00000000, 0x00000003, 0x00100246, 0x00000001, 0x08000038, 0x00100022, 0x00000001,
3339 0x0010001a, 0x00000000, 0x0020803a, 0x00000000, 0x00000003, 0x08000038, 0x00100012, 0x00000001,
3340 0x0010000a, 0x00000000, 0x0020803a, 0x00000000, 0x00000002, 0x0a000000, 0x00102032, 0x00000004,
3341 0x00100046, 0x00000001, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000, 0x00000000, 0x08000036,
3342 0x001020c2, 0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e,
3344 static const DWORD ps_code
[] =
3347 #define BRUSH_TYPE_SOLID 0
3348 #define BRUSH_TYPE_LINEAR 1
3349 #define BRUSH_TYPE_RADIAL 2
3350 #define BRUSH_TYPE_BITMAP 3
3351 #define BRUSH_TYPE_COUNT 4
3360 } colour_brush
, opacity_brush
;
3362 SamplerState s0
, s1
;
3364 Buffer
<float4
> b0
, b1
;
3368 float2 p
: WORLD_POSITION
;
3370 nointerpolation float2x2 stroke_transform
: STROKE_TRANSFORM
;
3373 float4
sample_gradient(Buffer
<float4
> gradient
, uint stop_count
, float position
)
3375 float4 c_low
, c_high
;
3376 float p_low
, p_high
;
3379 p_low
= gradient
.Load(0).x
;
3380 c_low
= gradient
.Load(1);
3383 if (position
< p_low
)
3386 for (i
= 1; i
< stop_count
; ++i
)
3388 p_high
= gradient
.Load(i
* 2).x
;
3389 c_high
= gradient
.Load(i
* 2 + 1);
3391 if (position
>= p_low
&& position
<= p_high
)
3392 return lerp(c_low
, c_high
, (position
- p_low
) / (p_high
- p_low
));
3401 float4
brush_linear(struct brush brush
, Buffer
<float4
> gradient
, float2 position
)
3403 float2 start
, end
, v_p
, v_q
;
3407 start
= brush
.data
[0].xy
;
3408 end
= brush
.data
[0].zw
;
3409 stop_count
= asuint(brush
.data
[1].x
);
3411 v_p
= position
- start
;
3413 p
= dot(v_q
, v_p
) / dot(v_q
, v_q
);
3415 return sample_gradient(gradient
, stop_count
, p
);
3418 float4
brush_radial(struct brush brush
, Buffer
<float4
> gradient
, float2 position
)
3420 float2 centre
, offset
, ra
, rb
, v_p
, v_q
, r
;
3424 centre
= brush
.data
[0].xy
;
3425 offset
= brush
.data
[0].zw
;
3426 ra
= brush
.data
[1].xy
;
3427 rb
= brush
.data
[1].zw
;
3428 stop_count
= asuint(brush
.data
[2].x
);
3430 /* Project onto ra, rb. */
3431 r
= float2(dot(ra
, ra
), dot(rb
, rb
));
3432 v_p
= position
- (centre
+ offset
);
3433 v_p
= float2(dot(v_p
, ra
), dot(v_p
, rb
)) / r
;
3434 v_q
= float2(dot(offset
, ra
), dot(offset
, rb
)) / r
;
3437 * (t·p̂ + q⃑) · (t·p̂ + q⃑) = 1
3438 * t² + 2·(p̂·q⃑)·t + (q⃑·q⃑) = 1
3442 * t = -b + √(b² - c) */
3444 b
= dot(v_p
, v_q
) / l
;
3445 c
= dot(v_q
, v_q
) - 1.0;
3446 t
= -b
+ sqrt(b
* b
- c
);
3448 return sample_gradient(gradient
, stop_count
, l
/ t
);
3451 float4
brush_bitmap(struct brush brush
, Texture2D t
, SamplerState s
, float2 position
)
3453 float3 transform
[2];
3458 transform
[0] = brush
.data
[0].xyz
;
3459 transform
[1] = brush
.data
[1].xyz
;
3460 ignore_alpha
= asuint(brush
.data
[1].w
);
3462 texcoord
.x
= dot(position
.xy
, transform
[0].xy
) + transform
[0].z
;
3463 texcoord
.y
= dot(position
.xy
, transform
[1].xy
) + transform
[1].z
;
3464 colour
= t
.Sample(s
, texcoord
);
3470 float4
sample_brush(struct brush brush
, Texture2D t
, SamplerState s
, Buffer
<float4
> b
, float2 position
)
3472 if (brush
.type
== BRUSH_TYPE_SOLID
)
3473 return brush
.data
[0] * brush
.opacity
;
3474 if (brush
.type
== BRUSH_TYPE_LINEAR
)
3475 return brush_linear(brush
, b
, position
) * brush
.opacity
;
3476 if (brush
.type
== BRUSH_TYPE_RADIAL
)
3477 return brush_radial(brush
, b
, position
) * brush
.opacity
;
3478 if (brush
.type
== BRUSH_TYPE_BITMAP
)
3479 return brush_bitmap(brush
, t
, s
, position
) * brush
.opacity
;
3480 return float4(0.0, 0.0, 0.0, brush
.opacity
);
3483 float4
main(struct input i
) : SV_Target
3487 colour
= sample_brush(colour_brush
, t0
, s0
, b0
, i
.p
);
3488 if (opacity_brush
.type
< BRUSH_TYPE_COUNT
)
3489 colour
*= sample_brush(opacity_brush
, t1
, s1
, b1
, i
.p
).a
;
3496 /* Evaluate the implicit form of the curve (u² - v = 0
3497 * for Béziers, u² + v² - 1 = 0 for arcs) in texture
3498 * space, using the screen-space partial derivatives
3499 * to convert the calculated distance to object space.
3501 * d(x, y) = |f(x, y)| / ‖∇f(x, y)‖
3502 * = |f(x, y)| / √((∂f/∂x)² + (∂f/∂y)²)
3505 * f(x, y) = u(x, y)² - v(x, y)
3506 * ∂f/∂x = 2u · ∂u/∂x - ∂v/∂x
3507 * ∂f/∂y = 2u · ∂u/∂y - ∂v/∂y
3510 * f(x, y) = u(x, y)² + v(x, y)² - 1
3511 * ∂f/∂x = 2u · ∂u/∂x + 2v · ∂v/∂x
3512 * ∂f/∂y = 2u · ∂u/∂y + 2v · ∂v/∂y */
3514 du
= float2(ddx(uv
.x
), ddy(uv
.x
));
3515 dv
= float2(ddx(uv
.y
), ddy(uv
.y
));
3519 df
= 2.0f
* uv
.x
* du
- dv
;
3521 clip(dot(df
, uv
.zw
));
3522 clip(length(mul(i
.stroke_transform
, df
)) - abs(uv
.x
* uv
.x
- uv
.y
));
3526 df
= 2.0f
* uv
.x
* du
+ 2.0f
* uv
.y
* dv
;
3528 clip(dot(df
, uv
.zw
));
3529 clip(length(mul(i
.stroke_transform
, df
)) - abs(uv
.x
* uv
.x
+ uv
.y
* uv
.y
- 1.0f
));
3534 /* Evaluate the implicit form of the curve in texture space.
3535 * "i.b.z" determines which side of the curve is shaded. */
3538 clip((i
.b
.x
* i
.b
.x
- i
.b
.y
) * i
.b
.z
);
3542 clip((i
.b
.x
* i
.b
.x
+ i
.b
.y
* i
.b
.y
- 1.0) * i
.b
.z
);
3549 0x43425844, 0xa8fee730, 0x92fa2196, 0xaf9f3eff, 0x888d4048, 0x00000001, 0x00002000, 0x00000003,
3550 0x0000002c, 0x000000c4, 0x000000f8, 0x4e475349, 0x00000090, 0x00000004, 0x00000008, 0x00000068,
3551 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x00000077, 0x00000000, 0x00000000,
3552 0x00000003, 0x00000001, 0x00000f0f, 0x0000007e, 0x00000000, 0x00000000, 0x00000003, 0x00000002,
3553 0x00000303, 0x0000007e, 0x00000001, 0x00000000, 0x00000003, 0x00000003, 0x00000303, 0x4c524f57,
3554 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, 0x54530052, 0x454b4f52, 0x4152545f, 0x4f46534e,
3555 0xab004d52, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
3556 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00001f00,
3557 0x00000040, 0x000007c0, 0x04000059, 0x00208e46, 0x00000000, 0x00000009, 0x0300005a, 0x00106000,
3558 0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555,
3559 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04000858, 0x00107000, 0x00000002, 0x00005555,
3560 0x04000858, 0x00107000, 0x00000003, 0x00005555, 0x03001062, 0x00101032, 0x00000000, 0x03001062,
3561 0x001010f2, 0x00000001, 0x03000862, 0x00101032, 0x00000002, 0x03000862, 0x00101032, 0x00000003,
3562 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x0000000a, 0x09000038, 0x001000f2, 0x00000000,
3563 0x00208556, 0x00000000, 0x00000001, 0x00208e46, 0x00000000, 0x00000002, 0x0404001f, 0x0020800a,
3564 0x00000000, 0x00000001, 0x08000020, 0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000001,
3565 0x00004001, 0x00000001, 0x0304001f, 0x0010000a, 0x00000001, 0x09000000, 0x00100062, 0x00000001,
3566 0x00101106, 0x00000000, 0x80208106, 0x00000041, 0x00000000, 0x00000002, 0x0a000000, 0x00100032,
3567 0x00000002, 0x80208046, 0x00000041, 0x00000000, 0x00000002, 0x00208ae6, 0x00000000, 0x00000002,
3568 0x0700000f, 0x00100022, 0x00000001, 0x00100046, 0x00000002, 0x00100596, 0x00000001, 0x0700000f,
3569 0x00100042, 0x00000001, 0x00100046, 0x00000002, 0x00100046, 0x00000002, 0x0700000e, 0x00100022,
3570 0x00000001, 0x0010001a, 0x00000001, 0x0010002a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000002,
3571 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000002, 0x0a00002d,
3572 0x001000f2, 0x00000003, 0x00004002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00107e46,
3573 0x00000002, 0x0700001d, 0x00100042, 0x00000001, 0x0010001a, 0x00000001, 0x0010000a, 0x00000002,
3574 0x0304001f, 0x0010002a, 0x00000001, 0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000003,
3575 0x05000036, 0x001000f2, 0x00000005, 0x00100e46, 0x00000003, 0x05000036, 0x001000f2, 0x00000006,
3576 0x00100e46, 0x00000003, 0x05000036, 0x00100042, 0x00000001, 0x0010000a, 0x00000002, 0x05000036,
3577 0x00100082, 0x00000001, 0x00004001, 0x00000001, 0x05000036, 0x00100022, 0x00000002, 0x00004001,
3578 0x00000000, 0x01000030, 0x08000050, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x0020800a,
3579 0x00000000, 0x00000003, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0x00000000, 0x03040003,
3580 0x0010002a, 0x00000002, 0x07000029, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x00004001,
3581 0x00000001, 0x0700002d, 0x001000f2, 0x00000007, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002,
3582 0x0700001e, 0x00100042, 0x00000002, 0x0010002a, 0x00000002, 0x00004001, 0x00000001, 0x0700002d,
3583 0x001000f2, 0x00000008, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002, 0x0700001d, 0x00100042,
3584 0x00000002, 0x0010001a, 0x00000001, 0x0010002a, 0x00000001, 0x0700001d, 0x00100082, 0x00000002,
3585 0x0010000a, 0x00000007, 0x0010001a, 0x00000001, 0x07000001, 0x00100042, 0x00000002, 0x0010003a,
3586 0x00000002, 0x0010002a, 0x00000002, 0x0304001f, 0x0010002a, 0x00000002, 0x08000000, 0x00100082,
3587 0x00000002, 0x8010002a, 0x00000041, 0x00000001, 0x0010001a, 0x00000001, 0x08000000, 0x00100022,
3588 0x00000007, 0x8010002a, 0x00000041, 0x00000001, 0x0010000a, 0x00000007, 0x0700000e, 0x00100082,
3589 0x00000002, 0x0010003a, 0x00000002, 0x0010001a, 0x00000007, 0x08000000, 0x001000f2, 0x00000009,
3590 0x80100e46, 0x00000041, 0x00000005, 0x00100e46, 0x00000008, 0x09000032, 0x001000f2, 0x00000009,
3591 0x00100ff6, 0x00000002, 0x00100e46, 0x00000009, 0x00100e46, 0x00000005, 0x05000036, 0x001000f2,
3592 0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0xffffffff,
3593 0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000009, 0x01000002, 0x01000015, 0x05000036,
3594 0x001000f2, 0x00000005, 0x00100e46, 0x00000008, 0x05000036, 0x00100042, 0x00000001, 0x0010000a,
3595 0x00000007, 0x0700001e, 0x00100082, 0x00000001, 0x0010003a, 0x00000001, 0x00004001, 0x00000001,
3596 0x05000036, 0x001000f2, 0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002,
3597 0x0010002a, 0x00000002, 0x01000016, 0x09000037, 0x001000f2, 0x00000003, 0x00100556, 0x00000002,
3598 0x00100e46, 0x00000004, 0x00100e46, 0x00000006, 0x01000015, 0x08000038, 0x001000f2, 0x00000000,
3599 0x00100e46, 0x00000003, 0x00208556, 0x00000000, 0x00000001, 0x01000015, 0x0300001f, 0x0010000a,
3600 0x00000001, 0x08000020, 0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000001, 0x00004001,
3601 0x00000002, 0x0304001f, 0x0010000a, 0x00000001, 0x0900000f, 0x00100012, 0x00000002, 0x00208046,
3602 0x00000000, 0x00000003, 0x00208046, 0x00000000, 0x00000003, 0x0900000f, 0x00100022, 0x00000002,
3603 0x00208ae6, 0x00000000, 0x00000003, 0x00208ae6, 0x00000000, 0x00000003, 0x09000000, 0x00100062,
3604 0x00000001, 0x00208ba6, 0x00000000, 0x00000002, 0x00208106, 0x00000000, 0x00000002, 0x08000000,
3605 0x00100062, 0x00000001, 0x80100656, 0x00000041, 0x00000001, 0x00101106, 0x00000000, 0x0800000f,
3606 0x00100012, 0x00000003, 0x00100596, 0x00000001, 0x00208046, 0x00000000, 0x00000003, 0x0800000f,
3607 0x00100022, 0x00000003, 0x00100596, 0x00000001, 0x00208ae6, 0x00000000, 0x00000003, 0x0700000e,
3608 0x00100062, 0x00000001, 0x00100106, 0x00000003, 0x00100106, 0x00000002, 0x0900000f, 0x00100012,
3609 0x00000003, 0x00208ae6, 0x00000000, 0x00000002, 0x00208046, 0x00000000, 0x00000003, 0x0900000f,
3610 0x00100022, 0x00000003, 0x00208ae6, 0x00000000, 0x00000002, 0x00208ae6, 0x00000000, 0x00000003,
3611 0x0700000e, 0x00100032, 0x00000002, 0x00100046, 0x00000003, 0x00100046, 0x00000002, 0x0700000f,
3612 0x00100082, 0x00000001, 0x00100596, 0x00000001, 0x00100596, 0x00000001, 0x0500004b, 0x00100082,
3613 0x00000001, 0x0010003a, 0x00000001, 0x0700000f, 0x00100022, 0x00000001, 0x00100596, 0x00000001,
3614 0x00100046, 0x00000002, 0x0700000e, 0x00100022, 0x00000001, 0x0010001a, 0x00000001, 0x0010003a,
3615 0x00000001, 0x0700000f, 0x00100042, 0x00000001, 0x00100046, 0x00000002, 0x00100046, 0x00000002,
3616 0x07000000, 0x00100042, 0x00000001, 0x0010002a, 0x00000001, 0x00004001, 0xbf800000, 0x0a000032,
3617 0x00100042, 0x00000001, 0x0010001a, 0x00000001, 0x0010001a, 0x00000001, 0x8010002a, 0x00000041,
3618 0x00000001, 0x0500004b, 0x00100042, 0x00000001, 0x0010002a, 0x00000001, 0x08000000, 0x00100022,
3619 0x00000001, 0x0010002a, 0x00000001, 0x8010001a, 0x00000041, 0x00000001, 0x0700000e, 0x00100022,
3620 0x00000001, 0x0010003a, 0x00000001, 0x0010001a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000002,
3621 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000002, 0x0a00002d,
3622 0x001000f2, 0x00000003, 0x00004002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00107e46,
3623 0x00000002, 0x0700001d, 0x00100042, 0x00000001, 0x0010001a, 0x00000001, 0x0010000a, 0x00000002,
3624 0x0304001f, 0x0010002a, 0x00000001, 0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000003,
3625 0x05000036, 0x001000f2, 0x00000005, 0x00100e46, 0x00000003, 0x05000036, 0x001000f2, 0x00000006,
3626 0x00100e46, 0x00000003, 0x05000036, 0x00100042, 0x00000001, 0x0010000a, 0x00000002, 0x05000036,
3627 0x00100082, 0x00000001, 0x00004001, 0x00000001, 0x05000036, 0x00100022, 0x00000002, 0x00004001,
3628 0x00000000, 0x01000030, 0x08000050, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x0020800a,
3629 0x00000000, 0x00000004, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0x00000000, 0x03040003,
3630 0x0010002a, 0x00000002, 0x07000029, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x00004001,
3631 0x00000001, 0x0700002d, 0x001000f2, 0x00000007, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002,
3632 0x0700001e, 0x00100042, 0x00000002, 0x0010002a, 0x00000002, 0x00004001, 0x00000001, 0x0700002d,
3633 0x001000f2, 0x00000008, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002, 0x0700001d, 0x00100042,
3634 0x00000002, 0x0010001a, 0x00000001, 0x0010002a, 0x00000001, 0x0700001d, 0x00100082, 0x00000002,
3635 0x0010000a, 0x00000007, 0x0010001a, 0x00000001, 0x07000001, 0x00100042, 0x00000002, 0x0010003a,
3636 0x00000002, 0x0010002a, 0x00000002, 0x0304001f, 0x0010002a, 0x00000002, 0x08000000, 0x00100082,
3637 0x00000002, 0x8010002a, 0x00000041, 0x00000001, 0x0010001a, 0x00000001, 0x08000000, 0x00100022,
3638 0x00000007, 0x8010002a, 0x00000041, 0x00000001, 0x0010000a, 0x00000007, 0x0700000e, 0x00100082,
3639 0x00000002, 0x0010003a, 0x00000002, 0x0010001a, 0x00000007, 0x08000000, 0x001000f2, 0x00000009,
3640 0x80100e46, 0x00000041, 0x00000005, 0x00100e46, 0x00000008, 0x09000032, 0x001000f2, 0x00000009,
3641 0x00100ff6, 0x00000002, 0x00100e46, 0x00000009, 0x00100e46, 0x00000005, 0x05000036, 0x001000f2,
3642 0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0xffffffff,
3643 0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000009, 0x01000002, 0x01000015, 0x05000036,
3644 0x001000f2, 0x00000005, 0x00100e46, 0x00000008, 0x05000036, 0x00100042, 0x00000001, 0x0010000a,
3645 0x00000007, 0x0700001e, 0x00100082, 0x00000001, 0x0010003a, 0x00000001, 0x00004001, 0x00000001,
3646 0x05000036, 0x001000f2, 0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002,
3647 0x0010002a, 0x00000002, 0x01000016, 0x09000037, 0x001000f2, 0x00000003, 0x00100556, 0x00000002,
3648 0x00100e46, 0x00000004, 0x00100e46, 0x00000006, 0x01000015, 0x08000038, 0x001000f2, 0x00000000,
3649 0x00100e46, 0x00000003, 0x00208556, 0x00000000, 0x00000001, 0x01000015, 0x0300001f, 0x0010000a,
3650 0x00000001, 0x08000020, 0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000001, 0x00004001,
3651 0x00000003, 0x0304001f, 0x0010000a, 0x00000001, 0x0800000f, 0x00100022, 0x00000001, 0x00101046,
3652 0x00000000, 0x00208046, 0x00000000, 0x00000002, 0x08000000, 0x00100012, 0x00000002, 0x0010001a,
3653 0x00000001, 0x0020802a, 0x00000000, 0x00000002, 0x0800000f, 0x00100022, 0x00000001, 0x00101046,
3654 0x00000000, 0x00208046, 0x00000000, 0x00000003, 0x08000000, 0x00100022, 0x00000002, 0x0010001a,
3655 0x00000001, 0x0020802a, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000002, 0x00100046,
3656 0x00000002, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000037, 0x00100082, 0x00000002,
3657 0x0020803a, 0x00000000, 0x00000003, 0x00004001, 0x3f800000, 0x0010003a, 0x00000002, 0x08000038,
3658 0x001000f2, 0x00000000, 0x00100e46, 0x00000002, 0x00208556, 0x00000000, 0x00000001, 0x01000015,
3659 0x05000036, 0x00100012, 0x00000002, 0x00004001, 0x00000000, 0x06000036, 0x00100082, 0x00000002,
3660 0x0020801a, 0x00000000, 0x00000001, 0x09000037, 0x001000f2, 0x00000000, 0x00100006, 0x00000001,
3661 0x00100e46, 0x00000000, 0x00100c06, 0x00000002, 0x01000015, 0x01000015, 0x01000015, 0x0800004f,
3662 0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000005, 0x00004001, 0x00000004, 0x0304001f,
3663 0x0010000a, 0x00000001, 0x09000038, 0x00100012, 0x00000001, 0x0020801a, 0x00000000, 0x00000005,
3664 0x0020803a, 0x00000000, 0x00000006, 0x0404001f, 0x0020800a, 0x00000000, 0x00000005, 0x08000020,
3665 0x00100022, 0x00000001, 0x0020800a, 0x00000000, 0x00000005, 0x00004001, 0x00000001, 0x0304001f,
3666 0x0010001a, 0x00000001, 0x09000000, 0x001000c2, 0x00000001, 0x00101406, 0x00000000, 0x80208406,
3667 0x00000041, 0x00000000, 0x00000006, 0x0a000000, 0x00100032, 0x00000002, 0x80208046, 0x00000041,
3668 0x00000000, 0x00000006, 0x00208ae6, 0x00000000, 0x00000006, 0x0700000f, 0x00100042, 0x00000001,
3669 0x00100046, 0x00000002, 0x00100ae6, 0x00000001, 0x0700000f, 0x00100082, 0x00000001, 0x00100046,
3670 0x00000002, 0x00100046, 0x00000002, 0x0700000e, 0x00100042, 0x00000001, 0x0010002a, 0x00000001,
3671 0x0010003a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000002, 0x00004002, 0x00000000, 0x00000000,
3672 0x00000000, 0x00000000, 0x00107e46, 0x00000003, 0x0a00002d, 0x001000f2, 0x00000003, 0x00004002,
3673 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00107e46, 0x00000003, 0x0700001d, 0x00100082,
3674 0x00000001, 0x0010002a, 0x00000001, 0x0010000a, 0x00000002, 0x0304001f, 0x0010003a, 0x00000001,
3675 0x05000036, 0x00100082, 0x00000001, 0x0010003a, 0x00000003, 0x05000036, 0x00100062, 0x00000002,
3676 0x00100ff6, 0x00000003, 0x05000036, 0x00100082, 0x00000002, 0x0010000a, 0x00000002, 0x08000036,
3677 0x00100032, 0x00000003, 0x00004002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x01000030,
3678 0x08000050, 0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x0020800a, 0x00000000, 0x00000007,
3679 0x05000036, 0x00100022, 0x00000003, 0x00004001, 0x00000000, 0x03040003, 0x0010002a, 0x00000003,
3680 0x07000029, 0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d,
3681 0x001000f2, 0x00000004, 0x00100aa6, 0x00000003, 0x00107e46, 0x00000003, 0x0700001e, 0x00100042,
3682 0x00000003, 0x0010002a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d, 0x001000f2, 0x00000005,
3683 0x00100aa6, 0x00000003, 0x00107e46, 0x00000003, 0x0700001d, 0x00100042, 0x00000003, 0x0010002a,
3684 0x00000001, 0x0010003a, 0x00000002, 0x0700001d, 0x00100022, 0x00000004, 0x0010000a, 0x00000004,
3685 0x0010002a, 0x00000001, 0x07000001, 0x00100042, 0x00000003, 0x0010002a, 0x00000003, 0x0010001a,
3686 0x00000004, 0x0304001f, 0x0010002a, 0x00000003, 0x08000000, 0x00100022, 0x00000004, 0x0010002a,
3687 0x00000001, 0x8010003a, 0x00000041, 0x00000002, 0x08000000, 0x00100042, 0x00000004, 0x8010003a,
3688 0x00000041, 0x00000002, 0x0010000a, 0x00000004, 0x0700000e, 0x00100022, 0x00000004, 0x0010001a,
3689 0x00000004, 0x0010002a, 0x00000004, 0x08000000, 0x00100042, 0x00000004, 0x8010001a, 0x00000041,
3690 0x00000002, 0x0010003a, 0x00000005, 0x09000032, 0x00100022, 0x00000004, 0x0010001a, 0x00000004,
3691 0x0010002a, 0x00000004, 0x0010001a, 0x00000002, 0x05000036, 0x00100042, 0x00000002, 0x0010003a,
3692 0x00000005, 0x05000036, 0x00100022, 0x00000003, 0x00004001, 0xffffffff, 0x05000036, 0x00100082,
3693 0x00000001, 0x0010001a, 0x00000004, 0x01000002, 0x01000015, 0x05000036, 0x00100022, 0x00000002,
3694 0x0010003a, 0x00000005, 0x05000036, 0x00100082, 0x00000002, 0x0010000a, 0x00000004, 0x0700001e,
3695 0x00100012, 0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x05000036, 0x00100042,
3696 0x00000002, 0x0010003a, 0x00000005, 0x05000036, 0x00100032, 0x00000003, 0x00100086, 0x00000003,
3697 0x01000016, 0x09000037, 0x00100042, 0x00000001, 0x0010001a, 0x00000003, 0x0010003a, 0x00000001,
3698 0x0010002a, 0x00000002, 0x01000012, 0x05000036, 0x00100042, 0x00000001, 0x0010003a, 0x00000003,
3699 0x01000015, 0x08000038, 0x00100012, 0x00000001, 0x0010002a, 0x00000001, 0x0020801a, 0x00000000,
3700 0x00000005, 0x01000015, 0x0300001f, 0x0010001a, 0x00000001, 0x08000020, 0x00100022, 0x00000001,
3701 0x0020800a, 0x00000000, 0x00000005, 0x00004001, 0x00000002, 0x0304001f, 0x0010001a, 0x00000001,
3702 0x0900000f, 0x00100012, 0x00000002, 0x00208046, 0x00000000, 0x00000007, 0x00208046, 0x00000000,
3703 0x00000007, 0x0900000f, 0x00100022, 0x00000002, 0x00208ae6, 0x00000000, 0x00000007, 0x00208ae6,
3704 0x00000000, 0x00000007, 0x09000000, 0x001000c2, 0x00000001, 0x00208ea6, 0x00000000, 0x00000006,
3705 0x00208406, 0x00000000, 0x00000006, 0x08000000, 0x001000c2, 0x00000001, 0x80100ea6, 0x00000041,
3706 0x00000001, 0x00101406, 0x00000000, 0x0800000f, 0x00100012, 0x00000003, 0x00100ae6, 0x00000001,
3707 0x00208046, 0x00000000, 0x00000007, 0x0800000f, 0x00100022, 0x00000003, 0x00100ae6, 0x00000001,
3708 0x00208ae6, 0x00000000, 0x00000007, 0x0700000e, 0x001000c2, 0x00000001, 0x00100406, 0x00000003,
3709 0x00100406, 0x00000002, 0x0900000f, 0x00100012, 0x00000003, 0x00208ae6, 0x00000000, 0x00000006,
3710 0x00208046, 0x00000000, 0x00000007, 0x0900000f, 0x00100022, 0x00000003, 0x00208ae6, 0x00000000,
3711 0x00000006, 0x00208ae6, 0x00000000, 0x00000007, 0x0700000e, 0x00100032, 0x00000002, 0x00100046,
3712 0x00000003, 0x00100046, 0x00000002, 0x0700000f, 0x00100042, 0x00000002, 0x00100ae6, 0x00000001,
3713 0x00100ae6, 0x00000001, 0x0500004b, 0x00100042, 0x00000002, 0x0010002a, 0x00000002, 0x0700000f,
3714 0x00100042, 0x00000001, 0x00100ae6, 0x00000001, 0x00100046, 0x00000002, 0x0700000e, 0x00100042,
3715 0x00000001, 0x0010002a, 0x00000001, 0x0010002a, 0x00000002, 0x0700000f, 0x00100082, 0x00000001,
3716 0x00100046, 0x00000002, 0x00100046, 0x00000002, 0x07000000, 0x00100082, 0x00000001, 0x0010003a,
3717 0x00000001, 0x00004001, 0xbf800000, 0x0a000032, 0x00100082, 0x00000001, 0x0010002a, 0x00000001,
3718 0x0010002a, 0x00000001, 0x8010003a, 0x00000041, 0x00000001, 0x0500004b, 0x00100082, 0x00000001,
3719 0x0010003a, 0x00000001, 0x08000000, 0x00100042, 0x00000001, 0x0010003a, 0x00000001, 0x8010002a,
3720 0x00000041, 0x00000001, 0x0700000e, 0x00100042, 0x00000001, 0x0010002a, 0x00000002, 0x0010002a,
3721 0x00000001, 0x0a00002d, 0x001000f2, 0x00000002, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
3722 0x00000000, 0x00107e46, 0x00000003, 0x0a00002d, 0x001000f2, 0x00000003, 0x00004002, 0x00000001,
3723 0x00000001, 0x00000001, 0x00000001, 0x00107e46, 0x00000003, 0x0700001d, 0x00100082, 0x00000001,
3724 0x0010002a, 0x00000001, 0x0010000a, 0x00000002, 0x0304001f, 0x0010003a, 0x00000001, 0x05000036,
3725 0x00100082, 0x00000001, 0x0010003a, 0x00000003, 0x05000036, 0x00100062, 0x00000002, 0x00100ff6,
3726 0x00000003, 0x05000036, 0x00100082, 0x00000002, 0x0010000a, 0x00000002, 0x08000036, 0x00100032,
3727 0x00000003, 0x00004002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x01000030, 0x08000050,
3728 0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x0020800a, 0x00000000, 0x00000008, 0x05000036,
3729 0x00100022, 0x00000003, 0x00004001, 0x00000000, 0x03040003, 0x0010002a, 0x00000003, 0x07000029,
3730 0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d, 0x001000f2,
3731 0x00000004, 0x00100aa6, 0x00000003, 0x00107e46, 0x00000003, 0x0700001e, 0x00100042, 0x00000003,
3732 0x0010002a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d, 0x001000f2, 0x00000005, 0x00100aa6,
3733 0x00000003, 0x00107e46, 0x00000003, 0x0700001d, 0x00100042, 0x00000003, 0x0010002a, 0x00000001,
3734 0x0010003a, 0x00000002, 0x0700001d, 0x00100022, 0x00000004, 0x0010000a, 0x00000004, 0x0010002a,
3735 0x00000001, 0x07000001, 0x00100042, 0x00000003, 0x0010002a, 0x00000003, 0x0010001a, 0x00000004,
3736 0x0304001f, 0x0010002a, 0x00000003, 0x08000000, 0x00100022, 0x00000004, 0x0010002a, 0x00000001,
3737 0x8010003a, 0x00000041, 0x00000002, 0x08000000, 0x00100042, 0x00000004, 0x8010003a, 0x00000041,
3738 0x00000002, 0x0010000a, 0x00000004, 0x0700000e, 0x00100022, 0x00000004, 0x0010001a, 0x00000004,
3739 0x0010002a, 0x00000004, 0x08000000, 0x00100042, 0x00000004, 0x8010001a, 0x00000041, 0x00000002,
3740 0x0010003a, 0x00000005, 0x09000032, 0x00100022, 0x00000004, 0x0010001a, 0x00000004, 0x0010002a,
3741 0x00000004, 0x0010001a, 0x00000002, 0x05000036, 0x00100042, 0x00000002, 0x0010003a, 0x00000005,
3742 0x05000036, 0x00100022, 0x00000003, 0x00004001, 0xffffffff, 0x05000036, 0x00100082, 0x00000001,
3743 0x0010001a, 0x00000004, 0x01000002, 0x01000015, 0x05000036, 0x00100022, 0x00000002, 0x0010003a,
3744 0x00000005, 0x05000036, 0x00100082, 0x00000002, 0x0010000a, 0x00000004, 0x0700001e, 0x00100012,
3745 0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x05000036, 0x00100042, 0x00000002,
3746 0x0010003a, 0x00000005, 0x05000036, 0x00100032, 0x00000003, 0x00100086, 0x00000003, 0x01000016,
3747 0x09000037, 0x00100042, 0x00000001, 0x0010001a, 0x00000003, 0x0010003a, 0x00000001, 0x0010002a,
3748 0x00000002, 0x01000012, 0x05000036, 0x00100042, 0x00000001, 0x0010003a, 0x00000003, 0x01000015,
3749 0x08000038, 0x00100012, 0x00000001, 0x0010002a, 0x00000001, 0x0020801a, 0x00000000, 0x00000005,
3750 0x01000015, 0x0300001f, 0x0010001a, 0x00000001, 0x08000020, 0x00100022, 0x00000001, 0x0020800a,
3751 0x00000000, 0x00000005, 0x00004001, 0x00000003, 0x0304001f, 0x0010001a, 0x00000001, 0x0800000f,
3752 0x00100042, 0x00000001, 0x00101046, 0x00000000, 0x00208046, 0x00000000, 0x00000006, 0x08000000,
3753 0x00100012, 0x00000002, 0x0010002a, 0x00000001, 0x0020802a, 0x00000000, 0x00000006, 0x0800000f,
3754 0x00100042, 0x00000001, 0x00101046, 0x00000000, 0x00208046, 0x00000000, 0x00000007, 0x08000000,
3755 0x00100022, 0x00000002, 0x0010002a, 0x00000001, 0x0020802a, 0x00000000, 0x00000007, 0x09000045,
3756 0x001000f2, 0x00000002, 0x00100046, 0x00000002, 0x00107e46, 0x00000001, 0x00106000, 0x00000001,
3757 0x0a000037, 0x00100042, 0x00000001, 0x0020803a, 0x00000000, 0x00000007, 0x00004001, 0x3f800000,
3758 0x0010003a, 0x00000002, 0x08000038, 0x00100012, 0x00000001, 0x0010002a, 0x00000001, 0x0020801a,
3759 0x00000000, 0x00000005, 0x01000015, 0x0a000037, 0x00100012, 0x00000001, 0x0010001a, 0x00000001,
3760 0x0010000a, 0x00000001, 0x0020801a, 0x00000000, 0x00000005, 0x01000015, 0x01000015, 0x01000015,
3761 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100006, 0x00000001, 0x01000012,
3762 0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x01000015, 0x0404001f, 0x0020800a,
3763 0x00000000, 0x00000000, 0x0500000b, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x0500000c,
3764 0x001000c2, 0x00000000, 0x00101406, 0x00000001, 0x08000027, 0x00100012, 0x00000001, 0x0020801a,
3765 0x00000000, 0x00000000, 0x00004001, 0x00000000, 0x0500003b, 0x00100022, 0x00000001, 0x0010000a,
3766 0x00000001, 0x07000000, 0x001000c2, 0x00000001, 0x00101406, 0x00000001, 0x00101406, 0x00000001,
3767 0x07000038, 0x001000f2, 0x00000002, 0x00100d86, 0x00000000, 0x00100fa6, 0x00000001, 0x0a000032,
3768 0x00100032, 0x00000000, 0x00100aa6, 0x00000001, 0x00100086, 0x00000000, 0x801005d6, 0x00000041,
3769 0x00000000, 0x0700000f, 0x00100042, 0x00000000, 0x00100046, 0x00000000, 0x00101ae6, 0x00000001,
3770 0x07000031, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x00004001, 0x00000000, 0x07000001,
3771 0x00100042, 0x00000000, 0x0010001a, 0x00000001, 0x0010002a, 0x00000000, 0x0304000d, 0x0010002a,
3772 0x00000000, 0x07000038, 0x00100062, 0x00000000, 0x00100556, 0x00000000, 0x00101106, 0x00000003,
3773 0x09000032, 0x00100032, 0x00000000, 0x00101046, 0x00000002, 0x00100006, 0x00000000, 0x00100596,
3774 0x00000000, 0x0700000f, 0x00100012, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000000,
3775 0x0500004b, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x07000038, 0x00100062, 0x00000000,
3776 0x00101106, 0x00000001, 0x00101106, 0x00000001, 0x0a000032, 0x00100082, 0x00000000, 0x0010100a,
3777 0x00000001, 0x0010100a, 0x00000001, 0x8010101a, 0x00000041, 0x00000001, 0x08000000, 0x00100012,
3778 0x00000000, 0x8010003a, 0x000000c1, 0x00000000, 0x0010000a, 0x00000000, 0x07000031, 0x00100012,
3779 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100012, 0x00000000,
3780 0x0010001a, 0x00000001, 0x0010000a, 0x00000000, 0x0304000d, 0x0010000a, 0x00000000, 0x07000000,
3781 0x00100092, 0x00000000, 0x00100ea6, 0x00000002, 0x00100406, 0x00000002, 0x0700000f, 0x00100022,
3782 0x00000001, 0x001000c6, 0x00000000, 0x00101ae6, 0x00000001, 0x07000031, 0x00100022, 0x00000001,
3783 0x0010001a, 0x00000001, 0x00004001, 0x00000000, 0x07000001, 0x00100022, 0x00000001, 0x0010000a,
3784 0x00000001, 0x0010001a, 0x00000001, 0x0304000d, 0x0010001a, 0x00000001, 0x07000038, 0x00100062,
3785 0x00000001, 0x00100ff6, 0x00000000, 0x00101106, 0x00000003, 0x09000032, 0x00100092, 0x00000000,
3786 0x00101406, 0x00000002, 0x00100006, 0x00000000, 0x00100956, 0x00000001, 0x0700000f, 0x00100012,
3787 0x00000000, 0x001000c6, 0x00000000, 0x001000c6, 0x00000000, 0x0500004b, 0x00100012, 0x00000000,
3788 0x0010000a, 0x00000000, 0x07000000, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a,
3789 0x00000000, 0x07000000, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0xbf800000,
3790 0x08000000, 0x00100012, 0x00000000, 0x8010001a, 0x000000c1, 0x00000000, 0x0010000a, 0x00000000,
3791 0x07000031, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000000, 0x07000001,
3792 0x00100012, 0x00000000, 0x0010000a, 0x00000001, 0x0010000a, 0x00000000, 0x0304000d, 0x0010000a,
3793 0x00000000, 0x01000012, 0x08000027, 0x00100012, 0x00000000, 0x0020801a, 0x00000000, 0x00000000,
3794 0x00004001, 0x00000000, 0x0500003b, 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x07000038,
3795 0x001000c2, 0x00000000, 0x00101406, 0x00000001, 0x00101406, 0x00000001, 0x0a000032, 0x00100012,
3796 0x00000001, 0x0010100a, 0x00000001, 0x0010100a, 0x00000001, 0x8010101a, 0x00000041, 0x00000001,
3797 0x07000038, 0x00100012, 0x00000001, 0x0010000a, 0x00000001, 0x0010102a, 0x00000001, 0x07000031,
3798 0x00100012, 0x00000001, 0x0010000a, 0x00000001, 0x00004001, 0x00000000, 0x07000001, 0x00100022,
3799 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000001, 0x0304000d, 0x0010001a, 0x00000000,
3800 0x07000000, 0x00100022, 0x00000000, 0x0010003a, 0x00000000, 0x0010002a, 0x00000000, 0x07000000,
3801 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0xbf800000, 0x07000038, 0x00100022,
3802 0x00000000, 0x0010001a, 0x00000000, 0x0010102a, 0x00000001, 0x07000031, 0x00100022, 0x00000000,
3803 0x0010001a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100012, 0x00000000, 0x0010000a,
3804 0x00000000, 0x0010001a, 0x00000000, 0x0304000d, 0x0010000a, 0x00000000, 0x01000015, 0x0100003e,
3806 static const struct shape_info
3808 enum d2d_shape_type shape_type
;
3809 const D3D10_INPUT_ELEMENT_DESC
*il_desc
;
3810 unsigned int il_element_count
;
3811 const void *vs_code
;
3812 size_t vs_code_size
;
3816 {D2D_SHAPE_TYPE_OUTLINE
, il_desc_outline
, ARRAY_SIZE(il_desc_outline
),
3817 vs_code_outline
, sizeof(vs_code_outline
)},
3818 {D2D_SHAPE_TYPE_BEZIER_OUTLINE
, il_desc_curve_outline
, ARRAY_SIZE(il_desc_curve_outline
),
3819 vs_code_bezier_outline
, sizeof(vs_code_bezier_outline
)},
3820 {D2D_SHAPE_TYPE_ARC_OUTLINE
, il_desc_curve_outline
, ARRAY_SIZE(il_desc_curve_outline
),
3821 vs_code_arc_outline
, sizeof(vs_code_arc_outline
)},
3822 {D2D_SHAPE_TYPE_TRIANGLE
, il_desc_triangle
, ARRAY_SIZE(il_desc_triangle
),
3823 vs_code_triangle
, sizeof(vs_code_triangle
)},
3824 {D2D_SHAPE_TYPE_CURVE
, il_desc_curve
, ARRAY_SIZE(il_desc_curve
),
3825 vs_code_curve
, sizeof(vs_code_curve
)},
3838 static const UINT16 indices
[] = {0, 1, 2, 2, 1, 3};
3840 render_target
->ID2D1DeviceContext_iface
.lpVtbl
= &d2d_device_context_vtbl
;
3841 render_target
->ID2D1GdiInteropRenderTarget_iface
.lpVtbl
= &d2d_gdi_interop_render_target_vtbl
;
3842 render_target
->IDWriteTextRenderer_iface
.lpVtbl
= &d2d_text_renderer_vtbl
;
3843 render_target
->IUnknown_iface
.lpVtbl
= &d2d_device_context_inner_unknown_vtbl
;
3844 render_target
->refcount
= 1;
3845 ID2D1Device_GetFactory(device
, &render_target
->factory
);
3846 render_target
->device
= device
;
3847 ID2D1Device_AddRef(render_target
->device
);
3849 render_target
->outer_unknown
= outer_unknown
? outer_unknown
: &render_target
->IUnknown_iface
;
3850 render_target
->ops
= ops
;
3852 device_impl
= unsafe_impl_from_ID2D1Device(device
);
3853 if (FAILED(hr
= IDXGIDevice_QueryInterface(device_impl
->dxgi_device
,
3854 &IID_ID3D10Device
, (void **)&render_target
->d3d_device
)))
3856 WARN("Failed to get device interface, hr %#x.\n", hr
);
3857 ID2D1Factory_Release(render_target
->factory
);
3861 if (FAILED(hr
= D3D10StateBlockMaskEnableAll(&state_mask
)))
3863 WARN("Failed to create stateblock mask, hr %#x.\n", hr
);
3867 if (FAILED(hr
= D3D10CreateStateBlock(render_target
->d3d_device
, &state_mask
, &render_target
->stateblock
)))
3869 WARN("Failed to create stateblock, hr %#x.\n", hr
);
3873 for (i
= 0; i
< ARRAY_SIZE(shape_info
); ++i
)
3875 const struct shape_info
*si
= &shape_info
[i
];
3877 if (FAILED(hr
= ID3D10Device_CreateInputLayout(render_target
->d3d_device
, si
->il_desc
, si
->il_element_count
,
3878 si
->vs_code
, si
->vs_code_size
, &render_target
->shape_resources
[si
->shape_type
].il
)))
3880 WARN("Failed to create input layout for shape type %#x, hr %#x.\n", si
->shape_type
, hr
);
3884 if (FAILED(hr
= ID3D10Device_CreateVertexShader(render_target
->d3d_device
, si
->vs_code
,
3885 si
->vs_code_size
, &render_target
->shape_resources
[si
->shape_type
].vs
)))
3887 WARN("Failed to create vertex shader for shape type %#x, hr %#x.\n", si
->shape_type
, hr
);
3893 if (FAILED(hr
= ID3D10Device_CreatePixelShader(render_target
->d3d_device
,
3894 ps_code
, sizeof(ps_code
), &render_target
->ps
)))
3896 WARN("Failed to create pixel shader, hr %#x.\n", hr
);
3900 buffer_desc
.ByteWidth
= sizeof(indices
);
3901 buffer_desc
.Usage
= D3D10_USAGE_DEFAULT
;
3902 buffer_desc
.BindFlags
= D3D10_BIND_INDEX_BUFFER
;
3903 buffer_desc
.CPUAccessFlags
= 0;
3904 buffer_desc
.MiscFlags
= 0;
3906 buffer_data
.pSysMem
= indices
;
3907 buffer_data
.SysMemPitch
= 0;
3908 buffer_data
.SysMemSlicePitch
= 0;
3910 if (FAILED(hr
= ID3D10Device_CreateBuffer(render_target
->d3d_device
,
3911 &buffer_desc
, &buffer_data
, &render_target
->ib
)))
3913 WARN("Failed to create clear index buffer, hr %#x.\n", hr
);
3917 buffer_desc
.ByteWidth
= sizeof(quad
);
3918 buffer_desc
.BindFlags
= D3D10_BIND_VERTEX_BUFFER
;
3919 buffer_data
.pSysMem
= quad
;
3921 render_target
->vb_stride
= sizeof(*quad
);
3922 if (FAILED(hr
= ID3D10Device_CreateBuffer(render_target
->d3d_device
,
3923 &buffer_desc
, &buffer_data
, &render_target
->vb
)))
3925 WARN("Failed to create clear vertex buffer, hr %#x.\n", hr
);
3929 rs_desc
.FillMode
= D3D10_FILL_SOLID
;
3930 rs_desc
.CullMode
= D3D10_CULL_NONE
;
3931 rs_desc
.FrontCounterClockwise
= FALSE
;
3932 rs_desc
.DepthBias
= 0;
3933 rs_desc
.DepthBiasClamp
= 0.0f
;
3934 rs_desc
.SlopeScaledDepthBias
= 0.0f
;
3935 rs_desc
.DepthClipEnable
= TRUE
;
3936 rs_desc
.ScissorEnable
= TRUE
;
3937 rs_desc
.MultisampleEnable
= FALSE
;
3938 rs_desc
.AntialiasedLineEnable
= FALSE
;
3939 if (FAILED(hr
= ID3D10Device_CreateRasterizerState(render_target
->d3d_device
, &rs_desc
, &render_target
->rs
)))
3941 WARN("Failed to create clear rasterizer state, hr %#x.\n", hr
);
3945 if (FAILED(hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
,
3946 &IID_IDWriteFactory
, (IUnknown
**)&dwrite_factory
)))
3948 ERR("Failed to create dwrite factory, hr %#x.\n", hr
);
3952 hr
= IDWriteFactory_CreateRenderingParams(dwrite_factory
, &render_target
->default_text_rendering_params
);
3953 IDWriteFactory_Release(dwrite_factory
);
3956 ERR("Failed to create default text rendering parameters, hr %#x.\n", hr
);
3960 render_target
->drawing_state
.transform
= identity
;
3962 if (!d2d_clip_stack_init(&render_target
->clip_stack
))
3964 WARN("Failed to initialize clip stack.\n");
3969 render_target
->desc
.dpiX
= 96.0f
;
3970 render_target
->desc
.dpiY
= 96.0f
;
3975 if (render_target
->default_text_rendering_params
)
3976 IDWriteRenderingParams_Release(render_target
->default_text_rendering_params
);
3977 if (render_target
->rs
)
3978 ID3D10RasterizerState_Release(render_target
->rs
);
3979 if (render_target
->vb
)
3980 ID3D10Buffer_Release(render_target
->vb
);
3981 if (render_target
->ib
)
3982 ID3D10Buffer_Release(render_target
->ib
);
3983 if (render_target
->ps
)
3984 ID3D10PixelShader_Release(render_target
->ps
);
3985 for (i
= 0; i
< D2D_SHAPE_TYPE_COUNT
; ++i
)
3987 if (render_target
->shape_resources
[i
].vs
)
3988 ID3D10VertexShader_Release(render_target
->shape_resources
[i
].vs
);
3989 if (render_target
->shape_resources
[i
].il
)
3990 ID3D10InputLayout_Release(render_target
->shape_resources
[i
].il
);
3992 if (render_target
->stateblock
)
3993 render_target
->stateblock
->lpVtbl
->Release(render_target
->stateblock
);
3994 if (render_target
->d3d_device
)
3995 ID3D10Device_Release(render_target
->d3d_device
);
3996 ID2D1Device_Release(render_target
->device
);
3997 ID2D1Factory_Release(render_target
->factory
);
4001 HRESULT
d2d_d3d_create_render_target(ID2D1Device
*device
, IDXGISurface
*surface
, IUnknown
*outer_unknown
,
4002 const struct d2d_device_context_ops
*ops
, const D2D1_RENDER_TARGET_PROPERTIES
*desc
, void **render_target
)
4004 D2D1_BITMAP_PROPERTIES1 bitmap_desc
;
4005 struct d2d_device_context
*object
;
4006 ID2D1Bitmap1
*bitmap
;
4009 if (desc
->type
!= D2D1_RENDER_TARGET_TYPE_DEFAULT
&& desc
->type
!= D2D1_RENDER_TARGET_TYPE_HARDWARE
)
4010 WARN("Ignoring render target type %#x.\n", desc
->type
);
4011 if (desc
->usage
!= D2D1_RENDER_TARGET_USAGE_NONE
)
4012 FIXME("Ignoring render target usage %#x.\n", desc
->usage
);
4013 if (desc
->minLevel
!= D2D1_FEATURE_LEVEL_DEFAULT
)
4014 WARN("Ignoring feature level %#x.\n", desc
->minLevel
);
4016 bitmap_desc
.dpiX
= desc
->dpiX
;
4017 bitmap_desc
.dpiY
= desc
->dpiY
;
4019 if (bitmap_desc
.dpiX
== 0.0f
&& bitmap_desc
.dpiY
== 0.0f
)
4021 bitmap_desc
.dpiX
= 96.0f
;
4022 bitmap_desc
.dpiY
= 96.0f
;
4024 else if (bitmap_desc
.dpiX
<= 0.0f
|| bitmap_desc
.dpiY
<= 0.0f
)
4025 return E_INVALIDARG
;
4027 if (!(object
= heap_alloc_zero(sizeof(*object
))))
4028 return E_OUTOFMEMORY
;
4030 if (FAILED(hr
= d2d_device_context_init(object
, device
, outer_unknown
, ops
)))
4032 WARN("Failed to initialize render target, hr %#x.\n", hr
);
4037 ID2D1DeviceContext_SetDpi(&object
->ID2D1DeviceContext_iface
, bitmap_desc
.dpiX
, bitmap_desc
.dpiY
);
4041 bitmap_desc
.pixelFormat
= desc
->pixelFormat
;
4042 bitmap_desc
.bitmapOptions
= D2D1_BITMAP_OPTIONS_TARGET
| D2D1_BITMAP_OPTIONS_CANNOT_DRAW
;
4043 bitmap_desc
.colorContext
= NULL
;
4045 if (FAILED(hr
= ID2D1DeviceContext_CreateBitmapFromDxgiSurface(&object
->ID2D1DeviceContext_iface
,
4046 surface
, &bitmap_desc
, &bitmap
)))
4048 WARN("Failed to create target bitmap, hr %#x.\n", hr
);
4049 IUnknown_Release(&object
->IUnknown_iface
);
4054 ID2D1DeviceContext_SetTarget(&object
->ID2D1DeviceContext_iface
, (ID2D1Image
*)bitmap
);
4055 ID2D1Bitmap1_Release(bitmap
);
4058 object
->desc
.pixelFormat
= desc
->pixelFormat
;
4060 TRACE("Created render target %p.\n", object
);
4061 *render_target
= outer_unknown
? &object
->IUnknown_iface
: (IUnknown
*)&object
->ID2D1DeviceContext_iface
;
4066 static HRESULT WINAPI
d2d_device_QueryInterface(ID2D1Device
*iface
, REFIID iid
, void **out
)
4068 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
4070 if (IsEqualGUID(iid
, &IID_ID2D1Device
)
4071 || IsEqualGUID(iid
, &IID_ID2D1Resource
)
4072 || IsEqualGUID(iid
, &IID_IUnknown
))
4074 ID2D1Device_AddRef(iface
);
4079 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
4082 return E_NOINTERFACE
;
4085 static ULONG WINAPI
d2d_device_AddRef(ID2D1Device
*iface
)
4087 struct d2d_device
*device
= impl_from_ID2D1Device(iface
);
4088 ULONG refcount
= InterlockedIncrement(&device
->refcount
);
4090 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
4095 static ULONG WINAPI
d2d_device_Release(ID2D1Device
*iface
)
4097 struct d2d_device
*device
= impl_from_ID2D1Device(iface
);
4098 ULONG refcount
= InterlockedDecrement(&device
->refcount
);
4100 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
4104 IDXGIDevice_Release(device
->dxgi_device
);
4105 ID2D1Factory1_Release(device
->factory
);
4112 static void WINAPI
d2d_device_GetFactory(ID2D1Device
*iface
, ID2D1Factory
**factory
)
4114 struct d2d_device
*device
= impl_from_ID2D1Device(iface
);
4116 TRACE("iface %p, factory %p.\n", iface
, factory
);
4118 *factory
= (ID2D1Factory
*)device
->factory
;
4119 ID2D1Factory1_AddRef(device
->factory
);
4122 static HRESULT WINAPI
d2d_device_CreateDeviceContext(ID2D1Device
*iface
, D2D1_DEVICE_CONTEXT_OPTIONS options
,
4123 ID2D1DeviceContext
**context
)
4125 struct d2d_device_context
*object
;
4128 TRACE("iface %p, options %#x, context %p.\n", iface
, options
, context
);
4131 FIXME("Options are ignored %#x.\n", options
);
4133 if (!(object
= heap_alloc_zero(sizeof(*object
))))
4134 return E_OUTOFMEMORY
;
4136 if (FAILED(hr
= d2d_device_context_init(object
, iface
, NULL
, NULL
)))
4138 WARN("Failed to initialize device context, hr %#x.\n", hr
);
4143 TRACE("Created device context %p.\n", object
);
4144 *context
= &object
->ID2D1DeviceContext_iface
;
4149 static HRESULT WINAPI
d2d_device_CreatePrintControl(ID2D1Device
*iface
, IWICImagingFactory
*wic_factory
,
4150 IPrintDocumentPackageTarget
*document_target
, const D2D1_PRINT_CONTROL_PROPERTIES
*desc
,
4151 ID2D1PrintControl
**print_control
)
4153 FIXME("iface %p, wic_factory %p, document_target %p, desc %p, print_control %p stub!\n", iface
, wic_factory
,
4154 document_target
, desc
, print_control
);
4159 static void WINAPI
d2d_device_SetMaximumTextureMemory(ID2D1Device
*iface
, UINT64 max_texture_memory
)
4161 FIXME("iface %p, max_texture_memory %s stub!\n", iface
, wine_dbgstr_longlong(max_texture_memory
));
4164 static UINT64 WINAPI
d2d_device_GetMaximumTextureMemory(ID2D1Device
*iface
)
4166 FIXME("iface %p stub!\n", iface
);
4171 static HRESULT WINAPI
d2d_device_ClearResources(ID2D1Device
*iface
, UINT msec_since_use
)
4173 FIXME("iface %p, msec_since_use %u stub!\n", iface
, msec_since_use
);
4178 static const struct ID2D1DeviceVtbl d2d_device_vtbl
=
4180 d2d_device_QueryInterface
,
4183 d2d_device_GetFactory
,
4184 d2d_device_CreateDeviceContext
,
4185 d2d_device_CreatePrintControl
,
4186 d2d_device_SetMaximumTextureMemory
,
4187 d2d_device_GetMaximumTextureMemory
,
4188 d2d_device_ClearResources
,
4191 static struct d2d_device
*unsafe_impl_from_ID2D1Device(ID2D1Device
*iface
)
4195 assert(iface
->lpVtbl
== &d2d_device_vtbl
);
4196 return CONTAINING_RECORD(iface
, struct d2d_device
, ID2D1Device_iface
);
4199 void d2d_device_init(struct d2d_device
*device
, ID2D1Factory1
*iface
, IDXGIDevice
*dxgi_device
)
4201 device
->ID2D1Device_iface
.lpVtbl
= &d2d_device_vtbl
;
4202 device
->refcount
= 1;
4203 device
->factory
= iface
;
4204 ID2D1Factory1_AddRef(device
->factory
);
4205 device
->dxgi_device
= dxgi_device
;
4206 IDXGIDevice_AddRef(device
->dxgi_device
);