Author: Carlos Lopez <genet...@gmail.com> Date: Tue Jul 3 18:33:36 2012 +0200
New synfig::render function that will accept Target_Cairo as target. --- synfig-core/src/modules/lyr_std/supersample.cpp | 2 +- synfig-core/src/synfig/layer.cpp | 5 +- synfig-core/src/synfig/layer_composite.cpp | 2 +- synfig-core/src/synfig/render.cpp | 136 +++++++++++++++++++++++ synfig-core/src/synfig/render.h | 1 + 5 files changed, 141 insertions(+), 5 deletions(-) diff --git a/synfig-core/src/modules/lyr_std/supersample.cpp b/synfig-core/src/modules/lyr_std/supersample.cpp index 292502b..affb827 100644 --- a/synfig-core/src/modules/lyr_std/supersample.cpp +++ b/synfig-core/src/modules/lyr_std/supersample.cpp @@ -123,7 +123,7 @@ SuperSample::accelerated_render(Context context,Surface *surface,int quality, co // Render the scene if(scanline) { - handle<Target> target=surface_target(&tempsurface); + handle<Target_Scanline> target=surface_target(&tempsurface); if(!target) { if(cb)cb->error(_("Unable to create SurfaceTarget")); diff --git a/synfig-core/src/synfig/layer.cpp b/synfig-core/src/synfig/layer.cpp index 9d90957..215a5a5 100644 --- a/synfig-core/src/synfig/layer.cpp +++ b/synfig-core/src/synfig/layer.cpp @@ -543,7 +543,7 @@ Layer::hit_check(synfig::Context context, const synfig::Point &pos)const bool Layer::accelerated_render(Context context,Surface *surface,int /*quality*/, const RendDesc &renddesc, ProgressCallback *cb) const { - handle<Target> target=surface_target(surface); + handle<Target_Scanline> target=surface_target(surface); if(!target) { if(cb)cb->error(_("Unable to create surface target")); @@ -568,7 +568,7 @@ Layer::accelerated_render(Context context,Surface *surface,int /*quality*/, cons bool Layer::accelerated_render(Context context, CairoSurface *surface,int /*quality*/, const RendDesc &renddesc, ProgressCallback *cb) const { - handle<Target> target=cairosurface_target(surface); + handle<Target_Cairo> target=cairosurface_target(surface); if(!target) { if(cb)cb->error(_("Unable to create surface target")); @@ -588,7 +588,6 @@ Layer::accelerated_render(Context context, CairoSurface *surface,int /*quality*/ --context; return render(context,target,desc,cb); - //return render_threaded(context,target,desc,cb,2); } diff --git a/synfig-core/src/synfig/layer_composite.cpp b/synfig-core/src/synfig/layer_composite.cpp index 3ee9c8e..5644689 100644 --- a/synfig-core/src/synfig/layer_composite.cpp +++ b/synfig-core/src/synfig/layer_composite.cpp @@ -121,7 +121,7 @@ Layer_Composite::accelerated_render(Context context,Surface *surface,int quality image.push_front(const_cast<synfig::Layer_Composite*>(this)); // Set up a surface target - Target::Handle target(surface_target(surface)); + Target_Scanline::Handle target(surface_target(surface)); if(!target) { diff --git a/synfig-core/src/synfig/render.cpp b/synfig-core/src/synfig/render.cpp index fffdd6f..dfc67a7 100644 --- a/synfig-core/src/synfig/render.cpp +++ b/synfig-core/src/synfig/render.cpp @@ -316,6 +316,142 @@ synfig::render( return(true); } +////////// +// Cairo_Target needs to have its RendDesc already set. +bool +synfig::render( + Context context, + Target_Cairo::Handle target, + const RendDesc &desc, + ProgressCallback *callback) +{ + Point::value_type + u,v, // Current location in image + su,sv, // Starting locations + du, dv, // Distance between pixels + dsu,dsv; // Distance between subpixels + + bool + no_clamp=!desc.get_clamp(); + + int + w(desc.get_w()), + h(desc.get_h()), + a(desc.get_antialias()); + + Point + tl(desc.get_tl()), + br(desc.get_br()); + + //Gamma + // gamma(desc.get_gamma()); + + int + x,y, // Current location on output bitmap + x2,y2; // Subpixel counters + + Color::value_type + pool; // Alpha pool (for correct alpha antialiasing) + + // why to assert if we can return gracefully? + //assert(target); + + // If we do not have a target then bail + if(!target) + return false; + + // Calculate the number of channels + //chan=channels(desc.get_pixel_format()); + + // Calculate the distance between pixels + du=(br[0]-tl[0])/(Point::value_type)w; + dv=(br[1]-tl[1])/(Point::value_type)h; + + // Calculate the distance between sub pixels + dsu=du/(Point::value_type)a; + dsv=dv/(Point::value_type)a; + + // Calculate the starting points + su=tl[0]+(du-dsu)/(Point::value_type)2.0; + sv=tl[1]-(dv-dsv)/(Point::value_type)2.0; + + // Mark the start of a new frame. This will map cairo_surface_t to etl::surface + if(!target->start_frame(callback)) + return false; + // Get the CairoSurface with its etl::surface already set. + CairoSurface *surface(target->obtain_surface()); + + // Loop through all horizontal lines + for(y=0,v=sv;y<h;y++,v+=dv) + { + // If we have a callback that we need + // to report to, do so now. + if(callback) + if( callback->amount_complete(y,h) == false ) + { + // If the callback returns false, + // then the render has been aborted. + // Exit gracefully. + target->end_frame(); + return false; + } + // Loop through every pixel in row + for(x=0,u=su;x<w;x++,u+=du) + { + Color c(Color::alpha()); + + // Loop through all subpixels + for(y2=0,pool=0;y2<a;y2++) + for(x2=0;x2<a;x2++) + { + //Notice that we will use Color instead of CairoColor + // because get_color for layers are at the moment defined for Color + // So I need to convert Color to CairoColor before place it on the + // CairoSurface of target. + Color color=context.get_color( + Point( + u+(Point::value_type)(x2)*dsu, + v+(Point::value_type)(y2)*dsv + ) + ); + if(!no_clamp) + { + color=color.clamped(); + c+=color*color.get_a(); + pool+=color.get_a(); + } + else + { + c+=color*color.get_a(); + pool+=color.get_a(); + } + } + if(pool) + c/=pool; + // Once the pixel is subsampled then I premultiply by alpha and pass + // it to the CairoSurface + (*surface)[y][x]=CairoColor(c).premult_alpha(); + } + } + // Finish up the target's frame. This will unmap the etl::surface to the cairo_surface_t + target->end_frame(); + + // Give the callback one more last call, + // this time with the full height as the + // current line + if(callback) + callback->amount_complete(h,h); + + // Report our success + return(true); +} + + +//////// + + + + bool synfig::render_threaded( Context context, diff --git a/synfig-core/src/synfig/render.h b/synfig-core/src/synfig/render.h index d59395d..7a1e765 100644 --- a/synfig-core/src/synfig/render.h +++ b/synfig-core/src/synfig/render.h @@ -51,6 +51,7 @@ namespace synfig { ** you call this function! */ extern bool render(Context context, Target_Scanline::Handle target, const RendDesc &desc,ProgressCallback *); +extern bool render(Context context, Target_Cairo::Handle target, const RendDesc &desc, ProgressCallback *cb=NULL); extern bool parametric_render(Context context, Surface &surface, const RendDesc &desc,ProgressCallback *); ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ Synfig-devl mailing list Synfig-devl@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/synfig-devl