/*
 * Copyright 2017 Lucian Poston
 *
 * 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
 */

import "d2d1.idl";

interface ID2D1DeviceContext;
interface ID2D1StrokeStyle1;
interface ID2D1PathGeometry1;
interface ID2D1GdiMetafile;
interface ID2D1Properties;
interface IPrintDocumentPackageTarget;
interface ID2D1PrintControl;
interface IWICImagingFactory;
interface IWICColorContext;
interface ID2D1ColorContext;
interface ID2D1Effect;
interface ID2D1GradientStopCollection1;
interface ID2D1ImageBrush;
interface ID2D1BitmapBrush1;

cpp_quote("#ifndef __dwrite_h__")
/* already defined in dwrite.h but needed for WIDL */
typedef struct DWRITE_GLYPH_RUN_DESCRIPTION DWRITE_GLYPH_RUN_DESCRIPTION;
cpp_quote("#endif /* __dwrite_h__ */")

typedef enum D2D1_DEVICE_CONTEXT_OPTIONS
{
    D2D1_DEVICE_CONTEXT_OPTIONS_NONE = 0x0,
    D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS = 0x1,
    D2D1_DEVICE_CONTEXT_OPTIONS_FORCE_DWORD = 0xffffffff,
} D2D1_DEVICE_CONTEXT_OPTIONS;

typedef enum D2D1_STROKE_TRANSFORM_TYPE
{
    D2D1_STROKE_TRANSFORM_TYPE_NORMAL = 0x0,
    D2D1_STROKE_TRANSFORM_TYPE_FIXED = 0x1,
    D2D1_STROKE_TRANSFORM_TYPE_HAIRLINE = 0x2,
    D2D1_STROKE_TRANSFORM_TYPE_FORCE_DWORD = 0xffffffff,
} D2D1_STROKE_TRANSFORM_TYPE;

typedef enum D2D1_PRIMITIVE_BLEND
{
    D2D1_PRIMITIVE_BLEND_SOURCE_OVER = 0x0,
    D2D1_PRIMITIVE_BLEND_COPY = 0x1,
    D2D1_PRIMITIVE_BLEND_MIN = 0x2,
    D2D1_PRIMITIVE_BLEND_ADD = 0x3,
    D2D1_PRIMITIVE_BLEND_MAX = 0x4,
    D2D1_PRIMITIVE_BLEND_FORCE_DWORD = 0xffffffff,
} D2D1_PRIMITIVE_BLEND;

typedef enum D2D1_UNIT_MODE
{
    D2D1_UNIT_MODE_DIPS = 0x0,
    D2D1_UNIT_MODE_PIXELS = 0x1,
    D2D1_UNIT_MODE_FORCE_DWORD = 0xffffffff,
} D2D1_UNIT_MODE;

typedef enum D2D1_PRINT_FONT_SUBSET_MODE
{
    D2D1_PRINT_FONT_SUBSET_MODE_DEFAULT = 0x0,
    D2D1_PRINT_FONT_SUBSET_MODE_EACHPAGE = 0x1,
    D2D1_PRINT_FONT_SUBSET_MODE_NONE = 0x2,
    D2D1_PRINT_FONT_SUBSET_MODE_FORCE_DWORD = 0xffffffff,
} D2D1_PRINT_FONT_SUBSET_MODE;

typedef enum D2D1_COLOR_SPACE
{
    D2D1_COLOR_SPACE_CUSTOM = 0x0,
    D2D1_COLOR_SPACE_SRGB = 0x1,
    D2D1_COLOR_SPACE_SCRGB = 0x2,
    D2D1_COLOR_SPACE_FORCE_DWORD = 0xffffffff,
} D2D1_COLOR_SPACE;

typedef enum D2D1_BITMAP_OPTIONS
{
    D2D1_BITMAP_OPTIONS_NONE = 0x0,
    D2D1_BITMAP_OPTIONS_TARGET = 0x1,
    D2D1_BITMAP_OPTIONS_CANNOT_DRAW = 0x2,
    D2D1_BITMAP_OPTIONS_CPU_READ = 0x4,
    D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE = 0x8,
    D2D1_BITMAP_OPTIONS_FORCE_DWORD = 0xffffffff,
} D2D1_BITMAP_OPTIONS;

typedef enum D2D1_MAP_OPTIONS
{
    D2D1_MAP_OPTIONS_NONE = 0x0,
    D2D1_MAP_OPTIONS_READ = 0x1,
    D2D1_MAP_OPTIONS_WRITE = 0x2,
    D2D1_MAP_OPTIONS_DISCARD = 0x4,
    D2D1_MAP_OPTIONS_FORCE_DWORD = 0xffffffff,
} D2D1_MAP_OPTIONS;

typedef enum D2D1_BUFFER_PRECISION
{
    D2D1_BUFFER_PRECISION_UNKNOWN = 0x0,
    D2D1_BUFFER_PRECISION_8BPC_UNORM = 0x1,
    D2D1_BUFFER_PRECISION_8BPC_UNORM_SRGB = 0x2,
    D2D1_BUFFER_PRECISION_16BPC_UNORM = 0x3,
    D2D1_BUFFER_PRECISION_16BPC_FLOAT = 0x4,
    D2D1_BUFFER_PRECISION_32BPC_FLOAT = 0x5,
    D2D1_BUFFER_PRECISION_FORCE_DWORD = 0xffffffff,
} D2D1_BUFFER_PRECISION;

typedef enum D2D1_COLOR_INTERPOLATION_MODE
{
    D2D1_COLOR_INTERPOLATION_MODE_STRAIGHT = 0x0,
    D2D1_COLOR_INTERPOLATION_MODE_PREMULTIPLIED = 0x1,
    D2D1_COLOR_INTERPOLATION_MODE_FORCE_DWORD = 0xffffffff,
} D2D1_COLOR_INTERPOLATION_MODE;

typedef enum D2D1_INTERPOLATION_MODE
{
    D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR = D2D1_INTERPOLATION_MODE_DEFINITION_NEAREST_NEIGHBOR,
    D2D1_INTERPOLATION_MODE_LINEAR = D2D1_INTERPOLATION_MODE_DEFINITION_LINEAR,
    D2D1_INTERPOLATION_MODE_CUBIC = D2D1_INTERPOLATION_MODE_DEFINITION_CUBIC,
    D2D1_INTERPOLATION_MODE_MULTI_SAMPLE_LINEAR = D2D1_INTERPOLATION_MODE_DEFINITION_MULTI_SAMPLE_LINEAR,
    D2D1_INTERPOLATION_MODE_ANISOTROPIC = D2D1_INTERPOLATION_MODE_DEFINITION_ANISOTROPIC,
    D2D1_INTERPOLATION_MODE_HIGH_QUALITY_CUBIC = D2D1_INTERPOLATION_MODE_DEFINITION_HIGH_QUALITY_CUBIC,
    D2D1_INTERPOLATION_MODE_FORCE_DWORD = 0xffffffff,
} D2D1_INTERPOLATION_MODE;

typedef enum D2D1_COMPOSITE_MODE
{
    D2D1_COMPOSITE_MODE_SOURCE_OVER = 0x0,
    D2D1_COMPOSITE_MODE_DESTINATION_OVER = 0x1,
    D2D1_COMPOSITE_MODE_SOURCE_IN = 0x2,
    D2D1_COMPOSITE_MODE_DESTINATION_IN = 0x3,
    D2D1_COMPOSITE_MODE_SOURCE_OUT = 0x4,
    D2D1_COMPOSITE_MODE_DESTINATION_OUT = 0x5,
    D2D1_COMPOSITE_MODE_SOURCE_ATOP = 0x6,
    D2D1_COMPOSITE_MODE_DESTINATION_ATOP = 0x7,
    D2D1_COMPOSITE_MODE_XOR = 0x8,
    D2D1_COMPOSITE_MODE_PLUS = 0x9,
    D2D1_COMPOSITE_MODE_SOURCE_COPY = 0xa,
    D2D1_COMPOSITE_MODE_BOUNDED_SOURCE_COPY = 0xb,
    D2D1_COMPOSITE_MODE_MASK_INVERT = 0xc,
    D2D1_COMPOSITE_MODE_FORCE_DWORD = 0xffffffff,
} D2D1_COMPOSITE_MODE;

