Author: Carlos Lopez <[email protected]>
Date:   Fri Nov 23 19:11:34 2012 +0100

Cairo Operators: Add support for blend mode DIVIDE using a custom blend 
function.

---

 synfig-core/src/synfig/cairo_operators.cpp |   44 ++++++++++++++++++++++++++-
 synfig-core/src/synfig/color.cpp           |   45 ++++++++++++++++++++++++++++
 2 files changed, 88 insertions(+), 1 deletions(-)

diff --git a/synfig-core/src/synfig/cairo_operators.cpp 
b/synfig-core/src/synfig/cairo_operators.cpp
index 5a5d862..9247835 100644
--- a/synfig-core/src/synfig/cairo_operators.cpp
+++ b/synfig-core/src/synfig/cairo_operators.cpp
@@ -231,10 +231,52 @@ void cairo_paint_with_alpha_operator(cairo_t* acr, float 
alpha, Color::BlendMeth
                        break;
                        
                }
+               case Color::BLEND_DIVIDE:
+               {
+                       cairo_push_group(cr);
+                       cairo_paint(cr);
+                       cairo_pattern_t* pattern=cairo_pop_group(cr);
+                       
+                       cairo_surface_t* source;
+                       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());
+                       assert(csource.map_cairo_image());
+                       
+                       double x1, y1, x2, y2, x0, y0;
+                       cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
+                       cairo_user_to_device(cr, &x1, &y1);
+                       cairo_user_to_device(cr, &x2, &y2);
+                       x0=x2<x1?x2:x1;
+                       y0=y2<y1?y2:y1;
+                       
+                       int w=csource.get_w();
+                       int h=csource.get_h();
+                       int h0=(int)y0;
+                       int w0=(int)x0;
+                       
+                       for(int y=0;y<h;y++)
+                               for(int x=0;x<w;x++)
+                               {
+                                       
cdest[h0+y][w0+x]=CairoColor::blend(csource[y][x], cdest[h0+y][w0+x], alpha,    
method);
+                               }
+                       csource.unmap_cairo_image();
+                       cdest.unmap_cairo_image();
+
+                       cairo_pattern_destroy(pattern);
+                       break;
+               }
                case Color::BLEND_ADD:
                case Color::BLEND_SUBTRACT:
                case Color::BLEND_DIFFERENCE:
-               case Color::BLEND_DIVIDE:
+               case Color::BLEND_COLOR:
                case Color::BLEND_ALPHA_BRIGHTEN:
                case Color::BLEND_ALPHA_DARKEN:
                default:
diff --git a/synfig-core/src/synfig/color.cpp b/synfig-core/src/synfig/color.cpp
index 67d51ae..95d538e 100644
--- a/synfig-core/src/synfig/color.cpp
+++ b/synfig-core/src/synfig/color.cpp
@@ -435,6 +435,51 @@ blendfunc_DIVIDE(C &a,C &b,float amount)
        return b;
 }
 
+// Specialization for CairoColor
+template <>
+static CairoColor
+blendfunc_DIVIDE(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();
+       
+       float alpha=amount*aa/255.0;
+       float ahpla=1.0-alpha;
+       
+       if(ab==0)
+               return CairoColor();
+       
+       ac=ab;
+       
+       if(ra==0)
+               rc=255;
+       else
+               rc=(rb*alpha*aa)/ra + ahpla*rb;
+
+       if(ga==0)
+               gc=255;
+       else
+               gc=(gb*alpha*aa)/ga + ahpla*gb;
+
+       if(ba==0)
+               bc=255;
+       else
+               bc=(bb*alpha*aa)/ba + ahpla*bb;
+               
+       return CairoColor(rc, gc, bc, ac);
+}
+
 template <class C>
 static C
 blendfunc_COLOR(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