The final 6/6 patch with ID2D1Bitmap1 implementation will come later once these first ones are ready.
Changes since v1, * Fixed idl issues pointed out by nsivov. * Squashed stub and implementation patches together into one commit. * Reorganized patch series so that each patch individually passes tests. * Switched internal implementations to use ID2D1Factory1 e.g. in geometry.c. * In test, replaced d3d11 device with d3d10 in order to reuse existing helper functions in other d2d1 tests, as requested in v1 review. * Removed NULL checks as requested in v1 review. * Reordered interface conditional check in QueryInterface per v1 review. * Renamed several identifiers as requested in v1 review.
Lucian Poston (5): d2d1: Add d2d1_1.idl d2d1: Add test that draws using d2d device context d2d1: Stub ID2D1Factory1 d2d1: Partially implement ID2D1Device d2d1: Partially implement ID2D1DeviceContext
dlls/d2d1/Makefile.in | 2 + dlls/d2d1/d2d1_private.h | 36 +- dlls/d2d1/device.c | 191 +++++++ dlls/d2d1/device_context.c | 1180 ++++++++++++++++++++++++++++++++++++++++++++ dlls/d2d1/factory.c | 193 ++++++-- dlls/d2d1/geometry.c | 30 +- dlls/d2d1/render_target.c | 82 ++- dlls/d2d1/tests/d2d1.c | 105 ++++ dlls/uuid/d2d.c | 1 + include/Makefile.in | 1 + include/d2d1_1.idl | 655 ++++++++++++++++++++++++ include/dcommon.idl | 15 + 12 files changed, 2420 insertions(+), 71 deletions(-) create mode 100644 dlls/d2d1/device.c create mode 100644 dlls/d2d1/device_context.c create mode 100644 include/d2d1_1.idl
https://bugs.winehq.org/show_bug.cgi?id=44052
Signed-off-by: Lucian Poston lucian.poston@gmail.com ---
Changes since v1, * Fixed idl issues pointed out by nsivov.
dlls/d2d1/d2d1_private.h | 2 +- dlls/uuid/d2d.c | 1 + include/Makefile.in | 1 + include/d2d1_1.idl | 655 +++++++++++++++++++++++++++++++++++++++++++++++ include/dcommon.idl | 15 ++ 5 files changed, 673 insertions(+), 1 deletion(-) create mode 100644 include/d2d1_1.idl
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 98298f892a..3b21bc1fb6 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -24,7 +24,7 @@ #include <assert.h> #include <limits.h> #define COBJMACROS -#include "d2d1.h" +#include "d2d1_1.h" #ifdef D2D1_INIT_GUID #include "initguid.h" #endif diff --git a/dlls/uuid/d2d.c b/dlls/uuid/d2d.c index dbe143ef92..1a6c72e189 100644 --- a/dlls/uuid/d2d.c +++ b/dlls/uuid/d2d.c @@ -19,3 +19,4 @@ #include "d3d10_1.h" #include "initguid.h" #include "d2d1.h" +#include "d2d1_1.h" diff --git a/include/Makefile.in b/include/Makefile.in index fa1e42738b..e6a369f035 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -36,6 +36,7 @@ IDL_SRCS = \ ctfutb.idl \ ctxtcall.idl \ d2d1.idl \ + d2d1_1.idl \ d3d10.idl \ d3d10_1.idl \ d3d10sdklayers.idl \ diff --git a/include/d2d1_1.idl b/include/d2d1_1.idl new file mode 100644 index 0000000000..891a426c0c --- /dev/null +++ b/include/d2d1_1.idl @@ -0,0 +1,655 @@ +/* + * Copyright 2017 Wine Project + * + * 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 "dxgi.idl"; +import "d2d1.idl"; + +interface IWICImagingFactory; +interface IWICColorContext; +interface IPrintDocumentPackageTarget; +interface ID2D1PrintControl; +interface ID2D1Properties; +interface ID2D1ColorContext; +interface ID2D1Bitmap1; +interface ID2D1CommandSink; +interface ID2D1Effect; +interface ID2D1ImageBrush; +interface ID2D1Device; + +typedef enum D2D1_PRIMITIVE_BLEND +{ + D2D1_PRIMITIVE_BLEND_SOURCE_OVER = 0, + D2D1_PRIMITIVE_BLEND_COPY = 1, + D2D1_PRIMITIVE_BLEND_MIN = 2, + D2D1_PRIMITIVE_BLEND_ADD = 3, + D2D1_PRIMITIVE_BLEND_MAX = 4, + D2D1_PRIMITIVE_BLEND_FORCE_DWORD = 0xffffffff, +} D2D1_PRIMITIVE_BLEND; + +typedef enum D2D1_UNIT_MODE +{ + D2D1_UNIT_MODE_DIPS = 0, + D2D1_UNIT_MODE_PIXELS = 1, + D2D1_UNIT_MODE_FORCE_DWORD = 0xffffffff, +} D2D1_UNIT_MODE; + +typedef enum D2D1_STROKE_TRANSFORM_TYPE +{ + D2D1_STROKE_TRANSFORM_TYPE_NORMAL = 0, + D2D1_STROKE_TRANSFORM_TYPE_FIXED = 1, + D2D1_STROKE_TRANSFORM_TYPE_HAIRLINE = 2, + D2D1_STROKE_TRANSFORM_TYPE_FORCE_DWORD = 0xffffffff, +} D2D1_STROKE_TRANSFORM_TYPE; + +typedef enum D2D1_DEVICE_CONTEXT_OPTIONS +{ + D2D1_DEVICE_CONTEXT_OPTIONS_NONE = 0, + D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS = 1, + D2D1_DEVICE_CONTEXT_OPTIONS_FORCE_DWORD = 0xffffffff, +} D2D1_DEVICE_CONTEXT_OPTIONS; + +typedef enum D2D1_PRINT_FONT_SUBSET_MODE +{ + D2D1_PRINT_FONT_SUBSET_DEFAULT = 0, + D2D1_PRINT_FONT_SUBSET_EACHPAGE = 1, + D2D1_PRINT_FONT_SUBSET_NONE = 2, + D2D1_PRINT_FONT_SUBSET_FORCE_DWORD = 0xffffffff, +} D2D1_PRINT_FONT_SUBSET_MODE; + +typedef enum D2D1_COLOR_SPACE +{ + D2D1_COLOR_SPACE_CUSTOM = 0, + D2D1_COLOR_SPACE_SRGB = 1, + D2D1_COLOR_SPACE_SCRGB = 2, + D2D1_COLOR_SPACE_FORCE_DWORD = 0xffffffff, +} D2D1_COLOR_SPACE; + +typedef enum D2D1_BITMAP_OPTIONS +{ + D2D1_BITMAP_OPTIONS_NONE = 0, + D2D1_BITMAP_OPTIONS_TARGET = 1, + D2D1_BITMAP_OPTIONS_CANNOT_DRAW = 2, + D2D1_BITMAP_OPTIONS_CPU_READ = 4, + D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE = 8, + D2D1_BITMAP_OPTIONS_FORCE_DWORD = 0xffffffff, +} D2D1_BITMAP_OPTIONS; + +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_BUFFER_PRECISION +{ + D2D1_BUFFER_PRECISION_UNKNOWN = 0, + D2D1_BUFFER_PRECISION_8BPC_UNORM = 1, + D2D1_BUFFER_PRECISION_8BPC_UNORM_SRGB = 2, + D2D1_BUFFER_PRECISION_16BPC_UNORM = 3, + D2D1_BUFFER_PRECISION_16BPC_FLOAT = 4, + D2D1_BUFFER_PRECISION_32BPC_FLOAT = 5, + D2D1_BUFFER_PRECISION_FORCE_DWORD = 0xffffffff, +} D2D1_BUFFER_PRECISION; + +typedef enum D2D1_COLOR_INTERPOLATION_MODE +{ + D2D1_COLOR_INTERPOLATION_MODE_STRAIGHT = 0, + D2D1_COLOR_INTERPOLATION_MODE_PREMULTIPLIED = 1, + D2D1_COLOR_INTERPOLATION_MODE_FORCE_DWORD = 0xffffffff, +} D2D1_COLOR_INTERPOLATION_MODE; + +typedef enum D2D1_COMPOSITE_MODE +{ + D2D1_COMPOSITE_MODE_SOURCE_OVER = 0, + D2D1_COMPOSITE_MODE_DESTINATION_OVER = 1, + D2D1_COMPOSITE_MODE_SOURCE_IN = 2, + D2D1_COMPOSITE_MODE_DESTINATION_IN = 3, + D2D1_COMPOSITE_MODE_SOURCE_OUT = 4, + D2D1_COMPOSITE_MODE_DESTINATION_OUT = 5, + D2D1_COMPOSITE_MODE_SOURCE_ATOP = 6, + D2D1_COMPOSITE_MODE_DESTINATION_ATOP = 7, + D2D1_COMPOSITE_MODE_XOR = 8, + D2D1_COMPOSITE_MODE_PLUS = 9, + D2D1_COMPOSITE_MODE_SOURCE_COPY = 10, + D2D1_COMPOSITE_MODE_BOUNDED_SOURCE_COPY = 11, + D2D1_COMPOSITE_MODE_MASK_INVERT = 12, + D2D1_COMPOSITE_MODE_FORCE_DWORD = 0xffffffff, +} D2D1_COMPOSITE_MODE; + +typedef enum D2D1_LAYER_OPTIONS1 +{ + D2D1_LAYER_OPTIONS1_NONE = 0, + D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND = 1, + D2D1_LAYER_OPTIONS1_IGNORE_ALPHA = 2, + D2D1_LAYER_OPTIONS1_FORCE_DWORD = 0xffffffff, +} D2D1_LAYER_OPTIONS1; + +typedef enum D2D1_MAP_OPTIONS +{ + D2D1_MAP_OPTIONS_NONE = 0, + D2D1_MAP_OPTIONS_READ = 1, + D2D1_MAP_OPTIONS_WRITE = 2, + D2D1_MAP_OPTIONS_DISCARD = 4, + D2D1_MAP_OPTIONS_FORCE_DWORD = 0xffffffff, +} D2D1_MAP_OPTIONS; + +typedef D2D_MATRIX_4X4_F D2D1_MATRIX_4X4_F; +typedef struct DWRITE_GLYPH_RUN_DESCRIPTION DWRITE_GLYPH_RUN_DESCRIPTION; +typedef struct D2D1_PROPERTY_BINDING D2D1_PROPERTY_BINDING; + +typedef struct D2D1_MAPPED_RECT +{ + UINT32 pitch; + BYTE *bits; +} D2D1_MAPPED_RECT; + +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_RENDERING_CONTROLS +{ + D2D1_BUFFER_PRECISION bufferPrecision; + D2D1_SIZE_U tileSize; +} D2D1_RENDERING_CONTROLS; + +typedef struct D2D1_EFFECT_INPUT_DESCRIPTION +{ + ID2D1Effect *effect; + UINT32 inputIndex; + D2D1_RECT_F inputRectangle; +} D2D1_EFFECT_INPUT_DESCRIPTION; + +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_BITMAP_PROPERTIES1 +{ + D2D1_PIXEL_FORMAT pixelFormat; + float dpiX; + float dpiY; + D2D1_BITMAP_OPTIONS bitmapOptions; + ID2D1ColorContext *colorContext; +} D2D1_BITMAP_PROPERTIES1; + +typedef HRESULT (__stdcall *PD2D1_EFFECT_FACTORY)(IUnknown **effect); + +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_POINT_DESCRIPTION +{ + D2D1_POINT_2F point; + D2D1_POINT_2F unitTangentVector; + UINT32 endSegment; + UINT32 endFigure; + float lengthToEndSegment; +} D2D1_POINT_DESCRIPTION; + +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_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; + +[ + local, + object, + uuid(a898a84c-3873-4588-b08b-ebbf978df041) +] +interface ID2D1Bitmap1 : ID2D1Bitmap +{ + void GetColorContext( + [out] ID2D1ColorContext **color_context + ); + D2D1_BITMAP_OPTIONS GetOptions(); + HRESULT GetSurface( + [out] IDXGISurface **surface + ); + HRESULT Map( + D2D1_MAP_OPTIONS options, + [out] D2D1_MAPPED_RECT *mapped_rect + ); + HRESULT Unmap(); +} + +[ + local, + object, + uuid(ae1572f4-5dd0-4777-998b-9279472ae63b) +] +interface ID2D1GradientStopCollection1 : ID2D1GradientStopCollection +{ + void GetGradientStops1( + [out] D2D1_GRADIENT_STOP *stops, + [in] UINT32 stop_count + ); + D2D1_COLOR_SPACE GetPreInterpolationSpace(); + D2D1_COLOR_SPACE GetPostInterpolationSpace(); + D2D1_BUFFER_PRECISION GetBufferPrecision(); + D2D1_COLOR_INTERPOLATION_MODE GetColorInterpolationMode(); +} + +[ + local, + object, + uuid(b4f34a19-2383-4d76-94f6-ec343657c3dc) +] +interface ID2D1CommandList : ID2D1Image +{ + HRESULT Stream( + [in] ID2D1CommandSink *Sink + ); + HRESULT Close(); +} + +[ + local, + object, + uuid(41343a53-e41a-49a2-91cd-21793bbb62e5) +] +interface ID2D1BitmapBrush1 : ID2D1BitmapBrush +{ + void SetInterpolationMode1( + D2D1_INTERPOLATION_MODE interpolation_mode + ); + D2D1_INTERPOLATION_MODE GetInterpolationMode1(); +} + +[ + local, + object, + uuid(1c4820bb-5771-4518-a581-2fe4dd0ec657) +] +interface ID2D1ColorContext : ID2D1Resource +{ + D2D1_COLOR_SPACE GetColorSpace(); + UINT32 GetProfileSize(); + HRESULT GetProfile( + [out] BYTE *profile, + [in] UINT32 size + ); +} + +[ + local, + object, + uuid(82237326-8111-4f7c-bcf4-b5c1175564fe) +] +interface ID2D1GdiMetafileSink : ID2D1Resource +{ + BOOL ProcessRecord( + [in] DWORD record_type, + [out] const void *data, + [in] DWORD data_size + ); +} + +[ + local, + object, + uuid(2f543dc3-cfc1-4211-864f-cfd91c6f3395) +] +interface ID2D1GdiMetafile : ID2D1Resource +{ + HRESULT Stream( + [in] ID2D1GdiMetafileSink *sink + ); + HRESULT GetBounds( + [out] D2D1_RECT_F *bounds + ); +} + +[ + local, + object, + uuid(10a72a66-e91c-43f4-993f-ddf4b82b0b4a) +] +interface ID2D1StrokeStyle1 : ID2D1StrokeStyle +{ + D2D1_STROKE_TRANSFORM_TYPE GetStrokeTransformType(); +} + +[ + local, + object, + uuid(62baa2d2-ab54-41b7-b872-787e0106a421) +] +interface ID2D1PathGeometry1 : ID2D1PathGeometry +{ + HRESULT ComputePointAndSegmentAtLength( + [in] float length, + [in] UINT32 start_segment, + [in] const D2D1_MATRIX_3X2_F *world_transform, + [in] float tolerance, + [out] D2D1_POINT_DESCRIPTION *desc + ); +} + +[ + local, + object, + uuid(689f1f85-c72e-4e33-8f19-85754efd5ace) +] +interface ID2D1DrawingStateBlock1 : ID2D1DrawingStateBlock +{ + void GetDescription( + [out] D2D1_DRAWING_STATE_DESCRIPTION1 *desc + ); + void SetDescription( + [in] const D2D1_DRAWING_STATE_DESCRIPTION1 *desc + ); +} + +[ + local, + object, + uuid(e8f7fe7a-191c-466d-ad95-975678bda998) +] +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 + ); +} + +[ + local, + object, + uuid(47dd575d-ac05-4cdd-8049-9b02cd16f44c) +] +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 + ); +} + +[ + local, + object, + uuid(bb12d362-daee-4b9a-aa1d-14ba401cfa1f) +] +interface ID2D1Factory1 : ID2D1Factory +{ + HRESULT CreateDevice( + [in] IDXGIDevice *dxgi_device, + [out] ID2D1Device **device + ); + HRESULT CreateStrokeStyle( + [in] const D2D1_STROKE_STYLE_PROPERTIES1 *desc, + [in] const float *dashes, + [in] UINT dashes_count, + [out] const 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 clsid, + [in] IStream *property_xml, + [in] const D2D1_PROPERTY_BINDING *bindings, + [in] UINT32 bindings_count, + [in] PD2D1_EFFECT_FACTORY effect_factory + ); + HRESULT RegisterEffectFromString( + [in] REFCLSID clsid, + [in] const WCHAR *property_xml, + [in] const D2D1_PROPERTY_BINDING *bindings, + [in] UINT32 bindings_count, + [in] PD2D1_EFFECT_FACTORY effect_factory + ); + HRESULT UnregisterEffect( + [in] REFCLSID clsid + ); + HRESULT GetRegisteredEffects( + [out] CLSID *clsids, + [in] UINT32 count, + [out] UINT32 *returned, + [out] UINT32 *registered + ); + HRESULT GetEffectProperties( + [in] REFCLSID effect_id, + [out] ID2D1Properties **props + ); +} diff --git a/include/dcommon.idl b/include/dcommon.idl index db5055d202..18f2fbeb3e 100644 --- a/include/dcommon.idl +++ b/include/dcommon.idl @@ -61,3 +61,18 @@ typedef struct D2D_SIZE_U UINT32 width; UINT32 height; } D2D_SIZE_U, D2D1_SIZE_U; + +typedef struct D2D_MATRIX_4X4_F +{ + union + { + struct + { + float _11, _12, _13, _14; + float _21, _22, _23, _24; + float _31, _32, _33, _34; + float _41, _42, _43, _44; + }; + float m[4][4]; + }; +} D2D_MATRIX_4X4_F;
This test is based on the d2d usage in the Temple+ app referred to in the winehq bug at https://bugs.winehq.org/show_bug.cgi?id=44052
Essentially, this test draws a rectangle using a d2d device context, similar to the basic how-to in the link below. https://msdn.microsoft.com/en-us/library/windows/desktop/hh780339(v=vs.85).a...
Signed-off-by: Lucian Poston lucian.poston@gmail.com ---
Changes since v1, * Added todo_wine's so that test passes without later patches in series. * Replaced d3d11 device with d3d10 in order to reuse existing helper functions in other d2d1 tests, as requested in v1 review.
dlls/d2d1/tests/d2d1.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index a0f22128fa..6006ad709d 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -20,6 +20,7 @@ #include <limits.h> #include <math.h> #include "d2d1.h" +#include "d2d1_1.h" #include "wincrypt.h" #include "wine/test.h" #include "initguid.h" @@ -4625,6 +4626,111 @@ todo_wine DestroyWindow(window); }
+static void test_draw_via_ID2D1DeviceContext(void) +{ + HRESULT hr; + ID2D1Factory1 *factory; + ID2D1Device *device; + ID3D10Device1 *d3d10_device; + IDXGIDevice *dxgi_device; + ID2D1DeviceContext *context; + IDXGISurface *dxgi_surface; + ID2D1Bitmap1 *bitmap; + D2D1_BITMAP_PROPERTIES1 bitmap_properties; + IDXGISwapChain *swapchain; + HWND window; + ID2D1SolidColorBrush *brush; + D2D1_COLOR_F c; + D2D1_RECT_F r; + set_color(&c, 0.5f, 0.5f, 0.5f, 0.5f); + set_rect(&r, 10.0f, 480.0f, 10.0f, 480.0f); + + if (!(d3d10_device = create_device())) + { + skip("Failed to create device, skipping test.\n"); + return; + } + + window = create_window(); + swapchain = create_swapchain(d3d10_device, window, TRUE); + hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&dxgi_surface); + ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr); + + hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, + &IID_ID2D1Factory1, NULL, (void**)&factory); + if (FAILED(hr)) + { + skip("ID2D1Factory1 unavailable, skipping test.\n"); + return; + } + + hr = ID3D10Device1_QueryInterface(d3d10_device, &IID_IDXGIDevice, + (void**)&dxgi_device); + ok(SUCCEEDED(hr), "Failed to create dxgi_device, hr %#x.\n", hr); + if (FAILED(hr)) + { + skip("dxgi_device unavailable, skipping test.\n"); + return; + } + + hr = ID2D1Factory1_CreateDevice(factory, dxgi_device, &device); + todo_wine + ok(SUCCEEDED(hr), "Failed to create device, hr %#x.\n", hr); + if (FAILED(hr)) + { + skip("device unavailable, skipping test.\n"); + return; + } + + hr = ID2D1Device_CreateDeviceContext(device, + D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &context); + todo_wine + ok(SUCCEEDED(hr), "Failed to create device context, hr %#x.\n", hr); + if (FAILED(hr)) + { + skip("device context unavailable, skipping test.\n"); + return; + } + + bitmap_properties.pixelFormat.format = DXGI_FORMAT_UNKNOWN; + bitmap_properties.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE; + bitmap_properties.dpiX = 96.0; + bitmap_properties.dpiY = 96.0; + bitmap_properties.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW; + hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(context, dxgi_surface, + &bitmap_properties, &bitmap); + todo_wine + ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr); + if (FAILED(hr)) + { + skip("bitmap unavailable for use as device context target, skipping test.\n"); + return; + } + + ID2D1DeviceContext_SetTarget(context, (ID2D1Image *)bitmap); + ID2D1DeviceContext_CreateSolidColorBrush(context, &c, NULL, &brush); + + ID2D1DeviceContext_BeginDraw(context); + ID2D1DeviceContext_DrawRectangle(context, &r, (ID2D1Brush *)brush, 1.0f, NULL); + hr = ID2D1DeviceContext_EndDraw(context, NULL, NULL); + todo_wine + ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); + hr = IDXGISwapChain_Present(swapchain, 0, 0); + todo_wine + ok(SUCCEEDED(hr), "Failed to present image, hr %#x.\n", hr); + + ID2D1SolidColorBrush_Release(brush); + DestroyWindow(window); + IDXGISwapChain_Release(swapchain); + ID2D1Bitmap1_Release(bitmap); + IDXGISurface_Release(dxgi_surface); + ID2D1DeviceContext_Release(context); + IDXGIDevice_Release(dxgi_device); + ID3D10Device1_Release(d3d10_device); + ID2D1Device_Release(device); + ID2D1Factory1_Release(factory); +} + static void create_target_dibsection(HDC hdc, UINT32 width, UINT32 height) { char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])]; @@ -6402,6 +6508,7 @@ START_TEST(d2d1) test_opacity_brush(); test_create_target(); test_draw_text_layout(); + test_draw_via_ID2D1DeviceContext(); test_dc_target(); test_hwnd_target(); test_bitmap_target();
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check? Full results can be found at https://testbot.winehq.org/JobDetails.pl?Key=34319
Your paranoid android.
=== build (build) === Make failed
https://bugs.winehq.org/show_bug.cgi?id=44052
Signed-off-by: Lucian Poston lucian.poston@gmail.com ---
Changes since v1, * Switched internal implementations to use ID2D1Factory1 e.g. in geometry.c. * Reordered interface conditional check in QueryInterface per v1 review. * Renamed several identifiers as requested in v1 review.
dlls/d2d1/d2d1_private.h | 8 +-- dlls/d2d1/factory.c | 184 ++++++++++++++++++++++++++++++++++++++--------- dlls/d2d1/geometry.c | 30 +++++--- 3 files changed, 177 insertions(+), 45 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index 3b21bc1fb6..c39a23bed8 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -399,7 +399,7 @@ struct d2d_geometry ID2D1Geometry ID2D1Geometry_iface; LONG refcount;
- ID2D1Factory *factory; + ID2D1Factory1 *factory;
D2D_MATRIX_3X2_F transform;
@@ -463,10 +463,10 @@ struct d2d_geometry } u; };
-void d2d_path_geometry_init(struct d2d_geometry *geometry, ID2D1Factory *factory) DECLSPEC_HIDDEN; +void d2d_path_geometry_init(struct d2d_geometry *geometry, ID2D1Factory1 *factory) DECLSPEC_HIDDEN; HRESULT d2d_rectangle_geometry_init(struct d2d_geometry *geometry, - ID2D1Factory *factory, const D2D1_RECT_F *rect) DECLSPEC_HIDDEN; -void d2d_transformed_geometry_init(struct d2d_geometry *geometry, ID2D1Factory *factory, + ID2D1Factory1 *factory, const D2D1_RECT_F *rect) DECLSPEC_HIDDEN; +void d2d_transformed_geometry_init(struct d2d_geometry *geometry, ID2D1Factory1 *factory, ID2D1Geometry *src_geometry, const D2D_MATRIX_3X2_F *transform) DECLSPEC_HIDDEN; struct d2d_geometry *unsafe_impl_from_ID2D1Geometry(ID2D1Geometry *iface) DECLSPEC_HIDDEN;
diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 4b9315f821..9b0bd5bb84 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -26,7 +26,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d2d);
struct d2d_factory { - ID2D1Factory ID2D1Factory_iface; + ID2D1Factory1 ID2D1Factory1_iface; LONG refcount;
ID3D10Device1 *device; @@ -35,9 +35,9 @@ struct d2d_factory float dpi_y; };
-static inline struct d2d_factory *impl_from_ID2D1Factory(ID2D1Factory *iface) +static inline struct d2d_factory *impl_from_ID2D1Factory(ID2D1Factory1 *iface) { - return CONTAINING_RECORD(iface, struct d2d_factory, ID2D1Factory_iface); + return CONTAINING_RECORD(iface, struct d2d_factory, ID2D1Factory1_iface); }
static HRESULT d2d_factory_reload_sysmetrics(struct d2d_factory *factory) @@ -58,14 +58,15 @@ static HRESULT d2d_factory_reload_sysmetrics(struct d2d_factory *factory) return S_OK; }
-static HRESULT STDMETHODCALLTYPE d2d_factory_QueryInterface(ID2D1Factory *iface, REFIID iid, void **out) +static HRESULT STDMETHODCALLTYPE d2d_factory_QueryInterface(ID2D1Factory1 *iface, REFIID iid, void **out) { TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
- if (IsEqualGUID(iid, &IID_ID2D1Factory) + if (IsEqualGUID(iid, &IID_ID2D1Factory1) + || IsEqualGUID(iid, &IID_ID2D1Factory) || IsEqualGUID(iid, &IID_IUnknown)) { - ID2D1Factory_AddRef(iface); + ID2D1Factory1_AddRef(iface); *out = iface; return S_OK; } @@ -76,7 +77,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_QueryInterface(ID2D1Factory *iface, return E_NOINTERFACE; }
-static ULONG STDMETHODCALLTYPE d2d_factory_AddRef(ID2D1Factory *iface) +static ULONG STDMETHODCALLTYPE d2d_factory_AddRef(ID2D1Factory1 *iface) { struct d2d_factory *factory = impl_from_ID2D1Factory(iface); ULONG refcount = InterlockedIncrement(&factory->refcount); @@ -86,7 +87,7 @@ static ULONG STDMETHODCALLTYPE d2d_factory_AddRef(ID2D1Factory *iface) return refcount; }
-static ULONG STDMETHODCALLTYPE d2d_factory_Release(ID2D1Factory *iface) +static ULONG STDMETHODCALLTYPE d2d_factory_Release(ID2D1Factory1 *iface) { struct d2d_factory *factory = impl_from_ID2D1Factory(iface); ULONG refcount = InterlockedDecrement(&factory->refcount); @@ -103,7 +104,7 @@ static ULONG STDMETHODCALLTYPE d2d_factory_Release(ID2D1Factory *iface) return refcount; }
-static HRESULT STDMETHODCALLTYPE d2d_factory_ReloadSystemMetrics(ID2D1Factory *iface) +static HRESULT STDMETHODCALLTYPE d2d_factory_ReloadSystemMetrics(ID2D1Factory1 *iface) { struct d2d_factory *factory = impl_from_ID2D1Factory(iface);
@@ -112,7 +113,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_ReloadSystemMetrics(ID2D1Factory *i return d2d_factory_reload_sysmetrics(factory); }
-static void STDMETHODCALLTYPE d2d_factory_GetDesktopDpi(ID2D1Factory *iface, float *dpi_x, float *dpi_y) +static void STDMETHODCALLTYPE d2d_factory_GetDesktopDpi(ID2D1Factory1 *iface, float *dpi_x, float *dpi_y) { struct d2d_factory *factory = impl_from_ID2D1Factory(iface);
@@ -122,7 +123,7 @@ static void STDMETHODCALLTYPE d2d_factory_GetDesktopDpi(ID2D1Factory *iface, flo *dpi_y = factory->dpi_y; }
-static HRESULT STDMETHODCALLTYPE d2d_factory_CreateRectangleGeometry(ID2D1Factory *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateRectangleGeometry(ID2D1Factory1 *iface, const D2D1_RECT_F *rect, ID2D1RectangleGeometry **geometry) { struct d2d_geometry *object; @@ -146,7 +147,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateRectangleGeometry(ID2D1Factor return S_OK; }
-static HRESULT STDMETHODCALLTYPE d2d_factory_CreateRoundedRectangleGeometry(ID2D1Factory *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateRoundedRectangleGeometry(ID2D1Factory1 *iface, const D2D1_ROUNDED_RECT *rect, ID2D1RoundedRectangleGeometry **geometry) { FIXME("iface %p, rect %p, geometry %p stub!\n", iface, rect, geometry); @@ -154,7 +155,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateRoundedRectangleGeometry(ID2D return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE d2d_factory_CreateEllipseGeometry(ID2D1Factory *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateEllipseGeometry(ID2D1Factory1 *iface, const D2D1_ELLIPSE *ellipse, ID2D1EllipseGeometry **geometry) { FIXME("iface %p, ellipse %p, geometry %p stub!\n", iface, ellipse, geometry); @@ -162,7 +163,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateEllipseGeometry(ID2D1Factory return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE d2d_factory_CreateGeometryGroup(ID2D1Factory *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateGeometryGroup(ID2D1Factory1 *iface, D2D1_FILL_MODE fill_mode, ID2D1Geometry **geometries, UINT32 geometry_count, ID2D1GeometryGroup **group) { FIXME("iface %p, fill_mode %#x, geometries %p, geometry_count %u, group %p stub!\n", @@ -171,7 +172,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateGeometryGroup(ID2D1Factory *i return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE d2d_factory_CreateTransformedGeometry(ID2D1Factory *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateTransformedGeometry(ID2D1Factory1 *iface, ID2D1Geometry *src_geometry, const D2D1_MATRIX_3X2_F *transform, ID2D1TransformedGeometry **transformed_geometry) { @@ -191,7 +192,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateTransformedGeometry(ID2D1Fact return S_OK; }
-static HRESULT STDMETHODCALLTYPE d2d_factory_CreatePathGeometry(ID2D1Factory *iface, ID2D1PathGeometry **geometry) +static HRESULT STDMETHODCALLTYPE d2d_factory_CreatePathGeometry(ID2D1Factory1 *iface, ID2D1PathGeometry **geometry) { struct d2d_geometry *object;
@@ -208,7 +209,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreatePathGeometry(ID2D1Factory *if return S_OK; }
-static HRESULT STDMETHODCALLTYPE d2d_factory_CreateStrokeStyle(ID2D1Factory *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateStrokeStyle(ID2D1Factory1 *iface, const D2D1_STROKE_STYLE_PROPERTIES *desc, const float *dashes, UINT32 dash_count, ID2D1StrokeStyle **stroke_style) { @@ -221,7 +222,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateStrokeStyle(ID2D1Factory *ifa if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) return E_OUTOFMEMORY;
- if (FAILED(hr = d2d_stroke_style_init(object, iface, desc, dashes, dash_count))) + if (FAILED(hr = d2d_stroke_style_init(object, (ID2D1Factory *)iface, desc, dashes, dash_count))) { WARN("Failed to initialize stroke style, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); @@ -234,7 +235,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateStrokeStyle(ID2D1Factory *ifa return S_OK; }
-static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDrawingStateBlock(ID2D1Factory *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDrawingStateBlock(ID2D1Factory1 *iface, const D2D1_DRAWING_STATE_DESCRIPTION *desc, IDWriteRenderingParams *text_rendering_params, ID2D1DrawingStateBlock **state_block) { @@ -246,7 +247,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDrawingStateBlock(ID2D1Factor if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) return E_OUTOFMEMORY;
- d2d_state_block_init(object, iface, desc, text_rendering_params); + d2d_state_block_init(object, (ID2D1Factory *)iface, desc, text_rendering_params);
TRACE("Created state block %p.\n", object); *state_block = &object->ID2D1DrawingStateBlock_iface; @@ -266,7 +267,7 @@ static HRESULT d2d_factory_get_device(struct d2d_factory *factory, ID3D10Device1 return hr; }
-static HRESULT STDMETHODCALLTYPE d2d_factory_CreateWicBitmapRenderTarget(ID2D1Factory *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateWicBitmapRenderTarget(ID2D1Factory1 *iface, IWICBitmap *target, const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1RenderTarget **render_target) { struct d2d_factory *factory = impl_from_ID2D1Factory(iface); @@ -285,7 +286,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateWicBitmapRenderTarget(ID2D1Fa return hr; }
- if (FAILED(hr = d2d_wic_render_target_init(object, iface, device, target, desc))) + if (FAILED(hr = d2d_wic_render_target_init(object, (ID2D1Factory *)iface, device, target, desc))) { WARN("Failed to initialize render target, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); @@ -298,7 +299,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateWicBitmapRenderTarget(ID2D1Fa return S_OK; }
-static HRESULT STDMETHODCALLTYPE d2d_factory_CreateHwndRenderTarget(ID2D1Factory *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateHwndRenderTarget(ID2D1Factory1 *iface, const D2D1_RENDER_TARGET_PROPERTIES *desc, const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwnd_rt_desc, ID2D1HwndRenderTarget **render_target) { @@ -315,7 +316,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateHwndRenderTarget(ID2D1Factory if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) return E_OUTOFMEMORY;
- if (FAILED(hr = d2d_hwnd_render_target_init(object, iface, device, desc, hwnd_rt_desc))) + if (FAILED(hr = d2d_hwnd_render_target_init(object, (ID2D1Factory *)iface, device, desc, hwnd_rt_desc))) { WARN("Failed to initialize render target, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); @@ -328,15 +329,15 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateHwndRenderTarget(ID2D1Factory return S_OK; }
-static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDxgiSurfaceRenderTarget(ID2D1Factory *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDxgiSurfaceRenderTarget(ID2D1Factory1 *iface, IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1RenderTarget **render_target) { TRACE("iface %p, surface %p, desc %p, render_target %p.\n", iface, surface, desc, render_target);
- return d2d_d3d_create_render_target(iface, surface, NULL, desc, render_target); + return d2d_d3d_create_render_target((ID2D1Factory *)iface, surface, NULL, desc, render_target); }
-static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDCRenderTarget(ID2D1Factory *iface, +static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDCRenderTarget(ID2D1Factory1 *iface, const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1DCRenderTarget **render_target) { struct d2d_factory *factory = impl_from_ID2D1Factory(iface); @@ -352,7 +353,7 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDCRenderTarget(ID2D1Factory * if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) return E_OUTOFMEMORY;
- if (FAILED(hr = d2d_dc_render_target_init(object, iface, device, desc))) + if (FAILED(hr = d2d_dc_render_target_init(object, (ID2D1Factory *)iface, device, desc))) { WARN("Failed to initialize render target, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); @@ -365,7 +366,116 @@ static HRESULT STDMETHODCALLTYPE d2d_factory_CreateDCRenderTarget(ID2D1Factory * return S_OK; }
-static const struct ID2D1FactoryVtbl d2d_factory_vtbl = +static HRESULT WINAPI d2d_factory1_CreateDevice( + ID2D1Factory1 *iface, + IDXGIDevice *dxgiDevice, + ID2D1Device **d2dDevice) +{ + struct d2d_factory *This = impl_from_ID2D1Factory(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_factory1_CreateStrokeStyle( + ID2D1Factory1 *iface, + const D2D1_STROKE_STYLE_PROPERTIES1 *strokeStyleProperties, + const float *dashes, + UINT dashesCount, + const ID2D1StrokeStyle1 **strokeStyle) +{ + struct d2d_factory *This = impl_from_ID2D1Factory(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_factory1_CreatePathGeometry( + ID2D1Factory1 *iface, + ID2D1PathGeometry1 **pathGeometry) +{ + struct d2d_factory *This = impl_from_ID2D1Factory(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_factory1_CreateDrawingStateBlock( + ID2D1Factory1 *iface, + const D2D1_DRAWING_STATE_DESCRIPTION1 *drawingStateDescription, + IDWriteRenderingParams *textRenderingParams, + ID2D1DrawingStateBlock1 **drawingStateBlock) +{ + struct d2d_factory *This = impl_from_ID2D1Factory(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_factory1_CreateGdiMetafile( + ID2D1Factory1 *iface, + IStream *metafileStream, + ID2D1GdiMetafile **metafile) +{ + struct d2d_factory *This = impl_from_ID2D1Factory(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_factory1_RegisterEffectFromStream( + ID2D1Factory1 *iface, + REFCLSID classId, + IStream *propertyXml, + const D2D1_PROPERTY_BINDING *Bindings, + UINT32 bindingsCount, + PD2D1_EFFECT_FACTORY effectFactory) +{ + struct d2d_factory *This = impl_from_ID2D1Factory(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_factory1_RegisterEffectFromString( + ID2D1Factory1 *iface, + REFCLSID classId, + PCWSTR propertyXml, + const D2D1_PROPERTY_BINDING *Bindings, + UINT32 bindingsCount, + PD2D1_EFFECT_FACTORY effectFactory) +{ + struct d2d_factory *This = impl_from_ID2D1Factory(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_factory1_UnregisterEffect( + ID2D1Factory1 *iface, + REFCLSID classId) +{ + struct d2d_factory *This = impl_from_ID2D1Factory(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_factory1_GetRegisteredEffects( + ID2D1Factory1 *iface, + CLSID *effects, + UINT32 effectCount, + UINT32 *effectsReturned, + UINT32 *effectsRegistered) +{ + struct d2d_factory *This = impl_from_ID2D1Factory(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_factory1_GetEffectProperties( + ID2D1Factory1 *iface, + REFCLSID effectId, + ID2D1Properties **props) +{ + struct d2d_factory *This = impl_from_ID2D1Factory(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static const struct ID2D1Factory1Vtbl d2d_factory_vtbl = { d2d_factory_QueryInterface, d2d_factory_AddRef, @@ -384,6 +494,16 @@ static const struct ID2D1FactoryVtbl d2d_factory_vtbl = d2d_factory_CreateHwndRenderTarget, d2d_factory_CreateDxgiSurfaceRenderTarget, d2d_factory_CreateDCRenderTarget, + d2d_factory1_CreateDevice, + d2d_factory1_CreateStrokeStyle, + d2d_factory1_CreatePathGeometry, + d2d_factory1_CreateDrawingStateBlock, + d2d_factory1_CreateGdiMetafile, + d2d_factory1_RegisterEffectFromStream, + d2d_factory1_RegisterEffectFromString, + d2d_factory1_UnregisterEffect, + d2d_factory1_GetRegisteredEffects, + d2d_factory1_GetEffectProperties, };
static void d2d_factory_init(struct d2d_factory *factory, D2D1_FACTORY_TYPE factory_type, @@ -394,7 +514,7 @@ static void d2d_factory_init(struct d2d_factory *factory, D2D1_FACTORY_TYPE fact if (factory_options && factory_options->debugLevel != D2D1_DEBUG_LEVEL_NONE) WARN("Ignoring debug level %#x.\n", factory_options->debugLevel);
- factory->ID2D1Factory_iface.lpVtbl = &d2d_factory_vtbl; + factory->ID2D1Factory1_iface.lpVtbl = &d2d_factory_vtbl; factory->refcount = 1; d2d_factory_reload_sysmetrics(factory); } @@ -415,8 +535,8 @@ HRESULT WINAPI D2D1CreateFactory(D2D1_FACTORY_TYPE factory_type, REFIID iid,
TRACE("Created factory %p.\n", object);
- hr = ID2D1Factory_QueryInterface(&object->ID2D1Factory_iface, iid, factory); - ID2D1Factory_Release(&object->ID2D1Factory_iface); + hr = ID2D1Factory1_QueryInterface(&object->ID2D1Factory1_iface, iid, factory); + ID2D1Factory1_Release(&object->ID2D1Factory1_iface);
return hr; } diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c index ab5a0b5929..642cfb4a28 100644 --- a/dlls/d2d1/geometry.c +++ b/dlls/d2d1/geometry.c @@ -2375,15 +2375,15 @@ static void d2d_geometry_cleanup(struct d2d_geometry *geometry) HeapFree(GetProcessHeap(), 0, geometry->fill.bezier_vertices); HeapFree(GetProcessHeap(), 0, geometry->fill.faces); HeapFree(GetProcessHeap(), 0, geometry->fill.vertices); - ID2D1Factory_Release(geometry->factory); + ID2D1Factory1_Release(geometry->factory); }
-static void d2d_geometry_init(struct d2d_geometry *geometry, ID2D1Factory *factory, +static void d2d_geometry_init(struct d2d_geometry *geometry, ID2D1Factory1 *factory, const D2D1_MATRIX_3X2_F *transform, const struct ID2D1GeometryVtbl *vtbl) { geometry->ID2D1Geometry_iface.lpVtbl = vtbl; geometry->refcount = 1; - ID2D1Factory_AddRef(geometry->factory = factory); + ID2D1Factory1_AddRef(geometry->factory = factory); geometry->transform = *transform; }
@@ -3072,10 +3072,14 @@ static ULONG STDMETHODCALLTYPE d2d_path_geometry_Release(ID2D1PathGeometry *ifac static void STDMETHODCALLTYPE d2d_path_geometry_GetFactory(ID2D1PathGeometry *iface, ID2D1Factory **factory) { struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry(iface); + HRESULT hr;
TRACE("iface %p, factory %p.\n", iface, factory);
- ID2D1Factory_AddRef(*factory = geometry->factory); + if (FAILED(hr = ID2D1Factory1_QueryInterface(geometry->factory, &IID_ID2D1Factory, (void **)factory))) + { + WARN("Unable to query ID2D1Factory interface %#x", hr); + } }
static HRESULT STDMETHODCALLTYPE d2d_path_geometry_GetBounds(ID2D1PathGeometry *iface, @@ -3523,7 +3527,7 @@ static const struct ID2D1PathGeometryVtbl d2d_path_geometry_vtbl = d2d_path_geometry_GetFigureCount, };
-void d2d_path_geometry_init(struct d2d_geometry *geometry, ID2D1Factory *factory) +void d2d_path_geometry_init(struct d2d_geometry *geometry, ID2D1Factory1 *factory) { d2d_geometry_init(geometry, factory, &identity, (ID2D1GeometryVtbl *)&d2d_path_geometry_vtbl); geometry->u.path.ID2D1GeometrySink_iface.lpVtbl = &d2d_geometry_sink_vtbl; @@ -3588,10 +3592,14 @@ static ULONG STDMETHODCALLTYPE d2d_rectangle_geometry_Release(ID2D1RectangleGeom static void STDMETHODCALLTYPE d2d_rectangle_geometry_GetFactory(ID2D1RectangleGeometry *iface, ID2D1Factory **factory) { struct d2d_geometry *geometry = impl_from_ID2D1RectangleGeometry(iface); + HRESULT hr;
TRACE("iface %p, factory %p.\n", iface, factory);
- ID2D1Factory_AddRef(*factory = geometry->factory); + if (FAILED(hr = ID2D1Factory1_QueryInterface(geometry->factory, &IID_ID2D1Factory, (void **)factory))) + { + WARN("Unable to query ID2D1Factory interface %#x", hr); + } }
static HRESULT STDMETHODCALLTYPE d2d_rectangle_geometry_GetBounds(ID2D1RectangleGeometry *iface, @@ -3812,7 +3820,7 @@ static const struct ID2D1RectangleGeometryVtbl d2d_rectangle_geometry_vtbl = d2d_rectangle_geometry_GetRect, };
-HRESULT d2d_rectangle_geometry_init(struct d2d_geometry *geometry, ID2D1Factory *factory, const D2D1_RECT_F *rect) +HRESULT d2d_rectangle_geometry_init(struct d2d_geometry *geometry, ID2D1Factory1 *factory, const D2D1_RECT_F *rect) { struct d2d_face *f; D2D1_POINT_2F *v; @@ -3933,10 +3941,14 @@ static void STDMETHODCALLTYPE d2d_transformed_geometry_GetFactory(ID2D1Transform ID2D1Factory **factory) { struct d2d_geometry *geometry = impl_from_ID2D1TransformedGeometry(iface); + HRESULT hr;
TRACE("iface %p, factory %p.\n", iface, factory);
- ID2D1Factory_AddRef(*factory = geometry->factory); + if (FAILED(hr = ID2D1Factory1_QueryInterface(geometry->factory, &IID_ID2D1Factory, (void **)factory))) + { + WARN("Unable to query ID2D1Factory interface %#x", hr); + } }
static HRESULT STDMETHODCALLTYPE d2d_transformed_geometry_GetBounds(ID2D1TransformedGeometry *iface, @@ -4130,7 +4142,7 @@ static const struct ID2D1TransformedGeometryVtbl d2d_transformed_geometry_vtbl = d2d_transformed_geometry_GetTransform, };
-void d2d_transformed_geometry_init(struct d2d_geometry *geometry, ID2D1Factory *factory, +void d2d_transformed_geometry_init(struct d2d_geometry *geometry, ID2D1Factory1 *factory, ID2D1Geometry *src_geometry, const D2D_MATRIX_3X2_F *transform) { struct d2d_geometry *src_impl;
https://bugs.winehq.org/show_bug.cgi?id=44052
Signed-off-by: Lucian Poston lucian.poston@gmail.com ---
Changes since v1, * Squashed stub and implementation patches together into one commit. * Removed NULL checks as requested in v1 review. * Renamed several identifiers as requested in v1 review.
dlls/d2d1/Makefile.in | 1 + dlls/d2d1/d2d1_private.h | 10 +++ dlls/d2d1/device.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++ dlls/d2d1/factory.c | 13 +++- dlls/d2d1/tests/d2d1.c | 1 - 5 files changed, 181 insertions(+), 3 deletions(-) create mode 100644 dlls/d2d1/device.c
diff --git a/dlls/d2d1/Makefile.in b/dlls/d2d1/Makefile.in index 51b9627047..88bdab98dc 100644 --- a/dlls/d2d1/Makefile.in +++ b/dlls/d2d1/Makefile.in @@ -8,6 +8,7 @@ C_SRCS = \ bitmap_render_target.c \ brush.c \ dc_render_target.c \ + device.c \ factory.c \ geometry.c \ hwnd_render_target.c \ diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index c39a23bed8..be239f12be 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -534,4 +534,14 @@ static inline const char *debug_d2d_rect_f(const D2D1_RECT_F *rect) return wine_dbg_sprintf("(%.8e,%.8e)-(%.8e,%.8e)", rect->left, rect->top, rect->right, rect->bottom ); }
+struct d2d_device +{ + ID2D1Device ID2D1Device_iface; + LONG refcount; + ID2D1Factory1 *factory; + IDXGIDevice *dxgi_device; +}; + +void d2d_device_init(struct d2d_device *This, ID2D1Factory1 *iface, IDXGIDevice *dxgiDevice) DECLSPEC_HIDDEN; + #endif /* __WINE_D2D1_PRIVATE_H */ diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c new file mode 100644 index 0000000000..c597362b79 --- /dev/null +++ b/dlls/d2d1/device.c @@ -0,0 +1,159 @@ +/* + * Copyright 2017 Wine Project + * + * 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" + +WINE_DEFAULT_DEBUG_CHANNEL(d2d); + +static inline struct d2d_device *impl_from_ID2D1Device(ID2D1Device *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_device, ID2D1Device_iface); +} + +static HRESULT WINAPI d2d_device_QueryInterface( + ID2D1Device *iface, + REFIID riid, + void **ppvObject) +{ + TRACE("iface %p, riid %s, ppvObject %p.\n", iface, debugstr_guid(riid), ppvObject); + if (ppvObject == NULL) + return E_POINTER; + + if (IsEqualGUID(riid, &IID_ID2D1Device) + || IsEqualGUID(riid, &IID_ID2D1Resource) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID2D1Device_AddRef(iface); + *ppvObject = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + *ppvObject = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI d2d_device_AddRef( + ID2D1Device *iface) +{ + struct d2d_device *This = impl_from_ID2D1Device(iface); + ULONG refcount = InterlockedIncrement(&This->refcount); + TRACE("%p increasing refcount to %u.\n", iface, refcount); + return refcount; +} + +static ULONG WINAPI d2d_device_Release( + ID2D1Device *iface) +{ + struct d2d_device *This = impl_from_ID2D1Device(iface); + ULONG refcount = InterlockedDecrement(&This->refcount); + TRACE("%p decreasing refcount to %u.\n", iface, refcount); + + if (refcount == 0) + { + IDXGIDevice_Release(This->dxgi_device); + ID2D1Factory1_Release(This->factory); + HeapFree(GetProcessHeap(), 0, This); + } + + return refcount; +} + +static void WINAPI d2d_device_GetFactory( + ID2D1Device *iface, + ID2D1Factory **factory) +{ + struct d2d_device *This = impl_from_ID2D1Device(iface); + + TRACE("iface %p, factory %p.\n", iface, factory); + *factory = (ID2D1Factory *)This->factory; + ID2D1Factory1_AddRef(This->factory); +} + +static HRESULT WINAPI d2d_device_CreateDeviceContext( + ID2D1Device *iface, + D2D1_DEVICE_CONTEXT_OPTIONS options, + ID2D1DeviceContext **deviceContext) +{ + struct d2d_device *This = impl_from_ID2D1Device(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_CreatePrintControl( + ID2D1Device *iface, + IWICImagingFactory *wicFactory, + IPrintDocumentPackageTarget *documentTarget, + const D2D1_PRINT_CONTROL_PROPERTIES *printControlProperties, + ID2D1PrintControl **printControl) +{ + struct d2d_device *This = impl_from_ID2D1Device(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static void WINAPI d2d_device_SetMaximumTextureMemory( + ID2D1Device *iface, + UINT64 maximumInBytes) +{ + struct d2d_device *This = impl_from_ID2D1Device(iface); + FIXME("%p stub!\n", This); +} + +static UINT64 WINAPI d2d_device_GetMaximumTextureMemory( + ID2D1Device *iface) +{ + struct d2d_device *This = impl_from_ID2D1Device(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_ClearResources( + ID2D1Device *iface, + UINT millisecondsSinceUse) +{ + struct d2d_device *This = impl_from_ID2D1Device(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static const struct ID2D1DeviceVtbl d2d_device_vtbl = +{ + d2d_device_QueryInterface, + d2d_device_AddRef, + d2d_device_Release, + d2d_device_GetFactory, + d2d_device_CreateDeviceContext, + d2d_device_CreatePrintControl, + d2d_device_SetMaximumTextureMemory, + d2d_device_GetMaximumTextureMemory, + d2d_device_ClearResources, +}; + +void d2d_device_init(struct d2d_device *device, ID2D1Factory1 *iface, IDXGIDevice *dxgi_device) +{ + device->ID2D1Device_iface.lpVtbl = &d2d_device_vtbl; + device->refcount = 1; + device->factory = iface; + ID2D1Factory1_AddRef(device->factory); + device->dxgi_device = dxgi_device; + IDXGIDevice_AddRef(device->dxgi_device); +} diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c index 9b0bd5bb84..f9d317fcb0 100644 --- a/dlls/d2d1/factory.c +++ b/dlls/d2d1/factory.c @@ -372,8 +372,17 @@ static HRESULT WINAPI d2d_factory1_CreateDevice( ID2D1Device **d2dDevice) { struct d2d_factory *This = impl_from_ID2D1Factory(iface); - FIXME("%p stub!\n", This); - return E_NOTIMPL; + struct d2d_device *object; + + TRACE("This %p, dxgiDevice %p\n", This, dxgiDevice); + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + d2d_device_init(object, iface, dxgiDevice); + *d2dDevice = &object->ID2D1Device_iface; + TRACE("Created device %p.\n", object); + + return S_OK; }
static HRESULT WINAPI d2d_factory1_CreateStrokeStyle( diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 6006ad709d..76b7b5a786 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -4674,7 +4674,6 @@ static void test_draw_via_ID2D1DeviceContext(void) }
hr = ID2D1Factory1_CreateDevice(factory, dxgi_device, &device); - todo_wine ok(SUCCEEDED(hr), "Failed to create device, hr %#x.\n", hr); if (FAILED(hr)) {
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check? Full results can be found at https://testbot.winehq.org/JobDetails.pl?Key=34320
Your paranoid android.
=== build (build) === Make failed
https://bugs.winehq.org/show_bug.cgi?id=44052
Signed-off-by: Lucian Poston lucian.poston@gmail.com ---
Changes since v1, * Changed types of function parameters as result of fixing idl in prior patch.
dlls/d2d1/Makefile.in | 1 + dlls/d2d1/d2d1_private.h | 16 + dlls/d2d1/device.c | 36 +- dlls/d2d1/device_context.c | 1180 ++++++++++++++++++++++++++++++++++++++++++++ dlls/d2d1/render_target.c | 82 ++- dlls/d2d1/tests/d2d1.c | 1 - 6 files changed, 1288 insertions(+), 28 deletions(-) create mode 100644 dlls/d2d1/device_context.c
diff --git a/dlls/d2d1/Makefile.in b/dlls/d2d1/Makefile.in index 88bdab98dc..39753bd384 100644 --- a/dlls/d2d1/Makefile.in +++ b/dlls/d2d1/Makefile.in @@ -9,6 +9,7 @@ C_SRCS = \ brush.c \ dc_render_target.c \ device.c \ + device_context.c \ factory.c \ geometry.c \ hwnd_render_target.c \ diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index be239f12be..dd76a14af4 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -147,6 +147,10 @@ struct d2d_d3d_render_target
HRESULT d2d_d3d_create_render_target(ID2D1Factory *factory, IDXGISurface *surface, IUnknown *outer_unknown, const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1RenderTarget **render_target) DECLSPEC_HIDDEN; +HRESULT d2d_d3d_create_render_target_with_device(ID2D1Factory *factory, + ID3D10Device *device, IUnknown *outer_unknown, + const D2D1_RENDER_TARGET_PROPERTIES *desc, + ID2D1RenderTarget **render_target) DECLSPEC_HIDDEN; HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *render_target, IDXGISurface1 *surface) DECLSPEC_HIDDEN;
struct d2d_wic_render_target @@ -544,4 +548,16 @@ struct d2d_device
void d2d_device_init(struct d2d_device *This, ID2D1Factory1 *iface, IDXGIDevice *dxgiDevice) DECLSPEC_HIDDEN;
+struct d2d_device_context +{ + ID2D1DeviceContext ID2D1DeviceContext_iface; + LONG refcount; + ID2D1Device *device; + ID2D1RenderTarget *dxgi_target; +}; + +HRESULT d2d_device_context_init(struct d2d_device_context *This, + ID2D1Device *device_iface, D2D1_DEVICE_CONTEXT_OPTIONS options, + ID3D10Device *d3d_device) DECLSPEC_HIDDEN; + #endif /* __WINE_D2D1_PRIVATE_H */ diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index c597362b79..9abd28d560 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -94,8 +94,40 @@ static HRESULT WINAPI d2d_device_CreateDeviceContext( ID2D1DeviceContext **deviceContext) { struct d2d_device *This = impl_from_ID2D1Device(iface); - FIXME("%p stub!\n", This); - return E_NOTIMPL; + struct d2d_device_context *object; + ID3D10Device *d3d_device; + HRESULT hr; + + TRACE("This %p, options %#x\n", This, options); + if (deviceContext == NULL) + return E_POINTER; + + if (FAILED(hr = IDXGIDevice_QueryInterface(This->dxgi_device, + &IID_ID3D10Device, (void **)&d3d_device))) + { + WARN("Failed to query d3d device, hr %#x.\n", hr); + return hr; + } + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + { + ID3D10Device_Release(d3d_device); + return E_OUTOFMEMORY; + } + + hr = d2d_device_context_init(object, iface, options, d3d_device); + ID3D10Device_Release(d3d_device); + if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, object); + WARN("Failed to create device context, hr %#x.\n", hr); + return hr; + } + + *deviceContext = &object->ID2D1DeviceContext_iface; + TRACE("Created device context %p.\n", object); + + return S_OK; }
static HRESULT WINAPI d2d_device_CreatePrintControl( diff --git a/dlls/d2d1/device_context.c b/dlls/d2d1/device_context.c new file mode 100644 index 0000000000..30657e260d --- /dev/null +++ b/dlls/d2d1/device_context.c @@ -0,0 +1,1180 @@ +/* + * Copyright 2017 Wine Project + * + * 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" + +WINE_DEFAULT_DEBUG_CHANNEL(d2d); + +static inline struct d2d_device_context *impl_from_ID2D1DeviceContext(ID2D1DeviceContext *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_device_context, ID2D1DeviceContext_iface); +} + +static HRESULT WINAPI d2d_device_context_QueryInterface( + ID2D1DeviceContext *iface, + REFIID riid, + void **ppvObject) +{ + TRACE("iface %p, riid %s, ppvObject %p.\n", iface, debugstr_guid(riid), ppvObject); + if (ppvObject == NULL) + return E_POINTER; + + if (IsEqualGUID(riid, &IID_ID2D1DeviceContext) + || IsEqualGUID(riid, &IID_ID2D1RenderTarget) + || IsEqualGUID(riid, &IID_ID2D1Resource) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID2D1DeviceContext_AddRef(iface); + *ppvObject = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + *ppvObject = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI d2d_device_context_AddRef( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + ULONG refcount = InterlockedIncrement(&This->refcount); + TRACE("%p increasing refcount to %u.\n", iface, refcount); + return refcount; +} + +static ULONG WINAPI d2d_device_context_Release( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + ULONG refcount = InterlockedDecrement(&This->refcount); + TRACE("%p decreasing refcount to %u.\n", iface, refcount); + + if (refcount == 0) + { + ID2D1RenderTarget_Release(This->dxgi_target); + ID2D1Device_Release(This->device); + HeapFree(GetProcessHeap(), 0, This); + } + + return refcount; +} + +static void WINAPI d2d_device_context_GetFactory( + ID2D1DeviceContext *iface, + ID2D1Factory **factory) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, factory %p.\n", This, factory); + ID2D1Device_GetFactory(This->device, factory); +} + +static HRESULT WINAPI d2d_device_context_CreateBitmap( + ID2D1DeviceContext *iface, + D2D1_SIZE_U size, + const void *src_data, + UINT32 pitch, + const D2D1_BITMAP_PROPERTIES *desc, + ID2D1Bitmap **bitmap) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, src_data %p, desc %p, bitmap %p.\n", This, src_data, desc, bitmap); + return ID2D1RenderTarget_CreateBitmap(This->dxgi_target, size, src_data, pitch, desc, bitmap); +} + +static HRESULT WINAPI d2d_device_context_CreateBitmapFromWicBitmap( + ID2D1DeviceContext *iface, + IWICBitmapSource *bitmap_source, + const D2D1_BITMAP_PROPERTIES *desc, + ID2D1Bitmap **bitmap) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, bitmap_source %p, desc %p, bitmap %p.\n", + This, bitmap_source, desc, bitmap); + return ID2D1RenderTarget_CreateBitmapFromWicBitmap(This->dxgi_target, bitmap_source, desc, bitmap); +} + +static HRESULT WINAPI d2d_device_context_CreateSharedBitmap( + ID2D1DeviceContext *iface, + REFIID iid, + void *data, + const D2D1_BITMAP_PROPERTIES *desc, + ID2D1Bitmap **bitmap) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, iid %s, data %p, desc %p, bitmap %p.\n", + This, debugstr_guid(iid), data, desc, bitmap); + return ID2D1RenderTarget_CreateSharedBitmap(This->dxgi_target, iid, data, desc, bitmap); +} + +static HRESULT WINAPI d2d_device_context_CreateBitmapBrush( + ID2D1DeviceContext *iface, + ID2D1Bitmap *bitmap, + const D2D1_BITMAP_BRUSH_PROPERTIES *bitmap_brush_desc, + const D2D1_BRUSH_PROPERTIES *brush_desc, + ID2D1BitmapBrush **brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, bitmap %p, bitmap_brush_desc %p, brush_desc %p, brush %p.\n", + This, bitmap, bitmap_brush_desc, brush_desc, brush); + return ID2D1RenderTarget_CreateBitmapBrush(This->dxgi_target, + bitmap, bitmap_brush_desc, brush_desc, brush); +} + +static HRESULT WINAPI d2d_device_context_CreateSolidColorBrush( + ID2D1DeviceContext *iface, + const D2D1_COLOR_F *color, + const D2D1_BRUSH_PROPERTIES *desc, + ID2D1SolidColorBrush **brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, color %p, desc %p, brush %p.\n", This, color, desc, brush); + return ID2D1RenderTarget_CreateSolidColorBrush(This->dxgi_target, color, desc, brush); +} + +static HRESULT WINAPI d2d_device_context_CreateGradientStopCollection( + ID2D1DeviceContext *iface, + const D2D1_GRADIENT_STOP *stops, + UINT32 stop_count, + D2D1_GAMMA gamma, + D2D1_EXTEND_MODE extend_mode, + ID2D1GradientStopCollection **gradient) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, stops %p, gradient %p.\n", This, stops, gradient); + return ID2D1RenderTarget_CreateGradientStopCollection(This->dxgi_target, + stops, stop_count, gamma, extend_mode, gradient); +} + +static HRESULT WINAPI d2d_device_context_CreateLinearGradientBrush( + ID2D1DeviceContext *iface, + const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, + const D2D1_BRUSH_PROPERTIES *brush_desc, + ID2D1GradientStopCollection *gradient, + ID2D1LinearGradientBrush **brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n", + This, gradient_brush_desc, brush_desc, gradient, brush); + return ID2D1RenderTarget_CreateLinearGradientBrush(This->dxgi_target, + gradient_brush_desc, brush_desc, gradient, brush); +} + +static HRESULT WINAPI d2d_device_context_CreateRadialGradientBrush( + ID2D1DeviceContext *iface, + const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, + const D2D1_BRUSH_PROPERTIES *brush_desc, + ID2D1GradientStopCollection *gradient, + ID2D1RadialGradientBrush **brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n", + This, gradient_brush_desc, brush_desc, gradient, brush); + return ID2D1RenderTarget_CreateRadialGradientBrush(This->dxgi_target, + gradient_brush_desc, brush_desc, gradient, brush); +} + +static HRESULT WINAPI d2d_device_context_CreateCompatibleRenderTarget( + ID2D1DeviceContext *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) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, size %p, pixel_size %p, format %p, render_target %p.\n", + This, size, pixel_size, format, render_target); + return ID2D1RenderTarget_CreateCompatibleRenderTarget(This->dxgi_target, + size, pixel_size, format, options, render_target); +} + +static HRESULT WINAPI d2d_device_context_CreateLayer( + ID2D1DeviceContext *iface, + const D2D1_SIZE_F *size, + ID2D1Layer **layer) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, size %p, layer %p.\n", This, size, layer); + return ID2D1RenderTarget_CreateLayer(This->dxgi_target, size, layer); +} + +static HRESULT WINAPI d2d_device_context_CreateMesh( + ID2D1DeviceContext *iface, + ID2D1Mesh **mesh) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, mesh %p.\n", This, mesh); + return ID2D1RenderTarget_CreateMesh(This->dxgi_target, mesh); +} + +static void WINAPI d2d_device_context_DrawLine( + ID2D1DeviceContext *iface, + D2D1_POINT_2F p0, + D2D1_POINT_2F p1, + ID2D1Brush *brush, + float stroke_width, + ID2D1StrokeStyle *stroke_style) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, brush %p, stroke_style %p.\n", This, brush, stroke_style); + ID2D1RenderTarget_DrawLine(This->dxgi_target, p0, p1, brush, stroke_width, stroke_style); +} + +static void WINAPI d2d_device_context_DrawRectangle( + ID2D1DeviceContext *iface, + const D2D1_RECT_F *rect, + ID2D1Brush *brush, + float stroke_width, + ID2D1StrokeStyle *stroke_style) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, rect %p, brush %p, stroke_style %p.\n", This, rect, brush, stroke_style); + ID2D1RenderTarget_DrawRectangle(This->dxgi_target, rect, brush, stroke_width, stroke_style); +} + +static void WINAPI d2d_device_context_FillRectangle( + ID2D1DeviceContext *iface, + const D2D1_RECT_F *rect, + ID2D1Brush *brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, rect %p, brush %p.\n", This, rect, brush); + ID2D1RenderTarget_FillRectangle(This->dxgi_target, rect, brush); +} + +static void WINAPI d2d_device_context_DrawRoundedRectangle( + ID2D1DeviceContext *iface, + const D2D1_ROUNDED_RECT *rect, + ID2D1Brush *brush, + float stroke_width, + ID2D1StrokeStyle *stroke_style) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, rect %p, brush %p, stroke_style %p.\n", This, rect, brush, stroke_style); + ID2D1RenderTarget_DrawRoundedRectangle(This->dxgi_target, rect, brush, stroke_width, stroke_style); +} + +static void WINAPI d2d_device_context_FillRoundedRectangle( + ID2D1DeviceContext *iface, + const D2D1_ROUNDED_RECT *rect, + ID2D1Brush *brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, rect %p, brush %p.\n", This, rect, brush); + ID2D1RenderTarget_FillRoundedRectangle(This->dxgi_target, rect, brush); +} + +static void WINAPI d2d_device_context_DrawEllipse( + ID2D1DeviceContext *iface, + const D2D1_ELLIPSE *ellipse, + ID2D1Brush *brush, + float stroke_width, + ID2D1StrokeStyle *stroke_style) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, ellipse %p, brush %p, stroke_style %p.\n", This, ellipse, brush, stroke_style); + ID2D1RenderTarget_DrawEllipse(This->dxgi_target, ellipse, brush, stroke_width, stroke_style); +} + +static void WINAPI d2d_device_context_FillEllipse( + ID2D1DeviceContext *iface, + const D2D1_ELLIPSE *ellipse, + ID2D1Brush *brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, ellipse %p, brush %p.\n", This, ellipse, brush); + ID2D1RenderTarget_FillEllipse(This->dxgi_target, ellipse, brush); +} + +static void WINAPI d2d_device_context_DrawGeometry( + ID2D1DeviceContext *iface, + ID2D1Geometry *geometry, + ID2D1Brush *brush, + float stroke_width, + ID2D1StrokeStyle *stroke_style) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, geometry %p, brush %p, stroke_style %p.\n", This, geometry, brush, stroke_style); + ID2D1RenderTarget_DrawGeometry(This->dxgi_target, geometry, brush, stroke_width, stroke_style); +} + +static void WINAPI d2d_device_context_FillGeometry( + ID2D1DeviceContext *iface, + ID2D1Geometry *geometry, + ID2D1Brush *brush, + ID2D1Brush *opacity_brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, geometry %p, brush %p, opacity_brush %p.\n", This, geometry, brush, opacity_brush); + ID2D1RenderTarget_FillGeometry(This->dxgi_target, geometry, brush, opacity_brush); +} + +static void WINAPI d2d_device_context_FillMesh( + ID2D1DeviceContext *iface, + ID2D1Mesh *mesh, + ID2D1Brush *brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, mesh %p, brush %p.\n", This, mesh, brush); + ID2D1RenderTarget_FillMesh(This->dxgi_target, mesh, brush); +} + +static void WINAPI d2d_device_context_FillOpacityMask( + ID2D1DeviceContext *iface, + ID2D1Bitmap *mask, + ID2D1Brush *brush, + D2D1_OPACITY_MASK_CONTENT content, + const D2D1_RECT_F *dst_rect, + const D2D1_RECT_F *src_rect) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, mask %p, brush %p.\n", This, mask, brush); + ID2D1RenderTarget_FillOpacityMask(This->dxgi_target, + mask, brush, content, dst_rect, src_rect); +} + +static void WINAPI d2d_device_context_DrawBitmap( + ID2D1DeviceContext *iface, + ID2D1Bitmap *bitmap, + const D2D1_RECT_F *dst_rect, + float opacity, + D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode, + const D2D1_RECT_F *src_rect) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, bitmap %p.\n", This, bitmap); + ID2D1RenderTarget_DrawBitmap(This->dxgi_target, + bitmap, dst_rect, opacity, interpolation_mode, src_rect); +} + +static void WINAPI d2d_device_context_DrawText( + ID2D1DeviceContext *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) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, string %s.\n", This, debugstr_w(string)); + ID2D1RenderTarget_DrawText(This->dxgi_target, string, string_len, + text_format, layout_rect, brush, options, measuring_mode); +} + +static void WINAPI d2d_device_context_DrawTextLayout( + ID2D1DeviceContext *iface, + D2D1_POINT_2F origin, + IDWriteTextLayout *layout, + ID2D1Brush *brush, + D2D1_DRAW_TEXT_OPTIONS options) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, layout %p, brush %p.\n", This, layout, brush); + ID2D1RenderTarget_DrawTextLayout(This->dxgi_target, origin, layout, brush, options); +} + +static void WINAPI d2d_device_context_DrawGlyphRun( + ID2D1DeviceContext *iface, + D2D1_POINT_2F baseline_origin, + const DWRITE_GLYPH_RUN *glyph_run, + ID2D1Brush *brush, + DWRITE_MEASURING_MODE measuring_mode) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, glyph_run %p, brush %p.\n", This, glyph_run, brush); + ID2D1RenderTarget_DrawGlyphRun(This->dxgi_target, + baseline_origin, glyph_run, brush, measuring_mode); +} + +static void WINAPI d2d_device_context_SetTransform( + ID2D1DeviceContext *iface, + const D2D1_MATRIX_3X2_F *transform) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, transform %p.\n", This, transform); + ID2D1RenderTarget_SetTransform(This->dxgi_target, transform); +} + +static void WINAPI d2d_device_context_GetTransform( + ID2D1DeviceContext *iface, + D2D1_MATRIX_3X2_F *transform) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, transform %p.\n", This, transform); + ID2D1RenderTarget_GetTransform(This->dxgi_target, transform); +} + +static void WINAPI d2d_device_context_SetAntialiasMode( + ID2D1DeviceContext *iface, + D2D1_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_SetAntialiasMode(This->dxgi_target, antialias_mode); +} + +static D2D1_ANTIALIAS_MODE WINAPI d2d_device_context_GetAntialiasMode( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + return ID2D1RenderTarget_GetAntialiasMode(This->dxgi_target); +} + +static void WINAPI d2d_device_context_SetTextAntialiasMode( + ID2D1DeviceContext *iface, + D2D1_TEXT_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_SetTextAntialiasMode(This->dxgi_target, antialias_mode); +} + +static D2D1_TEXT_ANTIALIAS_MODE WINAPI d2d_device_context_GetTextAntialiasMode( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + return ID2D1RenderTarget_GetTextAntialiasMode(This->dxgi_target); +} + +static void WINAPI d2d_device_context_SetTextRenderingParams( + ID2D1DeviceContext *iface, + IDWriteRenderingParams *text_rendering_params) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_SetTextRenderingParams(This->dxgi_target, text_rendering_params); +} + +static void WINAPI d2d_device_context_GetTextRenderingParams( + ID2D1DeviceContext *iface, + IDWriteRenderingParams **text_rendering_params) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_GetTextRenderingParams(This->dxgi_target, text_rendering_params); +} + +static void WINAPI d2d_device_context_SetTags( + ID2D1DeviceContext *iface, + D2D1_TAG tag1, + D2D1_TAG tag2) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_SetTags(This->dxgi_target, tag1, tag2); +} + +static void WINAPI d2d_device_context_GetTags( + ID2D1DeviceContext *iface, + D2D1_TAG *tag1, + D2D1_TAG *tag2) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_GetTags(This->dxgi_target, tag1, tag2); +} + +static void WINAPI d2d_device_context_PushLayer( + ID2D1DeviceContext *iface, + const D2D1_LAYER_PARAMETERS *layer_parameters, + ID2D1Layer *layer) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_PushLayer(This->dxgi_target, layer_parameters, layer); +} + +static void WINAPI d2d_device_context_PopLayer( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_PopLayer(This->dxgi_target); +} + +static HRESULT WINAPI d2d_device_context_Flush( + ID2D1DeviceContext *iface, + D2D1_TAG *tag1, + D2D1_TAG *tag2) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + return ID2D1RenderTarget_Flush(This->dxgi_target, tag1, tag2); +} + +static void WINAPI d2d_device_context_SaveDrawingState( + ID2D1DeviceContext *iface, + ID2D1DrawingStateBlock *state_block) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, state_block %p.\n", This, state_block); + ID2D1RenderTarget_SaveDrawingState(This->dxgi_target, state_block); +} + +static void WINAPI d2d_device_context_RestoreDrawingState( + ID2D1DeviceContext *iface, + ID2D1DrawingStateBlock *state_block) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, state_block %p.\n", This, state_block); + ID2D1RenderTarget_RestoreDrawingState(This->dxgi_target, state_block); +} + +static void WINAPI d2d_device_context_PushAxisAlignedClip( + ID2D1DeviceContext *iface, + const D2D1_RECT_F *clip_rect, + D2D1_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_PushAxisAlignedClip(This->dxgi_target, clip_rect, antialias_mode); +} + +static void WINAPI d2d_device_context_PopAxisAlignedClip( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_PopAxisAlignedClip(This->dxgi_target); +} + +static void WINAPI d2d_device_context_Clear( + ID2D1DeviceContext *iface, + const D2D1_COLOR_F *color) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_Clear(This->dxgi_target, color); +} + +static void WINAPI d2d_device_context_BeginDraw( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_BeginDraw(This->dxgi_target); +} + +static HRESULT WINAPI d2d_device_context_EndDraw( + ID2D1DeviceContext *iface, + D2D1_TAG *tag1, + D2D1_TAG *tag2) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + return ID2D1RenderTarget_EndDraw(This->dxgi_target, tag1, tag2); +} + +static D2D1_PIXEL_FORMAT * WINAPI d2d_device_context_GetPixelFormat( + ID2D1DeviceContext *iface, + D2D1_PIXEL_FORMAT *__ret) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, __ret %p.\n", This, __ret); + *__ret = ID2D1RenderTarget_GetPixelFormat(This->dxgi_target); + return __ret; +} + +static void WINAPI d2d_device_context_SetDpi( + ID2D1DeviceContext *iface, + float dpi_x, + float dpi_y) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_SetDpi(This->dxgi_target, dpi_x, dpi_y); +} + +static void WINAPI d2d_device_context_GetDpi( + ID2D1DeviceContext *iface, + float *dpi_x, + float *dpi_y) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_GetDpi(This->dxgi_target, dpi_x, dpi_y); +} + +static D2D1_SIZE_F * WINAPI d2d_device_context_GetSize( + ID2D1DeviceContext *iface, + D2D1_SIZE_F *__ret) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, __ret %p.\n", This, __ret); + *__ret = ID2D1RenderTarget_GetSize(This->dxgi_target); + return __ret; +} + +static D2D1_SIZE_U * WINAPI d2d_device_context_GetPixelSize( + ID2D1DeviceContext *iface, + D2D1_SIZE_U *__ret) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, __ret %p.\n", This, __ret); + *__ret = ID2D1RenderTarget_GetPixelSize(This->dxgi_target); + return __ret; +} + +static UINT32 WINAPI d2d_device_context_GetMaximumBitmapSize( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + return ID2D1RenderTarget_GetMaximumBitmapSize(This->dxgi_target); +} + +static BOOL WINAPI d2d_device_context_IsSupported( + ID2D1DeviceContext *iface, + const D2D1_RENDER_TARGET_PROPERTIES *desc) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + return ID2D1RenderTarget_IsSupported(This->dxgi_target, desc); +} + +static HRESULT WINAPI d2d_device_context_ID2D1DeviceContext_CreateBitmap( + ID2D1DeviceContext *iface, + D2D1_SIZE_U size, + const void *srcData, + UINT32 pitch, + const D2D1_BITMAP_PROPERTIES1 *bitmapProperties, + ID2D1Bitmap1 **bitmap) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_ID2D1DeviceContext_CreateBitmapFromWicBitmap( + ID2D1DeviceContext *iface, + IWICBitmapSource *wicBitmapSource, + const D2D1_BITMAP_PROPERTIES1 *bitmapProperties, + ID2D1Bitmap1 **bitmap) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_CreateColorContext( + ID2D1DeviceContext *iface, + D2D1_COLOR_SPACE space, + const BYTE *Profile, + UINT32 profileSize, + ID2D1ColorContext **colorContext) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_CreateColorContextFromFilename( + ID2D1DeviceContext *iface, + PCWSTR Filename, + ID2D1ColorContext **colorContext) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_CreateColorContextFromWicColorContext( + ID2D1DeviceContext *iface, + IWICColorContext *wicColorContext, + ID2D1ColorContext **colorContext) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_CreateBitmapFromDxgiSurface( + ID2D1DeviceContext *iface, + IDXGISurface *surface, + const D2D1_BITMAP_PROPERTIES1 *bitmapProperties, + ID2D1Bitmap1 **bitmap) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_CreateEffect( + ID2D1DeviceContext *iface, + REFCLSID effectId, + ID2D1Effect **effect) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_ID2D1DeviceContext_CreateGradientStopCollection( + ID2D1DeviceContext *iface, + const D2D1_GRADIENT_STOP *gradientStops, + UINT gradientStopsCount, + D2D1_COLOR_SPACE preInterpolationSpace, + D2D1_COLOR_SPACE postInterpolationSpace, + D2D1_BUFFER_PRECISION bufferPrecision, + D2D1_EXTEND_MODE extendMode, + D2D1_COLOR_INTERPOLATION_MODE colorInterpolationMode, + ID2D1GradientStopCollection1 **gradientStopCollection) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_CreateImageBrush( + ID2D1DeviceContext *iface, + ID2D1Image *image, + const D2D1_IMAGE_BRUSH_PROPERTIES *imageBrushProperties, + const D2D1_BRUSH_PROPERTIES *brushProperties, + ID2D1ImageBrush **imageBrush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_ID2D1DeviceContext_CreateBitmapBrush( + ID2D1DeviceContext *iface, + ID2D1Bitmap *bitmap, + const D2D1_BITMAP_BRUSH_PROPERTIES1 *bitmapBrushProperties, + const D2D1_BRUSH_PROPERTIES *brushProperties, + ID2D1BitmapBrush1 **bitmapBrush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_CreateCommandList( + ID2D1DeviceContext *iface, + ID2D1CommandList **commandList) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static BOOL WINAPI d2d_device_context_IsDxgiFormatSupported( + ID2D1DeviceContext *iface, + DXGI_FORMAT format) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return FALSE; +} + +static BOOL WINAPI d2d_device_context_IsBufferPrecisionSupported( + ID2D1DeviceContext *iface, + D2D1_BUFFER_PRECISION bufferPrecision) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return FALSE; +} + +static void WINAPI d2d_device_context_GetImageLocalBounds( + ID2D1DeviceContext *iface, + ID2D1Image *image, + D2D1_RECT_F *localBounds) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static HRESULT WINAPI d2d_device_context_GetImageWorldBounds( + ID2D1DeviceContext *iface, + ID2D1Image *image, + D2D1_RECT_F *worldBounds) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_GetGlyphRunWorldBounds( + ID2D1DeviceContext *iface, + D2D1_POINT_2F baselineOrigin, + const DWRITE_GLYPH_RUN *glyphRun, + DWRITE_MEASURING_MODE measuringMode, + D2D1_RECT_F *bounds) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static void WINAPI d2d_device_context_GetDevice( + ID2D1DeviceContext *iface, + ID2D1Device **device) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, device %p.\n", This, device); + if (device == NULL) + return; + + ID2D1Device_AddRef(This->device); + *device = This->device; +} + +static void WINAPI d2d_device_context_SetTarget( + ID2D1DeviceContext *iface, + ID2D1Image *target) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + IDXGISurface *surface; + IDXGISurface1 *surface1; + ID2D1Bitmap1 *bitmap; + HRESULT hr; + + TRACE("This %p, target %p.\n", This, target); + if (FAILED(hr = ID2D1Image_QueryInterface(target, &IID_ID2D1Bitmap1, (void **)&bitmap))) + { + FIXME("Provided ID2D1Image type not yet supported, hr %#x.\n", hr); + return; + } + + ID2D1Bitmap1_GetSurface(bitmap, &surface); + ID2D1Bitmap1_Release(bitmap); + hr = IDXGISurface_QueryInterface(surface, &IID_IDXGISurface1, (void **)&surface1); + IDXGISurface_Release(surface); + if (FAILED(hr)) + { + WARN("Failed to query IDXGISurface1, hr %#x.\n", hr); + return; + } + + if (FAILED(d2d_d3d_render_target_create_rtv(This->dxgi_target, surface1))) + { + WARN("Failed to set renderviewtarget, hr %#x.\n", hr); + } + + IDXGISurface1_Release(surface1); +} + +static void WINAPI d2d_device_context_GetTarget( + ID2D1DeviceContext *iface, + ID2D1Image **target) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static void WINAPI d2d_device_context_SetRenderingControls( + ID2D1DeviceContext *iface, + const D2D1_RENDERING_CONTROLS *renderingControls) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static void WINAPI d2d_device_context_GetRenderingControls( + ID2D1DeviceContext *iface, + D2D1_RENDERING_CONTROLS *renderingControls) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static void WINAPI d2d_device_context_SetPrimitiveBlend( + ID2D1DeviceContext *iface, + D2D1_PRIMITIVE_BLEND primitiveBlend) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static D2D1_PRIMITIVE_BLEND WINAPI d2d_device_context_GetPrimitiveBlend( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return D2D1_PRIMITIVE_BLEND_SOURCE_OVER; +} + +static void WINAPI d2d_device_context_SetUnitMode( + ID2D1DeviceContext *iface, + D2D1_UNIT_MODE unitMode) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static D2D1_UNIT_MODE WINAPI d2d_device_context_GetUnitMode( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return D2D1_UNIT_MODE_DIPS; +} + +static void WINAPI d2d_device_context_ID2D1DeviceContext_DrawGlyphRun( + ID2D1DeviceContext *iface, + D2D1_POINT_2F baselineOrigin, + const DWRITE_GLYPH_RUN *glyphRun, + const DWRITE_GLYPH_RUN_DESCRIPTION *glyphRunDescription, + ID2D1Brush *foregroundBrush, + DWRITE_MEASURING_MODE measuringMode) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static void WINAPI d2d_device_context_DrawImage( + ID2D1DeviceContext *iface, + ID2D1Image *image, + const D2D1_POINT_2F *targetOffset, + const D2D1_RECT_F *imageRectangle, + D2D1_INTERPOLATION_MODE interpolationMode, + D2D1_COMPOSITE_MODE compositeMode) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static void WINAPI d2d_device_context_DrawGdiMetafile( + ID2D1DeviceContext *iface, + ID2D1GdiMetafile *gdiMetafile, + const D2D1_POINT_2F *targetOffset) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static void WINAPI d2d_device_context_ID2D1DeviceContext_DrawBitmap( + ID2D1DeviceContext *iface, + ID2D1Bitmap *bitmap, + const D2D1_RECT_F *destinationRectangle, + float opacity, + D2D1_INTERPOLATION_MODE interpolationMode, + const D2D1_RECT_F *sourceRectangle, + const D2D1_MATRIX_4X4_F *perspectiveTransform) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static void WINAPI d2d_device_context_ID2D1DeviceContext_PushLayer( + ID2D1DeviceContext *iface, + const D2D1_LAYER_PARAMETERS1 *layerParameters, + ID2D1Layer *layer) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static HRESULT WINAPI d2d_device_context_InvalidateEffectInputRectangle( + ID2D1DeviceContext *iface, + ID2D1Effect *effect, + UINT32 input, + const D2D1_RECT_F *inputRectangle) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_GetEffectInvalidRectangleCount( + ID2D1DeviceContext *iface, + ID2D1Effect *effect, + UINT32 *rectangleCount) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_GetEffectInvalidRectangles( + ID2D1DeviceContext *iface, + ID2D1Effect *effect, + D2D1_RECT_F *rectangles, + UINT32 rectanglesCount) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_GetEffectRequiredInputRectangles( + ID2D1DeviceContext *iface, + ID2D1Effect *renderEffect, + const D2D1_RECT_F *renderImageRectangle, + const D2D1_EFFECT_INPUT_DESCRIPTION *inputDescriptions, + D2D1_RECT_F *requiredInputRects, + UINT32 inputCount) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static void WINAPI d2d_device_context_ID2D1DeviceContext_FillOpacityMask( + ID2D1DeviceContext *iface, + ID2D1Bitmap *opacityMask, + ID2D1Brush *brush, + const D2D1_RECT_F *destinationRectangle, + const D2D1_RECT_F *sourceRectangle) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static const struct ID2D1DeviceContextVtbl d2d_device_context_vtbl = +{ + d2d_device_context_QueryInterface, + d2d_device_context_AddRef, + d2d_device_context_Release, + d2d_device_context_GetFactory, + d2d_device_context_CreateBitmap, + d2d_device_context_CreateBitmapFromWicBitmap, + d2d_device_context_CreateSharedBitmap, + d2d_device_context_CreateBitmapBrush, + d2d_device_context_CreateSolidColorBrush, + d2d_device_context_CreateGradientStopCollection, + d2d_device_context_CreateLinearGradientBrush, + d2d_device_context_CreateRadialGradientBrush, + d2d_device_context_CreateCompatibleRenderTarget, + d2d_device_context_CreateLayer, + d2d_device_context_CreateMesh, + d2d_device_context_DrawLine, + d2d_device_context_DrawRectangle, + d2d_device_context_FillRectangle, + d2d_device_context_DrawRoundedRectangle, + d2d_device_context_FillRoundedRectangle, + d2d_device_context_DrawEllipse, + d2d_device_context_FillEllipse, + d2d_device_context_DrawGeometry, + d2d_device_context_FillGeometry, + d2d_device_context_FillMesh, + d2d_device_context_FillOpacityMask, + d2d_device_context_DrawBitmap, + d2d_device_context_DrawText, + d2d_device_context_DrawTextLayout, + d2d_device_context_DrawGlyphRun, + d2d_device_context_SetTransform, + d2d_device_context_GetTransform, + d2d_device_context_SetAntialiasMode, + d2d_device_context_GetAntialiasMode, + d2d_device_context_SetTextAntialiasMode, + d2d_device_context_GetTextAntialiasMode, + d2d_device_context_SetTextRenderingParams, + d2d_device_context_GetTextRenderingParams, + d2d_device_context_SetTags, + d2d_device_context_GetTags, + d2d_device_context_PushLayer, + d2d_device_context_PopLayer, + d2d_device_context_Flush, + d2d_device_context_SaveDrawingState, + d2d_device_context_RestoreDrawingState, + d2d_device_context_PushAxisAlignedClip, + d2d_device_context_PopAxisAlignedClip, + d2d_device_context_Clear, + d2d_device_context_BeginDraw, + d2d_device_context_EndDraw, + d2d_device_context_GetPixelFormat, + d2d_device_context_SetDpi, + d2d_device_context_GetDpi, + d2d_device_context_GetSize, + d2d_device_context_GetPixelSize, + d2d_device_context_GetMaximumBitmapSize, + d2d_device_context_IsSupported, + d2d_device_context_ID2D1DeviceContext_CreateBitmap, + d2d_device_context_ID2D1DeviceContext_CreateBitmapFromWicBitmap, + d2d_device_context_CreateColorContext, + d2d_device_context_CreateColorContextFromFilename, + d2d_device_context_CreateColorContextFromWicColorContext, + d2d_device_context_CreateBitmapFromDxgiSurface, + d2d_device_context_CreateEffect, + d2d_device_context_ID2D1DeviceContext_CreateGradientStopCollection, + d2d_device_context_CreateImageBrush, + d2d_device_context_ID2D1DeviceContext_CreateBitmapBrush, + d2d_device_context_CreateCommandList, + d2d_device_context_IsDxgiFormatSupported, + d2d_device_context_IsBufferPrecisionSupported, + d2d_device_context_GetImageLocalBounds, + d2d_device_context_GetImageWorldBounds, + d2d_device_context_GetGlyphRunWorldBounds, + d2d_device_context_GetDevice, + d2d_device_context_SetTarget, + d2d_device_context_GetTarget, + d2d_device_context_SetRenderingControls, + d2d_device_context_GetRenderingControls, + d2d_device_context_SetPrimitiveBlend, + d2d_device_context_GetPrimitiveBlend, + d2d_device_context_SetUnitMode, + d2d_device_context_GetUnitMode, + d2d_device_context_ID2D1DeviceContext_DrawGlyphRun, + d2d_device_context_DrawImage, + d2d_device_context_DrawGdiMetafile, + d2d_device_context_ID2D1DeviceContext_DrawBitmap, + d2d_device_context_ID2D1DeviceContext_PushLayer, + d2d_device_context_InvalidateEffectInputRectangle, + d2d_device_context_GetEffectInvalidRectangleCount, + d2d_device_context_GetEffectInvalidRectangles, + d2d_device_context_GetEffectRequiredInputRectangles, + d2d_device_context_ID2D1DeviceContext_FillOpacityMask, +}; + +HRESULT d2d_device_context_init(struct d2d_device_context *This, + ID2D1Device *device_iface, D2D1_DEVICE_CONTEXT_OPTIONS options, + ID3D10Device *d3d_device) +{ + HRESULT hr; + ID2D1Factory *factory; + D2D1_RENDER_TARGET_PROPERTIES desc; + desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; + desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN; + desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_UNKNOWN; + desc.dpiX = 96.0f; + desc.dpiY = 96.0f; + desc.usage = D2D1_RENDER_TARGET_USAGE_NONE; + desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; + + if (options == D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS) + FIXME("D2D1_DEVICE_CONTEXT_OPTIONS ignored."); + + This->ID2D1DeviceContext_iface.lpVtbl = &d2d_device_context_vtbl; + This->refcount = 1; + This->device = device_iface; + + ID2D1Device_GetFactory(This->device, &factory); + hr = d2d_d3d_create_render_target_with_device(factory, d3d_device, + (IUnknown *)&This->ID2D1DeviceContext_iface, + &desc, &This->dxgi_target); + ID2D1Factory_Release(factory); + if (FAILED(hr)) + { + WARN("Failed to create base render target, hr %#x.\n", hr); + return hr; + } + + ID2D1Device_AddRef(This->device); + + return S_OK; +} diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index 0c44014ae1..aa96b8f8ac 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -2152,7 +2152,7 @@ static const struct ID2D1GdiInteropRenderTargetVtbl d2d_gdi_interop_render_targe };
static HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory, - IDXGISurface *surface, IUnknown *outer_unknown, const D2D1_RENDER_TARGET_PROPERTIES *desc) + IDXGISurface *surface, ID3D10Device *device, IUnknown *outer_unknown, const D2D1_RENDER_TARGET_PROPERTIES *desc) { D3D10_SUBRESOURCE_DATA buffer_data; D3D10_STATE_BLOCK_MASK state_mask; @@ -3041,25 +3041,41 @@ static HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_t render_target->outer_unknown = outer_unknown ? outer_unknown : (IUnknown *)&render_target->ID2D1RenderTarget_iface;
- if (FAILED(hr = IDXGISurface_GetDevice(surface, &IID_ID3D10Device, (void **)&render_target->device))) + if (surface == NULL) { - WARN("Failed to get device interface, hr %#x.\n", hr); - ID2D1Factory_Release(render_target->factory); - return hr; + ID3D10Device_AddRef(render_target->device = device); } - - if (FAILED(hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource))) + else { - WARN("Failed to get ID3D10Resource interface, hr %#x.\n", hr); - goto err; - } + 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; + }
- 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 = 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 = 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; }
if (FAILED(hr = D3D10StateBlockMaskEnableAll(&state_mask))) @@ -3184,15 +3200,7 @@ static HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_t goto err; }
- if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc))) - { - WARN("Failed to get surface desc, hr %#x.\n", hr); - goto err; - } - render_target->desc.pixelFormat = desc->pixelFormat; - 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)) @@ -3246,7 +3254,31 @@ HRESULT d2d_d3d_create_render_target(ID2D1Factory *factory, IDXGISurface *surfac if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) return E_OUTOFMEMORY;
- if (FAILED(hr = d2d_d3d_render_target_init(object, factory, surface, outer_unknown, desc))) + if (FAILED(hr = d2d_d3d_render_target_init(object, factory, surface, NULL, outer_unknown, desc))) + { + WARN("Failed to initialize render target, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + + TRACE("Created render target %p.\n", object); + *render_target = &object->ID2D1RenderTarget_iface; + + return S_OK; +} + +HRESULT d2d_d3d_create_render_target_with_device(ID2D1Factory *factory, + ID3D10Device *device, IUnknown *outer_unknown, + const D2D1_RENDER_TARGET_PROPERTIES *desc, + ID2D1RenderTarget **render_target) +{ + struct d2d_d3d_render_target *object; + HRESULT hr; + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d2d_d3d_render_target_init(object, factory, NULL, device, outer_unknown, desc))) { WARN("Failed to initialize render target, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 76b7b5a786..77591708bd 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -4683,7 +4683,6 @@ static void test_draw_via_ID2D1DeviceContext(void)
hr = ID2D1Device_CreateDeviceContext(device, D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &context); - todo_wine ok(SUCCEEDED(hr), "Failed to create device context, hr %#x.\n", hr); if (FAILED(hr)) {
https://bugs.winehq.org/show_bug.cgi?id=44052
Signed-off-by: Lucian Poston lucian.poston@gmail.com ---
Resending since this patches didn't show up on the winehq patch list.
Changes since v1, * Squashed stub and implementation patches together into one commit.
dlls/d2d1/Makefile.in | 1 + dlls/d2d1/d2d1_private.h | 16 + dlls/d2d1/device.c | 36 +- dlls/d2d1/device_context.c | 1180 ++++++++++++++++++++++++++++++++++++++++++++ dlls/d2d1/render_target.c | 82 ++- dlls/d2d1/tests/d2d1.c | 1 - 6 files changed, 1288 insertions(+), 28 deletions(-) create mode 100644 dlls/d2d1/device_context.c
diff --git a/dlls/d2d1/Makefile.in b/dlls/d2d1/Makefile.in index 88bdab98dc..39753bd384 100644 --- a/dlls/d2d1/Makefile.in +++ b/dlls/d2d1/Makefile.in @@ -9,6 +9,7 @@ C_SRCS = \ brush.c \ dc_render_target.c \ device.c \ + device_context.c \ factory.c \ geometry.c \ hwnd_render_target.c \ diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index be239f12be..dd76a14af4 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -147,6 +147,10 @@ struct d2d_d3d_render_target
HRESULT d2d_d3d_create_render_target(ID2D1Factory *factory, IDXGISurface *surface, IUnknown *outer_unknown, const D2D1_RENDER_TARGET_PROPERTIES *desc, ID2D1RenderTarget **render_target) DECLSPEC_HIDDEN; +HRESULT d2d_d3d_create_render_target_with_device(ID2D1Factory *factory, + ID3D10Device *device, IUnknown *outer_unknown, + const D2D1_RENDER_TARGET_PROPERTIES *desc, + ID2D1RenderTarget **render_target) DECLSPEC_HIDDEN; HRESULT d2d_d3d_render_target_create_rtv(ID2D1RenderTarget *render_target, IDXGISurface1 *surface) DECLSPEC_HIDDEN;
struct d2d_wic_render_target @@ -544,4 +548,16 @@ struct d2d_device
void d2d_device_init(struct d2d_device *This, ID2D1Factory1 *iface, IDXGIDevice *dxgiDevice) DECLSPEC_HIDDEN;
+struct d2d_device_context +{ + ID2D1DeviceContext ID2D1DeviceContext_iface; + LONG refcount; + ID2D1Device *device; + ID2D1RenderTarget *dxgi_target; +}; + +HRESULT d2d_device_context_init(struct d2d_device_context *This, + ID2D1Device *device_iface, D2D1_DEVICE_CONTEXT_OPTIONS options, + ID3D10Device *d3d_device) DECLSPEC_HIDDEN; + #endif /* __WINE_D2D1_PRIVATE_H */ diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index c597362b79..9abd28d560 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -94,8 +94,40 @@ static HRESULT WINAPI d2d_device_CreateDeviceContext( ID2D1DeviceContext **deviceContext) { struct d2d_device *This = impl_from_ID2D1Device(iface); - FIXME("%p stub!\n", This); - return E_NOTIMPL; + struct d2d_device_context *object; + ID3D10Device *d3d_device; + HRESULT hr; + + TRACE("This %p, options %#x\n", This, options); + if (deviceContext == NULL) + return E_POINTER; + + if (FAILED(hr = IDXGIDevice_QueryInterface(This->dxgi_device, + &IID_ID3D10Device, (void **)&d3d_device))) + { + WARN("Failed to query d3d device, hr %#x.\n", hr); + return hr; + } + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + { + ID3D10Device_Release(d3d_device); + return E_OUTOFMEMORY; + } + + hr = d2d_device_context_init(object, iface, options, d3d_device); + ID3D10Device_Release(d3d_device); + if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, object); + WARN("Failed to create device context, hr %#x.\n", hr); + return hr; + } + + *deviceContext = &object->ID2D1DeviceContext_iface; + TRACE("Created device context %p.\n", object); + + return S_OK; }
static HRESULT WINAPI d2d_device_CreatePrintControl( diff --git a/dlls/d2d1/device_context.c b/dlls/d2d1/device_context.c new file mode 100644 index 0000000000..30657e260d --- /dev/null +++ b/dlls/d2d1/device_context.c @@ -0,0 +1,1180 @@ +/* + * Copyright 2017 Wine Project + * + * 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" + +WINE_DEFAULT_DEBUG_CHANNEL(d2d); + +static inline struct d2d_device_context *impl_from_ID2D1DeviceContext(ID2D1DeviceContext *iface) +{ + return CONTAINING_RECORD(iface, struct d2d_device_context, ID2D1DeviceContext_iface); +} + +static HRESULT WINAPI d2d_device_context_QueryInterface( + ID2D1DeviceContext *iface, + REFIID riid, + void **ppvObject) +{ + TRACE("iface %p, riid %s, ppvObject %p.\n", iface, debugstr_guid(riid), ppvObject); + if (ppvObject == NULL) + return E_POINTER; + + if (IsEqualGUID(riid, &IID_ID2D1DeviceContext) + || IsEqualGUID(riid, &IID_ID2D1RenderTarget) + || IsEqualGUID(riid, &IID_ID2D1Resource) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID2D1DeviceContext_AddRef(iface); + *ppvObject = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + *ppvObject = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI d2d_device_context_AddRef( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + ULONG refcount = InterlockedIncrement(&This->refcount); + TRACE("%p increasing refcount to %u.\n", iface, refcount); + return refcount; +} + +static ULONG WINAPI d2d_device_context_Release( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + ULONG refcount = InterlockedDecrement(&This->refcount); + TRACE("%p decreasing refcount to %u.\n", iface, refcount); + + if (refcount == 0) + { + ID2D1RenderTarget_Release(This->dxgi_target); + ID2D1Device_Release(This->device); + HeapFree(GetProcessHeap(), 0, This); + } + + return refcount; +} + +static void WINAPI d2d_device_context_GetFactory( + ID2D1DeviceContext *iface, + ID2D1Factory **factory) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, factory %p.\n", This, factory); + ID2D1Device_GetFactory(This->device, factory); +} + +static HRESULT WINAPI d2d_device_context_CreateBitmap( + ID2D1DeviceContext *iface, + D2D1_SIZE_U size, + const void *src_data, + UINT32 pitch, + const D2D1_BITMAP_PROPERTIES *desc, + ID2D1Bitmap **bitmap) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, src_data %p, desc %p, bitmap %p.\n", This, src_data, desc, bitmap); + return ID2D1RenderTarget_CreateBitmap(This->dxgi_target, size, src_data, pitch, desc, bitmap); +} + +static HRESULT WINAPI d2d_device_context_CreateBitmapFromWicBitmap( + ID2D1DeviceContext *iface, + IWICBitmapSource *bitmap_source, + const D2D1_BITMAP_PROPERTIES *desc, + ID2D1Bitmap **bitmap) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, bitmap_source %p, desc %p, bitmap %p.\n", + This, bitmap_source, desc, bitmap); + return ID2D1RenderTarget_CreateBitmapFromWicBitmap(This->dxgi_target, bitmap_source, desc, bitmap); +} + +static HRESULT WINAPI d2d_device_context_CreateSharedBitmap( + ID2D1DeviceContext *iface, + REFIID iid, + void *data, + const D2D1_BITMAP_PROPERTIES *desc, + ID2D1Bitmap **bitmap) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, iid %s, data %p, desc %p, bitmap %p.\n", + This, debugstr_guid(iid), data, desc, bitmap); + return ID2D1RenderTarget_CreateSharedBitmap(This->dxgi_target, iid, data, desc, bitmap); +} + +static HRESULT WINAPI d2d_device_context_CreateBitmapBrush( + ID2D1DeviceContext *iface, + ID2D1Bitmap *bitmap, + const D2D1_BITMAP_BRUSH_PROPERTIES *bitmap_brush_desc, + const D2D1_BRUSH_PROPERTIES *brush_desc, + ID2D1BitmapBrush **brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, bitmap %p, bitmap_brush_desc %p, brush_desc %p, brush %p.\n", + This, bitmap, bitmap_brush_desc, brush_desc, brush); + return ID2D1RenderTarget_CreateBitmapBrush(This->dxgi_target, + bitmap, bitmap_brush_desc, brush_desc, brush); +} + +static HRESULT WINAPI d2d_device_context_CreateSolidColorBrush( + ID2D1DeviceContext *iface, + const D2D1_COLOR_F *color, + const D2D1_BRUSH_PROPERTIES *desc, + ID2D1SolidColorBrush **brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, color %p, desc %p, brush %p.\n", This, color, desc, brush); + return ID2D1RenderTarget_CreateSolidColorBrush(This->dxgi_target, color, desc, brush); +} + +static HRESULT WINAPI d2d_device_context_CreateGradientStopCollection( + ID2D1DeviceContext *iface, + const D2D1_GRADIENT_STOP *stops, + UINT32 stop_count, + D2D1_GAMMA gamma, + D2D1_EXTEND_MODE extend_mode, + ID2D1GradientStopCollection **gradient) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, stops %p, gradient %p.\n", This, stops, gradient); + return ID2D1RenderTarget_CreateGradientStopCollection(This->dxgi_target, + stops, stop_count, gamma, extend_mode, gradient); +} + +static HRESULT WINAPI d2d_device_context_CreateLinearGradientBrush( + ID2D1DeviceContext *iface, + const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, + const D2D1_BRUSH_PROPERTIES *brush_desc, + ID2D1GradientStopCollection *gradient, + ID2D1LinearGradientBrush **brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n", + This, gradient_brush_desc, brush_desc, gradient, brush); + return ID2D1RenderTarget_CreateLinearGradientBrush(This->dxgi_target, + gradient_brush_desc, brush_desc, gradient, brush); +} + +static HRESULT WINAPI d2d_device_context_CreateRadialGradientBrush( + ID2D1DeviceContext *iface, + const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES *gradient_brush_desc, + const D2D1_BRUSH_PROPERTIES *brush_desc, + ID2D1GradientStopCollection *gradient, + ID2D1RadialGradientBrush **brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, gradient_brush_desc %p, brush_desc %p, gradient %p, brush %p.\n", + This, gradient_brush_desc, brush_desc, gradient, brush); + return ID2D1RenderTarget_CreateRadialGradientBrush(This->dxgi_target, + gradient_brush_desc, brush_desc, gradient, brush); +} + +static HRESULT WINAPI d2d_device_context_CreateCompatibleRenderTarget( + ID2D1DeviceContext *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) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, size %p, pixel_size %p, format %p, render_target %p.\n", + This, size, pixel_size, format, render_target); + return ID2D1RenderTarget_CreateCompatibleRenderTarget(This->dxgi_target, + size, pixel_size, format, options, render_target); +} + +static HRESULT WINAPI d2d_device_context_CreateLayer( + ID2D1DeviceContext *iface, + const D2D1_SIZE_F *size, + ID2D1Layer **layer) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, size %p, layer %p.\n", This, size, layer); + return ID2D1RenderTarget_CreateLayer(This->dxgi_target, size, layer); +} + +static HRESULT WINAPI d2d_device_context_CreateMesh( + ID2D1DeviceContext *iface, + ID2D1Mesh **mesh) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, mesh %p.\n", This, mesh); + return ID2D1RenderTarget_CreateMesh(This->dxgi_target, mesh); +} + +static void WINAPI d2d_device_context_DrawLine( + ID2D1DeviceContext *iface, + D2D1_POINT_2F p0, + D2D1_POINT_2F p1, + ID2D1Brush *brush, + float stroke_width, + ID2D1StrokeStyle *stroke_style) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, brush %p, stroke_style %p.\n", This, brush, stroke_style); + ID2D1RenderTarget_DrawLine(This->dxgi_target, p0, p1, brush, stroke_width, stroke_style); +} + +static void WINAPI d2d_device_context_DrawRectangle( + ID2D1DeviceContext *iface, + const D2D1_RECT_F *rect, + ID2D1Brush *brush, + float stroke_width, + ID2D1StrokeStyle *stroke_style) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, rect %p, brush %p, stroke_style %p.\n", This, rect, brush, stroke_style); + ID2D1RenderTarget_DrawRectangle(This->dxgi_target, rect, brush, stroke_width, stroke_style); +} + +static void WINAPI d2d_device_context_FillRectangle( + ID2D1DeviceContext *iface, + const D2D1_RECT_F *rect, + ID2D1Brush *brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, rect %p, brush %p.\n", This, rect, brush); + ID2D1RenderTarget_FillRectangle(This->dxgi_target, rect, brush); +} + +static void WINAPI d2d_device_context_DrawRoundedRectangle( + ID2D1DeviceContext *iface, + const D2D1_ROUNDED_RECT *rect, + ID2D1Brush *brush, + float stroke_width, + ID2D1StrokeStyle *stroke_style) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, rect %p, brush %p, stroke_style %p.\n", This, rect, brush, stroke_style); + ID2D1RenderTarget_DrawRoundedRectangle(This->dxgi_target, rect, brush, stroke_width, stroke_style); +} + +static void WINAPI d2d_device_context_FillRoundedRectangle( + ID2D1DeviceContext *iface, + const D2D1_ROUNDED_RECT *rect, + ID2D1Brush *brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, rect %p, brush %p.\n", This, rect, brush); + ID2D1RenderTarget_FillRoundedRectangle(This->dxgi_target, rect, brush); +} + +static void WINAPI d2d_device_context_DrawEllipse( + ID2D1DeviceContext *iface, + const D2D1_ELLIPSE *ellipse, + ID2D1Brush *brush, + float stroke_width, + ID2D1StrokeStyle *stroke_style) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, ellipse %p, brush %p, stroke_style %p.\n", This, ellipse, brush, stroke_style); + ID2D1RenderTarget_DrawEllipse(This->dxgi_target, ellipse, brush, stroke_width, stroke_style); +} + +static void WINAPI d2d_device_context_FillEllipse( + ID2D1DeviceContext *iface, + const D2D1_ELLIPSE *ellipse, + ID2D1Brush *brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, ellipse %p, brush %p.\n", This, ellipse, brush); + ID2D1RenderTarget_FillEllipse(This->dxgi_target, ellipse, brush); +} + +static void WINAPI d2d_device_context_DrawGeometry( + ID2D1DeviceContext *iface, + ID2D1Geometry *geometry, + ID2D1Brush *brush, + float stroke_width, + ID2D1StrokeStyle *stroke_style) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, geometry %p, brush %p, stroke_style %p.\n", This, geometry, brush, stroke_style); + ID2D1RenderTarget_DrawGeometry(This->dxgi_target, geometry, brush, stroke_width, stroke_style); +} + +static void WINAPI d2d_device_context_FillGeometry( + ID2D1DeviceContext *iface, + ID2D1Geometry *geometry, + ID2D1Brush *brush, + ID2D1Brush *opacity_brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, geometry %p, brush %p, opacity_brush %p.\n", This, geometry, brush, opacity_brush); + ID2D1RenderTarget_FillGeometry(This->dxgi_target, geometry, brush, opacity_brush); +} + +static void WINAPI d2d_device_context_FillMesh( + ID2D1DeviceContext *iface, + ID2D1Mesh *mesh, + ID2D1Brush *brush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, mesh %p, brush %p.\n", This, mesh, brush); + ID2D1RenderTarget_FillMesh(This->dxgi_target, mesh, brush); +} + +static void WINAPI d2d_device_context_FillOpacityMask( + ID2D1DeviceContext *iface, + ID2D1Bitmap *mask, + ID2D1Brush *brush, + D2D1_OPACITY_MASK_CONTENT content, + const D2D1_RECT_F *dst_rect, + const D2D1_RECT_F *src_rect) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, mask %p, brush %p.\n", This, mask, brush); + ID2D1RenderTarget_FillOpacityMask(This->dxgi_target, + mask, brush, content, dst_rect, src_rect); +} + +static void WINAPI d2d_device_context_DrawBitmap( + ID2D1DeviceContext *iface, + ID2D1Bitmap *bitmap, + const D2D1_RECT_F *dst_rect, + float opacity, + D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode, + const D2D1_RECT_F *src_rect) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, bitmap %p.\n", This, bitmap); + ID2D1RenderTarget_DrawBitmap(This->dxgi_target, + bitmap, dst_rect, opacity, interpolation_mode, src_rect); +} + +static void WINAPI d2d_device_context_DrawText( + ID2D1DeviceContext *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) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, string %s.\n", This, debugstr_w(string)); + ID2D1RenderTarget_DrawText(This->dxgi_target, string, string_len, + text_format, layout_rect, brush, options, measuring_mode); +} + +static void WINAPI d2d_device_context_DrawTextLayout( + ID2D1DeviceContext *iface, + D2D1_POINT_2F origin, + IDWriteTextLayout *layout, + ID2D1Brush *brush, + D2D1_DRAW_TEXT_OPTIONS options) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, layout %p, brush %p.\n", This, layout, brush); + ID2D1RenderTarget_DrawTextLayout(This->dxgi_target, origin, layout, brush, options); +} + +static void WINAPI d2d_device_context_DrawGlyphRun( + ID2D1DeviceContext *iface, + D2D1_POINT_2F baseline_origin, + const DWRITE_GLYPH_RUN *glyph_run, + ID2D1Brush *brush, + DWRITE_MEASURING_MODE measuring_mode) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, glyph_run %p, brush %p.\n", This, glyph_run, brush); + ID2D1RenderTarget_DrawGlyphRun(This->dxgi_target, + baseline_origin, glyph_run, brush, measuring_mode); +} + +static void WINAPI d2d_device_context_SetTransform( + ID2D1DeviceContext *iface, + const D2D1_MATRIX_3X2_F *transform) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, transform %p.\n", This, transform); + ID2D1RenderTarget_SetTransform(This->dxgi_target, transform); +} + +static void WINAPI d2d_device_context_GetTransform( + ID2D1DeviceContext *iface, + D2D1_MATRIX_3X2_F *transform) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, transform %p.\n", This, transform); + ID2D1RenderTarget_GetTransform(This->dxgi_target, transform); +} + +static void WINAPI d2d_device_context_SetAntialiasMode( + ID2D1DeviceContext *iface, + D2D1_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_SetAntialiasMode(This->dxgi_target, antialias_mode); +} + +static D2D1_ANTIALIAS_MODE WINAPI d2d_device_context_GetAntialiasMode( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + return ID2D1RenderTarget_GetAntialiasMode(This->dxgi_target); +} + +static void WINAPI d2d_device_context_SetTextAntialiasMode( + ID2D1DeviceContext *iface, + D2D1_TEXT_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_SetTextAntialiasMode(This->dxgi_target, antialias_mode); +} + +static D2D1_TEXT_ANTIALIAS_MODE WINAPI d2d_device_context_GetTextAntialiasMode( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + return ID2D1RenderTarget_GetTextAntialiasMode(This->dxgi_target); +} + +static void WINAPI d2d_device_context_SetTextRenderingParams( + ID2D1DeviceContext *iface, + IDWriteRenderingParams *text_rendering_params) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_SetTextRenderingParams(This->dxgi_target, text_rendering_params); +} + +static void WINAPI d2d_device_context_GetTextRenderingParams( + ID2D1DeviceContext *iface, + IDWriteRenderingParams **text_rendering_params) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_GetTextRenderingParams(This->dxgi_target, text_rendering_params); +} + +static void WINAPI d2d_device_context_SetTags( + ID2D1DeviceContext *iface, + D2D1_TAG tag1, + D2D1_TAG tag2) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_SetTags(This->dxgi_target, tag1, tag2); +} + +static void WINAPI d2d_device_context_GetTags( + ID2D1DeviceContext *iface, + D2D1_TAG *tag1, + D2D1_TAG *tag2) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_GetTags(This->dxgi_target, tag1, tag2); +} + +static void WINAPI d2d_device_context_PushLayer( + ID2D1DeviceContext *iface, + const D2D1_LAYER_PARAMETERS *layer_parameters, + ID2D1Layer *layer) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_PushLayer(This->dxgi_target, layer_parameters, layer); +} + +static void WINAPI d2d_device_context_PopLayer( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_PopLayer(This->dxgi_target); +} + +static HRESULT WINAPI d2d_device_context_Flush( + ID2D1DeviceContext *iface, + D2D1_TAG *tag1, + D2D1_TAG *tag2) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + return ID2D1RenderTarget_Flush(This->dxgi_target, tag1, tag2); +} + +static void WINAPI d2d_device_context_SaveDrawingState( + ID2D1DeviceContext *iface, + ID2D1DrawingStateBlock *state_block) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, state_block %p.\n", This, state_block); + ID2D1RenderTarget_SaveDrawingState(This->dxgi_target, state_block); +} + +static void WINAPI d2d_device_context_RestoreDrawingState( + ID2D1DeviceContext *iface, + ID2D1DrawingStateBlock *state_block) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, state_block %p.\n", This, state_block); + ID2D1RenderTarget_RestoreDrawingState(This->dxgi_target, state_block); +} + +static void WINAPI d2d_device_context_PushAxisAlignedClip( + ID2D1DeviceContext *iface, + const D2D1_RECT_F *clip_rect, + D2D1_ANTIALIAS_MODE antialias_mode) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_PushAxisAlignedClip(This->dxgi_target, clip_rect, antialias_mode); +} + +static void WINAPI d2d_device_context_PopAxisAlignedClip( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_PopAxisAlignedClip(This->dxgi_target); +} + +static void WINAPI d2d_device_context_Clear( + ID2D1DeviceContext *iface, + const D2D1_COLOR_F *color) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_Clear(This->dxgi_target, color); +} + +static void WINAPI d2d_device_context_BeginDraw( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_BeginDraw(This->dxgi_target); +} + +static HRESULT WINAPI d2d_device_context_EndDraw( + ID2D1DeviceContext *iface, + D2D1_TAG *tag1, + D2D1_TAG *tag2) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + return ID2D1RenderTarget_EndDraw(This->dxgi_target, tag1, tag2); +} + +static D2D1_PIXEL_FORMAT * WINAPI d2d_device_context_GetPixelFormat( + ID2D1DeviceContext *iface, + D2D1_PIXEL_FORMAT *__ret) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, __ret %p.\n", This, __ret); + *__ret = ID2D1RenderTarget_GetPixelFormat(This->dxgi_target); + return __ret; +} + +static void WINAPI d2d_device_context_SetDpi( + ID2D1DeviceContext *iface, + float dpi_x, + float dpi_y) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_SetDpi(This->dxgi_target, dpi_x, dpi_y); +} + +static void WINAPI d2d_device_context_GetDpi( + ID2D1DeviceContext *iface, + float *dpi_x, + float *dpi_y) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + ID2D1RenderTarget_GetDpi(This->dxgi_target, dpi_x, dpi_y); +} + +static D2D1_SIZE_F * WINAPI d2d_device_context_GetSize( + ID2D1DeviceContext *iface, + D2D1_SIZE_F *__ret) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, __ret %p.\n", This, __ret); + *__ret = ID2D1RenderTarget_GetSize(This->dxgi_target); + return __ret; +} + +static D2D1_SIZE_U * WINAPI d2d_device_context_GetPixelSize( + ID2D1DeviceContext *iface, + D2D1_SIZE_U *__ret) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, __ret %p.\n", This, __ret); + *__ret = ID2D1RenderTarget_GetPixelSize(This->dxgi_target); + return __ret; +} + +static UINT32 WINAPI d2d_device_context_GetMaximumBitmapSize( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + return ID2D1RenderTarget_GetMaximumBitmapSize(This->dxgi_target); +} + +static BOOL WINAPI d2d_device_context_IsSupported( + ID2D1DeviceContext *iface, + const D2D1_RENDER_TARGET_PROPERTIES *desc) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p.\n", This); + return ID2D1RenderTarget_IsSupported(This->dxgi_target, desc); +} + +static HRESULT WINAPI d2d_device_context_ID2D1DeviceContext_CreateBitmap( + ID2D1DeviceContext *iface, + D2D1_SIZE_U size, + const void *srcData, + UINT32 pitch, + const D2D1_BITMAP_PROPERTIES1 *bitmapProperties, + ID2D1Bitmap1 **bitmap) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_ID2D1DeviceContext_CreateBitmapFromWicBitmap( + ID2D1DeviceContext *iface, + IWICBitmapSource *wicBitmapSource, + const D2D1_BITMAP_PROPERTIES1 *bitmapProperties, + ID2D1Bitmap1 **bitmap) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_CreateColorContext( + ID2D1DeviceContext *iface, + D2D1_COLOR_SPACE space, + const BYTE *Profile, + UINT32 profileSize, + ID2D1ColorContext **colorContext) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_CreateColorContextFromFilename( + ID2D1DeviceContext *iface, + PCWSTR Filename, + ID2D1ColorContext **colorContext) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_CreateColorContextFromWicColorContext( + ID2D1DeviceContext *iface, + IWICColorContext *wicColorContext, + ID2D1ColorContext **colorContext) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_CreateBitmapFromDxgiSurface( + ID2D1DeviceContext *iface, + IDXGISurface *surface, + const D2D1_BITMAP_PROPERTIES1 *bitmapProperties, + ID2D1Bitmap1 **bitmap) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_CreateEffect( + ID2D1DeviceContext *iface, + REFCLSID effectId, + ID2D1Effect **effect) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_ID2D1DeviceContext_CreateGradientStopCollection( + ID2D1DeviceContext *iface, + const D2D1_GRADIENT_STOP *gradientStops, + UINT gradientStopsCount, + D2D1_COLOR_SPACE preInterpolationSpace, + D2D1_COLOR_SPACE postInterpolationSpace, + D2D1_BUFFER_PRECISION bufferPrecision, + D2D1_EXTEND_MODE extendMode, + D2D1_COLOR_INTERPOLATION_MODE colorInterpolationMode, + ID2D1GradientStopCollection1 **gradientStopCollection) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_CreateImageBrush( + ID2D1DeviceContext *iface, + ID2D1Image *image, + const D2D1_IMAGE_BRUSH_PROPERTIES *imageBrushProperties, + const D2D1_BRUSH_PROPERTIES *brushProperties, + ID2D1ImageBrush **imageBrush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_ID2D1DeviceContext_CreateBitmapBrush( + ID2D1DeviceContext *iface, + ID2D1Bitmap *bitmap, + const D2D1_BITMAP_BRUSH_PROPERTIES1 *bitmapBrushProperties, + const D2D1_BRUSH_PROPERTIES *brushProperties, + ID2D1BitmapBrush1 **bitmapBrush) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_CreateCommandList( + ID2D1DeviceContext *iface, + ID2D1CommandList **commandList) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static BOOL WINAPI d2d_device_context_IsDxgiFormatSupported( + ID2D1DeviceContext *iface, + DXGI_FORMAT format) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return FALSE; +} + +static BOOL WINAPI d2d_device_context_IsBufferPrecisionSupported( + ID2D1DeviceContext *iface, + D2D1_BUFFER_PRECISION bufferPrecision) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return FALSE; +} + +static void WINAPI d2d_device_context_GetImageLocalBounds( + ID2D1DeviceContext *iface, + ID2D1Image *image, + D2D1_RECT_F *localBounds) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static HRESULT WINAPI d2d_device_context_GetImageWorldBounds( + ID2D1DeviceContext *iface, + ID2D1Image *image, + D2D1_RECT_F *worldBounds) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_GetGlyphRunWorldBounds( + ID2D1DeviceContext *iface, + D2D1_POINT_2F baselineOrigin, + const DWRITE_GLYPH_RUN *glyphRun, + DWRITE_MEASURING_MODE measuringMode, + D2D1_RECT_F *bounds) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static void WINAPI d2d_device_context_GetDevice( + ID2D1DeviceContext *iface, + ID2D1Device **device) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + TRACE("This %p, device %p.\n", This, device); + if (device == NULL) + return; + + ID2D1Device_AddRef(This->device); + *device = This->device; +} + +static void WINAPI d2d_device_context_SetTarget( + ID2D1DeviceContext *iface, + ID2D1Image *target) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + IDXGISurface *surface; + IDXGISurface1 *surface1; + ID2D1Bitmap1 *bitmap; + HRESULT hr; + + TRACE("This %p, target %p.\n", This, target); + if (FAILED(hr = ID2D1Image_QueryInterface(target, &IID_ID2D1Bitmap1, (void **)&bitmap))) + { + FIXME("Provided ID2D1Image type not yet supported, hr %#x.\n", hr); + return; + } + + ID2D1Bitmap1_GetSurface(bitmap, &surface); + ID2D1Bitmap1_Release(bitmap); + hr = IDXGISurface_QueryInterface(surface, &IID_IDXGISurface1, (void **)&surface1); + IDXGISurface_Release(surface); + if (FAILED(hr)) + { + WARN("Failed to query IDXGISurface1, hr %#x.\n", hr); + return; + } + + if (FAILED(d2d_d3d_render_target_create_rtv(This->dxgi_target, surface1))) + { + WARN("Failed to set renderviewtarget, hr %#x.\n", hr); + } + + IDXGISurface1_Release(surface1); +} + +static void WINAPI d2d_device_context_GetTarget( + ID2D1DeviceContext *iface, + ID2D1Image **target) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static void WINAPI d2d_device_context_SetRenderingControls( + ID2D1DeviceContext *iface, + const D2D1_RENDERING_CONTROLS *renderingControls) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static void WINAPI d2d_device_context_GetRenderingControls( + ID2D1DeviceContext *iface, + D2D1_RENDERING_CONTROLS *renderingControls) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static void WINAPI d2d_device_context_SetPrimitiveBlend( + ID2D1DeviceContext *iface, + D2D1_PRIMITIVE_BLEND primitiveBlend) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static D2D1_PRIMITIVE_BLEND WINAPI d2d_device_context_GetPrimitiveBlend( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return D2D1_PRIMITIVE_BLEND_SOURCE_OVER; +} + +static void WINAPI d2d_device_context_SetUnitMode( + ID2D1DeviceContext *iface, + D2D1_UNIT_MODE unitMode) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static D2D1_UNIT_MODE WINAPI d2d_device_context_GetUnitMode( + ID2D1DeviceContext *iface) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return D2D1_UNIT_MODE_DIPS; +} + +static void WINAPI d2d_device_context_ID2D1DeviceContext_DrawGlyphRun( + ID2D1DeviceContext *iface, + D2D1_POINT_2F baselineOrigin, + const DWRITE_GLYPH_RUN *glyphRun, + const DWRITE_GLYPH_RUN_DESCRIPTION *glyphRunDescription, + ID2D1Brush *foregroundBrush, + DWRITE_MEASURING_MODE measuringMode) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static void WINAPI d2d_device_context_DrawImage( + ID2D1DeviceContext *iface, + ID2D1Image *image, + const D2D1_POINT_2F *targetOffset, + const D2D1_RECT_F *imageRectangle, + D2D1_INTERPOLATION_MODE interpolationMode, + D2D1_COMPOSITE_MODE compositeMode) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static void WINAPI d2d_device_context_DrawGdiMetafile( + ID2D1DeviceContext *iface, + ID2D1GdiMetafile *gdiMetafile, + const D2D1_POINT_2F *targetOffset) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static void WINAPI d2d_device_context_ID2D1DeviceContext_DrawBitmap( + ID2D1DeviceContext *iface, + ID2D1Bitmap *bitmap, + const D2D1_RECT_F *destinationRectangle, + float opacity, + D2D1_INTERPOLATION_MODE interpolationMode, + const D2D1_RECT_F *sourceRectangle, + const D2D1_MATRIX_4X4_F *perspectiveTransform) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static void WINAPI d2d_device_context_ID2D1DeviceContext_PushLayer( + ID2D1DeviceContext *iface, + const D2D1_LAYER_PARAMETERS1 *layerParameters, + ID2D1Layer *layer) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static HRESULT WINAPI d2d_device_context_InvalidateEffectInputRectangle( + ID2D1DeviceContext *iface, + ID2D1Effect *effect, + UINT32 input, + const D2D1_RECT_F *inputRectangle) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_GetEffectInvalidRectangleCount( + ID2D1DeviceContext *iface, + ID2D1Effect *effect, + UINT32 *rectangleCount) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_GetEffectInvalidRectangles( + ID2D1DeviceContext *iface, + ID2D1Effect *effect, + D2D1_RECT_F *rectangles, + UINT32 rectanglesCount) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_device_context_GetEffectRequiredInputRectangles( + ID2D1DeviceContext *iface, + ID2D1Effect *renderEffect, + const D2D1_RECT_F *renderImageRectangle, + const D2D1_EFFECT_INPUT_DESCRIPTION *inputDescriptions, + D2D1_RECT_F *requiredInputRects, + UINT32 inputCount) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static void WINAPI d2d_device_context_ID2D1DeviceContext_FillOpacityMask( + ID2D1DeviceContext *iface, + ID2D1Bitmap *opacityMask, + ID2D1Brush *brush, + const D2D1_RECT_F *destinationRectangle, + const D2D1_RECT_F *sourceRectangle) +{ + struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); + FIXME("%p stub!\n", This); +} + +static const struct ID2D1DeviceContextVtbl d2d_device_context_vtbl = +{ + d2d_device_context_QueryInterface, + d2d_device_context_AddRef, + d2d_device_context_Release, + d2d_device_context_GetFactory, + d2d_device_context_CreateBitmap, + d2d_device_context_CreateBitmapFromWicBitmap, + d2d_device_context_CreateSharedBitmap, + d2d_device_context_CreateBitmapBrush, + d2d_device_context_CreateSolidColorBrush, + d2d_device_context_CreateGradientStopCollection, + d2d_device_context_CreateLinearGradientBrush, + d2d_device_context_CreateRadialGradientBrush, + d2d_device_context_CreateCompatibleRenderTarget, + d2d_device_context_CreateLayer, + d2d_device_context_CreateMesh, + d2d_device_context_DrawLine, + d2d_device_context_DrawRectangle, + d2d_device_context_FillRectangle, + d2d_device_context_DrawRoundedRectangle, + d2d_device_context_FillRoundedRectangle, + d2d_device_context_DrawEllipse, + d2d_device_context_FillEllipse, + d2d_device_context_DrawGeometry, + d2d_device_context_FillGeometry, + d2d_device_context_FillMesh, + d2d_device_context_FillOpacityMask, + d2d_device_context_DrawBitmap, + d2d_device_context_DrawText, + d2d_device_context_DrawTextLayout, + d2d_device_context_DrawGlyphRun, + d2d_device_context_SetTransform, + d2d_device_context_GetTransform, + d2d_device_context_SetAntialiasMode, + d2d_device_context_GetAntialiasMode, + d2d_device_context_SetTextAntialiasMode, + d2d_device_context_GetTextAntialiasMode, + d2d_device_context_SetTextRenderingParams, + d2d_device_context_GetTextRenderingParams, + d2d_device_context_SetTags, + d2d_device_context_GetTags, + d2d_device_context_PushLayer, + d2d_device_context_PopLayer, + d2d_device_context_Flush, + d2d_device_context_SaveDrawingState, + d2d_device_context_RestoreDrawingState, + d2d_device_context_PushAxisAlignedClip, + d2d_device_context_PopAxisAlignedClip, + d2d_device_context_Clear, + d2d_device_context_BeginDraw, + d2d_device_context_EndDraw, + d2d_device_context_GetPixelFormat, + d2d_device_context_SetDpi, + d2d_device_context_GetDpi, + d2d_device_context_GetSize, + d2d_device_context_GetPixelSize, + d2d_device_context_GetMaximumBitmapSize, + d2d_device_context_IsSupported, + d2d_device_context_ID2D1DeviceContext_CreateBitmap, + d2d_device_context_ID2D1DeviceContext_CreateBitmapFromWicBitmap, + d2d_device_context_CreateColorContext, + d2d_device_context_CreateColorContextFromFilename, + d2d_device_context_CreateColorContextFromWicColorContext, + d2d_device_context_CreateBitmapFromDxgiSurface, + d2d_device_context_CreateEffect, + d2d_device_context_ID2D1DeviceContext_CreateGradientStopCollection, + d2d_device_context_CreateImageBrush, + d2d_device_context_ID2D1DeviceContext_CreateBitmapBrush, + d2d_device_context_CreateCommandList, + d2d_device_context_IsDxgiFormatSupported, + d2d_device_context_IsBufferPrecisionSupported, + d2d_device_context_GetImageLocalBounds, + d2d_device_context_GetImageWorldBounds, + d2d_device_context_GetGlyphRunWorldBounds, + d2d_device_context_GetDevice, + d2d_device_context_SetTarget, + d2d_device_context_GetTarget, + d2d_device_context_SetRenderingControls, + d2d_device_context_GetRenderingControls, + d2d_device_context_SetPrimitiveBlend, + d2d_device_context_GetPrimitiveBlend, + d2d_device_context_SetUnitMode, + d2d_device_context_GetUnitMode, + d2d_device_context_ID2D1DeviceContext_DrawGlyphRun, + d2d_device_context_DrawImage, + d2d_device_context_DrawGdiMetafile, + d2d_device_context_ID2D1DeviceContext_DrawBitmap, + d2d_device_context_ID2D1DeviceContext_PushLayer, + d2d_device_context_InvalidateEffectInputRectangle, + d2d_device_context_GetEffectInvalidRectangleCount, + d2d_device_context_GetEffectInvalidRectangles, + d2d_device_context_GetEffectRequiredInputRectangles, + d2d_device_context_ID2D1DeviceContext_FillOpacityMask, +}; + +HRESULT d2d_device_context_init(struct d2d_device_context *This, + ID2D1Device *device_iface, D2D1_DEVICE_CONTEXT_OPTIONS options, + ID3D10Device *d3d_device) +{ + HRESULT hr; + ID2D1Factory *factory; + D2D1_RENDER_TARGET_PROPERTIES desc; + desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT; + desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN; + desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_UNKNOWN; + desc.dpiX = 96.0f; + desc.dpiY = 96.0f; + desc.usage = D2D1_RENDER_TARGET_USAGE_NONE; + desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT; + + if (options == D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS) + FIXME("D2D1_DEVICE_CONTEXT_OPTIONS ignored."); + + This->ID2D1DeviceContext_iface.lpVtbl = &d2d_device_context_vtbl; + This->refcount = 1; + This->device = device_iface; + + ID2D1Device_GetFactory(This->device, &factory); + hr = d2d_d3d_create_render_target_with_device(factory, d3d_device, + (IUnknown *)&This->ID2D1DeviceContext_iface, + &desc, &This->dxgi_target); + ID2D1Factory_Release(factory); + if (FAILED(hr)) + { + WARN("Failed to create base render target, hr %#x.\n", hr); + return hr; + } + + ID2D1Device_AddRef(This->device); + + return S_OK; +} diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index 0c44014ae1..aa96b8f8ac 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -2152,7 +2152,7 @@ static const struct ID2D1GdiInteropRenderTargetVtbl d2d_gdi_interop_render_targe };
static HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target, ID2D1Factory *factory, - IDXGISurface *surface, IUnknown *outer_unknown, const D2D1_RENDER_TARGET_PROPERTIES *desc) + IDXGISurface *surface, ID3D10Device *device, IUnknown *outer_unknown, const D2D1_RENDER_TARGET_PROPERTIES *desc) { D3D10_SUBRESOURCE_DATA buffer_data; D3D10_STATE_BLOCK_MASK state_mask; @@ -3041,25 +3041,41 @@ static HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_t render_target->outer_unknown = outer_unknown ? outer_unknown : (IUnknown *)&render_target->ID2D1RenderTarget_iface;
- if (FAILED(hr = IDXGISurface_GetDevice(surface, &IID_ID3D10Device, (void **)&render_target->device))) + if (surface == NULL) { - WARN("Failed to get device interface, hr %#x.\n", hr); - ID2D1Factory_Release(render_target->factory); - return hr; + ID3D10Device_AddRef(render_target->device = device); } - - if (FAILED(hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource))) + else { - WARN("Failed to get ID3D10Resource interface, hr %#x.\n", hr); - goto err; - } + 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; + }
- 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 = 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 = 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; }
if (FAILED(hr = D3D10StateBlockMaskEnableAll(&state_mask))) @@ -3184,15 +3200,7 @@ static HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_t goto err; }
- if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc))) - { - WARN("Failed to get surface desc, hr %#x.\n", hr); - goto err; - } - render_target->desc.pixelFormat = desc->pixelFormat; - 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)) @@ -3246,7 +3254,31 @@ HRESULT d2d_d3d_create_render_target(ID2D1Factory *factory, IDXGISurface *surfac if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) return E_OUTOFMEMORY;
- if (FAILED(hr = d2d_d3d_render_target_init(object, factory, surface, outer_unknown, desc))) + if (FAILED(hr = d2d_d3d_render_target_init(object, factory, surface, NULL, outer_unknown, desc))) + { + WARN("Failed to initialize render target, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + + TRACE("Created render target %p.\n", object); + *render_target = &object->ID2D1RenderTarget_iface; + + return S_OK; +} + +HRESULT d2d_d3d_create_render_target_with_device(ID2D1Factory *factory, + ID3D10Device *device, IUnknown *outer_unknown, + const D2D1_RENDER_TARGET_PROPERTIES *desc, + ID2D1RenderTarget **render_target) +{ + struct d2d_d3d_render_target *object; + HRESULT hr; + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d2d_d3d_render_target_init(object, factory, NULL, device, outer_unknown, desc))) { WARN("Failed to initialize render target, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 76b7b5a786..77591708bd 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -4683,7 +4683,6 @@ static void test_draw_via_ID2D1DeviceContext(void)
hr = ID2D1Device_CreateDeviceContext(device, D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &context); - todo_wine ok(SUCCEEDED(hr), "Failed to create device context, hr %#x.\n", hr); if (FAILED(hr)) {
https://bugs.winehq.org/show_bug.cgi?id=44052
Signed-off-by: Lucian Poston lucian.poston@gmail.com ---
Changes since v1, * Squashed stub and implementation patches together into one commit. * Refactored common code to created shared bitmap from dxgi surface into one function
dlls/d2d1/bitmap.c | 278 +++++++++++++++++++++++++++++++++------------ dlls/d2d1/brush.c | 8 +- dlls/d2d1/d2d1_private.h | 8 +- dlls/d2d1/device_context.c | 24 +++- dlls/d2d1/render_target.c | 6 +- dlls/d2d1/tests/d2d1.c | 3 - 6 files changed, 244 insertions(+), 83 deletions(-)
diff --git a/dlls/d2d1/bitmap.c b/dlls/d2d1/bitmap.c index 6d9c352924..d54b4b095f 100644 --- a/dlls/d2d1/bitmap.c +++ b/dlls/d2d1/bitmap.c @@ -24,20 +24,46 @@
WINE_DEFAULT_DEBUG_CHANNEL(d2d);
-static inline struct d2d_bitmap *impl_from_ID2D1Bitmap(ID2D1Bitmap *iface) +static inline struct d2d_bitmap *impl_from_ID2D1Bitmap(ID2D1Bitmap1 *iface) { return CONTAINING_RECORD(iface, struct d2d_bitmap, ID2D1Bitmap_iface); }
-static HRESULT STDMETHODCALLTYPE d2d_bitmap_QueryInterface(ID2D1Bitmap *iface, REFIID iid, void **out) +static D2D1_BITMAP_PROPERTIES1 bitmap_properties_to_properties1( + const D2D1_BITMAP_PROPERTIES *desc) +{ + D2D1_BITMAP_PROPERTIES1 d; + d.bitmapOptions = D2D1_BITMAP_OPTIONS_NONE; + d.colorContext = NULL; + if (desc == NULL) + { + d.pixelFormat.format = DXGI_FORMAT_UNKNOWN; + d.pixelFormat.alphaMode = D2D1_ALPHA_MODE_UNKNOWN; + d.dpiX = 96.0f; + d.dpiY = 96.0f; + } + else + { + d.pixelFormat.format = desc->pixelFormat.format; + d.pixelFormat.alphaMode = desc->pixelFormat.alphaMode; + d.dpiX = desc->dpiX; + d.dpiY = desc->dpiY; + } + + return d; +} + +static HRESULT STDMETHODCALLTYPE d2d_bitmap_QueryInterface(ID2D1Bitmap1 *iface, REFIID iid, void **out) { TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
- if (IsEqualGUID(iid, &IID_ID2D1Bitmap) + if (IsEqualGUID(iid, &IID_ID2D1Bitmap1) + || IsEqualGUID(iid, &IID_ID2D1Bitmap) + || IsEqualGUID(iid, &IID_ID2D1Image) || IsEqualGUID(iid, &IID_ID2D1Resource) || IsEqualGUID(iid, &IID_IUnknown)) { - ID2D1Bitmap_AddRef(iface); + ID2D1Bitmap1_AddRef(iface); *out = iface; return S_OK; } @@ -48,7 +74,7 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_QueryInterface(ID2D1Bitmap *iface, R return E_NOINTERFACE; }
-static ULONG STDMETHODCALLTYPE d2d_bitmap_AddRef(ID2D1Bitmap *iface) +static ULONG STDMETHODCALLTYPE d2d_bitmap_AddRef(ID2D1Bitmap1 *iface) { struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap(iface); ULONG refcount = InterlockedIncrement(&bitmap->refcount); @@ -58,7 +84,7 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_AddRef(ID2D1Bitmap *iface) return refcount; }
-static ULONG STDMETHODCALLTYPE d2d_bitmap_Release(ID2D1Bitmap *iface) +static ULONG STDMETHODCALLTYPE d2d_bitmap_Release(ID2D1Bitmap1 *iface) { struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap(iface); ULONG refcount = InterlockedDecrement(&bitmap->refcount); @@ -67,6 +93,10 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_Release(ID2D1Bitmap *iface)
if (!refcount) { + if (bitmap->color_context) + ID2D1ColorContext_Release(bitmap->color_context); + if (bitmap->surface) + IDXGISurface_Release(bitmap->surface); ID3D10ShaderResourceView_Release(bitmap->view); ID2D1Factory_Release(bitmap->factory); HeapFree(GetProcessHeap(), 0, bitmap); @@ -75,7 +105,7 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_Release(ID2D1Bitmap *iface) return refcount; }
-static void STDMETHODCALLTYPE d2d_bitmap_GetFactory(ID2D1Bitmap *iface, ID2D1Factory **factory) +static void STDMETHODCALLTYPE d2d_bitmap_GetFactory(ID2D1Bitmap1 *iface, ID2D1Factory **factory) { struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap(iface);
@@ -84,7 +114,7 @@ static void STDMETHODCALLTYPE d2d_bitmap_GetFactory(ID2D1Bitmap *iface, ID2D1Fac ID2D1Factory_AddRef(*factory = bitmap->factory); }
-static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_bitmap_GetSize(ID2D1Bitmap *iface, D2D1_SIZE_F *size) +static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_bitmap_GetSize(ID2D1Bitmap1 *iface, D2D1_SIZE_F *size) { struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap(iface);
@@ -95,7 +125,7 @@ static D2D1_SIZE_F * STDMETHODCALLTYPE d2d_bitmap_GetSize(ID2D1Bitmap *iface, D2 return size; }
-static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_bitmap_GetPixelSize(ID2D1Bitmap *iface, D2D1_SIZE_U *pixel_size) +static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_bitmap_GetPixelSize(ID2D1Bitmap1 *iface, D2D1_SIZE_U *pixel_size) { struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap(iface);
@@ -105,7 +135,7 @@ static D2D1_SIZE_U * STDMETHODCALLTYPE d2d_bitmap_GetPixelSize(ID2D1Bitmap *ifac return pixel_size; }
-static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_bitmap_GetPixelFormat(ID2D1Bitmap *iface, D2D1_PIXEL_FORMAT *format) +static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_bitmap_GetPixelFormat(ID2D1Bitmap1 *iface, D2D1_PIXEL_FORMAT *format) { struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap(iface);
@@ -115,7 +145,7 @@ static D2D1_PIXEL_FORMAT * STDMETHODCALLTYPE d2d_bitmap_GetPixelFormat(ID2D1Bitm return format; }
-static void STDMETHODCALLTYPE d2d_bitmap_GetDpi(ID2D1Bitmap *iface, float *dpi_x, float *dpi_y) +static void STDMETHODCALLTYPE d2d_bitmap_GetDpi(ID2D1Bitmap1 *iface, float *dpi_x, float *dpi_y) { struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap(iface);
@@ -125,7 +155,7 @@ static void STDMETHODCALLTYPE d2d_bitmap_GetDpi(ID2D1Bitmap *iface, float *dpi_x *dpi_y = bitmap->dpi_y; }
-static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromBitmap(ID2D1Bitmap *iface, +static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromBitmap(ID2D1Bitmap1 *iface, const D2D1_POINT_2U *dst_point, ID2D1Bitmap *bitmap, const D2D1_RECT_U *src_rect) { FIXME("iface %p, dst_point %p, bitmap %p, src_rect %p stub!\n", iface, dst_point, bitmap, src_rect); @@ -133,7 +163,7 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromBitmap(ID2D1Bitmap *iface, return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromRenderTarget(ID2D1Bitmap *iface, +static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromRenderTarget(ID2D1Bitmap1 *iface, const D2D1_POINT_2U *dst_point, ID2D1RenderTarget *render_target, const D2D1_RECT_U *src_rect) { FIXME("iface %p, dst_point %p, render_target %p, src_rect %p stub!\n", iface, dst_point, render_target, src_rect); @@ -141,7 +171,7 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromRenderTarget(ID2D1Bitmap *if return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromMemory(ID2D1Bitmap *iface, +static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromMemory(ID2D1Bitmap1 *iface, const D2D1_RECT_U *dst_rect, const void *src_data, UINT32 pitch) { struct d2d_bitmap *bitmap = impl_from_ID2D1Bitmap(iface); @@ -170,7 +200,61 @@ static HRESULT STDMETHODCALLTYPE d2d_bitmap_CopyFromMemory(ID2D1Bitmap *iface, return S_OK; }
-static const struct ID2D1BitmapVtbl d2d_bitmap_vtbl = +static void WINAPI d2d_bitmap1_GetColorContext( + ID2D1Bitmap1 *iface, + ID2D1ColorContext **colorContext) +{ + struct d2d_bitmap *This = impl_from_ID2D1Bitmap(iface); + FIXME("%p stub!\n", This); +} + +static D2D1_BITMAP_OPTIONS WINAPI d2d_bitmap1_GetOptions( + ID2D1Bitmap1 *iface) +{ + struct d2d_bitmap *This = impl_from_ID2D1Bitmap(iface); + FIXME("%p stub!\n", This); + return D2D1_BITMAP_OPTIONS_NONE; +} + +static HRESULT WINAPI d2d_bitmap1_GetSurface( + ID2D1Bitmap1 *iface, + IDXGISurface **dxgiSurface) +{ + struct d2d_bitmap *This = impl_from_ID2D1Bitmap(iface); + + TRACE("This %p, dxgiSurface %p.\n", This, dxgiSurface); + if (dxgiSurface == NULL) + return E_POINTER; + + if (This->surface) + { + IDXGISurface_AddRef(This->surface); + } + + *dxgiSurface = This->surface; + + return S_OK; +} + +static HRESULT WINAPI d2d_bitmap1_Map( + ID2D1Bitmap1 *iface, + D2D1_MAP_OPTIONS Options, + D2D1_MAPPED_RECT *mappedRect) +{ + struct d2d_bitmap *This = impl_from_ID2D1Bitmap(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI d2d_bitmap1_Unmap( + ID2D1Bitmap1 *iface) +{ + struct d2d_bitmap *This = impl_from_ID2D1Bitmap(iface); + FIXME("%p stub!\n", This); + return E_NOTIMPL; +} + +static const struct ID2D1Bitmap1Vtbl d2d_bitmap_vtbl = { d2d_bitmap_QueryInterface, d2d_bitmap_AddRef, @@ -183,6 +267,11 @@ static const struct ID2D1BitmapVtbl d2d_bitmap_vtbl = d2d_bitmap_CopyFromBitmap, d2d_bitmap_CopyFromRenderTarget, d2d_bitmap_CopyFromMemory, + d2d_bitmap1_GetColorContext, + d2d_bitmap1_GetOptions, + d2d_bitmap1_GetSurface, + d2d_bitmap1_Map, + d2d_bitmap1_Unmap, };
static BOOL format_supported(const D2D1_PIXEL_FORMAT *format) @@ -221,7 +310,8 @@ static BOOL format_supported(const D2D1_PIXEL_FORMAT *format) }
static void d2d_bitmap_init(struct d2d_bitmap *bitmap, ID2D1Factory *factory, - ID3D10ShaderResourceView *view, D2D1_SIZE_U size, const D2D1_BITMAP_PROPERTIES *desc) + ID3D10ShaderResourceView *view, D2D1_SIZE_U size, const D2D1_BITMAP_PROPERTIES1 *desc, + IDXGISurface *surface) { bitmap->ID2D1Bitmap_iface.lpVtbl = &d2d_bitmap_vtbl; bitmap->refcount = 1; @@ -231,6 +321,12 @@ static void d2d_bitmap_init(struct d2d_bitmap *bitmap, ID2D1Factory *factory, bitmap->format = desc->pixelFormat; bitmap->dpi_x = desc->dpiX; bitmap->dpi_y = desc->dpiY; + bitmap->options = desc->bitmapOptions; + if (surface) + IDXGISurface_AddRef(bitmap->surface = surface); + + if (desc->colorContext) + FIXME("Ignoring ID2D1ColorContext");
if (bitmap->dpi_x == 0.0f && bitmap->dpi_y == 0.0f) { @@ -242,16 +338,18 @@ static void d2d_bitmap_init(struct d2d_bitmap *bitmap, ID2D1Factory *factory, HRESULT d2d_bitmap_create(ID2D1Factory *factory, ID3D10Device *device, D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) { + D2D1_BITMAP_PROPERTIES1 d = bitmap_properties_to_properties1(desc); D3D10_SUBRESOURCE_DATA resource_data; D3D10_TEXTURE2D_DESC texture_desc; ID3D10ShaderResourceView *view; ID3D10Texture2D *texture; + IDXGISurface *surface; HRESULT hr;
- if (!format_supported(&desc->pixelFormat)) + if (!format_supported(&d.pixelFormat)) { WARN("Tried to create bitmap with unsupported format {%#x / %#x}.\n", - desc->pixelFormat.format, desc->pixelFormat.alphaMode); + d.pixelFormat.format, d.pixelFormat.alphaMode); return D2DERR_UNSUPPORTED_PIXEL_FORMAT; }
@@ -259,7 +357,7 @@ HRESULT d2d_bitmap_create(ID2D1Factory *factory, ID3D10Device *device, D2D1_SIZE texture_desc.Height = size.height; texture_desc.MipLevels = 1; texture_desc.ArraySize = 1; - texture_desc.Format = desc->pixelFormat.format; + texture_desc.Format = d.pixelFormat.format; texture_desc.SampleDesc.Count = 1; texture_desc.SampleDesc.Quality = 0; texture_desc.Usage = D3D10_USAGE_DEFAULT; @@ -277,29 +375,109 @@ HRESULT d2d_bitmap_create(ID2D1Factory *factory, ID3D10Device *device, D2D1_SIZE return hr; }
+ if (FAILED(hr = ID3D10Texture2D_QueryInterface(texture, &IID_IDXGISurface, (void **)&surface))) + { + surface = NULL; + WARN("Texture2D had no underlying DXGISurface"); + } + hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)texture, NULL, &view); ID3D10Texture2D_Release(texture); if (FAILED(hr)) { + if (surface) IDXGISurface_Release(surface); ERR("Failed to create view, hr %#x.\n", hr); return hr; }
if ((*bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**bitmap)))) { - d2d_bitmap_init(*bitmap, factory, view, size, desc); + d2d_bitmap_init(*bitmap, factory, view, size, &d, surface); TRACE("Created bitmap %p.\n", *bitmap); }
ID3D10ShaderResourceView_Release(view); + if (surface) IDXGISurface_Release(surface);
return *bitmap ? S_OK : E_OUTOFMEMORY; }
+HRESULT d2d_bitmap_create_shared_from_dxgi_surface(ID2D1Factory *factory, + IDXGISurface *surface, const D2D1_BITMAP_PROPERTIES1 *requested_properties, + ID3D10Device *target_device, struct d2d_bitmap **bitmap) +{ + ID3D10ShaderResourceView *view; + D2D1_BITMAP_PROPERTIES1 desc; + DXGI_SURFACE_DESC surface_desc; + ID3D10Resource *resource; + D2D1_SIZE_U pixel_size; + ID3D10Device *device; + HRESULT hr; + + if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc))) + { + WARN("Failed to get surface desc, hr %#x.\n", hr); + return hr; + } + + if (requested_properties == NULL) + { + desc.pixelFormat.format = surface_desc.Format; + desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; + desc.dpiX = 96.0f; + desc.dpiY = 96.0f; + desc.bitmapOptions = D2D1_BITMAP_OPTIONS_NONE; + desc.colorContext = NULL; + } + else + { + desc = *requested_properties; + } + + pixel_size.width = surface_desc.Width; + pixel_size.height = surface_desc.Height; + + if (FAILED(IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, + (void **)&resource))) + { + WARN("Failed to get d3d10 resource from dxgi surface.\n"); + return E_FAIL; + } + + ID3D10Resource_GetDevice(resource, &device); + if (target_device && device != target_device) + { + ID3D10Device_Release(device); + ID3D10Resource_Release(resource); + return D2DERR_UNSUPPORTED_OPERATION; + } + + hr = ID3D10Device_CreateShaderResourceView(device, resource, NULL, &view); + ID3D10Device_Release(device); + ID3D10Resource_Release(resource); + if (FAILED(hr)) + { + WARN("Failed to create shader resource view, hr %#x.\n", hr); + return hr; + } + + if (!(*bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**bitmap)))) + { + ID3D10ShaderResourceView_Release(view); + return E_OUTOFMEMORY; + } + + d2d_bitmap_init(*bitmap, factory, view, pixel_size, &desc, surface); + ID3D10ShaderResourceView_Release(view); + TRACE("Created bitmap (%p) from surface (%p).\n", *bitmap, surface); + + return S_OK; +} + HRESULT d2d_bitmap_create_shared(ID2D1RenderTarget *render_target, ID3D10Device *target_device, REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) { - D2D1_BITMAP_PROPERTIES d; + D2D1_BITMAP_PROPERTIES1 d = bitmap_properties_to_properties1(desc); ID2D1Factory *factory;
if (IsEqualGUID(iid, &IID_ID2D1Bitmap)) @@ -328,13 +506,12 @@ HRESULT d2d_bitmap_create_shared(ID2D1RenderTarget *render_target, ID3D10Device d.pixelFormat = src_impl->format; d.dpiX = src_impl->dpi_x; d.dpiY = src_impl->dpi_y; - desc = &d; }
- if (!format_supported(&desc->pixelFormat)) + if (!format_supported(&d.pixelFormat)) { WARN("Tried to create bitmap with unsupported format {%#x / %#x}.\n", - desc->pixelFormat.format, desc->pixelFormat.alphaMode); + d.pixelFormat.format, d.pixelFormat.alphaMode); hr = D2DERR_UNSUPPORTED_PIXEL_FORMAT; goto failed; } @@ -345,7 +522,7 @@ HRESULT d2d_bitmap_create_shared(ID2D1RenderTarget *render_target, ID3D10Device goto failed; }
- d2d_bitmap_init(*bitmap, factory, src_impl->view, src_impl->pixel_size, desc); + d2d_bitmap_init(*bitmap, factory, src_impl->view, src_impl->pixel_size, &d, src_impl->surface); TRACE("Created bitmap %p.\n", *bitmap);
failed: @@ -355,43 +532,9 @@ HRESULT d2d_bitmap_create_shared(ID2D1RenderTarget *render_target, ID3D10Device
if (IsEqualGUID(iid, &IID_IDXGISurface) || IsEqualGUID(iid, &IID_IDXGISurface1)) { - ID3D10ShaderResourceView *view; - DXGI_SURFACE_DESC surface_desc; IDXGISurface *surface = data; - ID3D10Resource *resource; - D2D1_SIZE_U pixel_size; - ID3D10Device *device; HRESULT hr;
- if (FAILED(IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&resource))) - { - WARN("Failed to get d3d resource from dxgi surface.\n"); - return E_FAIL; - } - - ID3D10Resource_GetDevice(resource, &device); - ID3D10Device_Release(device); - if (device != target_device) - { - ID3D10Resource_Release(resource); - return D2DERR_UNSUPPORTED_OPERATION; - } - - hr = ID3D10Device_CreateShaderResourceView(target_device, resource, NULL, &view); - ID3D10Resource_Release(resource); - if (FAILED(hr)) - { - WARN("Failed to create shader resource view, hr %#x.\n", hr); - return hr; - } - - if (!(*bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**bitmap)))) - { - ID3D10ShaderResourceView_Release(view); - return E_OUTOFMEMORY; - } - - d = *desc; if (d.dpiX == 0.0f || d.dpiY == 0.0f) { float dpi_x, dpi_y; @@ -403,21 +546,16 @@ HRESULT d2d_bitmap_create_shared(ID2D1RenderTarget *render_target, ID3D10Device d.dpiY = dpi_y; }
- if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc))) + ID2D1RenderTarget_GetFactory(render_target, &factory); + if (FAILED(hr = d2d_bitmap_create_shared_from_dxgi_surface(factory, surface, + &d, target_device, bitmap))) { - WARN("Failed to get surface desc, hr %#x.\n", hr); - ID3D10ShaderResourceView_Release(view); + WARN("Failed to create bitmap from surface, hr %#x.\n", hr); + ID2D1Factory_Release(factory); return hr; }
- pixel_size.width = surface_desc.Width; - pixel_size.height = surface_desc.Height; - - ID2D1RenderTarget_GetFactory(render_target, &factory); - d2d_bitmap_init(*bitmap, factory, view, pixel_size, &d); - ID3D10ShaderResourceView_Release(view); ID2D1Factory_Release(factory); - TRACE("Created bitmap %p.\n", *bitmap);
return S_OK; } @@ -534,6 +672,6 @@ struct d2d_bitmap *unsafe_impl_from_ID2D1Bitmap(ID2D1Bitmap *iface) { if (!iface) return NULL; - assert(iface->lpVtbl == &d2d_bitmap_vtbl); + assert(((ID2D1Bitmap1 *)iface)->lpVtbl == &d2d_bitmap_vtbl); return CONTAINING_RECORD(iface, struct d2d_bitmap, ID2D1Bitmap_iface); } diff --git a/dlls/d2d1/brush.c b/dlls/d2d1/brush.c index ba07006c58..03573df054 100644 --- a/dlls/d2d1/brush.c +++ b/dlls/d2d1/brush.c @@ -863,7 +863,7 @@ static ULONG STDMETHODCALLTYPE d2d_bitmap_brush_Release(ID2D1BitmapBrush *iface) if (brush->u.bitmap.sampler_state) ID3D10SamplerState_Release(brush->u.bitmap.sampler_state); if (brush->u.bitmap.bitmap) - ID2D1Bitmap_Release(&brush->u.bitmap.bitmap->ID2D1Bitmap_iface); + ID2D1Bitmap1_Release(&brush->u.bitmap.bitmap->ID2D1Bitmap_iface); d2d_brush_destroy(brush); }
@@ -970,7 +970,7 @@ static void STDMETHODCALLTYPE d2d_bitmap_brush_SetBitmap(ID2D1BitmapBrush *iface if (bitmap) ID2D1Bitmap_AddRef(bitmap); if (brush->u.bitmap.bitmap) - ID2D1Bitmap_Release(&brush->u.bitmap.bitmap->ID2D1Bitmap_iface); + ID2D1Bitmap1_Release(&brush->u.bitmap.bitmap->ID2D1Bitmap_iface); brush->u.bitmap.bitmap = unsafe_impl_from_ID2D1Bitmap(bitmap); }
@@ -1007,7 +1007,7 @@ static void STDMETHODCALLTYPE d2d_bitmap_brush_GetBitmap(ID2D1BitmapBrush *iface
TRACE("iface %p, bitmap %p.\n", iface, bitmap);
- if ((*bitmap = &brush->u.bitmap.bitmap->ID2D1Bitmap_iface)) + if ((*bitmap = (ID2D1Bitmap *)&brush->u.bitmap.bitmap->ID2D1Bitmap_iface)) ID2D1Bitmap_AddRef(*bitmap); }
@@ -1040,7 +1040,7 @@ HRESULT d2d_bitmap_brush_create(ID2D1Factory *factory, ID2D1Bitmap *bitmap, cons d2d_brush_init(*brush, factory, D2D_BRUSH_TYPE_BITMAP, brush_desc, (ID2D1BrushVtbl *)&d2d_bitmap_brush_vtbl); if (((*brush)->u.bitmap.bitmap = unsafe_impl_from_ID2D1Bitmap(bitmap))) - ID2D1Bitmap_AddRef(&(*brush)->u.bitmap.bitmap->ID2D1Bitmap_iface); + ID2D1Bitmap1_AddRef(&(*brush)->u.bitmap.bitmap->ID2D1Bitmap_iface); if (bitmap_brush_desc) { (*brush)->u.bitmap.extend_mode_x = bitmap_brush_desc->extendModeX; diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index dd76a14af4..7a3d39fb9d 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -323,7 +323,8 @@ HRESULT d2d_mesh_create(ID2D1Factory *factory, struct d2d_mesh **mesh) DECLSPEC_
struct d2d_bitmap { - ID2D1Bitmap ID2D1Bitmap_iface; + ID2D1Bitmap1 ID2D1Bitmap_iface; + LONG refcount;
ID2D1Factory *factory; @@ -332,10 +333,15 @@ struct d2d_bitmap D2D1_PIXEL_FORMAT format; float dpi_x; float dpi_y; + D2D1_BITMAP_OPTIONS options; + ID2D1ColorContext *color_context; + IDXGISurface *surface; };
HRESULT d2d_bitmap_create(ID2D1Factory *factory, ID3D10Device *device, D2D1_SIZE_U size, const void *src_data, UINT32 pitch, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; +HRESULT d2d_bitmap_create_shared_from_dxgi_surface(ID2D1Factory *factory, IDXGISurface *surface, + const D2D1_BITMAP_PROPERTIES1 *desc, ID3D10Device *target_device, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; HRESULT d2d_bitmap_create_shared(ID2D1RenderTarget *render_target, ID3D10Device *device, REFIID iid, void *data, const D2D1_BITMAP_PROPERTIES *desc, struct d2d_bitmap **bitmap) DECLSPEC_HIDDEN; HRESULT d2d_bitmap_create_from_wic_bitmap(ID2D1Factory *factory, ID3D10Device *device, IWICBitmapSource *bitmap_source, diff --git a/dlls/d2d1/device_context.c b/dlls/d2d1/device_context.c index 30657e260d..3ce52ec672 100644 --- a/dlls/d2d1/device_context.c +++ b/dlls/d2d1/device_context.c @@ -718,8 +718,28 @@ static HRESULT WINAPI d2d_device_context_CreateBitmapFromDxgiSurface( ID2D1Bitmap1 **bitmap) { struct d2d_device_context *This = impl_from_ID2D1DeviceContext(iface); - FIXME("%p stub!\n", This); - return E_NOTIMPL; + struct d2d_bitmap *bitmap_impl; + HRESULT hr; + ID2D1Factory *factory; + + TRACE("This %p, surface %p, bitmapProperties %p, bitmap %p.\n", + This, surface, bitmapProperties, bitmap); + if (surface == NULL || bitmap == NULL) + return E_POINTER; + + ID2D1Device_GetFactory(This->device, &factory); + hr = d2d_bitmap_create_shared_from_dxgi_surface(factory, surface, + bitmapProperties, NULL, &bitmap_impl); + ID2D1Factory_Release(factory); + if (FAILED(hr)) + { + WARN("Failed to create bitmap, hr %#x.\n", hr); + return hr; + } + + *bitmap = &bitmap_impl->ID2D1Bitmap_iface; + + return S_OK; }
static HRESULT WINAPI d2d_device_context_CreateEffect( diff --git a/dlls/d2d1/render_target.c b/dlls/d2d1/render_target.c index aa96b8f8ac..afab3910f7 100644 --- a/dlls/d2d1/render_target.c +++ b/dlls/d2d1/render_target.c @@ -299,7 +299,7 @@ static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmap(ID2D1RenderT iface, size.width, size.height, src_data, pitch, desc, bitmap);
if (SUCCEEDED(hr = d2d_bitmap_create(render_target->factory, render_target->device, size, src_data, pitch, desc, &object))) - *bitmap = &object->ID2D1Bitmap_iface; + *bitmap = (ID2D1Bitmap *)&object->ID2D1Bitmap_iface;
return hr; } @@ -316,7 +316,7 @@ static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateBitmapFromWicBitmap
if (SUCCEEDED(hr = d2d_bitmap_create_from_wic_bitmap(render_target->factory, render_target->device, bitmap_source, desc, &object))) - *bitmap = &object->ID2D1Bitmap_iface; + *bitmap = (ID2D1Bitmap *)&object->ID2D1Bitmap_iface;
return hr; } @@ -332,7 +332,7 @@ static HRESULT STDMETHODCALLTYPE d2d_d3d_render_target_CreateSharedBitmap(ID2D1R iface, debugstr_guid(iid), data, desc, bitmap);
if (SUCCEEDED(hr = d2d_bitmap_create_shared(iface, render_target->device, iid, data, desc, &object))) - *bitmap = &object->ID2D1Bitmap_iface; + *bitmap = (ID2D1Bitmap *)&object->ID2D1Bitmap_iface;
return hr; } diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 77591708bd..6414fe391b 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -4697,7 +4697,6 @@ static void test_draw_via_ID2D1DeviceContext(void) bitmap_properties.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW; hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(context, dxgi_surface, &bitmap_properties, &bitmap); - todo_wine ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr); if (FAILED(hr)) { @@ -4711,10 +4710,8 @@ static void test_draw_via_ID2D1DeviceContext(void) ID2D1DeviceContext_BeginDraw(context); ID2D1DeviceContext_DrawRectangle(context, &r, (ID2D1Brush *)brush, 1.0f, NULL); hr = ID2D1DeviceContext_EndDraw(context, NULL, NULL); - todo_wine ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr); hr = IDXGISwapChain_Present(swapchain, 0, 0); - todo_wine ok(SUCCEEDED(hr), "Failed to present image, hr %#x.\n", hr);
ID2D1SolidColorBrush_Release(brush);