From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- include/d2d1_2.idl | 12 +++++++++ include/d2d1_3.idl | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+)
diff --git a/include/d2d1_2.idl b/include/d2d1_2.idl index 1fc9111151c..982131667df 100644 --- a/include/d2d1_2.idl +++ b/include/d2d1_2.idl @@ -89,3 +89,15 @@ interface ID2D1Factory2 : ID2D1Factory1 [out] ID2D1Device1 **device ); } + +[ + object, + uuid(9eb767fd-4269-4467-b8c2-eb30cb305743), + local, +] +interface ID2D1CommandSink1 : ID2D1CommandSink +{ + HRESULT SetPrimitiveBlend1( + [in] D2D1_PRIMITIVE_BLEND primitive_blend + ); +} diff --git a/include/d2d1_3.idl b/include/d2d1_3.idl index 07dc98968f8..29bcc8df56d 100644 --- a/include/d2d1_3.idl +++ b/include/d2d1_3.idl @@ -19,6 +19,8 @@ import "d2d1_2.idl"; import "d2d1effects_2.idl";
+interface ID2D1SpriteBatch; + typedef enum D2D1_INK_NIB_SHAPE { D2D1_INK_NIB_SHAPE_ROUND = 0x0, @@ -69,6 +71,13 @@ typedef enum D2D1_IMAGE_SOURCE_FROM_DXGI_OPTIONS D2D1_IMAGE_SOURCE_FROM_DXGI_OPTIONS_FORCE_DWORD = 0xffffffff } D2D1_IMAGE_SOURCE_FROM_DXGI_OPTIONS;
+typedef enum D2D1_SPRITE_OPTIONS +{ + D2D1_SPRITE_OPTIONS_NONE = 0x0, + D2D1_SPRITE_OPTIONS_CLAMP_TO_SOURCE_RECTANGLE = 0x1, + D2D1_SPRITE_OPTIONS_FORCE_DWORD = 0xffffffff +} D2D1_SPRITE_OPTIONS; + typedef struct D2D1_INK_POINT { float x; @@ -356,3 +365,56 @@ interface ID2D1Factory3 : ID2D1Factory2 [out] ID2D1Device2 **d2d_device ); } + +[ + object, + uuid(3bab440e-417e-47df-a2e2-bc0be6a00916), + local, +] +interface ID2D1CommandSink2 : ID2D1CommandSink1 +{ + HRESULT DrawInk( + [in] ID2D1Ink *ink, + [in] ID2D1Brush *brush, + [in] ID2D1InkStyle *ink_style + ); + + HRESULT DrawGradientMesh( + [in] ID2D1GradientMesh *gradient_mesh + ); + + HRESULT DrawGdiMetafile( + [in] ID2D1GdiMetafile *gdi_metafile, + [in] const D2D1_RECT_F *dest_rect, + [in] const D2D1_RECT_F *src_rect + ); +} + +[ + object, + uuid(18079135-4cf3-4868-bc8e-06067e6d242d), + local, +] +interface ID2D1CommandSink3 : ID2D1CommandSink2 +{ + HRESULT DrawSpriteBatch( + [in] ID2D1SpriteBatch *sprite_batch, + [in] UINT32 start_index, + [in] UINT32 sprite_count, + [in] ID2D1Bitmap *bitmap, + [in] D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode, + [in] D2D1_SPRITE_OPTIONS sprite_options + ); +} + +[ + object, + uuid(c78a6519-40d6-4218-b2de-beeeb744bb3e), + local, +] +interface ID2D1CommandSink4 : ID2D1CommandSink3 +{ + HRESULT SetPrimitiveBlend2( + [in] D2D1_PRIMITIVE_BLEND primitive_blend + ); +}
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/device.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index d25ad3a9d78..0d08ddd4cb5 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -2414,14 +2414,29 @@ static void STDMETHODCALLTYPE d2d_device_context_GetRenderingControls(ID2D1Devic static void STDMETHODCALLTYPE d2d_device_context_SetPrimitiveBlend(ID2D1DeviceContext1 *iface, D2D1_PRIMITIVE_BLEND primitive_blend) { - FIXME("iface %p, primitive_blend %#x stub!\n", iface, primitive_blend); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + + TRACE("iface %p, primitive_blend %u.\n", iface, primitive_blend); + + if (primitive_blend > D2D1_PRIMITIVE_BLEND_MAX) + { + WARN("Unknown blend mode %u.\n", primitive_blend); + return; + } + + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_set_primitive_blend(context->target.command_list, primitive_blend); + + context->drawing_state.primitiveBlend = primitive_blend; }
static D2D1_PRIMITIVE_BLEND STDMETHODCALLTYPE d2d_device_context_GetPrimitiveBlend(ID2D1DeviceContext1 *iface) { - FIXME("iface %p stub!\n", iface); + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + + TRACE("iface %p.\n", iface);
- return D2D1_PRIMITIVE_BLEND_SOURCE_OVER; + return context->drawing_state.primitiveBlend; }
static void STDMETHODCALLTYPE d2d_device_context_SetUnitMode(ID2D1DeviceContext1 *iface, D2D1_UNIT_MODE unit_mode)
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/command_list.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/dlls/d2d1/command_list.c b/dlls/d2d1/command_list.c index 0d40b59b2c1..664b2f1a412 100644 --- a/dlls/d2d1/command_list.c +++ b/dlls/d2d1/command_list.c @@ -297,7 +297,38 @@ static HRESULT STDMETHODCALLTYPE d2d_command_list_Stream(ID2D1CommandList *iface case D2D_COMMAND_SET_PRIMITIVE_BLEND: { const struct d2d_command_set_primitive_blend *c = data; - hr = ID2D1CommandSink_SetPrimitiveBlend(sink, c->primitive_blend); + ID2D1CommandSink1 *sink1; + ID2D1CommandSink4 *sink4; + + switch (c->primitive_blend) + { + case D2D1_PRIMITIVE_BLEND_SOURCE_OVER: + case D2D1_PRIMITIVE_BLEND_COPY: + hr = ID2D1CommandSink_SetPrimitiveBlend(sink, c->primitive_blend); + break; + case D2D1_PRIMITIVE_BLEND_MIN: + case D2D1_PRIMITIVE_BLEND_ADD: + if (SUCCEEDED(ID2D1CommandSink_QueryInterface(sink, &IID_ID2D1CommandSink1, (void **)&sink1))) + { + hr = ID2D1CommandSink1_SetPrimitiveBlend1(sink1, c->primitive_blend); + ID2D1CommandSink1_Release(sink1); + } + else + hr = ID2D1CommandSink_SetPrimitiveBlend(sink, D2D1_PRIMITIVE_BLEND_SOURCE_OVER); + break; + case D2D1_PRIMITIVE_BLEND_MAX: + if (SUCCEEDED(ID2D1CommandSink_QueryInterface(sink, &IID_ID2D1CommandSink4, (void **)&sink4))) + { + hr = ID2D1CommandSink4_SetPrimitiveBlend2(sink4, c->primitive_blend); + ID2D1CommandSink4_Release(sink4); + } + else + hr = ID2D1CommandSink_SetPrimitiveBlend(sink, D2D1_PRIMITIVE_BLEND_SOURCE_OVER); + break; + default: + FIXME("Unexpected blend mode %u.\n", c->primitive_blend); + hr = E_UNEXPECTED; + } break; } case D2D_COMMAND_SET_UNIT_MODE: