Author: Carlos Lopez <[email protected]>
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/synfig-devl