From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/command_list.c | 49 ++++++++++++++++++++++++++++++++++++++++ dlls/d2d1/d2d1_private.h | 3 +++ dlls/d2d1/device.c | 21 +++++++++++++++++ 3 files changed, 73 insertions(+)
diff --git a/dlls/d2d1/command_list.c b/dlls/d2d1/command_list.c index f5e3bd22246..bed650516ac 100644 --- a/dlls/d2d1/command_list.c +++ b/dlls/d2d1/command_list.c @@ -46,7 +46,9 @@ enum d2d_command_type D2D_COMMAND_FILL_GEOMETRY, D2D_COMMAND_FILL_RECTANGLE, D2D_COMMAND_PUSH_CLIP, + D2D_COMMAND_PUSH_LAYER, D2D_COMMAND_POP_CLIP, + D2D_COMMAND_POP_LAYER, };
struct d2d_command @@ -110,6 +112,13 @@ struct d2d_command_push_clip D2D1_ANTIALIAS_MODE mode; };
+struct d2d_command_push_layer +{ + struct d2d_command c; + D2D1_LAYER_PARAMETERS1 params; + ID2D1Layer *layer; +}; + struct d2d_command_draw_line { struct d2d_command c; @@ -435,9 +444,18 @@ static HRESULT STDMETHODCALLTYPE d2d_command_list_Stream(ID2D1CommandList *iface hr = ID2D1CommandSink_PushAxisAlignedClip(sink, &c->rect, c->mode); break; } + case D2D_COMMAND_PUSH_LAYER: + { + const struct d2d_command_push_layer *c = data; + hr = ID2D1CommandSink_PushLayer(sink, &c->params, c->layer); + break; + } case D2D_COMMAND_POP_CLIP: hr = ID2D1CommandSink_PopAxisAlignedClip(sink); break; + case D2D_COMMAND_POP_LAYER: + hr = ID2D1CommandSink_PopLayer(sink); + break; default: FIXME("Unhandled command %u.\n", command->op); hr = E_UNEXPECTED; @@ -694,6 +712,37 @@ void d2d_command_list_pop_clip(struct d2d_command_list *command_list) command->op = D2D_COMMAND_POP_CLIP; }
+void d2d_command_list_push_layer(struct d2d_command_list *command_list, const struct d2d_device_context *context, + const D2D1_LAYER_PARAMETERS1 *params, ID2D1Layer *layer) +{ + struct d2d_command_push_layer *command; + ID2D1Brush *opacity_brush = NULL; + + if (params->opacityBrush && FAILED(d2d_command_list_create_brush(command_list, context, + params->opacityBrush, &opacity_brush))) + { + command_list->state = D2D_COMMAND_LIST_STATE_ERROR; + return; + } + + d2d_command_list_reference_object(command_list, layer); + d2d_command_list_reference_object(command_list, params->geometricMask); + + command = d2d_command_list_require_space(command_list, sizeof(*command)); + command->c.op = D2D_COMMAND_PUSH_LAYER; + command->params = *params; + command->params.opacityBrush = opacity_brush; + command->layer = layer; +} + +void d2d_command_list_pop_layer(struct d2d_command_list *command_list) +{ + struct d2d_command *command; + + command = d2d_command_list_require_space(command_list, sizeof(*command)); + command->op = D2D_COMMAND_POP_LAYER; +} + void d2d_command_list_clear(struct d2d_command_list *command_list, const D2D1_COLOR_F *color) { struct d2d_command_clear *command; diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h index b309427b355..085febe95e7 100644 --- a/dlls/d2d1/d2d1_private.h +++ b/dlls/d2d1/d2d1_private.h @@ -776,6 +776,9 @@ void d2d_command_list_fill_mesh(struct d2d_command_list *command_list, const str ID2D1Mesh *mesh, ID2D1Brush *orig_brush) DECLSPEC_HIDDEN; void d2d_command_list_fill_opacity_mask(struct d2d_command_list *command_list, const struct d2d_device_context *context, ID2D1Bitmap *bitmap, ID2D1Brush *orig_brush, const D2D1_RECT_F *dst_rect, const D2D1_RECT_F *src_rect) DECLSPEC_HIDDEN; +void d2d_command_list_push_layer(struct d2d_command_list *command_list, const struct d2d_device_context *context, + const D2D1_LAYER_PARAMETERS1 *params, ID2D1Layer *layer) DECLSPEC_HIDDEN; +void d2d_command_list_pop_layer(struct d2d_command_list *command_list) DECLSPEC_HIDDEN;
static inline BOOL d2d_array_reserve(void **elements, size_t *capacity, size_t count, size_t size) { diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index 6a671ba2818..32519f662c9 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -1696,12 +1696,28 @@ static void STDMETHODCALLTYPE d2d_device_context_GetTags(ID2D1DeviceContext1 *if static void STDMETHODCALLTYPE d2d_device_context_PushLayer(ID2D1DeviceContext1 *iface, const D2D1_LAYER_PARAMETERS *layer_parameters, ID2D1Layer *layer) { + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + FIXME("iface %p, layer_parameters %p, layer %p stub!\n", iface, layer_parameters, layer); + + if (context->target.type == D2D_TARGET_COMMAND_LIST) + { + D2D1_LAYER_PARAMETERS1 parameters; + + memcpy(¶meters, layer_parameters, sizeof(*layer_parameters)); + parameters.layerOptions = D2D1_LAYER_OPTIONS1_NONE; + d2d_command_list_push_layer(context->target.command_list, context, ¶meters, layer); + } }
static void STDMETHODCALLTYPE d2d_device_context_PopLayer(ID2D1DeviceContext1 *iface) { + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + FIXME("iface %p stub!\n", iface); + + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_pop_layer(context->target.command_list); }
static HRESULT STDMETHODCALLTYPE d2d_device_context_Flush(ID2D1DeviceContext1 *iface, D2D1_TAG *tag1, D2D1_TAG *tag2) @@ -2564,7 +2580,12 @@ static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_DrawBitmap(I static void STDMETHODCALLTYPE d2d_device_context_ID2D1DeviceContext_PushLayer(ID2D1DeviceContext1 *iface, const D2D1_LAYER_PARAMETERS1 *layer_parameters, ID2D1Layer *layer) { + struct d2d_device_context *context = impl_from_ID2D1DeviceContext(iface); + FIXME("iface %p, layer_parameters %p, layer %p stub!\n", iface, layer_parameters, layer); + + if (context->target.type == D2D_TARGET_COMMAND_LIST) + d2d_command_list_push_layer(context->target.command_list, context, layer_parameters, layer); }
static HRESULT STDMETHODCALLTYPE d2d_device_context_InvalidateEffectInputRectangle(ID2D1DeviceContext1 *iface,