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

Reply via email to