summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/attributes.cpp3
-rw-r--r--src/attributes.h3
-rw-r--r--src/display/nr-filter-blend.cpp8
-rw-r--r--src/display/nr-filter-slot.cpp23
-rw-r--r--src/display/nr-filter-types.h2
-rw-r--r--src/display/nr-filter.cpp2
-rw-r--r--src/sp-feblend.cpp28
-rw-r--r--src/sp-feblend.h1
-rw-r--r--src/sp-filter-primitive.cpp80
-rw-r--r--src/sp-filter-primitive.h5
-rw-r--r--src/sp-filter.cpp30
-rw-r--r--src/sp-filter.h12
12 files changed, 170 insertions, 27 deletions
diff --git a/src/attributes.cpp b/src/attributes.cpp
index 39f6a04f9..a8cd2e83d 100644
--- a/src/attributes.cpp
+++ b/src/attributes.cpp
@@ -165,6 +165,9 @@ static SPStyleProp const props[] = {
{SP_ATTR_FILTERUNITS, "filterUnits"},
{SP_ATTR_PRIMITIVEUNITS, "primitiveUnits"},
{SP_ATTR_FILTERRES, "filterRes"},
+ /* Filter primitives common */
+ {SP_ATTR_IN, "in"},
+ {SP_ATTR_RESULT, "result"},
/*feBlend*/
{SP_ATTR_MODE, "mode"},
{SP_ATTR_IN2, "in2"},
diff --git a/src/attributes.h b/src/attributes.h
index 85eb00e38..fa492d978 100644
--- a/src/attributes.h
+++ b/src/attributes.h
@@ -165,6 +165,9 @@ enum SPAttributeEnum {
SP_ATTR_FILTERUNITS,
SP_ATTR_PRIMITIVEUNITS,
SP_ATTR_FILTERRES,
+ /* Filter primitives common */
+ SP_ATTR_IN,
+ SP_ATTR_RESULT,
/*feBlend*/
SP_ATTR_MODE,
SP_ATTR_IN2,
diff --git a/src/display/nr-filter-blend.cpp b/src/display/nr-filter-blend.cpp
index 1468eb61b..0e2f965b7 100644
--- a/src/display/nr-filter-blend.cpp
+++ b/src/display/nr-filter-blend.cpp
@@ -23,14 +23,6 @@
#include "libnr/nr-blit.h"
#include "libnr/nr-pixops.h"
-/*
-static inline int clamp(const int val, const int min, const int max) {
- if (val < min) return min;
- if (val > max) return max;
- return val;
-}
-*/
-
template <void(*blend)(unsigned char *cr, unsigned char const *ca, unsigned char const *cb)>
static void _render(NRPixBlock &out, NRPixBlock &in1, NRPixBlock &in2) {
unsigned char *in1_data = NR_PIXBLOCK_PX(&in1);
diff --git a/src/display/nr-filter-slot.cpp b/src/display/nr-filter-slot.cpp
index 3a2895ec6..673754f18 100644
--- a/src/display/nr-filter-slot.cpp
+++ b/src/display/nr-filter-slot.cpp
@@ -62,7 +62,7 @@ NRPixBlock *FilterSlot::get(int slot_nr)
|| slot_nr == NR_FILTER_BACKGROUNDIMAGE
|| slot_nr == NR_FILTER_BACKGROUNDALPHA
|| slot_nr == NR_FILTER_FILLPAINT
- || slot_nr == NR_FILTER_SOURCEPAINT))
+ || slot_nr == NR_FILTER_STROKEPAINT))
{
/* If needed, fetch background */
if (slot_nr == NR_FILTER_BACKGROUNDIMAGE
@@ -70,7 +70,22 @@ NRPixBlock *FilterSlot::get(int slot_nr)
{
NRPixBlock *pb;
pb = nr_arena_item_get_background(_arena_item);
- this->set(NR_FILTER_BACKGROUNDIMAGE, pb);
+ if (pb) {
+ this->set(NR_FILTER_BACKGROUNDIMAGE, pb);
+ } else {
+ NRPixBlock *source = this->get(NR_FILTER_SOURCEGRAPHIC);
+ pb = new NRPixBlock();
+ if (!pb) return NULL; // Allocation failed
+ nr_pixblock_setup_fast(pb, source->mode,
+ source->area.x0, source->area.y0,
+ source->area.x1, source->area.y1, true);
+ if (pb->size != NR_PIXBLOCK_SIZE_TINY && pb->data.px == NULL) {
+ // allocation failed
+ delete pb;
+ return NULL;
+ }
+ this->set(NR_FILTER_BACKGROUNDIMAGE, pb);
+ }
}
/* If only a alpha channel is needed, strip it from full image */
if (slot_nr == NR_FILTER_SOURCEALPHA) {
@@ -83,7 +98,7 @@ NRPixBlock *FilterSlot::get(int slot_nr)
if (slot_nr == NR_FILTER_FILLPAINT) {
// TODO
}
- if (slot_nr == NR_FILTER_SOURCEPAINT) {
+ if (slot_nr == NR_FILTER_STROKEPAINT) {
// TODO
}
}
@@ -125,7 +140,7 @@ int FilterSlot::_get_index(int slot_nr)
slot_nr == NR_FILTER_BACKGROUNDIMAGE ||
slot_nr == NR_FILTER_BACKGROUNDALPHA ||
slot_nr == NR_FILTER_FILLPAINT ||
- slot_nr == NR_FILTER_SOURCEPAINT);
+ slot_nr == NR_FILTER_STROKEPAINT);
int index = -1;
if (slot_nr == NR_FILTER_SLOT_NOT_SET) {
diff --git a/src/display/nr-filter-types.h b/src/display/nr-filter-types.h
index 3eebe3731..6f28c6257 100644
--- a/src/display/nr-filter-types.h
+++ b/src/display/nr-filter-types.h
@@ -31,7 +31,7 @@ enum {
NR_FILTER_BACKGROUNDIMAGE = -4,
NR_FILTER_BACKGROUNDALPHA = -5,
NR_FILTER_FILLPAINT = -6,
- NR_FILTER_SOURCEPAINT = -7
+ NR_FILTER_STROKEPAINT = -7
};
} /* namespace NR */
diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp
index 515d5961f..d8cfb2ecf 100644
--- a/src/display/nr-filter.cpp
+++ b/src/display/nr-filter.cpp
@@ -35,8 +35,6 @@
using Inkscape::round;
#endif
-//#include "display/nr-arena-shape.h"
-
__attribute__ ((const))
inline static int _max4(const double a, const double b,
const double c, const double d) {
diff --git a/src/sp-feblend.cpp b/src/sp-feblend.cpp
index 49ab18a25..bedbf4f61 100644
--- a/src/sp-feblend.cpp
+++ b/src/sp-feblend.cpp
@@ -43,7 +43,6 @@ static Inkscape::XML::Node *sp_feBlend_write(SPObject *object, Inkscape::XML::No
static void sp_feBlend_build_renderer(SPFilterPrimitive *sp_prim, NR::Filter *filter);
static SPFilterPrimitiveClass *feBlend_parent_class;
-static int renderer;
GType
sp_feBlend_get_type()
@@ -86,7 +85,7 @@ sp_feBlend_class_init(SPFeBlendClass *klass)
static void
sp_feBlend_init(SPFeBlend *feBlend)
{
- renderer = -1;
+ feBlend->in2 = NR::NR_FILTER_SLOT_NOT_SET;
}
/**
@@ -103,6 +102,7 @@ sp_feBlend_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *re
/*LOAD ATTRIBUTES FROM REPR HERE*/
sp_object_read_attr(object, "mode");
+ sp_object_read_attr(object, "in2");
}
/**
@@ -155,18 +155,23 @@ sp_feBlend_set(SPObject *object, unsigned int key, gchar const *value)
SPFeBlend *feBlend = SP_FEBLEND(object);
(void)feBlend;
+ NR::FilterBlendMode mode;
+ int input;
switch(key) {
/*DEAL WITH SETTING ATTRIBUTES HERE*/
case SP_ATTR_MODE:
- feBlend->blend_mode = sp_feBlend_readmode(value);
-/*
- if (renderer >= 0) {
- NR::Filter *filter = SP_FILTER(object->parent)->_renderer;
- NR::FilterBlend *blend = dynamic_cast<NR::FilterBlend*>(filter->get_primitive(renderer));
- blend->set_mode(feBlend->blend_mode);
+ mode = sp_feBlend_readmode(value);
+ if (mode != feBlend->blend_mode) {
+ feBlend->blend_mode = mode;
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ break;
+ case SP_ATTR_IN2:
+ input = sp_filter_primitive_read_in(feBlend, value);
+ if (input != feBlend->in2) {
+ feBlend->in2 = input;
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
}
-*/
- object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
break;
default:
if (((SPObjectClass *) feBlend_parent_class)->set)
@@ -228,8 +233,7 @@ static void sp_feBlend_build_renderer(SPFilterPrimitive *primitive, NR::Filter *
sp_filter_primitive_renderer_common(primitive, nr_primitive);
nr_blend->set_mode(sp_blend->blend_mode);
-
- renderer = primitive_n;
+ nr_blend->set_input(1, sp_blend->in2);
}
/*
diff --git a/src/sp-feblend.h b/src/sp-feblend.h
index 90ab8967f..f6f71b892 100644
--- a/src/sp-feblend.h
+++ b/src/sp-feblend.h
@@ -25,6 +25,7 @@ class SPFeBlendClass;
struct SPFeBlend : public SPFilterPrimitive {
/** BLEND ATTRIBUTES HERE */
NR::FilterBlendMode blend_mode;
+ int in2;
};
struct SPFeBlendClass {
diff --git a/src/sp-filter-primitive.cpp b/src/sp-filter-primitive.cpp
index f799dbe54..cd8c53c65 100644
--- a/src/sp-filter-primitive.cpp
+++ b/src/sp-filter-primitive.cpp
@@ -23,6 +23,7 @@
#include "xml/repr.h"
#include "sp-filter.h"
#include "display/nr-filter-primitive.h"
+#include "display/nr-filter-types.h"
/* FilterPrimitive base class */
@@ -80,6 +81,8 @@ sp_filter_primitive_class_init(SPFilterPrimitiveClass *klass)
static void
sp_filter_primitive_init(SPFilterPrimitive *filter_primitive)
{
+ filter_primitive->image_in = NR::NR_FILTER_SLOT_NOT_SET;
+ filter_primitive->image_out = NR::NR_FILTER_SLOT_NOT_SET;
}
/**
@@ -94,6 +97,9 @@ sp_filter_primitive_build(SPObject *object, SPDocument *document, Inkscape::XML:
((SPObjectClass *) filter_primitive_parent_class)->build(object, document, repr);
}
+ sp_object_read_attr(object, "in");
+ sp_object_read_attr(object, "result");
+
if (object->parent)
add_primitive((SPFilter*)object->parent, (SPFilterPrimitive*)object);
}
@@ -118,6 +124,32 @@ sp_filter_primitive_set(SPObject *object, unsigned int key, gchar const *value)
SPFilterPrimitive *filter_primitive = SP_FILTER_PRIMITIVE(object);
(void)filter_primitive;
+ int image_nr;
+ switch (key) {
+ case SP_ATTR_IN:
+ if (value) {
+ image_nr = sp_filter_primitive_read_in(filter_primitive, value);
+ } else {
+ image_nr = NR::NR_FILTER_SLOT_NOT_SET;
+ }
+ if (image_nr != filter_primitive->image_in) {
+ filter_primitive->image_in = image_nr;
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ break;
+ case SP_ATTR_RESULT:
+ if (value) {
+ image_nr = sp_filter_primitive_read_result(filter_primitive, value);
+ } else {
+ image_nr = NR::NR_FILTER_SLOT_NOT_SET;
+ }
+ if (image_nr != filter_primitive->image_out) {
+ filter_primitive->image_out = image_nr;
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ break;
+ }
+
/* See if any parents need this value. */
if (((SPObjectClass *) filter_primitive_parent_class)->set) {
((SPObjectClass *) filter_primitive_parent_class)->set(object, key, value);
@@ -169,12 +201,60 @@ sp_filter_primitive_write(SPObject *object, Inkscape::XML::Node *repr, guint fla
return repr;
}
+int sp_filter_primitive_read_in(SPFilterPrimitive *prim, gchar const *name)
+{
+ if (!name) return NR::NR_FILTER_SLOT_NOT_SET;
+ // TODO: are these case sensitive or not? (assumed yes)
+ switch (name[0]) {
+ case 'S':
+ if (strcmp(name, "SourceGraphic") == 0)
+ return NR::NR_FILTER_SOURCEGRAPHIC;
+ if (strcmp(name, "SourceAlpha") == 0)
+ return NR::NR_FILTER_SOURCEALPHA;
+ if (strcmp(name, "StrokePaint") == 0)
+ return NR::NR_FILTER_STROKEPAINT;
+ break;
+ case 'B':
+ if (strcmp(name, "BackgroundImage") == 0)
+ return NR::NR_FILTER_BACKGROUNDIMAGE;
+ if (strcmp(name, "BackgroundAlpha") == 0)
+ return NR::NR_FILTER_BACKGROUNDALPHA;
+ break;
+ case 'F':
+ if (strcmp(name, "FillPaint") == 0)
+ return NR::NR_FILTER_FILLPAINT;
+ break;
+ }
+
+ SPFilter *parent = SP_FILTER(prim->parent);
+ int ret = sp_filter_get_image_name(parent, name);
+ if (ret >= 0) return ret;
+
+ return NR::NR_FILTER_SLOT_NOT_SET;
+}
+
+int sp_filter_primitive_read_result(SPFilterPrimitive *prim, gchar const *name)
+{
+ SPFilter *parent = SP_FILTER(prim->parent);
+ int ret = sp_filter_get_image_name(parent, name);
+ if (ret >= 0) return ret;
+
+ ret = sp_filter_set_image_name(parent, name);
+ if (ret >= 0) return ret;
+
+ return NR::NR_FILTER_SLOT_NOT_SET;
+}
+
/* Common initialization for filter primitives */
void sp_filter_primitive_renderer_common(SPFilterPrimitive *sp_prim, NR::FilterPrimitive *nr_prim)
{
g_assert(sp_prim != NULL);
g_assert(nr_prim != NULL);
+
+ nr_prim->set_input(sp_prim->image_in);
+ nr_prim->set_output(sp_prim->image_out);
+
/* TODO: place here code to handle input images, filter area etc. */
}
diff --git a/src/sp-filter-primitive.h b/src/sp-filter-primitive.h
index 96268dbfe..6f6558c5c 100644
--- a/src/sp-filter-primitive.h
+++ b/src/sp-filter-primitive.h
@@ -17,6 +17,7 @@
#include "sp-object.h"
#include "display/nr-filter.h"
#include "display/nr-filter-primitive.h"
+#include "display/nr-filter-types.h"
#define SP_TYPE_FILTER_PRIMITIVE (sp_filter_primitive_get_type ())
#define SP_FILTER_PRIMITIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_FILTER_PRIMITIVE, SPFilterPrimitive))
@@ -28,6 +29,7 @@ class SPFilterPrimitive;
class SPFilterPrimitiveClass;
struct SPFilterPrimitive : public SPObject {
+ int image_in, image_out;
};
struct SPFilterPrimitiveClass {
@@ -40,6 +42,9 @@ GType sp_filter_primitive_get_type (void);
/* Common initialization for filter primitives */
void sp_filter_primitive_renderer_common(SPFilterPrimitive *sp_prim, NR::FilterPrimitive *nr_prim);
+int sp_filter_primitive_read_in(SPFilterPrimitive *prim, gchar const *name);
+int sp_filter_primitive_read_result(SPFilterPrimitive *prim, gchar const *name);
+
#endif
/*
Local Variables:
diff --git a/src/sp-filter.cpp b/src/sp-filter.cpp
index ac0d3d29e..43f2dc9d2 100644
--- a/src/sp-filter.cpp
+++ b/src/sp-filter.cpp
@@ -17,6 +17,11 @@
# include "config.h"
#endif
+#include <map>
+#include <string.h>
+using std::map;
+using std::pair;
+
#include "attributes.h"
#include "document.h"
#include "sp-filter.h"
@@ -454,6 +459,31 @@ int sp_filter_primitive_count(SPFilter *filter) {
return filter->_primitive_count;
}
+int sp_filter_get_image_name(SPFilter *filter, gchar const *name) {
+ gchar *name_copy = strdup(name);
+ map<gchar *, int, ltstr>::iterator result = filter->_image_name.find(name_copy);
+ free(name_copy);
+ if (result == filter->_image_name.end()) return -1;
+ else return (*result).second;
+}
+
+int sp_filter_set_image_name(SPFilter *filter, gchar const *name) {
+ int value = filter->_image_number_next;
+ filter->_image_number_next++;
+ gchar *name_copy = strdup(name);
+ pair<map<gchar*,int,ltstr>::iterator,bool> ret = filter->_image_name.insert(pair<gchar*,int>(name_copy, value));
+ if (ret.second == false) {
+ return (*ret.first).second;
+ }
+ return value;
+}
+
+bool ltstr::operator()(const char* s1, const char* s2) const
+{
+ return strcmp(s1, s2) < 0;
+}
+
+
/*
Local Variables:
mode:c++
diff --git a/src/sp-filter.h b/src/sp-filter.h
index 06b46ecc6..55e3eaa0a 100644
--- a/src/sp-filter.h
+++ b/src/sp-filter.h
@@ -14,6 +14,8 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+#include <map>
+
#include "number-opt-number.h"
#include "sp-object.h"
#include "sp-filter-units.h"
@@ -30,6 +32,10 @@ struct SPFilterReference;
class SPFilter;
class SPFilterClass;
+struct ltstr {
+ bool operator()(const char* s1, const char* s2) const;
+};
+
struct SPFilter : public SPObject {
/** filterUnits attribute */
@@ -55,6 +61,9 @@ struct SPFilter : public SPObject {
int _primitive_table_size;
SPFilterPrimitive ** _primitives;
NR::Filter *_renderer;
+
+ std::map<gchar *, int, ltstr> _image_name;
+ int _image_number_next;
};
struct SPFilterClass {
@@ -72,6 +81,9 @@ void sp_filter_build_renderer(SPFilter *sp_filter, NR::Filter *nr_filter);
*/
int sp_filter_primitive_count(SPFilter *filter);
+int sp_filter_get_image_name(SPFilter *filter, gchar const *name);
+int sp_filter_set_image_name(SPFilter *filter, gchar const *name);
+
#endif /* !SP_FILTER_H_SEEN */
/*