Author: Carlos Lopez <[email protected]>
Date:   Tue Mar  5 20:31:36 2013 +0100

Effectively use the Cairo render on the Preview when the Use Cairo render 
option is checked. It doesn't scale up or centers the rendered image yet.

---

 synfig-studio/src/gui/preview.cpp |   95 ++++++++++++++++++++++++++++--------
 synfig-studio/src/gui/preview.h   |    5 ++
 2 files changed, 79 insertions(+), 21 deletions(-)

diff --git a/synfig-studio/src/gui/preview.cpp 
b/synfig-studio/src/gui/preview.cpp
index a171ff9..5b110f3 100644
--- a/synfig-studio/src/gui/preview.cpp
+++ b/synfig-studio/src/gui/preview.cpp
@@ -230,17 +230,6 @@ void studio::Preview::render()
 {
        if(canvasview)
        {
-               //render using the preview target
-               etl::handle<Preview_Target>     target = new Preview_Target;
-
-               //connect our information to his...
-               //synfig::warning("Connecting to the end frame function...");
-               
target->signal_frame_done().connect(sigc::mem_fun(*this,&Preview::frame_finish));
-
-               //set the options
-               //synfig::warning("Setting Canvas");
-               target->set_canvas(get_canvas());
-               target->set_quality(quality);
 
                //render description
                RendDesc desc = get_canvas()->rend_desc();
@@ -257,7 +246,6 @@ void studio::Preview::render()
                /*synfig::warning("Setting the render description: %d x %d, %f 
fps, [%f,%f]",
                                                neww,newh,newfps, 
overbegin?begintime:(float)desc.get_time_start(),
                                                
overend?endtime:(float)desc.get_time_end());*/
-
                desc.set_w(neww);
                desc.set_h(newh);
                desc.set_frame_rate(newfps);
@@ -276,15 +264,33 @@ void studio::Preview::render()
                //setting the description
 
                //HACK - add on one extra frame because the renderer can't 
render the last frame
+               // Maybe this can be removed now because the next_time(&t) was 
refacgorized to consider the last frame too
+               //TODO: do not use get_time on Preview_Target
                desc.set_time_end(desc.get_time_end() + 1.000001/fps);
 
+               // Render using a Preview target (cairo or not)
+               etl::handle<Target> target;
+               if(use_cairo)
+               {
+                       target = etl::handle<Target>::cast_dynamic(new 
Preview_Target_Cairo(this));
+               }
+               else
+               {
+                       etl::handle<Preview_Target> t_target = new 
Preview_Target;
+                       //connect our information to his...
+                       
t_target->signal_frame_done().connect(sigc::mem_fun(*this,&Preview::frame_finish));
+                       target =etl::handle<Target>::cast_dynamic(t_target);
+               }
+               //set the options
+               target->set_canvas(get_canvas());
+               target->set_quality(quality);
+               // Set the render description
                target->set_rend_desc(&desc);
 
                //... first we must clear our current selves of space
                frames.resize(0);
 
                //now tell it to go... with inherited prog. reporting...
-               //synfig::info("Rendering Asynchronously...");
                if(renderer) renderer->stop();
                renderer = new AsyncRenderer(target);
                renderer->start();
@@ -363,6 +369,7 @@ Widget_Preview::Widget_Preview():
        adj_time_scrub(0, 0, 1000, 0, 10, 0),
        scr_time_scrub(adj_time_scrub),
        b_loop(/*_("Loop")*/),
+       current_surface(NULL),
        currentindex(-100000),//TODO get the value from canvas setting or 
preview option
        audiotime(0),
        adj_sound(0, 0, 4),
@@ -624,12 +631,16 @@ void studio::Widget_Preview::update()
                                synfig::error("i == end....");
                                //assert(0);
                                currentbuf.clear();
+                               current_surface=NULL;
                                currentindex = 0;
                                timedisp = -1;
                        }else
                        {
                                currentbuf = i->buf;
                                currentindex = i-beg;
+                               if(current_surface)
+                                       cairo_surface_destroy(current_surface);
+                               current_surface= 
cairo_surface_reference(i->surface);
                                if(timedisp != i->t)
                                {
                                        timedisp = i->t;
@@ -666,15 +677,44 @@ bool studio::Widget_Preview::redraw(GdkEventExpose 
*/*heh*/)
 {
        //And render the drawing area
        Glib::RefPtr<Gdk::Pixbuf> pxnew, px = currentbuf;
-
-       if(!px || draw_area.get_height() == 0
-               || px->get_height() == 0 || px->get_width() == 0 /*|| 
is_visible()*/) //made not need this line
+       cairo_surface_t* cs;
+       bool use_cairo= preview->get_use_cairo();
+       if(use_cairo)
+       {
+               if(current_surface)
+                       cs=cairo_surface_reference(current_surface);
+               else
+                       return true;
+       }
+       
+       int dw = draw_area.get_width();
+       int dh = draw_area.get_height();
+       
+       if(use_cairo && !cs)
+               return true;
+       else if(!use_cairo && !px)
                return true;
+       //made not need this line
+       //if ( draw_area.get_height() == 0 || px->get_height() == 0 || 
px->get_width() == 0)
+       //      return true;
 
        //figure out the scaling factors...
        float sx, sy;
        float q = 1 / preview->get_zoom();
        int nw, nh;
+       int w,h;
+       
+       // grab the source dimensions
+       if(use_cairo)
+       {
+               w=cairo_image_surface_get_width(cs);
+               h=cairo_image_surface_get_height(cs);
+       }
+       else
+       {
+               w=px->get_width();
+               h=px->get_height();
+       }
 
        Gtk::Entry* entry = zoom_preview.get_entry();
        String str(entry->get_text());
@@ -684,8 +724,8 @@ bool studio::Widget_Preview::redraw(GdkEventExpose */*heh*/)
 
        if (text == _("Fit") || text == "fit")
        {
-               sx = draw_area.get_width() / (float)px->get_width();
-               sy = draw_area.get_height()/ (float)px->get_height();
+               sx = dw / (float)w;
+               sy = dh/ (float)h;
 
                //synfig::info("widget_preview redraw: now to scale the bitmap: 
%.3f x %.3f",sx,sy);
 
@@ -711,12 +751,13 @@ bool studio::Widget_Preview::redraw(GdkEventExpose 
*/*heh*/)
        else sx = sy = atof(c) / 100 * q;
 
        //scale to a new pixmap and then copy over to the window
-       nw = (int)(px->get_width() * sx);
-       nh = (int)(px->get_height() * sx);
+       nw = (int)(w * sx);
+       nh = (int)(h * sx);
 
        if(nw == 0 || nh == 0)return true;
 
-       pxnew = px->scale_simple(nw, nh, Gdk::INTERP_NEAREST);
+       if(!use_cairo)
+               pxnew = px->scale_simple(nw, nh, Gdk::INTERP_NEAREST);
 
        //except "Fit" or "fit", we need to set size request for scrolled window
        if (text != _("Fit") & text != "fit")
@@ -731,6 +772,7 @@ bool studio::Widget_Preview::redraw(GdkEventExpose */*heh*/)
 
        if(!wind) synfig::warning("The destination window is broken...");
 
+       if(!use_cairo)
        {
                /* Options for drawing...
                        1) store with alpha, then clear and render with alpha 
every frame
@@ -753,6 +795,14 @@ bool studio::Widget_Preview::redraw(GdkEventExpose 
*/*heh*/)
                cr->paint();
                cr->restore();
        }
+       else
+       {
+               cr->save();
+               cairo_set_source_surface(cr->cobj(), cs, 0, 0);
+               cairo_surface_destroy(cs);
+               cr->paint();
+               cr->restore();
+       }
 
        //synfig::warning("Refresh the draw area");
        //make sure the widget refreshes
@@ -1084,6 +1134,9 @@ void studio::Widget_Preview::eraseall()
        stoprender();
 
        currentbuf.clear();
+       if(current_surface)
+               cairo_surface_destroy(current_surface);
+       current_surface=NULL;
        currentindex = 0;
        timedisp = 0;
        queue_draw();
diff --git a/synfig-studio/src/gui/preview.h b/synfig-studio/src/gui/preview.h
index e834eaa..0d5b611 100644
--- a/synfig-studio/src/gui/preview.h
+++ b/synfig-studio/src/gui/preview.h
@@ -74,6 +74,10 @@ public:
                {
                        surface=NULL;
                }
+               //Copy constructor
+               FlipbookElem(const FlipbookElem& other): t(other.t) 
,buf(other.buf), surface(cairo_surface_reference(other.surface))
+               {
+               }
                ~FlipbookElem()
                {
                        if(surface)
@@ -192,6 +196,7 @@ class Widget_Preview : public Gtk::Table
        Gtk::ScrolledWindow     preview_window;
        //Glib::RefPtr<Gdk::GC>         gc_area;
        Glib::RefPtr<Gdk::Pixbuf>       currentbuf;
+       cairo_surface_t* current_surface;
        int                             currentindex;
        //double                        timeupdate;
        double                          timedisp;


------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_feb
_______________________________________________
Synfig-devl mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/synfig-devl

Reply via email to