typedef enum D2D1_LAYER_OPTIONS1
{
    D2D1_LAYER_OPTIONS1_NONE = 0x0,
    D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND = 0x1,
    D2D1_LAYER_OPTIONS1_IGNORE_ALPHA = 0x2,
    D2D1_LAYER_OPTIONS1_FORCE_DWORD = 0xffffffff,
} D2D1_LAYER_OPTIONS1;

typedef struct D2D1_PROPERTY_BINDING D2D1_PROPERTY_BINDING;
typedef D2D_MATRIX_4X4_F D2D1_MATRIX_4X4_F;

typedef enum D2D1_PROPERTY_TYPE
{
    D2D1_PROPERTY_TYPE_UNKNOWN = 0x0,
    D2D1_PROPERTY_TYPE_STRING = 0x1,
    D2D1_PROPERTY_TYPE_BOOL = 0x2,
    D2D1_PROPERTY_TYPE_UINT32 = 0x3,
    D2D1_PROPERTY_TYPE_INT32 = 0x4,
    D2D1_PROPERTY_TYPE_FLOAT = 0x5,
    D2D1_PROPERTY_TYPE_VECTOR2 = 0x6,
    D2D1_PROPERTY_TYPE_VECTOR3 = 0x7,
    D2D1_PROPERTY_TYPE_VECTOR4 = 0x8,
    D2D1_PROPERTY_TYPE_BLOB = 0x9,
    D2D1_PROPERTY_TYPE_IUNKNOWN = 0xa,
    D2D1_PROPERTY_TYPE_ENUM = 0xb,
    D2D1_PROPERTY_TYPE_ARRAY = 0xc,
    D2D1_PROPERTY_TYPE_CLSID = 0xd,
    D2D1_PROPERTY_TYPE_MATRIX_3X2 = 0xe,
    D2D1_PROPERTY_TYPE_MATRIX_4X3 = 0xf,
    D2D1_PROPERTY_TYPE_MATRIX_4X4 = 0x10,
    D2D1_PROPERTY_TYPE_MATRIX_5X4 = 0x11,
    D2D1_PROPERTY_TYPE_COLOR_CONTEXT = 0x12,
    D2D1_PROPERTY_TYPE_FORCE_DWORD = 0xffffffff,
} D2D1_PROPERTY_TYPE;

typedef struct D2D1_STROKE_STYLE_PROPERTIES1
{
    D2D1_CAP_STYLE startCap;
    D2D1_CAP_STYLE endCap;
    D2D1_CAP_STYLE dashCap;
    D2D1_LINE_JOIN lineJoin;
    float miterLimit;
    D2D1_DASH_STYLE dashStyle;
    float dashOffset;
    D2D1_STROKE_TRANSFORM_TYPE transformType;
} D2D1_STROKE_STYLE_PROPERTIES1;

typedef struct D2D1_DRAWING_STATE_DESCRIPTION1
{
    D2D1_ANTIALIAS_MODE antialiasMode;
    D2D1_TEXT_ANTIALIAS_MODE textAntialiasMode;
    D2D1_TAG tag1;
    D2D1_TAG tag2;
    D2D1_MATRIX_3X2_F transform;
    D2D1_PRIMITIVE_BLEND primitiveBlend;
    D2D1_UNIT_MODE unitMode;
} D2D1_DRAWING_STATE_DESCRIPTION1;

typedef struct D2D1_PRINT_CONTROL_PROPERTIES
{
    D2D1_PRINT_FONT_SUBSET_MODE fontSubset;
    float rasterDPI;
    D2D1_COLOR_SPACE colorSpace;
} D2D1_PRINT_CONTROL_PROPERTIES;

typedef struct D2D1_MAPPED_RECT
{
    UINT32 pitch;
    BYTE *bits;
} D2D1_MAPPED_RECT;

