Set the description of some parameters
[synfig.git] / synfig-core / src / modules / lyr_std / supersample.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file supersample.cpp
3 **      \brief Implementation of the "Super Sample" layer
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **
10 **      This package is free software; you can redistribute it and/or
11 **      modify it under the terms of the GNU General Public License as
12 **      published by the Free Software Foundation; either version 2 of
13 **      the License, or (at your option) any later version.
14 **
15 **      This package is distributed in the hope that it will be useful,
16 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
17 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 **      General Public License for more details.
19 **      \endlegal
20 **
21 ** === N O T E S ===========================================================
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 "supersample.h"
35 #include <synfig/string.h>
36 #include <synfig/time.h>
37 #include <synfig/context.h>
38 #include <synfig/paramdesc.h>
39 #include <synfig/renddesc.h>
40 #include <synfig/surface.h>
41 #include <synfig/value.h>
42 #include <synfig/valuenode.h>
43
44 #include <synfig/target.h>
45 #include <synfig/render.h>
46
47 #endif
48
49 /* === M A C R O S ========================================================= */
50
51 /* === G L O B A L S ======================================================= */
52
53 SYNFIG_LAYER_INIT(SuperSample);
54 SYNFIG_LAYER_SET_NAME(SuperSample,"super_sample");
55 SYNFIG_LAYER_SET_LOCAL_NAME(SuperSample,N_("Super Sample"));
56 SYNFIG_LAYER_SET_CATEGORY(SuperSample,N_("Other"));
57 SYNFIG_LAYER_SET_VERSION(SuperSample,"0.1");
58 SYNFIG_LAYER_SET_CVS_ID(SuperSample,"$Id$");
59
60 /* === P R O C E D U R E S ================================================= */
61
62 /* === M E T H O D S ======================================================= */
63
64 SuperSample::SuperSample():width(2),height(2)
65 {
66         scanline=false;
67         alpha_aware=true;
68         Layer::Vocab voc(get_param_vocab());
69         Layer::fill_static(voc);
70 }
71
72 bool
73 SuperSample::set_param(const String & param, const ValueBase &value)
74 {
75
76         IMPORT(width);
77         IMPORT(height);
78         IMPORT(scanline);
79         IMPORT(alpha_aware);
80
81         return false;
82 }
83
84 ValueBase
85 SuperSample::get_param(const String& param)const
86 {
87         EXPORT(width);
88         EXPORT(height);
89     EXPORT(scanline);
90     EXPORT(alpha_aware);
91
92         EXPORT_NAME();
93         EXPORT_VERSION();
94
95         return ValueBase();
96 }
97
98 bool
99 SuperSample::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
100 {
101         // don't bother supersampling if our quality is too low.
102         if(quality>=10)
103                 return context.accelerated_render(surface,quality,renddesc,cb);
104
105         RendDesc desc(renddesc);
106
107         SuperCallback subcb(cb,1,9000,10000);
108         SuperCallback stagetwo(cb,9000,10000,10000);
109
110         desc.clear_flags();
111         desc.set_wh(desc.get_w()*width,desc.get_h()*height);
112
113         Surface tempsurface;
114
115         // Render the scene
116         if(scanline)
117         {
118                 handle<Target> target=surface_target(&tempsurface);
119                 if(!target)
120                 {
121                         if(cb)cb->error(_("Unable to create SurfaceTarget"));
122                         return false;
123                 }
124                 target->set_rend_desc(&desc);
125
126                 if(!render(context-1,target,desc,&subcb))
127                 {
128                         if(cb)cb->error(strprintf(__FILE__"%d: Scanline Renderer Failure",__LINE__));
129                         return false;
130                 }
131         }
132         else
133                 if(!context.accelerated_render(&tempsurface,quality,desc,cb))
134                 {
135                         //if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer Failure",__LINE__));
136                         return false;
137                 }
138
139         surface->set_wh(renddesc.get_w(),renddesc.get_h());
140
141         Surface::pen pen(surface->begin());
142         Surface::pen temp_pen(tempsurface.begin());
143
144         if(cb && !cb->amount_complete(9001,10000)) return false;
145
146         if(alpha_aware)
147         {
148                 int x,y,u,v;
149                 float sum;
150                 Color pool;
151                 for(y=0;y<surface->get_h();y++,pen.inc_y(),pen.dec_x(x),temp_pen.inc_y(height),temp_pen.dec_x(x*width))
152                 {
153                         for(x=0;x<surface->get_w();x++,pen.inc_x(),temp_pen.inc_x(width))
154                         {
155                                 pool=Color(0,0,0,0);
156                                 sum=0;
157
158                                 for(v=0;v<height;v++,temp_pen.inc_y(),temp_pen.dec_x(u))
159                                         for(u=0;u<width;u++,temp_pen.inc_x())
160                                         {
161                                                 pool+=temp_pen.get_value()*temp_pen.get_value().get_a();
162                                                 sum+=temp_pen.get_value().get_a();
163                                         }
164                                 temp_pen.dec_y(v);
165
166                                 if(sum)
167                                 {
168                                         pool/=sum;
169                                         pool.set_a(sum/float(width*height));
170                                         pen.put_value(pool);
171                                 }
172                                 else
173                                         pen.put_value(Color::alpha());
174                         }
175                         if((y&31)==0 && cb)
176                         {
177                                 if(!stagetwo.amount_complete(y,surface->get_h()))
178                                         return false;
179                         }
180                 }
181         }
182         else
183         {
184                 int x,y,u,v;
185                 Color pool;
186                 float multiplier=1.0f/float(width*height);
187                 for(y=0;y<surface->get_h();y++,pen.inc_y(),pen.dec_x(x),temp_pen.inc_y(height),temp_pen.dec_x(x*width))
188                 {
189                         for(x=0;x<surface->get_w();x++,pen.inc_x(),temp_pen.inc_x(width))
190                         {
191                                 pool=Color(0,0,0,0);
192                                 for(v=0;v<height;v++,temp_pen.inc_y(),temp_pen.dec_x(u))
193                                         for(u=0;u<width;u++,temp_pen.inc_x())
194                                                 pool+=temp_pen.get_value();
195                                 temp_pen.dec_y(v);
196                                 pen.put_value(pool*multiplier);
197                         }
198                         if((y&31)==0 && cb)
199                         {
200                                 if(!stagetwo.amount_complete(y,surface->get_h()))
201                                         return false;
202                         }
203                 }
204         }
205
206         if(cb && !cb->amount_complete(10000,10000)) return false;
207
208         return true;
209 }
210
211 Layer::Vocab
212 SuperSample::get_param_vocab(void)const
213 {
214         Layer::Vocab ret;
215
216         ret.push_back(ParamDesc("width")
217                 .set_local_name(_("Width"))
218                 .set_description(_("Width of sample area (In pixels)"))
219         );
220         ret.push_back(ParamDesc("height")
221                 .set_local_name(_("Height"))
222                 .set_description(_("Height of sample area (In pixels)"))
223         );
224         ret.push_back(ParamDesc("scanline")
225                 .set_local_name(_("Use Parametric"))
226                 .set_description(_("Use the Parametric Renderer"))
227         );
228         ret.push_back(ParamDesc("alpha_aware")
229                 .set_local_name(_("Be Alpha Safe"))
230                 .set_description(_("Avoid alpha artifacts when checked"))
231         );
232
233         return ret;
234 }
235
236 Rect
237 SuperSample::get_bounding_rect(Context context)const
238 {
239         return context.get_full_bounding_rect();
240 }