X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Ftrunk%2Fsrc%2Fsynfig%2Fcanvas.cpp;h=270a71f78a99dc546fbead7dd68f7cd1a0856c56;hb=34d470416675482ca866146fd6b3201a19f8e4e6;hp=967bc60e5f013da2c27f36464af5ee692fbfbca0;hpb=3e363592f62521ca3e0338f474deb1eb253f9e74;p=synfig.git diff --git a/synfig-core/trunk/src/synfig/canvas.cpp b/synfig-core/trunk/src/synfig/canvas.cpp index 967bc60..270a71f 100644 --- a/synfig-core/trunk/src/synfig/canvas.cpp +++ b/synfig-core/trunk/src/synfig/canvas.cpp @@ -1170,6 +1170,30 @@ synfig::optimize_layers(Time time, Context context, Canvas::Handle op_canvas, bo dynamic_cast(new_layer.get())->set_muck_with_time(true); layer=new_layer; } + else // not a PasteCanvas - does it use blend method 'Straight'? + { + /* when we use the 'straight' blend method, every pixel on the layer affects the layers underneath, + * not just the non-transparent pixels; the following workarea wraps non-pastecanvas layers in a + * new pastecanvas to ensure that the straight blend affects the full plane, not just the area + * within the layer's bounding box + */ + + // \todo: this code probably needs modification to work properly with motionblur and duplicate + etl::handle composite = etl::handle::cast_dynamic(layer); + if (composite && composite->get_blend_method() == Color::BLEND_STRAIGHT) + { + Canvas::Handle sub_canvas(Canvas::create_inline(op_canvas)); + sub_canvas->push_back(composite = composite->clone()); + sub_canvas->set_time(time); // region and outline don't calculate their bounding rects until their time is set + layer = Layer::create("PasteCanvas"); + layer->set_description(strprintf("PasteCanvas wrapper for '%s'", composite->get_non_empty_description().c_str())); + Layer_PasteCanvas* paste_canvas(static_cast(layer.get())); + paste_canvas->set_sub_canvas(sub_canvas); + paste_canvas->set_blend_method(Color::BLEND_STRAIGHT); + paste_canvas->set_amount(composite->get_amount()); + composite->set_amount(1.0f); + } + } sort_list.push_back(std::pair(z_depth,layer)); //op_canvas->push_back_simple(layer);