typedef struct D2D1_BITMAP_PROPERTIES1
{
    D2D1_PIXEL_FORMAT pixelFormat;
    float dpiX;
    float dpiY;
    D2D1_BITMAP_OPTIONS bitmapOptions;
    ID2D1ColorContext *colorContext;
} D2D1_BITMAP_PROPERTIES1;

typedef struct D2D1_IMAGE_BRUSH_PROPERTIES
{
    D2D1_RECT_F sourceRectangle;
    D2D1_EXTEND_MODE extendModeX;
    D2D1_EXTEND_MODE extendModeY;
    D2D1_INTERPOLATION_MODE interpolationMode;
} D2D1_IMAGE_BRUSH_PROPERTIES;

typedef struct D2D1_BITMAP_BRUSH_PROPERTIES1
{
    D2D1_EXTEND_MODE extendModeX;
    D2D1_EXTEND_MODE extendModeY;
    D2D1_INTERPOLATION_MODE interpolationMode;
} D2D1_BITMAP_BRUSH_PROPERTIES1;

typedef struct D2D1_RENDERING_CONTROLS
{
    D2D1_BUFFER_PRECISION bufferPrecision;
    D2D1_SIZE_U tileSize;
} D2D1_RENDERING_CONTROLS;

typedef struct D2D1_LAYER_PARAMETERS1
{
    D2D1_RECT_F contentBounds;
    ID2D1Geometry *geometricMask;
    D2D1_ANTIALIAS_MODE maskAntialiasMode;
    D2D1_MATRIX_3X2_F maskTransform;
    float opacity;
    ID2D1Brush *opacityBrush;
    D2D1_LAYER_OPTIONS1 layerOptions;
} D2D1_LAYER_PARAMETERS1;

typedef struct D2D1_EFFECT_INPUT_DESCRIPTION
{
    ID2D1Effect *effect;
    UINT32 inputIndex;
    D2D1_RECT_F inputRectangle;
} D2D1_EFFECT_INPUT_DESCRIPTION;

typedef HRESULT (__stdcall *PD2D1_EFFECT_FACTORY)(IUnknown **effect);

[
    object,
    uuid(483473d7-cd46-4f9d-9d3a-3112aa80159d),
    local,
]
interface ID2D1Properties : IUnknown
{
    UINT32 GetPropertyCount();
    HRESULT GetPropertyName(
        [in] UINT32 index,
        [out] WCHAR *name,
        [in] UINT32 name_count
    );
    UINT32 GetPropertyNameLength(
        [in] UINT32 index
    );
    D2D1_PROPERTY_TYPE GetType(
        [in] UINT32 index
    );
    UINT32 GetPropertyIndex(
        [in] const WCHAR *name
    );
    HRESULT SetValueByName(
        [in] const WCHAR *name,
        [in] D2D1_PROPERTY_TYPE type,
        [in] const BYTE *value,
        [in] UINT32 value_size
    );
    HRESULT SetValue(
        [in] UINT32 index,
        [in] D2D1_PROPERTY_TYPE type,
        [in] const BYTE *value,
        [in] UINT32 value_size
    );
    HRESULT GetValueByName(
        [in] const WCHAR *name,
        [in] D2D1_PROPERTY_TYPE type,
        [out] BYTE *value,
        [in] UINT32 value_size
    );
    HRESULT GetValue(
        [in] UINT32 index,
        [in] D2D1_PROPERTY_TYPE type,
        [out] BYTE *value,
        [in] UINT32 value_size
    );
    UINT32 GetValueSize(
        [in] UINT32 index
    );
    HRESULT GetSubProperties(
        [in] UINT32 index,
        [out] ID2D1Properties **props
    );
}

[
    object,
    uuid(28211a43-7d89-476f-8181-2d6159b220ad),
    local,
]
interface ID2D1Effect : ID2D1Properties
{
    void SetInput(
        [in] UINT32 index,
        [in] ID2D1Image *input,
        [in] BOOL invalidate
    );
    HRESULT SetInputCount(
        [in] UINT32 count
    );
    void GetInput(
        [in] UINT32 index,
        [out] ID2D1Image **input
    );
    UINT32 GetInputCount();
    void GetOutput(
        [out] ID2D1Image **output
    );
}

[
    object,
    uuid(689f1f85-c72e-4e33-8f19-85754efd5ace),
    local,
]
interface ID2D1DrawingStateBlock1 : ID2D1DrawingStateBlock
{
    void GetDescription(
        [out] D2D1_DRAWING_STATE_DESCRIPTION1 *desc
    );
    void SetDescription(
        [in] const D2D1_DRAWING_STATE_DESCRIPTION1 *desc
    );
}

[
    object,
    uuid(a898a84c-3873-4588-b08b-ebbf978df041),
    local,
]
interface ID2D1Bitmap1 : ID2D1Bitmap
{
    void GetColorContext(
        [out] ID2D1ColorContext **context
    );
    D2D1_BITMAP_OPTIONS GetOptions();
    HRESULT GetSurface(
        [out] IDXGISurface **surface
    );
    HRESULT Map(
        [in] D2D1_MAP_OPTIONS options,
        [out] D2D1_MAPPED_RECT *mapped_rect
    );
    HRESULT Unmap();
}

[
    object,
    uuid(41343a53-e41a-49a2-91cd-21793bbb62e5),
    local,
]
interface ID2D1BitmapBrush1 : ID2D1BitmapBrush
{
    void SetInterpolationMode1(
        [in] D2D1_INTERPOLATION_MODE mode
    );
    D2D1_INTERPOLATION_MODE GetInterpolationMode1();
}

[
    object,
    uuid(47dd575d-ac05-4cdd-8049-9b02cd16f44c),
    local,
]
interface ID2D1Device : ID2D1Resource
{
    HRESULT CreateDeviceContext(
        [in] D2D1_DEVICE_CONTEXT_OPTIONS options,
        [out] ID2D1DeviceContext **context
    );
    HRESULT CreatePrintControl(
        [in] IWICImagingFactory *wic_factory,
        [in] IPrintDocumentPackageTarget *document_target,
        [in] const D2D1_PRINT_CONTROL_PROPERTIES *desc,
        [out] ID2D1PrintControl **print_control
    );
    void SetMaximumTextureMemory(
        [in] UINT64 max_texture_memory
    );
    UINT64 GetMaximumTextureMemory();
    HRESULT ClearResources(
        [in, defaultvalue(0)] UINT msec_since_use
    );
}

