"Fossies" - the Fresh Open Source Software Archive

Member "wine-6.0.1/dlls/d2d1/device.c" (7 Jun 2021, 190970 Bytes) of package /linux/misc/wine-6.0.1.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "device.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 6.0_vs_6.0.1.

    1 /*
    2  * Copyright 2014 Henri Verbeet for CodeWeavers
    3  *
    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.
    8  *
    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.
   13  *
   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
   17  */
   18 
   19 #include "d2d1_private.h"
   20 
   21 WINE_DEFAULT_DEBUG_CHANNEL(d2d);
   22 
   23 #define INITIAL_CLIP_STACK_SIZE 4
   24 
   25 static const D2D1_MATRIX_3X2_F identity =
   26 {{{
   27     1.0f, 0.0f,
   28     0.0f, 1.0f,
   29     0.0f, 0.0f,
   30 }}};
   31 
   32 struct d2d_draw_text_layout_ctx
   33 {
   34     ID2D1Brush *brush;
   35     D2D1_DRAW_TEXT_OPTIONS options;
   36 };
   37 
   38 static inline struct d2d_device *impl_from_ID2D1Device(ID2D1Device *iface)
   39 {
   40     return CONTAINING_RECORD(iface, struct d2d_device, ID2D1Device_iface);
   41 }
   42 
   43 static struct d2d_device *unsafe_impl_from_ID2D1Device(ID2D1Device *iface);
   44 
   45 static ID2D1Brush *d2d_draw_get_text_brush(struct d2d_draw_text_layout_ctx *context, IUnknown *effect)
   46 {
   47     ID2D1Brush *brush = NULL;
   48 
   49     if (effect && SUCCEEDED(IUnknown_QueryInterface(effect, &IID_ID2D1Brush, (void**)&brush)))
   50         return brush;
   51 
   52     ID2D1Brush_AddRef(context->brush);
   53     return context->brush;
   54 }
   55 
   56 static void d2d_rect_intersect(D2D1_RECT_F *dst, const D2D1_RECT_F *src)
   57 {
   58     if (src->left > dst->left)
   59         dst->left = src->left;
   60     if (src->top > dst->top)
   61         dst->top = src->top;
   62     if (src->right < dst->right)
   63         dst->right = src->right;
   64     if (src->bottom < dst->bottom)
   65         dst->bottom = src->bottom;
   66 }
   67 
   68 static void d2d_rect_set(D2D1_RECT_F *dst, float left, float top, float right, float bottom)
   69 {
   70     dst->left = left;
   71     dst->top = top;
   72     dst->right = right;
   73     dst->bottom = bottom;
   74 }
   75 
   76 static void d2d_size_set(D2D1_SIZE_U *dst, float width, float height)
   77 {
   78     dst->width = width;
   79     dst->height = height;
   80 }
   81 
   82 static BOOL d2d_clip_stack_init(struct d2d_clip_stack *stack)
   83 {
   84     if (!(stack->stack = heap_alloc(INITIAL_CLIP_STACK_SIZE * sizeof(*stack->stack))))
   85         return FALSE;
   86 
   87     stack->size = INITIAL_CLIP_STACK_SIZE;
   88     stack->count = 0;
   89 
   90     return TRUE;
   91 }
   92 
   93 static void d2d_clip_stack_cleanup(struct d2d_clip_stack *stack)
   94 {
   95     heap_free(stack->stack);
   96 }
   97 
   98 static BOOL d2d_clip_stack_push(struct d2d_clip_stack *stack, const D2D1_RECT_F *rect)
   99 {
  100     D2D1_RECT_F r;
  101 
  102     if (!d2d_array_reserve((void **)&stack->stack, &stack->size, stack->count + 1, sizeof(*stack->stack)))
  103         return FALSE;
  104 
  105     r = *rect;
  106     if (stack->count)
  107         d2d_rect_intersect(&r, &stack->stack[stack->count - 1]);
  108     stack->stack[stack->count++] = r;
  109 
  110     return TRUE;
  111 }
  112 
  113 static void d2d_clip_stack_pop(struct d2d_clip_stack *stack)
  114 {
  115     if (!stack->count)
  116         return;
  117     --stack->count;
  118 }
  119 
  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)
  123 {
  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;
  127     unsigned int offset;
  128     D3D10_VIEWPORT vp;
  129     HRESULT hr;
  130 
  131     vp.TopLeftX = 0;
  132     vp.TopLeftY = 0;
  133     vp.Width = render_target->pixel_size.width;
  134     vp.Height = render_target->pixel_size.height;
  135     vp.MinDepth = 0.0f;
  136     vp.MaxDepth = 1.0f;
  137 
  138     if (FAILED(hr = render_target->stateblock->lpVtbl->Capture(render_target->stateblock)))
  139     {
  140         WARN("Failed to capture stateblock, hr %#x.\n", hr);
  141         return;
  142     }
  143 
  144     ID3D10Device_ClearState(device);
  145 
  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);
  149     offset = 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)
  157     {
  158         const D2D1_RECT_F *clip_rect;
  159 
  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);
  165     }
  166     else
  167     {
  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;
  172     }
  173     ID3D10Device_RSSetScissorRects(device, 1, &scissor_rect);
  174     ID3D10Device_RSSetState(device, render_target->rs);
  175     ID3D10Device_OMSetRenderTargets(device, 1, &render_target->target->rtv, NULL);
  176     if (brush)
  177     {
  178         ID3D10Device_OMSetBlendState(device, render_target->bs, NULL, D3D10_DEFAULT_SAMPLE_MASK);
  179         d2d_brush_bind_resources(brush, device, 0);
  180     }
  181     if (opacity_brush)
  182         d2d_brush_bind_resources(opacity_brush, device, 1);
  183 
  184     if (ib)
  185         ID3D10Device_DrawIndexed(device, index_count, 0, 0);
  186     else
  187         ID3D10Device_Draw(device, index_count, 0);
  188 
  189     if (FAILED(hr = render_target->stateblock->lpVtbl->Apply(render_target->stateblock)))
  190         WARN("Failed to apply stateblock, hr %#x.\n", hr);
  191 }
  192 
  193 static void d2d_device_context_set_error(struct d2d_device_context *context, HRESULT code)
  194 {
  195     context->error.code = code;
  196     context->error.tag1 = context->drawing_state.tag1;
  197     context->error.tag2 = context->drawing_state.tag2;
  198 }
  199 
  200 static inline struct d2d_device_context *impl_from_IUnknown(IUnknown *iface)
  201 {
  202     return CONTAINING_RECORD(iface, struct d2d_device_context, IUnknown_iface);
  203 }
  204 
  205 static inline struct d2d_device_context *impl_from_ID2D1DeviceContext(ID2D1DeviceContext *iface)
  206 {
  207     return CONTAINING_RECORD(iface, struct d2d_device_context, ID2D1DeviceContext_iface);
  208 }
  209 
  210 static HRESULT STDMETHODCALLTYPE d2d_device_context_inner_QueryInterface(IUnknown *iface, REFIID iid, void **out)
  211 {
  212     struct d2d_device_context *context = impl_from_IUnknown(iface);
  213 
  214     TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
  215 
  216     if (IsEqualGUID(iid, &IID_ID2D1DeviceContext)
  217             || IsEqualGUID(iid, &IID_ID2D1RenderTarget)
  218             || IsEqualGUID(iid, &IID_ID2D1Resource)
  219             || IsEqualGUID(iid, &IID_IUnknown))
  220     {
  221         ID2D1DeviceContext_AddRef(&context->ID2D1DeviceContext_iface);
  222         *out = &context->ID2D1DeviceContext_iface;
  223         return S_OK;
  224     }
  225     else if (IsEqualGUID(iid, &IID_ID2D1GdiInteropRenderTarget))
  226     {
  227         ID2D1GdiInteropRenderTarget_AddRef(&context->ID2D1GdiInteropRenderTarget_iface);
  228         *out = &context->ID2D1GdiInteropRenderTarget_iface;
  229         return S_OK;
  230     }
  231 
  232     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
  233 
  234     *out = NULL;
  235     return E_NOINTERFACE;
  236 }
  237 
  238 static ULONG STDMETHODCALLTYPE d2d_device_context_inner_AddRef(IUnknown *iface)
  239 {
  240     struct d2d_device_context *context = impl_from_IUnknown(iface);
  241     ULONG refcount = InterlockedIncrement(&context->refcount);
  242 
  243     TRACE("%p increasing refcount to %u.\n", iface, refcount);
  244 
  245     return refcount;
  246 }
  247 
  248 static ULONG STDMETHODCALLTYPE d2d_device_context_inner_Release(IUnknown *iface)
  249 {
  250     struct d2d_device_context *context = impl_from_IUnknown(iface);
  251     ULONG refcount = InterlockedDecrement(&context->refcount);
  252 
  253     TRACE("%p decreasing refcount to %u.\n", iface, refcount);
  254 
  255     if (!refcount)
  256     {
  257         unsigned int i;
  258 
  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);
  263         if (context->bs)
  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)
  270         {
  271             ID3D10VertexShader_Release(context->shape_resources[i].vs);
  272             ID3D10InputLayout_Release(context->shape_resources[i].il);
  273         }
  274         context->stateblock->lpVtbl->Release(context->stateblock);
  275         if (context->target)
  276             ID2D1Bitmap1_Release(&context->target->ID2D1Bitmap1_iface);
  277         ID3D10Device_Release(context->d3d_device);
  278         ID2D1Factory_Release(context->factory);
  279         ID2D1Device_Release(context->device);
  280         heap_free(context);
  281     }
  282 
  283     return refcount;
  284 }
  285 
  286 static const struct IUnknownVtbl d2d_device_context_inner_unknown_vtbl =
  287 {
  288     d2d_device_context_inner_QueryInterface,
  289     d2d_device_context_inner_AddRef,
  290     d2d_device_context_inner_Release,
  291 };
  292 
  293 static HRESULT STDMETHODCALLTYPE d2d_device_context_QueryInterface(ID2D1DeviceContext *iface, REFIID iid, void **out)
  294 {
  295     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
  296 
  297     TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
  298 
  299     return IUnknown_QueryInterface(context->outer_unknown, iid, out);
  300 }
  301 
  302 static ULONG STDMETHODCALLTYPE d2d_device_context_AddRef(ID2D1DeviceContext *iface)
  303 {
  304     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
  305 
  306     TRACE("iface %p.\n", iface);
  307 
  308     return IUnknown_AddRef(context->outer_unknown);
  309 }
  310 
  311 static ULONG STDMETHODCALLTYPE d2d_device_context_Release(ID2D1DeviceContext *iface)
  312 {
  313     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
  314 
  315     TRACE("iface %p.\n", iface);
  316 
  317     return IUnknown_Release(context->outer_unknown);
  318 }
  319 
  320 static void STDMETHODCALLTYPE d2d_device_context_GetFactory(ID2D1DeviceContext *iface, ID2D1Factory **factory)
  321 {
  322     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
  323 
  324     TRACE("iface %p, factory %p.\n", iface, factory);
  325 
  326     *factory = render_target->factory;
  327     ID2D1Factory_AddRef(*factory);
  328 }
  329 
  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)
  332 {
  333     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
  334     D2D1_BITMAP_PROPERTIES1 bitmap_desc;
  335     struct d2d_bitmap *object;
  336     HRESULT hr;
  337 
  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);
  340 
  341     if (desc)
  342     {
  343         memcpy(&bitmap_desc, desc, sizeof(*desc));
  344         bitmap_desc.bitmapOptions = 0;
  345         bitmap_desc.colorContext = NULL;
  346     }
  347 
  348     if (SUCCEEDED(hr = d2d_bitmap_create(context, size, src_data, pitch, desc ? &bitmap_desc : NULL, &object)))
  349         *bitmap = (ID2D1Bitmap *)&object->ID2D1Bitmap1_iface;
  350 
  351     return hr;
  352 }
  353 
  354 static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapFromWicBitmap(ID2D1DeviceContext *iface,
  355         IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
  356 {
  357     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
  358     D2D1_BITMAP_PROPERTIES1 bitmap_desc;
  359     struct d2d_bitmap *object;
  360     HRESULT hr;
  361 
  362     TRACE("iface %p, bitmap_source %p, desc %p, bitmap %p.\n",
  363             iface, bitmap_source, desc, bitmap);
  364 
  365     if (desc)
  366     {
  367         memcpy(&bitmap_desc, desc, sizeof(*desc));
  368         bitmap_desc.bitmapOptions = 0;
  369         bitmap_desc.colorContext = NULL;
  370     }
  371 
  372     if (SUCCEEDED(hr = d2d_bitmap_create_from_wic_bitmap(context, bitmap_source, desc ? &bitmap_desc : NULL, &object)))
  373         *bitmap = (ID2D1Bitmap *)&object->ID2D1Bitmap1_iface;
  374 
  375     return hr;
  376 }
  377 
  378 static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateSharedBitmap(ID2D1DeviceContext *iface,
  379         REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
  380 {
  381     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
  382     D2D1_BITMAP_PROPERTIES1 bitmap_desc;
  383     struct d2d_bitmap *object;
  384     HRESULT hr;
  385 
  386     TRACE("iface %p, iid %s, data %p, desc %p, bitmap %p.\n",
  387             iface, debugstr_guid(iid), data, desc, bitmap);
  388 
  389     if (desc)
  390     {
  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;
  394     }
  395 
  396     if (SUCCEEDED(hr = d2d_bitmap_create_shared(context, iid, data, desc ? &bitmap_desc : NULL, &object)))
  397         *bitmap = (ID2D1Bitmap *)&object->ID2D1Bitmap1_iface;
  398 
  399     return hr;
  400 }
  401 
  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)
  405 {
  406     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
  407     struct d2d_brush *object;
  408     HRESULT hr;
  409 
  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);
  412 
  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;
  416 
  417     return hr;
  418 }
  419 
  420 static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateSolidColorBrush(ID2D1DeviceContext *iface,
  421         const D2D1_COLOR_F *color, const D2D1_BRUSH_PROPERTIES *desc, ID2D1SolidColorBrush **brush)
  422 {
  423     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
  424     struct d2d_brush *object;
  425     HRESULT hr;
  426 
  427     TRACE("iface %p, color %p, desc %p, brush %p.\n", iface, color, desc, brush);
  428 
  429     if (SUCCEEDED(hr = d2d_solid_color_brush_create(render_target->factory, color, desc, &object)))
  430         *brush = (ID2D1SolidColorBrush *)&object->ID2D1Brush_iface;
  431 
  432     return hr;
  433 }
  434 
  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)
  438 {
  439     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
  440     struct d2d_gradient *object;
  441     HRESULT hr;
  442 
  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);
  445 
  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;
  449 
  450     return hr;
  451 }
  452 
  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)
  456 {
  457     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
  458     struct d2d_brush *object;
  459     HRESULT hr;
  460 
  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);
  463 
  464     if (SUCCEEDED(hr = d2d_linear_gradient_brush_create(render_target->factory, gradient_brush_desc, brush_desc,
  465         gradient, &object)))
  466         *brush = (ID2D1LinearGradientBrush *)&object->ID2D1Brush_iface;
  467 
  468     return hr;
  469 }
  470 
  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)
  474 {
  475     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
  476     struct d2d_brush *object;
  477     HRESULT hr;
  478 
  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);
  481 
  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;
  485 
  486     return hr;
  487 }
  488 
  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)
  492 {
  493     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
  494     struct d2d_bitmap_render_target *object;
  495     HRESULT hr;
  496 
  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);
  499 
  500     if (!(object = heap_alloc_zero(sizeof(*object))))
  501         return E_OUTOFMEMORY;
  502 
  503     if (FAILED(hr = d2d_bitmap_render_target_init(object, render_target, size, pixel_size,
  504             format, options)))
  505     {
  506         WARN("Failed to initialize render target, hr %#x.\n", hr);
  507         heap_free(object);
  508         return hr;
  509     }
  510 
  511     TRACE("Created render target %p.\n", object);
  512     *rt = &object->ID2D1BitmapRenderTarget_iface;
  513 
  514     return S_OK;
  515 }
  516 
  517 static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateLayer(ID2D1DeviceContext *iface,
  518         const D2D1_SIZE_F *size, ID2D1Layer **layer)
  519 {
  520     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
  521     struct d2d_layer *object;
  522     HRESULT hr;
  523 
  524     TRACE("iface %p, size %p, layer %p.\n", iface, size, layer);
  525 
  526     if (SUCCEEDED(hr = d2d_layer_create(render_target->factory, size, &object)))
  527         *layer = &object->ID2D1Layer_iface;
  528 
  529     return hr;
  530 }
  531 
  532 static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateMesh(ID2D1DeviceContext *iface, ID2D1Mesh **mesh)
  533 {
  534     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
  535     struct d2d_mesh *object;
  536     HRESULT hr;
  537 
  538     TRACE("iface %p, mesh %p.\n", iface, mesh);
  539 
  540     if (SUCCEEDED(hr = d2d_mesh_create(render_target->factory, &object)))
  541         *mesh = &object->ID2D1Mesh_iface;
  542 
  543     return hr;
  544 }
  545 
  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)
  548 {
  549     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
  550     ID2D1PathGeometry *geometry;
  551     ID2D1GeometrySink *sink;
  552     HRESULT hr;
  553 
  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);
  556 
  557     if (FAILED(hr = ID2D1Factory_CreatePathGeometry(render_target->factory, &geometry)))
  558     {
  559         WARN("Failed to create path geometry, %#x.\n", hr);
  560         return;
  561     }
  562 
  563     if (FAILED(hr = ID2D1PathGeometry_Open(geometry, &sink)))
  564     {
  565         WARN("Open() failed, %#x.\n", hr);
  566         ID2D1PathGeometry_Release(geometry);
  567         return;
  568     }
  569 
  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);
  576 
  577     ID2D1DeviceContext_DrawGeometry(iface, (ID2D1Geometry *)geometry, brush, stroke_width, stroke_style);
  578     ID2D1PathGeometry_Release(geometry);
  579 }
  580 
  581 static void STDMETHODCALLTYPE d2d_device_context_DrawRectangle(ID2D1DeviceContext *iface,
  582         const D2D1_RECT_F *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
  583 {
  584     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
  585     ID2D1RectangleGeometry *geometry;
  586     HRESULT hr;
  587 
  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);
  590 
  591     if (FAILED(hr = ID2D1Factory_CreateRectangleGeometry(render_target->factory, rect, &geometry)))
  592     {
  593         ERR("Failed to create geometry, hr %#x.\n", hr);
  594         return;
  595     }
  596 
  597     ID2D1DeviceContext_DrawGeometry(iface, (ID2D1Geometry *)geometry, brush, stroke_width, stroke_style);
  598     ID2D1RectangleGeometry_Release(geometry);
  599 }
  600 
  601 static void STDMETHODCALLTYPE d2d_device_context_FillRectangle(ID2D1DeviceContext *iface,
  602         const D2D1_RECT_F *rect, ID2D1Brush *brush)
  603 {
  604     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
  605     ID2D1RectangleGeometry *geometry;
  606     HRESULT hr;
  607 
  608     TRACE("iface %p, rect %s, brush %p.\n", iface, debug_d2d_rect_f(rect), brush);
  609 
  610     if (FAILED(hr = ID2D1Factory_CreateRectangleGeometry(render_target->factory, rect, &geometry)))
  611     {
  612         ERR("Failed to create geometry, hr %#x.\n", hr);
  613         return;
  614     }
  615 
  616     ID2D1DeviceContext_FillGeometry(iface, (ID2D1Geometry *)geometry, brush, NULL);
  617     ID2D1RectangleGeometry_Release(geometry);
  618 }
  619 
  620 static void STDMETHODCALLTYPE d2d_device_context_DrawRoundedRectangle(ID2D1DeviceContext *iface,
  621         const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
  622 {
  623     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
  624     ID2D1RoundedRectangleGeometry *geometry;
  625     HRESULT hr;
  626 
  627     TRACE("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p.\n",
  628             iface, rect, brush, stroke_width, stroke_style);
  629 
  630     if (FAILED(hr = ID2D1Factory_CreateRoundedRectangleGeometry(render_target->factory, rect, &geometry)))
  631     {
  632         ERR("Failed to create geometry, hr %#x.\n", hr);
  633         return;
  634     }
  635 
  636     ID2D1DeviceContext_DrawGeometry(iface, (ID2D1Geometry *)geometry, brush, stroke_width, stroke_style);
  637     ID2D1RoundedRectangleGeometry_Release(geometry);
  638 }
  639 
  640 static void STDMETHODCALLTYPE d2d_device_context_FillRoundedRectangle(ID2D1DeviceContext *iface,
  641         const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush)
  642 {
  643     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
  644     ID2D1RoundedRectangleGeometry *geometry;
  645     HRESULT hr;
  646 
  647     TRACE("iface %p, rect %p, brush %p.\n", iface, rect, brush);
  648 
  649     if (FAILED(hr = ID2D1Factory_CreateRoundedRectangleGeometry(render_target->factory, rect, &geometry)))
  650     {
  651         ERR("Failed to create geometry, hr %#x.\n", hr);
  652         return;
  653     }
  654 
  655     ID2D1DeviceContext_FillGeometry(iface, (ID2D1Geometry *)geometry, brush, NULL);
  656     ID2D1RoundedRectangleGeometry_Release(geometry);
  657 }
  658 
  659 static void STDMETHODCALLTYPE d2d_device_context_DrawEllipse(ID2D1DeviceContext *iface,
  660         const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
  661 {
  662     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
  663     ID2D1EllipseGeometry *geometry;
  664     HRESULT hr;
  665 
  666     TRACE("iface %p, ellipse %p, brush %p, stroke_width %.8e, stroke_style %p.\n",
  667             iface, ellipse, brush, stroke_width, stroke_style);
  668 
  669     if (FAILED(hr = ID2D1Factory_CreateEllipseGeometry(render_target->factory, ellipse, &geometry)))
  670     {
  671         ERR("Failed to create geometry, hr %#x.\n", hr);
  672         return;
  673     }
  674 
  675     ID2D1DeviceContext_DrawGeometry(iface, (ID2D1Geometry *)geometry, brush, stroke_width, stroke_style);
  676     ID2D1EllipseGeometry_Release(geometry);
  677 }
  678 
  679 static void STDMETHODCALLTYPE d2d_device_context_FillEllipse(ID2D1DeviceContext *iface,
  680         const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush)
  681 {
  682     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
  683     ID2D1EllipseGeometry *geometry;
  684     HRESULT hr;
  685 
  686     TRACE("iface %p, ellipse %p, brush %p.\n", iface, ellipse, brush);
  687 
  688     if (FAILED(hr = ID2D1Factory_CreateEllipseGeometry(render_target->factory, ellipse, &geometry)))
  689     {
  690         ERR("Failed to create geometry, hr %#x.\n", hr);
  691         return;
  692     }
  693 
  694     ID2D1DeviceContext_FillGeometry(iface, (ID2D1Geometry *)geometry, brush, NULL);
  695     ID2D1EllipseGeometry_Release(geometry);
  696 }
  697 
  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)
  700 {
  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;
  705     float tmp_x, tmp_y;
  706     HRESULT hr;
  707     struct
  708     {
  709         struct
  710         {
  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;
  716     } vs_cb_data;
  717 
  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;
  726 
  727     w = &render_target->drawing_state.transform;
  728 
  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;
  734 
  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;
  740 
  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;
  746 
  747     buffer_data.pSysMem = &vs_cb_data;
  748     buffer_data.SysMemPitch = 0;
  749     buffer_data.SysMemSlicePitch = 0;
  750 
  751     if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vs_cb)))
  752     {
  753         WARN("Failed to create constant buffer, hr %#x.\n", hr);
  754         return;
  755     }
  756 
  757     if (FAILED(hr = d2d_brush_get_ps_cb(brush, NULL, TRUE, FALSE, render_target, &ps_cb_bezier)))
  758     {
  759         WARN("Failed to get ps constant buffer, hr %#x.\n", hr);
  760         ID3D10Buffer_Release(vs_cb);
  761         return;
  762     }
  763 
  764     if (FAILED(hr = d2d_brush_get_ps_cb(brush, NULL, TRUE, TRUE, render_target, &ps_cb_arc)))
  765     {
  766         WARN("Failed to get ps constant buffer, hr %#x.\n", hr);
  767         ID3D10Buffer_Release(vs_cb);
  768         ID3D10Buffer_Release(ps_cb_bezier);
  769         return;
  770     }
  771 
  772     if (geometry->outline.face_count)
  773     {
  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;
  777 
  778         if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib)))
  779         {
  780             WARN("Failed to create index buffer, hr %#x.\n", hr);
  781             goto done;
  782         }
  783 
  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;
  787 
  788         if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb)))
  789         {
  790             ERR("Failed to create vertex buffer, hr %#x.\n", hr);
  791             ID3D10Buffer_Release(ib);
  792             goto done;
  793         }
  794 
  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);
  797 
  798         ID3D10Buffer_Release(vb);
  799         ID3D10Buffer_Release(ib);
  800     }
  801 
  802     if (geometry->outline.bezier_face_count)
  803     {
  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;
  807 
  808         if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib)))
  809         {
  810             WARN("Failed to create beziers index buffer, hr %#x.\n", hr);
  811             goto done;
  812         }
  813 
  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;
  817 
  818         if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb)))
  819         {
  820             ERR("Failed to create beziers vertex buffer, hr %#x.\n", hr);
  821             ID3D10Buffer_Release(ib);
  822             goto done;
  823         }
  824 
  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);
  828 
  829         ID3D10Buffer_Release(vb);
  830         ID3D10Buffer_Release(ib);
  831     }
  832 
  833     if (geometry->outline.arc_face_count)
  834     {
  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;
  838 
  839         if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib)))
  840         {
  841             WARN("Failed to create arcs index buffer, hr %#x.\n", hr);
  842             goto done;
  843         }
  844 
  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;
  848 
  849         if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb)))
  850         {
  851             ERR("Failed to create arcs vertex buffer, hr %#x.\n", hr);
  852             ID3D10Buffer_Release(ib);
  853             goto done;
  854         }
  855 
  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);
  859 
  860         ID3D10Buffer_Release(vb);
  861         ID3D10Buffer_Release(ib);
  862     }
  863 
  864 done:
  865     ID3D10Buffer_Release(ps_cb_arc);
  866     ID3D10Buffer_Release(ps_cb_bezier);
  867     ID3D10Buffer_Release(vs_cb);
  868 }
  869 
  870 static void STDMETHODCALLTYPE d2d_device_context_DrawGeometry(ID2D1DeviceContext *iface,
  871         ID2D1Geometry *geometry, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
  872 {
  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);
  876 
  877     TRACE("iface %p, geometry %p, brush %p, stroke_width %.8e, stroke_style %p.\n",
  878             iface, geometry, brush, stroke_width, stroke_style);
  879 
  880     if (stroke_style)
  881         FIXME("Ignoring stroke style %p.\n", stroke_style);
  882 
  883     d2d_device_context_draw_geometry(render_target, geometry_impl, brush_impl, stroke_width);
  884 }
  885 
  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)
  888 {
  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;
  893     float tmp_x, tmp_y;
  894     HRESULT hr;
  895     struct
  896     {
  897         struct
  898         {
  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;
  904     } vs_cb_data;
  905 
  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;
  914 
  915     w = &render_target->drawing_state.transform;
  916 
  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;
  922 
  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;
  928 
  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;
  934 
  935     buffer_data.pSysMem = &vs_cb_data;
  936     buffer_data.SysMemPitch = 0;
  937     buffer_data.SysMemSlicePitch = 0;
  938 
  939     if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vs_cb)))
  940     {
  941         WARN("Failed to create constant buffer, hr %#x.\n", hr);
  942         return;
  943     }
  944 
  945     if (FAILED(hr = d2d_brush_get_ps_cb(brush, opacity_brush, FALSE, FALSE, render_target, &ps_cb_bezier)))
  946     {
  947         WARN("Failed to get ps constant buffer, hr %#x.\n", hr);
  948         ID3D10Buffer_Release(vs_cb);
  949         return;
  950     }
  951 
  952     if (FAILED(hr = d2d_brush_get_ps_cb(brush, opacity_brush, FALSE, TRUE, render_target, &ps_cb_arc)))
  953     {
  954         WARN("Failed to get ps constant buffer, hr %#x.\n", hr);
  955         ID3D10Buffer_Release(vs_cb);
  956         ID3D10Buffer_Release(ps_cb_bezier);
  957         return;
  958     }
  959 
  960     if (geometry->fill.face_count)
  961     {
  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;
  965 
  966         if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ib)))
  967         {
  968             WARN("Failed to create index buffer, hr %#x.\n", hr);
  969             goto done;
  970         }
  971 
  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;
  975 
  976         if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb)))
  977         {
  978             ERR("Failed to create vertex buffer, hr %#x.\n", hr);
  979             ID3D10Buffer_Release(ib);
  980             goto done;
  981         }
  982 
  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);
  985 
  986         ID3D10Buffer_Release(vb);
  987         ID3D10Buffer_Release(ib);
  988     }
  989 
  990     if (geometry->fill.bezier_vertex_count)
  991     {
  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;
  995 
  996         if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb)))
  997         {
  998             ERR("Failed to create beziers vertex buffer, hr %#x.\n", hr);
  999             goto done;
 1000         }
 1001 
 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);
 1004 
 1005         ID3D10Buffer_Release(vb);
 1006     }
 1007 
 1008     if (geometry->fill.arc_vertex_count)
 1009     {
 1010         buffer_desc.ByteWidth = geometry->fill.arc_vertex_count * sizeof(*geometry->fill.arc_vertices);
 1011         buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
 1012         buffer_data.pSysMem = geometry->fill.arc_vertices;
 1013 
 1014         if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vb)))
 1015         {
 1016             ERR("Failed to create arc vertex buffer, hr %#x.\n", hr);
 1017             goto done;
 1018         }
 1019 
 1020         d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_CURVE, NULL, geometry->fill.arc_vertex_count, vb,
 1021                 sizeof(*geometry->fill.arc_vertices), vs_cb, ps_cb_arc, brush, opacity_brush);
 1022 
 1023         ID3D10Buffer_Release(vb);
 1024     }
 1025 
 1026 done:
 1027     ID3D10Buffer_Release(ps_cb_arc);
 1028     ID3D10Buffer_Release(ps_cb_bezier);
 1029     ID3D10Buffer_Release(vs_cb);
 1030 }
 1031 
 1032 static void STDMETHODCALLTYPE d2d_device_context_FillGeometry(ID2D1DeviceContext *iface,
 1033         ID2D1Geometry *geometry, ID2D1Brush *brush, ID2D1Brush *opacity_brush)
 1034 {
 1035     const struct d2d_geometry *geometry_impl = unsafe_impl_from_ID2D1Geometry(geometry);
 1036     struct d2d_brush *opacity_brush_impl = unsafe_impl_from_ID2D1Brush(opacity_brush);
 1037     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
 1038     struct d2d_brush *brush_impl = unsafe_impl_from_ID2D1Brush(brush);
 1039 
 1040     TRACE("iface %p, geometry %p, brush %p, opacity_brush %p.\n", iface, geometry, brush, opacity_brush);
 1041 
 1042     if (FAILED(context->error.code))
 1043         return;
 1044 
 1045     if (opacity_brush && brush_impl->type != D2D_BRUSH_TYPE_BITMAP)
 1046     {
 1047         d2d_device_context_set_error(context, D2DERR_INCOMPATIBLE_BRUSH_TYPES);
 1048         return;
 1049     }
 1050 
 1051     d2d_device_context_fill_geometry(context, geometry_impl, brush_impl, opacity_brush_impl);
 1052 }
 1053 
 1054 static void STDMETHODCALLTYPE d2d_device_context_FillMesh(ID2D1DeviceContext *iface,
 1055         ID2D1Mesh *mesh, ID2D1Brush *brush)
 1056 {
 1057     FIXME("iface %p, mesh %p, brush %p stub!\n", iface, mesh, brush);
 1058 }
 1059 
 1060 static void STDMETHODCALLTYPE d2d_device_context_FillOpacityMask(ID2D1DeviceContext *iface,
 1061         ID2D1Bitmap *mask, ID2D1Brush *brush, D2D1_OPACITY_MASK_CONTENT content,
 1062         const D2D1_RECT_F *dst_rect, const D2D1_RECT_F *src_rect)
 1063 {
 1064     FIXME("iface %p, mask %p, brush %p, content %#x, dst_rect %s, src_rect %s stub!\n",
 1065             iface, mask, brush, content, debug_d2d_rect_f(dst_rect), debug_d2d_rect_f(src_rect));
 1066 }
 1067 
 1068 static void d2d_device_context_draw_bitmap(struct d2d_device_context *context, ID2D1Bitmap *bitmap,
 1069         const D2D1_RECT_F *dst_rect, float opacity, D2D1_INTERPOLATION_MODE interpolation_mode,
 1070         const D2D1_RECT_F *src_rect, const D2D1_MATRIX_4X4_F *perspective_transform)
 1071 {
 1072     D2D1_BITMAP_BRUSH_PROPERTIES1 bitmap_brush_desc;
 1073     D2D1_BRUSH_PROPERTIES brush_desc;
 1074     struct d2d_brush *brush;
 1075     D2D1_RECT_F s, d;
 1076     HRESULT hr;
 1077 
 1078     if (perspective_transform)
 1079         FIXME("Perspective transform is ignored.\n");
 1080 
 1081     if (src_rect)
 1082     {
 1083         s = *src_rect;
 1084     }
 1085     else
 1086     {
 1087         D2D1_SIZE_F size;
 1088 
 1089         size = ID2D1Bitmap_GetSize(bitmap);
 1090         s.left = 0.0f;
 1091         s.top = 0.0f;
 1092         s.right = size.width;
 1093         s.bottom = size.height;
 1094     }
 1095 
 1096     if (dst_rect)
 1097     {
 1098         d = *dst_rect;
 1099     }
 1100     else
 1101     {
 1102         d.left = 0.0f;
 1103         d.top = 0.0f;
 1104         d.right = s.right - s.left;
 1105         d.bottom = s.bottom - s.top;
 1106     }
 1107 
 1108     bitmap_brush_desc.extendModeX = D2D1_EXTEND_MODE_CLAMP;
 1109     bitmap_brush_desc.extendModeY = D2D1_EXTEND_MODE_CLAMP;
 1110     bitmap_brush_desc.interpolationMode = interpolation_mode;
 1111 
 1112     brush_desc.opacity = opacity;
 1113     brush_desc.transform._11 = fabsf((d.right - d.left) / (s.right - s.left));
 1114     brush_desc.transform._21 = 0.0f;
 1115     brush_desc.transform._31 = min(d.left, d.right) - min(s.left, s.right) * brush_desc.transform._11;
 1116     brush_desc.transform._12 = 0.0f;
 1117     brush_desc.transform._22 = fabsf((d.bottom - d.top) / (s.bottom - s.top));
 1118     brush_desc.transform._32 = min(d.top, d.bottom) - min(s.top, s.bottom) * brush_desc.transform._22;
 1119 
 1120     if (FAILED(hr = d2d_bitmap_brush_create(context->factory, bitmap, &bitmap_brush_desc, &brush_desc, &brush)))
 1121     {
 1122         ERR("Failed to create bitmap brush, hr %#x.\n", hr);
 1123         return;
 1124     }
 1125 
 1126     d2d_device_context_FillRectangle(&context->ID2D1DeviceContext_iface, &d, &brush->ID2D1Brush_iface);
 1127     ID2D1Brush_Release(&brush->ID2D1Brush_iface);
 1128 }
 1129 
 1130 static void STDMETHODCALLTYPE d2d_device_context_DrawBitmap(ID2D1DeviceContext *iface,
 1131         ID2D1Bitmap *bitmap, const D2D1_RECT_F *dst_rect, float opacity,
 1132         D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode, const D2D1_RECT_F *src_rect)
 1133 {
 1134     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
 1135 
 1136     TRACE("iface %p, bitmap %p, dst_rect %s, opacity %.8e, interpolation_mode %#x, src_rect %s.\n",
 1137             iface, bitmap, debug_d2d_rect_f(dst_rect), opacity, interpolation_mode, debug_d2d_rect_f(src_rect));
 1138 
 1139     if (interpolation_mode != D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR
 1140             && interpolation_mode != D2D1_BITMAP_INTERPOLATION_MODE_LINEAR)
 1141     {
 1142         d2d_device_context_set_error(context, E_INVALIDARG);
 1143         return;
 1144     }
 1145 
 1146     d2d_device_context_draw_bitmap(context, bitmap, dst_rect, opacity, d2d1_1_interp_mode_from_d2d1(interpolation_mode),
 1147             src_rect, NULL);
 1148 }
 1149 
 1150 static void STDMETHODCALLTYPE d2d_device_context_DrawText(ID2D1DeviceContext *iface,
 1151         const WCHAR *string, UINT32 string_len, IDWriteTextFormat *text_format, const D2D1_RECT_F *layout_rect,
 1152         ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options, DWRITE_MEASURING_MODE measuring_mode)
 1153 {
 1154     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1155     IDWriteTextLayout *text_layout;
 1156     IDWriteFactory *dwrite_factory;
 1157     D2D1_POINT_2F origin;
 1158     float width, height;
 1159     HRESULT hr;
 1160 
 1161     TRACE("iface %p, string %s, string_len %u, text_format %p, layout_rect %s, "
 1162             "brush %p, options %#x, measuring_mode %#x.\n",
 1163             iface, debugstr_wn(string, string_len), string_len, text_format, debug_d2d_rect_f(layout_rect),
 1164             brush, options, measuring_mode);
 1165 
 1166     if (FAILED(hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
 1167             &IID_IDWriteFactory, (IUnknown **)&dwrite_factory)))
 1168     {
 1169         ERR("Failed to create dwrite factory, hr %#x.\n", hr);
 1170         return;
 1171     }
 1172 
 1173     width = max(0.0f, layout_rect->right - layout_rect->left);
 1174     height = max(0.0f, layout_rect->bottom - layout_rect->top);
 1175     if (measuring_mode == DWRITE_MEASURING_MODE_NATURAL)
 1176         hr = IDWriteFactory_CreateTextLayout(dwrite_factory, string, string_len, text_format,
 1177                 width, height, &text_layout);
 1178     else
 1179         hr = IDWriteFactory_CreateGdiCompatibleTextLayout(dwrite_factory, string, string_len, text_format,
 1180                 width, height, render_target->desc.dpiX / 96.0f, (DWRITE_MATRIX *)&render_target->drawing_state.transform,
 1181                 measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL, &text_layout);
 1182     IDWriteFactory_Release(dwrite_factory);
 1183     if (FAILED(hr))
 1184     {
 1185         ERR("Failed to create text layout, hr %#x.\n", hr);
 1186         return;
 1187     }
 1188 
 1189     d2d_point_set(&origin, min(layout_rect->left, layout_rect->right), min(layout_rect->top, layout_rect->bottom));
 1190     ID2D1DeviceContext_DrawTextLayout(iface, origin, text_layout, brush, options);
 1191     IDWriteTextLayout_Release(text_layout);
 1192 }
 1193 
 1194 static void STDMETHODCALLTYPE d2d_device_context_DrawTextLayout(ID2D1DeviceContext *iface,
 1195         D2D1_POINT_2F origin, IDWriteTextLayout *layout, ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options)
 1196 {
 1197     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1198     struct d2d_draw_text_layout_ctx ctx;
 1199     HRESULT hr;
 1200 
 1201     TRACE("iface %p, origin %s, layout %p, brush %p, options %#x.\n",
 1202             iface, debug_d2d_point_2f(&origin), layout, brush, options);
 1203 
 1204     ctx.brush = brush;
 1205     ctx.options = options;
 1206 
 1207     if (FAILED(hr = IDWriteTextLayout_Draw(layout,
 1208             &ctx, &render_target->IDWriteTextRenderer_iface, origin.x, origin.y)))
 1209         FIXME("Failed to draw text layout, hr %#x.\n", hr);
 1210 }
 1211 
 1212 static D2D1_ANTIALIAS_MODE d2d_device_context_set_aa_mode_from_text_aa_mode(struct d2d_device_context *rt)
 1213 {
 1214     D2D1_ANTIALIAS_MODE prev_antialias_mode = rt->drawing_state.antialiasMode;
 1215     rt->drawing_state.antialiasMode = rt->drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_ALIASED ?
 1216             D2D1_ANTIALIAS_MODE_ALIASED : D2D1_ANTIALIAS_MODE_PER_PRIMITIVE;
 1217     return prev_antialias_mode;
 1218 }
 1219 
 1220 static void d2d_device_context_draw_glyph_run_outline(struct d2d_device_context *render_target,
 1221         D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush)
 1222 {
 1223     D2D1_MATRIX_3X2_F *transform, prev_transform;
 1224     D2D1_ANTIALIAS_MODE prev_antialias_mode;
 1225     ID2D1PathGeometry *geometry;
 1226     ID2D1GeometrySink *sink;
 1227     HRESULT hr;
 1228 
 1229     if (FAILED(hr = ID2D1Factory_CreatePathGeometry(render_target->factory, &geometry)))
 1230     {
 1231         ERR("Failed to create geometry, hr %#x.\n", hr);
 1232         return;
 1233     }
 1234 
 1235     if (FAILED(hr = ID2D1PathGeometry_Open(geometry, &sink)))
 1236     {
 1237         ERR("Failed to open geometry sink, hr %#x.\n", hr);
 1238         ID2D1PathGeometry_Release(geometry);
 1239         return;
 1240     }
 1241 
 1242     if (FAILED(hr = IDWriteFontFace_GetGlyphRunOutline(glyph_run->fontFace, glyph_run->fontEmSize,
 1243             glyph_run->glyphIndices, glyph_run->glyphAdvances, glyph_run->glyphOffsets, glyph_run->glyphCount,
 1244             glyph_run->isSideways, glyph_run->bidiLevel & 1, (IDWriteGeometrySink *)sink)))
 1245     {
 1246         ERR("Failed to get glyph run outline, hr %#x.\n", hr);
 1247         ID2D1GeometrySink_Release(sink);
 1248         ID2D1PathGeometry_Release(geometry);
 1249         return;
 1250     }
 1251 
 1252     if (FAILED(hr = ID2D1GeometrySink_Close(sink)))
 1253         ERR("Failed to close geometry sink, hr %#x.\n", hr);
 1254     ID2D1GeometrySink_Release(sink);
 1255 
 1256     transform = &render_target->drawing_state.transform;
 1257     prev_transform = *transform;
 1258     transform->_31 += baseline_origin.x * transform->_11 + baseline_origin.y * transform->_21;
 1259     transform->_32 += baseline_origin.x * transform->_12 + baseline_origin.y * transform->_22;
 1260     prev_antialias_mode = d2d_device_context_set_aa_mode_from_text_aa_mode(render_target);
 1261     d2d_device_context_fill_geometry(render_target, unsafe_impl_from_ID2D1Geometry((ID2D1Geometry *)geometry),
 1262             unsafe_impl_from_ID2D1Brush(brush), NULL);
 1263     render_target->drawing_state.antialiasMode = prev_antialias_mode;
 1264     *transform = prev_transform;
 1265 
 1266     ID2D1PathGeometry_Release(geometry);
 1267 }
 1268 
 1269 static void d2d_device_context_draw_glyph_run_bitmap(struct d2d_device_context *render_target,
 1270         D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush,
 1271         DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEASURING_MODE measuring_mode,
 1272         DWRITE_TEXT_ANTIALIAS_MODE antialias_mode)
 1273 {
 1274     ID2D1RectangleGeometry *geometry = NULL;
 1275     ID2D1BitmapBrush *opacity_brush = NULL;
 1276     D2D1_BITMAP_PROPERTIES bitmap_desc;
 1277     ID2D1Bitmap *opacity_bitmap = NULL;
 1278     IDWriteGlyphRunAnalysis *analysis;
 1279     DWRITE_TEXTURE_TYPE texture_type;
 1280     D2D1_BRUSH_PROPERTIES brush_desc;
 1281     IDWriteFactory2 *dwrite_factory;
 1282     D2D1_MATRIX_3X2_F *transform, m;
 1283     void *opacity_values = NULL;
 1284     size_t opacity_values_size;
 1285     D2D1_SIZE_U bitmap_size;
 1286     float scale_x, scale_y;
 1287     D2D1_RECT_F run_rect;
 1288     RECT bounds;
 1289     HRESULT hr;
 1290 
 1291     if (FAILED(hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
 1292             &IID_IDWriteFactory2, (IUnknown **)&dwrite_factory)))
 1293     {
 1294         ERR("Failed to create dwrite factory, hr %#x.\n", hr);
 1295         return;
 1296     }
 1297 
 1298     transform = &render_target->drawing_state.transform;
 1299 
 1300     scale_x = render_target->desc.dpiX / 96.0f;
 1301     m._11 = transform->_11 * scale_x;
 1302     m._21 = transform->_21 * scale_x;
 1303     m._31 = transform->_31 * scale_x;
 1304 
 1305     scale_y = render_target->desc.dpiY / 96.0f;
 1306     m._12 = transform->_12 * scale_y;
 1307     m._22 = transform->_22 * scale_y;
 1308     m._32 = transform->_32 * scale_y;
 1309 
 1310     hr = IDWriteFactory2_CreateGlyphRunAnalysis(dwrite_factory, glyph_run, (DWRITE_MATRIX *)&m,
 1311             rendering_mode, measuring_mode, DWRITE_GRID_FIT_MODE_DEFAULT, antialias_mode,
 1312             baseline_origin.x, baseline_origin.y, &analysis);
 1313     IDWriteFactory2_Release(dwrite_factory);
 1314     if (FAILED(hr))
 1315     {
 1316         ERR("Failed to create glyph run analysis, hr %#x.\n", hr);
 1317         return;
 1318     }
 1319 
 1320     if (rendering_mode == DWRITE_RENDERING_MODE_ALIASED || antialias_mode == DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE)
 1321         texture_type = DWRITE_TEXTURE_ALIASED_1x1;
 1322     else
 1323         texture_type = DWRITE_TEXTURE_CLEARTYPE_3x1;
 1324 
 1325     if (FAILED(hr = IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis, texture_type, &bounds)))
 1326     {
 1327         ERR("Failed to get alpha texture bounds, hr %#x.\n", hr);
 1328         goto done;
 1329     }
 1330 
 1331     d2d_size_set(&bitmap_size, bounds.right - bounds.left, bounds.bottom - bounds.top);
 1332     if (!bitmap_size.width || !bitmap_size.height)
 1333     {
 1334         /* Empty run, nothing to do. */
 1335         goto done;
 1336     }
 1337 
 1338     if (texture_type == DWRITE_TEXTURE_CLEARTYPE_3x1)
 1339         bitmap_size.width *= 3;
 1340     if (!(opacity_values = heap_calloc(bitmap_size.height, bitmap_size.width)))
 1341     {
 1342         ERR("Failed to allocate opacity values.\n");
 1343         goto done;
 1344     }
 1345     opacity_values_size = bitmap_size.height * bitmap_size.width;
 1346 
 1347     if (FAILED(hr = IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis,
 1348             texture_type, &bounds, opacity_values, opacity_values_size)))
 1349     {
 1350         ERR("Failed to create alpha texture, hr %#x.\n", hr);
 1351         goto done;
 1352     }
 1353 
 1354     bitmap_desc.pixelFormat.format = DXGI_FORMAT_A8_UNORM;
 1355     bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
 1356     bitmap_desc.dpiX = render_target->desc.dpiX;
 1357     if (texture_type == DWRITE_TEXTURE_CLEARTYPE_3x1)
 1358         bitmap_desc.dpiX *= 3.0f;
 1359     bitmap_desc.dpiY = render_target->desc.dpiY;
 1360     if (FAILED(hr = d2d_device_context_CreateBitmap(&render_target->ID2D1DeviceContext_iface,
 1361             bitmap_size, opacity_values, bitmap_size.width, &bitmap_desc, &opacity_bitmap)))
 1362     {
 1363         ERR("Failed to create opacity bitmap, hr %#x.\n", hr);
 1364         goto done;
 1365     }
 1366 
 1367     d2d_rect_set(&run_rect, bounds.left / scale_x, bounds.top / scale_y,
 1368             bounds.right / scale_x, bounds.bottom / scale_y);
 1369 
 1370     brush_desc.opacity = 1.0f;
 1371     brush_desc.transform._11 = 1.0f;
 1372     brush_desc.transform._12 = 0.0f;
 1373     brush_desc.transform._21 = 0.0f;
 1374     brush_desc.transform._22 = 1.0f;
 1375     brush_desc.transform._31 = run_rect.left;
 1376     brush_desc.transform._32 = run_rect.top;
 1377     if (FAILED(hr = d2d_device_context_CreateBitmapBrush(&render_target->ID2D1DeviceContext_iface,
 1378             opacity_bitmap, NULL, &brush_desc, &opacity_brush)))
 1379     {
 1380         ERR("Failed to create opacity bitmap brush, hr %#x.\n", hr);
 1381         goto done;
 1382     }
 1383 
 1384     if (FAILED(hr = ID2D1Factory_CreateRectangleGeometry(render_target->factory, &run_rect, &geometry)))
 1385     {
 1386         ERR("Failed to create geometry, hr %#x.\n", hr);
 1387         goto done;
 1388     }
 1389 
 1390     m = *transform;
 1391     *transform = identity;
 1392     d2d_device_context_fill_geometry(render_target, unsafe_impl_from_ID2D1Geometry((ID2D1Geometry *)geometry),
 1393             unsafe_impl_from_ID2D1Brush(brush), unsafe_impl_from_ID2D1Brush((ID2D1Brush *)opacity_brush));
 1394     *transform = m;
 1395 
 1396 done:
 1397     if (geometry)
 1398         ID2D1RectangleGeometry_Release(geometry);
 1399     if (opacity_brush)
 1400         ID2D1BitmapBrush_Release(opacity_brush);
 1401     if (opacity_bitmap)
 1402         ID2D1Bitmap_Release(opacity_bitmap);
 1403     heap_free(opacity_values);
 1404     IDWriteGlyphRunAnalysis_Release(analysis);
 1405 }
 1406 
 1407 static void STDMETHODCALLTYPE d2d_device_context_DrawGlyphRun(ID2D1DeviceContext *iface,
 1408         D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush,
 1409         DWRITE_MEASURING_MODE measuring_mode)
 1410 {
 1411     TRACE("iface %p, baseline_origin %s, glyph_run %p, brush %p, measuring_mode %#x.\n",
 1412             iface, debug_d2d_point_2f(&baseline_origin), glyph_run, brush, measuring_mode);
 1413 
 1414     ID2D1DeviceContext_DrawGlyphRun(iface, baseline_origin, glyph_run, NULL, brush, measuring_mode);
 1415 }
 1416 
 1417 static void STDMETHODCALLTYPE d2d_device_context_SetTransform(ID2D1DeviceContext *iface,
 1418         const D2D1_MATRIX_3X2_F *transform)
 1419 {
 1420     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1421 
 1422     TRACE("iface %p, transform %p.\n", iface, transform);
 1423 
 1424     render_target->drawing_state.transform = *transform;
 1425 }
 1426 
 1427 static void STDMETHODCALLTYPE d2d_device_context_GetTransform(ID2D1DeviceContext *iface,
 1428         D2D1_MATRIX_3X2_F *transform)
 1429 {
 1430     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1431 
 1432     TRACE("iface %p, transform %p.\n", iface, transform);
 1433 
 1434     *transform = render_target->drawing_state.transform;
 1435 }
 1436 
 1437 static void STDMETHODCALLTYPE d2d_device_context_SetAntialiasMode(ID2D1DeviceContext *iface,
 1438         D2D1_ANTIALIAS_MODE antialias_mode)
 1439 {
 1440     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1441 
 1442     TRACE("iface %p, antialias_mode %#x stub!\n", iface, antialias_mode);
 1443 
 1444     render_target->drawing_state.antialiasMode = antialias_mode;
 1445 }
 1446 
 1447 static D2D1_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_device_context_GetAntialiasMode(ID2D1DeviceContext *iface)
 1448 {
 1449     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1450 
 1451     TRACE("iface %p.\n", iface);
 1452 
 1453     return render_target->drawing_state.antialiasMode;
 1454 }
 1455 
 1456 static void STDMETHODCALLTYPE d2d_device_context_SetTextAntialiasMode(ID2D1DeviceContext *iface,
 1457         D2D1_TEXT_ANTIALIAS_MODE antialias_mode)
 1458 {
 1459     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1460 
 1461     TRACE("iface %p, antialias_mode %#x.\n", iface, antialias_mode);
 1462 
 1463     render_target->drawing_state.textAntialiasMode = antialias_mode;
 1464 }
 1465 
 1466 static D2D1_TEXT_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_device_context_GetTextAntialiasMode(ID2D1DeviceContext *iface)
 1467 {
 1468     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1469 
 1470     TRACE("iface %p.\n", iface);
 1471 
 1472     return render_target->drawing_state.textAntialiasMode;
 1473 }
 1474 
 1475 static void STDMETHODCALLTYPE d2d_device_context_SetTextRenderingParams(ID2D1DeviceContext *iface,
 1476         IDWriteRenderingParams *text_rendering_params)
 1477 {
 1478     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1479 
 1480     TRACE("iface %p, text_rendering_params %p.\n", iface, text_rendering_params);
 1481 
 1482     if (text_rendering_params)
 1483         IDWriteRenderingParams_AddRef(text_rendering_params);
 1484     if (render_target->text_rendering_params)
 1485         IDWriteRenderingParams_Release(render_target->text_rendering_params);
 1486     render_target->text_rendering_params = text_rendering_params;
 1487 }
 1488 
 1489 static void STDMETHODCALLTYPE d2d_device_context_GetTextRenderingParams(ID2D1DeviceContext *iface,
 1490         IDWriteRenderingParams **text_rendering_params)
 1491 {
 1492     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1493 
 1494     TRACE("iface %p, text_rendering_params %p.\n", iface, text_rendering_params);
 1495 
 1496     if ((*text_rendering_params = render_target->text_rendering_params))
 1497         IDWriteRenderingParams_AddRef(*text_rendering_params);
 1498 }
 1499 
 1500 static void STDMETHODCALLTYPE d2d_device_context_SetTags(ID2D1DeviceContext *iface, D2D1_TAG tag1, D2D1_TAG tag2)
 1501 {
 1502     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1503 
 1504     TRACE("iface %p, tag1 %s, tag2 %s.\n", iface, wine_dbgstr_longlong(tag1), wine_dbgstr_longlong(tag2));
 1505 
 1506     render_target->drawing_state.tag1 = tag1;
 1507     render_target->drawing_state.tag2 = tag2;
 1508 }
 1509 
 1510 static void STDMETHODCALLTYPE d2d_device_context_GetTags(ID2D1DeviceContext *iface, D2D1_TAG *tag1, D2D1_TAG *tag2)
 1511 {
 1512     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1513 
 1514     TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2);
 1515 
 1516     *tag1 = render_target->drawing_state.tag1;
 1517     *tag2 = render_target->drawing_state.tag2;
 1518 }
 1519 
 1520 static void STDMETHODCALLTYPE d2d_device_context_PushLayer(ID2D1DeviceContext *iface,
 1521         const D2D1_LAYER_PARAMETERS *layer_parameters, ID2D1Layer *layer)
 1522 {
 1523     FIXME("iface %p, layer_parameters %p, layer %p stub!\n", iface, layer_parameters, layer);
 1524 }
 1525 
 1526 static void STDMETHODCALLTYPE d2d_device_context_PopLayer(ID2D1DeviceContext *iface)
 1527 {
 1528     FIXME("iface %p stub!\n", iface);
 1529 }
 1530 
 1531 static HRESULT STDMETHODCALLTYPE d2d_device_context_Flush(ID2D1DeviceContext *iface, D2D1_TAG *tag1, D2D1_TAG *tag2)
 1532 {
 1533     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
 1534 
 1535     FIXME("iface %p, tag1 %p, tag2 %p stub!\n", iface, tag1, tag2);
 1536 
 1537     if (context->ops && context->ops->device_context_present)
 1538         context->ops->device_context_present(context->outer_unknown);
 1539 
 1540     return E_NOTIMPL;
 1541 }
 1542 
 1543 static void STDMETHODCALLTYPE d2d_device_context_SaveDrawingState(ID2D1DeviceContext *iface,
 1544         ID2D1DrawingStateBlock *state_block)
 1545 {
 1546     struct d2d_state_block *state_block_impl = unsafe_impl_from_ID2D1DrawingStateBlock(state_block);
 1547     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1548 
 1549     TRACE("iface %p, state_block %p.\n", iface, state_block);
 1550 
 1551     state_block_impl->drawing_state = render_target->drawing_state;
 1552     if (render_target->text_rendering_params)
 1553         IDWriteRenderingParams_AddRef(render_target->text_rendering_params);
 1554     if (state_block_impl->text_rendering_params)
 1555         IDWriteRenderingParams_Release(state_block_impl->text_rendering_params);
 1556     state_block_impl->text_rendering_params = render_target->text_rendering_params;
 1557 }
 1558 
 1559 static void STDMETHODCALLTYPE d2d_device_context_RestoreDrawingState(ID2D1DeviceContext *iface,
 1560         ID2D1DrawingStateBlock *state_block)
 1561 {
 1562     struct d2d_state_block *state_block_impl = unsafe_impl_from_ID2D1DrawingStateBlock(state_block);
 1563     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1564 
 1565     TRACE("iface %p, state_block %p.\n", iface, state_block);
 1566 
 1567     render_target->drawing_state = state_block_impl->drawing_state;
 1568     if (state_block_impl->text_rendering_params)
 1569         IDWriteRenderingParams_AddRef(state_block_impl->text_rendering_params);
 1570     if (render_target->text_rendering_params)
 1571         IDWriteRenderingParams_Release(render_target->text_rendering_params);
 1572     render_target->text_rendering_params = state_block_impl->text_rendering_params;
 1573 }
 1574 
 1575 static void STDMETHODCALLTYPE d2d_device_context_PushAxisAlignedClip(ID2D1DeviceContext *iface,
 1576         const D2D1_RECT_F *clip_rect, D2D1_ANTIALIAS_MODE antialias_mode)
 1577 {
 1578     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1579     D2D1_RECT_F transformed_rect;
 1580     float x_scale, y_scale;
 1581     D2D1_POINT_2F point;
 1582 
 1583     TRACE("iface %p, clip_rect %s, antialias_mode %#x.\n", iface, debug_d2d_rect_f(clip_rect), antialias_mode);
 1584 
 1585     if (antialias_mode != D2D1_ANTIALIAS_MODE_ALIASED)
 1586         FIXME("Ignoring antialias_mode %#x.\n", antialias_mode);
 1587 
 1588     x_scale = render_target->desc.dpiX / 96.0f;
 1589     y_scale = render_target->desc.dpiY / 96.0f;
 1590     d2d_point_transform(&point, &render_target->drawing_state.transform,
 1591             clip_rect->left * x_scale, clip_rect->top * y_scale);
 1592     d2d_rect_set(&transformed_rect, point.x, point.y, point.x, point.y);
 1593     d2d_point_transform(&point, &render_target->drawing_state.transform,
 1594             clip_rect->left * x_scale, clip_rect->bottom * y_scale);
 1595     d2d_rect_expand(&transformed_rect, &point);
 1596     d2d_point_transform(&point, &render_target->drawing_state.transform,
 1597             clip_rect->right * x_scale, clip_rect->top * y_scale);
 1598     d2d_rect_expand(&transformed_rect, &point);
 1599     d2d_point_transform(&point, &render_target->drawing_state.transform,
 1600             clip_rect->right * x_scale, clip_rect->bottom * y_scale);
 1601     d2d_rect_expand(&transformed_rect, &point);
 1602 
 1603     if (!d2d_clip_stack_push(&render_target->clip_stack, &transformed_rect))
 1604         WARN("Failed to push clip rect.\n");
 1605 }
 1606 
 1607 static void STDMETHODCALLTYPE d2d_device_context_PopAxisAlignedClip(ID2D1DeviceContext *iface)
 1608 {
 1609     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1610 
 1611     TRACE("iface %p.\n", iface);
 1612 
 1613     d2d_clip_stack_pop(&render_target->clip_stack);
 1614 }
 1615 
 1616 static void STDMETHODCALLTYPE d2d_device_context_Clear(ID2D1DeviceContext *iface, const D2D1_COLOR_F *colour)
 1617 {
 1618     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1619     D3D10_SUBRESOURCE_DATA buffer_data;
 1620     struct d2d_ps_cb ps_cb_data = {0};
 1621     D3D10_BUFFER_DESC buffer_desc;
 1622     ID3D10Buffer *vs_cb, *ps_cb;
 1623     D2D1_COLOR_F *c;
 1624     HRESULT hr;
 1625 
 1626     static const struct
 1627     {
 1628         struct
 1629         {
 1630             float _11, _21, _31, pad0;
 1631             float _12, _22, _32, pad1;
 1632         } transform_geometry;
 1633         struct d2d_vec4 transform_rtx;
 1634         struct d2d_vec4 transform_rty;
 1635     }
 1636     vs_cb_data =
 1637     {
 1638         {1.0f, 0.0f, 0.0f,  0.0f,
 1639          0.0f, 1.0f, 0.0f,  0.0f},
 1640         {1.0f, 0.0f, 1.0f,  1.0f},
 1641         {0.0f, 1.0f, 1.0f, -1.0f},
 1642     };
 1643 
 1644     TRACE("iface %p, colour %p.\n", iface, colour);
 1645 
 1646     buffer_desc.ByteWidth = sizeof(vs_cb_data);
 1647     buffer_desc.Usage = D3D10_USAGE_DEFAULT;
 1648     buffer_desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
 1649     buffer_desc.CPUAccessFlags = 0;
 1650     buffer_desc.MiscFlags = 0;
 1651 
 1652     buffer_data.pSysMem = &vs_cb_data;
 1653     buffer_data.SysMemPitch = 0;
 1654     buffer_data.SysMemSlicePitch = 0;
 1655 
 1656     if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &vs_cb)))
 1657     {
 1658         WARN("Failed to create constant buffer, hr %#x.\n", hr);
 1659         return;
 1660     }
 1661 
 1662     ps_cb_data.outline = FALSE;
 1663     ps_cb_data.colour_brush.type = D2D_BRUSH_TYPE_SOLID;
 1664     ps_cb_data.colour_brush.opacity = 1.0f;
 1665     c = &ps_cb_data.colour_brush.u.solid.colour;
 1666     if (colour)
 1667         *c = *colour;
 1668     if (render_target->desc.pixelFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE)
 1669         c->a = 1.0f;
 1670     c->r *= c->a;
 1671     c->g *= c->a;
 1672     c->b *= c->a;
 1673 
 1674     ps_cb_data.opacity_brush.type = D2D_BRUSH_TYPE_COUNT;
 1675 
 1676     buffer_desc.ByteWidth = sizeof(ps_cb_data);
 1677     buffer_data.pSysMem = &ps_cb_data;
 1678 
 1679     if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->d3d_device, &buffer_desc, &buffer_data, &ps_cb)))
 1680     {
 1681         WARN("Failed to create constant buffer, hr %#x.\n", hr);
 1682         ID3D10Buffer_Release(vs_cb);
 1683         return;
 1684     }
 1685 
 1686     d2d_device_context_draw(render_target, D2D_SHAPE_TYPE_TRIANGLE, render_target->ib, 6,
 1687             render_target->vb, render_target->vb_stride, vs_cb, ps_cb, NULL, NULL);
 1688 
 1689     ID3D10Buffer_Release(ps_cb);
 1690     ID3D10Buffer_Release(vs_cb);
 1691 }
 1692 
 1693 static void STDMETHODCALLTYPE d2d_device_context_BeginDraw(ID2D1DeviceContext *iface)
 1694 {
 1695     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1696 
 1697     TRACE("iface %p.\n", iface);
 1698 
 1699     memset(&render_target->error, 0, sizeof(render_target->error));
 1700 }
 1701 
 1702 static HRESULT STDMETHODCALLTYPE d2d_device_context_EndDraw(ID2D1DeviceContext *iface,
 1703         D2D1_TAG *tag1, D2D1_TAG *tag2)
 1704 {
 1705     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
 1706     HRESULT hr;
 1707 
 1708     TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2);
 1709 
 1710     if (tag1)
 1711         *tag1 = context->error.tag1;
 1712     if (tag2)
 1713         *tag2 = context->error.tag2;
 1714 
 1715     if (context->ops && context->ops->device_context_present)
 1716     {
 1717         if (FAILED(hr = context->ops->device_context_present(context->outer_unknown)))
 1718             context->error.code = hr;
 1719     }
 1720 
 1721     return context->error.code;
 1722 }
 1723 
 1724 static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_device_context_GetPixelFormat(ID2D1DeviceContext *iface,
 1725         D2D1_PIXEL_FORMAT *format)
 1726 {
 1727     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1728 
 1729     TRACE("iface %p, format %p.\n", iface, format);
 1730 
 1731     *format = render_target->desc.pixelFormat;
 1732     return format;
 1733 }
 1734 
 1735 static void STDMETHODCALLTYPE d2d_device_context_SetDpi(ID2D1DeviceContext *iface, float dpi_x, float dpi_y)
 1736 {
 1737     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1738 
 1739     TRACE("iface %p, dpi_x %.8e, dpi_y %.8e.\n", iface, dpi_x, dpi_y);
 1740 
 1741     if (dpi_x == 0.0f && dpi_y == 0.0f)
 1742     {
 1743         dpi_x = 96.0f;
 1744         dpi_y = 96.0f;
 1745     }
 1746     else if (dpi_x <= 0.0f || dpi_y <= 0.0f)
 1747         return;
 1748 
 1749     render_target->desc.dpiX = dpi_x;
 1750     render_target->desc.dpiY = dpi_y;
 1751 }
 1752 
 1753 static void STDMETHODCALLTYPE d2d_device_context_GetDpi(ID2D1DeviceContext *iface, float *dpi_x, float *dpi_y)
 1754 {
 1755     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1756 
 1757     TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface, dpi_x, dpi_y);
 1758 
 1759     *dpi_x = render_target->desc.dpiX;
 1760     *dpi_y = render_target->desc.dpiY;
 1761 }
 1762 
 1763 static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_device_context_GetSize(ID2D1DeviceContext *iface, D2D1_SIZE_F *size)
 1764 {
 1765     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1766 
 1767     TRACE("iface %p, size %p.\n", iface, size);
 1768 
 1769     size->width = render_target->pixel_size.width / (render_target->desc.dpiX / 96.0f);
 1770     size->height = render_target->pixel_size.height / (render_target->desc.dpiY / 96.0f);
 1771     return size;
 1772 }
 1773 
 1774 static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_device_context_GetPixelSize(ID2D1DeviceContext *iface,
 1775         D2D1_SIZE_U *pixel_size)
 1776 {
 1777     struct d2d_device_context *render_target = impl_from_ID2D1DeviceContext(iface);
 1778 
 1779     TRACE("iface %p, pixel_size %p.\n", iface, pixel_size);
 1780 
 1781     *pixel_size = render_target->pixel_size;
 1782     return pixel_size;
 1783 }
 1784 
 1785 static UINT32 STDMETHODCALLTYPE d2d_device_context_GetMaximumBitmapSize(ID2D1DeviceContext *iface)
 1786 {
 1787     TRACE("iface %p.\n", iface);
 1788 
 1789     return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
 1790 }
 1791 
 1792 static BOOL STDMETHODCALLTYPE d2d_device_context_IsSupported(ID2D1DeviceContext *iface,
 1793         const D2D1_RENDER_TARGET_PROPERTIES *desc)
 1794 {
 1795     FIXME("iface %p, desc %p stub!\n", iface, desc);
 1796 
 1797     return FALSE;
 1798 }
 1799 
 1800 static HRESULT STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_CreateBitmap(ID2D1DeviceContext *iface,
 1801         D2D1_SIZE_U size, const void *src_data, UINT32 pitch,
 1802         const D2D1_BITMAP_PROPERTIES1 *desc, ID2D1Bitmap1 **bitmap)
 1803 {
 1804     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
 1805     struct d2d_bitmap *object;
 1806     HRESULT hr;
 1807 
 1808     TRACE("iface %p, size {%u, %u}, src_data %p, pitch %u, desc %p, bitmap %p.\n",
 1809             iface, size.width, size.height, src_data, pitch, desc, bitmap);
 1810 
 1811     if (SUCCEEDED(hr = d2d_bitmap_create(context, size, src_data, pitch, desc, &object)))
 1812         *bitmap = &object->ID2D1Bitmap1_iface;
 1813 
 1814     return hr;
 1815 }
 1816 
 1817 static HRESULT STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_CreateBitmapFromWicBitmap(
 1818         ID2D1DeviceContext *iface, IWICBitmapSource *bitmap_source,
 1819         const D2D1_BITMAP_PROPERTIES1 *desc, ID2D1Bitmap1 **bitmap)
 1820 {
 1821     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
 1822     struct d2d_bitmap *object;
 1823     HRESULT hr;
 1824 
 1825     TRACE("iface %p, bitmap_source %p, desc %p, bitmap %p.\n", iface, bitmap_source, desc, bitmap);
 1826 
 1827     if (SUCCEEDED(hr = d2d_bitmap_create_from_wic_bitmap(context, bitmap_source, desc, &object)))
 1828         *bitmap = &object->ID2D1Bitmap1_iface;
 1829 
 1830     return hr;
 1831 }
 1832 
 1833 static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateColorContext(ID2D1DeviceContext *iface,
 1834         D2D1_COLOR_SPACE space, const BYTE *profile, UINT32 profile_size, ID2D1ColorContext **color_context)
 1835 {
 1836     FIXME("iface %p, space %#x, profile %p, profile_size %u, color_context %p stub!\n",
 1837             iface, space, profile, profile_size, color_context);
 1838 
 1839     return E_NOTIMPL;
 1840 }
 1841 
 1842 static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateColorContextFromFilename(ID2D1DeviceContext *iface,
 1843         const WCHAR *filename, ID2D1ColorContext **color_context)
 1844 {
 1845     FIXME("iface %p, filename %s, color_context %p stub!\n", iface, debugstr_w(filename), color_context);
 1846 
 1847     return E_NOTIMPL;
 1848 }
 1849 
 1850 static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateColorContextFromWicColorContext(ID2D1DeviceContext *iface,
 1851         IWICColorContext *wic_color_context, ID2D1ColorContext **color_context)
 1852 {
 1853     FIXME("iface %p, wic_color_context %p, color_context %p stub!\n", iface, wic_color_context, color_context);
 1854 
 1855     return E_NOTIMPL;
 1856 }
 1857 
 1858 static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateBitmapFromDxgiSurface(ID2D1DeviceContext *iface,
 1859         IDXGISurface *surface, const D2D1_BITMAP_PROPERTIES1 *desc, ID2D1Bitmap1 **bitmap)
 1860 {
 1861     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
 1862     D2D1_BITMAP_PROPERTIES1 bitmap_desc;
 1863     struct d2d_bitmap *object;
 1864     HRESULT hr;
 1865 
 1866     TRACE("iface %p, surface %p, desc %p, bitmap %p.\n", iface, surface, desc, bitmap);
 1867 
 1868     if (!desc)
 1869     {
 1870         DXGI_SURFACE_DESC surface_desc;
 1871 
 1872         if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc)))
 1873         {
 1874             WARN("Failed to get surface desc, hr %#x.\n", hr);
 1875             return hr;
 1876         }
 1877 
 1878         memset(&bitmap_desc, 0, sizeof(bitmap_desc));
 1879         bitmap_desc.pixelFormat.format = surface_desc.Format;
 1880         bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
 1881         bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
 1882         desc = &bitmap_desc;
 1883     }
 1884 
 1885     if (SUCCEEDED(hr = d2d_bitmap_create_shared(context, &IID_IDXGISurface, surface, desc, &object)))
 1886         *bitmap = &object->ID2D1Bitmap1_iface;
 1887 
 1888     return hr;
 1889 }
 1890 
 1891 static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateEffect(ID2D1DeviceContext *iface,
 1892         REFCLSID effect_id, ID2D1Effect **effect)
 1893 {
 1894     struct d2d_effect *object;
 1895 
 1896     FIXME("iface %p, effect_id %s, effect %p stub!\n", iface, debugstr_guid(effect_id), effect);
 1897 
 1898     if (!(object = heap_alloc_zero(sizeof(*object))))
 1899         return E_OUTOFMEMORY;
 1900 
 1901     d2d_effect_init(object);
 1902 
 1903     TRACE("Created effect %p.\n", object);
 1904     *effect = &object->ID2D1Effect_iface;
 1905 
 1906     return S_OK;
 1907 }
 1908 
 1909 static HRESULT STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_CreateGradientStopCollection(
 1910         ID2D1DeviceContext *iface, const D2D1_GRADIENT_STOP *stops, UINT32 stop_count,
 1911         D2D1_COLOR_SPACE preinterpolation_space, D2D1_COLOR_SPACE postinterpolation_space,
 1912         D2D1_BUFFER_PRECISION buffer_precision, D2D1_EXTEND_MODE extend_mode,
 1913         D2D1_COLOR_INTERPOLATION_MODE color_interpolation_mode, ID2D1GradientStopCollection1 **gradient)
 1914 {
 1915     FIXME("iface %p, stops %p, stop_count %u, preinterpolation_space %#x, postinterpolation_space %#x, "
 1916             "buffer_precision %#x, extend_mode %#x, color_interpolation_mode %#x, gradient %p stub!\n",
 1917             iface, stops, stop_count, preinterpolation_space, postinterpolation_space,
 1918             buffer_precision, extend_mode, color_interpolation_mode, gradient);
 1919 
 1920     return E_NOTIMPL;
 1921 }
 1922 
 1923 static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateImageBrush(ID2D1DeviceContext *iface,
 1924         ID2D1Image *image, const D2D1_IMAGE_BRUSH_PROPERTIES *image_brush_desc,
 1925         const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1ImageBrush **brush)
 1926 {
 1927     FIXME("iface %p, image %p, image_brush_desc %p, brush_desc %p, brush %p stub!\n",
 1928             iface, image, image_brush_desc, brush_desc, brush);
 1929 
 1930     return E_NOTIMPL;
 1931 }
 1932 
 1933 static HRESULT STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_CreateBitmapBrush(ID2D1DeviceContext *iface,
 1934         ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES1 *bitmap_brush_desc,
 1935         const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1BitmapBrush1 **brush)
 1936 {
 1937     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
 1938     struct d2d_brush *object;
 1939     HRESULT hr;
 1940 
 1941     TRACE("iface %p, bitmap %p, bitmap_brush_desc %p, brush_desc %p, brush %p.\n", iface, bitmap, bitmap_brush_desc,
 1942             brush_desc, brush);
 1943 
 1944     if (SUCCEEDED(hr = d2d_bitmap_brush_create(context->factory, bitmap, bitmap_brush_desc, brush_desc, &object)))
 1945         *brush = (ID2D1BitmapBrush1 *)&object->ID2D1Brush_iface;
 1946 
 1947     return hr;
 1948 }
 1949 
 1950 static HRESULT STDMETHODCALLTYPE d2d_device_context_CreateCommandList(ID2D1DeviceContext *iface,
 1951         ID2D1CommandList **command_list)
 1952 {
 1953     FIXME("iface %p, command_list %p stub!\n", iface, command_list);
 1954 
 1955     return E_NOTIMPL;
 1956 }
 1957 
 1958 static BOOL STDMETHODCALLTYPE d2d_device_context_IsDxgiFormatSupported(ID2D1DeviceContext *iface, DXGI_FORMAT format)
 1959 {
 1960     FIXME("iface %p, format %#x stub!\n", iface, format);
 1961 
 1962     return FALSE;
 1963 }
 1964 
 1965 static BOOL STDMETHODCALLTYPE d2d_device_context_IsBufferPrecisionSupported(ID2D1DeviceContext *iface,
 1966         D2D1_BUFFER_PRECISION buffer_precision)
 1967 {
 1968     FIXME("iface %p, buffer_precision %#x stub!\n", iface, buffer_precision);
 1969 
 1970     return FALSE;
 1971 }
 1972 
 1973 static void STDMETHODCALLTYPE d2d_device_context_GetImageLocalBounds(ID2D1DeviceContext *iface,
 1974         ID2D1Image *image, D2D1_RECT_F *local_bounds)
 1975 {
 1976     FIXME("iface %p, image %p, local_bounds %p stub!\n", iface, image, local_bounds);
 1977 }
 1978 
 1979 static HRESULT STDMETHODCALLTYPE d2d_device_context_GetImageWorldBounds(ID2D1DeviceContext *iface,
 1980         ID2D1Image *image, D2D1_RECT_F *world_bounds)
 1981 {
 1982     FIXME("iface %p, image %p, world_bounds %p stub!\n", iface, image, world_bounds);
 1983 
 1984     return E_NOTIMPL;
 1985 }
 1986 
 1987 static HRESULT STDMETHODCALLTYPE d2d_device_context_GetGlyphRunWorldBounds(ID2D1DeviceContext *iface,
 1988         D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run,
 1989         DWRITE_MEASURING_MODE measuring_mode, D2D1_RECT_F *bounds)
 1990 {
 1991     FIXME("iface %p, baseline_origin %s, glyph_run %p, measuring_mode %#x, bounds %p stub!\n",
 1992             iface, debug_d2d_point_2f(&baseline_origin), glyph_run, measuring_mode, bounds);
 1993 
 1994     return E_NOTIMPL;
 1995 }
 1996 
 1997 static void STDMETHODCALLTYPE d2d_device_context_GetDevice(ID2D1DeviceContext *iface, ID2D1Device **device)
 1998 {
 1999     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
 2000 
 2001     TRACE("iface %p, device %p.\n", iface, device);
 2002 
 2003     *device = context->device;
 2004     ID2D1Device_AddRef(*device);
 2005 }
 2006 
 2007 static void d2d_device_context_reset_target(struct d2d_device_context *context)
 2008 {
 2009     if (!context->target)
 2010         return;
 2011 
 2012     ID2D1Bitmap1_Release(&context->target->ID2D1Bitmap1_iface);
 2013     context->target = NULL;
 2014 
 2015     /* Note that DPI settings are kept. */
 2016     memset(&context->desc.pixelFormat, 0, sizeof(context->desc.pixelFormat));
 2017     memset(&context->pixel_size, 0, sizeof(context->pixel_size));
 2018 
 2019     ID3D10BlendState_Release(context->bs);
 2020     context->bs = NULL;
 2021 }
 2022 
 2023 static void STDMETHODCALLTYPE d2d_device_context_SetTarget(ID2D1DeviceContext *iface, ID2D1Image *target)
 2024 {
 2025     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
 2026     struct d2d_bitmap *bitmap_impl;
 2027     D3D10_BLEND_DESC blend_desc;
 2028     ID2D1Bitmap *bitmap;
 2029     HRESULT hr;
 2030 
 2031     TRACE("iface %p, target %p.\n", iface, target);
 2032 
 2033     if (!target)
 2034     {
 2035         d2d_device_context_reset_target(context);
 2036         return;
 2037     }
 2038 
 2039     if (FAILED(ID2D1Image_QueryInterface(target, &IID_ID2D1Bitmap, (void **)&bitmap)))
 2040     {
 2041         FIXME("Only bitmap targets are supported.\n");
 2042         return;
 2043     }
 2044 
 2045     bitmap_impl = unsafe_impl_from_ID2D1Bitmap(bitmap);
 2046 
 2047     if (!(bitmap_impl->options & D2D1_BITMAP_OPTIONS_TARGET))
 2048     {
 2049         d2d_device_context_set_error(context, D2DERR_INVALID_TARGET);
 2050         return;
 2051     }
 2052 
 2053     d2d_device_context_reset_target(context);
 2054 
 2055     /* Set sizes and pixel format. */
 2056     context->pixel_size = bitmap_impl->pixel_size;
 2057     context->desc.pixelFormat = bitmap_impl->format;
 2058     context->target = bitmap_impl;
 2059 
 2060     memset(&blend_desc, 0, sizeof(blend_desc));
 2061     blend_desc.BlendEnable[0] = TRUE;
 2062     blend_desc.SrcBlend = D3D10_BLEND_ONE;
 2063     blend_desc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA;
 2064     blend_desc.BlendOp = D3D10_BLEND_OP_ADD;
 2065     if (context->desc.pixelFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE)
 2066     {
 2067         blend_desc.SrcBlendAlpha = D3D10_BLEND_ZERO;
 2068         blend_desc.DestBlendAlpha = D3D10_BLEND_ONE;
 2069     }
 2070     else
 2071     {
 2072         blend_desc.SrcBlendAlpha = D3D10_BLEND_ONE;
 2073         blend_desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA;
 2074     }
 2075     blend_desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
 2076     blend_desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
 2077     if (FAILED(hr = ID3D10Device_CreateBlendState(context->d3d_device, &blend_desc, &context->bs)))
 2078         WARN("Failed to create blend state, hr %#x.\n", hr);
 2079 }
 2080 
 2081 static void STDMETHODCALLTYPE d2d_device_context_GetTarget(ID2D1DeviceContext *iface, ID2D1Image **target)
 2082 {
 2083     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
 2084 
 2085     TRACE("iface %p, target %p.\n", iface, target);
 2086 
 2087     *target = context->target ? (ID2D1Image *)&context->target->ID2D1Bitmap1_iface : NULL;
 2088     if (*target)
 2089         ID2D1Image_AddRef(*target);
 2090 }
 2091 
 2092 static void STDMETHODCALLTYPE d2d_device_context_SetRenderingControls(ID2D1DeviceContext *iface,
 2093         const D2D1_RENDERING_CONTROLS *rendering_controls)
 2094 {
 2095     FIXME("iface %p, rendering_controls %p stub!\n", iface, rendering_controls);
 2096 }
 2097 
 2098 static void STDMETHODCALLTYPE d2d_device_context_GetRenderingControls(ID2D1DeviceContext *iface,
 2099         D2D1_RENDERING_CONTROLS *rendering_controls)
 2100 {
 2101     FIXME("iface %p, rendering_controls %p stub!\n", iface, rendering_controls);
 2102 }
 2103 
 2104 static void STDMETHODCALLTYPE d2d_device_context_SetPrimitiveBlend(ID2D1DeviceContext *iface,
 2105         D2D1_PRIMITIVE_BLEND primitive_blend)
 2106 {
 2107     FIXME("iface %p, primitive_blend %#x stub!\n", iface, primitive_blend);
 2108 }
 2109 
 2110 static D2D1_PRIMITIVE_BLEND STDMETHODCALLTYPE d2d_device_context_GetPrimitiveBlend(ID2D1DeviceContext *iface)
 2111 {
 2112     FIXME("iface %p stub!\n", iface);
 2113 
 2114     return D2D1_PRIMITIVE_BLEND_SOURCE_OVER;
 2115 }
 2116 
 2117 static void STDMETHODCALLTYPE d2d_device_context_SetUnitMode(ID2D1DeviceContext *iface, D2D1_UNIT_MODE unit_mode)
 2118 {
 2119     FIXME("iface %p, unit_mode %#x stub!\n", iface, unit_mode);
 2120 }
 2121 
 2122 static D2D1_UNIT_MODE STDMETHODCALLTYPE d2d_device_context_GetUnitMode(ID2D1DeviceContext *iface)
 2123 {
 2124     FIXME("iface %p stub!\n", iface);
 2125 
 2126     return D2D1_UNIT_MODE_DIPS;
 2127 }
 2128 
 2129 static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_DrawGlyphRun(ID2D1DeviceContext *iface,
 2130         D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run,
 2131         const DWRITE_GLYPH_RUN_DESCRIPTION *glyph_run_desc, ID2D1Brush *brush, DWRITE_MEASURING_MODE measuring_mode)
 2132 {
 2133     DWRITE_TEXT_ANTIALIAS_MODE antialias_mode = DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE;
 2134     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
 2135     IDWriteRenderingParams *rendering_params;
 2136     DWRITE_RENDERING_MODE rendering_mode;
 2137     HRESULT hr;
 2138 
 2139     TRACE("iface %p, baseline_origin %s, glyph_run %p, glyph_run_desc %p, brush %p, measuring_mode %#x.\n",
 2140             iface, debug_d2d_point_2f(&baseline_origin), glyph_run, glyph_run_desc, brush, measuring_mode);
 2141 
 2142     if (FAILED(context->error.code))
 2143         return;
 2144 
 2145     rendering_params = context->text_rendering_params ? context->text_rendering_params
 2146             : context->default_text_rendering_params;
 2147 
 2148     rendering_mode = IDWriteRenderingParams_GetRenderingMode(rendering_params);
 2149 
 2150     switch (context->drawing_state.textAntialiasMode)
 2151     {
 2152         case D2D1_TEXT_ANTIALIAS_MODE_ALIASED:
 2153             if (rendering_mode == DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL
 2154                     || rendering_mode == DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC
 2155                     || rendering_mode == DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL
 2156                     || rendering_mode == DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC)
 2157                 d2d_device_context_set_error(context, E_INVALIDARG);
 2158             break;
 2159 
 2160         case D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE:
 2161             if (rendering_mode == DWRITE_RENDERING_MODE_ALIASED
 2162                     || rendering_mode == DWRITE_RENDERING_MODE_OUTLINE)
 2163                 d2d_device_context_set_error(context, E_INVALIDARG);
 2164             break;
 2165 
 2166         case D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE:
 2167             if (rendering_mode == DWRITE_RENDERING_MODE_ALIASED)
 2168                 d2d_device_context_set_error(context, E_INVALIDARG);
 2169             break;
 2170 
 2171         default:
 2172             break;
 2173     }
 2174 
 2175     if (FAILED(context->error.code))
 2176         return;
 2177 
 2178     rendering_mode = DWRITE_RENDERING_MODE_DEFAULT;
 2179     switch (context->drawing_state.textAntialiasMode)
 2180     {
 2181         case D2D1_TEXT_ANTIALIAS_MODE_DEFAULT:
 2182             if (IDWriteRenderingParams_GetClearTypeLevel(rendering_params) > 0.0f)
 2183                 antialias_mode = DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE;
 2184             break;
 2185 
 2186         case D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE:
 2187             antialias_mode = DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE;
 2188             break;
 2189 
 2190         case D2D1_TEXT_ANTIALIAS_MODE_ALIASED:
 2191             rendering_mode = DWRITE_RENDERING_MODE_ALIASED;
 2192             break;
 2193 
 2194         default:
 2195             break;
 2196     }
 2197 
 2198     if (rendering_mode == DWRITE_RENDERING_MODE_DEFAULT)
 2199     {
 2200         if (FAILED(hr = IDWriteFontFace_GetRecommendedRenderingMode(glyph_run->fontFace, glyph_run->fontEmSize,
 2201                 max(context->desc.dpiX, context->desc.dpiY) / 96.0f,
 2202                 measuring_mode, rendering_params, &rendering_mode)))
 2203         {
 2204             ERR("Failed to get recommended rendering mode, hr %#x.\n", hr);
 2205             rendering_mode = DWRITE_RENDERING_MODE_OUTLINE;
 2206         }
 2207     }
 2208 
 2209     if (rendering_mode == DWRITE_RENDERING_MODE_OUTLINE)
 2210         d2d_device_context_draw_glyph_run_outline(context, baseline_origin, glyph_run, brush);
 2211     else
 2212         d2d_device_context_draw_glyph_run_bitmap(context, baseline_origin, glyph_run, brush,
 2213                 rendering_mode, measuring_mode, antialias_mode);
 2214 }
 2215 
 2216 static void STDMETHODCALLTYPE d2d_device_context_DrawImage(ID2D1DeviceContext *iface, ID2D1Image *image,
 2217         const D2D1_POINT_2F *target_offset, const D2D1_RECT_F *image_rect, D2D1_INTERPOLATION_MODE interpolation_mode,
 2218         D2D1_COMPOSITE_MODE composite_mode)
 2219 {
 2220     FIXME("iface %p, image %p, target_offset %s, image_rect %s, interpolation_mode %#x, composite_mode %#x stub!\n",
 2221             iface, image, debug_d2d_point_2f(target_offset), debug_d2d_rect_f(image_rect),
 2222             interpolation_mode, composite_mode);
 2223 }
 2224 
 2225 static void STDMETHODCALLTYPE d2d_device_context_DrawGdiMetafile(ID2D1DeviceContext *iface,
 2226         ID2D1GdiMetafile *metafile, const D2D1_POINT_2F *target_offset)
 2227 {
 2228     FIXME("iface %p, metafile %p, target_offset %s stub!\n",
 2229             iface, metafile, debug_d2d_point_2f(target_offset));
 2230 }
 2231 
 2232 static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_DrawBitmap(ID2D1DeviceContext *iface,
 2233         ID2D1Bitmap *bitmap, const D2D1_RECT_F *dst_rect, float opacity, D2D1_INTERPOLATION_MODE interpolation_mode,
 2234         const D2D1_RECT_F *src_rect, const D2D1_MATRIX_4X4_F *perspective_transform)
 2235 {
 2236     struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface);
 2237 
 2238     TRACE("iface %p, bitmap %p, dst_rect %s, opacity %.8e, interpolation_mode %#x, "
 2239             "src_rect %s, perspective_transform %p.\n",
 2240             iface, bitmap, debug_d2d_rect_f(dst_rect), opacity, interpolation_mode,
 2241             debug_d2d_rect_f(src_rect), perspective_transform);
 2242 
 2243     d2d_device_context_draw_bitmap(context, bitmap, dst_rect, opacity, interpolation_mode, src_rect,
 2244             perspective_transform);
 2245 }
 2246 
 2247 static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_PushLayer(ID2D1DeviceContext *iface,
 2248         const D2D1_LAYER_PARAMETERS1 *layer_parameters, ID2D1Layer *layer)
 2249 {
 2250     FIXME("iface %p, layer_parameters %p, layer %p stub!\n", iface, layer_parameters, layer);
 2251 }
 2252 
 2253 static HRESULT STDMETHODCALLTYPE d2d_device_context_InvalidateEffectInputRectangle(ID2D1DeviceContext *iface,
 2254         ID2D1Effect *effect, UINT32 input, const D2D1_RECT_F *input_rect)
 2255 {
 2256     FIXME("iface %p, effect %p, input %u, input_rect %s stub!\n",
 2257             iface, effect, input, debug_d2d_rect_f(input_rect));
 2258 
 2259     return E_NOTIMPL;
 2260 }
 2261 
 2262 static HRESULT STDMETHODCALLTYPE d2d_device_context_GetEffectInvalidRectangleCount(ID2D1DeviceContext *iface,
 2263         ID2D1Effect *effect, UINT32 *rect_count)
 2264 {
 2265     FIXME("iface %p, effect %p, rect_count %p stub!\n", iface, effect, rect_count);
 2266 
 2267     return E_NOTIMPL;
 2268 }
 2269 
 2270 static HRESULT STDMETHODCALLTYPE d2d_device_context_GetEffectInvalidRectangles(ID2D1DeviceContext *iface,
 2271         ID2D1Effect *effect, D2D1_RECT_F *rectangles, UINT32 rect_count)
 2272 {
 2273     FIXME("iface %p, effect %p, rectangles %p, rect_count %u stub!\n", iface, effect, rectangles, rect_count);
 2274 
 2275     return E_NOTIMPL;
 2276 }
 2277 
 2278 static HRESULT STDMETHODCALLTYPE d2d_device_context_GetEffectRequiredInputRectangles(ID2D1DeviceContext *iface,
 2279         ID2D1Effect *effect, const D2D1_RECT_F *image_rect, const D2D1_EFFECT_INPUT_DESCRIPTION *desc,
 2280         D2D1_RECT_F *input_rect, UINT32 input_count)
 2281 {
 2282     FIXME("iface %p, effect %p, image_rect %s, desc %p, input_rect %p, input_count %u stub!\n",
 2283             iface, effect, debug_d2d_rect_f(image_rect), desc, input_rect, input_count);
 2284 
 2285     return E_NOTIMPL;
 2286 }
 2287 
 2288 static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_FillOpacityMask(ID2D1DeviceContext *iface,
 2289         ID2D1Bitmap *mask, ID2D1Brush *brush, const D2D1_RECT_F *dst_rect, const D2D1_RECT_F *src_rect)
 2290 {
 2291     FIXME("iface %p, mask %p, brush %p, dst_rect %s, src_rect %s stub!\n",
 2292             iface, mask, brush, debug_d2d_rect_f(dst_rect), debug_d2d_rect_f(src_rect));
 2293 }
 2294 
 2295 static const struct ID2D1DeviceContextVtbl d2d_device_context_vtbl =
 2296 {
 2297     d2d_device_context_QueryInterface,
 2298     d2d_device_context_AddRef,
 2299     d2d_device_context_Release,
 2300     d2d_device_context_GetFactory,
 2301     d2d_device_context_CreateBitmap,
 2302     d2d_device_context_CreateBitmapFromWicBitmap,
 2303     d2d_device_context_CreateSharedBitmap,
 2304     d2d_device_context_CreateBitmapBrush,
 2305     d2d_device_context_CreateSolidColorBrush,
 2306     d2d_device_context_CreateGradientStopCollection,
 2307     d2d_device_context_CreateLinearGradientBrush,
 2308     d2d_device_context_CreateRadialGradientBrush,
 2309     d2d_device_context_CreateCompatibleRenderTarget,
 2310     d2d_device_context_CreateLayer,
 2311     d2d_device_context_CreateMesh,
 2312     d2d_device_context_DrawLine,
 2313     d2d_device_context_DrawRectangle,
 2314     d2d_device_context_FillRectangle,
 2315     d2d_device_context_DrawRoundedRectangle,
 2316     d2d_device_context_FillRoundedRectangle,
 2317     d2d_device_context_DrawEllipse,
 2318     d2d_device_context_FillEllipse,
 2319     d2d_device_context_DrawGeometry,
 2320     d2d_device_context_FillGeometry,
 2321     d2d_device_context_FillMesh,
 2322     d2d_device_context_FillOpacityMask,
 2323     d2d_device_context_DrawBitmap,
 2324     d2d_device_context_DrawText,
 2325     d2d_device_context_DrawTextLayout,
 2326     d2d_device_context_DrawGlyphRun,
 2327     d2d_device_context_SetTransform,
 2328     d2d_device_context_GetTransform,
 2329     d2d_device_context_SetAntialiasMode,
 2330     d2d_device_context_GetAntialiasMode,
 2331     d2d_device_context_SetTextAntialiasMode,
 2332     d2d_device_context_GetTextAntialiasMode,
 2333     d2d_device_context_SetTextRenderingParams,
 2334     d2d_device_context_GetTextRenderingParams,
 2335     d2d_device_context_SetTags,
 2336     d2d_device_context_GetTags,
 2337     d2d_device_context_PushLayer,
 2338     d2d_device_context_PopLayer,
 2339     d2d_device_context_Flush,
 2340     d2d_device_context_SaveDrawingState,
 2341     d2d_device_context_RestoreDrawingState,
 2342     d2d_device_context_PushAxisAlignedClip,
 2343     d2d_device_context_PopAxisAlignedClip,
 2344     d2d_device_context_Clear,
 2345     d2d_device_context_BeginDraw,
 2346     d2d_device_context_EndDraw,
 2347     d2d_device_context_GetPixelFormat,
 2348     d2d_device_context_SetDpi,
 2349     d2d_device_context_GetDpi,
 2350     d2d_device_context_GetSize,
 2351     d2d_device_context_GetPixelSize,
 2352     d2d_device_context_GetMaximumBitmapSize,
 2353     d2d_device_context_IsSupported,
 2354     d2d_device_context_ID2D1DeviceContext_CreateBitmap,
 2355     d2d_device_context_ID2D1DeviceContext_CreateBitmapFromWicBitmap,
 2356     d2d_device_context_CreateColorContext,
 2357     d2d_device_context_CreateColorContextFromFilename,
 2358     d2d_device_context_CreateColorContextFromWicColorContext,
 2359     d2d_device_context_CreateBitmapFromDxgiSurface,
 2360     d2d_device_context_CreateEffect,
 2361     d2d_device_context_ID2D1DeviceContext_CreateGradientStopCollection,
 2362     d2d_device_context_CreateImageBrush,
 2363     d2d_device_context_ID2D1DeviceContext_CreateBitmapBrush,
 2364     d2d_device_context_CreateCommandList,
 2365     d2d_device_context_IsDxgiFormatSupported,
 2366     d2d_device_context_IsBufferPrecisionSupported,
 2367     d2d_device_context_GetImageLocalBounds,
 2368     d2d_device_context_GetImageWorldBounds,
 2369     d2d_device_context_GetGlyphRunWorldBounds,
 2370     d2d_device_context_GetDevice,
 2371     d2d_device_context_SetTarget,
 2372     d2d_device_context_GetTarget,
 2373     d2d_device_context_SetRenderingControls,
 2374     d2d_device_context_GetRenderingControls,
 2375     d2d_device_context_SetPrimitiveBlend,
 2376     d2d_device_context_GetPrimitiveBlend,
 2377     d2d_device_context_SetUnitMode,
 2378     d2d_device_context_GetUnitMode,
 2379     d2d_device_context_ID2D1DeviceContext_DrawGlyphRun,
 2380     d2d_device_context_DrawImage,
 2381     d2d_device_context_DrawGdiMetafile,
 2382     d2d_device_context_ID2D1DeviceContext_DrawBitmap,
 2383     d2d_device_context_ID2D1DeviceContext_PushLayer,
 2384     d2d_device_context_InvalidateEffectInputRectangle,
 2385     d2d_device_context_GetEffectInvalidRectangleCount,
 2386     d2d_device_context_GetEffectInvalidRectangles,
 2387     d2d_device_context_GetEffectRequiredInputRectangles,
 2388     d2d_device_context_ID2D1DeviceContext_FillOpacityMask,
 2389 };
 2390 
 2391 static inline struct d2d_device_context *impl_from_IDWriteTextRenderer(IDWriteTextRenderer *iface)
 2392 {
 2393     return CONTAINING_RECORD(iface, struct d2d_device_context, IDWriteTextRenderer_iface);
 2394 }
 2395 
 2396 static HRESULT STDMETHODCALLTYPE d2d_text_renderer_QueryInterface(IDWriteTextRenderer *iface, REFIID iid, void **out)
 2397 {
 2398     TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
 2399 
 2400     if (IsEqualGUID(iid, &IID_IDWriteTextRenderer)
 2401             || IsEqualGUID(iid, &IID_IDWritePixelSnapping)
 2402             || IsEqualGUID(iid, &IID_IUnknown))
 2403     {
 2404         IDWriteTextRenderer_AddRef(iface);
 2405         *out = iface;
 2406         return S_OK;
 2407     }
 2408 
 2409     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
 2410 
 2411     *out = NULL;
 2412     return E_NOINTERFACE;
 2413 }
 2414 
 2415 static ULONG STDMETHODCALLTYPE d2d_text_renderer_AddRef(IDWriteTextRenderer *iface)
 2416 {
 2417     struct d2d_device_context *render_target = impl_from_IDWriteTextRenderer(iface);
 2418 
 2419     TRACE("iface %p.\n", iface);
 2420 
 2421     return d2d_device_context_AddRef(&render_target->ID2D1DeviceContext_iface);
 2422 }
 2423 
 2424 static ULONG STDMETHODCALLTYPE d2d_text_renderer_Release(IDWriteTextRenderer *iface)
 2425 {
 2426     struct d2d_device_context *render_target = impl_from_IDWriteTextRenderer(iface);
 2427 
 2428     TRACE("iface %p.\n", iface);
 2429 
 2430     return d2d_device_context_Release(&render_target->ID2D1DeviceContext_iface);
 2431 }
 2432 
 2433 static HRESULT STDMETHODCALLTYPE d2d_text_renderer_IsPixelSnappingDisabled(IDWriteTextRenderer *iface,
 2434         void *ctx, BOOL *disabled)
 2435 {
 2436     struct d2d_draw_text_layout_ctx *context = ctx;
 2437 
 2438     TRACE("iface %p, ctx %p, disabled %p.\n", iface, ctx, disabled);
 2439 
 2440     *disabled = context->options & D2D1_DRAW_TEXT_OPTIONS_NO_SNAP;
 2441 
 2442     return S_OK;
 2443 }
 2444 
 2445 static HRESULT STDMETHODCALLTYPE d2d_text_renderer_GetCurrentTransform(IDWriteTextRenderer *iface,
 2446         void *ctx, DWRITE_MATRIX *transform)
 2447 {
 2448     struct d2d_device_context *render_target = impl_from_IDWriteTextRenderer(iface);
 2449 
 2450     TRACE("iface %p, ctx %p, transform %p.\n", iface, ctx, transform);
 2451 
 2452     d2d_device_context_GetTransform(&render_target->ID2D1DeviceContext_iface, (D2D1_MATRIX_3X2_F *)transform);
 2453 
 2454     return S_OK;
 2455 }
 2456 
 2457 static HRESULT STDMETHODCALLTYPE d2d_text_renderer_GetPixelsPerDip(IDWriteTextRenderer *iface, void *ctx, float *ppd)
 2458 {
 2459     struct d2d_device_context *render_target = impl_from_IDWriteTextRenderer(iface);
 2460 
 2461     TRACE("iface %p, ctx %p, ppd %p.\n", iface, ctx, ppd);
 2462 
 2463     *ppd = render_target->desc.dpiY / 96.0f;
 2464 
 2465     return S_OK;
 2466 }
 2467 
 2468 static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawGlyphRun(IDWriteTextRenderer *iface, void *ctx,
 2469         float baseline_origin_x, float baseline_origin_y, DWRITE_MEASURING_MODE measuring_mode,
 2470         const DWRITE_GLYPH_RUN *glyph_run, const DWRITE_GLYPH_RUN_DESCRIPTION *desc, IUnknown *effect)
 2471 {
 2472     struct d2d_device_context *render_target = impl_from_IDWriteTextRenderer(iface);
 2473     D2D1_POINT_2F baseline_origin = {baseline_origin_x, baseline_origin_y};
 2474     struct d2d_draw_text_layout_ctx *context = ctx;
 2475     BOOL color_font = FALSE;
 2476     ID2D1Brush *brush;
 2477 
 2478     TRACE("iface %p, ctx %p, baseline_origin_x %.8e, baseline_origin_y %.8e, "
 2479             "measuring_mode %#x, glyph_run %p, desc %p, effect %p.\n",
 2480             iface, ctx, baseline_origin_x, baseline_origin_y,
 2481             measuring_mode, glyph_run, desc, effect);
 2482 
 2483     if (desc)
 2484         WARN("Ignoring glyph run description %p.\n", desc);
 2485     if (context->options & ~(D2D1_DRAW_TEXT_OPTIONS_NO_SNAP | D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT))
 2486         FIXME("Ignoring options %#x.\n", context->options);
 2487 
 2488     brush = d2d_draw_get_text_brush(context, effect);
 2489 
 2490     TRACE("%s\n", debugstr_wn(desc->string, desc->stringLength));
 2491 
 2492     if (context->options & D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT)
 2493     {
 2494         IDWriteFontFace2 *fontface;
 2495 
 2496         if (SUCCEEDED(IDWriteFontFace_QueryInterface(glyph_run->fontFace,
 2497                 &IID_IDWriteFontFace2, (void **)&fontface)))
 2498         {
 2499             color_font = IDWriteFontFace2_IsColorFont(fontface);
 2500             IDWriteFontFace2_Release(fontface);
 2501         }
 2502     }
 2503 
 2504     if (color_font)
 2505     {
 2506         IDWriteColorGlyphRunEnumerator *layers;
 2507         IDWriteFactory2 *dwrite_factory;
 2508         HRESULT hr;
 2509 
 2510         if (FAILED(hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory2,
 2511                 (IUnknown **)&dwrite_factory)))
 2512         {
 2513             ERR("Failed to create dwrite factory, hr %#x.\n", hr);
 2514             ID2D1Brush_Release(brush);
 2515             return hr;
 2516         }
 2517 
 2518         hr = IDWriteFactory2_TranslateColorGlyphRun(dwrite_factory, baseline_origin_x, baseline_origin_y,
 2519                 glyph_run, desc, measuring_mode, (DWRITE_MATRIX *)&render_target->drawing_state.transform, 0, &layers);
 2520         IDWriteFactory2_Release(dwrite_factory);
 2521         if (FAILED(hr))
 2522         {
 2523             ERR("Failed to create color glyph run enumerator, hr %#x.\n", hr);
 2524             ID2D1Brush_Release(brush);
 2525             return hr;
 2526         }
 2527 
 2528         for (;;)
 2529         {
 2530             const DWRITE_COLOR_GLYPH_RUN *color_run;
 2531             ID2D1Brush *color_brush;
 2532             D2D1_POINT_2F origin;
 2533             BOOL has_run = FALSE;
 2534 
 2535             if (FAILED(hr = IDWriteColorGlyphRunEnumerator_MoveNext(layers, &has_run)))
 2536             {
 2537                 ERR("Failed to switch color glyph layer, hr %#x.\n", hr);
 2538                 break;
 2539             }
 2540 
 2541             if (!has_run)
 2542                 break;
 2543 
 2544             if (FAILED(hr = IDWriteColorGlyphRunEnumerator_GetCurrentRun(layers, &color_run)))
 2545             {
 2546                 ERR("Failed to get current color run, hr %#x.\n", hr);
 2547                 break;
 2548             }
 2549 
 2550             if (color_run->paletteIndex == 0xffff)
 2551                 color_brush = brush;
 2552             else
 2553             {
 2554                 if (FAILED(hr = d2d_device_context_CreateSolidColorBrush(&render_target->ID2D1DeviceContext_iface,
 2555                         &color_run->runColor, NULL, (ID2D1SolidColorBrush **)&color_brush)))
 2556                 {
 2557                     ERR("Failed to create solid color brush, hr %#x.\n", hr);
 2558                     break;
 2559                 }
 2560             }
 2561 
 2562             origin.x = color_run->baselineOriginX;
 2563             origin.y = color_run->baselineOriginY;
 2564             d2d_device_context_DrawGlyphRun(&render_target->ID2D1DeviceContext_iface,
 2565                     origin, &color_run->glyphRun, color_brush, measuring_mode);
 2566 
 2567             if (color_brush != brush)
 2568                 ID2D1Brush_Release(color_brush);
 2569         }
 2570 
 2571         IDWriteColorGlyphRunEnumerator_Release(layers);
 2572     }
 2573     else
 2574         d2d_device_context_DrawGlyphRun(&render_target->ID2D1DeviceContext_iface,
 2575                 baseline_origin, glyph_run, brush, measuring_mode);
 2576 
 2577     ID2D1Brush_Release(brush);
 2578 
 2579     return S_OK;
 2580 }
 2581 
 2582 static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawUnderline(IDWriteTextRenderer *iface, void *ctx,
 2583         float baseline_origin_x, float baseline_origin_y, const DWRITE_UNDERLINE *underline, IUnknown *effect)
 2584 {
 2585     struct d2d_device_context *render_target = impl_from_IDWriteTextRenderer(iface);
 2586     const D2D1_MATRIX_3X2_F *m = &render_target->drawing_state.transform;
 2587     struct d2d_draw_text_layout_ctx *context = ctx;
 2588     D2D1_ANTIALIAS_MODE prev_antialias_mode;
 2589     D2D1_POINT_2F start, end;
 2590     ID2D1Brush *brush;
 2591     float thickness;
 2592 
 2593     TRACE("iface %p, ctx %p, baseline_origin_x %.8e, baseline_origin_y %.8e, underline %p, effect %p\n",
 2594             iface, ctx, baseline_origin_x, baseline_origin_y, underline, effect);
 2595 
 2596     /* minimal thickness in DIPs that will result in at least 1 pixel thick line */
 2597     thickness = max(96.0f / (render_target->desc.dpiY * sqrtf(m->_21 * m->_21 + m->_22 * m->_22)),
 2598             underline->thickness);
 2599 
 2600     brush = d2d_draw_get_text_brush(context, effect);
 2601 
 2602     start.x = baseline_origin_x;
 2603     start.y = baseline_origin_y + underline->offset + thickness / 2.0f;
 2604     end.x = start.x + underline->width;
 2605     end.y = start.y;
 2606     prev_antialias_mode = d2d_device_context_set_aa_mode_from_text_aa_mode(render_target);
 2607     d2d_device_context_DrawLine(&render_target->ID2D1DeviceContext_iface, start, end, brush, thickness, NULL);
 2608     render_target->drawing_state.antialiasMode = prev_antialias_mode;
 2609 
 2610     ID2D1Brush_Release(brush);
 2611 
 2612     return S_OK;
 2613 }
 2614 
 2615 static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawStrikethrough(IDWriteTextRenderer *iface, void *ctx,
 2616         float baseline_origin_x, float baseline_origin_y, const DWRITE_STRIKETHROUGH *strikethrough, IUnknown *effect)
 2617 {
 2618     struct d2d_device_context *render_target = impl_from_IDWriteTextRenderer(iface);
 2619     const D2D1_MATRIX_3X2_F *m = &render_target->drawing_state.transform;
 2620     struct d2d_draw_text_layout_ctx *context = ctx;
 2621     D2D1_ANTIALIAS_MODE prev_antialias_mode;
 2622     D2D1_POINT_2F start, end;
 2623     ID2D1Brush *brush;
 2624     float thickness;
 2625 
 2626     TRACE("iface %p, ctx %p, baseline_origin_x %.8e, baseline_origin_y %.8e, strikethrough %p, effect %p.\n",
 2627             iface, ctx, baseline_origin_x, baseline_origin_y, strikethrough, effect);
 2628 
 2629     /* minimal thickness in DIPs that will result in at least 1 pixel thick line */
 2630     thickness = max(96.0f / (render_target->desc.dpiY * sqrtf(m->_21 * m->_21 + m->_22 * m->_22)),
 2631             strikethrough->thickness);
 2632 
 2633     brush = d2d_draw_get_text_brush(context, effect);
 2634 
 2635     start.x = baseline_origin_x;
 2636     start.y = baseline_origin_y + strikethrough->offset + thickness / 2.0f;
 2637     end.x = start.x + strikethrough->width;
 2638     end.y = start.y;
 2639     prev_antialias_mode = d2d_device_context_set_aa_mode_from_text_aa_mode(render_target);
 2640     d2d_device_context_DrawLine(&render_target->ID2D1DeviceContext_iface, start, end, brush, thickness, NULL);
 2641     render_target->drawing_state.antialiasMode = prev_antialias_mode;
 2642 
 2643     ID2D1Brush_Release(brush);
 2644 
 2645     return S_OK;
 2646 }
 2647 
 2648 static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawInlineObject(IDWriteTextRenderer *iface, void *ctx,
 2649         float origin_x, float origin_y, IDWriteInlineObject *object, BOOL is_sideways, BOOL is_rtl, IUnknown *effect)
 2650 {
 2651     struct d2d_draw_text_layout_ctx *context = ctx;
 2652     ID2D1Brush *brush;
 2653     HRESULT hr;
 2654 
 2655     TRACE("iface %p, ctx %p, origin_x %.8e, origin_y %.8e, object %p, is_sideways %#x, is_rtl %#x, effect %p.\n",
 2656             iface, ctx, origin_x, origin_y, object, is_sideways, is_rtl, effect);
 2657 
 2658     /* Inline objects may not pass effects all the way down, when using layout object internally for example.
 2659        This is how default trimming sign object in DirectWrite works - it does not use effect passed to Draw(),
 2660        and resulting DrawGlyphRun() is always called with NULL effect, however original effect is used and correct
 2661        brush is selected at Direct2D level. */
 2662     brush = context->brush;
 2663     context->brush = d2d_draw_get_text_brush(context, effect);
 2664 
 2665     hr = IDWriteInlineObject_Draw(object, ctx, iface, origin_x, origin_y, is_sideways, is_rtl, effect);
 2666 
 2667     ID2D1Brush_Release(context->brush);
 2668     context->brush = brush;
 2669 
 2670     return hr;
 2671 }
 2672 
 2673 static const struct IDWriteTextRendererVtbl d2d_text_renderer_vtbl =
 2674 {
 2675     d2d_text_renderer_QueryInterface,
 2676     d2d_text_renderer_AddRef,
 2677     d2d_text_renderer_Release,
 2678     d2d_text_renderer_IsPixelSnappingDisabled,
 2679     d2d_text_renderer_GetCurrentTransform,
 2680     d2d_text_renderer_GetPixelsPerDip,
 2681     d2d_text_renderer_DrawGlyphRun,
 2682     d2d_text_renderer_DrawUnderline,
 2683     d2d_text_renderer_DrawStrikethrough,
 2684     d2d_text_renderer_DrawInlineObject,
 2685 };
 2686 
 2687 static inline struct d2d_device_context *impl_from_ID2D1GdiInteropRenderTarget(ID2D1GdiInteropRenderTarget *iface)
 2688 {
 2689     return CONTAINING_RECORD(iface, struct d2d_device_context, ID2D1GdiInteropRenderTarget_iface);
 2690 }
 2691 
 2692 static HRESULT STDMETHODCALLTYPE d2d_gdi_interop_render_target_QueryInterface(ID2D1GdiInteropRenderTarget *iface,
 2693         REFIID iid, void **out)
 2694 {
 2695     struct d2d_device_context *render_target = impl_from_ID2D1GdiInteropRenderTarget(iface);
 2696 
 2697     TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
 2698 
 2699     return IUnknown_QueryInterface(render_target->outer_unknown, iid, out);
 2700 }
 2701 
 2702 static ULONG STDMETHODCALLTYPE d2d_gdi_interop_render_target_AddRef(ID2D1GdiInteropRenderTarget *iface)
 2703 {
 2704     struct d2d_device_context *render_target = impl_from_ID2D1GdiInteropRenderTarget(iface);
 2705 
 2706     TRACE("iface %p.\n", iface);
 2707 
 2708     return IUnknown_AddRef(render_target->outer_unknown);
 2709 }
 2710 
 2711 static ULONG STDMETHODCALLTYPE d2d_gdi_interop_render_target_Release(ID2D1GdiInteropRenderTarget *iface)
 2712 {
 2713     struct d2d_device_context *render_target = impl_from_ID2D1GdiInteropRenderTarget(iface);
 2714 
 2715     TRACE("iface %p.\n", iface);
 2716 
 2717     return IUnknown_Release(render_target->outer_unknown);
 2718 }
 2719 
 2720 static HRESULT d2d_device_context_get_surface(struct d2d_device_context *render_target, IDXGISurface1 **surface)
 2721 {
 2722     ID3D10Resource *resource;
 2723     HRESULT hr;
 2724 
 2725     ID3D10RenderTargetView_GetResource(render_target->target->rtv, &resource);
 2726     hr = ID3D10Resource_QueryInterface(resource, &IID_IDXGISurface1, (void **)surface);
 2727     ID3D10Resource_Release(resource);
 2728     if (FAILED(hr))
 2729     {
 2730         *surface = NULL;
 2731         WARN("Failed to get DXGI surface, %#x.\n", hr);
 2732         return hr;
 2733     }
 2734 
 2735     return hr;
 2736 }
 2737 
 2738 static HRESULT STDMETHODCALLTYPE d2d_gdi_interop_render_target_GetDC(ID2D1GdiInteropRenderTarget *iface,
 2739         D2D1_DC_INITIALIZE_MODE mode, HDC *dc)
 2740 {
 2741     struct d2d_device_context *render_target = impl_from_ID2D1GdiInteropRenderTarget(iface);
 2742     IDXGISurface1 *surface;
 2743     HRESULT hr;
 2744 
 2745     TRACE("iface %p, mode %d, dc %p.\n", iface, mode, dc);
 2746 
 2747     if (FAILED(hr = d2d_device_context_get_surface(render_target, &surface)))
 2748         return hr;
 2749 
 2750     hr = IDXGISurface1_GetDC(surface, mode != D2D1_DC_INITIALIZE_MODE_COPY, dc);
 2751     IDXGISurface1_Release(surface);
 2752 
 2753     return hr;
 2754 }
 2755 
 2756 static HRESULT STDMETHODCALLTYPE d2d_gdi_interop_render_target_ReleaseDC(ID2D1GdiInteropRenderTarget *iface,
 2757         const RECT *update)
 2758 {
 2759     struct d2d_device_context *render_target = impl_from_ID2D1GdiInteropRenderTarget(iface);
 2760     IDXGISurface1 *surface;
 2761     RECT update_rect;
 2762     HRESULT hr;
 2763 
 2764     TRACE("iface %p, update rect %s.\n", iface, wine_dbgstr_rect(update));
 2765 
 2766     if (FAILED(hr = d2d_device_context_get_surface(render_target, &surface)))
 2767         return hr;
 2768 
 2769     if (update)
 2770         update_rect = *update;
 2771     hr = IDXGISurface1_ReleaseDC(surface, update ? &update_rect : NULL);
 2772     IDXGISurface1_Release(surface);
 2773 
 2774     return hr;
 2775 }
 2776 
 2777 static const struct ID2D1GdiInteropRenderTargetVtbl d2d_gdi_interop_render_target_vtbl =
 2778 {
 2779     d2d_gdi_interop_render_target_QueryInterface,
 2780     d2d_gdi_interop_render_target_AddRef,
 2781     d2d_gdi_interop_render_target_Release,
 2782     d2d_gdi_interop_render_target_GetDC,
 2783     d2d_gdi_interop_render_target_ReleaseDC,
 2784 };
 2785 
 2786 static HRESULT d2d_device_context_init(struct d2d_device_context *render_target, ID2D1Device *device,
 2787         IUnknown *outer_unknown, const struct d2d_device_context_ops *ops)
 2788 {
 2789     D3D10_SUBRESOURCE_DATA buffer_data;
 2790     D3D10_STATE_BLOCK_MASK state_mask;
 2791     struct d2d_device *device_impl;
 2792     IDWriteFactory *dwrite_factory;
 2793     D3D10_RASTERIZER_DESC rs_desc;
 2794     D3D10_BUFFER_DESC buffer_desc;
 2795     unsigned int i;
 2796     HRESULT hr;
 2797 
 2798     static const D3D10_INPUT_ELEMENT_DESC il_desc_outline[] =
 2799     {
 2800         {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
 2801         {"PREV", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D10_INPUT_PER_VERTEX_DATA, 0},
 2802         {"NEXT", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0},
 2803     };
 2804     static const D3D10_INPUT_ELEMENT_DESC il_desc_curve_outline[] =
 2805     {
 2806         {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
 2807         {"P", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D10_INPUT_PER_VERTEX_DATA, 0},
 2808         {"P", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0},
 2809         {"P", 2, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D10_INPUT_PER_VERTEX_DATA, 0},
 2810         {"PREV", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 32, D3D10_INPUT_PER_VERTEX_DATA, 0},
 2811         {"NEXT", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 40, D3D10_INPUT_PER_VERTEX_DATA, 0},
 2812     };
 2813     static const D3D10_INPUT_ELEMENT_DESC il_desc_triangle[] =
 2814     {
 2815         {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
 2816     };
 2817     static const D3D10_INPUT_ELEMENT_DESC il_desc_curve[] =
 2818     {
 2819         {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT,    0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
 2820         {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 8, D3D10_INPUT_PER_VERTEX_DATA, 0},
 2821     };
 2822     static const DWORD vs_code_outline[] =
 2823     {
 2824 #if 0
 2825         float3x2 transform_geometry;
 2826         float stroke_width;
 2827         float4 transform_rtx;
 2828         float4 transform_rty;
 2829 
 2830         struct output
 2831         {
 2832             float2 p : WORLD_POSITION;
 2833             float4 b : BEZIER;
 2834             nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM;
 2835             float4 position : SV_POSITION;
 2836         };
 2837 
 2838         /* The lines PₚᵣₑᵥP₀ and P₀Pₙₑₓₜ, both offset by ±½w, intersect each other at:
 2839          *
 2840          *   Pᵢ = P₀ ± w · ½q⃑ᵢ.
 2841          *
 2842          * Where:
 2843          *
 2844          *   q⃑ᵢ = q̂ₚᵣₑᵥ⊥ + tan(½θ) · -q̂ₚᵣₑᵥ
 2845          *   θ  = ∠PₚᵣₑᵥP₀Pₙₑₓₜ
 2846          *   q⃑ₚᵣₑᵥ = P₀ - Pₚᵣₑᵥ */
 2847         void main(float2 position : POSITION, float2 prev : PREV, float2 next : NEXT, out struct output o)
 2848         {
 2849             float2 q_prev, q_next, v_p, q_i;
 2850             float2x2 geom;
 2851             float l;
 2852 
 2853             o.stroke_transform = float2x2(transform_rtx.xy, transform_rty.xy) * stroke_width * 0.5f;
 2854 
 2855             geom = float2x2(transform_geometry._11_21, transform_geometry._12_22);
 2856             q_prev = normalize(mul(geom, prev));
 2857             q_next = normalize(mul(geom, next));
 2858 
 2859             /* tan(½θ) = sin(θ) / (1 + cos(θ))
 2860              *         = (q̂ₚᵣₑᵥ⊥ · q̂ₙₑₓₜ) / (1 + (q̂ₚᵣₑᵥ · q̂ₙₑₓₜ)) */
 2861             v_p = float2(-q_prev.y, q_prev.x);
 2862             l = -dot(v_p, q_next) / (1.0f + dot(q_prev, q_next));
 2863             q_i = l * q_prev + v_p;
 2864 
 2865             o.b = float4(0.0, 0.0, 0.0, 0.0);
 2866 
 2867             o.p = mul(float3(position, 1.0f), transform_geometry) + stroke_width * 0.5f * q_i;
 2868             position = mul(float2x3(transform_rtx.xyz, transform_rty.xyz), float3(o.p, 1.0f))
 2869                     * float2(transform_rtx.w, transform_rty.w);
 2870             o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f);
 2871         }
 2872 #endif
 2873         0x43425844, 0xfb16cd75, 0xf5ec3e80, 0xceacf250, 0x91d29d18, 0x00000001, 0x00000608, 0x00000003,
 2874         0x0000002c, 0x00000098, 0x00000154, 0x4e475349, 0x00000064, 0x00000003, 0x00000008, 0x00000050,
 2875         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x00000059, 0x00000000, 0x00000000,
 2876         0x00000003, 0x00000001, 0x00000303, 0x0000005e, 0x00000000, 0x00000000, 0x00000003, 0x00000002,
 2877         0x00000303, 0x49534f50, 0x4e4f4954, 0x45525000, 0x454e0056, 0xab005458, 0x4e47534f, 0x000000b4,
 2878         0x00000005, 0x00000008, 0x00000080, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000c03,
 2879         0x0000008f, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f, 0x00000096, 0x00000000,
 2880         0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x00000096, 0x00000001, 0x00000000, 0x00000003,
 2881         0x00000003, 0x00000c03, 0x000000a7, 0x00000000, 0x00000001, 0x00000003, 0x00000004, 0x0000000f,
 2882         0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, 0x54530052, 0x454b4f52, 0x4152545f,
 2883         0x4f46534e, 0x53004d52, 0x4f505f56, 0x49544953, 0xab004e4f, 0x52444853, 0x000004ac, 0x00010040,
 2884         0x0000012b, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, 0x0300005f, 0x00101032, 0x00000000,
 2885         0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x00101032, 0x00000002, 0x03000065, 0x00102032,
 2886         0x00000000, 0x03000065, 0x001020f2, 0x00000001, 0x03000065, 0x00102032, 0x00000002, 0x03000065,
 2887         0x00102032, 0x00000003, 0x04000067, 0x001020f2, 0x00000004, 0x00000001, 0x02000068, 0x00000003,
 2888         0x0800000f, 0x00100012, 0x00000000, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000002,
 2889         0x0800000f, 0x00100022, 0x00000000, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000002,
 2890         0x0700000f, 0x00100042, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000000, 0x05000044,
 2891         0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x07000038, 0x00100032, 0x00000000, 0x00100aa6,
 2892         0x00000000, 0x00100046, 0x00000000, 0x0800000f, 0x00100012, 0x00000001, 0x00208046, 0x00000000,
 2893         0x00000000, 0x00101046, 0x00000001, 0x0800000f, 0x00100022, 0x00000001, 0x00208046, 0x00000000,
 2894         0x00000001, 0x00101046, 0x00000001, 0x0700000f, 0x00100042, 0x00000000, 0x00100046, 0x00000001,
 2895         0x00100046, 0x00000001, 0x05000044, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x07000038,
 2896         0x00100032, 0x00000001, 0x00100aa6, 0x00000000, 0x00100046, 0x00000001, 0x06000036, 0x001000c2,
 2897         0x00000001, 0x80100556, 0x00000041, 0x00000001, 0x0700000f, 0x00100042, 0x00000000, 0x00100a26,
 2898         0x00000001, 0x00100046, 0x00000000, 0x0700000f, 0x00100012, 0x00000000, 0x00100046, 0x00000001,
 2899         0x00100046, 0x00000000, 0x07000000, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001,
 2900         0x3f800000, 0x0800000e, 0x00100012, 0x00000000, 0x8010002a, 0x00000041, 0x00000000, 0x0010000a,
 2901         0x00000000, 0x09000032, 0x00100032, 0x00000000, 0x00100006, 0x00000000, 0x00100046, 0x00000001,
 2902         0x00100f36, 0x00000001, 0x08000038, 0x00100042, 0x00000000, 0x0020803a, 0x00000000, 0x00000001,
 2903         0x00004001, 0x3f000000, 0x05000036, 0x00100032, 0x00000001, 0x00101046, 0x00000000, 0x05000036,
 2904         0x00100042, 0x00000001, 0x00004001, 0x3f800000, 0x08000010, 0x00100012, 0x00000002, 0x00100246,
 2905         0x00000001, 0x00208246, 0x00000000, 0x00000000, 0x08000010, 0x00100022, 0x00000002, 0x00100246,
 2906         0x00000001, 0x00208246, 0x00000000, 0x00000001, 0x09000032, 0x00100032, 0x00000000, 0x00100aa6,
 2907         0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000002, 0x05000036, 0x00102032, 0x00000000,
 2908         0x00100046, 0x00000000, 0x08000036, 0x001020f2, 0x00000001, 0x00004002, 0x00000000, 0x00000000,
 2909         0x00000000, 0x00000000, 0x06000036, 0x00100032, 0x00000001, 0x00208046, 0x00000000, 0x00000002,
 2910         0x06000036, 0x001000c2, 0x00000001, 0x00208406, 0x00000000, 0x00000003, 0x08000038, 0x001000f2,
 2911         0x00000001, 0x00100e46, 0x00000001, 0x00208ff6, 0x00000000, 0x00000001, 0x0a000038, 0x001000f2,
 2912         0x00000001, 0x00100e46, 0x00000001, 0x00004002, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000,
 2913         0x05000036, 0x00102032, 0x00000002, 0x00100086, 0x00000001, 0x05000036, 0x00102032, 0x00000003,
 2914         0x001005d6, 0x00000001, 0x05000036, 0x00100042, 0x00000000, 0x00004001, 0x3f800000, 0x08000010,
 2915         0x00100082, 0x00000000, 0x00208246, 0x00000000, 0x00000002, 0x00100246, 0x00000000, 0x08000010,
 2916         0x00100012, 0x00000000, 0x00208246, 0x00000000, 0x00000003, 0x00100246, 0x00000000, 0x08000038,
 2917         0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x0020803a, 0x00000000, 0x00000003, 0x08000038,
 2918         0x00100012, 0x00000000, 0x0010003a, 0x00000000, 0x0020803a, 0x00000000, 0x00000002, 0x0a000000,
 2919         0x00102032, 0x00000004, 0x00100046, 0x00000000, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000,
 2920         0x00000000, 0x08000036, 0x001020c2, 0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
 2921         0x3f800000, 0x0100003e,
 2922     };
 2923     /*     ⎡p0.x p0.y 1⎤
 2924      * A = ⎢p1.x p1.y 1⎥
 2925      *     ⎣p2.x p2.y 1⎦
 2926      *
 2927      *     ⎡0 0⎤
 2928      * B = ⎢½ 0⎥
 2929      *     ⎣1 1⎦
 2930      *
 2931      * A' = ⎡p1.x-p0.x p1.y-p0.y⎤
 2932      *      ⎣p2.x-p0.x p2.y-p0.y⎦
 2933      *
 2934      * B' = ⎡½ 0⎤
 2935      *      ⎣1 1⎦
 2936      *
 2937      * A'T = B'
 2938      * T = A'⁻¹B'
 2939      */
 2940     static const DWORD vs_code_bezier_outline[] =
 2941     {
 2942 #if 0
 2943         float3x2 transform_geometry;
 2944         float stroke_width;
 2945         float4 transform_rtx;
 2946         float4 transform_rty;
 2947 
 2948         struct output
 2949         {
 2950             float2 p : WORLD_POSITION;
 2951             float4 b : BEZIER;
 2952             nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM;
 2953             float4 position : SV_POSITION;
 2954         };
 2955 
 2956         void main(float2 position : POSITION, float2 p0 : P0, float2 p1 : P1, float2 p2 : P2,
 2957                 float2 prev : PREV, float2 next : NEXT, out struct output o)
 2958         {
 2959             float2 q_prev, q_next, v_p, q_i, p;
 2960             float2x2 geom, rt;
 2961             float l;
 2962 
 2963             geom = float2x2(transform_geometry._11_21, transform_geometry._12_22);
 2964             rt = float2x2(transform_rtx.xy, transform_rty.xy);
 2965             o.stroke_transform = rt * stroke_width * 0.5f;
 2966 
 2967             p = mul(geom, position);
 2968             p0 = mul(geom, p0);
 2969             p1 = mul(geom, p1);
 2970             p2 = mul(geom, p2);
 2971 
 2972             p -= p0;
 2973             p1 -= p0;
 2974             p2 -= p0;
 2975 
 2976             q_prev = normalize(mul(geom, prev));
 2977             q_next = normalize(mul(geom, next));
 2978 
 2979             v_p = float2(-q_prev.y, q_prev.x);
 2980             l = -dot(v_p, q_next) / (1.0f + dot(q_prev, q_next));
 2981             q_i = l * q_prev + v_p;
 2982             p += 0.5f * stroke_width * q_i;
 2983 
 2984             v_p = mul(rt, p2);
 2985             v_p = normalize(float2(-v_p.y, v_p.x));
 2986             if (abs(dot(mul(rt, p1), v_p)) < 1.0f)
 2987             {
 2988                 o.b.xzw = float3(0.0f, 0.0f, 0.0f);
 2989                 o.b.y = dot(mul(rt, p), v_p);
 2990             }
 2991             else
 2992             {
 2993                 o.b.zw = sign(dot(mul(rt, p1), v_p)) * v_p;
 2994                 v_p = -float2(-p.y, p.x) / dot(float2(-p1.y, p1.x), p2);
 2995                 o.b.x = dot(v_p, p1 - 0.5f * p2);
 2996                 o.b.y = dot(v_p, p1);
 2997             }
 2998 
 2999             o.p = mul(float3(position, 1.0f), transform_geometry) + 0.5f * stroke_width * q_i;
 3000             position = mul(float2x3(transform_rtx.xyz, transform_rty.xyz), float3(o.p, 1.0f))
 3001                     * float2(transform_rtx.w, transform_rty.w);
 3002             o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f);
 3003         }
 3004 #endif
 3005         0x43425844, 0x356a0c5f, 0x8e4ba153, 0xe52cf793, 0xa6b774ea, 0x00000001, 0x00000afc, 0x00000003,
 3006         0x0000002c, 0x000000e4, 0x000001a0, 0x4e475349, 0x000000b0, 0x00000006, 0x00000008, 0x00000098,
 3007         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x000000a1, 0x00000000, 0x00000000,
 3008         0x00000003, 0x00000001, 0x00000303, 0x000000a1, 0x00000001, 0x00000000, 0x00000003, 0x00000002,
 3009         0x00000303, 0x000000a1, 0x00000002, 0x00000000, 0x00000003, 0x00000003, 0x00000303, 0x000000a3,
 3010         0x00000000, 0x00000000, 0x00000003, 0x00000004, 0x00000303, 0x000000a8, 0x00000000, 0x00000000,
 3011         0x00000003, 0x00000005, 0x00000303, 0x49534f50, 0x4e4f4954, 0x50005000, 0x00564552, 0x5458454e,
 3012         0xababab00, 0x4e47534f, 0x000000b4, 0x00000005, 0x00000008, 0x00000080, 0x00000000, 0x00000000,
 3013         0x00000003, 0x00000000, 0x00000c03, 0x0000008f, 0x00000000, 0x00000000, 0x00000003, 0x00000001,
 3014         0x0000000f, 0x00000096, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x00000096,
 3015         0x00000001, 0x00000000, 0x00000003, 0x00000003, 0x00000c03, 0x000000a7, 0x00000000, 0x00000001,
 3016         0x00000003, 0x00000004, 0x0000000f, 0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45,
 3017         0x54530052, 0x454b4f52, 0x4152545f, 0x4f46534e, 0x53004d52, 0x4f505f56, 0x49544953, 0xab004e4f,
 3018         0x52444853, 0x00000954, 0x00010040, 0x00000255, 0x04000059, 0x00208e46, 0x00000000, 0x00000004,
 3019         0x0300005f, 0x00101032, 0x00000000, 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x00101032,
 3020         0x00000002, 0x0300005f, 0x00101032, 0x00000003, 0x0300005f, 0x00101032, 0x00000004, 0x0300005f,
 3021         0x00101032, 0x00000005, 0x03000065, 0x00102032, 0x00000000, 0x03000065, 0x001020f2, 0x00000001,
 3022         0x03000065, 0x00102032, 0x00000002, 0x03000065, 0x00102032, 0x00000003, 0x04000067, 0x001020f2,
 3023         0x00000004, 0x00000001, 0x02000068, 0x00000006, 0x0800000f, 0x00100012, 0x00000000, 0x00208046,
 3024         0x00000000, 0x00000000, 0x00101046, 0x00000005, 0x0800000f, 0x00100022, 0x00000000, 0x00208046,
 3025         0x00000000, 0x00000001, 0x00101046, 0x00000005, 0x0700000f, 0x00100042, 0x00000000, 0x00100046,
 3026         0x00000000, 0x00100046, 0x00000000, 0x05000044, 0x00100042, 0x00000000, 0x0010002a, 0x00000000,
 3027         0x07000038, 0x00100032, 0x00000000, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x0800000f,
 3028         0x00100012, 0x00000001, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000004, 0x0800000f,
 3029         0x00100022, 0x00000001, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000004, 0x0700000f,
 3030         0x00100042, 0x00000000, 0x00100046, 0x00000001, 0x00100046, 0x00000001, 0x05000044, 0x00100042,
 3031         0x00000000, 0x0010002a, 0x00000000, 0x07000038, 0x00100032, 0x00000001, 0x00100aa6, 0x00000000,
 3032         0x00100046, 0x00000001, 0x06000036, 0x001000c2, 0x00000001, 0x80100556, 0x00000041, 0x00000001,
 3033         0x0700000f, 0x00100042, 0x00000000, 0x00100a26, 0x00000001, 0x00100046, 0x00000000, 0x0700000f,
 3034         0x00100012, 0x00000000, 0x00100046, 0x00000001, 0x00100046, 0x00000000, 0x07000000, 0x00100012,
 3035         0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0800000e, 0x00100012, 0x00000000,
 3036         0x8010002a, 0x00000041, 0x00000000, 0x0010000a, 0x00000000, 0x09000032, 0x00100032, 0x00000000,
 3037         0x00100006, 0x00000000, 0x00100046, 0x00000001, 0x00100f36, 0x00000001, 0x05000036, 0x00100032,
 3038         0x00000001, 0x00101046, 0x00000000, 0x05000036, 0x00100042, 0x00000001, 0x00004001, 0x3f800000,
 3039         0x08000010, 0x00100012, 0x00000002, 0x00100246, 0x00000001, 0x00208246, 0x00000000, 0x00000000,
 3040         0x08000010, 0x00100022, 0x00000002, 0x00100246, 0x00000001, 0x00208246, 0x00000000, 0x00000001,
 3041         0x08000038, 0x00100042, 0x00000000, 0x0020803a, 0x00000000, 0x00000001, 0x00004001, 0x3f000000,
 3042         0x09000032, 0x00100032, 0x00000001, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x00100046,
 3043         0x00000002, 0x05000036, 0x00102032, 0x00000000, 0x00100046, 0x00000001, 0x0800000f, 0x00100012,
 3044         0x00000002, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000000, 0x0800000f, 0x00100022,
 3045         0x00000002, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000000, 0x0800000f, 0x00100012,
 3046         0x00000003, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000001, 0x0800000f, 0x00100022,
 3047         0x00000003, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000001, 0x08000000, 0x00100032,
 3048         0x00000002, 0x00100046, 0x00000002, 0x80100046, 0x00000041, 0x00000003, 0x09000032, 0x00100032,
 3049         0x00000000, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000002, 0x0800000f,
 3050         0x00100012, 0x00000002, 0x00208046, 0x00000000, 0x00000002, 0x00100046, 0x00000000, 0x0800000f,
 3051         0x00100022, 0x00000002, 0x00208046, 0x00000000, 0x00000003, 0x00100046, 0x00000000, 0x0800000f,
 3052         0x00100012, 0x00000004, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000003, 0x0800000f,
 3053         0x00100022, 0x00000004, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000003, 0x08000000,
 3054         0x001000c2, 0x00000002, 0x80100406, 0x00000041, 0x00000003, 0x00100406, 0x00000004, 0x0800000f,
 3055         0x00100082, 0x00000000, 0x00208046, 0x00000000, 0x00000003, 0x00100ae6, 0x00000002, 0x06000036,
 3056         0x00100042, 0x00000003, 0x8010003a, 0x00000041, 0x00000000, 0x0800000f, 0x00100082, 0x00000003,
 3057         0x00208046, 0x00000000, 0x00000002, 0x00100ae6, 0x00000002, 0x0700000f, 0x00100082, 0x00000000,
 3058         0x00100ae6, 0x00000003, 0x00100ae6, 0x00000003, 0x05000044, 0x00100082, 0x00000000, 0x0010003a,
 3059         0x00000000, 0x07000038, 0x001000c2, 0x00000003, 0x00100ff6, 0x00000000, 0x00100ea6, 0x00000003,
 3060         0x0700000f, 0x00100022, 0x00000004, 0x00100046, 0x00000002, 0x00100ae6, 0x00000003, 0x06000036,
 3061         0x00100042, 0x00000000, 0x8010001a, 0x00000041, 0x00000000, 0x0800000f, 0x00100012, 0x00000002,
 3062         0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000002, 0x0800000f, 0x00100022, 0x00000002,
 3063         0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000002, 0x08000000, 0x00100032, 0x00000005,
 3064         0x80100046, 0x00000041, 0x00000003, 0x00100046, 0x00000002, 0x06000036, 0x00100042, 0x00000005,
 3065         0x8010001a, 0x00000041, 0x00000005, 0x0700000f, 0x00100022, 0x00000000, 0x00100a26, 0x00000005,
 3066         0x00100ae6, 0x00000002, 0x0d000032, 0x00100032, 0x00000002, 0x80100ae6, 0x00000041, 0x00000002,
 3067         0x00004002, 0x3f000000, 0x3f000000, 0x00000000, 0x00000000, 0x00100046, 0x00000005, 0x0800000e,
 3068         0x00100032, 0x00000000, 0x80100a26, 0x00000041, 0x00000000, 0x00100556, 0x00000000, 0x0700000f,
 3069         0x00100012, 0x00000002, 0x00100046, 0x00000000, 0x00100046, 0x00000002, 0x0700000f, 0x00100022,
 3070         0x00000002, 0x00100046, 0x00000000, 0x00100046, 0x00000005, 0x0800000f, 0x00100012, 0x00000000,
 3071         0x00208046, 0x00000000, 0x00000002, 0x00100046, 0x00000005, 0x0800000f, 0x00100022, 0x00000000,
 3072         0x00208046, 0x00000000, 0x00000003, 0x00100046, 0x00000005, 0x0700000f, 0x00100012, 0x00000000,
 3073         0x00100046, 0x00000000, 0x00100ae6, 0x00000003, 0x07000031, 0x00100022, 0x00000000, 0x00004001,
 3074         0x00000000, 0x0010000a, 0x00000000, 0x07000031, 0x00100042, 0x00000000, 0x0010000a, 0x00000000,
 3075         0x00004001, 0x00000000, 0x08000031, 0x00100012, 0x00000000, 0x8010000a, 0x00000081, 0x00000000,
 3076         0x00004001, 0x3f800000, 0x0800001e, 0x00100022, 0x00000000, 0x8010001a, 0x00000041, 0x00000000,
 3077         0x0010002a, 0x00000000, 0x0500002b, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x07000038,
 3078         0x001000c2, 0x00000002, 0x00100ea6, 0x00000003, 0x00100556, 0x00000000, 0x08000036, 0x001000d2,
 3079         0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x09000037, 0x001020f2,
 3080         0x00000001, 0x00100006, 0x00000000, 0x00100e46, 0x00000004, 0x00100e46, 0x00000002, 0x06000036,
 3081         0x00100032, 0x00000000, 0x00208046, 0x00000000, 0x00000002, 0x06000036, 0x001000c2, 0x00000000,
 3082         0x00208406, 0x00000000, 0x00000003, 0x08000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000,
 3083         0x00208ff6, 0x00000000, 0x00000001, 0x0a000038, 0x001000f2, 0x00000000, 0x00100e46, 0x00000000,
 3084         0x00004002, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x05000036, 0x00102032, 0x00000002,
 3085         0x00100086, 0x00000000, 0x05000036, 0x00102032, 0x00000003, 0x001005d6, 0x00000000, 0x05000036,
 3086         0x00100042, 0x00000001, 0x00004001, 0x3f800000, 0x08000010, 0x00100012, 0x00000000, 0x00208246,
 3087         0x00000000, 0x00000002, 0x00100246, 0x00000001, 0x08000010, 0x00100022, 0x00000000, 0x00208246,
 3088         0x00000000, 0x00000003, 0x00100246, 0x00000001, 0x08000038, 0x00100022, 0x00000001, 0x0010001a,
 3089         0x00000000, 0x0020803a, 0x00000000, 0x00000003, 0x08000038, 0x00100012, 0x00000001, 0x0010000a,
 3090         0x00000000, 0x0020803a, 0x00000000, 0x00000002, 0x0a000000, 0x00102032, 0x00000004, 0x00100046,
 3091         0x00000001, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000, 0x00000000, 0x08000036, 0x001020c2,
 3092         0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e,
 3093     };
 3094     /*     ⎡p0.x p0.y 1⎤
 3095      * A = ⎢p1.x p1.y 1⎥
 3096      *     ⎣p2.x p2.y 1⎦
 3097      *
 3098      *     ⎡1 0⎤
 3099      * B = ⎢1 1⎥
 3100      *     ⎣0 1⎦
 3101      *
 3102      * A' = ⎡p1.x-p0.x p1.y-p0.y⎤
 3103      *      ⎣p2.x-p0.x p2.y-p0.y⎦
 3104      *
 3105      * B' = ⎡ 0 1⎤
 3106      *      ⎣-1 1⎦
 3107      *
 3108      * A'T = B'
 3109      * T = A'⁻¹B' = (B'⁻¹A')⁻¹
 3110      */
 3111     static const DWORD vs_code_arc_outline[] =
 3112     {
 3113 #if 0
 3114         float3x2 transform_geometry;
 3115         float stroke_width;
 3116         float4 transform_rtx;
 3117         float4 transform_rty;
 3118 
 3119         struct output
 3120         {
 3121             float2 p : WORLD_POSITION;
 3122             float4 b : BEZIER;
 3123             nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM;
 3124             float4 position : SV_POSITION;
 3125         };
 3126 
 3127         void main(float2 position : POSITION, float2 p0 : P0, float2 p1 : P1, float2 p2 : P2,
 3128                 float2 prev : PREV, float2 next : NEXT, out struct output o)
 3129         {
 3130             float2 q_prev, q_next, v_p, q_i, p;
 3131             float2x2 geom, rt, p_inv;
 3132             float l;
 3133             float a;
 3134             float2 bc;
 3135 
 3136             geom = float2x2(transform_geometry._11_21, transform_geometry._12_22);
 3137             rt = float2x2(transform_rtx.xy, transform_rty.xy);
 3138             o.stroke_transform = rt * stroke_width * 0.5f;
 3139 
 3140             p = mul(geom, position);
 3141             p0 = mul(geom, p0);
 3142             p1 = mul(geom, p1);
 3143             p2 = mul(geom, p2);
 3144 
 3145             p -= p0;
 3146             p1 -= p0;
 3147             p2 -= p0;
 3148 
 3149             q_prev = normalize(mul(geom, prev));
 3150             q_next = normalize(mul(geom, next));
 3151 
 3152             v_p = float2(-q_prev.y, q_prev.x);
 3153             l = -dot(v_p, q_next) / (1.0f + dot(q_prev, q_next));
 3154             q_i = l * q_prev + v_p;
 3155             p += 0.5f * stroke_width * q_i;
 3156 
 3157             p_inv = float2x2(p1.y, -p1.x, p2.y - p1.y, p1.x - p2.x) / (p1.x * p2.y - p2.x * p1.y);
 3158             o.b.xy = mul(p_inv, p) + float2(1.0f, 0.0f);
 3159             o.b.zw = 0.0f;
 3160 
 3161             o.p = mul(float3(position, 1.0f), transform_geometry) + 0.5f * stroke_width * q_i;
 3162             position = mul(float2x3(transform_rtx.xyz, transform_rty.xyz), float3(o.p, 1.0f))
 3163                     * float2(transform_rtx.w, transform_rty.w);
 3164             o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f);
 3165         }
 3166 #endif
 3167         0x43425844, 0xde1911bf, 0xfff8c893, 0xb0bfc24d, 0x78c9bbc4, 0x00000001, 0x00000924, 0x00000003,
 3168         0x0000002c, 0x000000e4, 0x000001a0, 0x4e475349, 0x000000b0, 0x00000006, 0x00000008, 0x00000098,
 3169         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x000000a1, 0x00000000, 0x00000000,
 3170         0x00000003, 0x00000001, 0x00000303, 0x000000a1, 0x00000001, 0x00000000, 0x00000003, 0x00000002,
 3171         0x00000303, 0x000000a1, 0x00000002, 0x00000000, 0x00000003, 0x00000003, 0x00000303, 0x000000a3,
 3172         0x00000000, 0x00000000, 0x00000003, 0x00000004, 0x00000303, 0x000000a8, 0x00000000, 0x00000000,
 3173         0x00000003, 0x00000005, 0x00000303, 0x49534f50, 0x4e4f4954, 0x50005000, 0x00564552, 0x5458454e,
 3174         0xababab00, 0x4e47534f, 0x000000b4, 0x00000005, 0x00000008, 0x00000080, 0x00000000, 0x00000000,
 3175         0x00000003, 0x00000000, 0x00000c03, 0x0000008f, 0x00000000, 0x00000000, 0x00000003, 0x00000001,
 3176         0x0000000f, 0x00000096, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x00000096,
 3177         0x00000001, 0x00000000, 0x00000003, 0x00000003, 0x00000c03, 0x000000a7, 0x00000000, 0x00000001,
 3178         0x00000003, 0x00000004, 0x0000000f, 0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45,
 3179         0x54530052, 0x454b4f52, 0x4152545f, 0x4f46534e, 0x53004d52, 0x4f505f56, 0x49544953, 0xab004e4f,
 3180         0x52444853, 0x0000077c, 0x00010040, 0x000001df, 0x04000059, 0x00208e46, 0x00000000, 0x00000004,
 3181         0x0300005f, 0x00101032, 0x00000000, 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x00101032,
 3182         0x00000002, 0x0300005f, 0x00101032, 0x00000003, 0x0300005f, 0x00101032, 0x00000004, 0x0300005f,
 3183         0x00101032, 0x00000005, 0x03000065, 0x00102032, 0x00000000, 0x03000065, 0x001020f2, 0x00000001,
 3184         0x03000065, 0x00102032, 0x00000002, 0x03000065, 0x00102032, 0x00000003, 0x04000067, 0x001020f2,
 3185         0x00000004, 0x00000001, 0x02000068, 0x00000004, 0x0800000f, 0x00100012, 0x00000000, 0x00208046,
 3186         0x00000000, 0x00000000, 0x00101046, 0x00000005, 0x0800000f, 0x00100022, 0x00000000, 0x00208046,
 3187         0x00000000, 0x00000001, 0x00101046, 0x00000005, 0x0700000f, 0x00100042, 0x00000000, 0x00100046,
 3188         0x00000000, 0x00100046, 0x00000000, 0x05000044, 0x00100042, 0x00000000, 0x0010002a, 0x00000000,
 3189         0x07000038, 0x00100032, 0x00000000, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x0800000f,
 3190         0x00100012, 0x00000001, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000004, 0x0800000f,
 3191         0x00100022, 0x00000001, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000004, 0x0700000f,
 3192         0x00100042, 0x00000000, 0x00100046, 0x00000001, 0x00100046, 0x00000001, 0x05000044, 0x00100042,
 3193         0x00000000, 0x0010002a, 0x00000000, 0x07000038, 0x00100032, 0x00000001, 0x00100aa6, 0x00000000,
 3194         0x00100046, 0x00000001, 0x06000036, 0x001000c2, 0x00000001, 0x80100556, 0x00000041, 0x00000001,
 3195         0x0700000f, 0x00100042, 0x00000000, 0x00100a26, 0x00000001, 0x00100046, 0x00000000, 0x0700000f,
 3196         0x00100012, 0x00000000, 0x00100046, 0x00000001, 0x00100046, 0x00000000, 0x07000000, 0x00100012,
 3197         0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x3f800000, 0x0800000e, 0x00100012, 0x00000000,
 3198         0x8010002a, 0x00000041, 0x00000000, 0x0010000a, 0x00000000, 0x09000032, 0x00100032, 0x00000000,
 3199         0x00100006, 0x00000000, 0x00100046, 0x00000001, 0x00100f36, 0x00000001, 0x05000036, 0x00100032,
 3200         0x00000001, 0x00101046, 0x00000000, 0x05000036, 0x00100042, 0x00000001, 0x00004001, 0x3f800000,
 3201         0x08000010, 0x00100012, 0x00000002, 0x00100246, 0x00000001, 0x00208246, 0x00000000, 0x00000000,
 3202         0x08000010, 0x00100022, 0x00000002, 0x00100246, 0x00000001, 0x00208246, 0x00000000, 0x00000001,
 3203         0x08000038, 0x00100042, 0x00000000, 0x0020803a, 0x00000000, 0x00000001, 0x00004001, 0x3f000000,
 3204         0x09000032, 0x00100032, 0x00000001, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x00100046,
 3205         0x00000002, 0x05000036, 0x00102032, 0x00000000, 0x00100046, 0x00000001, 0x0800000f, 0x00100012,
 3206         0x00000002, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000000, 0x0800000f, 0x00100022,
 3207         0x00000002, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000000, 0x0800000f, 0x00100022,
 3208         0x00000003, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000001, 0x0800000f, 0x00100012,
 3209         0x00000003, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000001, 0x08000000, 0x00100032,
 3210         0x00000002, 0x00100046, 0x00000002, 0x80100516, 0x00000041, 0x00000003, 0x09000032, 0x00100032,
 3211         0x00000000, 0x00100aa6, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000002, 0x0800000f,
 3212         0x00100022, 0x00000002, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000003, 0x0800000f,
 3213         0x00100012, 0x00000002, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000003, 0x08000000,
 3214         0x001000c2, 0x00000000, 0x80100406, 0x00000041, 0x00000003, 0x00100406, 0x00000002, 0x0800000f,
 3215         0x00100022, 0x00000002, 0x00208046, 0x00000000, 0x00000000, 0x00101046, 0x00000002, 0x0800000f,
 3216         0x00100012, 0x00000002, 0x00208046, 0x00000000, 0x00000001, 0x00101046, 0x00000002, 0x08000000,
 3217         0x00100032, 0x00000002, 0x80100046, 0x00000041, 0x00000003, 0x00100046, 0x00000002, 0x07000038,
 3218         0x00100082, 0x00000001, 0x0010003a, 0x00000000, 0x0010000a, 0x00000002, 0x0a000032, 0x00100082,
 3219         0x00000001, 0x0010001a, 0x00000002, 0x0010002a, 0x00000000, 0x8010003a, 0x00000041, 0x00000001,
 3220         0x08000000, 0x00100042, 0x00000003, 0x0010002a, 0x00000000, 0x8010000a, 0x00000041, 0x00000002,
 3221         0x08000000, 0x00100082, 0x00000003, 0x8010003a, 0x00000041, 0x00000000, 0x0010001a, 0x00000002,
 3222         0x0a000038, 0x00100032, 0x00000003, 0x00100046, 0x00000002, 0x00004002, 0x3f800000, 0xbf800000,
 3223         0x00000000, 0x00000000, 0x0700000e, 0x001000f2, 0x00000002, 0x00100e46, 0x00000003, 0x00100ff6,
 3224         0x00000001, 0x0700000f, 0x00100012, 0x00000002, 0x00100046, 0x00000002, 0x00100046, 0x00000000,
 3225         0x0700000f, 0x00100022, 0x00000002, 0x00100ae6, 0x00000002, 0x00100046, 0x00000000, 0x0a000000,
 3226         0x00102032, 0x00000001, 0x00100046, 0x00000002, 0x00004002, 0x3f800000, 0x00000000, 0x00000000,
 3227         0x00000000, 0x08000036, 0x001020c2, 0x00000001, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
 3228         0x00000000, 0x06000036, 0x00100032, 0x00000000, 0x00208046, 0x00000000, 0x00000002, 0x06000036,
 3229         0x001000c2, 0x00000000, 0x00208406, 0x00000000, 0x00000003, 0x08000038, 0x001000f2, 0x00000000,
 3230         0x00100e46, 0x00000000, 0x00208ff6, 0x00000000, 0x00000001, 0x0a000038, 0x001000f2, 0x00000000,
 3231         0x00100e46, 0x00000000, 0x00004002, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, 0x05000036,
 3232         0x00102032, 0x00000002, 0x00100086, 0x00000000, 0x05000036, 0x00102032, 0x00000003, 0x001005d6,
 3233         0x00000000, 0x05000036, 0x00100042, 0x00000001, 0x00004001, 0x3f800000, 0x08000010, 0x00100012,
 3234         0x00000000, 0x00208246, 0x00000000, 0x00000002, 0x00100246, 0x00000001, 0x08000010, 0x00100022,
 3235         0x00000000, 0x00208246, 0x00000000, 0x00000003, 0x00100246, 0x00000001, 0x08000038, 0x00100022,
 3236         0x00000001, 0x0010001a, 0x00000000, 0x0020803a, 0x00000000, 0x00000003, 0x08000038, 0x00100012,
 3237         0x00000001, 0x0010000a, 0x00000000, 0x0020803a, 0x00000000, 0x00000002, 0x0a000000, 0x00102032,
 3238         0x00000004, 0x00100046, 0x00000001, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000, 0x00000000,
 3239         0x08000036, 0x001020c2, 0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,
 3240         0x0100003e,
 3241     };
 3242     static const DWORD vs_code_triangle[] =
 3243     {
 3244 #if 0
 3245         float3x2 transform_geometry;
 3246         float4 transform_rtx;
 3247         float4 transform_rty;
 3248 
 3249         struct output
 3250         {
 3251             float2 p : WORLD_POSITION;
 3252             float4 b : BEZIER;
 3253             nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM;
 3254             float4 position : SV_POSITION;
 3255         };
 3256 
 3257         void main(float2 position : POSITION, out struct output o)
 3258         {
 3259             o.p = mul(float3(position, 1.0f), transform_geometry);
 3260             o.b = float4(1.0, 0.0, 1.0, 1.0);
 3261             o.stroke_transform = float2x2(1.0, 0.0, 0.0, 1.0);
 3262             position = mul(float2x3(transform_rtx.xyz, transform_rty.xyz), float3(o.p, 1.0f))
 3263                     * float2(transform_rtx.w, transform_rty.w);
 3264             o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f);
 3265         }
 3266 #endif
 3267         0x43425844, 0xda43bf17, 0x06e6d155, 0xdbce2ae5, 0x8aed6fd8, 0x00000001, 0x0000034c, 0x00000003,
 3268         0x0000002c, 0x00000060, 0x0000011c, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
 3269         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x49534f50, 0x4e4f4954, 0xababab00,
 3270         0x4e47534f, 0x000000b4, 0x00000005, 0x00000008, 0x00000080, 0x00000000, 0x00000000, 0x00000003,
 3271         0x00000000, 0x00000c03, 0x0000008f, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f,
 3272         0x00000096, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x00000096, 0x00000001,
 3273         0x00000000, 0x00000003, 0x00000003, 0x00000c03, 0x000000a7, 0x00000000, 0x00000001, 0x00000003,
 3274         0x00000004, 0x0000000f, 0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, 0x54530052,
 3275         0x454b4f52, 0x4152545f, 0x4f46534e, 0x53004d52, 0x4f505f56, 0x49544953, 0xab004e4f, 0x52444853,
 3276         0x00000228, 0x00010040, 0x0000008a, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, 0x0300005f,
 3277         0x00101032, 0x00000000, 0x03000065, 0x00102032, 0x00000000, 0x03000065, 0x001020f2, 0x00000001,
 3278         0x03000065, 0x00102032, 0x00000002, 0x03000065, 0x00102032, 0x00000003, 0x04000067, 0x001020f2,
 3279         0x00000004, 0x00000001, 0x02000068, 0x00000002, 0x05000036, 0x00100032, 0x00000000, 0x00101046,
 3280         0x00000000, 0x05000036, 0x00100042, 0x00000000, 0x00004001, 0x3f800000, 0x08000010, 0x00100012,
 3281         0x00000001, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x08000010, 0x00100022,
 3282         0x00000001, 0x00100246, 0x00000000, 0x00208246, 0x00000000, 0x00000001, 0x05000036, 0x00102032,
 3283         0x00000000, 0x00100046, 0x00000001, 0x08000036, 0x001020f2, 0x00000001, 0x00004002, 0x3f800000,
 3284         0x00000000, 0x3f800000, 0x3f800000, 0x08000036, 0x00102032, 0x00000002, 0x00004002, 0x3f800000,
 3285         0x00000000, 0x00000000, 0x00000000, 0x08000036, 0x00102032, 0x00000003, 0x00004002, 0x00000000,
 3286         0x3f800000, 0x00000000, 0x00000000, 0x05000036, 0x00100042, 0x00000001, 0x00004001, 0x3f800000,
 3287         0x08000010, 0x00100012, 0x00000000, 0x00208246, 0x00000000, 0x00000002, 0x00100246, 0x00000001,
 3288         0x08000010, 0x00100022, 0x00000000, 0x00208246, 0x00000000, 0x00000003, 0x00100246, 0x00000001,
 3289         0x08000038, 0x00100022, 0x00000001, 0x0010001a, 0x00000000, 0x0020803a, 0x00000000, 0x00000003,
 3290         0x08000038, 0x00100012, 0x00000001, 0x0010000a, 0x00000000, 0x0020803a, 0x00000000, 0x00000002,
 3291         0x0a000000, 0x00102032, 0x00000004, 0x00100046, 0x00000001, 0x00004002, 0xbf800000, 0x3f800000,
 3292         0x00000000, 0x00000000, 0x08000036, 0x001020c2, 0x00000004, 0x00004002, 0x00000000, 0x00000000,
 3293         0x00000000, 0x3f800000, 0x0100003e,
 3294     };
 3295     static const DWORD vs_code_curve[] =
 3296     {
 3297 #if 0
 3298         float3x2 transform_geometry;
 3299         float4 transform_rtx;
 3300         float4 transform_rty;
 3301 
 3302         struct output
 3303         {
 3304             float2 p : WORLD_POSITION;
 3305             float4 b : BEZIER;
 3306             nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM;
 3307             float4 position : SV_POSITION;
 3308         };
 3309 
 3310         void main(float2 position : POSITION, float3 texcoord : TEXCOORD0, out struct output o)
 3311         {
 3312             o.p = mul(float3(position, 1.0f), transform_geometry);
 3313             o.b = float4(texcoord, 1.0);
 3314             o.stroke_transform = float2x2(1.0, 0.0, 0.0, 1.0);
 3315             position = mul(float2x3(transform_rtx.xyz, transform_rty.xyz), float3(o.p, 1.0f))
 3316                     * float2(transform_rtx.w, transform_rty.w);
 3317             o.position = float4(position + float2(-1.0f, 1.0f), 0.0f, 1.0f);
 3318         }
 3319 #endif
 3320         0x43425844, 0xedb7472a, 0x2c2ea147, 0x36710079, 0xffc2e907, 0x00000001, 0x00000380, 0x00000003,
 3321         0x0000002c, 0x00000080, 0x0000013c, 0x4e475349, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
 3322         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x00000041, 0x00000000, 0x00000000,
 3323         0x00000003, 0x00000001, 0x00000707, 0x49534f50, 0x4e4f4954, 0x58455400, 0x524f4f43, 0xabab0044,
 3324         0x4e47534f, 0x000000b4, 0x00000005, 0x00000008, 0x00000080, 0x00000000, 0x00000000, 0x00000003,
 3325         0x00000000, 0x00000c03, 0x0000008f, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x0000000f,
 3326         0x00000096, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000c03, 0x00000096, 0x00000001,
 3327         0x00000000, 0x00000003, 0x00000003, 0x00000c03, 0x000000a7, 0x00000000, 0x00000001, 0x00000003,
 3328         0x00000004, 0x0000000f, 0x4c524f57, 0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, 0x54530052,
 3329         0x454b4f52, 0x4152545f, 0x4f46534e, 0x53004d52, 0x4f505f56, 0x49544953, 0xab004e4f, 0x52444853,
 3330         0x0000023c, 0x00010040, 0x0000008f, 0x04000059, 0x00208e46, 0x00000000, 0x00000004, 0x0300005f,
 3331         0x00101032, 0x00000000, 0x0300005f, 0x00101072, 0x00000001, 0x03000065, 0x00102032, 0x00000000,
 3332         0x03000065, 0x001020f2, 0x00000001, 0x03000065, 0x00102032, 0x00000002, 0x03000065, 0x00102032,
 3333         0x00000003, 0x04000067, 0x001020f2, 0x00000004, 0x00000001, 0x02000068, 0x00000002, 0x05000036,
 3334         0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x05000036, 0x00100042, 0x00000000, 0x00004001,
 3335         0x3f800000, 0x08000010, 0x00100012, 0x00000001, 0x00100246, 0x00000000, 0x00208246, 0x00000000,
 3336         0x00000000, 0x08000010, 0x00100022, 0x00000001, 0x00100246, 0x00000000, 0x00208246, 0x00000000,
 3337         0x00000001, 0x05000036, 0x00102032, 0x00000000, 0x00100046, 0x00000001, 0x05000036, 0x00102072,
 3338         0x00000001, 0x00101246, 0x00000001, 0x05000036, 0x00102082, 0x00000001, 0x00004001, 0x3f800000,
 3339         0x08000036, 0x00102032, 0x00000002, 0x00004002, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,
 3340         0x08000036, 0x00102032, 0x00000003, 0x00004002, 0x00000000, 0x3f800000, 0x00000000, 0x00000000,
 3341         0x05000036, 0x00100042, 0x00000001, 0x00004001, 0x3f800000, 0x08000010, 0x00100012, 0x00000000,
 3342         0x00208246, 0x00000000, 0x00000002, 0x00100246, 0x00000001, 0x08000010, 0x00100022, 0x00000000,
 3343         0x00208246, 0x00000000, 0x00000003, 0x00100246, 0x00000001, 0x08000038, 0x00100022, 0x00000001,
 3344         0x0010001a, 0x00000000, 0x0020803a, 0x00000000, 0x00000003, 0x08000038, 0x00100012, 0x00000001,
 3345         0x0010000a, 0x00000000, 0x0020803a, 0x00000000, 0x00000002, 0x0a000000, 0x00102032, 0x00000004,
 3346         0x00100046, 0x00000001, 0x00004002, 0xbf800000, 0x3f800000, 0x00000000, 0x00000000, 0x08000036,
 3347         0x001020c2, 0x00000004, 0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x0100003e,
 3348     };
 3349     static const DWORD ps_code[] =
 3350     {
 3351 #if 0
 3352 #define BRUSH_TYPE_SOLID    0
 3353 #define BRUSH_TYPE_LINEAR   1
 3354 #define BRUSH_TYPE_RADIAL   2
 3355 #define BRUSH_TYPE_BITMAP   3
 3356 #define BRUSH_TYPE_COUNT    4
 3357 
 3358         bool outline;
 3359         bool is_arc;
 3360         struct brush
 3361         {
 3362             uint type;
 3363             float opacity;
 3364             float4 data[3];
 3365         } colour_brush, opacity_brush;
 3366 
 3367         SamplerState s0, s1;
 3368         Texture2D t0, t1;
 3369         Buffer<float4> b0, b1;
 3370 
 3371         struct input
 3372         {
 3373             float2 p : WORLD_POSITION;
 3374             float4 b : BEZIER;
 3375             nointerpolation float2x2 stroke_transform : STROKE_TRANSFORM;
 3376         };
 3377 
 3378         float4 sample_gradient(Buffer<float4> gradient, uint stop_count, float position)
 3379         {
 3380             float4 c_low, c_high;
 3381             float p_low, p_high;
 3382             uint i;
 3383 
 3384             p_low = gradient.Load(0).x;
 3385             c_low = gradient.Load(1);
 3386             c_high = c_low;
 3387 
 3388             if (position < p_low)
 3389                 return c_low;
 3390 
 3391             for (i = 1; i < stop_count; ++i)
 3392             {
 3393                 p_high = gradient.Load(i * 2).x;
 3394                 c_high = gradient.Load(i * 2 + 1);
 3395 
 3396                 if (position >= p_low && position <= p_high)
 3397                     return lerp(c_low, c_high, (position - p_low) / (p_high - p_low));
 3398 
 3399                 p_low = p_high;
 3400                 c_low = c_high;
 3401             }
 3402 
 3403             return c_high;
 3404         }
 3405 
 3406         float4 brush_linear(struct brush brush, Buffer<float4> gradient, float2 position)
 3407         {
 3408             float2 start, end, v_p, v_q;
 3409             uint stop_count;
 3410             float p;
 3411 
 3412             start = brush.data[0].xy;
 3413             end = brush.data[0].zw;
 3414             stop_count = asuint(brush.data[1].x);
 3415 
 3416             v_p = position - start;
 3417             v_q = end - start;
 3418             p = dot(v_q, v_p) / dot(v_q, v_q);
 3419 
 3420             return sample_gradient(gradient, stop_count, p);
 3421         }
 3422 
 3423         float4 brush_radial(struct brush brush, Buffer<float4> gradient, float2 position)
 3424         {
 3425             float2 centre, offset, ra, rb, v_p, v_q, r;
 3426             float b, c, l, t;
 3427             uint stop_count;
 3428 
 3429             centre = brush.data[0].xy;
 3430             offset = brush.data[0].zw;
 3431             ra = brush.data[1].xy;
 3432             rb = brush.data[1].zw;
 3433             stop_count = asuint(brush.data[2].x);
 3434 
 3435             /* Project onto ra, rb. */
 3436             r = float2(dot(ra, ra), dot(rb, rb));
 3437             v_p = position - (centre + offset);
 3438             v_p = float2(dot(v_p, ra), dot(v_p, rb)) / r;
 3439             v_q = float2(dot(offset, ra), dot(offset, rb)) / r;
 3440 
 3441             /* ‖t·p̂ + q⃑‖ = 1
 3442              * (t·p̂ + q⃑) · (t·p̂ + q⃑) = 1
 3443              * t² + 2·(p̂·q⃑)·t + (q⃑·q⃑) = 1
 3444              *
 3445              * b = p̂·q⃑
 3446              * c = q⃑·q⃑ - 1
 3447              * t = -b + √(b² - c) */
 3448             l = length(v_p);
 3449             b = dot(v_p, v_q) / l;
 3450             c = dot(v_q, v_q) - 1.0;
 3451             t = -b + sqrt(b * b - c);
 3452 
 3453             return sample_gradient(gradient, stop_count, l / t);
 3454         }
 3455 
 3456         float4 brush_bitmap(struct brush brush, Texture2D t, SamplerState s, float2 position)
 3457         {
 3458             float3 transform[2];
 3459             bool ignore_alpha;
 3460             float2 texcoord;
 3461             float4 colour;
 3462 
 3463             transform[0] = brush.data[0].xyz;
 3464             transform[1] = brush.data[1].xyz;
 3465             ignore_alpha = asuint(brush.data[1].w);
 3466 
 3467             texcoord.x = dot(position.xy, transform[0].xy) + transform[0].z;
 3468             texcoord.y = dot(position.xy, transform[1].xy) + transform[1].z;
 3469             colour = t.Sample(s, texcoord);
 3470             if (ignore_alpha)
 3471                 colour.a = 1.0;
 3472             return colour;
 3473         }
 3474 
 3475         float4 sample_brush(struct brush brush, Texture2D t, SamplerState s, Buffer<float4> b, float2 position)
 3476         {
 3477             if (brush.type == BRUSH_TYPE_SOLID)
 3478                 return brush.data[0] * brush.opacity;
 3479             if (brush.type == BRUSH_TYPE_LINEAR)
 3480                 return brush_linear(brush, b, position) * brush.opacity;
 3481             if (brush.type == BRUSH_TYPE_RADIAL)
 3482                 return brush_radial(brush, b, position) * brush.opacity;
 3483             if (brush.type == BRUSH_TYPE_BITMAP)
 3484                 return brush_bitmap(brush, t, s, position) * brush.opacity;
 3485             return float4(0.0, 0.0, 0.0, brush.opacity);
 3486         }
 3487 
 3488         float4 main(struct input i) : SV_Target
 3489         {
 3490             float4 colour;
 3491 
 3492             colour = sample_brush(colour_brush, t0, s0, b0, i.p);
 3493             if (opacity_brush.type < BRUSH_TYPE_COUNT)
 3494                 colour *= sample_brush(opacity_brush, t1, s1, b1, i.p).a;
 3495 
 3496             if (outline)
 3497             {
 3498                 float2 du, dv, df;
 3499                 float4 uv;
 3500 
 3501                 /* Evaluate the implicit form of the curve (u² - v = 0
 3502                  * for Béziers, u² + v² - 1 = 0 for arcs) in texture
 3503                  * space, using the screen-space partial derivatives
 3504                  * to convert the calculated distance to object space.
 3505                  *
 3506                  * d(x, y) = |f(x, y)| / ‖∇f(x, y)‖
 3507                  *         = |f(x, y)| / √((∂f/∂x)² + (∂f/∂y)²)
 3508                  *
 3509                  * For Béziers:
 3510                  * f(x, y) = u(x, y)² - v(x, y)
 3511                  * ∂f/∂x = 2u · ∂u/∂x - ∂v/∂x
 3512                  * ∂f/∂y = 2u · ∂u/∂y - ∂v/∂y
 3513                  *
 3514                  * For arcs:
 3515                  * f(x, y) = u(x, y)² + v(x, y)² - 1
 3516                  * ∂f/∂x = 2u · ∂u/∂x + 2v · ∂v/∂x
 3517                  * ∂f/∂y = 2u · ∂u/∂y + 2v · ∂v/∂y */
 3518                 uv = i.b;
 3519                 du = float2(ddx(uv.x), ddy(uv.x));
 3520                 dv = float2(ddx(uv.y), ddy(uv.y));
 3521 
 3522                 if (!is_arc)
 3523                 {
 3524                     df = 2.0f * uv.x * du - dv;
 3525 
 3526                     clip(dot(df, uv.zw));
 3527                     clip(length(mul(i.stroke_transform, df)) - abs(uv.x * uv.x - uv.y));
 3528                 }
 3529                 else
 3530                 {
 3531                     df = 2.0f * uv.x * du + 2.0f * uv.y * dv;
 3532 
 3533                     clip(dot(df, uv.zw));
 3534                     clip(length(mul(i.stroke_transform, df)) - abs(uv.x * uv.x + uv.y * uv.y - 1.0f));
 3535                 }
 3536             }
 3537             else
 3538             {
 3539                 /* Evaluate the implicit form of the curve in texture space.
 3540                  * "i.b.z" determines which side of the curve is shaded. */
 3541                 if (!is_arc)
 3542                 {
 3543                     clip((i.b.x * i.b.x - i.b.y) * i.b.z);
 3544                 }
 3545                 else
 3546                 {
 3547                     clip((i.b.x * i.b.x + i.b.y * i.b.y - 1.0) * i.b.z);
 3548                 }
 3549             }
 3550 
 3551             return colour;
 3552         }
 3553 #endif
 3554         0x43425844, 0xa8fee730, 0x92fa2196, 0xaf9f3eff, 0x888d4048, 0x00000001, 0x00002000, 0x00000003,
 3555         0x0000002c, 0x000000c4, 0x000000f8, 0x4e475349, 0x00000090, 0x00000004, 0x00000008, 0x00000068,
 3556         0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000303, 0x00000077, 0x00000000, 0x00000000,
 3557         0x00000003, 0x00000001, 0x00000f0f, 0x0000007e, 0x00000000, 0x00000000, 0x00000003, 0x00000002,
 3558         0x00000303, 0x0000007e, 0x00000001, 0x00000000, 0x00000003, 0x00000003, 0x00000303, 0x4c524f57,
 3559         0x4f505f44, 0x49544953, 0x42004e4f, 0x45495a45, 0x54530052, 0x454b4f52, 0x4152545f, 0x4f46534e,
 3560         0xab004d52, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
 3561         0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00001f00,
 3562         0x00000040, 0x000007c0, 0x04000059, 0x00208e46, 0x00000000, 0x00000009, 0x0300005a, 0x00106000,
 3563         0x00000000, 0x0300005a, 0x00106000, 0x00000001, 0x04001858, 0x00107000, 0x00000000, 0x00005555,
 3564         0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04000858, 0x00107000, 0x00000002, 0x00005555,
 3565         0x04000858, 0x00107000, 0x00000003, 0x00005555, 0x03001062, 0x00101032, 0x00000000, 0x03001062,
 3566         0x001010f2, 0x00000001, 0x03000862, 0x00101032, 0x00000002, 0x03000862, 0x00101032, 0x00000003,
 3567         0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x0000000a, 0x09000038, 0x001000f2, 0x00000000,
 3568         0x00208556, 0x00000000, 0x00000001, 0x00208e46, 0x00000000, 0x00000002, 0x0404001f, 0x0020800a,
 3569         0x00000000, 0x00000001, 0x08000020, 0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000001,
 3570         0x00004001, 0x00000001, 0x0304001f, 0x0010000a, 0x00000001, 0x09000000, 0x00100062, 0x00000001,
 3571         0x00101106, 0x00000000, 0x80208106, 0x00000041, 0x00000000, 0x00000002, 0x0a000000, 0x00100032,
 3572         0x00000002, 0x80208046, 0x00000041, 0x00000000, 0x00000002, 0x00208ae6, 0x00000000, 0x00000002,
 3573         0x0700000f, 0x00100022, 0x00000001, 0x00100046, 0x00000002, 0x00100596, 0x00000001, 0x0700000f,
 3574         0x00100042, 0x00000001, 0x00100046, 0x00000002, 0x00100046, 0x00000002, 0x0700000e, 0x00100022,
 3575         0x00000001, 0x0010001a, 0x00000001, 0x0010002a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000002,
 3576         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000002, 0x0a00002d,
 3577         0x001000f2, 0x00000003, 0x00004002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00107e46,
 3578         0x00000002, 0x0700001d, 0x00100042, 0x00000001, 0x0010001a, 0x00000001, 0x0010000a, 0x00000002,
 3579         0x0304001f, 0x0010002a, 0x00000001, 0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000003,
 3580         0x05000036, 0x001000f2, 0x00000005, 0x00100e46, 0x00000003, 0x05000036, 0x001000f2, 0x00000006,
 3581         0x00100e46, 0x00000003, 0x05000036, 0x00100042, 0x00000001, 0x0010000a, 0x00000002, 0x05000036,
 3582         0x00100082, 0x00000001, 0x00004001, 0x00000001, 0x05000036, 0x00100022, 0x00000002, 0x00004001,
 3583         0x00000000, 0x01000030, 0x08000050, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x0020800a,
 3584         0x00000000, 0x00000003, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0x00000000, 0x03040003,
 3585         0x0010002a, 0x00000002, 0x07000029, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x00004001,
 3586         0x00000001, 0x0700002d, 0x001000f2, 0x00000007, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002,
 3587         0x0700001e, 0x00100042, 0x00000002, 0x0010002a, 0x00000002, 0x00004001, 0x00000001, 0x0700002d,
 3588         0x001000f2, 0x00000008, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002, 0x0700001d, 0x00100042,
 3589         0x00000002, 0x0010001a, 0x00000001, 0x0010002a, 0x00000001, 0x0700001d, 0x00100082, 0x00000002,
 3590         0x0010000a, 0x00000007, 0x0010001a, 0x00000001, 0x07000001, 0x00100042, 0x00000002, 0x0010003a,
 3591         0x00000002, 0x0010002a, 0x00000002, 0x0304001f, 0x0010002a, 0x00000002, 0x08000000, 0x00100082,
 3592         0x00000002, 0x8010002a, 0x00000041, 0x00000001, 0x0010001a, 0x00000001, 0x08000000, 0x00100022,
 3593         0x00000007, 0x8010002a, 0x00000041, 0x00000001, 0x0010000a, 0x00000007, 0x0700000e, 0x00100082,
 3594         0x00000002, 0x0010003a, 0x00000002, 0x0010001a, 0x00000007, 0x08000000, 0x001000f2, 0x00000009,
 3595         0x80100e46, 0x00000041, 0x00000005, 0x00100e46, 0x00000008, 0x09000032, 0x001000f2, 0x00000009,
 3596         0x00100ff6, 0x00000002, 0x00100e46, 0x00000009, 0x00100e46, 0x00000005, 0x05000036, 0x001000f2,
 3597         0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0xffffffff,
 3598         0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000009, 0x01000002, 0x01000015, 0x05000036,
 3599         0x001000f2, 0x00000005, 0x00100e46, 0x00000008, 0x05000036, 0x00100042, 0x00000001, 0x0010000a,
 3600         0x00000007, 0x0700001e, 0x00100082, 0x00000001, 0x0010003a, 0x00000001, 0x00004001, 0x00000001,
 3601         0x05000036, 0x001000f2, 0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002,
 3602         0x0010002a, 0x00000002, 0x01000016, 0x09000037, 0x001000f2, 0x00000003, 0x00100556, 0x00000002,
 3603         0x00100e46, 0x00000004, 0x00100e46, 0x00000006, 0x01000015, 0x08000038, 0x001000f2, 0x00000000,
 3604         0x00100e46, 0x00000003, 0x00208556, 0x00000000, 0x00000001, 0x01000015, 0x0300001f, 0x0010000a,
 3605         0x00000001, 0x08000020, 0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000001, 0x00004001,
 3606         0x00000002, 0x0304001f, 0x0010000a, 0x00000001, 0x0900000f, 0x00100012, 0x00000002, 0x00208046,
 3607         0x00000000, 0x00000003, 0x00208046, 0x00000000, 0x00000003, 0x0900000f, 0x00100022, 0x00000002,
 3608         0x00208ae6, 0x00000000, 0x00000003, 0x00208ae6, 0x00000000, 0x00000003, 0x09000000, 0x00100062,
 3609         0x00000001, 0x00208ba6, 0x00000000, 0x00000002, 0x00208106, 0x00000000, 0x00000002, 0x08000000,
 3610         0x00100062, 0x00000001, 0x80100656, 0x00000041, 0x00000001, 0x00101106, 0x00000000, 0x0800000f,
 3611         0x00100012, 0x00000003, 0x00100596, 0x00000001, 0x00208046, 0x00000000, 0x00000003, 0x0800000f,
 3612         0x00100022, 0x00000003, 0x00100596, 0x00000001, 0x00208ae6, 0x00000000, 0x00000003, 0x0700000e,
 3613         0x00100062, 0x00000001, 0x00100106, 0x00000003, 0x00100106, 0x00000002, 0x0900000f, 0x00100012,
 3614         0x00000003, 0x00208ae6, 0x00000000, 0x00000002, 0x00208046, 0x00000000, 0x00000003, 0x0900000f,
 3615         0x00100022, 0x00000003, 0x00208ae6, 0x00000000, 0x00000002, 0x00208ae6, 0x00000000, 0x00000003,
 3616         0x0700000e, 0x00100032, 0x00000002, 0x00100046, 0x00000003, 0x00100046, 0x00000002, 0x0700000f,
 3617         0x00100082, 0x00000001, 0x00100596, 0x00000001, 0x00100596, 0x00000001, 0x0500004b, 0x00100082,
 3618         0x00000001, 0x0010003a, 0x00000001, 0x0700000f, 0x00100022, 0x00000001, 0x00100596, 0x00000001,
 3619         0x00100046, 0x00000002, 0x0700000e, 0x00100022, 0x00000001, 0x0010001a, 0x00000001, 0x0010003a,
 3620         0x00000001, 0x0700000f, 0x00100042, 0x00000001, 0x00100046, 0x00000002, 0x00100046, 0x00000002,
 3621         0x07000000, 0x00100042, 0x00000001, 0x0010002a, 0x00000001, 0x00004001, 0xbf800000, 0x0a000032,
 3622         0x00100042, 0x00000001, 0x0010001a, 0x00000001, 0x0010001a, 0x00000001, 0x8010002a, 0x00000041,
 3623         0x00000001, 0x0500004b, 0x00100042, 0x00000001, 0x0010002a, 0x00000001, 0x08000000, 0x00100022,
 3624         0x00000001, 0x0010002a, 0x00000001, 0x8010001a, 0x00000041, 0x00000001, 0x0700000e, 0x00100022,
 3625         0x00000001, 0x0010003a, 0x00000001, 0x0010001a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000002,
 3626         0x00004002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00107e46, 0x00000002, 0x0a00002d,
 3627         0x001000f2, 0x00000003, 0x00004002, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00107e46,
 3628         0x00000002, 0x0700001d, 0x00100042, 0x00000001, 0x0010001a, 0x00000001, 0x0010000a, 0x00000002,
 3629         0x0304001f, 0x0010002a, 0x00000001, 0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000003,
 3630         0x05000036, 0x001000f2, 0x00000005, 0x00100e46, 0x00000003, 0x05000036, 0x001000f2, 0x00000006,
 3631         0x00100e46, 0x00000003, 0x05000036, 0x00100042, 0x00000001, 0x0010000a, 0x00000002, 0x05000036,
 3632         0x00100082, 0x00000001, 0x00004001, 0x00000001, 0x05000036, 0x00100022, 0x00000002, 0x00004001,
 3633         0x00000000, 0x01000030, 0x08000050, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x0020800a,
 3634         0x00000000, 0x00000004, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0x00000000, 0x03040003,
 3635         0x0010002a, 0x00000002, 0x07000029, 0x00100042, 0x00000002, 0x0010003a, 0x00000001, 0x00004001,
 3636         0x00000001, 0x0700002d, 0x001000f2, 0x00000007, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002,
 3637         0x0700001e, 0x00100042, 0x00000002, 0x0010002a, 0x00000002, 0x00004001, 0x00000001, 0x0700002d,
 3638         0x001000f2, 0x00000008, 0x00100aa6, 0x00000002, 0x00107e46, 0x00000002, 0x0700001d, 0x00100042,
 3639         0x00000002, 0x0010001a, 0x00000001, 0x0010002a, 0x00000001, 0x0700001d, 0x00100082, 0x00000002,
 3640         0x0010000a, 0x00000007, 0x0010001a, 0x00000001, 0x07000001, 0x00100042, 0x00000002, 0x0010003a,
 3641         0x00000002, 0x0010002a, 0x00000002, 0x0304001f, 0x0010002a, 0x00000002, 0x08000000, 0x00100082,
 3642         0x00000002, 0x8010002a, 0x00000041, 0x00000001, 0x0010001a, 0x00000001, 0x08000000, 0x00100022,
 3643         0x00000007, 0x8010002a, 0x00000041, 0x00000001, 0x0010000a, 0x00000007, 0x0700000e, 0x00100082,
 3644         0x00000002, 0x0010003a, 0x00000002, 0x0010001a, 0x00000007, 0x08000000, 0x001000f2, 0x00000009,
 3645         0x80100e46, 0x00000041, 0x00000005, 0x00100e46, 0x00000008, 0x09000032, 0x001000f2, 0x00000009,
 3646         0x00100ff6, 0x00000002, 0x00100e46, 0x00000009, 0x00100e46, 0x00000005, 0x05000036, 0x001000f2,
 3647         0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002, 0x00004001, 0xffffffff,
 3648         0x05000036, 0x001000f2, 0x00000004, 0x00100e46, 0x00000009, 0x01000002, 0x01000015, 0x05000036,
 3649         0x001000f2, 0x00000005, 0x00100e46, 0x00000008, 0x05000036, 0x00100042, 0x00000001, 0x0010000a,
 3650         0x00000007, 0x0700001e, 0x00100082, 0x00000001, 0x0010003a, 0x00000001, 0x00004001, 0x00000001,
 3651         0x05000036, 0x001000f2, 0x00000006, 0x00100e46, 0x00000008, 0x05000036, 0x00100022, 0x00000002,
 3652         0x0010002a, 0x00000002, 0x01000016, 0x09000037, 0x001000f2, 0x00000003, 0x00100556, 0x00000002,
 3653         0x00100e46, 0x00000004, 0x00100e46, 0x00000006, 0x01000015, 0x08000038, 0x001000f2, 0x00000000,
 3654         0x00100e46, 0x00000003, 0x00208556, 0x00000000, 0x00000001, 0x01000015, 0x0300001f, 0x0010000a,
 3655         0x00000001, 0x08000020, 0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000001, 0x00004001,
 3656         0x00000003, 0x0304001f, 0x0010000a, 0x00000001, 0x0800000f, 0x00100022, 0x00000001, 0x00101046,
 3657         0x00000000, 0x00208046, 0x00000000, 0x00000002, 0x08000000, 0x00100012, 0x00000002, 0x0010001a,
 3658         0x00000001, 0x0020802a, 0x00000000, 0x00000002, 0x0800000f, 0x00100022, 0x00000001, 0x00101046,
 3659         0x00000000, 0x00208046, 0x00000000, 0x00000003, 0x08000000, 0x00100022, 0x00000002, 0x0010001a,
 3660         0x00000001, 0x0020802a, 0x00000000, 0x00000003, 0x09000045, 0x001000f2, 0x00000002, 0x00100046,
 3661         0x00000002, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0a000037, 0x00100082, 0x00000002,
 3662         0x0020803a, 0x00000000, 0x00000003, 0x00004001, 0x3f800000, 0x0010003a, 0x00000002, 0x08000038,
 3663         0x001000f2, 0x00000000, 0x00100e46, 0x00000002, 0x00208556, 0x00000000, 0x00000001, 0x01000015,
 3664         0x05000036, 0x00100012, 0x00000002, 0x00004001, 0x00000000, 0x06000036, 0x00100082, 0x00000002,
 3665         0x0020801a, 0x00000000, 0x00000001, 0x09000037, 0x001000f2, 0x00000000, 0x00100006, 0x00000001,
 3666         0x00100e46, 0x00000000, 0x00100c06, 0x00000002, 0x01000015, 0x01000015, 0x01000015, 0x0800004f,
 3667         0x00100012, 0x00000001, 0x0020800a, 0x00000000, 0x00000005, 0x00004001, 0x00000004, 0x0304001f,
 3668         0x0010000a, 0x00000001, 0x09000038, 0x00100012, 0x00000001, 0x0020801a, 0x00000000, 0x00000005,
 3669         0x0020803a, 0x00000000, 0x00000006, 0x0404001f, 0x0020800a, 0x00000000, 0x00000005, 0x08000020,
 3670         0x00100022, 0x00000001, 0x0020800a, 0x00000000, 0x00000005, 0x00004001, 0x00000001, 0x0304001f,
 3671         0x0010001a, 0x00000001, 0x09000000, 0x001000c2, 0x00000001, 0x00101406, 0x00000000, 0x80208406,
 3672         0x00000041, 0x00000000, 0x00000006, 0x0a000000, 0x00100032, 0x00000002, 0x80208046, 0x00000041,
 3673         0x00000000, 0x00000006, 0x00208ae6, 0x00000000, 0x00000006, 0x0700000f, 0x00100042, 0x00000001,
 3674         0x00100046, 0x00000002, 0x00100ae6, 0x00000001, 0x0700000f, 0x00100082, 0x00000001, 0x00100046,
 3675         0x00000002, 0x00100046, 0x00000002, 0x0700000e, 0x00100042, 0x00000001, 0x0010002a, 0x00000001,
 3676         0x0010003a, 0x00000001, 0x0a00002d, 0x001000f2, 0x00000002, 0x00004002, 0x00000000, 0x00000000,
 3677         0x00000000, 0x00000000, 0x00107e46, 0x00000003, 0x0a00002d, 0x001000f2, 0x00000003, 0x00004002,
 3678         0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00107e46, 0x00000003, 0x0700001d, 0x00100082,
 3679         0x00000001, 0x0010002a, 0x00000001, 0x0010000a, 0x00000002, 0x0304001f, 0x0010003a, 0x00000001,
 3680         0x05000036, 0x00100082, 0x00000001, 0x0010003a, 0x00000003, 0x05000036, 0x00100062, 0x00000002,
 3681         0x00100ff6, 0x00000003, 0x05000036, 0x00100082, 0x00000002, 0x0010000a, 0x00000002, 0x08000036,
 3682         0x00100032, 0x00000003, 0x00004002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x01000030,
 3683         0x08000050, 0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x0020800a, 0x00000000, 0x00000007,
 3684         0x05000036, 0x00100022, 0x00000003, 0x00004001, 0x00000000, 0x03040003, 0x0010002a, 0x00000003,
 3685         0x07000029, 0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d,
 3686         0x001000f2, 0x00000004, 0x00100aa6, 0x00000003, 0x00107e46, 0x00000003, 0x0700001e, 0x00100042,
 3687         0x00000003, 0x0010002a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d, 0x001000f2, 0x00000005,
 3688         0x00100aa6, 0x00000003, 0x00107e46, 0x00000003, 0x0700001d, 0x00100042, 0x00000003, 0x0010002a,
 3689         0x00000001, 0x0010003a, 0x00000002, 0x0700001d, 0x00100022, 0x00000004, 0x0010000a, 0x00000004,
 3690         0x0010002a, 0x00000001, 0x07000001, 0x00100042, 0x00000003, 0x0010002a, 0x00000003, 0x0010001a,
 3691         0x00000004, 0x0304001f, 0x0010002a, 0x00000003, 0x08000000, 0x00100022, 0x00000004, 0x0010002a,
 3692         0x00000001, 0x8010003a, 0x00000041, 0x00000002, 0x08000000, 0x00100042, 0x00000004, 0x8010003a,
 3693         0x00000041, 0x00000002, 0x0010000a, 0x00000004, 0x0700000e, 0x00100022, 0x00000004, 0x0010001a,
 3694         0x00000004, 0x0010002a, 0x00000004, 0x08000000, 0x00100042, 0x00000004, 0x8010001a, 0x00000041,
 3695         0x00000002, 0x0010003a, 0x00000005, 0x09000032, 0x00100022, 0x00000004, 0x0010001a, 0x00000004,
 3696         0x0010002a, 0x00000004, 0x0010001a, 0x00000002, 0x05000036, 0x00100042, 0x00000002, 0x0010003a,
 3697         0x00000005, 0x05000036, 0x00100022, 0x00000003, 0x00004001, 0xffffffff, 0x05000036, 0x00100082,
 3698         0x00000001, 0x0010001a, 0x00000004, 0x01000002, 0x01000015, 0x05000036, 0x00100022, 0x00000002,
 3699         0x0010003a, 0x00000005, 0x05000036, 0x00100082, 0x00000002, 0x0010000a, 0x00000004, 0x0700001e,
 3700         0x00100012, 0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x05000036, 0x00100042,
 3701         0x00000002, 0x0010003a, 0x00000005, 0x05000036, 0x00100032, 0x00000003, 0x00100086, 0x00000003,
 3702         0x01000016, 0x09000037, 0x00100042, 0x00000001, 0x0010001a, 0x00000003, 0x0010003a, 0x00000001,
 3703         0x0010002a, 0x00000002, 0x01000012, 0x05000036, 0x00100042, 0x00000001, 0x0010003a, 0x00000003,
 3704         0x01000015, 0x08000038, 0x00100012, 0x00000001, 0x0010002a, 0x00000001, 0x0020801a, 0x00000000,
 3705         0x00000005, 0x01000015, 0x0300001f, 0x0010001a, 0x00000001, 0x08000020, 0x00100022, 0x00000001,
 3706         0x0020800a, 0x00000000, 0x00000005, 0x00004001, 0x00000002, 0x0304001f, 0x0010001a, 0x00000001,
 3707         0x0900000f, 0x00100012, 0x00000002, 0x00208046, 0x00000000, 0x00000007, 0x00208046, 0x00000000,
 3708         0x00000007, 0x0900000f, 0x00100022, 0x00000002, 0x00208ae6, 0x00000000, 0x00000007, 0x00208ae6,
 3709         0x00000000, 0x00000007, 0x09000000, 0x001000c2, 0x00000001, 0x00208ea6, 0x00000000, 0x00000006,
 3710         0x00208406, 0x00000000, 0x00000006, 0x08000000, 0x001000c2, 0x00000001, 0x80100ea6, 0x00000041,
 3711         0x00000001, 0x00101406, 0x00000000, 0x0800000f, 0x00100012, 0x00000003, 0x00100ae6, 0x00000001,
 3712         0x00208046, 0x00000000, 0x00000007, 0x0800000f, 0x00100022, 0x00000003, 0x00100ae6, 0x00000001,
 3713         0x00208ae6, 0x00000000, 0x00000007, 0x0700000e, 0x001000c2, 0x00000001, 0x00100406, 0x00000003,
 3714         0x00100406, 0x00000002, 0x0900000f, 0x00100012, 0x00000003, 0x00208ae6, 0x00000000, 0x00000006,
 3715         0x00208046, 0x00000000, 0x00000007, 0x0900000f, 0x00100022, 0x00000003, 0x00208ae6, 0x00000000,
 3716         0x00000006, 0x00208ae6, 0x00000000, 0x00000007, 0x0700000e, 0x00100032, 0x00000002, 0x00100046,
 3717         0x00000003, 0x00100046, 0x00000002, 0x0700000f, 0x00100042, 0x00000002, 0x00100ae6, 0x00000001,
 3718         0x00100ae6, 0x00000001, 0x0500004b, 0x00100042, 0x00000002, 0x0010002a, 0x00000002, 0x0700000f,
 3719         0x00100042, 0x00000001, 0x00100ae6, 0x00000001, 0x00100046, 0x00000002, 0x0700000e, 0x00100042,
 3720         0x00000001, 0x0010002a, 0x00000001, 0x0010002a, 0x00000002, 0x0700000f, 0x00100082, 0x00000001,
 3721         0x00100046, 0x00000002, 0x00100046, 0x00000002, 0x07000000, 0x00100082, 0x00000001, 0x0010003a,
 3722         0x00000001, 0x00004001, 0xbf800000, 0x0a000032, 0x00100082, 0x00000001, 0x0010002a, 0x00000001,
 3723         0x0010002a, 0x00000001, 0x8010003a, 0x00000041, 0x00000001, 0x0500004b, 0x00100082, 0x00000001,
 3724         0x0010003a, 0x00000001, 0x08000000, 0x00100042, 0x00000001, 0x0010003a, 0x00000001, 0x8010002a,
 3725         0x00000041, 0x00000001, 0x0700000e, 0x00100042, 0x00000001, 0x0010002a, 0x00000002, 0x0010002a,
 3726         0x00000001, 0x0a00002d, 0x001000f2, 0x00000002, 0x00004002, 0x00000000, 0x00000000, 0x00000000,
 3727         0x00000000, 0x00107e46, 0x00000003, 0x0a00002d, 0x001000f2, 0x00000003, 0x00004002, 0x00000001,
 3728         0x00000001, 0x00000001, 0x00000001, 0x00107e46, 0x00000003, 0x0700001d, 0x00100082, 0x00000001,
 3729         0x0010002a, 0x00000001, 0x0010000a, 0x00000002, 0x0304001f, 0x0010003a, 0x00000001, 0x05000036,
 3730         0x00100082, 0x00000001, 0x0010003a, 0x00000003, 0x05000036, 0x00100062, 0x00000002, 0x00100ff6,
 3731         0x00000003, 0x05000036, 0x00100082, 0x00000002, 0x0010000a, 0x00000002, 0x08000036, 0x00100032,
 3732         0x00000003, 0x00004002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x01000030, 0x08000050,
 3733         0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x0020800a, 0x00000000, 0x00000008, 0x05000036,
 3734         0x00100022, 0x00000003, 0x00004001, 0x00000000, 0x03040003, 0x0010002a, 0x00000003, 0x07000029,
 3735         0x00100042, 0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d, 0x001000f2,
 3736         0x00000004, 0x00100aa6, 0x00000003, 0x00107e46, 0x00000003, 0x0700001e, 0x00100042, 0x00000003,
 3737         0x0010002a, 0x00000003, 0x00004001, 0x00000001, 0x0700002d, 0x001000f2, 0x00000005, 0x00100aa6,
 3738         0x00000003, 0x00107e46, 0x00000003, 0x0700001d, 0x00100042, 0x00000003, 0x0010002a, 0x00000001,
 3739         0x0010003a, 0x00000002, 0x0700001d, 0x00100022, 0x00000004, 0x0010000a, 0x00000004, 0x0010002a,
 3740         0x00000001, 0x07000001, 0x00100042, 0x00000003, 0x0010002a, 0x00000003, 0x0010001a, 0x00000004,
 3741         0x0304001f, 0x0010002a, 0x00000003, 0x08000000, 0x00100022, 0x00000004, 0x0010002a, 0x00000001,
 3742         0x8010003a, 0x00000041, 0x00000002, 0x08000000, 0x00100042, 0x00000004, 0x8010003a, 0x00000041,
 3743         0x00000002, 0x0010000a, 0x00000004, 0x0700000e, 0x00100022, 0x00000004, 0x0010001a, 0x00000004,
 3744         0x0010002a, 0x00000004, 0x08000000, 0x00100042, 0x00000004, 0x8010001a, 0x00000041, 0x00000002,
 3745         0x0010003a, 0x00000005, 0x09000032, 0x00100022, 0x00000004, 0x0010001a, 0x00000004, 0x0010002a,
 3746         0x00000004, 0x0010001a, 0x00000002, 0x05000036, 0x00100042, 0x00000002, 0x0010003a, 0x00000005,
 3747         0x05000036, 0x00100022, 0x00000003, 0x00004001, 0xffffffff, 0x05000036, 0x00100082, 0x00000001,
 3748         0x0010001a, 0x00000004, 0x01000002, 0x01000015, 0x05000036, 0x00100022, 0x00000002, 0x0010003a,
 3749         0x00000005, 0x05000036, 0x00100082, 0x00000002, 0x0010000a, 0x00000004, 0x0700001e, 0x00100012,
 3750         0x00000003, 0x0010000a, 0x00000003, 0x00004001, 0x00000001, 0x05000036, 0x00100042, 0x00000002,
 3751         0x0010003a, 0x00000005, 0x05000036, 0x00100032, 0x00000003, 0x00100086, 0x00000003, 0x01000016,
 3752         0x09000037, 0x00100042, 0x00000001, 0x0010001a, 0x00000003, 0x0010003a, 0x00000001, 0x0010002a,
 3753         0x00000002, 0x01000012, 0x05000036, 0x00100042, 0x00000001, 0x0010003a, 0x00000003, 0x01000015,
 3754         0x08000038, 0x00100012, 0x00000001, 0x0010002a, 0x00000001, 0x0020801a, 0x00000000, 0x00000005,
 3755         0x01000015, 0x0300001f, 0x0010001a, 0x00000001, 0x08000020, 0x00100022, 0x00000001, 0x0020800a,
 3756         0x00000000, 0x00000005, 0x00004001, 0x00000003, 0x0304001f, 0x0010001a, 0x00000001, 0x0800000f,
 3757         0x00100042, 0x00000001, 0x00101046, 0x00000000, 0x00208046, 0x00000000, 0x00000006, 0x08000000,
 3758         0x00100012, 0x00000002, 0x0010002a, 0x00000001, 0x0020802a, 0x00000000, 0x00000006, 0x0800000f,
 3759         0x00100042, 0x00000001, 0x00101046, 0x00000000, 0x00208046, 0x00000000, 0x00000007, 0x08000000,
 3760         0x00100022, 0x00000002, 0x0010002a, 0x00000001, 0x0020802a, 0x00000000, 0x00000007, 0x09000045,
 3761         0x001000f2, 0x00000002, 0x00100046, 0x00000002, 0x00107e46, 0x00000001, 0x00106000, 0x00000001,
 3762         0x0a000037, 0x00100042, 0x00000001, 0x0020803a, 0x00000000, 0x00000007, 0x00004001, 0x3f800000,
 3763         0x0010003a, 0x00000002, 0x08000038, 0x00100012, 0x00000001, 0x0010002a, 0x00000001, 0x0020801a,
 3764         0x00000000, 0x00000005, 0x01000015, 0x0a000037, 0x00100012, 0x00000001, 0x0010001a, 0x00000001,
 3765         0x0010000a, 0x00000001, 0x0020801a, 0x00000000, 0x00000005, 0x01000015, 0x01000015, 0x01000015,
 3766         0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x00100006, 0x00000001, 0x01000012,
 3767         0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000, 0x01000015, 0x0404001f, 0x0020800a,
 3768         0x00000000, 0x00000000, 0x0500000b, 0x00100032, 0x00000000, 0x00101046, 0x00000001, 0x0500000c,
 3769         0x001000c2, 0x00000000, 0x00101406, 0x00000001, 0x08000027, 0x00100012, 0x00000001, 0x0020801a,
 3770         0x00000000, 0x00000000, 0x00004001, 0x00000000, 0x0500003b, 0x00100022, 0x00000001, 0x0010000a,
 3771         0x00000001, 0x07000000, 0x001000c2, 0x00000001, 0x00101406, 0x00000001, 0x00101406, 0x00000001,
 3772         0x07000038, 0x001000f2, 0x00000002, 0x00100d86, 0x00000000, 0x00100fa6, 0x00000001, 0x0a000032,
 3773         0x00100032, 0x00000000, 0x00100aa6, 0x00000001, 0x00100086, 0x00000000, 0x801005d6, 0x00000041,
 3774         0x00000000, 0x0700000f, 0x00100042, 0x00000000, 0x00100046, 0x00000000, 0x00101ae6, 0x00000001,
 3775         0x07000031, 0x00100042, 0x00000000, 0x0010002a, 0x00000000, 0x00004001, 0x00000000, 0x07000001,
 3776         0x00100042, 0x00000000, 0x0010001a, 0x00000001, 0x0010002a, 0x00000000, 0x0304000d, 0x0010002a,
 3777         0x00000000, 0x07000038, 0x00100062, 0x00000000, 0x00100556, 0x00000000, 0x00101106, 0x00000003,
 3778         0x09000032, 0x00100032, 0x00000000, 0x00101046, 0x00000002, 0x00100006, 0x00000000, 0x00100596,
 3779         0x00000000, 0x0700000f, 0x00100012, 0x00000000, 0x00100046, 0x00000000, 0x00100046, 0x00000000,
 3780         0x0500004b, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x07000038, 0x00100062, 0x00000000,
 3781         0x00101106, 0x00000001, 0x00101106, 0x00000001, 0x0a000032, 0x00100082, 0x00000000, 0x0010100a,
 3782         0x00000001, 0x0010100a, 0x00000001, 0x8010101a, 0x00000041, 0x00000001, 0x08000000, 0x00100012,
 3783         0x00000000, 0x8010003a, 0x000000c1, 0x00000000, 0x0010000a, 0x00000000, 0x07000031, 0x00100012,
 3784         0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100012, 0x00000000,
 3785         0x0010001a, 0x00000001, 0x0010000a, 0x00000000, 0x0304000d, 0x0010000a, 0x00000000, 0x07000000,
 3786         0x00100092, 0x00000000, 0x00100ea6, 0x00000002, 0x00100406, 0x00000002, 0x0700000f, 0x00100022,
 3787         0x00000001, 0x001000c6, 0x00000000, 0x00101ae6, 0x00000001, 0x07000031, 0x00100022, 0x00000001,
 3788         0x0010001a, 0x00000001, 0x00004001, 0x00000000, 0x07000001, 0x00100022, 0x00000001, 0x0010000a,
 3789         0x00000001, 0x0010001a, 0x00000001, 0x0304000d, 0x0010001a, 0x00000001, 0x07000038, 0x00100062,
 3790         0x00000001, 0x00100ff6, 0x00000000, 0x00101106, 0x00000003, 0x09000032, 0x00100092, 0x00000000,
 3791         0x00101406, 0x00000002, 0x00100006, 0x00000000, 0x00100956, 0x00000001, 0x0700000f, 0x00100012,
 3792         0x00000000, 0x001000c6, 0x00000000, 0x001000c6, 0x00000000, 0x0500004b, 0x00100012, 0x00000000,
 3793         0x0010000a, 0x00000000, 0x07000000, 0x00100022, 0x00000000, 0x0010002a, 0x00000000, 0x0010001a,
 3794         0x00000000, 0x07000000, 0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0xbf800000,
 3795         0x08000000, 0x00100012, 0x00000000, 0x8010001a, 0x000000c1, 0x00000000, 0x0010000a, 0x00000000,
 3796         0x07000031, 0x00100012, 0x00000000, 0x0010000a, 0x00000000, 0x00004001, 0x00000000, 0x07000001,
 3797         0x00100012, 0x00000000, 0x0010000a, 0x00000001, 0x0010000a, 0x00000000, 0x0304000d, 0x0010000a,
 3798         0x00000000, 0x01000012, 0x08000027, 0x00100012, 0x00000000, 0x0020801a, 0x00000000, 0x00000000,
 3799         0x00004001, 0x00000000, 0x0500003b, 0x00100022, 0x00000000, 0x0010000a, 0x00000000, 0x07000038,
 3800         0x001000c2, 0x00000000, 0x00101406, 0x00000001, 0x00101406, 0x00000001, 0x0a000032, 0x00100012,
 3801         0x00000001, 0x0010100a, 0x00000001, 0x0010100a, 0x00000001, 0x8010101a, 0x00000041, 0x00000001,
 3802         0x07000038, 0x00100012, 0x00000001, 0x0010000a, 0x00000001, 0x0010102a, 0x00000001, 0x07000031,
 3803         0x00100012, 0x00000001, 0x0010000a, 0x00000001, 0x00004001, 0x00000000, 0x07000001, 0x00100022,
 3804         0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000001, 0x0304000d, 0x0010001a, 0x00000000,
 3805         0x07000000, 0x00100022, 0x00000000, 0x0010003a, 0x00000000, 0x0010002a, 0x00000000, 0x07000000,
 3806         0x00100022, 0x00000000, 0x0010001a, 0x00000000, 0x00004001, 0xbf800000, 0x07000038, 0x00100022,
 3807         0x00000000, 0x0010001a, 0x00000000, 0x0010102a, 0x00000001, 0x07000031, 0x00100022, 0x00000000,
 3808         0x0010001a, 0x00000000, 0x00004001, 0x00000000, 0x07000001, 0x00100012, 0x00000000, 0x0010000a,
 3809         0x00000000, 0x0010001a, 0x00000000, 0x0304000d, 0x0010000a, 0x00000000, 0x01000015, 0x0100003e,
 3810     };
 3811     static const struct shape_info
 3812     {
 3813         enum d2d_shape_type shape_type;
 3814         const D3D10_INPUT_ELEMENT_DESC *il_desc;
 3815         unsigned int il_element_count;
 3816         const void *vs_code;
 3817         size_t vs_code_size;
 3818     }
 3819     shape_info[] =
 3820     {
 3821         {D2D_SHAPE_TYPE_OUTLINE,        il_desc_outline,        ARRAY_SIZE(il_desc_outline),
 3822                                         vs_code_outline,        sizeof(vs_code_outline)},
 3823         {D2D_SHAPE_TYPE_BEZIER_OUTLINE, il_desc_curve_outline,  ARRAY_SIZE(il_desc_curve_outline),
 3824                                         vs_code_bezier_outline, sizeof(vs_code_bezier_outline)},
 3825         {D2D_SHAPE_TYPE_ARC_OUTLINE,    il_desc_curve_outline,  ARRAY_SIZE(il_desc_curve_outline),
 3826                                         vs_code_arc_outline,    sizeof(vs_code_arc_outline)},
 3827         {D2D_SHAPE_TYPE_TRIANGLE,       il_desc_triangle,       ARRAY_SIZE(il_desc_triangle),
 3828                                         vs_code_triangle,       sizeof(vs_code_triangle)},
 3829         {D2D_SHAPE_TYPE_CURVE,          il_desc_curve,          ARRAY_SIZE(il_desc_curve),
 3830                                         vs_code_curve,          sizeof(vs_code_curve)},
 3831     };
 3832     static const struct
 3833     {
 3834         float x, y;
 3835     }
 3836     quad[] =
 3837     {
 3838         {-1.0f,  1.0f},
 3839         {-1.0f, -1.0f},
 3840         { 1.0f,  1.0f},
 3841         { 1.0f, -1.0f},
 3842     };
 3843     static const UINT16 indices[] = {0, 1, 2, 2, 1, 3};
 3844 
 3845     render_target->ID2D1DeviceContext_iface.lpVtbl = &d2d_device_context_vtbl;
 3846     render_target->ID2D1GdiInteropRenderTarget_iface.lpVtbl = &d2d_gdi_interop_render_target_vtbl;
 3847     render_target->IDWriteTextRenderer_iface.lpVtbl = &d2d_text_renderer_vtbl;
 3848     render_target->IUnknown_iface.lpVtbl = &d2d_device_context_inner_unknown_vtbl;
 3849     render_target->refcount = 1;
 3850     ID2D1Device_GetFactory(device, &render_target->factory);
 3851     render_target->device = device;
 3852     ID2D1Device_AddRef(render_target->device);
 3853 
 3854     render_target->outer_unknown = outer_unknown ? outer_unknown : &render_target->IUnknown_iface;
 3855     render_target->ops = ops;
 3856 
 3857     device_impl = unsafe_impl_from_ID2D1Device(device);
 3858     if (FAILED(hr = IDXGIDevice_QueryInterface(device_impl->dxgi_device,
 3859             &IID_ID3D10Device, (void **)&render_target->d3d_device)))
 3860     {
 3861         WARN("Failed to get device interface, hr %#x.\n", hr);
 3862         ID2D1Factory_Release(render_target->factory);
 3863         return hr;
 3864     }
 3865