[cairo-commit] 5 commits - configure.ac src/cairo.h src/cairo-image-surface.c src/cairo-misc.c src/cairo-pdf-surface.c src/cairo-pdf-surface-private.h src/cairo-svg-surface.c src/cairo-xlib-surface.c test/extended-blend-alpha.argb32.ref.png test/extended-blend-alpha.c test/extended-blend-alpha.rgb24.ref.png test/extended-blend.argb32.ref.png test/extended-blend.c test/extended-blend.rgb24.ref.png test/Makefile.am test/Makefile.sources

Carlos Garcia Campos carlosgc at kemper.freedesktop.org
Tue Jul 14 07:17:26 PDT 2009


 configure.ac                             |    2 
 src/cairo-image-surface.c                |   31 +++++
 src/cairo-misc.c                         |   30 +++++
 src/cairo-pdf-surface-private.h          |    4 
 src/cairo-pdf-surface.c                  |  162 ++++++++++++++++++++++++++++++-
 src/cairo-svg-surface.c                  |    6 +
 src/cairo-xlib-surface.c                 |   28 +++++
 src/cairo.h                              |   53 +++++++++-
 test/Makefile.am                         |    4 
 test/Makefile.sources                    |    2 
 test/extended-blend-alpha.argb32.ref.png |binary
 test/extended-blend-alpha.c              |  115 ++++++++++++++++++++++
 test/extended-blend-alpha.rgb24.ref.png  |binary
 test/extended-blend.argb32.ref.png       |binary
 test/extended-blend.c                    |  117 ++++++++++++++++++++++
 test/extended-blend.rgb24.ref.png        |binary
 16 files changed, 549 insertions(+), 5 deletions(-)

New commits:
commit 75736603d3b976dab8ac1ef473164c618084ee60
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date:   Wed Aug 29 15:11:23 2007 +0200

    [SVG] Add extended blend modes.

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 15e3684..3a6b62d 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -787,6 +787,12 @@ _cairo_svg_surface_operators[] = {
 
     "xor", "plus",
     "color-dodge", /* FIXME: saturate ? */
+
+    "multiply",	"screen", "overlay",
+    "darken", "lighten",
+    "color-dodge", "color-burn",
+    "hard-light", "soft-light",
+    "difference", "exclusion"
 };
 
 static cairo_bool_t
commit 47af6cf2803737ab7248d1ce4d76f038d1f3188e
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Tue Jul 14 15:34:13 2009 +0200

    [pdf] Add support for the extra blend modes
    
    HSL modes support added by Benjamin Otte <otte at gnome.org>

diff --git a/src/cairo-pdf-surface-private.h b/src/cairo-pdf-surface-private.h
index 5aedcd0..2e7d244 100644
--- a/src/cairo-pdf-surface-private.h
+++ b/src/cairo-pdf-surface-private.h
@@ -52,7 +52,10 @@ typedef struct _cairo_pdf_resource {
     unsigned int id;
 } cairo_pdf_resource_t;
 