[
    object,
    uuid(54d7898a-a061-40a7-bec7-e465bcba2c4f),
    local,
]
interface ID2D1CommandSink : IUnknown
{
    HRESULT BeginDraw();
    HRESULT EndDraw();
    HRESULT SetAntialiasMode(
        [in] D2D1_ANTIALIAS_MODE antialias_mode
    );
    HRESULT SetTags(
        [in] D2D1_TAG tag1,
        [in] D2D1_TAG tag2
    );
    HRESULT SetTextAntialiasMode(
        [in] D2D1_TEXT_ANTIALIAS_MODE antialias_mode
    );
    HRESULT SetTextRenderingParams(
        [in] IDWriteRenderingParams *text_rendering_params
    );
    HRESULT SetTransform(
        [in] D2D1_MATRIX_3X2_F *transform
    );
    HRESULT SetPrimitiveBlend(
        [in] D2D1_PRIMITIVE_BLEND primitive_blend
    );
    HRESULT SetUnitMode(
        [in] D2D1_UNIT_MODE unit_mode
    );
    HRESULT Clear(
        [in] const D2D1_COLOR_F *color
    );
    HRESULT DrawGlyphRun(
        [in] D2D1_POINT_2F baseline_origin,
        [in] const DWRITE_GLYPH_RUN *glyph_run,
        [in] const DWRITE_GLYPH_RUN_DESCRIPTION *glyph_run_desc,
        [in] ID2D1Brush *brush,
        [in] DWRITE_MEASURING_MODE measuring_mode
    );
    HRESULT DrawLine(
        [in] D2D1_POINT_2F p0,
        [in] D2D1_POINT_2F p1,
        [in] ID2D1Brush *brush,
        [in] float stroke_width,
        [in] ID2D1StrokeStyle *stroke_style
    );
    HRESULT DrawGeometry(
        [in] ID2D1Geometry *geometry,
        [in] ID2D1Brush *brush,
        [in] float stroke_width,
        [in] ID2D1StrokeStyle *stroke_style
    );
    HRESULT DrawRectangle(
        [in] const D2D1_RECT_F *rect,
        [in] ID2D1Brush *brush,
        [in] float stroke_width,
        [in] ID2D1StrokeStyle *stroke_style
    );
    HRESULT DrawBitmap(
        [in] ID2D1Bitmap *bitmap,
        [in] const D2D1_RECT_F *dst_rect,
        [in] float opacity,
        [in] D2D1_INTERPOLATION_MODE interpolation_mode,
        [in] const D2D1_RECT_F *src_rect,
        [in] const D2D1_MATRIX_4X4_F *perspective_transform
    );
    HRESULT DrawImage(
        [in] ID2D1Image *image,
        [in] const D2D1_POINT_2F *target_offset,
        [in] const D2D1_POINT_2F *image_rect,
        [in] D2D1_INTERPOLATION_MODE interpolation_mode,
        [in] D2D1_COMPOSITE_MODE composite_mode
    );
    HRESULT DrawGdiMetafile(
        [in] ID2D1GdiMetafile *metafile,
        [in] const D2D1_POINT_2F *target_offset
    );
    HRESULT FillMesh(
        [in] ID2D1Mesh *mesh,
        [in] ID2D1Brush *brush
    );
    HRESULT FillOpacityMask(
        [in] ID2D1Bitmap *bitmap,
        [in] ID2D1Brush *brush,
        [in] const D2D1_RECT_F *dst_rect,
        [in] const D2D1_RECT_F *src_rect
    );
    HRESULT FillGeometry(
        [in] ID2D1Geometry *geometry,
        [in] ID2D1Brush *brush,
        [in] ID2D1Brush *opacity_brush
    );
    HRESULT FillRectangle(
        [in] const D2D1_RECT_F *rect,
        [in] ID2D1Brush *brush
    );
    HRESULT PushAxisAlignedClip(
        [in] const D2D1_RECT_F *clip_rect,
        [in] D2D1_ANTIALIAS_MODE antialias_mode
    );
    HRESULT PushLayer(
        [in] const D2D1_LAYER_PARAMETERS1 *layer_parameters,
        [in] ID2D1Layer *layer
    );
    HRESULT PopAxisAlignedClip();
    HRESULT PopLayer();
}

[
    object,
    uuid(b4f34a19-2383-4d76-94f6-ec343657c3dc),
    local,
]
interface ID2D1CommandList : ID2D1Image
{
    HRESULT Stream(
        [in] ID2D1CommandSink *sink
    );
    HRESULT Close();
}

[
    object,
    uuid(e8f7fe7a-191c-466d-ad95-975678bda998),
    local,
]
interface ID2D1DeviceContext : ID2D1RenderTarget
{
    HRESULT CreateBitmap(
        [in] D2D1_SIZE_U size,
        [in] const void *src_data,
        [in] UINT32 pitch,
        [in] const D2D1_BITMAP_PROPERTIES1 *desc,
        [out] ID2D1Bitmap1 **bitmap
    );
    HRESULT CreateBitmapFromWicBitmap(
        [in] IWICBitmapSource *bitmap_source,
        [in] const D2D1_BITMAP_PROPERTIES1 *desc,
        [out] ID2D1Bitmap1 **bitmap
    );
    HRESULT CreateColorContext(
        [in] D2D1_COLOR_SPACE space,
        [in] const BYTE *profile,
        [in] UINT32 profile_size,
        [out] ID2D1ColorContext **color_context
    );
    HRESULT CreateColorContextFromFilename(
        [in] const WCHAR *filename,
        [out] ID2D1ColorContext **color_context
    );
    HRESULT CreateColorContextFromWicColorContext(
        [in] IWICColorContext *wic_color_context,
        [out] ID2D1ColorContext **color_context
    );
    HRESULT CreateBitmapFromDxgiSurface(
        [in] IDXGISurface *surface,
        [in] const D2D1_BITMAP_PROPERTIES1 *desc,
        [out] ID2D1Bitmap1 **bitmap
    );
    HRESULT CreateEffect(
        [in] REFCLSID effect_id,
        [out] ID2D1Effect **effect
    );
    HRESULT CreateGradientStopCollection(
        [in] const D2D1_GRADIENT_STOP *stops,
        [in] UINT32 stop_count,
        [in] D2D1_COLOR_SPACE preinterpolation_space,
        [in] D2D1_COLOR_SPACE postinterpolation_space,
        [in] D2D1_BUFFER_PRECISION buffer_precision,
        [in] D2D1_EXTEND_MODE extend_mode,
        [in] D2D1_COLOR_INTERPOLATION_MODE color_interpolation_mode,
        [out] ID2D1GradientStopCollection1 **gradient
    );
    HRESULT CreateImageBrush(
        [in] ID2D1Image *image,
        [in] const D2D1_IMAGE_BRUSH_PROPERTIES *image_brush_desc,
        [in] const D2D1_BRUSH_PROPERTIES *brush_desc,
        [out] ID2D1ImageBrush **brush
    );
    HRESULT CreateBitmapBrush(
        [in] ID2D1Bitmap *bitmap,
        [in] const D2D1_BITMAP_BRUSH_PROPERTIES1 *bitmap_brush_desc,
        [in] const D2D1_BRUSH_PROPERTIES *brush_desc,
        [out] ID2D1BitmapBrush1 **bitmap_brush
    );
    HRESULT CreateCommandList(
        [out] ID2D1CommandList **command_list
    );
    BOOL IsDxgiFormatSupported(
        [in] DXGI_FORMAT format
    );
    BOOL IsBufferPrecisionSupported(
        [in] D2D1_BUFFER_PRECISION buffer_precision
    );
    void GetImageLocalBounds(
        [in] ID2D1Image *image,
        [out] D2D1_RECT_F *local_bounds
    );
    HRESULT GetImageWorldBounds(
        [in] ID2D1Image *image,
        [out] D2D1_RECT_F *world_bounds
    );
    HRESULT GetGlyphRunWorldBounds(
        [in] D2D1_POINT_2F baseline_origin,
        [in] const DWRITE_GLYPH_RUN *glyph_run,
        [in] DWRITE_MEASURING_MODE measuring_mode,
        [out] D2D1_RECT_F *bounds
    );
    void GetDevice(
        [out] ID2D1Device **device
    );
    void SetTarget(
        [in] ID2D1Image *target
    );
    void GetTarget(
        [out] ID2D1Image **target
    );
    void SetRenderingControls(
        [in] const D2D1_RENDERING_CONTROLS *rendering_controls
    );
    void GetRenderingControls(
        [out] D2D1_RENDERING_CONTROLS *rendering_controls
    );
    void SetPrimitiveBlend(
        [in] D2D1_PRIMITIVE_BLEND primitive_blend
    );
    D2D1_PRIMITIVE_BLEND GetPrimitiveBlend();
    void SetUnitMode(
        [in] D2D1_UNIT_MODE unit_mode
    );
    D2D1_UNIT_MODE GetUnitMode();
    void DrawGlyphRun(
        [in] D2D1_POINT_2F baseline_origin,
        [in] const DWRITE_GLYPH_RUN *glyph_run,
        [in] const DWRITE_GLYPH_RUN_DESCRIPTION *glyph_run_desc,
        [in] ID2D1Brush *brush,
        [in] DWRITE_MEASURING_MODE measuring_mode
    );
    void DrawImage(
        [in] ID2D1Image *image,
        [in] const D2D1_POINT_2F *target_offset,
        [in] const D2D1_RECT_F *image_rect,
        [in] D2D1_INTERPOLATION_MODE interpolation_mode,
        [in] D2D1_COMPOSITE_MODE composite_mode
    );
    void DrawGdiMetafile(
        [in] ID2D1GdiMetafile *metafile,
        [in] const D2D1_POINT_2F *target_offset
    );
    void DrawBitmap(
        [in] ID2D1Bitmap *bitmap,
        [in] const D2D1_RECT_F *dst_rect,
        [in] float opacity,
        [in] D2D1_INTERPOLATION_MODE interpolation_mode,
        [in] const D2D1_RECT_F *src_rect,
        [in] const D2D1_MATRIX_4X4_F *perspective_transform
    );
    void PushLayer(
        [in] const D2D1_LAYER_PARAMETERS1 *layer_parameters,
        [in] ID2D1Layer *layer
    );
    HRESULT InvalidateEffectInputRectangle(
        [in] ID2D1Effect *effect,
        [in] UINT32 input,
        [in] const D2D1_RECT_F *input_rect
    );
    HRESULT GetEffectInvalidRectangleCount(
        [in] ID2D1Effect *effect,
        [out] UINT32 *rect_count
    );
    HRESULT GetEffectInvalidRectangles(
        [in] ID2D1Effect *effect,
        [out] D2D1_RECT_F *rectangles,
        [in] UINT32 rect_count
    );
    HRESULT GetEffectRequiredInputRectangles(
        [in] ID2D1Effect *effect,
        [in] const D2D1_RECT_F *image_rect,
        [in] const D2D1_EFFECT_INPUT_DESCRIPTION *desc,
        [out] D2D1_RECT_F *input_rect,
        [in] UINT32 input_count
    );
    void FillOpacityMask(
        [in] ID2D1Bitmap *mask,
        [in] ID2D1Brush *brush,
        [in] const D2D1_RECT_F *dst_rect,
        [in] const D2D1_RECT_F *src_rect
    );
}

