1 /* === S Y N F I G ========================================================= */
2 /*! \file layer_duplicate.cpp
3 ** \brief Implementation of the "Duplicate" layer
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 ** Copyright (c) 2007, 2008 Chris Moore
11 ** This package is free software; you can redistribute it and/or
12 ** modify it under the terms of the GNU General Public License as
13 ** published by the Free Software Foundation; either version 2 of
14 ** the License, or (at your option) any later version.
16 ** This package is distributed in the hope that it will be useful,
17 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ** General Public License for more details.
22 /* ========================================================================= */
24 /* === H E A D E R S ======================================================= */
34 #include "layer_duplicate.h"
37 #include "paramdesc.h"
41 #include "valuenode.h"
46 /* === U S I N G =========================================================== */
48 using namespace synfig
;
52 /* === G L O B A L S ======================================================= */
54 SYNFIG_LAYER_INIT(Layer_Duplicate
);
55 SYNFIG_LAYER_SET_NAME(Layer_Duplicate
,"duplicate");
56 SYNFIG_LAYER_SET_LOCAL_NAME(Layer_Duplicate
,N_("Duplicate"));
57 SYNFIG_LAYER_SET_CATEGORY(Layer_Duplicate
,N_("Other"));
58 SYNFIG_LAYER_SET_VERSION(Layer_Duplicate
,"0.1");
59 SYNFIG_LAYER_SET_CVS_ID(Layer_Duplicate
,"$Id$");
61 /* === M E M B E R S ======================================================= */
63 Layer_Duplicate::Layer_Duplicate():
64 Layer_Composite(1.0,Color::BLEND_COMPOSITE
)
66 LinkableValueNode
* index_value_node
= ValueNode_Duplicate::create(Real(3));
67 connect_dynamic_param("index", index_value_node
);
71 Layer_Duplicate::clone(const GUID
& deriv_guid
)const
73 Layer::Handle ret
= (Layer::Handle
)Layer_Composite::clone(deriv_guid
);
75 const DynamicParamList
&dpl
= dynamic_param_list();
76 DynamicParamList::const_iterator iter
= dpl
.find("index");
78 // if we have a dynamic "index" parameter, make a new one in the clone
79 // it's not good to have two references to the same index valuenode,
80 // or nested duplications cause an infinite loop
81 if (iter
!= dpl
.end())
82 ret
->connect_dynamic_param(iter
->first
,iter
->second
->clone(deriv_guid
));
88 Layer_Duplicate::set_param(const String
¶m
, const ValueBase
&value
)
91 return Layer_Composite::set_param(param
,value
);
95 Layer_Duplicate::get_param(const String
¶m
)const
102 return Layer_Composite::get_param(param
);
106 Layer_Duplicate::set_time(Context context
, Time time
)const
108 context
.set_time(time
);
113 Layer_Duplicate::set_time(Context context
, Time time
, const Point
&pos
)const
115 context
.set_time(time
,pos
);
120 Layer_Duplicate::get_color(Context context
, const Point
&pos
)const
122 handle
<ValueNode_Duplicate
> duplicate_param
= get_duplicate_param();
123 if (!duplicate_param
) return context
.get_color(pos
);
125 Color::BlendMethod
blend_method(get_blend_method());
126 float amount(get_amount());
129 Mutex::Lock
lock(mutex
);
130 duplicate_param
->reset_index(time_cur
);
133 context
.set_time(time_cur
+1);
134 context
.set_time(time_cur
);
135 color
= Color::blend(context
.get_color(pos
),color
,amount
,blend_method
);
136 } while (duplicate_param
->step(time_cur
));
142 Layer_Duplicate::get_param_vocab()const
145 ret
=Layer_Composite::get_param_vocab();
147 ret
.push_back(ParamDesc("index")
148 .set_local_name(_("Index"))
149 .set_description(_("Copy Index"))
155 ValueNode_Duplicate::Handle
156 Layer_Duplicate::get_duplicate_param()const
158 const DynamicParamList
&dpl
= dynamic_param_list();
159 DynamicParamList::const_iterator iter
= dpl
.find("index");
160 if (iter
== dpl
.end()) return NULL
;
161 etl::rhandle
<ValueNode
> param(iter
->second
);
162 return ValueNode_Duplicate::Handle::cast_dynamic(param
);
166 Layer_Duplicate::accelerated_render(Context context
,Surface
*surface
,int quality
, const RendDesc
&renddesc
, ProgressCallback
*cb
)const
169 return context
.accelerated_render(surface
,quality
,renddesc
,cb
);
173 surface
->set_wh(renddesc
.get_w(),renddesc
.get_h());
178 SuperCallback subimagecb
;
182 handle
<ValueNode_Duplicate
> duplicate_param
= get_duplicate_param();
183 if (!duplicate_param
) return context
.accelerated_render(surface
,quality
,renddesc
,cb
);
185 surface
->set_wh(renddesc
.get_w(),renddesc
.get_h());
188 Color::BlendMethod
blend_method(get_blend_method());
189 int steps
= duplicate_param
->count_steps(time_cur
);
191 Mutex::Lock
lock(mutex
);
192 duplicate_param
->reset_index(time_cur
);
195 subimagecb
=SuperCallback(cb
,i
*(5000/steps
),(i
+1)*(5000/steps
),5000);
196 // \todo can we force a re-evaluation of all the variables without changing the time twice?
197 context
.set_time(time_cur
+1);
198 context
.set_time(time_cur
);
199 if(!context
.accelerated_render(&tmp
,quality
,renddesc
,&subimagecb
)) return false;
201 Surface::alpha_pen
apen(surface
->begin());
202 apen
.set_alpha(get_amount());
203 // \todo have a checkbox allowing use of 'behind' to reverse the order?
204 apen
.set_blend_method(i
? blend_method
: Color::BLEND_COMPOSITE
);
207 } while (duplicate_param
->step(time_cur
));