[lasem] svg: add beginning of feBlend support. Fix feFlood.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [lasem] svg: add beginning of feBlend support. Fix feFlood.
- Date: Sun, 14 Oct 2012 15:05:04 +0000 (UTC)
commit 31be1ce5e8f9cf3faa4005df76e205558ea44c5c
Author: Emmanuel Pacaud <emmanuel gnome org>
Date: Sun Oct 14 17:04:27 2012 +0200
svg: add beginning of feBlend support. Fix feFlood.
docs/reference/lasem/Makefile.am | 1 +
src/Makefile.am | 2 +
src/lsmcairo.c | 78 +++++++++++++++++++---------
src/lsmcairo.h | 7 ++-
src/lsmsvgattributes.h | 5 ++
src/lsmsvgdocument.c | 9 ++-
src/lsmsvgenums.c | 24 +++++++++
src/lsmsvgenums.h | 13 +++++
src/lsmsvgfilterblend.c | 106 ++++++++++++++++++++++++++++++++++++++
src/lsmsvgfilterblend.h | 58 +++++++++++++++++++++
src/lsmsvgtraits.c | 24 +++++++++
src/lsmsvgtraits.h | 1 +
src/lsmsvgtypes.h | 3 +-
src/lsmsvgview.c | 91 ++++++++++++++++++--------------
src/lsmsvgview.h | 2 +
15 files changed, 355 insertions(+), 69 deletions(-)
---
diff --git a/docs/reference/lasem/Makefile.am b/docs/reference/lasem/Makefile.am
index cb8b57a..d505435 100644
--- a/docs/reference/lasem/Makefile.am
+++ b/docs/reference/lasem/Makefile.am
@@ -147,6 +147,7 @@ IGNORE_HFILES=\
lsmsvgmaskelement.h \
lsmsvgfilterelement.h \
lsmsvgfilterprimitive.h \
+ lsmsvgfilterblend.h \
lsmsvgfilterflood.h \
lsmsvgfiltergaussianblur.h
diff --git a/src/Makefile.am b/src/Makefile.am
index cfb9577..cd1b0d8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -126,6 +126,7 @@ LASEM_SVG_SRCS = \
lsmsvgmaskelement.c \
lsmsvgfilterelement.c \
lsmsvgfilterprimitive.c \
+ lsmsvgfilterblend.c \
lsmsvgfilterflood.c \
lsmsvgfiltergaussianblur.c
@@ -232,6 +233,7 @@ LASEM_SVG_HDRS = \
lsmsvgmaskelement.h \
lsmsvgfilterelement.h \
lsmsvgfilterprimitive.h \
+ lsmsvgfilterblend.h \
lsmsvgfilterflood.h \
lsmsvgfiltergaussianblur.h
diff --git a/src/lsmcairo.c b/src/lsmcairo.c
index 34e1007..4b31cd1 100644
--- a/src/lsmcairo.c
+++ b/src/lsmcairo.c
@@ -1,7 +1,7 @@
/* Lasem
*
* Copyright  2004 Caleb Moore
- * Copyright  2010 Emmanuel Pacaud
+ * Copyright  2012 Emmanuel Pacaud
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -24,6 +24,7 @@
*/
#include <lsmcairo.h>
+#include <lsmsvgenums.h>
#include <math.h>
#include <string.h>
@@ -84,26 +85,6 @@ lsm_filter_surface_new_similar (const char *name, LsmFilterSurface *model)
return lsm_filter_surface_new (name, model->x0, model->y0, model->x1, model->y1);
}
-void
-lsm_filter_surface_copy_data (LsmFilterSurface *to, LsmFilterSurface *from)
-{
- size_t to_size;
- size_t from_size;
- void *to_data;
- void *from_data;
-
- g_return_if_fail (to != NULL);
- g_return_if_fail (from != NULL);
-
- to_size = cairo_image_surface_get_height (to->surface) * cairo_image_surface_get_stride (to->surface);
- from_size = cairo_image_surface_get_height (from->surface) * cairo_image_surface_get_stride (from->surface);
- to_data = cairo_image_surface_get_data (to->surface);
- from_data = cairo_image_surface_get_data (from->surface);
-
- if (to_size == from_size)
- memcpy (to_data, from_data, to_size);
-}
-
const char *
lsm_filter_surface_get_name (LsmFilterSurface *surface)
{
@@ -285,6 +266,8 @@ lsm_filter_surface_fast_blur (LsmFilterSurface *input,
box_blur (output, output, intermediate, kx, ky);
g_free (intermediate);
+
+ cairo_surface_mark_dirty (output->surface);
}
void
@@ -295,6 +278,7 @@ lsm_filter_surface_flood (LsmFilterSurface *surface, guint32 color, double opaci
int i, x, y;
int stride;
unsigned char *pixels;
+ int channelmap[4] = {0, 1, 2, 3};
g_return_if_fail (surface != NULL);
@@ -306,12 +290,58 @@ lsm_filter_surface_flood (LsmFilterSurface *surface, guint32 color, double opaci
for (i = 0; i < 3; i++)
pixcolour[i] = (int) (((unsigned char *)
(&color))[2 - i]) * int_opacity / 255;
- pixcolour[3] = opacity;
+ pixcolour[3] = int_opacity;
for (y = surface->y0; y < surface->y1; y++)
for (x = surface->x0; x < surface->x1; x++)
- for (i = 0; i < 4; i++)
- pixels[4 * x + y * stride + /*ctx->channelmap[i]*/ i] = pixcolour[i];
+ for (i = 0; i < 4; i++) {
+ pixels[4 * x + y * stride + channelmap[i]] = pixcolour[i];
+ }
+
+ cairo_surface_mark_dirty (surface->surface);
+}
+
+void
+lsm_filter_surface_blend (LsmFilterSurface *input_1,
+ LsmFilterSurface *input_2,
+ LsmFilterSurface *output,
+ int blending_mode)
+{
+ cairo_t *cairo;
+ cairo_operator_t op;
+
+ g_return_if_fail (input_1 != NULL);
+ g_return_if_fail (input_2 != NULL);
+ g_return_if_fail (output != NULL);
+
+ switch (blending_mode) {
+ case LSM_SVG_BLENDING_MODE_MULTIPLY:
+ op = CAIRO_OPERATOR_MULTIPLY;
+ break;
+ case LSM_SVG_BLENDING_MODE_SCREEN:
+ op = CAIRO_OPERATOR_SCREEN;
+ break;
+ case LSM_SVG_BLENDING_MODE_DARKEN:
+ op = CAIRO_OPERATOR_DARKEN;
+ break;
+ case LSM_SVG_BLENDING_MODE_LIGHTEN:
+ op = CAIRO_OPERATOR_LIGHTEN;
+ break;
+ default:
+ op = CAIRO_OPERATOR_OVER;
+ break;
+ }
+
+ cairo = cairo_create (output->surface);
+
+ cairo_set_source_surface (cairo, input_1->surface, 0, 0);
+ cairo_paint (cairo);
+
+ cairo_set_source_surface (cairo, input_2->surface, 0, 0);
+ cairo_set_operator (cairo, op);
+ cairo_paint (cairo);
+
+ cairo_destroy (cairo);
}
/**
diff --git a/src/lsmcairo.h b/src/lsmcairo.h
index d71b176..102081f 100644
--- a/src/lsmcairo.h
+++ b/src/lsmcairo.h
@@ -1,6 +1,6 @@
/* Lasem
*
- * Copyright  2010 Emmanuel Pacaud
+ * Copyright  2012 Emmanuel Pacaud
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,6 +25,7 @@
#define LSM_CAIRO_H
#include <lsmtypes.h>
+#include <lsmsvgenums.h>
#include <cairo.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
@@ -49,6 +50,10 @@ cairo_surface_t * lsm_filter_surface_get_cairo_surface (LsmFilterSurface *surfac
void lsm_filter_surface_unref (LsmFilterSurface *filter_surface);
LsmFilterSurface * lsm_filter_surface_ref (LsmFilterSurface *filter_surface);
+void lsm_filter_surface_blend (LsmFilterSurface *input_1,
+ LsmFilterSurface *input_2,
+ LsmFilterSurface *output,
+ int blending_mode);
void lsm_filter_surface_fast_blur (LsmFilterSurface *input,
LsmFilterSurface *output,
double sx, double sy);
diff --git a/src/lsmsvgattributes.h b/src/lsmsvgattributes.h
index 1d50919..3e5c8e4 100644
--- a/src/lsmsvgattributes.h
+++ b/src/lsmsvgattributes.h
@@ -35,6 +35,11 @@ G_BEGIN_DECLS
typedef struct {
LsmAttribute base;
+ LsmSvgBlendingMode value;
+} LsmSvgBlendingModeAttribute;
+
+typedef struct {
+ LsmAttribute base;
double value;
} LsmSvgDoubleAttribute;
diff --git a/src/lsmsvgdocument.c b/src/lsmsvgdocument.c
index ed1e745..7fc90b6 100644
--- a/src/lsmsvgdocument.c
+++ b/src/lsmsvgdocument.c
@@ -46,8 +46,9 @@
#include <lsmsvgpatternelement.h>
#include <lsmsvgmaskelement.h>
#include <lsmsvgfilterelement.h>
-#include <lsmsvgfiltergaussianblur.h>
+#include <lsmsvgfilterblend.h>
#include <lsmsvgfilterflood.h>
+#include <lsmsvgfiltergaussianblur.h>
#include <lsmsvgview.h>
#include <string.h>
@@ -135,10 +136,12 @@ _create_element (LsmDomDocument *document, const char *tag_name)
node = lsm_svg_clip_path_element_new ();
else if (strcmp (tag_name, "filter") == 0)
node = lsm_svg_filter_element_new ();
- else if (strcmp (tag_name, "feGaussianBlur") == 0)
- node = lsm_svg_filter_gaussian_blur_new ();
+ else if (strcmp (tag_name, "feBlend") == 0)
+ node = lsm_svg_filter_blend_new ();
else if (strcmp (tag_name, "feFlood") == 0)
node = lsm_svg_filter_flood_new ();
+ else if (strcmp (tag_name, "feGaussianBlur") == 0)
+ node = lsm_svg_filter_gaussian_blur_new ();
if (node != NULL)
lsm_debug_dom ("[LsmSvgDocument::create_element] Create a %s element", tag_name);
diff --git a/src/lsmsvgenums.c b/src/lsmsvgenums.c
index 8a31c3d..95c8b69 100644
--- a/src/lsmsvgenums.c
+++ b/src/lsmsvgenums.c
@@ -25,6 +25,30 @@
#include <lsmtraits.h>
#include <string.h>
+static const char *lsm_svg_blending_mode_strings[] = {
+ "normal",
+ "multiply",
+ "screen",
+ "darken",
+ "lighten"
+};
+
+const char *
+lsm_svg_blending_mode_to_string (LsmSvgBlendingMode blending_mode)
+{
+ if (blending_mode < 0 || blending_mode > LSM_SVG_BLENDING_MODE_LIGHTEN)
+ return NULL;
+
+ return lsm_svg_blending_mode_strings[blending_mode];
+}
+
+LsmSvgBlendingMode
+lsm_svg_blending_mode_from_string (const char *string)
+{
+ return lsm_enum_value_from_string (string, lsm_svg_blending_mode_strings,
+ G_N_ELEMENTS (lsm_svg_blending_mode_strings));
+}
+
static const char *lsm_svg_length_type_strings[] = {
"",
"%",
diff --git a/src/lsmsvgenums.h b/src/lsmsvgenums.h
index 942cbed..003c0e5 100644
--- a/src/lsmsvgenums.h
+++ b/src/lsmsvgenums.h
@@ -25,6 +25,7 @@
#define LSM_SVG_ENUMS_H
#include <glib-object.h>
+#include <lsmtypes.h>
G_BEGIN_DECLS
@@ -35,6 +36,18 @@ typedef enum {
} LsmSvgAngleType;
typedef enum {
+ LSM_SVG_BLENDING_MODE_ERROR = -1,
+ LSM_SVG_BLENDING_MODE_NORMAL,
+ LSM_SVG_BLENDING_MODE_MULTIPLY,
+ LSM_SVG_BLENDING_MODE_SCREEN,
+ LSM_SVG_BLENDING_MODE_DARKEN,
+ LSM_SVG_BLENDING_MODE_LIGHTEN
+} LsmSvgBlendingMode;
+
+const char * lsm_svg_blending_mode_to_string (LsmSvgBlendingMode blending_mode);
+LsmSvgBlendingMode lsm_svg_blending_mode_from_string (const char *string);
+
+typedef enum {
LSM_SVG_PAINT_TYPE_ERROR = -1,
LSM_SVG_PAINT_TYPE_UNKNOWN = 0,
LSM_SVG_PAINT_TYPE_RGB_COLOR,
diff --git a/src/lsmsvgfilterblend.c b/src/lsmsvgfilterblend.c
new file mode 100644
index 0000000..a72257e
--- /dev/null
+++ b/src/lsmsvgfilterblend.c
@@ -0,0 +1,106 @@
+/* Lasem
+ *
+ * Copyright  2012 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#include <lsmsvgfilterblend.h>
+#include <lsmsvgview.h>
+
+static GObjectClass *parent_class;
+
+/* GdomNode implementation */
+
+static const char *
+lsm_svg_filter_blend_get_node_name (LsmDomNode *node)
+{
+ return "feBlend";
+}
+
+/* LsmSvgElement implementation */
+
+static void
+lsm_svg_filter_blend_apply (LsmSvgFilterPrimitive *self, LsmSvgView *view,
+ const char *input, const char *output,
+ double x, double y, double w, double h)
+{
+ LsmSvgFilterBlend *blend = LSM_SVG_FILTER_BLEND (self);
+
+ lsm_svg_view_apply_blend (view, input, blend->in2.value, output, blend->mode.value);
+}
+
+/* LsmSvgFilterBlend implementation */
+
+LsmDomNode *
+lsm_svg_filter_blend_new (void)
+{
+ return g_object_new (LSM_TYPE_SVG_FILTER_BLEND, NULL);
+}
+
+static void
+lsm_svg_filter_blend_init (LsmSvgFilterBlend *self)
+{
+}
+
+static void
+lsm_svg_filter_blend_finalize (GObject *object)
+{
+ parent_class->finalize (object);
+}
+
+/* LsmSvgFilterBlend class */
+
+static const LsmAttributeInfos lsm_svg_filter_blend_attribute_infos[] = {
+ {
+ .name = "in2",
+ .attribute_offset = offsetof (LsmSvgFilterBlend, in2),
+ .trait_class = &lsm_null_trait_class
+ },
+ {
+ .name = "mode",
+ .attribute_offset = offsetof (LsmSvgFilterBlend, mode),
+ .trait_class = &lsm_svg_blending_mode_trait_class
+ }
+};
+
+static void
+lsm_svg_filter_blend_class_init (LsmSvgFilterBlendClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (klass);
+ LsmSvgElementClass *s_element_class = LSM_SVG_ELEMENT_CLASS (klass);
+ LsmSvgFilterPrimitiveClass *f_primitive_class = LSM_SVG_FILTER_PRIMITIVE_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->finalize = lsm_svg_filter_blend_finalize;
+
+ d_node_class->get_node_name = lsm_svg_filter_blend_get_node_name;
+
+ s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
+
+ lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
+ G_N_ELEMENTS (lsm_svg_filter_blend_attribute_infos),
+ lsm_svg_filter_blend_attribute_infos);
+
+ f_primitive_class->apply = lsm_svg_filter_blend_apply;
+}
+
+G_DEFINE_TYPE (LsmSvgFilterBlend, lsm_svg_filter_blend, LSM_TYPE_SVG_FILTER_PRIMITIVE)
diff --git a/src/lsmsvgfilterblend.h b/src/lsmsvgfilterblend.h
new file mode 100644
index 0000000..69e05ed
--- /dev/null
+++ b/src/lsmsvgfilterblend.h
@@ -0,0 +1,58 @@
+/* Lasem
+ *
+ * Copyright  2012 Emmanuel Pacaud
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#ifndef LSM_SVG_FILTER_BLEND_H
+#define LSM_SVG_FILTER_BLEND_H
+
+#include <lsmsvgtypes.h>
+#include <lsmsvgfilterprimitive.h>
+
+G_BEGIN_DECLS
+
+#define LSM_TYPE_SVG_FILTER_BLEND (lsm_svg_filter_blend_get_type ())
+#define LSM_SVG_FILTER_BLEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_SVG_FILTER_BLEND, LsmSvgFilterBlend))
+#define LSM_SVG_FILTER_BLEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_SVG_FILTER_BLEND, LsmSvgFilterBlendClass))
+#define LSM_IS_SVG_FILTER_BLEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_SVG_FILTER_BLEND))
+#define LSM_IS_SVG_FILTER_BLEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_SVG_FILTER_BLEND))
+#define LSM_SVG_FILTER_BLEND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_SVG_FILTER_BLEND, LsmSvgFilterBlendClass))
+
+typedef struct _LsmSvgFilterBlendClass LsmSvgFilterBlendClass;
+
+struct _LsmSvgFilterBlend {
+ LsmSvgFilterPrimitive base;
+
+ LsmAttribute in2;
+ LsmSvgBlendingModeAttribute mode;
+};
+
+struct _LsmSvgFilterBlendClass {
+ LsmSvgFilterPrimitiveClass element_class;
+};
+
+GType lsm_svg_filter_blend_get_type (void);
+
+LsmDomNode * lsm_svg_filter_blend_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmsvgtraits.c b/src/lsmsvgtraits.c
index 5b4299b..d79a57c 100644
--- a/src/lsmsvgtraits.c
+++ b/src/lsmsvgtraits.c
@@ -32,6 +32,30 @@ const LsmSvgColor lsm_svg_color_null = {0.0, 0.0, 0.0};
const LsmSvgDashArray lsm_svg_dash_array_null = {0, NULL};
static gboolean
+lsm_svg_blending_mode_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+ LsmSvgBlendingMode *trait = (LsmSvgBlendingMode *) abstract_trait;
+
+ *trait = lsm_svg_blending_mode_from_string (string);
+
+ return *trait >= 0;
+}
+
+char *
+lsm_svg_blending_mode_trait_to_string (LsmTrait *abstract_trait)
+{
+ LsmSvgBlendingMode *trait = (LsmSvgBlendingMode *) abstract_trait;
+
+ return g_strdup (lsm_svg_blending_mode_to_string (*trait));
+}
+
+const LsmTraitClass lsm_svg_blending_mode_trait_class = {
+ .size = sizeof (LsmSvgBlendingMode),
+ .from_string = lsm_svg_blending_mode_trait_from_string,
+ .to_string = lsm_svg_blending_mode_trait_to_string
+};
+
+static gboolean
lsm_svg_length_trait_from_string (LsmTrait *abstract_trait, char *string)
{
LsmSvgLength *svg_length = (LsmSvgLength *) abstract_trait;
diff --git a/src/lsmsvgtraits.h b/src/lsmsvgtraits.h
index 716da41..8cd0a91 100644
--- a/src/lsmsvgtraits.h
+++ b/src/lsmsvgtraits.h
@@ -73,6 +73,7 @@ typedef struct {
} LsmSvgOneOrTwoDouble;
extern const LsmTraitClass lsm_svg_angle_trait_class;
+extern const LsmTraitClass lsm_svg_blending_mode_trait_class;
extern const LsmTraitClass lsm_svg_color_trait_class;
extern const LsmTraitClass lsm_svg_dash_array_trait_class;
extern const LsmTraitClass lsm_svg_display_trait_class;
diff --git a/src/lsmsvgtypes.h b/src/lsmsvgtypes.h
index aeefcf0..fa8b0b1 100644
--- a/src/lsmsvgtypes.h
+++ b/src/lsmsvgtypes.h
@@ -57,8 +57,9 @@ typedef struct _LsmSvgPatternElement LsmSvgPatternElement;
typedef struct _LsmSvgMaskElement LsmSvgMaskElement;
typedef struct _LsmSvgFilterElement LsmSvgFilterElement;
typedef struct _LsmSvgFilterPrimitive LsmSvgFilterPrimitive;
-typedef struct _LsmSvgFilterGaussianBlur LsmSvgFilterGaussianBlur;
+typedef struct _LsmSvgFilterBlend LsmSvgFilterBlend;
typedef struct _LsmSvgFilterFlood LsmSvgFilterFlood;
+typedef struct _LsmSvgFilterGaussianBlur LsmSvgFilterGaussianBlur;
typedef struct _LsmSvgView LsmSvgView;
typedef struct _LsmSvgStyle LsmSvgStyle;
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index e01836f..da2fba5 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -2007,29 +2007,15 @@ lsm_svg_view_pop_filter (LsmSvgView *view)
}
if (view->filter_surfaces->next != NULL) {
-#if 1
- lsm_filter_surface_copy_data (filter_surface, view->filter_surfaces->data);
+ cairo_pattern_t *pattern;
+ cairo_surface_t *surface;
- cairo_pattern_set_extend (view->pattern_data->pattern, CAIRO_EXTEND_NONE);
- cairo_set_source (view->pattern_data->old_cairo, view->pattern_data->pattern);
- cairo_paint_with_alpha (view->pattern_data->old_cairo, view->pattern_data->opacity);
-#else
- /* This is the code that should be used. But unfortunately it doesn't work.
- * For some reason, cairo_paint paints nothing. I fail to see why it doesn't, while
- * the above code does. */
- {
- cairo_pattern_t *pattern;
- cairo_surface_t *surface;
-
- surface = lsm_filter_surface_get_cairo_surface (view->filter_surfaces->data);
- pattern = cairo_pattern_create_for_surface (surface);
- cairo_pattern_set_extend (pattern, CAIRO_EXTEND_NONE);
- cairo_pattern_set_matrix (pattern, &matrix);
- cairo_pattern_set_filter (pattern, CAIRO_FILTER_NEAREST);
- cairo_set_source (view->pattern_data->old_cairo, pattern);
- cairo_paint_with_alpha (view->pattern_data->old_cairo, view->pattern_data->opacity);
- }
-#endif
+ surface = lsm_filter_surface_get_cairo_surface (view->filter_surfaces->data);
+ pattern = cairo_pattern_create_for_surface (surface);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_NONE);
+ cairo_pattern_set_matrix (pattern, &matrix);
+ cairo_set_source (view->pattern_data->old_cairo, pattern);
+ cairo_paint (view->pattern_data->old_cairo);
}
for (iter = view->filter_surfaces; iter != NULL; iter = iter->next)
@@ -2072,35 +2058,28 @@ _create_filter_surface (LsmSvgView *view, const char *output, LsmFilterSurface *
}
void
-lsm_svg_view_apply_gaussian_blur (LsmSvgView *view, const char *input, const char *output,
- double x, double y, double w, double h,
- double std_x, double std_y)
+lsm_svg_view_apply_blend (LsmSvgView *view, const char *input_1, const char*input_2, const char *output,
+ LsmSvgBlendingMode mode)
{
- LsmFilterSurface *input_surface;
LsmFilterSurface *output_surface;
+ LsmFilterSurface *input_1_surface;
+ LsmFilterSurface *input_2_surface;
g_return_if_fail (LSM_IS_SVG_VIEW (view));
- input_surface = _get_filter_surface (view, input);
+ input_1_surface = _get_filter_surface (view, input_1);
+ input_2_surface = _get_filter_surface (view, input_2);
- if (input_surface == NULL) {
- lsm_debug_render ("[SvgView::apply_gaussian_blur] Input '%s' not found", input);
+ if (input_1_surface == NULL || input_2_surface == NULL) {
+ lsm_debug_render ("[SvgView::apply_blend] Inputs '%s' or '%s' not found", input_1, input_2);
return;
}
- output_surface = _create_filter_surface (view, output, input_surface);
+ output_surface = _create_filter_surface (view, output, input_1_surface);
- lsm_log_render ("[SvgView::apply_gaussian_blur] %s -> %s (x:%g,y:%g,w:%g,h:%g) (%g,%g)",
- input != NULL ? input : "previous",
- output != NULL ? output : "next",
- x, y, w, h, std_x, std_y);
-
- cairo_user_to_device_distance (view->dom_view.cairo, &std_x, &std_y);
+ lsm_log_render ("[SvgView::blend] mode = %s", lsm_svg_blending_mode_to_string (mode));
- lsm_log_render ("[SvgView::apply_gaussian_blur] %g px,%g px",
- std_x, std_y);
-
- lsm_filter_surface_fast_blur (input_surface, output_surface, std_x, std_y);
+ lsm_filter_surface_blend (input_1_surface, input_2_surface, output_surface, mode);
}
void
@@ -2132,6 +2111,38 @@ lsm_svg_view_apply_flood (LsmSvgView *view, const char *output,
}
void
+lsm_svg_view_apply_gaussian_blur (LsmSvgView *view, const char *input, const char *output,
+ double x, double y, double w, double h,
+ double std_x, double std_y)
+{
+ LsmFilterSurface *input_surface;
+ LsmFilterSurface *output_surface;
+
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+
+ input_surface = _get_filter_surface (view, input);
+
+ if (input_surface == NULL) {
+ lsm_debug_render ("[SvgView::apply_gaussian_blur] Input '%s' not found", input);
+ return;
+ }
+
+ output_surface = _create_filter_surface (view, output, input_surface);
+
+ lsm_log_render ("[SvgView::apply_gaussian_blur] %s -> %s (x:%g,y:%g,w:%g,h:%g) (%g,%g)",
+ input != NULL ? input : "previous",
+ output != NULL ? output : "next",
+ x, y, w, h, std_x, std_y);
+
+ cairo_user_to_device_distance (view->dom_view.cairo, &std_x, &std_y);
+
+ lsm_log_render ("[SvgView::apply_gaussian_blur] %g px,%g px",
+ std_x, std_y);
+
+ lsm_filter_surface_fast_blur (input_surface, output_surface, std_x, std_y);
+}
+
+void
lsm_svg_view_push_element (LsmSvgView *view, const LsmSvgElement *element)
{
g_return_if_fail (LSM_IS_SVG_VIEW (view));
diff --git a/src/lsmsvgview.h b/src/lsmsvgview.h
index cde1146..002ef54 100644
--- a/src/lsmsvgview.h
+++ b/src/lsmsvgview.h
@@ -154,6 +154,8 @@ void lsm_svg_view_pop_style (LsmSvgView *view);
LsmSvgStyle * lsm_svg_view_get_current_style (LsmSvgView *view);
+void lsm_svg_view_apply_blend (LsmSvgView *view, const char *input_1, const char*input_2, const char *output,
+ LsmSvgBlendingMode mode);
void lsm_svg_view_apply_flood (LsmSvgView *view, const char *output,
double x, double y, double w, double h);
void lsm_svg_view_apply_gaussian_blur (LsmSvgView *view, const char *input, const char *output,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]