[
    object,
    uuid(bb12d362-daee-4b9a-aa1d-14ba401cfa1f),
    local,
]
interface ID2D1Factory1 : ID2D1Factory
{
    HRESULT CreateDevice(
        [in] IDXGIDevice *dxgi_device,
        [out] ID2D1Device **device
    );
    HRESULT CreateStrokeStyle(
        [in] const D2D1_STROKE_STYLE_PROPERTIES1 *desc,
        [in, size_is(dash_count)] const float *dashes,
        [in] UINT32 dash_count,
        [out] ID2D1StrokeStyle1 **stroke_style
    );
    HRESULT CreatePathGeometry(
        [out] ID2D1PathGeometry1 **geometry
    );
    HRESULT CreateDrawingStateBlock(
        [in] const D2D1_DRAWING_STATE_DESCRIPTION1 *desc,
        [in] IDWriteRenderingParams *text_rendering_params,
        [out] ID2D1DrawingStateBlock1 **state_block
    );
    HRESULT CreateGdiMetafile(
        [in] IStream *stream,
        [out] ID2D1GdiMetafile **metafile
    );
    HRESULT RegisterEffectFromStream(
        [in] REFCLSID effect_id,
        [in] IStream *property_xml,
        [in, size_is(binding_count)] const D2D1_PROPERTY_BINDING *bindings,
        [in] UINT32 binding_count,
        [in] PD2D1_EFFECT_FACTORY effect_factory
    );
    HRESULT RegisterEffectFromString(
        [in] REFCLSID effect_id,
        [in] const WCHAR *property_xml,
        [in, size_is(binding_count)] const D2D1_PROPERTY_BINDING *bindings,
        [in] UINT32 binding_count,
        [in] PD2D1_EFFECT_FACTORY effect_factory
    );
    HRESULT UnregisterEffect(
        [in] REFCLSID effect_id
    );
    HRESULT GetRegisteredEffects(
        [out, size_is(effect_count)] CLSID *effects,
        [in] UINT32 effect_count,
        [out] UINT32 *returned,
        [out] UINT32 *registered
    );
    HRESULT GetEffectProperties(
        [in] REFCLSID effect_id,
        [out] ID2D1Properties **props
    );
}