+#define CAIRO_NUM_OPERATORS (CAIRO_OPERATOR_HSL_LUMINOSITY + 1)
+
 typedef struct _cairo_pdf_group_resources {
+    cairo_bool_t  operators[CAIRO_NUM_OPERATORS];
     cairo_array_t alphas;
     cairo_array_t smasks;
     cairo_array_t patterns;
@@ -177,6 +180,7 @@ struct _cairo_pdf_surface {
 
     cairo_bool_t force_fallbacks;
 
+    cairo_operator_t current_operator;
     cairo_bool_t current_pattern_is_solid_color;
     cairo_bool_t current_color_is_stroke;
     double current_color_red;
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 47fdb1b..0108572 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -310,6 +310,7 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t	*output,
     surface->force_fallbacks = FALSE;
     surface->select_pattern_gstate_saved = FALSE;
     surface->current_pattern_is_solid_color = FALSE;
+    surface->current_operator = CAIRO_OPERATOR_OVER;
     surface->header_emitted = FALSE;
 
     _cairo_pdf_operators_init (&surface->pdf_operators,
@@ -612,6 +613,11 @@ _cairo_pdf_surface_clear (cairo_pdf_surface_t *surface)
 static void
 _cairo_pdf_group_resources_init (cairo_pdf_group_resources_t *res)
 {
+    int i;
+
+    for (i = 0; i < CAIRO_NUM_OPERATORS; i++)
+	res->operators[i] = FALSE;
+
     _cairo_array_init (&res->alphas, sizeof (double));
     _cairo_array_init (&res->smasks, sizeof (cairo_pdf_resource_t));
     _cairo_array_init (&res->patterns, sizeof (cairo_pdf_resource_t));
@@ -632,6 +638,11 @@ _cairo_pdf_group_resources_fini (cairo_pdf_group_resources_t *res)
 static void
 _cairo_pdf_group_resources_clear (cairo_pdf_group_resources_t *res)
 {
+    int i;
+
+    for (i = 0; i < CAIRO_NUM_OPERATORS; i++)
+	res->operators[i] = FALSE;
+
     _cairo_array_truncate (&res->alphas, 0);
     _cairo_array_truncate (&res->smasks, 0);
     _cairo_array_truncate (&res->patterns, 0);
@@ -639,6 +650,15 @@ _cairo_pdf_group_resources_clear (cairo_pdf_group_resources_t *res)
     _cairo_array_truncate (&res->fonts, 0);
 }
 
+static void
+_cairo_pdf_surface_add_operator (cairo_pdf_surface_t *surface,
+				 cairo_operator_t     op)
+{
+    cairo_pdf_group_resources_t *res = &surface->resources;
+
+    res->operators[op] = TRUE;
+}
+
 static cairo_status_t
 _cairo_pdf_surface_add_alpha (cairo_pdf_surface_t *surface,
 			      double               alpha,
@@ -747,6 +767,60 @@ _cairo_pdf_surface_get_font_resource (cairo_pdf_surface_t *surface,
     return font.subset_resource;
 }
 
+static const char *
+_cairo_operator_to_pdf_blend_mode (cairo_operator_t op)
+{
+    switch (op) {
+    case CAIRO_OPERATOR_MULTIPLY:
+	return "Multiply";
+
+    case CAIRO_OPERATOR_SCREEN:
+	return "Screen";
+
+    case CAIRO_OPERATOR_OVERLAY:
+	return "Overlay";
+
+    case CAIRO_OPERATOR_DARKEN:
+	return "Darken";
+
+    case  CAIRO_OPERATOR_LIGHTEN:
+	return "Lighten";
+
+    case CAIRO_OPERATOR_COLOR_DODGE:
+	return "ColorDodge";
+
+    case CAIRO_OPERATOR_COLOR_BURN:
+	return "ColorBurn";
+
+    case CAIRO_OPERATOR_HARD_LIGHT:
+	return "HardLight";
+
+    case CAIRO_OPERATOR_SOFT_LIGHT:
+	return "SoftLight";
+
+    case CAIRO_OPERATOR_DIFFERENCE:
+	return "Difference";
+
+    case CAIRO_OPERATOR_EXCLUSION:
+	return "Exclusion";
+
+    case CAIRO_OPERATOR_HSL_HUE:
+	return "Hue";
+
+    case CAIRO_OPERATOR_HSL_SATURATION:
+	return "Saturation";
+
+    case CAIRO_OPERATOR_HSL_COLOR:
+	return "Color";
+
+    case CAIRO_OPERATOR_HSL_LUMINOSITY:
+	return "Luminosity";
+
+    default:
+	return "Normal";
+    }
+}
+
 static void
 _cairo_pdf_surface_emit_group_resources (cairo_pdf_surface_t         *surface,
 					 cairo_pdf_group_resources_t *res)
@@ -764,6 +838,13 @@ _cairo_pdf_surface_emit_group_resources (cairo_pdf_surface_t         *surface,
 	_cairo_output_stream_printf (surface->output,
 				     "   /ExtGState <<\n");
 
+	for (i = 0; i < CAIRO_NUM_OPERATORS; i++) {
+	    if (res->operators[i])
+		_cairo_output_stream_printf (surface->output,
+					     "      /b%d << /BM /%s >>\n",
+					     i, _cairo_operator_to_pdf_blend_mode(i));
+	}
+
 	for (i = 0; i < num_alphas; i++) {
 	    _cairo_array_copy_element (&res->alphas, i, &alpha);
 	    _cairo_output_stream_printf (surface->output,
@@ -1169,6 +1250,7 @@ _cairo_pdf_surface_open_stream (cairo_pdf_surface_t	*surface,
     surface->pdf_stream.length = length;
     surface->pdf_stream.compressed = compressed;
     surface->current_pattern_is_solid_color = FALSE;
+    surface->current_operator = CAIRO_OPERATOR_OVER;
     _cairo_pdf_operators_reset (&surface->pdf_operators);
 
     _cairo_output_stream_printf (surface->output,
@@ -1309,6 +1391,7 @@ _cairo_pdf_surface_open_group (cairo_pdf_surface_t  *surface,
 
     surface->group_stream.active = TRUE;
     surface->current_pattern_is_solid_color = FALSE;
+    surface->current_operator = CAIRO_OPERATOR_OVER;
     _cairo_pdf_operators_reset (&surface->pdf_operators);
 
     surface->group_stream.mem_stream = _cairo_memory_stream_create ();
@@ -3169,6 +3252,27 @@ _cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pdf_pattern
 }
 
 static cairo_status_t
+_cairo_pdf_surface_select_operator (cairo_pdf_surface_t *surface,
+				    cairo_operator_t     op)
+{
+    cairo_status_t status;
+
+    if (op == surface->current_operator)
+	return CAIRO_STATUS_SUCCESS;
+
+    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
+    if (status)
+	return status;
+
+    _cairo_output_stream_printf (surface->output,
+				 "/b%d gs\n", op);
+    surface->current_operator = op;
+    _cairo_pdf_surface_add_operator (surface, op);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
 _cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface,
 				   const cairo_pattern_t     *pattern,
 				   cairo_pdf_resource_t pattern_res,
@@ -4998,6 +5102,33 @@ _pattern_supported (const cairo_pattern_t *pattern)
     return FALSE;
 }
 
+static cairo_bool_t
+_pdf_operator_supported (cairo_operator_t op)
+{
+    switch (op) {
+    case CAIRO_OPERATOR_OVER:
+    case CAIRO_OPERATOR_MULTIPLY:
+    case CAIRO_OPERATOR_SCREEN:
+    case CAIRO_OPERATOR_OVERLAY:
+    case CAIRO_OPERATOR_DARKEN:
+    case CAIRO_OPERATOR_LIGHTEN:
+    case CAIRO_OPERATOR_COLOR_DODGE:
+    case CAIRO_OPERATOR_COLOR_BURN:
+    case CAIRO_OPERATOR_HARD_LIGHT:
+    case CAIRO_OPERATOR_SOFT_LIGHT:
+    case CAIRO_OPERATOR_DIFFERENCE:
+    case CAIRO_OPERATOR_EXCLUSION:
+    case CAIRO_OPERATOR_HSL_HUE:
+    case CAIRO_OPERATOR_HSL_SATURATION:
+    case CAIRO_OPERATOR_HSL_COLOR:
+    case CAIRO_OPERATOR_HSL_LUMINOSITY:
+	return TRUE;
+
+    default:
+	return FALSE;
+    }
+}
+
 static cairo_int_status_t
 _cairo_pdf_surface_analyze_operation (cairo_pdf_surface_t  *surface,
 				      cairo_operator_t      op,
@@ -5012,7 +5143,7 @@ _cairo_pdf_surface_analyze_operation (cairo_pdf_surface_t  *surface,
     if (! _pattern_supported (pattern))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    if (op == CAIRO_OPERATOR_OVER) {
+    if (_pdf_operator_supported (op)) {
 	if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
 	    cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern;
 
@@ -5025,7 +5156,7 @@ _cairo_pdf_surface_analyze_operation (cairo_pdf_surface_t  *surface,
 	}
     }
 
-    if (op == CAIRO_OPERATOR_OVER)
+    if (_pdf_operator_supported (op))
 	return CAIRO_STATUS_SUCCESS;
 
     /* The SOURCE operator is supported if the pattern is opaque or if
@@ -5121,6 +5252,10 @@ _cairo_pdf_surface_paint (void			*abstract_surface,
     if (unlikely (status))
 	return status;
 
+    status = _cairo_pdf_surface_select_operator (surface, op);
+    if (status)
+	return status;
+
     if (gstate_res.id != 0) {
 	group = _cairo_pdf_surface_create_smask_group (surface);
 	if (unlikely (group == NULL))
@@ -5244,6 +5379,10 @@ _cairo_pdf_surface_mask	(void			*abstract_surface,
     if (unlikely (status))
 	return status;
 
+    status = _cairo_pdf_surface_select_operator (surface, op);
+    if (status)
+	return status;
+
     _cairo_output_stream_printf (surface->output,
 				 "q /s%d gs /x%d Do Q\n",
 				 group->group_res.id,
@@ -5283,6 +5422,10 @@ _cairo_pdf_surface_stroke (void			*abstract_surface,
     if (unlikely (status))
 	return status;
 
+    status = _cairo_pdf_surface_select_operator (surface, op);
+    if (status)
+	return status;
+
     if (gstate_res.id != 0) {
 	group = _cairo_pdf_surface_create_smask_group (surface);
 	if (unlikely (group == NULL))
@@ -5381,6 +5524,10 @@ _cairo_pdf_surface_fill (void			*abstract_surface,
     if (unlikely (status))
 	return status;
 
+    status = _cairo_pdf_surface_select_operator (surface, op);
+    if (status)
+	return status;
+
     if (gstate_res.id != 0) {
 	group = _cairo_pdf_surface_create_smask_group (surface);
 	if (unlikely (group == NULL))
@@ -5481,6 +5628,13 @@ _cairo_pdf_surface_fill_stroke (void		     *abstract_surface,
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
+    if (fill_op != stroke_op)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    status = _cairo_pdf_surface_select_operator (surface, fill_op);
+    if (status)
+	return status;
+
     fill_pattern_res.id = 0;
     gstate_res.id = 0;
     status = _cairo_pdf_surface_add_pdf_pattern (surface, fill_source,
@@ -5571,6 +5725,10 @@ _cairo_pdf_surface_show_text_glyphs (void			*abstract_surface,
     if (unlikely (status))
 	return status;
 
+    status = _cairo_pdf_surface_select_operator (surface, op);
+    if (status)
+	return status;
+
     if (gstate_res.id != 0) {
 	group = _cairo_pdf_surface_create_smask_group (surface);
 	if (unlikely (group == NULL))
commit cf186d60b0d96cde859869237fa859e28a74a037
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Aug 30 10:16:00 2007 +0200

    [xlib] Add support for new operators
    
    This is of course just making sure fallbacks get used as Render does not support
    the new operators yet.

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 54cfd63..e7d30b2 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -327,6 +327,8 @@ _cairo_xlib_surface_finish (void *abstract_surface)
     return status;
 }
 
+#define CAIRO_SURFACE_RENDER_SUPPORTS_OPERATOR(surface, op)	((op) <= CAIRO_OPERATOR_SATURATE)
+
 static int
 _noop_error_handler (Display     *display,
 		     XErrorEvent *event)
@@ -1588,6 +1590,9 @@ _categorize_composite_operation (cairo_xlib_surface_t *dst,
 				 cairo_bool_t	       have_mask)
 
 {
+    if (!CAIRO_SURFACE_RENDER_SUPPORTS_OPERATOR (dst, op))
+	return DO_UNSUPPORTED;
+
     if (!dst->buggy_repeat)
 	return DO_RENDER;
 
@@ -1728,6 +1733,24 @@ _render_operator (cairo_operator_t op)
 	return PictOpAdd;
     case CAIRO_OPERATOR_SATURATE:
 	return PictOpSaturate;
+
+    case CAIRO_OPERATOR_MULTIPLY:
+    case CAIRO_OPERATOR_SCREEN:
+    case CAIRO_OPERATOR_OVERLAY:
+    case CAIRO_OPERATOR_DARKEN:
+    case CAIRO_OPERATOR_LIGHTEN:
+    case CAIRO_OPERATOR_COLOR_DODGE:
+    case CAIRO_OPERATOR_COLOR_BURN:
+    case CAIRO_OPERATOR_HARD_LIGHT:
+    case CAIRO_OPERATOR_SOFT_LIGHT:
+    case CAIRO_OPERATOR_DIFFERENCE:
+    case CAIRO_OPERATOR_EXCLUSION:
+    case CAIRO_OPERATOR_HSL_HUE:
+    case CAIRO_OPERATOR_HSL_SATURATION:
+    case CAIRO_OPERATOR_HSL_COLOR:
+    case CAIRO_OPERATOR_HSL_LUMINOSITY:
+	ASSERT_NOT_REACHED;
+
     default:
 	return PictOpOver;
     }
@@ -1993,7 +2016,10 @@ _cairo_xlib_surface_fill_rectangles (void		     *abstract_surface,
 
     _cairo_xlib_display_notify (surface->display);
 
-    if (! CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLES (surface)) {
+    if (!CAIRO_SURFACE_RENDER_SUPPORTS_OPERATOR (surface, op))
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    if (!CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLES (surface)) {
 	if (op == CAIRO_OPERATOR_CLEAR ||
 	    ((op == CAIRO_OPERATOR_SOURCE || op == CAIRO_OPERATOR_OVER) &&
 	     CAIRO_COLOR_IS_OPAQUE (color)))
commit 0fd944d4bfbc2fff9960378eafd18a7d8fb9f296
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jul 14 15:28:10 2009 +0200

    Use new pixman extended blend operators
    
    It also adds extended-blend tests.
    
    Based on a previous patch by Emmanuel Pacaud <emmanuel.pacaud at free.fr>

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 6bbf80c..d8d57c6 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -936,6 +936,37 @@ _pixman_operator (cairo_operator_t op)
 	return PIXMAN_OP_ADD;
     case CAIRO_OPERATOR_SATURATE:
 	return PIXMAN_OP_SATURATE;
+
+    case CAIRO_OPERATOR_MULTIPLY:
+	return PIXMAN_OP_MULTIPLY;
+    case CAIRO_OPERATOR_SCREEN:
+	return PIXMAN_OP_SCREEN;
+    case CAIRO_OPERATOR_OVERLAY:
+	return PIXMAN_OP_OVERLAY;
+    case CAIRO_OPERATOR_DARKEN:
+	return PIXMAN_OP_DARKEN;
+    case CAIRO_OPERATOR_LIGHTEN:
+ 	return PIXMAN_OP_LIGHTEN;
+    case CAIRO_OPERATOR_COLOR_DODGE:
+ 	return PIXMAN_OP_COLOR_DODGE;
+    case CAIRO_OPERATOR_COLOR_BURN:
+ 	return PIXMAN_OP_COLOR_BURN;
+    case CAIRO_OPERATOR_HARD_LIGHT:
+ 	return PIXMAN_OP_HARD_LIGHT;
+    case CAIRO_OPERATOR_SOFT_LIGHT:
+	return PIXMAN_OP_SOFT_LIGHT;
+    case CAIRO_OPERATOR_DIFFERENCE:
+	return PIXMAN_OP_DIFFERENCE;
+    case CAIRO_OPERATOR_EXCLUSION:
+	return PIXMAN_OP_EXCLUSION;
+    case CAIRO_OPERATOR_HSL_HUE:
+	return PIXMAN_OP_HSL_HUE;
+    case CAIRO_OPERATOR_HSL_SATURATION:
+	return PIXMAN_OP_HSL_SATURATION;
+    case CAIRO_OPERATOR_HSL_COLOR:
+	return PIXMAN_OP_HSL_COLOR;
+    case CAIRO_OPERATOR_HSL_LUMINOSITY:
+	return PIXMAN_OP_HSL_LUMINOSITY;
     default:
 	return PIXMAN_OP_OVER;
     }
diff --git a/src/cairo-misc.c b/src/cairo-misc.c
index 8d9557e..56c7d0b 100644
--- a/src/cairo-misc.c
+++ b/src/cairo-misc.c
@@ -334,6 +334,21 @@ _cairo_operator_bounded_by_mask (cairo_operator_t op)
     case CAIRO_OPERATOR_XOR:
     case CAIRO_OPERATOR_ADD:
     case CAIRO_OPERATOR_SATURATE:
+    case CAIRO_OPERATOR_MULTIPLY:
+    case CAIRO_OPERATOR_SCREEN:
+    case CAIRO_OPERATOR_OVERLAY:
+    case CAIRO_OPERATOR_DARKEN:
+    case CAIRO_OPERATOR_LIGHTEN:
+    case CAIRO_OPERATOR_COLOR_DODGE:
+    case CAIRO_OPERATOR_COLOR_BURN:
+    case CAIRO_OPERATOR_HARD_LIGHT:
+    case CAIRO_OPERATOR_SOFT_LIGHT:
+    case CAIRO_OPERATOR_DIFFERENCE:
+    case CAIRO_OPERATOR_EXCLUSION:
+    case CAIRO_OPERATOR_HSL_HUE:
+    case CAIRO_OPERATOR_HSL_SATURATION:
+    case CAIRO_OPERATOR_HSL_COLOR:
+    case CAIRO_OPERATOR_HSL_LUMINOSITY:
 	return TRUE;
     case CAIRO_OPERATOR_OUT:
     case CAIRO_OPERATOR_IN:
@@ -372,6 +387,21 @@ _cairo_operator_bounded_by_source (cairo_operator_t op)
     case CAIRO_OPERATOR_XOR:
     case CAIRO_OPERATOR_ADD:
     case CAIRO_OPERATOR_SATURATE:
+    case CAIRO_OPERATOR_MULTIPLY:
+    case CAIRO_OPERATOR_SCREEN:
+    case CAIRO_OPERATOR_OVERLAY:
+    case CAIRO_OPERATOR_DARKEN:
+    case CAIRO_OPERATOR_LIGHTEN:
+    case CAIRO_OPERATOR_COLOR_DODGE:
+    case CAIRO_OPERATOR_COLOR_BURN:
+    case CAIRO_OPERATOR_HARD_LIGHT:
+    case CAIRO_OPERATOR_SOFT_LIGHT:
+    case CAIRO_OPERATOR_DIFFERENCE:
+    case CAIRO_OPERATOR_EXCLUSION:
+    case CAIRO_OPERATOR_HSL_HUE:
+    case CAIRO_OPERATOR_HSL_SATURATION:
+    case CAIRO_OPERATOR_HSL_COLOR:
+    case CAIRO_OPERATOR_HSL_LUMINOSITY:
 	return TRUE;
     case CAIRO_OPERATOR_CLEAR:
     case CAIRO_OPERATOR_SOURCE:
diff --git a/src/cairo.h b/src/cairo.h
index 8f7e533..c2f209c 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -422,6 +422,41 @@ cairo_pop_group_to_source (cairo_t *cr);
  * @CAIRO_OPERATOR_ADD: source and destination layers are accumulated
  * @CAIRO_OPERATOR_SATURATE: like over, but assuming source and dest are
  * disjoint geometries
+ * @CAIRO_OPERATOR_MULTIPLY: source and destination layers are multiplied.
+ * This causes the result to be at least as dark as the darker inputs.
+ * @CAIRO_OPERATOR_SCREEN: source and destination are complemented and
+ * multiplied. This causes the result to be at least as light as the lighter
+ * inputs.
+ * @CAIRO_OPERATOR_OVERLAY: multiplies or screens, depending on the 
+ * lightness of the destination color.
+ * @CAIRO_OPERATOR_DARKEN: replaces the destination with the source if it
+ * is darker, otherwise keeps the source.
+ * @CAIRO_OPERATOR_LIGHTEN: replaces the destination with the source if it
+ * is lighter, otherwise keeps the source.
+ * @CAIRO_OPERATOR_COLOR_DODGE: brightens the destination color to reflect 
+ * the source color.
+ * @CAIRO_OPERATOR_COLOR_BURN: darkens the destination color to reflect
+ * the source color.
+ * @CAIRO_OPERATOR_HARD_LIGHT: Multiplies or screens, dependant on source 
+ * color.
+ * @CAIRO_OPERATOR_SOFT_LIGHT: Darkens or lightens, dependant on source 
+ * color.
+ * @CAIRO_OPERATOR_DIFFERENCE: Takes the difference of the source and 
+ * destination color.
+ * @CAIRO_OPERATOR_EXCLUSION: Produces an effect similar to difference, but
+ * with lower contrast.
+ * @CAIRO_OPERATOR_HSL_HUE: Creates a color with the hue of the source 
+ * and the saturation and luminosity of the target.
+ * @CAIRO_OPERATOR_HSL_SATURATION: Creates a color with the saturation
+ * of the source and the hue and luminosity of the target. Painting with 
+ * this mode onto a gray area prduces no change.
+ * @CAIRO_OPERATOR_HSL_COLOR: Creates a color with the hue and saturation 
+ * of the source and the luminosity of the target. This preserves the gray 
+ * levels of the target and is useful for coloring monochrome images or
+ * tinting color images.
+ * @CAIRO_OPERATOR_HSL_LUMINOSITY: Creates a color with the luminosity of 
+ * the source and the hue and saturation of the target. This produces an 
+ * inverse effect to @CAIRO_OPERATOR_HSL_COLOR.
  *
  * #cairo_operator_t is used to set the compositing operator for all cairo
  * drawing operations.
@@ -458,7 +493,23 @@ typedef enum _cairo_operator {
 
     CAIRO_OPERATOR_XOR,
     CAIRO_OPERATOR_ADD,
-    CAIRO_OPERATOR_SATURATE
+    CAIRO_OPERATOR_SATURATE,
+
+    CAIRO_OPERATOR_MULTIPLY,
+    CAIRO_OPERATOR_SCREEN,
+    CAIRO_OPERATOR_OVERLAY,
+    CAIRO_OPERATOR_DARKEN,
+    CAIRO_OPERATOR_LIGHTEN,
+    CAIRO_OPERATOR_COLOR_DODGE,
+    CAIRO_OPERATOR_COLOR_BURN,
+    CAIRO_OPERATOR_HARD_LIGHT,
+    CAIRO_OPERATOR_SOFT_LIGHT,
+    CAIRO_OPERATOR_DIFFERENCE,
+    CAIRO_OPERATOR_EXCLUSION,
+    CAIRO_OPERATOR_HSL_HUE,
+    CAIRO_OPERATOR_HSL_SATURATION,
+    CAIRO_OPERATOR_HSL_COLOR,
+    CAIRO_OPERATOR_HSL_LUMINOSITY
 } cairo_operator_t;
 
 cairo_public void
diff --git a/test/Makefile.am b/test/Makefile.am
index 81add8c..68b9325 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -308,6 +308,10 @@ REFERENCE_IMAGES = \
 	device-offset.ref.png \
 	device-offset.rgb24.ref.png \
 	device-offset-scale.ref.png \
+	extended-blend.argb32.ref.png \
+	extended-blend.rgb24.ref.png \
+	extended-blend-alpha.argb32.ref.png \
+	extended-blend-alpha.rgb24.ref.png \
 	extend-pad-border.ref.png \
 	extend-pad.ref.png \
 	extend-pad.ps.ref.png \
diff --git a/test/Makefile.sources b/test/Makefile.sources
index e37b3e8..7409820 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -55,6 +55,8 @@ test_sources = \
 	extend-reflect-similar.c			\
 	extend-repeat.c					\
 	extend-repeat-similar.c				\
+	extended-blend.c				\
+	extended-blend-alpha.c				\
 	fill-alpha.c					\
 	fill-alpha-pattern.c				\
 	fill-and-stroke.c				\
diff --git a/test/extended-blend-alpha.argb32.ref.png b/test/extended-blend-alpha.argb32.ref.png
new file mode 100644
index 0000000..3ecd618
Binary files /dev/null and b/test/extended-blend-alpha.argb32.ref.png differ
diff --git a/test/extended-blend-alpha.c b/test/extended-blend-alpha.c
new file mode 100644
index 0000000..e0316f3
--- /dev/null
+++ b/test/extended-blend-alpha.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ * Copyright © 2007 Emmanuel Pacaud
+ * Copyright © 2008 Benjamin Otte
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Owen Taylor <otaylor at redhat.com>
+ *          Kristian Høgsberg <krh at redhat.com>
+ *          Emmanuel Pacaud <emmanuel.pacaud at lapp.in2p3.fr>
+ */
+
+#include <math.h>
+#include "cairo-test.h"
+#include <stdio.h>
+
+#define STEPS 16
+#define START_OPERATOR	CAIRO_OPERATOR_MULTIPLY
+#define STOP_OPERATOR	CAIRO_OPERATOR_HSL_LUMINOSITY
+
+static void
+create_patterns (cairo_t *bg, cairo_t *fg)
+{
+    int x;
+
+    for (x = 0; x < STEPS; x++) {
+	/* draw a yellow background fading in using discrete steps */
+	cairo_set_source_rgba (bg, 1, 1, 0, (double) x / (STEPS - 1));
+	cairo_rectangle (bg, x, 0, 1, STEPS);
+	cairo_fill (bg);
+
+	/* draw an orthogonal teal pattern fading in using discrete steps */
+	cairo_set_source_rgba (fg, 0, 1, 1, (double) x / (STEPS - 1));
+	cairo_rectangle (fg, 0, x, STEPS, 1);
+	cairo_fill (fg);
+    }
+}
+
+/* expects a STEP*STEP pixel rectangle */
+static void
+do_blend (cairo_t *cr, cairo_operator_t op, cairo_surface_t *bg, cairo_surface_t *fg)
+{
+    /* not using CAIRO_OPERATOR_SOURCE here, it triggers a librsvg bug */
+    cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+    cairo_set_source_surface (cr, bg, 0, 0);
+    cairo_paint (cr);
+
+    cairo_set_operator (cr, op);
+    cairo_set_source_surface (cr, fg, 0, 0);
+    cairo_paint (cr);
+}
+
+#define SIZE 5
+#define COUNT 4
+#define FULL_WIDTH  ((STEPS + 1) * COUNT - 1)
+#define FULL_HEIGHT ((COUNT + STOP_OPERATOR - START_OPERATOR) / COUNT) * (STEPS + 1)
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    size_t i = 0;
+    cairo_operator_t op;
+    cairo_t *bgcr, *fgcr;
+    cairo_surface_t *bg, *fg;
+
+    bg = cairo_surface_create_similar (cairo_get_target (cr), 
+	    CAIRO_CONTENT_COLOR_ALPHA, SIZE * STEPS, SIZE * STEPS);
+    fg = cairo_surface_create_similar (cairo_get_target (cr), 
+	    CAIRO_CONTENT_COLOR_ALPHA, SIZE * STEPS, SIZE * STEPS);
+    bgcr = cairo_create (bg);
+    fgcr = cairo_create (fg);
+    cairo_scale (bgcr, SIZE, SIZE);
+    cairo_scale (fgcr, SIZE, SIZE);
+    create_patterns (bgcr, fgcr);
+    cairo_destroy (bgcr);
+    cairo_destroy (fgcr);
+
+    for (op = START_OPERATOR; op <= STOP_OPERATOR; op++, i++) {
+	cairo_save (cr);
+	cairo_translate (cr, 
+		SIZE * (STEPS + 1) * (i % COUNT),
+		SIZE * (STEPS + 1) * (i / COUNT));
+	do_blend (cr, op, bg, fg);
+	cairo_restore (cr);
+    }
+
+    cairo_surface_destroy (fg);
+    cairo_surface_destroy (bg);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (extended_blend_alpha,
+	    "Tests extended blend modes with alpha",
+	    "operator", /* keywords */
+	    NULL, /* requirements */
+	    FULL_WIDTH * SIZE, FULL_HEIGHT * SIZE,
+	    NULL, draw)
diff --git a/test/extended-blend-alpha.rgb24.ref.png b/test/extended-blend-alpha.rgb24.ref.png
new file mode 100644
index 0000000..f62dda9
Binary files /dev/null and b/test/extended-blend-alpha.rgb24.ref.png differ
diff --git a/test/extended-blend.argb32.ref.png b/test/extended-blend.argb32.ref.png
new file mode 100644
index 0000000..083fe87
Binary files /dev/null and b/test/extended-blend.argb32.ref.png differ
diff --git a/test/extended-blend.c b/test/extended-blend.c
new file mode 100644
index 0000000..cd2b06b
--- /dev/null
+++ b/test/extended-blend.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2005 Red Hat, Inc.
+ * Copyright © 2007 Emmanuel Pacaud
+ * Copyright © 2008 Benjamin Otte
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Owen Taylor <otaylor at redhat.com>
+ *          Kristian Høgsberg <krh at redhat.com>
+ *          Emmanuel Pacaud <emmanuel.pacaud at lapp.in2p3.fr>
+ */
+
+#include <math.h>
+#include "cairo-test.h"
+#include <stdio.h>
+
+#define STEPS 16
+#define START_OPERATOR	CAIRO_OPERATOR_MULTIPLY
+#define STOP_OPERATOR	CAIRO_OPERATOR_HSL_LUMINOSITY
+
+static void
+create_patterns (cairo_t *bg, cairo_t *fg)
+{
+    int x;
+
+    for (x = 0; x < STEPS; x++) {
+	double i = (double) x / (STEPS - 1);
+	/* draw a yellow background fading in using discrete steps */
+	cairo_set_source_rgba (bg, i, i, 0, 1);
+	cairo_rectangle (bg, x, 0, 1, STEPS);
+	cairo_fill (bg);
+
+	/* draw an orthogonal teal pattern fading in using discrete steps */
+	cairo_set_source_rgba (fg, 0, i, i, 1);
+	cairo_rectangle (fg, 0, x, STEPS, 1);
+	cairo_fill (fg);
+    }
+}
+
+/* expects a STEP*STEP pixel rectangle */
+static void
+do_blend (cairo_t *cr, cairo_operator_t op, cairo_surface_t *bg, cairo_surface_t *fg)
+{
+    /* not using CAIRO_OPERATOR_SOURCE here, it triggers a librsvg bug */
+    cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+    cairo_set_source_surface (cr, bg, 0, 0);
+    cairo_paint (cr);
+
+    cairo_set_operator (cr, op);
+    cairo_set_source_surface (cr, fg, 0, 0);
+    cairo_paint (cr);
+}
+
+#define SIZE 5
+#define COUNT 4
+#define FULL_WIDTH  ((STEPS + 1) * COUNT - 1)
+#define FULL_HEIGHT ((COUNT + STOP_OPERATOR - START_OPERATOR) / COUNT) * (STEPS + 1)
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    size_t i = 0;
+    cairo_operator_t op;
+    cairo_t *bgcr, *fgcr;
+    cairo_surface_t *bg, *fg;
+
+    bg = cairo_surface_create_similar (cairo_get_target (cr), 
+	    CAIRO_CONTENT_COLOR_ALPHA, SIZE * STEPS, SIZE * STEPS);
+    fg = cairo_surface_create_similar (cairo_get_target (cr), 
+	    CAIRO_CONTENT_COLOR_ALPHA, SIZE * STEPS, SIZE * STEPS);
+    bgcr = cairo_create (bg);
+    fgcr = cairo_create (fg);
+    cairo_scale (bgcr, SIZE, SIZE);
+    cairo_scale (fgcr, SIZE, SIZE);
+    create_patterns (bgcr, fgcr);
+    cairo_destroy (bgcr);
+    cairo_destroy (fgcr);
+
+    for (op = START_OPERATOR; op <= STOP_OPERATOR; op++, i++) {
+	cairo_save (cr);
+	cairo_translate (cr, 
+		SIZE * (STEPS + 1) * (i % COUNT),
+		SIZE * (STEPS + 1) * (i / COUNT));
+	do_blend (cr, op, bg, fg);
+	cairo_restore (cr);
+    }
+
+    cairo_surface_destroy (fg);
+    cairo_surface_destroy (bg);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (extended_blend,
+	    "Tests extended blend modes without alpha",
+	    "operator", /* keywords */
+	    NULL, /* requirements */
+	    FULL_WIDTH * SIZE, FULL_HEIGHT * SIZE,
+	    NULL, draw)
+
diff --git a/test/extended-blend.rgb24.ref.png b/test/extended-blend.rgb24.ref.png
new file mode 100644
index 0000000..53c1b22
Binary files /dev/null and b/test/extended-blend.rgb24.ref.png differ
commit 16387f0a7dd3b474bcaf637d3e290029b79afec1
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date:   Tue Jul 14 11:16:24 2009 +0200

    [configure] Bump pixman dependency
    
    Version 0.15.16 contains the new PDF blend mode operators.

diff --git a/configure.ac b/configure.ac
index 4f8f1b2..de1be8f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -462,7 +462,7 @@ CAIRO_ENABLE(test_surfaces, test surfaces, no)
 dnl ===========================================================================
 
 CAIRO_ENABLE_SURFACE_BACKEND(image, image, always, [
-  pixman_REQUIRES="pixman-1 >= 0.15.0"
+  pixman_REQUIRES="pixman-1 >= 0.15.16"
   PKG_CHECK_MODULES(pixman, $pixman_REQUIRES, , [AC_MSG_RESULT(no)
   use_image="no (requires $pixman_REQUIRES http://cairographics.org/releases/)"])
   image_REQUIRES=$pixman_REQUIRES


More information about the cairo-commit mailing list