Code

Added support for in-parameter in filter primitives
authorkiirala <kiirala@users.sourceforge.net>
Tue, 29 May 2007 10:47:04 +0000 (10:47 +0000)
committerkiirala <kiirala@users.sourceforge.net>
Tue, 29 May 2007 10:47:04 +0000 (10:47 +0000)
12 files changed:
src/attributes.cpp
src/attributes.h
src/display/nr-filter-blend.cpp
src/display/nr-filter-slot.cpp
src/display/nr-filter-types.h
src/display/nr-filter.cpp
src/sp-feblend.cpp
src/sp-feblend.h
src/sp-filter-primitive.cpp
src/sp-filter-primitive.h
src/sp-filter.cpp
src/sp-filter.h

index 39f6a04f95491f0810beb8e0797944cfc7d861d3..a8cd2e83d0518185cf0fb9fb21e5e559afa649b7 100644 (file)
@@ -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"},
index 85eb00e38f1644f9511c780a66e04c48581c9c51..fa492d978d72e5725d50406705fc1d95bb651d5c 100644 (file)
@@ -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,
index 1468eb61bbd777a603d43e5a018a634d665ad2fa..0e2f965b7256cbe4ac0f0444cb929e4d184a1ac5 100644 (file)
 #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);
index 3a2895ec61d45485a489ce330a2a31da7df77f1c..673754f1855692e02dbceabe38c362e77ca75af3 100644 (file)
@@ -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) {
index 3eebe37319089edb341ae0073ba959d8779f1499..6f28c6257d7c40ff8924976b72e01581b19b1317 100644 (file)
@@ -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 */
index 515d5961f0d5a578f88e67b8114f36ebac30091e..d8cfb2ecf2c98261d06f08b0ee71cdd07f7d627f 100644 (file)
@@ -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) {
index 49ab18a25fcf7c25343d01f8e90d9e797a6c085a..bedbf4f610710da3f9d29048693d1544997d40e6 100644 (file)
@@ -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);
 }
 
 /*
index 90ab8967f589dd05a7eeacd92db593464cffc70c..f6f71b892df50f3a9779ea5c2f36729bba9a75f9 100644 (file)
@@ -25,6 +25,7 @@ class SPFeBlendClass;
 struct SPFeBlend : public SPFilterPrimitive {
     /** BLEND ATTRIBUTES HERE */
     NR::FilterBlendMode blend_mode;
+    int in2;
 };
 
 struct SPFeBlendClass {
index f799dbe5432c4a8ebee7e3d4cfa173a926d9833b..cd8c53c653b88255356fe30329a8e7b12e4a9766 100644 (file)
@@ -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. */
 }
 
index 96268dbfe9da631dae61a7f888f9928f201ffe05..6f6558c5ccbe65a5b5de1f4e79d852a5d2ca314a 100644 (file)
@@ -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:
index ac0d3d29ec53f4aabc1abc6b379eb94aaea40c35..43f2dc9d22eb31bd598987566eb3acb1e9e32c6e 100644 (file)
 # 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++
index 06b46ecc6d087a804a3f3e6cb993805ea6262f6f..55e3eaa0ad5228a48ba78a7a38472bcda2d050e2 100644 (file)
@@ -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 */
 
 /*