diff options
| author | Felipe Corr??a da Silva Sanches <juca@members.fsf.org> | 2007-08-09 05:06:49 +0000 |
|---|---|---|
| committer | jucablues <jucablues@users.sourceforge.net> | 2007-08-09 05:06:49 +0000 |
| commit | c3fbe67f54e1998fe76ee14dc38a3f192c62b780 (patch) | |
| tree | ee88335d5afd796c08ac3064f76d91782b8b5b0d /src | |
| parent | 2006-08-09 Michael Wybrow <mjwybrow@users.sourceforge.net> (diff) | |
| download | inkscape-c3fbe67f54e1998fe76ee14dc38a3f192c62b780.tar.gz inkscape-c3fbe67f54e1998fe76ee14dc38a3f192c62b780.zip | |
feMorphology filter primitive implementation
(bzr r3432)
Diffstat (limited to 'src')
| -rw-r--r-- | src/display/nr-filter-morphology.cpp | 65 | ||||
| -rw-r--r-- | src/display/nr-filter-morphology.h | 13 | ||||
| -rw-r--r-- | src/sp-femorphology.cpp | 47 | ||||
| -rw-r--r-- | src/sp-femorphology.h | 5 |
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 { |
