[lasem] svg_convolve_matrix: implement divisor, bias, target and preserve_alpha
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [lasem] svg_convolve_matrix: implement divisor, bias, target and preserve_alpha
- Date: Mon, 3 Aug 2015 21:42:42 +0000 (UTC)
commit f280e32dcde106709f42cf7d88dba724040f3e8f
Author: Emmanuel Pacaud <emmanuel gnome org>
Date: Mon Aug 3 23:41:18 2015 +0200
svg_convolve_matrix: implement divisor, bias, target and preserve_alpha
src/lsmsvgattributes.h | 10 ++++
src/lsmsvgfilterconvolvematrix.c | 87 ++++++++++++++++++++++++++++++++++++-
src/lsmsvgfilterconvolvematrix.h | 5 ++
src/lsmsvgfiltersurface.c | 21 ++++-----
src/lsmsvgfiltersurface.h | 3 +-
src/lsmsvgview.c | 7 ++-
src/lsmsvgview.h | 3 +-
src/lsmtraits.c | 53 +++++++++++++++++++++++
src/lsmtraits.h | 2 +
9 files changed, 173 insertions(+), 18 deletions(-)
---
diff --git a/src/lsmsvgattributes.h b/src/lsmsvgattributes.h
index 9ac6db4..280c6e8 100644
--- a/src/lsmsvgattributes.h
+++ b/src/lsmsvgattributes.h
@@ -40,6 +40,16 @@ typedef struct {
typedef struct {
LsmAttribute base;
+ gboolean value;
+} LsmSvgBooleanAttribute;
+
+typedef struct {
+ LsmAttribute base;
+ int value;
+} LsmSvgIntegerAttribute;
+
+typedef struct {
+ LsmAttribute base;
double value;
} LsmSvgDoubleAttribute;
diff --git a/src/lsmsvgfilterconvolvematrix.c b/src/lsmsvgfilterconvolvematrix.c
index e65b926..46f0721 100644
--- a/src/lsmsvgfilterconvolvematrix.c
+++ b/src/lsmsvgfilterconvolvematrix.c
@@ -40,14 +40,56 @@ static void
lsm_svg_filter_convolve_matrix_apply (LsmSvgFilterPrimitive *self, LsmSvgView *view,
const char *input, const char *output, const LsmBox *subregion)
{
+ double divisor;
+ int order_x;
+ int order_y;
+ int target_x;
+ int target_y;
+
LsmSvgFilterConvolveMatrix *convolve_matrix = LSM_SVG_FILTER_CONVOLVE_MATRIX (self);
+ order_x = convolve_matrix->order.value.a;
+ order_y = convolve_matrix->order.value.b;
+
+ if (lsm_attribute_is_defined (&convolve_matrix->target_x.base))
+ target_x = convolve_matrix->target_x.value;
+ else
+ target_x = order_x / 2;
+
+ if (lsm_attribute_is_defined (&convolve_matrix->target_y.base))
+ target_y = convolve_matrix->target_y.value;
+ else
+ target_y = order_y / 2;
+
+ target_x = CLAMP (target_x, 0, order_x);
+ target_y = CLAMP (target_y, 0, order_y);
+
+ if (lsm_attribute_is_defined (&convolve_matrix->divisor.base))
+ divisor = convolve_matrix->divisor.value;
+ else {
+ int i;
+
+ divisor = 0.0;
+
+ for (i = 0; i < convolve_matrix->kernel.value.n_values; i++)
+ divisor += convolve_matrix->kernel.value.values[i];
+ }
+
+ if (divisor <= 0.0) {
+ lsm_warning_dom ("[SvgFilterConvolveMatrix::apply] Invalid divisor");
+ return;
+ }
+
lsm_svg_view_apply_convolve_matrix (view, input, output, subregion,
- convolve_matrix->order.value.a,
- convolve_matrix->order.value.b,
+ order_x, order_y,
convolve_matrix->kernel.value.n_values,
convolve_matrix->kernel.value.values,
- convolve_matrix->edge_mode.value);
+ divisor,
+ convolve_matrix->bias.value,
+ target_x,
+ target_y,
+ convolve_matrix->edge_mode.value,
+ convolve_matrix->preserve_alpha.value);
}
/* LsmSvgFilterConvolveMatrix implementation */
@@ -60,14 +102,23 @@ lsm_svg_filter_convolve_matrix_new (void)
static const LsmSvgOneOrTwoInteger order_default = {0, 0};
static const LsmSvgVector kernel_default = { .n_values = 0, .values = NULL};
+static const double divisor_default = 0.0;
+static const double bias_default = 0.0;
+static const int target_default = -1;
static const LsmSvgEdgeMode edge_mode_default = LSM_SVG_EDGE_MODE_NONE;
+static const gboolean preserve_alpha_default = FALSE;
static void
lsm_svg_filter_convolve_matrix_init (LsmSvgFilterConvolveMatrix *self)
{
self->order.value = order_default;
self->kernel.value = kernel_default;
+ self->divisor.value = divisor_default;
+ self->bias.value = bias_default;
+ self->target_x.value = target_default;
+ self->target_y.value = target_default;
self->edge_mode.value = edge_mode_default;
+ self->preserve_alpha.value = preserve_alpha_default;
}
static void
@@ -92,10 +143,40 @@ static const LsmAttributeInfos lsm_svg_filter_convolve_matrix_attribute_infos[]
.trait_default = &kernel_default
},
{
+ .name = "divisor",
+ .attribute_offset = offsetof (LsmSvgFilterConvolveMatrix, divisor),
+ .trait_class = &lsm_double_trait_class,
+ .trait_default = &divisor_default
+ },
+ {
+ .name = "bias",
+ .attribute_offset = offsetof (LsmSvgFilterConvolveMatrix, bias),
+ .trait_class = &lsm_double_trait_class,
+ .trait_default = &bias_default
+ },
+ {
+ .name = "targetX",
+ .attribute_offset = offsetof (LsmSvgFilterConvolveMatrix, target_x),
+ .trait_class = &lsm_integer_trait_class,
+ .trait_default = &target_default
+ },
+ {
+ .name = "targetY",
+ .attribute_offset = offsetof (LsmSvgFilterConvolveMatrix, target_y),
+ .trait_class = &lsm_integer_trait_class,
+ .trait_default = &target_default
+ },
+ {
.name = "edgeMode",
.attribute_offset = offsetof (LsmSvgFilterConvolveMatrix, edge_mode),
.trait_class = &lsm_svg_edge_mode_trait_class,
.trait_default = &edge_mode_default
+ },
+ {
+ .name = "preserveAlpha",
+ .attribute_offset = offsetof (LsmSvgFilterConvolveMatrix, preserve_alpha),
+ .trait_class = &lsm_boolean_trait_class,
+ .trait_default = &preserve_alpha_default
}
};
diff --git a/src/lsmsvgfilterconvolvematrix.h b/src/lsmsvgfilterconvolvematrix.h
index 1f98d61..be012a5 100644
--- a/src/lsmsvgfilterconvolvematrix.h
+++ b/src/lsmsvgfilterconvolvematrix.h
@@ -43,7 +43,12 @@ struct _LsmSvgFilterConvolveMatrix {
LsmSvgOneOrTwoIntegerAttribute order;
LsmSvgVectorAttribute kernel;
+ LsmSvgDoubleAttribute divisor;
+ LsmSvgDoubleAttribute bias;
+ LsmSvgIntegerAttribute target_x;
+ LsmSvgIntegerAttribute target_y;
LsmSvgEdgeModeAttribute edge_mode;
+ LsmSvgBooleanAttribute preserve_alpha;
};
struct _LsmSvgFilterConvolveMatrixClass {
diff --git a/src/lsmsvgfiltersurface.c b/src/lsmsvgfiltersurface.c
index 57e1adc..9c77d59 100644
--- a/src/lsmsvgfiltersurface.c
+++ b/src/lsmsvgfiltersurface.c
@@ -615,7 +615,8 @@ lsm_svg_filter_surface_color_matrix (LsmSvgFilterSurface *input, LsmSvgFilterSur
void
lsm_svg_filter_surface_convolve_matrix (LsmSvgFilterSurface *input, LsmSvgFilterSurface *output,
unsigned order_x, unsigned order_y, unsigned n_values, const double
*values,
- LsmSvgEdgeMode edge_mode)
+ double divisor, double bias, unsigned target_x, unsigned target_y,
+ LsmSvgEdgeMode edge_mode, gboolean preserve_alpha)
{
cairo_t *cairo;
int ch;
@@ -627,16 +628,8 @@ lsm_svg_filter_surface_convolve_matrix (LsmSvgFilterSurface *input, LsmSvgFilter
double kval, sum;
guchar sval;
int sx, sy, kx, ky;
- /* TODO target */
- double targetx = 0.0, targety = 0.0;
/* TODO d */
double dx = 1.0, dy = 1.0;
- /* TODO */
- gboolean preserve_alpha = FALSE;
- /* TODO */
- double divisor = 1.0;
- /* TODO */
- double bias = 0.0;
int umch, i, j;
gint tempresult;
@@ -644,6 +637,9 @@ lsm_svg_filter_surface_convolve_matrix (LsmSvgFilterSurface *input, LsmSvgFilter
g_return_if_fail (output != NULL);
g_return_if_fail (values != NULL || n_values < 1);
+ if (divisor <= 0.0)
+ return;
+
width = cairo_image_surface_get_width (input->surface);
height = cairo_image_surface_get_height (input->surface);
@@ -657,6 +653,9 @@ lsm_svg_filter_surface_convolve_matrix (LsmSvgFilterSurface *input, LsmSvgFilter
if (order_y * order_x != n_values)
return;
+ if (target_x > order_x || target_y > order_y)
+ return;
+
x1 = CLAMP (input->subregion.x, 0, width);
x2 = CLAMP (input->subregion.x + input->subregion.width, 0, width);
y1 = CLAMP (input->subregion.y, 0, height);
@@ -677,8 +676,8 @@ lsm_svg_filter_surface_convolve_matrix (LsmSvgFilterSurface *input, LsmSvgFilter
for (i = 0; i < order_y; i++)
for (j = 0; j < order_x; j++) {
int alpha;
- sx = x - targetx + j * dx;
- sy = y - targety + i * dy;
+ sx = x - target_x + j * dx;
+ sy = y - target_y + i * dy;
if (edge_mode == LSM_SVG_EDGE_MODE_DUPLICATE) {
if (sx < x1)
sx = x1;
diff --git a/src/lsmsvgfiltersurface.h b/src/lsmsvgfiltersurface.h
index 731e348..45ab6ed 100644
--- a/src/lsmsvgfiltersurface.h
+++ b/src/lsmsvgfiltersurface.h
@@ -67,7 +67,8 @@ void lsm_svg_filter_surface_color_matrix (LsmSvgFilterSurface *input,
LsmSvg
void lsm_svg_filter_surface_convolve_matrix (LsmSvgFilterSurface *input,
LsmSvgFilterSurface *output,
unsigned x_order, unsigned y_order,
unsigned n_values, const double *values,
- LsmSvgEdgeMode edge_mode);
+ double divisor, double bias, unsigned
target_x, unsigned target_y,
+ LsmSvgEdgeMode edge_mode, gboolean
preserve_alpha);
void lsm_svg_filter_surface_image (LsmSvgFilterSurface *output, GdkPixbuf
*pixbuf,
LsmSvgPreserveAspectRatio
preserve_aspect_ratio);
void lsm_svg_filter_surface_morphology (LsmSvgFilterSurface *input_surface,
LsmSvgFilterSurface *output_surface,
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index 348ff40..6b34f09 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -2252,7 +2252,9 @@ lsm_svg_view_apply_morphology (LsmSvgView *view, const char *input, const char *
void
lsm_svg_view_apply_convolve_matrix (LsmSvgView *view, const char *input, const char *output, const LsmBox
*subregion,
- unsigned x_order, unsigned y_order, unsigned n_values, double *values,
LsmSvgEdgeMode edge_mode)
+ unsigned x_order, unsigned y_order, unsigned n_values, double *values,
+ double divisor, double bias, int target_x, int target_y,
+ LsmSvgEdgeMode edge_mode, gboolean preserve_alpha)
{
LsmSvgFilterSurface *input_surface;
LsmSvgFilterSurface *output_surface;
@@ -2270,7 +2272,8 @@ lsm_svg_view_apply_convolve_matrix (LsmSvgView *view, const char *input, const c
lsm_cairo_box_user_to_device (view->dom_view.cairo, &subregion_px, subregion);
output_surface = _create_filter_surface (view, output, input_surface, &subregion_px);
- lsm_svg_filter_surface_convolve_matrix (input_surface, output_surface, x_order, y_order, n_values,
values, edge_mode);
+ lsm_svg_filter_surface_convolve_matrix (input_surface, output_surface, x_order, y_order, n_values,
values,
+ divisor, bias, target_x, target_y, edge_mode, preserve_alpha);
}
void
diff --git a/src/lsmsvgview.h b/src/lsmsvgview.h
index 487e5b0..bc6c780 100644
--- a/src/lsmsvgview.h
+++ b/src/lsmsvgview.h
@@ -183,7 +183,8 @@ void lsm_svg_view_apply_morphology (LsmSvgView *view, const char
*input, con
LsmSvgMorphologyOperator op, double radius);
void lsm_svg_view_apply_convolve_matrix (LsmSvgView *view, const char *input, const char
*output, const LsmBox *subregion,
unsigned a, unsigned b, unsigned n_values, double
*values,
- LsmSvgEdgeMode edge_mode);
+ double divisor, double bias, int target_x, int
target_y,
+ LsmSvgEdgeMode edge_mode, gboolean preserve_alpha);
void lsm_svg_view_apply_specular_lighting (LsmSvgView *view, const char *output, const LsmBox
*subregion,
double surface_scale, double specular_constant,
double specular_exponent,
double dx, double dy);
diff --git a/src/lsmtraits.c b/src/lsmtraits.c
index ad46efb..96809dd 100644
--- a/src/lsmtraits.c
+++ b/src/lsmtraits.c
@@ -31,6 +31,59 @@ const LsmTraitClass lsm_null_trait_class = {
};
static gboolean
+lsm_boolean_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+ gboolean *trait = (gboolean *) abstract_trait;
+
+ if (g_strcmp0 ("true", string) == 0)
+ *trait = TRUE;
+ else if (g_strcmp0 ("false", string) == 0)
+ *trait = FALSE;
+ else return FALSE;
+
+ return TRUE;
+}
+
+static char *
+lsm_boolean_trait_to_string (LsmTrait *abstract_trait)
+{
+ gboolean *trait = (gboolean *) abstract_trait;
+
+ return g_strdup_printf ("%s", *trait ? "true" : "false");
+}
+
+const LsmTraitClass lsm_boolean_trait_class = {
+ .size = sizeof (gboolean),
+ .from_string = lsm_boolean_trait_from_string,
+ .to_string = lsm_boolean_trait_to_string
+};
+
+static gboolean
+lsm_integer_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+ int *trait = (int *) abstract_trait;
+ char *end_ptr;
+
+ *trait = g_ascii_strtoll (string, &end_ptr, 10);
+
+ return end_ptr != string;
+}
+
+static char *
+lsm_integer_trait_to_string (LsmTrait *abstract_trait)
+{
+ int *trait = (int *) abstract_trait;
+
+ return g_strdup_printf ("%d", *trait);
+}
+
+const LsmTraitClass lsm_integer_trait_class = {
+ .size = sizeof (int),
+ .from_string = lsm_integer_trait_from_string,
+ .to_string = lsm_integer_trait_to_string
+};
+
+static gboolean
lsm_double_trait_from_string (LsmTrait *abstract_trait, char *string)
{
double *trait = (double *) abstract_trait;
diff --git a/src/lsmtraits.h b/src/lsmtraits.h
index 5716554..6d58d0d 100644
--- a/src/lsmtraits.h
+++ b/src/lsmtraits.h
@@ -39,6 +39,8 @@ typedef struct {
} LsmTraitClass;
extern const LsmTraitClass lsm_null_trait_class;
+extern const LsmTraitClass lsm_boolean_trait_class;
+extern const LsmTraitClass lsm_integer_trait_class;
extern const LsmTraitClass lsm_double_trait_class;
extern const LsmTraitClass lsm_box_trait_class;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]