Author: Carlos Lopez <genet...@gmail.com> Date: Thu Aug 23 19:02:05 2012 +0200
Rotate Layer: add support for Cairo render --- synfig-core/src/modules/lyr_std/rotate.cpp | 108 ++++++++++++++++++++++++++++ synfig-core/src/modules/lyr_std/rotate.h | 1 + 2 files changed, 109 insertions(+), 0 deletions(-) diff --git a/synfig-core/src/modules/lyr_std/rotate.cpp b/synfig-core/src/modules/lyr_std/rotate.cpp index 4fd9356..9966179 100644 --- a/synfig-core/src/modules/lyr_std/rotate.cpp +++ b/synfig-core/src/modules/lyr_std/rotate.cpp @@ -336,6 +336,114 @@ Rotate::accelerated_render(Context context,Surface *surface,int quality, const R return true; } +//////// +bool +Rotate::accelerated_cairorender(Context context,cairo_surface_t *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const +{ + + const Point otl(renddesc.get_tl()); + const Point obr(renddesc.get_br()); + const int w(renddesc.get_w()); + const int h(renddesc.get_h()); + + // Width and Height of a pixel + const Real pw = (obr[0] - otl[0]) / w; + const Real ph = (obr[1] - otl[1]) / h; + + // These are the scale values + const double sx(1/pw); + const double sy(1/ph); + +// if(amount.dist(Angle::deg(0))==Angle::deg(0)) +// return context.accelerated_cairorender(surface,quality,renddesc,cb); +// if(amount.dist(Angle::deg(180))==Angle::deg(0)) +// { +// RendDesc desc(renddesc); +// desc.clear_flags(); +// Point tmp; +// tmp=renddesc.get_tl()-origin; +// desc.set_tl(Point(-tmp[0],-tmp[1])+origin); +// tmp=renddesc.get_br()-origin; +// desc.set_br(Point(-tmp[0],-tmp[1])+origin); +// return context.accelerated_cairorender(surface,quality,desc,cb); +// } + Point tl(renddesc.get_tl()-origin); + Point br(renddesc.get_br()-origin); + + { + Point rot_tl(cos_val*tl[0]+sin_val*tl[1],-sin_val*tl[0]+cos_val*tl[1]); + Point rot_br(cos_val*br[0]+sin_val*br[1],-sin_val*br[0]+cos_val*br[1]); + Point rot_tr(cos_val*br[0]+sin_val*tl[1],-sin_val*br[0]+cos_val*tl[1]); + Point rot_bl(cos_val*tl[0]+sin_val*br[1],-sin_val*tl[0]+cos_val*br[1]); + rot_tl+=origin; + rot_br+=origin; + rot_tr+=origin; + rot_bl+=origin; + + Point min_point(min(min(min(rot_tl[0],rot_br[0]),rot_tr[0]),rot_bl[0]),min(min(min(rot_tl[1],rot_br[1]),rot_tr[1]),rot_bl[1])); + Point max_point(max(max(max(rot_tl[0],rot_br[0]),rot_tr[0]),rot_bl[0]),max(max(max(rot_tl[1],rot_br[1]),rot_tr[1]),rot_bl[1])); + + if(tl[0]>br[0]) + { + tl[0]=max_point[0]; + br[0]=min_point[0]; + } + else + { + br[0]=max_point[0]; + tl[0]=min_point[0]; + } + if(tl[1]>br[1]) + { + tl[1]=max_point[1]; + br[1]=min_point[1]; + } + else + { + br[1]=max_point[1]; + tl[1]=min_point[1]; + } + } + Real pww=(renddesc.get_w())/(renddesc.get_br()[0]-renddesc.get_tl()[0]); + Real phh=(renddesc.get_h())/(renddesc.get_br()[1]-renddesc.get_tl()[1]); + // we're going to round the canvas size to an integer number of pixels, so round the + // tl-br rectangle accordingly - otherwise we see the jittering described in bug 2152666 + br[0] -= (pww*(br[0]-tl[0]) - round_to_int(pww*(br[0]-tl[0]))) / pww; + br[1] -= (phh*(br[1]-tl[1]) - round_to_int(phh*(br[1]-tl[1]))) / phh; + + RendDesc desc(renddesc); + desc.clear_flags(); + desc.set_tl(tl); + desc.set_br(br); + desc.set_wh(round_to_int(pww*(br[0]-tl[0])),round_to_int(phh*(br[1]-tl[1]))); + + cairo_surface_t* source=cairo_surface_create_similar(surface, CAIRO_CONTENT_COLOR_ALPHA, desc.get_w(), desc.get_h()); + + if(!context.accelerated_cairorender(source,quality,desc,cb)) + return false; + + cairo_t *cr=cairo_create(surface); + cairo_save(cr); + + float angle=Angle::rad(amount).get(); + cairo_translate(cr, (origin[0]-otl[0])*sx, (origin[1]-otl[1])*sy); + cairo_rotate(cr, -1.0*angle); + cairo_translate(cr, -(origin[0]-otl[0])*sx, -(origin[1]-otl[1])*sy); + cairo_set_source_surface(cr, source, (tl[0]-otl[0])*sx, (tl[1]-otl[1])*sy); + + if(quality>8) cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST); + else if(quality>=4) cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_GOOD); + else cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_BEST); + + cairo_set_operator(cr, CAIRO_OPERATOR_OVER); // again this has to be the real operator + cairo_paint(cr); + cairo_restore(cr); + cairo_surface_destroy(source); + cairo_destroy(cr); + return true; + +} +/////////// Rect Rotate::get_full_bounding_rect(Context context)const { diff --git a/synfig-core/src/modules/lyr_std/rotate.h b/synfig-core/src/modules/lyr_std/rotate.h index a80d3de..bf7b6f6 100644 --- a/synfig-core/src/modules/lyr_std/rotate.h +++ b/synfig-core/src/modules/lyr_std/rotate.h @@ -62,6 +62,7 @@ public: virtual ValueBase get_param(const synfig::String & param)const; virtual Color get_color(Context context, const Point &pos)const; virtual bool accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const; + virtual bool accelerated_cairorender(Context context,cairo_surface_t *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const; synfig::Layer::Handle hit_check(synfig::Context context, const synfig::Point &point)const; virtual Vocab get_param_vocab()const; virtual Rect get_full_bounding_rect(Context context)const; ------------------------------------------------------------------------------ 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