1 /* === S Y N F I G ========================================================= */
2 /*!	\file layer.cpp
3 **	\brief Layer class implementation
4 **
5 **	$Id$
6 **
7 **	\legal
8 **	Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **	Copyright (c) 2007, 2008 Chris Moore
10 **	Copyright (c) 2011-2013 Carlos López
11 **
12 **	This package is free software; you can redistribute it and/or
13 **	modify it under the terms of the GNU General Public License as
14 **	published by the Free Software Foundation; either version 2 of
15 **	the License, or (at your option) any later version.
16 **
17 **	This package is distributed in the hope that it will be useful,
18 **	but WITHOUT ANY WARRANTY; without even the implied warranty of
19 **	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 **	General Public License for more details.
21 **	\endlegal
22 */
23 /* ========================================================================= */
24 
25 /* === H E A D E R S ======================================================= */
26 
27 #ifdef USING_PCH
28 #	include "pch.h"
29 #else
30 #ifdef HAVE_CONFIG_H
31 #	include <config.h>
32 #endif
33 
34 #include <sigc++/adaptors/bind.h>
35 
36 #include "layer.h"
37 
38 #include "general.h"
39 #include <synfig/localization.h>
40 #include "rect.h"
41 #include "guid.h"
42 #include "value.h"
43 #include "render.h"
44 #include "canvas.h"
45 #include "context.h"
46 #include "surface.h"
47 #include "paramdesc.h"
48 #include "transform.h"
49 
50 #include "layers/layer_composite.h"
51 #include "layers/layer_bitmap.h"
52 #include "layers/layer_duplicate.h"
53 #include "layers/layer_filtergroup.h"
54 #include "layers/layer_group.h"
55 #include "layers/layer_mime.h"
56 #include "layers/layer_motionblur.h"
57 #include "layers/layer_polygon.h"
58 #include "layers/layer_skeleton.h"
59 #include "layers/layer_skeletondeformation.h"
60 #include "layers/layer_solidcolor.h"
61 #include "layers/layer_sound.h"
62 #include "layers/layer_switch.h"
63 
64 #include "valuenodes/valuenode_const.h"
65 
66 #include "rendering/common/task/tasklayer.h"
67 #include "rendering/common/task/tasksurfaceempty.h"
68 
69 #include "importer.h"
70 
71 #endif
72 
73 /* === U S I N G =========================================================== */
74 
75 using namespace etl;
76 using namespace std;
77 using namespace synfig;
78 
79 /* === G L O B A L S ======================================================= */
80 
81 static Layer::Book* _layer_book;
82 
83 struct _LayerCounter
84 {
85 	static int counter;
~_LayerCounter_LayerCounter86 	~_LayerCounter()
87 	{
88 		if (counter)
89 			synfig::error("%d layers not yet deleted!",counter);
90 	}
91 } _layer_counter;
92 
93 int _LayerCounter::counter(0);
94 
95 /* === P R O C E D U R E S ================================================= */
96 
97 Layer::Book&
book()98 Layer::book()
99 {
100 	return *_layer_book;
101 }
102 
103 void
register_in_book(const BookEntry & entry)104 Layer::register_in_book(const BookEntry &entry)
105 {
106 	book()[entry.name]=entry;
107 }
108 
109 bool
subsys_init()110 Layer::subsys_init()
111 {
112 	_layer_book=new Book();
113 
114 #define INCLUDE_LAYER(class)									\
115 	synfig::Layer::book() [synfig::String(class::name__)] =		\
116 		BookEntry(class::create,								\
117 				  class::name__,								\
118 				  dgettext("synfig", class::local_name__),		\
119 				  class::category__,							\
120 				  class::cvs_id__,								\
121 				  class::version__)
122 
123 #define LAYER_ALIAS(class,alias)								\
124 	synfig::Layer::book()[synfig::String(alias)] =				\
125 		BookEntry(class::create,								\
126 				  alias,										\
127 				  alias,										\
128 				  CATEGORY_DO_NOT_USE,							\
129 				  class::cvs_id__,								\
130 				  class::version__)
131 
132 	INCLUDE_LAYER(Layer_SolidColor);
133 		LAYER_ALIAS(Layer_SolidColor,	"solid_color");
134 	INCLUDE_LAYER(Layer_FilterGroup);
135 	INCLUDE_LAYER(Layer_Group);
136 		LAYER_ALIAS(Layer_Group,		"paste_canvas");
137 		LAYER_ALIAS(Layer_Group,		"PasteCanvas");
138 	INCLUDE_LAYER(Layer_Switch);
139 	INCLUDE_LAYER(Layer_Polygon);
140 		LAYER_ALIAS(Layer_Polygon,		"Polygon");
141 	INCLUDE_LAYER(Layer_MotionBlur);
142 		LAYER_ALIAS(Layer_MotionBlur,	"motion_blur");
143 	INCLUDE_LAYER(Layer_Duplicate);
144 	INCLUDE_LAYER(Layer_Skeleton);
145 	INCLUDE_LAYER(Layer_SkeletonDeformation);
146 	INCLUDE_LAYER(Layer_Sound);
147 
148 #undef LAYER_ALIAS
149 #undef INCLUDE_LAYER
150 
151 	return true;
152 }
153 
154 bool
subsys_stop()155 Layer::subsys_stop()
156 {
157 	delete _layer_book;
158 	return true;
159 }
160 
161 /* === M E T H O D S ======================================================= */
162 
Layer()163 Layer::Layer():
164 	active_(true),
165 	optimized_(false),
166 	exclude_from_rendering_(false),
167 	param_z_depth(Real(0.0f)),
168 	time_mark(Time::end()),
169 	outline_grow_mark(0.0)
170 {
171 	_LayerCounter::counter++;
172 	SET_INTERPOLATION_DEFAULTS();
173 	SET_STATIC_DEFAULTS();
174 }
175 
176 Layer::LooseHandle
create(const String & name)177 synfig::Layer::create(const String &name)
178 {
179 	if(!book().count(name))
180 	{
181 		return Layer::LooseHandle(new Layer_Mime(name));
182 	}
183 
184 	Layer* layer(book()[name].factory());
185 	return Layer::LooseHandle(layer);
186 }
187 
~Layer()188 synfig::Layer::~Layer()
189 {
190 	if (monitor_connection) monitor_connection.disconnect(); // disconnect signal handler
191 
192 	_LayerCounter::counter--;
193 
194 	while(!dynamic_param_list_.empty())
195 	{
196 		remove_child(dynamic_param_list_.begin()->second.get());
197 		dynamic_param_list_.erase(dynamic_param_list_.begin());
198 	}
199 
200 	remove_from_all_groups();
201 
202 	parent_death_connect_.disconnect();
203 	begin_delete();
204 }
205 
206 void
set_canvas(etl::loose_handle<Canvas> x)207 synfig::Layer::set_canvas(etl::loose_handle<Canvas> x)
208 {
209 	if(canvas_!=x)
210 	{
211 		parent_death_connect_.disconnect();
212 		canvas_=x;
213 		if(x)
214 		{
215 			parent_death_connect_=x->signal_deleted().connect(
216 				sigc::bind(
217 					sigc::mem_fun(
218 						*this,
219 						&Layer::set_canvas
220 					),
221 					etl::loose_handle<synfig::Canvas>(0)
222 				)
223 			);
224 		}
225 		on_canvas_set();
226 	}
227 }
228 
229 void
on_canvas_set()230 synfig::Layer::on_canvas_set()
231 	{ }
232 
233 void
on_static_param_changed(const String &)234 synfig::Layer::on_static_param_changed(const String & /* param */)
235 	{ }
236 
237 void
on_dynamic_param_changed(const String &)238 synfig::Layer::on_dynamic_param_changed(const String & /* param */)
239 	{ }
240 
241 
242 etl::loose_handle<synfig::Canvas>
get_canvas() const243 synfig::Layer::get_canvas()const
244 {
245 	return canvas_;
246 }
247 
248 int
get_depth() const249 Layer::get_depth()const
250 {
251 	if(!get_canvas())
252 		return -1;
253 	return get_canvas()->get_depth(const_cast<synfig::Layer*>(this));
254 }
255 
256 void
set_active(bool x)257 Layer::set_active(bool x)
258 {
259 	if(active_!=x)
260 	{
261 		active_=x;
262 
263 		Node::on_changed();
264 		signal_status_changed_();
265 	}
266 }
267 
268 void
set_exclude_from_rendering(bool x)269 Layer::set_exclude_from_rendering(bool x)
270 {
271 	if(exclude_from_rendering_!=x)
272 	{
273 		exclude_from_rendering_=x;
274 
275 		Node::on_changed();
276 		signal_status_changed_();
277 	}
278 }
279 
280 void
set_description(const String & x)281 Layer::set_description(const String& x)
282 {
283 	if(description_!=x)
284 	{
285 		description_=x;
286 		signal_description_changed_();
287 	}
288 }
289 
290 void
static_param_changed(const String & param)291 Layer::static_param_changed(const String &param)
292 {
293 	on_static_param_changed(param);
294 	if (!dynamic_param_list().count(param))
295 		signal_static_param_changed_(param);
296 }
297 
298 void
dynamic_param_changed(const String & param)299 Layer::dynamic_param_changed(const String &param)
300 {
301 	on_dynamic_param_changed(param);
302 	if (!dynamic_param_list().count(param))
303 		signal_dynamic_param_changed_(param);
304 }
305 
306 bool
connect_dynamic_param(const String & param,etl::loose_handle<ValueNode> value_node)307 Layer::connect_dynamic_param(const String& param, etl::loose_handle<ValueNode> value_node)
308 {
309 	if (!value_node) return disconnect_dynamic_param(param);
310 
311 	ValueNode::Handle previous;
312 	DynamicParamList::iterator i = dynamic_param_list_.find(param);
313 	if (i != dynamic_param_list_.end()) previous = i->second;
314 
315 	if (previous == value_node)
316 		return true;
317 
318 	String param_noref = param;
319 	dynamic_param_list_[param]=ValueNode::Handle(value_node);
320 
321 	if (previous)
322 	{
323 		// fix 2353284: if two parameters in the same layer are
324 		// connected to the same valuenode and we disconnect one of
325 		// them, the parent-child relationship for the remaining
326 		// connection was being deleted.  now we search the parameter
327 		// list to see if another parameter uses the same valuenode
328 		DynamicParamList::const_iterator iter;
329 		for (iter = dynamic_param_list().begin(); iter != dynamic_param_list().end(); iter++)
330 			if (iter->second == previous)
331 				break;
332 		if (iter == dynamic_param_list().end())
333 			remove_child(previous.get());
334 	}
335 
336 	add_child(value_node.get());
337 	if(!value_node->is_exported() && get_canvas())
338 		value_node->set_parent_canvas(get_canvas());
339 
340 	dynamic_param_changed(param);
341 	changed();
342 	return true;
343 }
344 
345 bool
disconnect_dynamic_param(const String & param)346 Layer::disconnect_dynamic_param(const String& param)
347 {
348 	DynamicParamList::iterator i = dynamic_param_list_.find(param);
349 	if (i == dynamic_param_list_.end()) return true;
350 
351 	ValueNode::Handle previous(i->second);
352 	dynamic_param_list_.erase(i);
353 
354 	if(previous)
355 	{
356 		// fix 2353284: if two parameters in the same layer are
357 		// connected to the same valuenode and we disconnect one of
358 		// them, the parent-child relationship for the remaining
359 		// connection was being deleted.  now we search the parameter
360 		// list to see if another parameter uses the same valuenode
361 		DynamicParamList::const_iterator iter;
362 		for (iter = dynamic_param_list().begin(); iter != dynamic_param_list().end(); iter++)
363 			if (iter->second == previous)
364 				break;
365 		if (iter == dynamic_param_list().end())
366 			remove_child(previous.get());
367 	}
368 
369 	static_param_changed(param);
370 	changed();
371 
372 	return true;
373 }
374 
375 void
on_changed()376 Layer::on_changed()
377 {
378 	if (getenv("SYNFIG_DEBUG_ON_CHANGED"))
379 		printf("%s:%d Layer::on_changed()\n", __FILE__, __LINE__);
380 
381 	clear_time_mark();
382 	Node::on_changed();
383 }
384 
385 void
on_child_changed(const Node * x)386 Layer::on_child_changed(const Node *x)
387 {
388 	Node::on_child_changed(x);
389 	for(DynamicParamList::const_iterator i = dynamic_param_list().begin(); i != dynamic_param_list().end();)
390 	{
391 		DynamicParamList::const_iterator j = i;
392 		++i;
393 		if (j->second.get() == x)
394 			dynamic_param_changed(j->first);
395 	}
396 }
397 
398 bool
set_param(const String & param,const ValueBase & value)399 Layer::set_param(const String &param, const ValueBase &value)
400 {
401 	IMPORT_VALUE(param_z_depth)
402 	return false;
403 }
404 
405 etl::handle<Transform>
get_transform() const406 Layer::get_transform()const
407 {
408 	return 0;
409 }
410 
411 float
get_z_depth(const synfig::Time & t) const412 Layer::get_z_depth(const synfig::Time& t)const
413 {
414 	if(!dynamic_param_list().count("z_depth"))
415 		return param_z_depth.get(Real());
416 	return (*dynamic_param_list().find("z_depth")->second)(t).get(Real());
417 }
418 
419 float
get_true_z_depth(const synfig::Time & t) const420 Layer::get_true_z_depth(const synfig::Time& t)const
421 {
422 	// TODO: the 1.0001 constant should be somehow user defined
423 	return get_z_depth(t)*1.0001+get_depth();
424 }
425 
426 float
get_true_z_depth() const427 Layer::get_true_z_depth()const
428 {
429 	// TODO: the 1.0001 constant should be somehow user defined
430 	return get_z_depth()*1.0001+get_depth();
431 }
432 
433 Layer::Handle
simple_clone() const434 Layer::simple_clone()const
435 {
436 	if(!book().count(get_name())) return 0;
437 	Handle ret = create(get_name()).get();
438 	ret->group_=group_;
439 	//ret->set_canvas(get_canvas());
440 	ret->set_description(get_description());
441 	ret->set_active(active());
442 	ret->set_optimized(optimized());
443 	ret->set_exclude_from_rendering(get_exclude_from_rendering());
444 	ret->set_param_list(get_param_list());
445 	for(DynamicParamList::const_iterator iter=dynamic_param_list().begin();iter!=dynamic_param_list().end();++iter)
446 		ret->connect_dynamic_param(iter->first, iter->second);
447 	return ret;
448 }
449 
450 Layer::Handle
clone(Canvas::LooseHandle canvas,const GUID & deriv_guid) const451 Layer::clone(Canvas::LooseHandle canvas, const GUID& deriv_guid) const
452 {
453 	if(!book().count(get_name())) return 0;
454 
455 	//Layer *ret = book()[get_name()].factory();//create(get_name()).get();
456 	Handle ret = create(get_name()).get();
457 
458 	ret->group_=group_;
459 	//ret->set_canvas(get_canvas());
460 	ret->set_description(get_description());
461 	ret->set_active(active());
462 	ret->set_optimized(optimized());
463 	ret->set_exclude_from_rendering(get_exclude_from_rendering());
464 	ret->set_guid(get_guid()^deriv_guid);
465 
466 	ret->set_time_mark(get_time_mark());
467 	ret->set_outline_grow_mark(get_outline_grow_mark());
468 
469 	//ret->set_param_list(get_param_list());
470 	// Process the parameter list so that
471 	// we can duplicate any inline canvases
472 	ParamList param_list(get_param_list());
473 	for(ParamList::const_iterator iter(param_list.begin()); iter != param_list.end(); ++iter)
474 	{
475 		if(dynamic_param_list().count(iter->first)==0 && iter->second.get_type()==type_canvas)
476 		{
477 			// This parameter is a canvas.  We need a close look.
478 			Canvas::Handle canvas(iter->second.get(Canvas::Handle()));
479 			if(canvas && canvas->is_inline())
480 			{
481 				// This parameter is an inline canvas! we need to clone it
482 				// before we set it as a parameter.
483 
484 				// clone canvas (all code that clones a canvas has this comment)
485 				Canvas::Handle new_canvas(canvas->clone(deriv_guid));
486 
487 				ValueBase value(new_canvas);
488 				ret->set_param(iter->first, value);
489 				continue;
490 			}
491 		}
492 
493 		// This is a normal parameter,go ahead and set it.
494 		ret->set_param(iter->first, iter->second);
495 	}
496 
497 	// Duplicate the dynamic paramlist, but only the exported data nodes
498 	DynamicParamList::const_iterator iter;
499 	for(iter=dynamic_param_list().begin();iter!=dynamic_param_list().end();++iter)
500 	{
501 		// Make sure we clone inline canvases
502 		if(iter->second->get_type()==type_canvas)
503 		{
504 			Canvas::Handle canvas((*iter->second)(0).get(Canvas::Handle()));
505 			if(canvas->is_inline())
506 			{
507 				// clone canvas (all code that clones a canvas has this comment)
508 				Canvas::Handle new_canvas(canvas->clone(deriv_guid));
509 				ValueBase value(new_canvas);
510 				ret->connect_dynamic_param(iter->first,ValueNode_Const::create(value));
511 				continue;
512 			}
513 		}
514 
515 		if(iter->second->is_exported())
516 			ret->connect_dynamic_param(iter->first,iter->second);
517 		else
518 			ret->connect_dynamic_param(iter->first,iter->second->clone(canvas, deriv_guid));
519 	}
520 
521 	//ret->set_canvas(0);
522 
523 	return ret;
524 }
525 
526 bool
reads_context() const527 Layer::reads_context() const
528 {
529 	return false;
530 }
531 
532 Rect
get_full_bounding_rect(Context context) const533 Layer::get_full_bounding_rect(Context context)const
534 {
535 	// No one of overrides of this function don't check the "active" flag
536 	// So this check also disabled here
537 	//if(Context::active(context.get_params(),*this))
538 		return context.get_full_bounding_rect()|get_bounding_rect();
539 	//return context.get_full_bounding_rect();
540 }
541 
542 Rect
get_bounding_rect() const543 Layer::get_bounding_rect()const
544 {
545 	return Rect::full_plane();
546 }
547 
548 bool
set_param_list(const ParamList & list)549 Layer::set_param_list(const ParamList &list)
550 {
551 	bool ret=true;
552 	if(!list.size())
553 		return false;
554 	ParamList::const_iterator iter(list.begin());
555 	for(;iter!=list.end();++iter)
556 	{
557 		if(!set_param(iter->first, iter->second))ret=false;
558 	}
559 	return ret;
560 }
561 
562 Layer::ParamList
get_param_list() const563 Layer::get_param_list()const
564 {
565 	ParamList ret;
566 
567 	Vocab vocab(get_param_vocab());
568 
569 	Vocab::const_iterator iter=vocab.begin();
570 	for(;iter!=vocab.end();++iter)
571 	{
572 		ret[iter->get_name()]=get_param(iter->get_name());
573 	}
574 	return ret;
575 }
576 
577 ValueBase
get_param(const String & param) const578 Layer::get_param(const String & param)const
579 {
580 	EXPORT_VALUE(param_z_depth);
581 	return ValueBase();
582 }
583 
584 String
get_version() const585 Layer::get_version()const
586 {
587 	return get_param("version__").get(String());
588 }
589 
590 bool
set_version(const String &)591 Layer::set_version(const String &/*ver*/)
592 {
593 	return false;
594 }
595 
596 void
reset_version()597 Layer::reset_version()
598 	{ }
599 
600 
601 void
set_time(IndependentContext context,Time time) const602 Layer::set_time(IndependentContext context, Time time)const
603 {
604 	Layer::ParamList params;
605 	Layer::DynamicParamList::const_iterator iter;
606 	// For each parameter of the layer sets the time by the operator()(time)
607 	for(iter=dynamic_param_list().begin();iter!=dynamic_param_list().end();iter++)
608 		params[iter->first]=(*iter->second)(time);
609 	// Sets the modified parameter list to the current context layer
610 	const_cast<Layer*>(this)->set_param_list(params);
611 
612 	set_time_mark(time);
613 
614 	set_time_vfunc(context, time);
615 }
616 
617 void
set_time_vfunc(IndependentContext context,Time time) const618 Layer::set_time_vfunc(IndependentContext context, Time time)const
619 {
620 	context.set_time(time);
621 }
622 
623 void
set_outline_grow(IndependentContext context,Real outline_grow) const624 Layer::set_outline_grow(IndependentContext context, Real outline_grow)const
625 {
626 	set_outline_grow_mark(outline_grow);
627 	set_outline_grow_vfunc(context, outline_grow);
628 }
629 
630 void
set_outline_grow_vfunc(IndependentContext context,Real outline_grow) const631 Layer::set_outline_grow_vfunc(IndependentContext context, Real outline_grow)const
632 {
633 	context.set_outline_grow(outline_grow);
634 }
635 
636 void
set_render_method(Context context,RenderMethod x)637 Layer::set_render_method(Context context, RenderMethod x)
638 {
639 	context.set_render_method(x);
640 }
641 
642 Color
get_color(Context context,const Point & pos) const643 Layer::get_color(Context context, const Point &pos)const
644 {
645 	return context.get_color(pos);
646 }
647 
648 CairoColor
get_cairocolor(Context context,const Point & pos) const649 Layer::get_cairocolor(Context context, const Point &pos)const
650 {
651 	// When the layer doesn't define its own get_cairocolor
652 	// then the normal get_cairo color will be used and
653 	// a Color to CairoColor conversion will be done.
654 	return CairoColor(get_color(context, pos));
655 }
656 
657 
658 synfig::Layer::Handle
hit_check(synfig::Context context,const synfig::Point & pos) const659 Layer::hit_check(synfig::Context context, const synfig::Point &pos)const
660 {
661 	return context.hit_check(pos);
662 }
663 
664 // Temporary function to render transformed layer for layers which yet not suppurt transformed rendering
665 #ifdef _DEBUG
666 bool
render_transformed(const Layer * layer,Context context,Surface * surface,int quality,const RendDesc & renddesc,ProgressCallback * cb,const char * file,int line)667 Layer::render_transformed(const Layer *layer, Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb, const char *file, int line)
668 {
669 	warning("%s:%d Resampling used while rendering - possible overhead (called from %s:%d)", __FILE__, __LINE__, file, line);
670 #else
671 bool
672 Layer::render_transformed(const Layer *layer, Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb, const char *, int)
673 {
674 #endif
675 
676 	Transformation transformation(renddesc.get_transformation_matrix());
677 
678 	if(cb && !cb->amount_complete(0,10000)) return false;
679 
680 	SuperCallback stageone(cb,0,4500,10000);
681 	SuperCallback stagetwo(cb,4500,9000,10000);
682 	SuperCallback stagethree(cb,9000,9999,10000);
683 
684 	surface->set_wh(renddesc.get_w(),renddesc.get_h());
685 	surface->clear();
686 
687 	const Rect full_bounding_rect(layer->get_full_bounding_rect(context));
688 	Rect inner_bounds(
689 	    full_bounding_rect.get_min(),
690 	    full_bounding_rect.get_max()
691 	);
692 	inner_bounds &= transformation.back_transform_bounds(renddesc.get_rect());
693 	Rect outer_bounds(transformation.transform_bounds(inner_bounds));
694 	outer_bounds &= renddesc.get_rect();
695 
696 	// sometimes the user changes the parameters while we're
697 	// rendering, causing our pasted canvas' bounding box to shrink
698 	// and no longer overlap with our tile.  if that has happened,
699 	// let's just stop now - we'll be refreshing soon anyway
700 	//! \todo shouldn't a mutex ensure this isn't needed?
701 	// http://synfig.org/images/d/d2/Bbox-change.sifz is an example
702 	// that shows this happening - open the encapsulation, select the
703 	// 'shade', and toggle the 'invert' parameter quickly.
704 	// Occasionally you'll see:
705 	//   error: Context::accelerated_render(): Layer "shade" threw a bad_alloc exception!
706 	// where the shade layer tries to allocate itself a canvas of
707 	// negative proportions, due to changing bounding boxes.
708 	if (!inner_bounds.is_valid())
709 	{
710 		warning("%s:%d bounding box shrank while rendering?", __FILE__, __LINE__);
711 		return true;
712 	}
713 
714 	Vector width_vector(
715 		transformation.transform(
716 			Vector(inner_bounds.maxx - inner_bounds.minx, 0.0), false ));
717 	Vector pixels_width_vector(
718 		width_vector[0]/renddesc.get_pw(),
719 		width_vector[1]/renddesc.get_ph() );
720 	int inner_width_pixels = (int)ceil(pixels_width_vector.mag());
721 
722 	Vector ortho_axis_x(width_vector.norm());
723 	Vector ortho_axis_y(-ortho_axis_x.perp());
724 
725 	Vector height_vector(
726 		transformation.transform(
727 			Vector(0.0, inner_bounds.maxy - inner_bounds.miny), false ));
728 	Vector ortho_height_vector(
729 		ortho_axis_y * (height_vector*ortho_axis_y) );
730 	Vector pixels_height_vector(
731 		ortho_height_vector[0]/renddesc.get_pw(),
732 		ortho_height_vector[1]/renddesc.get_ph() );
733 	int inner_height_pixels = (int)ceil(pixels_height_vector.mag());
734 
735 	// make 8 pixels border for bicubic resampling
736 	float intermediate_pw = (inner_bounds.maxx-inner_bounds.minx)/(float)inner_width_pixels;
737 	float intermediate_ph = (inner_bounds.maxy-inner_bounds.miny)/(float)inner_height_pixels;
738 	inner_bounds.maxx += 8.f*intermediate_pw;
739 	inner_bounds.minx -= 8.f*intermediate_pw;
740 	inner_bounds.maxy += 8.f*intermediate_ph;
741 	inner_bounds.miny -= 8.f*intermediate_ph;
742 	inner_width_pixels += 16;
743 	inner_height_pixels += 16;
744 
745 	RendDesc intermediate_desc(renddesc);
746 	intermediate_desc.clear_flags();
747 	intermediate_desc.set_transformation_matrix(Matrix());
748 	intermediate_desc.set_tl(Vector(inner_bounds.minx,inner_bounds.maxy));
749 	intermediate_desc.set_br(Vector(inner_bounds.maxx,inner_bounds.miny));
750 	intermediate_desc.set_flags(0);
751 	intermediate_desc.set_w(inner_width_pixels);
752 	intermediate_desc.set_h(inner_height_pixels);
753 
754 	Surface intermediate_surface;
755 	if(!layer->accelerated_render(context,&intermediate_surface,quality,intermediate_desc,&stagetwo))
756 		return false;
757 
758 	Rect pixels_outer_bounds(
759 		Vector((outer_bounds.minx-renddesc.get_tl()[0])/renddesc.get_pw(),
760 			   (outer_bounds.miny-renddesc.get_tl()[1])/renddesc.get_ph()),
761 		Vector((outer_bounds.maxx-renddesc.get_tl()[0])/renddesc.get_pw(),
762 			   (outer_bounds.maxy-renddesc.get_tl()[1])/renddesc.get_ph())
763 	);
764 
765 	int left   = (int)floor(pixels_outer_bounds.minx);
766 	int top    = (int)floor(pixels_outer_bounds.miny);
767 	int right  = (int)ceil (pixels_outer_bounds.maxx);
768 	int bottom = (int)ceil (pixels_outer_bounds.maxy);
769 
770 	int w = min(surface->get_w(), renddesc.get_w());
771 	int h = min(surface->get_h(), renddesc.get_h());
772 
773 	if (left < 0) left = 0;
774 	if (top < 0) top = 0;
775 	if (right > w) right = w;
776 	if (bottom > h) bottom = h;
777 
778 	int decx = right - left;
779 	if (top < bottom && left < right) {
780 		Vector initial_outer_pos(left*renddesc.get_pw(), top*renddesc.get_ph());
781 		initial_outer_pos += renddesc.get_tl();
782 		Vector initial_inner_pos = transformation.back_transform(initial_outer_pos);
783 		Vector initial_inner_surface_pos(initial_inner_pos - intermediate_desc.get_tl());
784 		initial_inner_surface_pos[0] /= intermediate_desc.get_pw();
785 		initial_inner_surface_pos[1] /= intermediate_desc.get_ph();
786 
787 		Vector initial_outer_pos01((left+1)*renddesc.get_pw(), top*renddesc.get_ph());
788 		initial_outer_pos01 += renddesc.get_tl();
789 		Vector initial_inner_pos01 = transformation.back_transform(initial_outer_pos01);
790 		Vector initial_inner_surface_pos01(initial_inner_pos01 - intermediate_desc.get_tl());
791 		initial_inner_surface_pos01[0] /= intermediate_desc.get_pw();
792 		initial_inner_surface_pos01[1] /= intermediate_desc.get_ph();
793 
794 		Vector initial_outer_pos10(left*renddesc.get_pw(), (top+1)*renddesc.get_ph());
795 		initial_outer_pos10 += renddesc.get_tl();
796 		Vector initial_inner_pos10 = transformation.back_transform(initial_outer_pos10);
797 		Vector initial_inner_surface_pos10(initial_inner_pos10 - intermediate_desc.get_tl());
798 		initial_inner_surface_pos10[0] /= intermediate_desc.get_pw();
799 		initial_inner_surface_pos10[1] /= intermediate_desc.get_ph();
800 
801 		Vector dx(initial_inner_surface_pos01 - initial_inner_surface_pos);
802 		Vector dy(initial_inner_surface_pos10 - initial_inner_surface_pos);
803 
804 		Vector row_inner_surface_pos(initial_inner_surface_pos);
805 		Vector inner_surface_pos;
806 
807 		Surface::pen pen(surface->get_pen(left, top));
808 		for(int y = top; y < bottom; y++) {
809 			inner_surface_pos = row_inner_surface_pos;
810 			for(int x = left; x < right; x++) {
811 				pen.put_value( intermediate_surface.cubic_sample(inner_surface_pos[0], inner_surface_pos[1]) );
812 				pen.inc_x();
813 				inner_surface_pos += dx;
814 			}
815 			pen.dec_x(decx);
816 			pen.inc_y();
817 			row_inner_surface_pos += dy;
818 		}
819 	}
820 
821 	if(cb && !cb->amount_complete(10000,10000)) return false;
822 
823 	return true;
824 }
825 
826 /* 	The default accelerated renderer
827 **	is anything but accelerated...
828 */
829 bool
830 Layer::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)  const
831 {
832 	RENDER_TRANSFORMED_IF_NEED(__FILE__, __LINE__)
833 
834 	handle<Target_Scanline> target=surface_target_scanline(surface);
835 	if(!target)
836 	{
837 		if(cb)cb->error(_("Unable to create surface target"));
838 		return false;
839 	}
840 	RendDesc desc=renddesc;
841 	target->set_rend_desc(&desc);
842 
843 	// When we render, we want to
844 	// make sure that we are rendered too...
845 	// Since the context iterator is for
846 	// the layer after us, we need to back up.
847 	// This could be considered a hack, as
848 	// it is a possibility that we are indeed
849 	// not the previous layer.
850 	--context;
851 
852 	return render(context,target,desc,cb);
853 	//return render_threaded(context,target,desc,cb,2);
854 }
855 
856 
857 bool
858 Layer::accelerated_cairorender(Context context, cairo_t *cr, int /*quality*/, const RendDesc &renddesc, ProgressCallback *cb)  const
859 {
860 	// When we render, we want to
861 	// make sure that we are rendered too...
862 	// Since the context iterator is for
863 	// the layer after us, we need to back up.
864 	// This could be considered a hack, as
865 	// it is a possibility that we are indeed
866 	// not the previous layer.
867 	--context;
868 
869 	return cairorender(context,cr,renddesc,cb);
870 }
871 
872 RendDesc
873 Layer::get_sub_renddesc_vfunc(const RendDesc &renddesc) const
874 {
875 	return renddesc;
876 }
877 
878 void
879 Layer::get_sub_renddesc_vfunc(const RendDesc &renddesc, std::vector<RendDesc> &out_descs) const
880 {
881 	out_descs.push_back( get_sub_renddesc_vfunc(renddesc) );
882 }
883 
884 void
885 Layer::get_sub_renddesc(const RendDesc &renddesc, std::vector<RendDesc> &out_descs) const
886 {
887 	get_sub_renddesc_vfunc(renddesc, out_descs);
888 }
889 
890 RendDesc
891 Layer::get_sub_renddesc(const RendDesc &renddesc, int index) const
892 {
893 	std::vector<RendDesc> descs;
894 	get_sub_renddesc(renddesc, descs);
895 	return index >=0 && index < (int)descs.size() ? descs[index] : RendDesc::zero();
896 }
897 
898 rendering::Task::Handle
899 Layer::build_rendering_task_vfunc(Context context)const
900 {
901 	rendering::TaskLayer::Handle task = new rendering::TaskLayer();
902 	// TODO: This is not thread-safe
903 	//task->layer = const_cast<Layer*>(this);//clone(NULL);
904 	task->layer = clone(NULL);
905 	task->layer->set_canvas(get_canvas());
906 
907 	Real amount = Context::z_depth_visibility(context.get_params(), *this);
908 	if (approximate_not_equal(amount, 1.0) && task->layer.type_is<Layer_Composite>())
909 	{
910 		//task->layer = task->layer->clone(NULL);
911 		etl::handle<Layer_Composite> composite = etl::handle<Layer_Composite>::cast_dynamic(task->layer);
912 		composite->set_amount( composite->get_amount()*amount );
913 	}
914 
915 	task->sub_task() = context.build_rendering_task();
916 	return task;
917 }
918 
919 rendering::Task::Handle
920 Layer::build_rendering_task(Context context)const
921 {
922 	rendering::Task::Handle task = build_rendering_task_vfunc(context);
923 	return task ? task : rendering::Task::Handle(new rendering::TaskSurfaceEmpty());
924 }
925 
926 String
927 Layer::get_name()const
928 {
929 	return get_param("name__").get(String());
930 }
931 
932 String
933 Layer::get_local_name()const
934 {
935 	return get_param("local_name__").get(String());
936 }
937 
938 
939 Layer::Vocab
940 Layer::get_param_vocab()const
941 {
942 	Layer::Vocab ret;
943 
944 	ret.push_back(ParamDesc(param_z_depth,"z_depth")
945 		.set_local_name(_("Z Depth"))
946 		.set_animation_only(true)
947 		.set_description(_("Modifies the position of the layer in the layer stack"))
948 	);
949 
950 	return ret;
951 }
952 
953 void
954 Layer::get_times_vfunc(Node::time_set &set) const
955 {
956 	DynamicParamList::const_iterator 	i = dynamic_param_list_.begin(),
957 										end = dynamic_param_list_.end();
958 
959 	for(; i != end; ++i)
960 	{
961 		const Node::time_set &tset = i->second->get_times();
962 		set.insert(tset.begin(),tset.end());
963 	}
964 }
965 
966 
967 void
968 Layer::add_to_group(const String&x)
969 {
970 	if(x==group_)
971 		return;
972 	if(!group_.empty())
973 		remove_from_all_groups();
974 	group_=x;
975 	signal_added_to_group()(group_);
976 }
977 
978 void
979 Layer::remove_from_group(const String&x)
980 {
981 	if(group_==x)
982 		remove_from_all_groups();
983 }
984 
985 void
986 Layer::remove_from_all_groups()
987 {
988 	if(group_.empty())
989 		return;
990 	signal_removed_from_group()(group_);
991 	group_.clear();
992 }
993 
994 String
995 Layer::get_group()const
996 {
997 	return group_;
998 }
999 
1000 const String
1001 Layer::get_param_local_name(const String &param_name)const
1002 {
1003 	ParamVocab vocab = get_param_vocab();
1004 	// loop to find the parameter in the parameter vocab - this gives us its local name
1005 	for (ParamVocab::iterator iter = vocab.begin(); iter != vocab.end(); iter++)
1006 		if (iter->get_name() == param_name)
1007 			return iter->get_local_name();
1008 	return String();
1009 }
1010 
1011 synfig::Layer::LooseHandle
1012 synfig::Layer::get_parent_paste_canvas_layer()const
1013 {
1014 	synfig::Canvas::LooseHandle canvas=get_canvas();
1015 	if(canvas->parent())
1016 	{
1017 		synfig::Canvas::LooseHandle parent_canvas=canvas->parent();
1018 		Canvas::iterator iter;
1019 		for(iter=parent_canvas->begin();iter!=parent_canvas->end();++iter)
1020 		{
1021 			Layer::LooseHandle layer=iter->get();
1022 			if(dynamic_cast<Layer_PasteCanvas*>(layer.get()) != NULL)
1023 			{
1024 				Layer_PasteCanvas* paste_canvas(static_cast<Layer_PasteCanvas*>(layer.get()));
1025 				Canvas::Handle sub_canvas=paste_canvas->get_sub_canvas();
1026 				if(sub_canvas==canvas)
1027 					return layer;
1028 			}
1029 		}
1030 		synfig::warning("Layer's canvas has parent canvas but I can't find a proper Layer_PasteCanvas in it");
1031 		return NULL;
1032 	}
1033 	return NULL;
1034 }
1035 
1036 String
1037 Layer::get_string()const
1038 {
1039 	return String("Layer: ") + get_non_empty_description();
1040 
1041 }
1042 
1043 void
1044 Layer::fill_sound_processor(SoundProcessor & /* soundProcessor */) const
1045 	{ }
1046 
1047 using Glib::RefPtr;
1048 
1049 void Layer::on_file_changed(const RefPtr<Gio::File> &/*file*/, const RefPtr<Gio::File> &/*other_file*/, Gio::FileMonitorEvent event) {
1050 	if (event == Gio::FILE_MONITOR_EVENT_CHANGES_DONE_HINT)
1051 	{
1052 		synfig::warning("file changed! (" + monitored_path + ")");
1053 		set_param("filename", ValueBase("")); // first clear filename to force image reload
1054 		Importer::forget(get_canvas()->get_file_system()->get_identifier(monitored_path)); // clear file in list of loaded files
1055 		set_param("filename", ValueBase(monitored_path));
1056 		get_canvas()->signal_changed()();
1057 	}
1058 }
1059 
1060 bool Layer::monitor(const std::string& path) { // append file monitor (returns true on success, false on fail)
1061 	if (file_monitor)
1062 	{
1063 		synfig::warning("File monitor for file '" + path + "' is already attached!");
1064 		return false;
1065 	}
1066 
1067 	RefPtr<Gio::File> file = Gio::File::create_for_path(path);
1068 	file_monitor = file->monitor_file(); // defaults to Gio::FileMonitorFlags::FILE_MONITOR_NONE
1069 	monitor_connection = file_monitor->signal_changed().connect(sigc::mem_fun(*this, &Layer::on_file_changed));
1070 	monitored_path = path;
1071 	synfig::info("File monitor attached to file: (" + path + ")");
1072 
1073 	return true;
1074 }
1075