Author: Carlos Lopez <[email protected]>
Date:   Sun Nov 25 21:25:55 2012 +0100

Cairo Operators: Add support for blend mode BRIGHTEN and DARKEN using a custom 
blend function.
Native Cairo operators didn't give the same result.

---

 synfig-core/src/synfig/cairo_operators.cpp |   36 +-----------
 synfig-core/src/synfig/color.cpp           |   88 ++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 34 deletions(-)

diff --git a/synfig-core/src/synfig/cairo_operators.cpp 
b/synfig-core/src/synfig/cairo_operators.cpp
index 842233d..9840417 100644
--- a/synfig-core/src/synfig/cairo_operators.cpp
+++ b/synfig-core/src/synfig/cairo_operators.cpp
@@ -73,34 +73,6 @@ void cairo_paint_with_alpha_operator(cairo_t* acr, float 
alpha, Color::BlendMeth
                        cairo_paint_with_alpha(cr, alpha);              
                        break;
                }
-               case Color::BLEND_BRIGHTEN:
-               {
-                       cairo_push_group(cr);
-                       cairo_identity_matrix(cr);
-                       cairo_set_source_surface(cr, cairo_get_target(cr), 0, 
0);
-                       cairo_paint_with_alpha(cr, alpha);
-                       cairo_pattern_t* pattern=cairo_pop_group(cr);
-                       
-                       cairo_set_operator(cr, CAIRO_OPERATOR_LIGHTEN);
-                       cairo_mask(cr, pattern);
-                       
-                       cairo_pattern_destroy(pattern);
-                       break;
-               }
-               case Color::BLEND_DARKEN:
-               {
-                       cairo_push_group(cr);
-                       cairo_identity_matrix(cr);
-                       cairo_set_source_surface(cr, cairo_get_target(cr), 0, 
0);
-                       cairo_paint_with_alpha(cr, alpha);
-                       cairo_pattern_t* pattern=cairo_pop_group(cr);
-                       
-                       cairo_set_operator(cr, CAIRO_OPERATOR_DARKEN);
-                       cairo_mask(cr, pattern);
-                       
-                       cairo_pattern_destroy(pattern);
-                       break;
-               }
                case Color::BLEND_MULTIPLY:
                {
                        cairo_push_group(cr);
@@ -230,10 +202,7 @@ void cairo_paint_with_alpha_operator(cairo_t* acr, float 
alpha, Color::BlendMeth
                        cairo_status_t status;
                        status=cairo_pattern_get_surface(pattern, &source);
                        if(status)
-                       {
-                               synfig::info("%s", 
cairo_status_to_string(status));
                                return;
-                       }
                        CairoSurface csource(source);
                        CairoSurface cdest(cairo_get_target(cr));
                        assert(cdest.map_cairo_image());
@@ -271,6 +240,8 @@ void cairo_paint_with_alpha_operator(cairo_t* acr, float 
alpha, Color::BlendMeth
                        break;
                        
                }
+               case Color::BLEND_BRIGHTEN:
+               case Color::BLEND_DARKEN:
                case Color::BLEND_ADD:
                case Color::BLEND_SUBTRACT:
                case Color::BLEND_DIFFERENCE:
@@ -286,10 +257,7 @@ void cairo_paint_with_alpha_operator(cairo_t* acr, float 
alpha, Color::BlendMeth
                        cairo_status_t status;
                        status=cairo_pattern_get_surface(pattern, &source);
                        if(status)
-                       {
-                               synfig::info("%s", 
cairo_status_to_string(status));
                                return;
-                       }
                        CairoSurface csource(source);
                        CairoSurface cdest(cairo_get_target(cr));
                        assert(cdest.map_cairo_image());
diff --git a/synfig-core/src/synfig/color.cpp b/synfig-core/src/synfig/color.cpp
index c4b199c..2735f9b 100644
--- a/synfig-core/src/synfig/color.cpp
+++ b/synfig-core/src/synfig/color.cpp
@@ -345,6 +345,49 @@ blendfunc_BRIGHTEN(C &a,C &b,float amount)
        return b;
 }
 
+//Specialization for CairoColor
+template <>
+static CairoColor
+blendfunc_BRIGHTEN(CairoColor &a, CairoColor &b, float amount)
+{
+       int ra, ga, ba, aa;
+       int rb, gb, bb, ab;
+       int rc, gc, bc, ac;
+       
+       ra=a.get_r();
+       ga=a.get_g();
+       ba=a.get_b();
+       aa=a.get_a();
+       
+       rb=b.get_r();
+       gb=b.get_g();
+       bb=b.get_b();
+       ab=b.get_a();
+
+       const int raab(ra*ab*amount/255.0);
+       const int gaab(ga*ab*amount/255.0);
+       const int baab(ba*ab*amount/255.0);
+       
+       if(rb<raab)
+               rc=raab;
+       else
+               rc=rb;
+               
+       if(gb<gaab)
+               gc=gaab;
+       else
+               gc=gb;
+       
+       if(bb<baab)
+               bc=baab;
+       else
+               bc=bb;
+
+       ac=ab;
+               
+       return CairoColor(rc, gc, bc, ac);
+}
+
 template <class C>
 static C
 blendfunc_DARKEN(C &a,C &b,float amount)
@@ -365,6 +408,51 @@ blendfunc_DARKEN(C &a,C &b,float amount)
        return b;
 }
 
+//Specialization for CairoColor
+template <>
+static CairoColor
+blendfunc_DARKEN(CairoColor &a, CairoColor &b, float amount)
+{
+       int ra, ga, ba, aa;
+       int rb, gb, bb, ab;
+       int rc, gc, bc, ac;
+       
+       ra=a.get_r();
+       ga=a.get_g();
+       ba=a.get_b();
+       aa=a.get_a();
+       
+       rb=b.get_r();
+       gb=b.get_g();
+       bb=b.get_b();
+       ab=b.get_a();
+       
+       const int ab255=ab*255;
+       const int abaa=ab*aa;
+       
+       int rcompare=(amount*(ra*ab-abaa)+ab255)/255;
+       if(rb > rcompare)
+               rc=rcompare;
+       else
+               rc=rb;
+               
+       int gcompare=(amount*(ga*ab-abaa)+ab255)/255;
+       if(gb > gcompare)
+               gc=gcompare;
+       else
+               gc=gb;
+
+       int bcompare=(amount*(ba*ab-abaa)+ab255)/255;
+       if(bb > bcompare)
+               bc=bcompare;
+       else
+               bc=bb;
+       
+       ac=ab;
+       
+       return CairoColor(rc, gc, bc, ac);
+}
+
 template <class C>
 static C
 blendfunc_ADD(C &a,C &b,float amount)


------------------------------------------------------------------------------
Monitor your physical, virtual and cloud infrastructure from a single
web console. Get in-depth insight into apps, servers, databases, vmware,
SAP, cloud infrastructure, etc. Download 30-day Free Trial.
Pricing starts from $795 for 25 servers or applications!
http://p.sf.net/sfu/zoho_dev2dev_nov
_______________________________________________
Synfig-devl mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/synfig-devl

Reply via email to