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

Reply via email to