**
** \legal
** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2007 Chris Moore
+** Copyright (c) 2007, 2008 Chris Moore
**
** This package is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License as
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
+
+ // the set_sub_canvas(0) ends up deleting the parent-child link,
+ // which deletes the current element from the set we're iterating
+ // through, so we have to make sure we've incremented the iterator
+ // before we mess with the pastecanvas
+ std::set<Node*>::iterator iter = parent_set.begin();
+ while (iter != parent_set.end())
+ {
+ Layer_PasteCanvas* paste_canvas = dynamic_cast<Layer_PasteCanvas*>(*iter);
+ 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();
return id;
}
-
ValueNode::Handle
Canvas::find_value_node(const String &id)
{
x->set_id("");
}
-
etl::handle<Canvas>
Canvas::surefind_canvas(const String &id)
{
return child_canvas->find_canvas(string(id,id.find_first_of(':')+1));
}
-
Canvas::Handle
Canvas::create()
{
x->set_canvas(this);
-
add_child(x.get());
-
LooseHandle correct_canvas(this);
//while(correct_canvas->is_inline())correct_canvas=correct_canvas->parent();
Layer::LooseHandle loose_layer(x);
&Canvas::remove_group_pair),
loose_layer))));
-
if(!x->get_group().empty())
add_group_pair(x->get_group(),x);
-
changed();
}
// it was failing to ascertain the absolute pathname of the imported image, since it needs the pathname
// of the canvas to get that, which is stored in the parent canvas
canvas->parent_=parent();
+ canvas->rend_desc() = rend_desc();
//canvas->set_inline(parent());
}
return dirname(file_name_);
}
-
String
Canvas::get_meta_data(const String& key)const
{
// \todo: this code probably needs modification to work properly with motionblur and duplicate
etl::handle<Layer_Composite> composite = etl::handle<Layer_Composite>::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_PasteCanvas*>(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);
}
}