X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Ftrunk%2Fsrc%2Fsynfig%2Fcanvas.cpp;h=c51507a0607fe11505b72b3b832cbe58cca3841d;hb=3f11cd07d0b39fbd614ca1f8b0eb903dc5571fc8;hp=270a71f78a99dc546fbead7dd68f7cd1a0856c56;hpb=a50de53f5e4b23b1e3c0d79866a8503758422dba;p=synfig.git diff --git a/synfig-core/trunk/src/synfig/canvas.cpp b/synfig-core/trunk/src/synfig/canvas.cpp index 270a71f..c51507a 100644 --- a/synfig-core/trunk/src/synfig/canvas.cpp +++ b/synfig-core/trunk/src/synfig/canvas.cpp @@ -90,6 +90,19 @@ Canvas::on_changed() Canvas::~Canvas() { + // we were having a crash where pastecanvas layers were still + // refering to a canvas after it had been destroyed; this code + // will stop the pastecanvas layers from refering to the canvas + // before the canvas is destroyed + for (std::set::iterator iter = parent_set.begin(); iter != parent_set.end(); iter++) + { + Layer_PasteCanvas* paste_canvas = dynamic_cast(*iter); + if(paste_canvas) + paste_canvas->set_sub_canvas(0); + else + warning("destroyed canvas has a parent that is not a pastecanvas - please report if repeatable"); + } + //if(is_inline() && parent_) assert(0); _CanvasCounter::counter--; clear(); @@ -1180,18 +1193,33 @@ synfig::optimize_layers(Time time, Context context, Canvas::Handle op_canvas, bo // \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) + + /* some layers (such as circle) don't touch pixels that aren't + * part of the circle, so they don't get blended correctly when + * using a straight blend. so we encapsulate the circle, and the + * encapsulation layer takes care of the transparent pixels + * for us. if we do that for all layers, however, then the + * distortion layers no longer work, since they have no + * context to work on. the Layer::reads_context() method + * returns true for layers which need to be able to see + * their context. we can't encapsulate those. + */ + if (composite && + Color::is_straight(composite->get_blend_method()) && + !composite->reads_context()) { 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"); + composite->set_description(strprintf("Wrapped clone of '%s'", composite->get_non_empty_description().c_str())); 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_blend_method(composite->get_blend_method()); paste_canvas->set_amount(composite->get_amount()); - composite->set_amount(1.0f); + sub_canvas->set_time(time); // region and outline don't calculate their bounding rects until their time is set + composite->set_blend_method(Color::BLEND_STRAIGHT); // do this before calling set_sub_canvas(), but after set_time() + composite->set_amount(1.0f); // after set_time() + paste_canvas->set_sub_canvas(sub_canvas); } }