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