/*
 * Copyright 2014 Henri Verbeet for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

#include "d2d1_private.h"
#include "wincodec.h"

WINE_DEFAULT_DEBUG_CHANNEL(d2d);

#define INITIAL_CLIP_STACK_SIZE 4

struct d2d_draw_text_layout_ctx
{
    ID2D1Brush *brush;
    D2D1_DRAW_TEXT_OPTIONS options;
};

static void d2d_matrix_multiply(D2D_MATRIX_3X2_F *a, const D2D_MATRIX_3X2_F *b)
{
    D2D_MATRIX_3X2_F tmp = *a;

    a->_11 = tmp._11 * b->_11 + tmp._12 * b->_21;
    a->_12 = tmp._11 * b->_12 + tmp._12 * b->_22;
    a->_21 = tmp._21 * b->_11 + tmp._22 * b->_21;
    a->_22 = tmp._21 * b->_12 + tmp._22 * b->_22;
    a->_31 = tmp._31 * b->_11 + tmp._32 * b->_21 + b->_31;
    a->_32 = tmp._31 * b->_12 + tmp._32 * b->_22 + b->_32;
}

static void d2d_point_transform(D2D1_POINT_2F *dst, const D2D1_MATRIX_3X2_F *matrix, float x, float y)
{
    dst->x = x * matrix->_11 + y * matrix->_21 + matrix->_31;
    dst->y = x * matrix->_12 + y * matrix->_22 + matrix->_32;
}

static void d2d_rect_expand(D2D1_RECT_F *dst, const D2D1_POINT_2F *point)
{
    if (point->x < dst->left)
        dst->left = point->x;
    if (point->y < dst->top)
        dst->top = point->y;
    if (point->x > dst->right)
        dst->right = point->x;
    if (point->y > dst->bottom)
        dst->bottom = point->y;
}

static void d2d_rect_intersect(D2D1_RECT_F *dst, const D2D1_RECT_F *src)
{
    if (src->left > dst->left)
        dst->left = src->left;
    if (src->top > dst->top)
        dst->top = src->top;
    if (src->right < dst->right)
        dst->right = src->right;
    if (src->bottom < dst->bottom)
        dst->bottom = src->bottom;
}

static void d2d_rect_set(D2D1_RECT_F *dst, float left, float top, float right, float bottom)
{
    dst->left = left;
    dst->top = top;
    dst->right = right;
    dst->bottom = bottom;
}

static BOOL d2d_clip_stack_init(struct d2d_clip_stack *stack)
{
    if (!(stack->stack = HeapAlloc(GetProcessHeap(), 0, INITIAL_CLIP_STACK_SIZE * sizeof(*stack->stack))))
        return FALSE;

    stack->size = INITIAL_CLIP_STACK_SIZE;
    stack->count = 0;

    return TRUE;
}

static void d2d_clip_stack_cleanup(struct d2d_clip_stack *stack)
{
    HeapFree(GetProcessHeap(), 0, stack->stack);
}

static BOOL d2d_clip_stack_push(struct d2d_clip_stack *stack, const D2D1_RECT_F *rect)
{
    D2D1_RECT_F r;

    if (stack->count == stack->size)
    {
        D2D1_RECT_F *new_stack;
        unsigned int new_size;

        if (stack->size > UINT_MAX / 2)
            return FALSE;

        new_size = stack->size * 2;
        if (!(new_stack = HeapReAlloc(GetProcessHeap(), 0, stack->stack, new_size * sizeof(*stack->stack))))
            return FALSE;

        stack->stack = new_stack;
        stack->size = new_size;
    }

    r = *rect;
    if (stack->count)
        d2d_rect_intersect(&r, &stack->stack[stack->count - 1]);
    stack->stack[stack->count++] = r;

    return TRUE;
}

static void d2d_clip_stack_pop(struct d2d_clip_stack *stack)
{
    if (!stack->count)
        return;
    --stack->count;
}

static void d2d_draw(struct d2d_d3d_render_target *render_target, ID3D10Buffer *vs_cb,
        ID3D10PixelShader *ps, ID3D10Buffer *ps_cb, struct d2d_brush *brush)
{
    ID3D10Device *device = render_target->device;
    unsigned int offset;
    D3D10_VIEWPORT vp;
    HRESULT hr;
    static const float blend_factor[] = {1.0f, 1.0f, 1.0f, 1.0f};

    vp.TopLeftX = 0;
    vp.TopLeftY = 0;
    vp.Width = render_target->pixel_size.width;
    vp.Height = render_target->pixel_size.height;
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;

    if (FAILED(hr = render_target->stateblock->lpVtbl->Capture(render_target->stateblock)))
    {
        WARN("Failed to capture stateblock, hr %#x.\n", hr);
        return;
    }

    ID3D10Device_ClearState(device);

    ID3D10Device_IASetInputLayout(device, render_target->il);
    ID3D10Device_IASetPrimitiveTopology(device, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
    offset = 0;
    ID3D10Device_IASetVertexBuffers(device, 0, 1, &render_target->vb,
            &render_target->vb_stride, &offset);
    ID3D10Device_VSSetConstantBuffers(device, 0, 1, &vs_cb);
    ID3D10Device_VSSetShader(device, render_target->vs);
    ID3D10Device_PSSetConstantBuffers(device, 0, 1, &ps_cb);
    ID3D10Device_PSSetShader(device, ps);
    ID3D10Device_RSSetViewports(device, 1, &vp);
    if (render_target->clip_stack.count)
    {
        const D2D1_RECT_F *clip_rect;
        D3D10_RECT scissor_rect;

        clip_rect = &render_target->clip_stack.stack[render_target->clip_stack.count - 1];
        scissor_rect.left = clip_rect->left + 0.5f;
        scissor_rect.top = clip_rect->top + 0.5f;
        scissor_rect.right = clip_rect->right + 0.5f;
        scissor_rect.bottom = clip_rect->bottom + 0.5f;
        ID3D10Device_RSSetScissorRects(device, 1, &scissor_rect);
        ID3D10Device_RSSetState(device, render_target->rs);
    }
    ID3D10Device_OMSetRenderTargets(device, 1, &render_target->view, NULL);
    if (brush)
    {
        ID3D10Device_OMSetBlendState(device, render_target->bs, blend_factor, D3D10_DEFAULT_SAMPLE_MASK);
        d2d_brush_bind_resources(brush, device);
    }

    ID3D10Device_Draw(device, 4, 0);

    if (FAILED(hr = render_target->stateblock->lpVtbl->Apply(render_target->stateblock)))
        WARN("Failed to apply stateblock, hr %#x.\n", hr);
}

static inline struct d2d_d3d_render_target *impl_from_ID2D1RenderTarget(ID2D1RenderTarget *iface)
{
    return CONTAINING_RECORD(iface, struct d2d_d3d_render_target, ID2D1RenderTarget_iface);
}

static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_QueryInterface(ID2D1RenderTarget *iface, REFIID iid, void **out)
{
    TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);

    if (IsEqualGUID(iid, &IID_ID2D1RenderTarget)
            || IsEqualGUID(iid, &IID_ID2D1Resource)
            || IsEqualGUID(iid, &IID_IUnknown))
    {
        ID2D1RenderTarget_AddRef(iface);
        *out = iface;
        return S_OK;
    }

    WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));

    *out = NULL;
    return E_NOINTERFACE;
}

static ULONG STDMETHODCALLTYPE d2d_d3d_render_target_AddRef(ID2D1RenderTarget *iface)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
    ULONG refcount = InterlockedIncrement(&render_target->refcount);

    TRACE("%p increasing refcount to %u.\n", iface, refcount);

    return refcount;
}

static ULONG STDMETHODCALLTYPE d2d_d3d_render_target_Release(ID2D1RenderTarget *iface)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
    ULONG refcount = InterlockedDecrement(&render_target->refcount);

    TRACE("%p decreasing refcount to %u.\n", iface, refcount);

    if (!refcount)
    {
        d2d_clip_stack_cleanup(&render_target->clip_stack);
        if (render_target->text_rendering_params)
            IDWriteRenderingParams_Release(render_target->text_rendering_params);
        ID3D10PixelShader_Release(render_target->rect_bitmap_ps);
        ID3D10PixelShader_Release(render_target->rect_solid_ps);
        ID3D10BlendState_Release(render_target->bs);
        ID3D10RasterizerState_Release(render_target->rs);
        ID3D10VertexShader_Release(render_target->vs);
        ID3D10Buffer_Release(render_target->vb);
        ID3D10InputLayout_Release(render_target->il);
        render_target->stateblock->lpVtbl->Release(render_target->stateblock);
        ID3D10RenderTargetView_Release(render_target->view);
        ID3D10Device_Release(render_target->device);
        ID2D1Factory_Release(render_target->factory);
        HeapFree(GetProcessHeap(), 0, render_target);
    }

    return refcount;
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_GetFactory(ID2D1RenderTarget *iface, ID2D1Factory **factory)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p, factory %p.\n", iface, factory);

    *factory = render_target->factory;
    ID2D1Factory_AddRef(*factory);
}

static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmap(ID2D1RenderTarget *iface,
        D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
    struct d2d_bitmap *object;
    HRESULT hr;

    TRACE("iface %p, size {%u, %u}, src_data %p, pitch %u, desc %p, bitmap %p.\n",
            iface, size.width, size.height, src_data, pitch, desc, bitmap);

    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
        return E_OUTOFMEMORY;

    if (FAILED(hr = d2d_bitmap_init(object, render_target, size, src_data, pitch, desc)))
    {
        WARN("Failed to initialize bitmap, hr %#x.\n", hr);
        HeapFree(GetProcessHeap(), 0, object);
        return hr;
    }

    TRACE("Created bitmap %p.\n", object);
    *bitmap = &object->ID2D1Bitmap_iface;

    return S_OK;
}

static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmapFromWicBitmap(ID2D1RenderTarget *iface,
        IWICBitmapSource *bitmap_source, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
{
    D2D1_BITMAP_PROPERTIES bitmap_desc;
    unsigned int bpp, data_size;
    D2D1_SIZE_U size;
    WICRect rect;
    UINT32 pitch;
    HRESULT hr;
    void *data;

    TRACE("iface %p, bitmap_source %p, desc %p, bitmap %p.\n",
            iface, bitmap_source, desc, bitmap);

    if (FAILED(hr = IWICBitmapSource_GetSize(bitmap_source, &size.width, &size.height)))
    {
        WARN("Failed to get bitmap size, hr %#x.\n", hr);
        return hr;
    }

    if (!desc)
    {
        bitmap_desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
        bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_UNKNOWN;
        bitmap_desc.dpiX = 0.0f;
        bitmap_desc.dpiY = 0.0f;
    }
    else
    {
        bitmap_desc = *desc;
    }

    if (bitmap_desc.pixelFormat.format == DXGI_FORMAT_UNKNOWN)
    {
        WICPixelFormatGUID wic_format;

        if (FAILED(hr = IWICBitmapSource_GetPixelFormat(bitmap_source, &wic_format)))
        {
            WARN("Failed to get bitmap format, hr %#x.\n", hr);
            return hr;
        }

        if (IsEqualGUID(&wic_format, &GUID_WICPixelFormat32bppPBGRA)
                || IsEqualGUID(&wic_format, &GUID_WICPixelFormat32bppBGR))
        {
            bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
        }
        else
        {
            WARN("Unsupported WIC bitmap format %s.\n", debugstr_guid(&wic_format));
            return D2DERR_UNSUPPORTED_PIXEL_FORMAT;
        }
    }

    switch (bitmap_desc.pixelFormat.format)
    {
        case DXGI_FORMAT_B8G8R8A8_UNORM:
            bpp = 4;
            break;

        default:
            FIXME("Unhandled format %#x.\n", bitmap_desc.pixelFormat.format);
            return D2DERR_UNSUPPORTED_PIXEL_FORMAT;
    }

    pitch = ((bpp * size.width) + 15) & ~15;
    data_size = pitch * size.height;
    if (!(data = HeapAlloc(GetProcessHeap(), 0, data_size)))
        return E_OUTOFMEMORY;

    rect.X = 0;
    rect.Y = 0;
    rect.Width = size.width;
    rect.Height = size.height;
    if (FAILED(hr = IWICBitmapSource_CopyPixels(bitmap_source, &rect, pitch, data_size, data)))
    {
        WARN("Failed to copy bitmap pixels, hr %#x.\n", hr);
        HeapFree(GetProcessHeap(), 0, data);
        return hr;
    }

    hr = d2d_d3d_render_target_CreateBitmap(iface, size, data, pitch, &bitmap_desc, bitmap);

    HeapFree(GetProcessHeap(), 0, data);

    return hr;
}

static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateSharedBitmap(ID2D1RenderTarget *iface,
        REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, ID2D1Bitmap **bitmap)
{
    FIXME("iface %p, iid %s, data %p, desc %p, bitmap %p stub!\n",
        iface, debugstr_guid(iid), data, desc, bitmap);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmapBrush(ID2D1RenderTarget *iface,
        ID2D1Bitmap *bitmap, const D2D1_BITMAP_BRUSH_PROPERTIES *bitmap_brush_desc,
        const D2D1_BRUSH_PROPERTIES *brush_desc, ID2D1BitmapBrush **brush)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
    struct d2d_brush *object;
    HRESULT hr;

    TRACE("iface %p, bitmap %p, bitmap_brush_desc %p, brush_desc %p, brush %p.\n",
            iface, bitmap, bitmap_brush_desc, brush_desc, brush);

    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
        return E_OUTOFMEMORY;

    if (FAILED(hr = d2d_bitmap_brush_init(object, render_target, bitmap, bitmap_brush_desc, brush_desc)))
    {
        WARN("Failed to initialize brush, hr %#x.\n", hr);
        HeapFree(GetProcessHeap(), 0, object);
        return hr;
    }

    TRACE("Created brush %p.\n", object);
    *brush = (ID2D1BitmapBrush *)&object->ID2D1Brush_iface;

    return S_OK;
}

static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateSolidColorBrush(ID2D1RenderTarget *iface,
        const D2D1_COLOR_F *color, const D2D1_BRUSH_PROPERTIES *desc, ID2D1SolidColorBrush **brush)
{
    struct d2d_brush *object;

    TRACE("iface %p, color %p, desc %p, brush %p.\n", iface, color, desc, brush);

    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
        return E_OUTOFMEMORY;

    d2d_solid_color_brush_init(object, iface, color, desc);

    TRACE("Created brush %p.\n", object);
    *brush = (ID2D1SolidColorBrush *)&object->ID2D1Brush_iface;

    return S_OK;
}

static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateGradientStopCollection(ID2D1RenderTarget *iface,
        const D2D1_GRADIENT_STOP *stops, UINT32 stop_count, D2D1_GAMMA gamma, D2D1_EXTEND_MODE extend_mode,
        ID2D1GradientStopCollection **gradient)
{
    struct d2d_gradient *object;
    HRESULT hr;

    TRACE("iface %p, stops %p, stop_count %u, gamma %#x, extend_mode %#x, gradient %p.\n",
            iface, stops, stop_count, gamma, extend_mode, gradient);

    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
        return E_OUTOFMEMORY;

    if (FAILED(hr = d2d_gradient_init(object, iface, stops, stop_count, gamma, extend_mode)))
    {
        WARN("Failed to initialize gradient, hr %#x.\n", hr);
        HeapFree(GetProcessHeap(), 0, object);
        return hr;
    }

    TRACE("Created gradient %p.\n", object);
    *gradient = &object->ID2D1GradientStopCollection_iface;

    return S_OK;
}

static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateLinearGradientBrush(ID2D1RenderTarget *iface,
        const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc,
        ID2D1GradientStopCollection *gradient, ID2D1LinearGradientBrush **brush)
{
    struct d2d_brush *object;

    TRACE("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n",
            iface, gradient_brush_desc, brush_desc, gradient, brush);

    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
        return E_OUTOFMEMORY;

    d2d_linear_gradient_brush_init(object, iface, gradient_brush_desc, brush_desc, gradient);

    TRACE("Created brush %p.\n", object);
    *brush = (ID2D1LinearGradientBrush *)&object->ID2D1Brush_iface;

    return S_OK;
}

static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateRadialGradientBrush(ID2D1RenderTarget *iface,
        const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, const D2D1_BRUSH_PROPERTIES *brush_desc,
        ID2D1GradientStopCollection *gradient, ID2D1RadialGradientBrush **brush)
{
    FIXME("iface %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p stub!\n",
            iface, gradient_brush_desc, brush_desc, gradient, brush);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateCompatibleRenderTarget(ID2D1RenderTarget *iface,
        const D2D1_SIZE_F *size, const D2D1_SIZE_U *pixel_size, const D2D1_PIXEL_FORMAT *format,
        D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options, ID2D1BitmapRenderTarget **render_target)
{
    FIXME("iface %p, size %p, pixel_size %p, format %p, options %#x, render_target %p stub!\n",
            iface, size, pixel_size, format, options, render_target);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateLayer(ID2D1RenderTarget *iface,
        const D2D1_SIZE_F *size, ID2D1Layer **layer)
{
    FIXME("iface %p, size %p, layer %p stub!\n", iface, size, layer);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateMesh(ID2D1RenderTarget *iface, ID2D1Mesh **mesh)
{
    struct d2d_mesh *object;

    TRACE("iface %p, mesh %p.\n", iface, mesh);

    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
        return E_OUTOFMEMORY;

    d2d_mesh_init(object);

    TRACE("Created mesh %p.\n", object);
    *mesh = &object->ID2D1Mesh_iface;

    return S_OK;
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawLine(ID2D1RenderTarget *iface,
        D2D1_POINT_2F p0, D2D1_POINT_2F p1, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
{
    FIXME("iface %p, p0 {%.8e, %.8e}, p1 {%.8e, %.8e}, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
            iface, p0.x, p0.y, p1.x, p1.y, brush, stroke_width, stroke_style);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawRectangle(ID2D1RenderTarget *iface,
        const D2D1_RECT_F *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
{
    FIXME("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
            iface, rect, brush, stroke_width, stroke_style);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRectangle(ID2D1RenderTarget *iface,
        const D2D1_RECT_F *rect, ID2D1Brush *brush)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
    struct d2d_brush *brush_impl = unsafe_impl_from_ID2D1Brush(brush);
    D3D10_SUBRESOURCE_DATA buffer_data;
    D3D10_BUFFER_DESC buffer_desc;
    ID3D10Buffer *vs_cb, *ps_cb;
    ID3D10PixelShader *ps;
    D2D1_COLOR_F color;
    float tmp_x, tmp_y;
    HRESULT hr;
    struct
    {
        float _11, _21, _31, pad0;
        float _12, _22, _32, pad1;
    } transform;

    TRACE("iface %p, rect %p, brush %p.\n", iface, rect, brush);

    if (brush_impl->type != D2D_BRUSH_TYPE_SOLID
            && brush_impl->type != D2D_BRUSH_TYPE_BITMAP)
    {
        FIXME("Unhandled brush type %#x.\n", brush_impl->type);
        return;
    }

    /* Translate from clip space to world (D2D rendertarget) space, taking the
     * dpi and rendertarget transform into account. */
    tmp_x =  (2.0f * render_target->dpi_x) / (96.0f * render_target->pixel_size.width);
    tmp_y = -(2.0f * render_target->dpi_y) / (96.0f * render_target->pixel_size.height);
    transform._11 = render_target->drawing_state.transform._11 * tmp_x;
    transform._21 = render_target->drawing_state.transform._21 * tmp_x;
    transform._31 = render_target->drawing_state.transform._31 * tmp_x - 1.0f;
    transform.pad0 = 0.0f;
    transform._12 = render_target->drawing_state.transform._12 * tmp_y;
    transform._22 = render_target->drawing_state.transform._22 * tmp_y;
    transform._32 = render_target->drawing_state.transform._32 * tmp_y + 1.0f;
    transform.pad1 = 0.0f;

    /* Translate from world space to object space. */
    tmp_x = min(rect->left, rect->right) + fabsf(rect->right - rect->left) / 2.0f;
    tmp_y = min(rect->top, rect->bottom) + fabsf(rect->bottom - rect->top) / 2.0f;
    transform._31 += tmp_x * transform._11 + tmp_y * transform._21;
    transform._32 += tmp_x * transform._12 + tmp_y * transform._22;
    tmp_x = fabsf(rect->right - rect->left) / 2.0f;
    tmp_y = fabsf(rect->bottom - rect->top) / 2.0f;
    transform._11 *= tmp_x;
    transform._12 *= tmp_x;
    transform._21 *= tmp_y;
    transform._22 *= tmp_y;

    buffer_desc.ByteWidth = sizeof(transform);
    buffer_desc.Usage = D3D10_USAGE_DEFAULT;
    buffer_desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
    buffer_desc.CPUAccessFlags = 0;
    buffer_desc.MiscFlags = 0;

    buffer_data.pSysMem = &transform;
    buffer_data.SysMemPitch = 0;
    buffer_data.SysMemSlicePitch = 0;

    if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &vs_cb)))
    {
        WARN("Failed to create constant buffer, hr %#x.\n", hr);
        return;
    }

    if (brush_impl->type == D2D_BRUSH_TYPE_BITMAP)
    {
        struct d2d_bitmap *bitmap = brush_impl->u.bitmap.bitmap;
        D2D_MATRIX_3X2_F w, b;
        float dpi_scale, d;

        ps = render_target->rect_bitmap_ps;

        /* Scale for dpi. */
        w = render_target->drawing_state.transform;
        dpi_scale = render_target->dpi_x / 96.0f;
        w._11 *= dpi_scale;
        w._21 *= dpi_scale;
        w._31 *= dpi_scale;
        dpi_scale = render_target->dpi_y / 96.0f;
        w._12 *= dpi_scale;
        w._22 *= dpi_scale;
        w._32 *= dpi_scale;

        /* Scale for bitmap size and dpi. */
        b = brush_impl->transform;
        dpi_scale = bitmap->pixel_size.width * (bitmap->dpi_x / 96.0f);
        b._11 *= dpi_scale;
        b._21 *= dpi_scale;
        dpi_scale = bitmap->pixel_size.height * (bitmap->dpi_y / 96.0f);
        b._12 *= dpi_scale;
        b._22 *= dpi_scale;

        d2d_matrix_multiply(&b, &w);

        /* Invert the matrix. (Because the matrix is applied to the sampling
         * coordinates. I.e., to scale the bitmap by 2 we need to divide the
         * coordinates by 2.) */
        d = b._11 * b._22 - b._21 * b._12;
        if (d != 0.0f)
        {
            transform._11 = b._22 / d;
            transform._21 = -b._21 / d;
            transform._31 = (b._21 * b._32 - b._31 * b._22) / d;
            transform._12 = -b._12 / d;
            transform._22 = b._11 / d;
            transform._32 = -(b._11 * b._32 - b._31 * b._12) / d;
        }
        transform.pad1 = brush_impl->opacity;

        buffer_desc.ByteWidth = sizeof(transform);
        buffer_data.pSysMem = &transform;
    }
    else
    {
        ps = render_target->rect_solid_ps;

        color = brush_impl->u.solid.color;
        color.a *= brush_impl->opacity;

        buffer_desc.ByteWidth = sizeof(color);
        buffer_data.pSysMem = &color;
    }

    if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &ps_cb)))
    {
        WARN("Failed to create constant buffer, hr %#x.\n", hr);
        ID3D10Buffer_Release(vs_cb);
        return;
    }

    d2d_draw(render_target, vs_cb, ps, ps_cb, brush_impl);

    ID3D10Buffer_Release(ps_cb);
    ID3D10Buffer_Release(vs_cb);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawRoundedRectangle(ID2D1RenderTarget *iface,
        const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
{
    FIXME("iface %p, rect %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
            iface, rect, brush, stroke_width, stroke_style);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_FillRoundedRectangle(ID2D1RenderTarget *iface,
        const D2D1_ROUNDED_RECT *rect, ID2D1Brush *brush)
{
    FIXME("iface %p, rect %p, brush %p stub!\n", iface, rect, brush);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawEllipse(ID2D1RenderTarget *iface,
        const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
{
    FIXME("iface %p, ellipse %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
            iface, ellipse, brush, stroke_width, stroke_style);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_FillEllipse(ID2D1RenderTarget *iface,
        const D2D1_ELLIPSE *ellipse, ID2D1Brush *brush)
{
    FIXME("iface %p, ellipse %p, brush %p stub!\n", iface, ellipse, brush);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGeometry(ID2D1RenderTarget *iface,
        ID2D1Geometry *geometry, ID2D1Brush *brush, float stroke_width, ID2D1StrokeStyle *stroke_style)
{
    FIXME("iface %p, geometry %p, brush %p, stroke_width %.8e, stroke_style %p stub!\n",
            iface, geometry, brush, stroke_width, stroke_style);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_FillGeometry(ID2D1RenderTarget *iface,
        ID2D1Geometry *geometry, ID2D1Brush *brush, ID2D1Brush *opacity_brush)
{
    FIXME("iface %p, geometry %p, brush %p, opacity_brush %p stub!\n", iface, geometry, brush, opacity_brush);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_FillMesh(ID2D1RenderTarget *iface,
        ID2D1Mesh *mesh, ID2D1Brush *brush)
{
    FIXME("iface %p, mesh %p, brush %p stub!\n", iface, mesh, brush);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_FillOpacityMask(ID2D1RenderTarget *iface,
        ID2D1Bitmap *mask, ID2D1Brush *brush, D2D1_OPACITY_MASK_CONTENT content,
        const D2D1_RECT_F *dst_rect, const D2D1_RECT_F *src_rect)
{
    FIXME("iface %p, mask %p, brush %p, content %#x, dst_rect %p, src_rect %p stub!\n",
            iface, mask, brush, content, dst_rect, src_rect);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawBitmap(ID2D1RenderTarget *iface,
        ID2D1Bitmap *bitmap, const D2D1_RECT_F *dst_rect, float opacity,
        D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode, const D2D1_RECT_F *src_rect)
{
    D2D1_BITMAP_BRUSH_PROPERTIES bitmap_brush_desc;
    D2D1_BRUSH_PROPERTIES brush_desc;
    ID2D1BitmapBrush *brush;
    D2D1_RECT_F s, d;
    HRESULT hr;

    TRACE("iface %p, bitmap %p, dst_rect %p, opacity %.8e, interpolation_mode %#x, src_rect %p.\n",
            iface, bitmap, dst_rect, opacity, interpolation_mode, src_rect);

    if (src_rect)
    {
        s = *src_rect;
    }
    else
    {
        D2D1_SIZE_F size;

        size = ID2D1Bitmap_GetSize(bitmap);
        s.left = 0.0f;
        s.top = 0.0f;
        s.right = size.width;
        s.bottom = size.height;
    }

    if (dst_rect)
    {
        d = *dst_rect;
    }
    else
    {
        d.left = 0.0f;
        d.top = 0.0f;
        d.right = s.right - s.left;
        d.bottom = s.bottom - s.top;
    }

    bitmap_brush_desc.extendModeX = D2D1_EXTEND_MODE_CLAMP;
    bitmap_brush_desc.extendModeY = D2D1_EXTEND_MODE_CLAMP;
    bitmap_brush_desc.interpolationMode = interpolation_mode;

    brush_desc.opacity = opacity;
    brush_desc.transform._11 = fabsf((d.right - d.left) / (s.right - s.left));
    brush_desc.transform._21 = 0.0f;
    brush_desc.transform._31 = min(d.left, d.right) - min(s.left, s.right) * brush_desc.transform._11;
    brush_desc.transform._12 = 0.0f;
    brush_desc.transform._22 = fabsf((d.bottom - d.top) / (s.bottom - s.top));
    brush_desc.transform._32 = min(d.top, d.bottom) - min(s.top, s.bottom) * brush_desc.transform._22;

    if (FAILED(hr = ID2D1RenderTarget_CreateBitmapBrush(iface, bitmap, &bitmap_brush_desc, &brush_desc, &brush)))
    {
        ERR("Failed to create bitmap brush, hr %#x.\n", hr);
        return;
    }

    ID2D1RenderTarget_FillRectangle(iface, &d, (ID2D1Brush *)brush);
    ID2D1BitmapBrush_Release(brush);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawText(ID2D1RenderTarget *iface,
        const WCHAR *string, UINT32 string_len, IDWriteTextFormat *text_format, const D2D1_RECT_F *layout_rect,
        ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options, DWRITE_MEASURING_MODE measuring_mode)
{
    FIXME("iface %p, string %s, string_len %u, text_format %p, layout_rect %p, "
            "brush %p, options %#x, measuring_mode %#x stub!\n",
            iface, debugstr_wn(string, string_len), string_len, text_format, layout_rect,
            brush, options, measuring_mode);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawTextLayout(ID2D1RenderTarget *iface,
        D2D1_POINT_2F origin, IDWriteTextLayout *layout, ID2D1Brush *brush, D2D1_DRAW_TEXT_OPTIONS options)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
    struct d2d_draw_text_layout_ctx ctx;
    HRESULT hr;

    TRACE("iface %p, origin {%.8e, %.8e}, layout %p, brush %p, options %#x.\n",
            iface, origin.x, origin.y, layout, brush, options);

    ctx.brush = brush;
    ctx.options = options;

    if (FAILED(hr = IDWriteTextLayout_Draw(layout,
            &ctx, &render_target->IDWriteTextRenderer_iface, origin.x, origin.y)))
        FIXME("Failed to draw text layout, hr %#x.\n", hr);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGlyphRun(ID2D1RenderTarget *iface,
        D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush,
        DWRITE_MEASURING_MODE measuring_mode)
{
    FIXME("iface %p, baseline_origin {%.8e, %.8e}, glyph_run %p, brush %p, measuring_mode %#x stub!\n",
            iface, baseline_origin.x, baseline_origin.y, glyph_run, brush, measuring_mode);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTransform(ID2D1RenderTarget *iface,
        const D2D1_MATRIX_3X2_F *transform)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p, transform %p.\n", iface, transform);

    render_target->drawing_state.transform = *transform;
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_GetTransform(ID2D1RenderTarget *iface,
        D2D1_MATRIX_3X2_F *transform)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p, transform %p.\n", iface, transform);

    *transform = render_target->drawing_state.transform;
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_SetAntialiasMode(ID2D1RenderTarget *iface,
        D2D1_ANTIALIAS_MODE antialias_mode)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p, antialias_mode %#x stub!\n", iface, antialias_mode);

    render_target->drawing_state.antialiasMode = antialias_mode;
}

static D2D1_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_d3d_render_target_GetAntialiasMode(ID2D1RenderTarget *iface)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p.\n", iface);

    return render_target->drawing_state.antialiasMode;
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTextAntialiasMode(ID2D1RenderTarget *iface,
        D2D1_TEXT_ANTIALIAS_MODE antialias_mode)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p, antialias_mode %#x.\n", iface, antialias_mode);

    render_target->drawing_state.textAntialiasMode = antialias_mode;
}

static D2D1_TEXT_ANTIALIAS_MODE STDMETHODCALLTYPE d2d_d3d_render_target_GetTextAntialiasMode(ID2D1RenderTarget *iface)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p.\n", iface);

    return render_target->drawing_state.textAntialiasMode;
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTextRenderingParams(ID2D1RenderTarget *iface,
        IDWriteRenderingParams *text_rendering_params)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p, text_rendering_params %p.\n", iface, text_rendering_params);

    if (text_rendering_params)
        IDWriteRenderingParams_AddRef(text_rendering_params);
    if (render_target->text_rendering_params)
        IDWriteRenderingParams_Release(render_target->text_rendering_params);
    render_target->text_rendering_params = text_rendering_params;
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_GetTextRenderingParams(ID2D1RenderTarget *iface,
        IDWriteRenderingParams **text_rendering_params)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p, text_rendering_params %p.\n", iface, text_rendering_params);

    if ((*text_rendering_params = render_target->text_rendering_params))
        IDWriteRenderingParams_AddRef(*text_rendering_params);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTags(ID2D1RenderTarget *iface, D2D1_TAG tag1, D2D1_TAG tag2)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p, tag1 %s, tag2 %s.\n", iface, wine_dbgstr_longlong(tag1), wine_dbgstr_longlong(tag2));

    render_target->drawing_state.tag1 = tag1;
    render_target->drawing_state.tag2 = tag2;
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_GetTags(ID2D1RenderTarget *iface, D2D1_TAG *tag1, D2D1_TAG *tag2)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2);

    *tag1 = render_target->drawing_state.tag1;
    *tag2 = render_target->drawing_state.tag2;
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_PushLayer(ID2D1RenderTarget *iface,
        const D2D1_LAYER_PARAMETERS *layer_parameters, ID2D1Layer *layer)
{
    FIXME("iface %p, layer_parameters %p, layer %p stub!\n", iface, layer_parameters, layer);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_PopLayer(ID2D1RenderTarget *iface)
{
    FIXME("iface %p stub!\n", iface);
}

static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_Flush(ID2D1RenderTarget *iface, D2D1_TAG *tag1, D2D1_TAG *tag2)
{
    FIXME("iface %p, tag1 %p, tag2 %p stub!\n", iface, tag1, tag2);

    return E_NOTIMPL;
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_SaveDrawingState(ID2D1RenderTarget *iface,
        ID2D1DrawingStateBlock *state_block)
{
    struct d2d_state_block *state_block_impl = unsafe_impl_from_ID2D1DrawingStateBlock(state_block);
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p, state_block %p.\n", iface, state_block);

    state_block_impl->drawing_state = render_target->drawing_state;
    if (render_target->text_rendering_params)
        IDWriteRenderingParams_AddRef(render_target->text_rendering_params);
    if (state_block_impl->text_rendering_params)
        IDWriteRenderingParams_Release(state_block_impl->text_rendering_params);
    state_block_impl->text_rendering_params = render_target->text_rendering_params;
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_RestoreDrawingState(ID2D1RenderTarget *iface,
        ID2D1DrawingStateBlock *state_block)
{
    struct d2d_state_block *state_block_impl = unsafe_impl_from_ID2D1DrawingStateBlock(state_block);
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p, state_block %p.\n", iface, state_block);

    render_target->drawing_state = state_block_impl->drawing_state;
    if (state_block_impl->text_rendering_params)
        IDWriteRenderingParams_AddRef(state_block_impl->text_rendering_params);
    if (render_target->text_rendering_params)
        IDWriteRenderingParams_Release(render_target->text_rendering_params);
    render_target->text_rendering_params = state_block_impl->text_rendering_params;
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_PushAxisAlignedClip(ID2D1RenderTarget *iface,
        const D2D1_RECT_F *clip_rect, D2D1_ANTIALIAS_MODE antialias_mode)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
    D2D1_RECT_F transformed_rect;
    float x_scale, y_scale;
    D2D1_POINT_2F point;

    TRACE("iface %p, clip_rect %p, antialias_mode %#x.\n", iface, clip_rect, antialias_mode);

    if (antialias_mode != D2D1_ANTIALIAS_MODE_ALIASED)
        FIXME("Ignoring antialias_mode %#x.\n", antialias_mode);

    x_scale = render_target->dpi_x / 96.0f;
    y_scale = render_target->dpi_y / 96.0f;
    d2d_point_transform(&point, &render_target->drawing_state.transform,
            clip_rect->left * x_scale, clip_rect->top * y_scale);
    d2d_rect_set(&transformed_rect, point.x, point.y, point.x, point.y);
    d2d_point_transform(&point, &render_target->drawing_state.transform,
            clip_rect->left * x_scale, clip_rect->bottom * y_scale);
    d2d_rect_expand(&transformed_rect, &point);
    d2d_point_transform(&point, &render_target->drawing_state.transform,
            clip_rect->right * x_scale, clip_rect->top * y_scale);
    d2d_rect_expand(&transformed_rect, &point);
    d2d_point_transform(&point, &render_target->drawing_state.transform,
            clip_rect->right * x_scale, clip_rect->bottom * y_scale);
    d2d_rect_expand(&transformed_rect, &point);

    if (!d2d_clip_stack_push(&render_target->clip_stack, &transformed_rect))
        WARN("Failed to push clip rect.\n");
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_PopAxisAlignedClip(ID2D1RenderTarget *iface)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p.\n", iface);

    d2d_clip_stack_pop(&render_target->clip_stack);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_Clear(ID2D1RenderTarget *iface, const D2D1_COLOR_F *color)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
    D3D10_SUBRESOURCE_DATA buffer_data;
    D3D10_BUFFER_DESC buffer_desc;
    ID3D10Buffer *vs_cb, *ps_cb;
    HRESULT hr;

    static const float transform[] =
    {
        1.0f,  0.0f, 0.0f, 0.0f,
        0.0f, -1.0f, 0.0f, 0.0f,
    };

    TRACE("iface %p, color %p.\n", iface, color);

    buffer_desc.ByteWidth = sizeof(transform);
    buffer_desc.Usage = D3D10_USAGE_DEFAULT;
    buffer_desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
    buffer_desc.CPUAccessFlags = 0;
    buffer_desc.MiscFlags = 0;

    buffer_data.pSysMem = transform;
    buffer_data.SysMemPitch = 0;
    buffer_data.SysMemSlicePitch = 0;

    if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &vs_cb)))
    {
        WARN("Failed to create constant buffer, hr %#x.\n", hr);
        return;
    }

    buffer_desc.ByteWidth = sizeof(*color);
    buffer_data.pSysMem = color;

    if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &ps_cb)))
    {
        WARN("Failed to create constant buffer, hr %#x.\n", hr);
        ID3D10Buffer_Release(vs_cb);
        return;
    }

    d2d_draw(render_target, vs_cb, render_target->rect_solid_ps, ps_cb, NULL);

    ID3D10Buffer_Release(ps_cb);
    ID3D10Buffer_Release(vs_cb);
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_BeginDraw(ID2D1RenderTarget *iface)
{
    TRACE("iface %p.\n", iface);
}

static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_EndDraw(ID2D1RenderTarget *iface,
        D2D1_TAG *tag1, D2D1_TAG *tag2)
{
    TRACE("iface %p, tag1 %p, tag2 %p.\n", iface, tag1, tag2);

    if (tag1)
        *tag1 = 0;
    if (tag2)
        *tag2 = 0;

    return S_OK;
}

static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_d3d_render_target_GetPixelFormat(ID2D1RenderTarget *iface,
        D2D1_PIXEL_FORMAT *format)
{
    FIXME("iface %p, format %p stub!\n", iface, format);

    format->format = DXGI_FORMAT_UNKNOWN;
    format->alphaMode = D2D1_ALPHA_MODE_UNKNOWN;
    return format;
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_SetDpi(ID2D1RenderTarget *iface, float dpi_x, float dpi_y)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p, dpi_x %.8e, dpi_y %.8e.\n", iface, dpi_x, dpi_y);

    if (dpi_x == 0.0f && dpi_y == 0.0f)
    {
        dpi_x = 96.0f;
        dpi_y = 96.0f;
    }

    render_target->dpi_x = dpi_x;
    render_target->dpi_y = dpi_y;
}

static void STDMETHODCALLTYPE d2d_d3d_render_target_GetDpi(ID2D1RenderTarget *iface, float *dpi_x, float *dpi_y)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface, dpi_x, dpi_y);

    *dpi_x = render_target->dpi_x;
    *dpi_y = render_target->dpi_y;
}

static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_d3d_render_target_GetSize(ID2D1RenderTarget *iface, D2D1_SIZE_F *size)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p, size %p.\n", iface, size);

    size->width = render_target->pixel_size.width / (render_target->dpi_x / 96.0f);
    size->height = render_target->pixel_size.height / (render_target->dpi_y / 96.0f);
    return size;
}

static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_d3d_render_target_GetPixelSize(ID2D1RenderTarget *iface,
        D2D1_SIZE_U *pixel_size)
{
    struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);

    TRACE("iface %p, pixel_size %p.\n", iface, pixel_size);

    *pixel_size = render_target->pixel_size;
    return pixel_size;
}

static UINT32 STDMETHODCALLTYPE d2d_d3d_render_target_GetMaximumBitmapSize(ID2D1RenderTarget *iface)
{
    FIXME("iface %p stub!\n", iface);

    return 0;
}

static BOOL STDMETHODCALLTYPE d2d_d3d_render_target_IsSupported(ID2D1RenderTarget *iface,
        const D2D1_RENDER_TARGET_PROPERTIES *desc)
{
    FIXME("iface %p, desc %p stub!\n", iface, desc);

    return FALSE;
}

static const struct ID2D1RenderTargetVtbl d2d_d3d_render_target_vtbl =
{
    d2d_d3d_render_target_QueryInterface,
    d2d_d3d_render_target_AddRef,
    d2d_d3d_render_target_Release,
    d2d_d3d_render_target_GetFactory,
    d2d_d3d_render_target_CreateBitmap,
    d2d_d3d_render_target_CreateBitmapFromWicBitmap,
    d2d_d3d_render_target_CreateSharedBitmap,
    d2d_d3d_render_target_CreateBitmapBrush,
    d2d_d3d_render_target_CreateSolidColorBrush,
    d2d_d3d_render_target_CreateGradientStopCollection,
    d2d_d3d_render_target_CreateLinearGradientBrush,
    d2d_d3d_render_target_CreateRadialGradientBrush,
    d2d_d3d_render_target_CreateCompatibleRenderTarget,
    d2d_d3d_render_target_CreateLayer,
    d2d_d3d_render_target_CreateMesh,
    d2d_d3d_render_target_DrawLine,
    d2d_d3d_render_target_DrawRectangle,
    d2d_d3d_render_target_FillRectangle,
    d2d_d3d_render_target_DrawRoundedRectangle,
    d2d_d3d_render_target_FillRoundedRectangle,
    d2d_d3d_render_target_DrawEllipse,
    d2d_d3d_render_target_FillEllipse,
    d2d_d3d_render_target_DrawGeometry,
    d2d_d3d_render_target_FillGeometry,
    d2d_d3d_render_target_FillMesh,
    d2d_d3d_render_target_FillOpacityMask,
    d2d_d3d_render_target_DrawBitmap,
    d2d_d3d_render_target_DrawText,
    d2d_d3d_render_target_DrawTextLayout,
    d2d_d3d_render_target_DrawGlyphRun,
    d2d_d3d_render_target_SetTransform,
    d2d_d3d_render_target_GetTransform,
    d2d_d3d_render_target_SetAntialiasMode,
    d2d_d3d_render_target_GetAntialiasMode,
    d2d_d3d_render_target_SetTextAntialiasMode,
    d2d_d3d_render_target_GetTextAntialiasMode,
    d2d_d3d_render_target_SetTextRenderingParams,
    d2d_d3d_render_target_GetTextRenderingParams,
    d2d_d3d_render_target_SetTags,
    d2d_d3d_render_target_GetTags,
    d2d_d3d_render_target_PushLayer,
    d2d_d3d_render_target_PopLayer,
    d2d_d3d_render_target_Flush,
    d2d_d3d_render_target_SaveDrawingState,
    d2d_d3d_render_target_RestoreDrawingState,
    d2d_d3d_render_target_PushAxisAlignedClip,
    d2d_d3d_render_target_PopAxisAlignedClip,
    d2d_d3d_render_target_Clear,
    d2d_d3d_render_target_BeginDraw,
    d2d_d3d_render_target_EndDraw,
    d2d_d3d_render_target_GetPixelFormat,
    d2d_d3d_render_target_SetDpi,
    d2d_d3d_render_target_GetDpi,
    d2d_d3d_render_target_GetSize,
    d2d_d3d_render_target_GetPixelSize,
    d2d_d3d_render_target_GetMaximumBitmapSize,
    d2d_d3d_render_target_IsSupported,
};

static inline struct d2d_d3d_render_target *impl_from_IDWriteTextRenderer(IDWriteTextRenderer *iface)
{
    return CONTAINING_RECORD(iface, struct d2d_d3d_render_target, IDWriteTextRenderer_iface);
}

static HRESULT STDMETHODCALLTYPE d2d_text_renderer_QueryInterface(IDWriteTextRenderer *iface, REFIID iid, void **out)
{
    TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);

    if (IsEqualGUID(iid, &IID_IDWriteTextRenderer)
            || IsEqualGUID(iid, &IID_IDWritePixelSnapping)
            || IsEqualGUID(iid, &IID_IUnknown))
    {
        IDWriteTextRenderer_AddRef(iface);
        *out = iface;
        return S_OK;
    }

    WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));

    *out = NULL;
    return E_NOINTERFACE;
}

static ULONG STDMETHODCALLTYPE d2d_text_renderer_AddRef(IDWriteTextRenderer *iface)
{
    struct d2d_d3d_render_target *render_target = impl_from_IDWriteTextRenderer(iface);

    TRACE("iface %p.\n", iface);

    return d2d_d3d_render_target_AddRef(&render_target->ID2D1RenderTarget_iface);
}

static ULONG STDMETHODCALLTYPE d2d_text_renderer_Release(IDWriteTextRenderer *iface)
{
    struct d2d_d3d_render_target *render_target = impl_from_IDWriteTextRenderer(iface);

    TRACE("iface %p.\n", iface);

    return d2d_d3d_render_target_Release(&render_target->ID2D1RenderTarget_iface);
}

static HRESULT STDMETHODCALLTYPE d2d_text_renderer_IsPixelSnappingDisabled(IDWriteTextRenderer *iface,
        void *ctx, BOOL *disabled)
{
    FIXME("iface %p, ctx %p, disabled %p stub!\n", iface, ctx, disabled);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE d2d_text_renderer_GetCurrentTransform(IDWriteTextRenderer *iface,
        void *ctx, DWRITE_MATRIX *transform)
{
    FIXME("iface %p, ctx %p, transform %p stub!\n", iface, ctx, transform);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE d2d_text_renderer_GetPixelsPerDip(IDWriteTextRenderer *iface, void *ctx, float *ppd)
{
    FIXME("iface %p, ctx %p, ppd %p stub!\n", iface, ctx, ppd);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawGlyphRun(IDWriteTextRenderer *iface, void *ctx,
        float baseline_origin_x, float baseline_origin_y, DWRITE_MEASURING_MODE measuring_mode,
        const DWRITE_GLYPH_RUN *glyph_run, const DWRITE_GLYPH_RUN_DESCRIPTION *desc, IUnknown *effect)
{
    FIXME("iface %p, ctx %p, baseline_origin_x %.8e, baseline_origin_y %.8e, "
            "measuring_mode %#x, glyph_run %p, desc %p, effect %p stub!\n",
            iface, ctx, baseline_origin_x, baseline_origin_y,
            measuring_mode, glyph_run, desc, effect);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawUnderline(IDWriteTextRenderer *iface, void *ctx,
        float baseline_origin_x, float baseline_origin_y, const DWRITE_UNDERLINE *underline, IUnknown *effect)
{
    FIXME("iface %p, ctx %p, baseline_origin_x %.8e, baseline_origin_y %.8e, underline %p, effect %p stub!\n",
            iface, ctx, baseline_origin_x, baseline_origin_y, underline, effect);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawStrikethrough(IDWriteTextRenderer *iface, void *ctx,
        float baseline_origin_x, float baseline_origin_y, const DWRITE_STRIKETHROUGH *strikethrough, IUnknown *effect)
{
    FIXME("iface %p, ctx %p, baseline_origin_x %.8e, baseline_origin_y %.8e, strikethrough %p, effect %p stub!\n",
            iface, ctx, baseline_origin_x, baseline_origin_y, strikethrough, effect);

    return E_NOTIMPL;
}

static HRESULT STDMETHODCALLTYPE d2d_text_renderer_DrawInlineObject(IDWriteTextRenderer *iface, void *ctx,
        float origin_x, float origin_y, IDWriteInlineObject *object, BOOL is_sideways, BOOL is_rtl, IUnknown *effect)
{
    FIXME("iface %p, ctx %p, origin_x %.8e, origin_y %.8e, object %p, is_sideways %#x, is_rtl %#x, effect %p stub!\n",
            iface, ctx, origin_x, origin_y, object, is_sideways, is_rtl, effect);

    return E_NOTIMPL;
}

static const struct IDWriteTextRendererVtbl d2d_text_renderer_vtbl =
{
    d2d_text_renderer_QueryInterface,
    d2d_text_renderer_AddRef,
    d2d_text_renderer_Release,
    d2d_text_renderer_IsPixelSnappingDisabled,
    d2d_text_renderer_GetCurrentTransform,
    d2d_text_renderer_GetPixelsPerDip,
    d2d_text_renderer_DrawGlyphRun,
    d2d_text_renderer_DrawUnderline,
    d2d_text_renderer_DrawStrikethrough,
    d2d_text_renderer_DrawInlineObject,
};

HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory,
        IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc)
{
    D3D10_SUBRESOURCE_DATA buffer_data;
    D3D10_STATE_BLOCK_MASK state_mask;
    DXGI_SURFACE_DESC surface_desc;
    D3D10_RASTERIZER_DESC rs_desc;
    D3D10_BUFFER_DESC buffer_desc;
    D3D10_BLEND_DESC blend_desc;
    ID3D10Resource *resource;
    HRESULT hr;

    static const D3D10_INPUT_ELEMENT_DESC il_desc[] =
    {
        {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0},
    };
    static const DWORD vs_code[] =
    {
        /* float3x2 transform;
         *
         * float4 main(float4 position : POSITION) : SV_POSITION
         * {
         *     return float4(mul(position.xyw, transform), position.zw);
         * } */
        0x43425844, 0x0add3194, 0x205f74ec, 0xab527fe7, 0xbe6ad704, 0x00000001, 0x00000128, 0x00000003,
        0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
        0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x49534f50, 0x4e4f4954, 0xababab00,
        0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003,
        0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x52444853, 0x0000008c, 0x00010040,
        0x00000023, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0300005f, 0x001010f2, 0x00000000,
        0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x08000010, 0x00102012, 0x00000000, 0x00101346,
        0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x08000010, 0x00102022, 0x00000000, 0x00101346,
        0x00000000, 0x00208246, 0x00000000, 0x00000001, 0x05000036, 0x001020c2, 0x00000000, 0x00101ea6,
        0x00000000, 0x0100003e,
    };
    static const DWORD rect_solid_ps_code[] =
    {
        /* float4 color;
         *
         * float4 main(float4 position : SV_POSITION) : SV_Target
         * {
         *     return color;
         * } */
        0x43425844, 0x88eefcfd, 0x93d6fd47, 0x173c242f, 0x0106d07a, 0x00000001, 0x000000dc, 0x00000003,
        0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
        0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49,
        0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
        0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000040, 0x00000040,
        0x00000010, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000,
        0x06000036, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x0100003e,
    };
    static const DWORD rect_bitmap_ps_code[] =
    {
#if 0
        float3x2 transform;
        float opacity;

        SamplerState s;
        Texture2D t;

        float4 main(float4 position : SV_POSITION) : SV_Target
        {
            float2 texcoord;
            float4 ret;

            texcoord.x = position.x * transform._11 + position.y * transform._21 + transform._31;
            texcoord.y = position.x * transform._12 + position.y * transform._22 + transform._32;
            ret = t.Sample(s, texcoord);
            ret.a *= opacity;

            return ret;
        }
#endif
        0x43425844, 0x9a5f9280, 0xa5351c23, 0x15d6e760, 0xce35bcc3, 0x00000001, 0x000001d0, 0x00000003,
        0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
        0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
        0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
        0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000134, 0x00000040,
        0x0000004d, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0300005a, 0x00106000, 0x00000000,
        0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001,
        0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x0800000f, 0x00100012, 0x00000000,
        0x00101046, 0x00000000, 0x00208046, 0x00000000, 0x00000000, 0x08000000, 0x00100012, 0x00000000,
        0x0010000a, 0x00000000, 0x0020802a, 0x00000000, 0x00000000, 0x0800000f, 0x00100042, 0x00000000,
        0x00101046, 0x00000000, 0x00208046, 0x00000000, 0x00000001, 0x08000000, 0x00100022, 0x00000000,
        0x0010002a, 0x00000000, 0x0020802a, 0x00000000, 0x00000001, 0x09000045, 0x001000f2, 0x00000000,
        0x00100046, 0x00000000, 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x08000038, 0x00102082,
        0x00000000, 0x0010003a, 0x00000000, 0x0020803a, 0x00000000, 0x00000001, 0x05000036, 0x00102072,
        0x00000000, 0x00100246, 0x00000000, 0x0100003e,
    };
    static const struct
    {
        float x, y;
    }
    quad[] =
    {
        {-1.0f,  1.0f},
        {-1.0f, -1.0f},
        { 1.0f,  1.0f},
        { 1.0f, -1.0f},
    };
    static const D2D1_MATRIX_3X2_F identity =
    {
        1.0f, 0.0f,
        0.0f, 1.0f,
        0.0f, 0.0f,
    };

    FIXME("Ignoring render target properties.\n");

    render_target->ID2D1RenderTarget_iface.lpVtbl = &d2d_d3d_render_target_vtbl;
    render_target->IDWriteTextRenderer_iface.lpVtbl = &d2d_text_renderer_vtbl;
    render_target->refcount = 1;
    render_target->factory = factory;
    ID2D1Factory_AddRef(render_target->factory);

    if (FAILED(hr = IDXGISurface_GetDevice(surface, &IID_ID3D10Device, (void **)&render_target->device)))
    {
        WARN("Failed to get device interface, hr %#x.\n", hr);
        ID2D1Factory_Release(render_target->factory);
        return hr;
    }

    if (FAILED(hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource)))
    {
        WARN("Failed to get ID3D10Resource interface, hr %#x.\n", hr);
        goto err;
    }

    hr = ID3D10Device_CreateRenderTargetView(render_target->device, resource, NULL, &render_target->view);
    ID3D10Resource_Release(resource);
    if (FAILED(hr))
    {
        WARN("Failed to create rendertarget view, hr %#x.\n", hr);
        goto err;
    }

    if (FAILED(hr = D3D10StateBlockMaskEnableAll(&state_mask)))
    {
        WARN("Failed to create stateblock mask, hr %#x.\n", hr);
        goto err;
    }

    if (FAILED(hr = D3D10CreateStateBlock(render_target->device, &state_mask, &render_target->stateblock)))
    {
        WARN("Failed to create stateblock, hr %#x.\n", hr);
        goto err;
    }

    if (FAILED(hr = ID3D10Device_CreateInputLayout(render_target->device, il_desc,
            sizeof(il_desc) / sizeof(*il_desc), vs_code, sizeof(vs_code),
            &render_target->il)))
    {
        WARN("Failed to create clear input layout, hr %#x.\n", hr);
        goto err;
    }

    buffer_desc.ByteWidth = sizeof(quad);
    buffer_desc.Usage = D3D10_USAGE_DEFAULT;
    buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    buffer_desc.CPUAccessFlags = 0;
    buffer_desc.MiscFlags = 0;

    buffer_data.pSysMem = quad;
    buffer_data.SysMemPitch = 0;
    buffer_data.SysMemSlicePitch = 0;

    render_target->vb_stride = sizeof(*quad);
    if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device,
            &buffer_desc, &buffer_data, &render_target->vb)))
    {
        WARN("Failed to create clear vertex buffer, hr %#x.\n", hr);
        goto err;
    }

    if (FAILED(hr = ID3D10Device_CreateVertexShader(render_target->device,
            vs_code, sizeof(vs_code), &render_target->vs)))
    {
        WARN("Failed to create clear vertex shader, hr %#x.\n", hr);
        goto err;
    }

    rs_desc.FillMode = D3D10_FILL_SOLID;
    rs_desc.CullMode = D3D10_CULL_BACK;
    rs_desc.FrontCounterClockwise = FALSE;
    rs_desc.DepthBias = 0;
    rs_desc.DepthBiasClamp = 0.0f;
    rs_desc.SlopeScaledDepthBias = 0.0f;
    rs_desc.DepthClipEnable = TRUE;
    rs_desc.ScissorEnable = TRUE;
    rs_desc.MultisampleEnable = FALSE;
    rs_desc.AntialiasedLineEnable = FALSE;
    if (FAILED(hr = ID3D10Device_CreateRasterizerState(render_target->device, &rs_desc, &render_target->rs)))
    {
        WARN("Failed to create clear rasterizer state, hr %#x.\n", hr);
        goto err;
    }

    memset(&blend_desc, 0, sizeof(blend_desc));
    blend_desc.BlendEnable[0] = TRUE;
    blend_desc.SrcBlend = D3D10_BLEND_SRC_ALPHA;
    blend_desc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA;
    blend_desc.BlendOp = D3D10_BLEND_OP_ADD;
    blend_desc.SrcBlendAlpha = D3D10_BLEND_ZERO;
    blend_desc.DestBlendAlpha = D3D10_BLEND_ONE;
    blend_desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
    blend_desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
    if (FAILED(hr = ID3D10Device_CreateBlendState(render_target->device, &blend_desc, &render_target->bs)))
    {
        WARN("Failed to create blend state, hr %#x.\n", hr);
        goto err;
    }

    if (FAILED(hr = ID3D10Device_CreatePixelShader(render_target->device,
            rect_solid_ps_code, sizeof(rect_solid_ps_code), &render_target->rect_solid_ps)))
    {
        WARN("Failed to create pixel shader, hr %#x.\n", hr);
        goto err;
    }

    if (FAILED(hr = ID3D10Device_CreatePixelShader(render_target->device,
            rect_bitmap_ps_code, sizeof(rect_bitmap_ps_code), &render_target->rect_bitmap_ps)))
    {
        WARN("Failed to create pixel shader, hr %#x.\n", hr);
        goto err;
    }

    if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc)))
    {
        WARN("Failed to get surface desc, hr %#x.\n", hr);
        goto err;
    }

    render_target->pixel_size.width = surface_desc.Width;
    render_target->pixel_size.height = surface_desc.Height;
    render_target->drawing_state.transform = identity;

    if (!d2d_clip_stack_init(&render_target->clip_stack))
    {
        WARN("Failed to initialize clip stack.\n");
        hr = E_FAIL;
        goto err;
    }

    render_target->dpi_x = desc->dpiX;
    render_target->dpi_y = desc->dpiY;

    if (render_target->dpi_x == 0.0f && render_target->dpi_y == 0.0f)
    {
        render_target->dpi_x = 96.0f;
        render_target->dpi_y = 96.0f;
    }

    return S_OK;

err:
    if (render_target->rect_bitmap_ps)
        ID3D10PixelShader_Release(render_target->rect_bitmap_ps);
    if (render_target->rect_solid_ps)
        ID3D10PixelShader_Release(render_target->rect_solid_ps);
    if (render_target->bs)
        ID3D10BlendState_Release(render_target->bs);
    if (render_target->rs)
        ID3D10RasterizerState_Release(render_target->rs);
    if (render_target->vs)
        ID3D10VertexShader_Release(render_target->vs);
    if (render_target->vb)
        ID3D10Buffer_Release(render_target->vb);
    if (render_target->il)
        ID3D10InputLayout_Release(render_target->il);
    if (render_target->stateblock)
        render_target->stateblock->lpVtbl->Release(render_target->stateblock);
    if (render_target->view)
        ID3D10RenderTargetView_Release(render_target->view);
    if (render_target->device)
        ID3D10Device_Release(render_target->device);
    ID2D1Factory_Release(render_target->factory);
    return hr;
}
