[lasem] svg: add feFlood support (not working yet).
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [lasem] svg: add feFlood support (not working yet).
- Date: Sun, 14 Oct 2012 10:20:07 +0000 (UTC)
commit dba92601694710de3591ecd1eb98e24f2a7384b6
Author: Emmanuel Pacaud <emmanuel gnome org>
Date: Sun Oct 14 12:19:43 2012 +0200
svg: add feFlood support (not working yet).
docs/reference/lasem/Makefile.am | 1 +
src/Makefile.am | 2 +
src/lsmcairo.c | 31 +++++++++++-
src/lsmcairo.h | 2 +
src/lsmsvgdocument.c | 3 +
src/lsmsvgfilterflood.c | 103 ++++++++++++++++++++++++++++++++++++++
src/lsmsvgfilterflood.h | 57 +++++++++++++++++++++
src/lsmsvgfilterprimitive.c | 7 +++
src/lsmsvgstyle.c | 6 +-
src/lsmsvgstyle.h | 6 +-
src/lsmsvgtypes.h | 1 +
src/lsmsvgview.c | 76 ++++++++++++++++++++--------
12 files changed, 265 insertions(+), 30 deletions(-)
---
diff --git a/docs/reference/lasem/Makefile.am b/docs/reference/lasem/Makefile.am
index 4ac9476..cb8b57a 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 \
+ lsmsvgfilterflood.h \
lsmsvgfiltergaussianblur.h
# Images to copy into HTML directory.
diff --git a/src/Makefile.am b/src/Makefile.am
index ebabeb2..cfb9577 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -126,6 +126,7 @@ LASEM_SVG_SRCS = \
lsmsvgmaskelement.c \
lsmsvgfilterelement.c \
lsmsvgfilterprimitive.c \
+ lsmsvgfilterflood.c \
lsmsvgfiltergaussianblur.c
LASEM_DOM_HDRS = \
@@ -231,6 +232,7 @@ LASEM_SVG_HDRS = \
lsmsvgmaskelement.h \
lsmsvgfilterelement.h \
lsmsvgfilterprimitive.h \
+ lsmsvgfilterflood.h \
lsmsvgfiltergaussianblur.h
liblasem_ LASEM_API_VERSION@_ladir = $(includedir)/lasem- LASEM_API_VERSION@
diff --git a/src/lsmcairo.c b/src/lsmcairo.c
index deeb227..34e1007 100644
--- a/src/lsmcairo.c
+++ b/src/lsmcairo.c
@@ -263,8 +263,8 @@ box_blur (LsmFilterSurface *input,
void
lsm_filter_surface_fast_blur (LsmFilterSurface *input,
- LsmFilterSurface *output,
- double sx, double sy)
+ LsmFilterSurface *output,
+ double sx, double sy)
{
gint kx, ky;
guchar *intermediate;
@@ -287,6 +287,33 @@ lsm_filter_surface_fast_blur (LsmFilterSurface *input,
g_free (intermediate);
}
+void
+lsm_filter_surface_flood (LsmFilterSurface *surface, guint32 color, double opacity)
+{
+ guint8 int_opacity;
+ char pixcolour[4];
+ int i, x, y;
+ int stride;
+ unsigned char *pixels;
+
+ g_return_if_fail (surface != NULL);
+
+ stride = cairo_image_surface_get_stride (surface->surface);
+ pixels = cairo_image_surface_get_data (surface->surface);
+
+ int_opacity = (double) (0.5 + opacity * 255.0);
+
+ for (i = 0; i < 3; i++)
+ pixcolour[i] = (int) (((unsigned char *)
+ (&color))[2 - i]) * int_opacity / 255;
+ pixcolour[3] = 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];
+}
+
/**
* lsm_cairo_set_source_pixbuf:
* @cr: a cairo context
diff --git a/src/lsmcairo.h b/src/lsmcairo.h
index 8955f4f..d71b176 100644
--- a/src/lsmcairo.h
+++ b/src/lsmcairo.h
@@ -52,6 +52,8 @@ LsmFilterSurface * lsm_filter_surface_ref (LsmFilterSurface *filter_surface);
void lsm_filter_surface_fast_blur (LsmFilterSurface *input,
LsmFilterSurface *output,
double sx, double sy);
+void lsm_filter_surface_flood (LsmFilterSurface *surface, guint32 color, double opacity);
+
void lsm_cairo_set_source_pixbuf (cairo_t *cr,
const GdkPixbuf *pixbuf,
gdouble pixbuf_x,
diff --git a/src/lsmsvgdocument.c b/src/lsmsvgdocument.c
index 082b8ad..ed1e745 100644
--- a/src/lsmsvgdocument.c
+++ b/src/lsmsvgdocument.c
@@ -47,6 +47,7 @@
#include <lsmsvgmaskelement.h>
#include <lsmsvgfilterelement.h>
#include <lsmsvgfiltergaussianblur.h>
+#include <lsmsvgfilterflood.h>
#include <lsmsvgview.h>
#include <string.h>
@@ -136,6 +137,8 @@ _create_element (LsmDomDocument *document, const char *tag_name)
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, "feFlood") == 0)
+ node = lsm_svg_filter_flood_new ();
if (node != NULL)
lsm_debug_dom ("[LsmSvgDocument::create_element] Create a %s element", tag_name);
diff --git a/src/lsmsvgfilterflood.c b/src/lsmsvgfilterflood.c
new file mode 100644
index 0000000..11a4600
--- /dev/null
+++ b/src/lsmsvgfilterflood.c
@@ -0,0 +1,103 @@
+/* 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 <lsmsvgfilterflood.h>
+#include <lsmsvgview.h>
+
+static GObjectClass *parent_class;
+
+/* GdomNode implementation */
+
+static const char *
+lsm_svg_filter_flood_get_node_name (LsmDomNode *node)
+{
+ return "feFlood";
+}
+
+/* LsmSvgElement implementation */
+
+static void
+lsm_svg_filter_flood_apply (LsmSvgFilterPrimitive *self, LsmSvgView *view,
+ const char *input, const char *output,
+ double x, double y, double w, double h)
+{
+ lsm_svg_view_apply_flood (view, output, x, y, w, h);
+}
+
+/* LsmSvgFilterFlood implementation */
+
+static const LsmSvgOneOrTwoDouble std_deviation_default = {.a = 0.0, .b = 0.0};
+
+LsmDomNode *
+lsm_svg_filter_flood_new (void)
+{
+ return g_object_new (LSM_TYPE_SVG_FILTER_FLOOD, NULL);
+}
+
+static void
+lsm_svg_filter_flood_init (LsmSvgFilterFlood *self)
+{
+ self->std_deviation.value = std_deviation_default;
+}
+
+static void
+lsm_svg_filter_flood_finalize (GObject *object)
+{
+ parent_class->finalize (object);
+}
+
+/* LsmSvgFilterFlood class */
+
+static const LsmAttributeInfos lsm_svg_filter_flood_attribute_infos[] = {
+ {
+ .name = "stdDeviation",
+ .attribute_offset = offsetof (LsmSvgFilterFlood, std_deviation),
+ .trait_class = &lsm_svg_one_or_two_double_trait_class,
+ .trait_default = &std_deviation_default
+ }
+};
+
+static void
+lsm_svg_filter_flood_class_init (LsmSvgFilterFloodClass *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_flood_finalize;
+
+ d_node_class->get_node_name = lsm_svg_filter_flood_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_flood_attribute_infos),
+ lsm_svg_filter_flood_attribute_infos);
+
+ f_primitive_class->apply = lsm_svg_filter_flood_apply;
+}
+
+G_DEFINE_TYPE (LsmSvgFilterFlood, lsm_svg_filter_flood, LSM_TYPE_SVG_FILTER_PRIMITIVE)
diff --git a/src/lsmsvgfilterflood.h b/src/lsmsvgfilterflood.h
new file mode 100644
index 0000000..5da9242
--- /dev/null
+++ b/src/lsmsvgfilterflood.h
@@ -0,0 +1,57 @@
+/* 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_FLOOD_H
+#define LSM_SVG_FILTER_FLOOD_H
+
+#include <lsmsvgtypes.h>
+#include <lsmsvgfilterprimitive.h>
+
+G_BEGIN_DECLS
+
+#define LSM_TYPE_SVG_FILTER_FLOOD (lsm_svg_filter_flood_get_type ())
+#define LSM_SVG_FILTER_FLOOD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LSM_TYPE_SVG_FILTER_FLOOD, LsmSvgFilterFlood))
+#define LSM_SVG_FILTER_FLOOD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LSM_TYPE_SVG_FILTER_FLOOD, LsmSvgFilterFloodClass))
+#define LSM_IS_SVG_FILTER_FLOOD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LSM_TYPE_SVG_FILTER_FLOOD))
+#define LSM_IS_SVG_FILTER_FLOOD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LSM_TYPE_SVG_FILTER_FLOOD))
+#define LSM_SVG_FILTER_FLOOD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LSM_TYPE_SVG_FILTER_FLOOD, LsmSvgFilterFloodClass))
+
+typedef struct _LsmSvgFilterFloodClass LsmSvgFilterFloodClass;
+
+struct _LsmSvgFilterFlood {
+ LsmSvgFilterPrimitive base;
+
+ LsmSvgOneOrTwoDoubleAttribute std_deviation;
+};
+
+struct _LsmSvgFilterFloodClass {
+ LsmSvgFilterPrimitiveClass element_class;
+};
+
+GType lsm_svg_filter_flood_get_type (void);
+
+LsmDomNode * lsm_svg_filter_flood_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/lsmsvgfilterprimitive.c b/src/lsmsvgfilterprimitive.c
index 2d9cf44..536bc6e 100644
--- a/src/lsmsvgfilterprimitive.c
+++ b/src/lsmsvgfilterprimitive.c
@@ -42,6 +42,8 @@ void
lsm_svg_filter_primitive_apply (LsmSvgFilterPrimitive *self, LsmSvgView *view)
{
LsmSvgFilterPrimitiveClass *primitive_class;
+ const LsmSvgStyle *parent_style;
+ LsmSvgStyle *style;
double x, y, w, h;
g_return_if_fail (LSM_IS_SVG_FILTER_PRIMITIVE (self));
@@ -55,8 +57,13 @@ lsm_svg_filter_primitive_apply (LsmSvgFilterPrimitive *self, LsmSvgView *view)
lsm_log_render ("[Svg::FilterPrimitive::apply] Apply %s", lsm_dom_node_get_node_name (LSM_DOM_NODE (self)));
+ parent_style = lsm_svg_view_get_current_style (view);
+ style = lsm_svg_style_new_inherited (parent_style, &(LSM_SVG_ELEMENT (self))->property_bag);
+
if (primitive_class->apply != NULL)
primitive_class->apply (self, view, self->in.value, self->result.value, x, y, w, h);
+
+ lsm_svg_style_unref (style);
}
static const LsmSvgLength x_y_default = { .value_unit = 0.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
diff --git a/src/lsmsvgstyle.c b/src/lsmsvgstyle.c
index b2790d5..85b8b1f 100644
--- a/src/lsmsvgstyle.c
+++ b/src/lsmsvgstyle.c
@@ -74,19 +74,19 @@ static const LsmPropertyInfos lsm_svg_property_infos[] = {
{
.name = "flood-color",
.id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, flood_color),
- .trait_class = &lsm_null_trait_class,
+ .trait_class = &lsm_svg_color_trait_class,
.trait_default = "black"
},
{
.name = "flood-opacity",
.id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, flood_opacity),
- .trait_class = &lsm_null_trait_class,
+ .trait_class = &lsm_double_trait_class,
.trait_default = "1"
},
{
.name = "lighting-color",
.id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, lighting_color),
- .trait_class = &lsm_null_trait_class,
+ .trait_class = &lsm_svg_color_trait_class,
.trait_default = "white"
},
{
diff --git a/src/lsmsvgstyle.h b/src/lsmsvgstyle.h
index 56a8ebe..fca298d 100644
--- a/src/lsmsvgstyle.h
+++ b/src/lsmsvgstyle.h
@@ -124,9 +124,9 @@ struct _LsmSvgStyle {
LsmProperty * dominant_baseline;
LsmProperty * enable_background;
LsmProperty * filter;
- LsmProperty * flood_color;
- LsmProperty * flood_opacity;
- LsmProperty * lighting_color;
+ LsmSvgColorProperty * flood_color;
+ LsmSvgDoubleProperty * flood_opacity;
+ LsmSvgColorProperty * lighting_color;
LsmProperty * mask;
LsmSvgDoubleProperty * opacity;
LsmSvgOverflowProperty * overflow;
diff --git a/src/lsmsvgtypes.h b/src/lsmsvgtypes.h
index 8ef45d8..aeefcf0 100644
--- a/src/lsmsvgtypes.h
+++ b/src/lsmsvgtypes.h
@@ -58,6 +58,7 @@ typedef struct _LsmSvgMaskElement LsmSvgMaskElement;
typedef struct _LsmSvgFilterElement LsmSvgFilterElement;
typedef struct _LsmSvgFilterPrimitive LsmSvgFilterPrimitive;
typedef struct _LsmSvgFilterGaussianBlur LsmSvgFilterGaussianBlur;
+typedef struct _LsmSvgFilterFlood LsmSvgFilterFlood;
typedef struct _LsmSvgView LsmSvgView;
typedef struct _LsmSvgStyle LsmSvgStyle;
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index 2465e41..8457a95 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -1990,28 +1990,6 @@ lsm_svg_view_pop_filter (LsmSvgView *view)
lsm_svg_element_force_render (filter_element, view);
-#if 1
- lsm_filter_surface_copy_data (filter_surface, view->filter_surfaces->data);
-
- 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;
-
- pattern = cairo_pattern_create_for_surface (lsm_filter_surface_get_cairo_surface (view->filter_surfaces->data));
- 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
-
if (view->debug_filter) {
GSList *iter;
char *filename;
@@ -2028,6 +2006,32 @@ 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_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
+ }
+
for (iter = view->filter_surfaces; iter != NULL; iter = iter->next)
lsm_filter_surface_unref (iter->data);
g_slist_free (view->filter_surfaces);
@@ -2100,6 +2104,34 @@ lsm_svg_view_apply_gaussian_blur (LsmSvgView *view, const char *input, const cha
}
void
+lsm_svg_view_apply_flood (LsmSvgView *view, const char *output,
+ double x, double y, double w, double h)
+{
+ LsmFilterSurface *output_surface;
+ LsmFilterSurface *input_surface;
+ guint8 red, green, blue;
+ guint32 color;
+ double opacity;
+
+ g_return_if_fail (LSM_IS_SVG_VIEW (view));
+
+ input_surface = _get_filter_surface (view, NULL);
+
+ output_surface = _create_filter_surface (view, output, input_surface);
+
+ red = (double) (0.5 + view->style->flood_color->value.red * 255.0);
+ green = (double) (0.5 + view->style->flood_color->value.green * 255.0);
+ blue = (double) (0.5 + view->style->flood_color->value.blue * 255.0);
+ color = red << 16 | green << 8 | blue << 0;
+ opacity = view->style->fill_opacity->value;
+
+ lsm_log_render ("[SvgView::apply_flood] color = 0x%06x - opacity = %g",
+ color, opacity);
+
+ lsm_filter_surface_flood (output_surface, color, opacity);
+}
+
+void
lsm_svg_view_push_element (LsmSvgView *view, const LsmSvgElement *element)
{
g_return_if_fail (LSM_IS_SVG_VIEW (view));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]