Author: Carlos Lopez <[email protected]>
Date: Sun Oct 14 10:23:34 2012 +0200
Cairo operators: Add support for blend modes not supported by Cairo. Add
support for MULTIPLY, HUE, SATURATION, LUMINANCE, SCREEN and HARD_LIGHT. The
transparency is not correctly handled in those cases and could need further
operations.
---
synfig-core/src/synfig/cairo_operators.cpp | 96 +++++++++++++++++++++++++++-
1 files changed, 93 insertions(+), 3 deletions(-)
diff --git a/synfig-core/src/synfig/cairo_operators.cpp
b/synfig-core/src/synfig/cairo_operators.cpp
index ae93917..cb53a42 100644
--- a/synfig-core/src/synfig/cairo_operators.cpp
+++ b/synfig-core/src/synfig/cairo_operators.cpp
@@ -30,6 +30,7 @@
#endif
#include "cairo_operators.h"
+#include "surface.h"
#include "general.h"
@@ -75,7 +76,7 @@ void cairo_paint_with_alpha_operator(cairo_t* acr, float
alpha, Color::BlendMeth
case Color::BLEND_BRIGHTEN:
{
cairo_surface_t*
dest=cairo_copy_target_image(cairo_get_target(cr), alpha);
- cairo_set_operator(cr, CAIRO_OPERATOR_HSL_LUMINOSITY);
+ cairo_set_operator(cr, CAIRO_OPERATOR_LIGHTEN);
cairo_identity_matrix(cr);
cairo_mask_surface(cr, dest, 0,0);
cairo_surface_destroy(dest);
@@ -90,6 +91,42 @@ void cairo_paint_with_alpha_operator(cairo_t* acr, float
alpha, Color::BlendMeth
cairo_surface_destroy(dest);
break;
}
+ case Color::BLEND_MULTIPLY:
+ {
+ cairo_surface_t*
dest=cairo_copy_target_image(cairo_get_target(cr), alpha);
+ cairo_set_operator(cr, CAIRO_OPERATOR_MULTIPLY);
+ cairo_identity_matrix(cr);
+ cairo_mask_surface(cr, dest, 0,0);
+ cairo_surface_destroy(dest);
+ break;
+ }
+ case Color::BLEND_HUE:
+ {
+ cairo_surface_t*
dest=cairo_copy_target_image(cairo_get_target(cr), alpha);
+ cairo_set_operator(cr, CAIRO_OPERATOR_HSL_HUE);
+ cairo_identity_matrix(cr);
+ cairo_mask_surface(cr, dest, 0,0);
+ cairo_surface_destroy(dest);
+ break;
+ }
+ case Color::BLEND_SATURATION:
+ {
+ cairo_surface_t*
dest=cairo_copy_target_image(cairo_get_target(cr), alpha);
+ cairo_set_operator(cr, CAIRO_OPERATOR_HSL_SATURATION);
+ cairo_identity_matrix(cr);
+ cairo_mask_surface(cr, dest, 0,0);
+ cairo_surface_destroy(dest);
+ break;
+ }
+ case Color::BLEND_LUMINANCE:
+ {
+ cairo_surface_t*
dest=cairo_copy_target_image(cairo_get_target(cr), alpha);
+ cairo_set_operator(cr, CAIRO_OPERATOR_HSL_LUMINOSITY);
+ cairo_identity_matrix(cr);
+ cairo_mask_surface(cr, dest, 0,0);
+ cairo_surface_destroy(dest);
+ break;
+ }
case Color::BLEND_BEHIND:
{
cairo_set_operator(cr, CAIRO_OPERATOR_DEST_OVER);
@@ -102,6 +139,24 @@ void cairo_paint_with_alpha_operator(cairo_t* acr, float
alpha, Color::BlendMeth
cairo_paint_with_alpha(cr, alpha);
break;
}
+ case Color::BLEND_SCREEN:
+ {
+ cairo_surface_t*
dest=cairo_copy_target_image(cairo_get_target(cr), alpha);
+ cairo_set_operator(cr, CAIRO_OPERATOR_SCREEN);
+ cairo_identity_matrix(cr);
+ cairo_mask_surface(cr, dest, 0,0);
+ cairo_surface_destroy(dest);
+ break;
+ }
+ case Color::BLEND_HARD_LIGHT:
+ {
+ cairo_surface_t*
dest=cairo_copy_target_image(cairo_get_target(cr), alpha);
+ cairo_set_operator(cr, CAIRO_OPERATOR_HARD_LIGHT);
+ cairo_identity_matrix(cr);
+ cairo_mask_surface(cr, dest, 0,0);
+ cairo_surface_destroy(dest);
+ break;
+ }
case Color::BLEND_ALPHA_OVER:
{
cairo_set_operator(cr, CAIRO_OPERATOR_DEST_OUT);
@@ -125,10 +180,45 @@ void cairo_paint_with_alpha_operator(cairo_t* acr, float
alpha, Color::BlendMeth
cairo_surface_destroy(source);
break;
}
+ case Color::BLEND_ADD:
+ case Color::BLEND_SUBTRACT:
+ case Color::BLEND_DIVIDE:
+ case Color::BLEND_ALPHA_BRIGHTEN:
+ case Color::BLEND_ALPHA_DARKEN:
+ case Color::BLEND_OVERLAY:
default:
{
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
- cairo_paint_with_alpha(cr, alpha);
+ cairo_surface_t* target=cairo_get_target(cr);
+ cairo_surface_t* dest=cairo_copy_target_image(target);
+
+ cairo_save(cr);
+ cairo_reset_clip(cr);
+ cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint(cr);
+ cairo_restore(cr);
+
+ cairo_paint(cr);
+
+ CairoSurface cresult(target);
+ CairoSurface cdest(dest);
+ assert(cdest.map_cairo_image());
+ assert(cresult.map_cairo_image());
+
+ int w=cresult.get_w();
+ int h=cresult.get_h();
+
+ for(int y=0;y<h;y++)
+ for(int x=0;x<w;x++)
+ {
+ Color
src=Color(cresult[y][x].demult_alpha());
+ Color
dst=Color(cdest[y][x].demult_alpha());
+
cresult[y][x]=CairoColor(Color::blend(src, dst, alpha,
method).clamped()).premult_alpha();
+ }
+
+ cresult.unmap_cairo_image();
+ cdest.unmap_cairo_image();
+
+ cairo_surface_destroy(dest);
break;
}
}
------------------------------------------------------------------------------
Don't let slow site performance ruin your business. Deploy New Relic APM
Deploy New Relic app performance management and know exactly
what is happening inside your Ruby, Python, PHP, Java, and .NET app
Try New Relic at no cost today and get our sweet Data Nerd shirt too!
http://p.sf.net/sfu/newrelic-dev2dev
_______________________________________________
Synfig-devl mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/synfig-devl