summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFelipe Corr??a da Silva Sanches <juca@members.fsf.org>2007-08-09 05:06:49 +0000
committerjucablues <jucablues@users.sourceforge.net>2007-08-09 05:06:49 +0000
commitc3fbe67f54e1998fe76ee14dc38a3f192c62b780 (patch)
treeee88335d5afd796c08ac3064f76d91782b8b5b0d /src
parent2006-08-09 Michael Wybrow <mjwybrow@users.sourceforge.net> (diff)
downloadinkscape-c3fbe67f54e1998fe76ee14dc38a3f192c62b780.tar.gz
inkscape-c3fbe67f54e1998fe76ee14dc38a3f192c62b780.zip
feMorphology filter primitive implementation
(bzr r3432)
Diffstat (limited to 'src')
-rw-r--r--src/display/nr-filter-morphology.cpp65
-rw-r--r--src/display/nr-filter-morphology.h13
-rw-r--r--src/sp-femorphology.cpp47
-rw-r--r--src/sp-femorphology.h5
4 files changed, 117 insertions, 13 deletions
diff --git a/src/display/nr-filter-morphology.cpp b/src/display/nr-filter-morphology.cpp
index 9660d61ef..bbf26c87c 100644
--- a/src/display/nr-filter-morphology.cpp
+++ b/src/display/nr-filter-morphology.cpp
@@ -14,7 +14,6 @@ namespace NR {
FilterMorphology::FilterMorphology()
{
- g_warning("FilterMorphology::render not implemented.");
}
FilterPrimitive * FilterMorphology::create() {
@@ -28,15 +27,53 @@ int FilterMorphology::render(FilterSlot &slot, Matrix const &trans) {
NRPixBlock *in = slot.get(_input);
NRPixBlock *out = new NRPixBlock;
- nr_pixblock_setup_fast(out, in->mode,
- in->area.x0, in->area.y0, in->area.x1, in->area.y1,
- true);
+ int x0=in->area.x0;
+ int y0=in->area.y0;
+ int x1=in->area.x1;
+ int y1=in->area.y1;
+ int w=x1-x0, h=y1-y0;
+ int x,y,i,j;
+ int rmax,gmax,bmax,amax;
+ int rmin,gmin,bmin,amin;
+
+ nr_pixblock_setup_fast(out, in->mode, x0, y0, x1, y1, true);
unsigned char *in_data = NR_PIXBLOCK_PX(in);
unsigned char *out_data = NR_PIXBLOCK_PX(out);
-//IMPLEMENT ME!
-
+ for(x=xradius; x<w-xradius; x++){
+ for(y=yradius; y<h-yradius; y++){
+ rmin=rmax=in_data[4*(x + w*y)];
+ gmin=gmax=in_data[4*(x + w*y)+1];
+ bmin=bmax=in_data[4*(x + w*y)+2];
+ amin=amax=in_data[4*(x + w*y)+3];
+ for(i=x-xradius;i<x+xradius;i++){
+ for(j=y-yradius;j<y+yradius;j++){
+ if(in_data[4*(i + w*j)]>rmax) rmax = in_data[4*(i + w*j)];
+ if(in_data[4*(i + w*j)+1]>gmax) gmax = in_data[4*(i + w*j)+1];
+ if(in_data[4*(i + w*j)+2]>bmax) bmax = in_data[4*(i + w*j)+2];
+ if(in_data[4*(i + w*j)+3]>amax) amax = in_data[4*(i + w*j)+3];
+
+ if(in_data[4*(i + w*j)]<rmin) rmin = in_data[4*(i + w*j)];
+ if(in_data[4*(i + w*j)+1]<gmin) gmin = in_data[4*(i + w*j)+1];
+ if(in_data[4*(i + w*j)+2]<bmin) bmin = in_data[4*(i + w*j)+2];
+ if(in_data[4*(i + w*j)+3]<amin) amin = in_data[4*(i + w*j)+3];
+ }
+ }
+ if (Operator==MORPHOLOGY_OPERATOR_ERODE){
+ out_data[4*(x + w*y)]=rmax;
+ out_data[4*(x + w*y)+1]=gmax;
+ out_data[4*(x + w*y)+2]=bmax;
+ out_data[4*(x + w*y)+3]=amax;
+ } else {
+ out_data[4*(x + w*y)]=rmin;
+ out_data[4*(x + w*y)+1]=gmin;
+ out_data[4*(x + w*y)+2]=bmin;
+ out_data[4*(x + w*y)+3]=amin;
+ }
+ }
+ }
+
out->empty = FALSE;
slot.set(_output, out);
return 0;
@@ -44,6 +81,22 @@ int FilterMorphology::render(FilterSlot &slot, Matrix const &trans) {
void FilterMorphology::area_enlarge(NRRectL &area, Matrix const &trans)
{
+ area.x0-=xradius;
+ area.x1+=xradius;
+ area.y0-=yradius;
+ area.y1+=yradius;
+}
+
+void FilterMorphology::set_operator(FilterMorphologyOperator &o){
+ Operator = o;
+}
+
+void FilterMorphology::set_xradius(int x){
+ xradius = x;
+}
+
+void FilterMorphology::set_yradius(int y){
+ yradius = y;
}
} /* namespace NR */
diff --git a/src/display/nr-filter-morphology.h b/src/display/nr-filter-morphology.h
index 5f89688d0..be9ad2031 100644
--- a/src/display/nr-filter-morphology.h
+++ b/src/display/nr-filter-morphology.h
@@ -17,6 +17,11 @@
namespace NR {
+enum FilterMorphologyOperator {
+ MORPHOLOGY_OPERATOR_ERODE,
+ MORPHOLOGY_OPERATOR_DILATE
+};
+
class FilterMorphology : public FilterPrimitive {
public:
FilterMorphology();
@@ -25,6 +30,14 @@ public:
virtual int render(FilterSlot &slot, Matrix const &trans);
virtual void area_enlarge(NRRectL &area, Matrix const &trans);
+ void set_operator(FilterMorphologyOperator &o);
+ void set_xradius(int x);
+ void set_yradius(int y);
+
+private:
+ FilterMorphologyOperator Operator;
+ int xradius;
+ int yradius;
};
} /* namespace NR */
diff --git a/src/sp-femorphology.cpp b/src/sp-femorphology.cpp
index 980d77968..22c6de038 100644
--- a/src/sp-femorphology.cpp
+++ b/src/sp-femorphology.cpp
@@ -6,7 +6,8 @@
*/
/*
* Authors:
- * hugo Rodrigues <haa.rodrigues@gmail.com>
+ * Felipe Sanches <felipe.sanches@gmail.com>
+ * Hugo Rodrigues <haa.rodrigues@gmail.com>
*
* Copyright (C) 2006 Hugo Rodrigues
*
@@ -21,7 +22,7 @@
#include "svg/svg.h"
#include "sp-femorphology.h"
#include "xml/repr.h"
-
+#include "display/nr-filter-morphology.h"
/* FeMorphology base class */
@@ -77,6 +78,8 @@ sp_feMorphology_class_init(SPFeMorphologyClass *klass)
static void
sp_feMorphology_init(SPFeMorphology *feMorphology)
{
+ //Setting default values:
+ feMorphology->radius.set("0");
}
/**
@@ -92,6 +95,8 @@ sp_feMorphology_build(SPObject *object, SPDocument *document, Inkscape::XML::Nod
}
/*LOAD ATTRIBUTES FROM REPR HERE*/
+ sp_object_read_attr(object, "operator");
+ sp_object_read_attr(object, "radius");
}
/**
@@ -104,6 +109,19 @@ sp_feMorphology_release(SPObject *object)
((SPObjectClass *) feMorphology_parent_class)->release(object);
}
+static NR::FilterMorphologyOperator sp_feMorphology_read_operator(gchar const *value){
+ if (!value) return NR::MORPHOLOGY_OPERATOR_ERODE; //erode is default
+ switch(value[0]){
+ case 'e':
+ if (strncmp(value, "erode", 5) == 0) return NR::MORPHOLOGY_OPERATOR_ERODE;
+ break;
+ case 'd':
+ if (strncmp(value, "dilate", 6) == 0) return NR::MORPHOLOGY_OPERATOR_DILATE;
+ break;
+ }
+ return NR::MORPHOLOGY_OPERATOR_ERODE; //erode is default
+}
+
/**
* Sets a specific value in the SPFeMorphology.
*/
@@ -112,9 +130,24 @@ sp_feMorphology_set(SPObject *object, unsigned int key, gchar const *value)
{
SPFeMorphology *feMorphology = SP_FEMORPHOLOGY(object);
(void)feMorphology;
-
+
+ NR::FilterMorphologyOperator read_operator;
switch(key) {
- /*DEAL WITH SETTING ATTRIBUTES HERE*/
+ /*DEAL WITH SETTING ATTRIBUTES HERE*/
+ case SP_ATTR_OPERATOR:
+ read_operator = sp_feMorphology_read_operator(value);
+ if (read_operator != feMorphology->Operator){
+ feMorphology->Operator = read_operator;
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ }
+ break;
+ case SP_ATTR_RADIUS:
+ feMorphology->radius.set(value);
+ //From SVG spec: If <y-radius> is not provided, it defaults to <x-radius>.
+ if (feMorphology->radius.optNumIsSet() == false)
+ feMorphology->radius.setOptNumber(feMorphology->radius.getNumber());
+ object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
default:
if (((SPObjectClass *) feMorphology_parent_class)->set)
((SPObjectClass *) feMorphology_parent_class)->set(object, key, value);
@@ -175,7 +208,11 @@ static void sp_feMorphology_build_renderer(SPFilterPrimitive *primitive, NR::Fil
NR::FilterMorphology *nr_morphology = dynamic_cast<NR::FilterMorphology*>(nr_primitive);
g_assert(nr_morphology != NULL);
- sp_filter_primitive_renderer_common(primitive, nr_primitive);
+ sp_filter_primitive_renderer_common(primitive, nr_primitive);
+
+ nr_morphology->set_operator(sp_morphology->Operator);
+ nr_morphology->set_xradius( (int)sp_morphology->radius.getNumber() );
+ nr_morphology->set_yradius( (int)sp_morphology->radius.getOptNumber() );
}
/*
diff --git a/src/sp-femorphology.h b/src/sp-femorphology.h
index 11206b2da..1229c90d1 100644
--- a/src/sp-femorphology.h
+++ b/src/sp-femorphology.h
@@ -15,7 +15,7 @@
#include "sp-filter.h"
#include "sp-femorphology-fns.h"
-
+#include "number-opt-number.h"
#include "display/nr-filter.h"
#include "display/nr-filter-morphology.h"
@@ -25,7 +25,8 @@ class SPFeMorphologyClass;
struct SPFeMorphology : public SPFilterPrimitive {
/** MORPHOLOGY ATTRIBUTES HERE */
-
+ NR::FilterMorphologyOperator Operator;
+ NumberOptNumber radius;
};
struct SPFeMorphologyClass {