Author: Carlos Lopez <[email protected]>
Date: Wed Aug 15 18:03:39 2012 +0200
RadialGradient: add support for Cairo render.
---
.../src/modules/mod_gradient/radialgradient.cpp | 111 ++++++++++++++++++++
.../src/modules/mod_gradient/radialgradient.h | 28 +++--
2 files changed, 128 insertions(+), 11 deletions(-)
diff --git a/synfig-core/src/modules/mod_gradient/radialgradient.cpp
b/synfig-core/src/modules/mod_gradient/radialgradient.cpp
index 6d1862e..1a5571e 100644
--- a/synfig-core/src/modules/mod_gradient/radialgradient.cpp
+++ b/synfig-core/src/modules/mod_gradient/radialgradient.cpp
@@ -255,3 +255,114 @@ RadialGradient::accelerated_render(Context
context,Surface *surface,int quality,
return true;
}
+
+bool
+RadialGradient::accelerated_cairorender(Context context,cairo_surface_t
*surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ const Point tl(renddesc.get_tl());
+ const Point br(renddesc.get_br());
+
+ const int w(renddesc.get_w());
+ const int h(renddesc.get_h());
+
+ // Width and Height of a pixel
+ const Real pw = (br[0] - tl[0]) / w;
+ const Real ph = (br[1] - tl[1]) / h;
+
+ const double tx(-tl[0]/pw);
+ const double ty(-tl[1]/ph);
+ const double sx(1/pw);
+ const double sy(1/ph);
+
+ cairo_t* cr=cairo_create(surface);
+ cairo_save(cr);
+ cairo_pattern_t* pattern=cairo_pattern_create_radial(center[0],
center[1], 0.0 ,center[0], center[1], radius);
+ bool cpoints_all_opaque=compile_gradient(pattern, gradient);
+ if(loop)
+ cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
+ if(quality>8) cairo_pattern_set_filter(pattern, CAIRO_FILTER_FAST);
+ else if(quality>=4) cairo_pattern_set_filter(pattern,
CAIRO_FILTER_GOOD);
+ else cairo_pattern_set_filter(pattern, CAIRO_FILTER_BEST);
+ if(
+ !
+ (is_solid_color() ||
+ cpoints_all_opaque &&
get_blend_method()==Color::BLEND_COMPOSITE && get_amount()==1.0)
+ )
+ {
+ // Initially render what's behind us
+
if(!context.accelerated_cairorender(surface,quality,renddesc,cb))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Accelerated
Cairo Renderer Failure",__LINE__));
+ cairo_destroy(cr);
+ return false;
+ }
+ }
+ cairo_translate(cr, tx , ty);
+ cairo_scale(cr, sx, sy);
+ cairo_set_operator(cr, CAIRO_OPERATOR_OVER); // TODO: this has to be
the real operator
+ cairo_set_source(cr, pattern);
+ cairo_paint_with_alpha(cr, get_amount());
+
+ cairo_pattern_destroy(pattern); // Not needed more
+ cairo_restore(cr);
+ cairo_destroy(cr);
+
+}
+
+bool
+RadialGradient::compile_gradient(cairo_pattern_t* pattern, Gradient
mygradient)const
+{
+ bool cpoints_all_opaque=true;
+ float a,r,g,b;
+ Gradient::CPoint cp;
+ Gradient::const_iterator iter;
+ mygradient.sort();
+ if(zigzag)
+ {
+ Gradient zgradient;
+ for(iter=mygradient.begin();iter!=mygradient.end(); iter++)
+ {
+ cp=*iter;
+ cp.pos=cp.pos/2;
+ zgradient.push_back(cp);
+ }
+ for(iter=mygradient.begin();iter!=mygradient.end(); iter++)
+ {
+ cp=*iter;
+ cp.pos=1.0-cp.pos/2;
+ zgradient.push_back(cp);
+ }
+ mygradient=zgradient;
+ }
+ mygradient.sort();
+ if(loop)
+ {
+ cp=*mygradient.begin();
+ a=cp.color.get_a();
+ r=cp.color.get_r();
+ g=cp.color.get_g();
+ b=cp.color.get_b();
+ cairo_pattern_add_color_stop_rgba(pattern, 0.0, r, g, b, a);
+ }
+ for(iter=mygradient.begin();iter!=mygradient.end(); iter++)
+ {
+ cp=*iter;
+ a=cp.color.get_a();
+ r=cp.color.get_r();
+ g=cp.color.get_g();
+ b=cp.color.get_b();
+ cairo_pattern_add_color_stop_rgba(pattern, cp.pos, r, g, b, a);
+ if(a!=1.0) cpoints_all_opaque=false;
+ }
+ if(loop)
+ {
+ cp=*(--mygradient.end());
+ a=cp.color.get_a();
+ r=cp.color.get_r();
+ g=cp.color.get_g();
+ b=cp.color.get_b();
+ cairo_pattern_add_color_stop_rgba(pattern, 1.0, r, g, b, a);
+ }
+ return cpoints_all_opaque;
+}
+
diff --git a/synfig-core/src/modules/mod_gradient/radialgradient.h
b/synfig-core/src/modules/mod_gradient/radialgradient.h
index 4c39f91..3e638b8 100644
--- a/synfig-core/src/modules/mod_gradient/radialgradient.h
+++ b/synfig-core/src/modules/mod_gradient/radialgradient.h
@@ -39,37 +39,43 @@
/* === C L A S S E S & S T R U C T S ======================================= */
-class RadialGradient : public synfig::Layer_Composite, public
synfig::Layer_NoDeform
+using namespace synfig;
+using namespace std;
+using namespace etl;
+
+class RadialGradient : public Layer_Composite, public Layer_NoDeform
{
SYNFIG_LAYER_MODULE_EXT
private:
- synfig::Gradient gradient;
+ Gradient gradient;
- synfig::Point center;
+ Point center;
- synfig::Real radius;
+ Real radius;
bool loop;
bool zigzag;
- synfig::Color color_func(const synfig::Point &x, float
supersample=0)const;
+ Color color_func(const Point &x, float supersample=0)const;
- float calc_supersample(const synfig::Point &x, float pw,float ph)const;
+ float calc_supersample(const Point &x, float pw,float ph)const;
+ bool compile_gradient(cairo_pattern_t* pattern, Gradient gradient)const;
public:
RadialGradient();
- virtual bool set_param(const synfig::String & param, const
synfig::ValueBase &value);
+ virtual bool set_param(const String & param, const ValueBase &value);
- virtual synfig::ValueBase get_param(const synfig::String & param)const;
+ virtual ValueBase get_param(const String & param)const;
- virtual synfig::Color get_color(synfig::Context context, const
synfig::Point &pos)const;
+ virtual Color get_color(Context context, const Point &pos)const;
- virtual bool accelerated_render(synfig::Context context,synfig::Surface
*surface,int quality, const synfig::RendDesc &renddesc,
synfig::ProgressCallback *cb)const;
- synfig::Layer::Handle hit_check(synfig::Context context, const
synfig::Point &point)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;
+ Layer::Handle hit_check(Context context, const Point &point)const;
virtual Vocab get_param_vocab()const;
}; // END of class RadialGradient
------------------------------------------------------------------------------
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