Author: Carlos Lopez <[email protected]>
Date: Thu Feb 28 12:57:34 2013 +0100
Navigator now uses Cairo render based on user preference.
Gamma is wrong and pending to fix.
---
synfig-studio/src/gui/docks/dock_navigator.cpp | 153 +++++++++++++-----------
synfig-studio/src/gui/docks/dock_navigator.h | 13 +-
2 files changed, 92 insertions(+), 74 deletions(-)
diff --git a/synfig-studio/src/gui/docks/dock_navigator.cpp
b/synfig-studio/src/gui/docks/dock_navigator.cpp
index e066b5c..99ef0de 100644
--- a/synfig-studio/src/gui/docks/dock_navigator.cpp
+++ b/synfig-studio/src/gui/docks/dock_navigator.cpp
@@ -71,7 +71,8 @@
studio::Widget_NavView::Widget_NavView(CanvasView::LooseHandle cv)
:canvview(cv),
adj_zoom(0,-4,4,1,2),
scrolling(false),
-surface(new synfig::Surface)
+surface(new synfig::Surface),
+cairo_surface(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 2, 2))
{
attach(drawto,0,4,0,1);
@@ -118,6 +119,7 @@ surface(new synfig::Surface)
studio::Widget_NavView::~Widget_NavView()
{
+ cairo_surface_destroy(*(cairo_surface.get()));
}
@@ -130,60 +132,68 @@ void studio::Widget_NavView::on_start_render()
{
if(dirty)
{
- //synfig::warning("Nav: Starting render");
- //synfig::warning("Nav: Rendering canvas");
- etl::handle<Target_Scanline> targ =
surface_target(surface.get());
-
- targ->set_canvas(get_canvas_view()->get_canvas());
- targ->set_remove_alpha();
- targ->set_avoid_time_sync();
-
targ->set_quality(get_canvas_view()->get_work_area()->get_quality());
- //synfig::info("Set the quality level to: %d",
get_canvas_view()->get_work_area()->get_quality());
-
//this should set it to render a single frame
RendDesc r =
get_canvas_view()->get_canvas()->rend_desc();
r.set_time(get_canvas_view()->canvas_interface()->get_time());
//this changes the size of the canvas to the closest thing we
can find
int sw = r.get_w(), sh = r.get_h();
-
- //synfig::warning("Nav: source image is %d x %d", sw,sh);
-
+
//resize so largest dimension is 128
int dw = sw > sh ? 128 : sw*128/sh,
- dh = sh > sw ? 128 : sh*128/sw;
-
- //synfig::warning("Nav: dest image is %d x %d", dw,dh);
-
+ dh = sh > sw ? 128 : sh*128/sw;
+
r.set_w(dw);
r.set_h(dh);
- //get the pw and ph
- //float pw = r.get_pw();
- //float ph = r.get_ph();
- //synfig::warning("Nav: pixel size is %f x %f", pw,ph);
-
- //this renders that single frame
- targ->set_rend_desc(&r);
-
- //synfig::warning("Nav: Building async renderer and starting
it...");
-
- renderer = new AsyncRenderer(targ);
+ if(studio::App::navigator_uses_cairo)
+ {
+ // Create a cairo_image_target
+ etl::handle<Target_Cairo> targ =
cairo_image_target(cairo_surface.get());
+ // Fill the target with the proper information
+ targ->set_canvas(get_canvas_view()->get_canvas());
+ targ->set_remove_alpha();
+ targ->set_avoid_time_sync();
+
targ->set_quality(get_canvas_view()->get_work_area()->get_quality());
+ targ->set_rend_desc(&r);
+ // Sets up a Asynchronous renderer
+ renderer = new AsyncRenderer(targ);
+ }
+ else
+ {
+ // Create a surface_target
+ etl::handle<Target_Scanline> targ =
surface_target(surface.get());
+ // Fill the target with the proper information
+ targ->set_canvas(get_canvas_view()->get_canvas());
+ targ->set_remove_alpha();
+ targ->set_avoid_time_sync();
+
targ->set_quality(get_canvas_view()->get_work_area()->get_quality());
+ targ->set_rend_desc(&r);
+ // Sets up a Asynchronous renderer
+ renderer = new AsyncRenderer(targ);
+ }
+ // connnect the renderer success to the finish render handler
renderer->signal_success().connect(sigc::mem_fun(*this,&Widget_NavView::on_finish_render));
+ // Mark it as clean since we are to start to render
dirty = false;
+ // start the asynchronous rendering
renderer->start();
}
}
void studio::Widget_NavView::on_finish_render()
{
+ if(studio::App::navigator_uses_cairo)
+ {
+ cairo_surface_t* surf=*cairo_surface.get();
+ if(cairo_surface_status(surf))
+ return;
+ queue_draw();
+ return;
+ }
//convert it into our pixmap
PixelFormat pf(PF_RGB);
- //synfig::warning("Nav: It hath succeeded!!!");
-
- //assert(renderer && renderer->has_success());
- //synfig::warning("Nav: now we know it really succeeded");
if(!*surface)
{
synfig::warning("dock_navigator: Bad surface");
@@ -227,9 +237,6 @@ void studio::Widget_NavView::on_finish_render()
}
else
{
- //synfig::warning("Nav: Don't need to resize");
- //convert into our buffered dataS
- //synfig::warning("Nav: converting color format into buffer");
if(prev) //just in case we're stupid
{
convert_color_format((unsigned char
*)prev->get_pixels(), (*surface)[0], dw*dh, pf, App::gamma);
@@ -267,31 +274,34 @@ bool
studio::Widget_NavView::on_expose_draw(GdkEventExpose */*exp*/)
return false;
#endif
- //print out the zoom
- //HACK kind of...
-
//zoom_print.set_text(strprintf("%.1f%%",100*unit_to_zoom(adj_zoom.get_value())));
-
//draw the good stuff
on_start_render();
//if we've got a preview etc. display it...
- if(get_canvas_view() && prev)
+ if(get_canvas_view())
{
//axis transform from units to pixel coords
float xaxis = 0, yaxis = 0;
int canvw =
get_canvas_view()->get_canvas()->rend_desc().get_w();
- //int canvh =
get_canvas_view()->get_canvas()->rend_desc().get_h();
-
+ int w, h;
+
float pw =
get_canvas_view()->get_canvas()->rend_desc().get_pw();
float ph =
get_canvas_view()->get_canvas()->rend_desc().get_ph();
-
- int w = prev->get_width();
- int h = prev->get_height();
+ if(prev && !studio::App::navigator_uses_cairo)
+ {
+ w = prev->get_width();
+ h = prev->get_height();
+ }
+ else
+ {
+ w=cairo_image_surface_get_width(*cairo_surface.get());
+ h=cairo_image_surface_get_height(*cairo_surface.get());
+ }
//scale up/down to the nearest pixel ratio...
//and center in center
- int offx=0, offy=0;
+ float offx=0, offy=0;
float sx, sy;
int nw,nh;
@@ -299,8 +309,6 @@ bool studio::Widget_NavView::on_expose_draw(GdkEventExpose
*/*exp*/)
sx = drawto.get_width() / (float)w;
sy = drawto.get_height() / (float)h;
- //synfig::warning("Nav redraw: now to scale the bitmap: %.3f x
%.3f",sx,sy);
-
//round to smallest scale (fit entire thing in window without
distortion)
if(sx > sy) sx = sy;
//else sy = sx;
@@ -323,24 +331,33 @@ bool
studio::Widget_NavView::on_expose_draw(GdkEventExpose */*exp*/)
//trivial escape
if(nw == 0 || nh == 0)return true;
-
//draw to drawing area
- Glib::RefPtr<Gdk::GC> gc =
Gdk::GC::create(drawto.get_window());
Cairo::RefPtr<Cairo::Context> cr =
drawto.get_window()->create_cairo_context();
- //synfig::warning("Nav: Scaling pixmap to off (%d,%d) with size
(%d,%d)", offx,offy,nw, nh);
- Glib::RefPtr<Gdk::Pixbuf> scalepx =
prev->scale_simple(nw,nh,Gdk::INTERP_NEAREST);
-
+ if(prev && !studio::App::navigator_uses_cairo)
+ {
+ Glib::RefPtr<Gdk::Pixbuf> scalepx =
prev->scale_simple(nw,nh,Gdk::INTERP_NEAREST);
+
+ cr->save();
+
+ //synfig::warning("Nav: Drawing scaled bitmap");
+ Gdk::Cairo::set_source_pixbuf(
+ cr, //cairo context
+ scalepx, //pixbuf
+ (int)offx, (int)offy //coordinates to place
upper left corner of pixbuf
+ );
+ cr->paint();
+ cr->restore();
+ }
+ if(studio::App::navigator_uses_cairo)
+ {
+ cr->save();
+ cr->scale(sx, sx);
+ cairo_set_source_surface(cr->cobj(),
*cairo_surface.get(), offx/sx, offy/sx);
+ cr->paint();
+ cr->restore();
+ }
cr->save();
-
- //synfig::warning("Nav: Drawing scaled bitmap");
- Gdk::Cairo::set_source_pixbuf(
- cr, //cairo context
- scalepx, //pixbuf
- offx, offy //coordinates to place upper left corner of
pixbuf
- );
- cr->paint();
-
//draw fancy red rectangle around focus point
const Point &wtl =
get_canvas_view()->work_area->get_window_tl(),
&wbr =
get_canvas_view()->work_area->get_window_br();
@@ -360,21 +377,21 @@ bool
studio::Widget_NavView::on_expose_draw(GdkEventExpose */*exp*/)
//coord system:
// tl : (offx,offy)
// axis multipliers = xaxis,yaxis
- //synfig::warning("Nav: tl (%f,%f), br (%f,%f)",
wtl[0],wtl[1],wbr[0],wbr[1]);
- //synfig::warning("Nav: tl (%f,%f), br (%f,%f)",
wtl[0],wtl[1],wbr[0],wbr[1]);
- //synfig::warning("Nav: Drawing Rectangle (%d,%d) with dim
(%d,%d)", l,t,rw,rh);
cr->set_line_width(2.0);
cr->set_line_cap(Cairo::LINE_CAP_BUTT);
cr->set_line_join(Cairo::LINE_JOIN_MITER);
cr->set_antialias(Cairo::ANTIALIAS_NONE);
- cr->set_source_rgb(1,0,0);
+ // Visually distinguish when using Cairo on Navigator or not.
+ if(!studio::App::navigator_uses_cairo)
+ cr->set_source_rgb(1,0,0);
+ else
+ cr->set_source_rgb(0,1,0);
cr->rectangle(l,t,rw,rh);
cr->stroke();
cr->restore();
}
-
return false; //draw everything else too
}
diff --git a/synfig-studio/src/gui/docks/dock_navigator.h
b/synfig-studio/src/gui/docks/dock_navigator.h
index 4100af1..a346eb8 100644
--- a/synfig-studio/src/gui/docks/dock_navigator.h
+++ b/synfig-studio/src/gui/docks/dock_navigator.h
@@ -53,17 +53,17 @@ class AsyncRenderer;
class Widget_NavView : public Gtk::Table
{
//handle to out parent canvas
- CanvasView::LooseHandle canvview;
+ CanvasView::LooseHandle canvview;
- Glib::RefPtr<Gdk::Pixbuf> prev;
+ Glib::RefPtr<Gdk::Pixbuf> prev;
bool dirty;
//The drawing stuff
- Gtk::DrawingArea drawto;
+ Gtk::DrawingArea drawto;
//The input stuff
- Gtk::Adjustment adj_zoom;
- Gtk::Label zoom_print;
+ Gtk::Adjustment adj_zoom;
+ Gtk::Label zoom_print;
//zoom window stuff
bool scrolling;
@@ -71,7 +71,8 @@ class Widget_NavView : public Gtk::Table
//asynchronous rendering stuff
etl::handle<AsyncRenderer> renderer;
etl::smart_ptr<synfig::Surface> surface;
- bool rendering;
+ etl::smart_ptr<cairo_surface_t*> cairo_surface;
+ bool rendering;
//drawing functionality
void on_start_render(); //breaks out into asynchronous rendering
------------------------------------------------------------------------------
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