From 26fe967f30c5b0de45897a858d1ae09dff7c0ea7 Mon Sep 17 00:00:00 2001 From: kiirala Date: Tue, 4 Jul 2006 14:05:32 +0000 Subject: [PATCH] Created NR::FilterSlot to handle pixblocks in rendering filters --- doc/nr-filter-interface.txt | 2 +- src/display/Makefile_insert | 5 +- src/display/nr-filter-gaussian.cpp | 9 +- src/display/nr-filter-gaussian.h | 3 +- src/display/nr-filter-primitive.cpp | 6 +- src/display/nr-filter-primitive.h | 5 +- src/display/nr-filter-slot.cpp | 160 ++++++++++++++++++++++++++++ src/display/nr-filter-slot.h | 54 ++++++++++ src/display/nr-filter-types.h | 2 +- src/display/nr-filter.cpp | 31 +++--- 10 files changed, 251 insertions(+), 26 deletions(-) create mode 100644 src/display/nr-filter-slot.cpp create mode 100644 src/display/nr-filter-slot.h diff --git a/doc/nr-filter-interface.txt b/doc/nr-filter-interface.txt index d5eb84a52..6065333fe 100644 --- a/doc/nr-filter-interface.txt +++ b/doc/nr-filter-interface.txt @@ -84,7 +84,7 @@ Constant name Corresponding SVG input name NR_FILTER_SOURCEGRAPHIC SourceGraphic NR_FILTER_SOURCEALPHA SourceAlpha NR_FILTER_BACKGROUNDIMAGE BackgroundImage -NR_FILTER_BACKGROUNDAPLHA BackgroundAlpha +NR_FILTER_BACKGROUNDALPHA BackgroundAlpha NR_FILTER_FILLPAINT FillPaint NR_FILTER_SOURCEPAINT SourcePaint (defined in display/nr-filter-types.h) diff --git a/src/display/Makefile_insert b/src/display/Makefile_insert index 5aec6894f..f19ced220 100644 --- a/src/display/Makefile_insert +++ b/src/display/Makefile_insert @@ -66,7 +66,10 @@ display_libspdisplay_a_SOURCES = \ display/nr-filter-primitive.cpp \ display/nr-filter-primitive.h \ display/nr-filter-gaussian.cpp \ - display/nr-filter-gaussian.h + display/nr-filter-gaussian.h \ + display/nr-filter-slot.cpp \ + display/nr-filter-slot.h \ + display/nr-filter-types.h display_bezier_utils_test_SOURCES = display/bezier-utils-test.cpp display_bezier_utils_test_LDADD = libnr/libnr.a -lglib-2.0 diff --git a/src/display/nr-filter-gaussian.cpp b/src/display/nr-filter-gaussian.cpp index d8cb84a02..ee1fd7d99 100644 --- a/src/display/nr-filter-gaussian.cpp +++ b/src/display/nr-filter-gaussian.cpp @@ -18,6 +18,7 @@ using std::isnormal; #include "display/nr-filter-primitive.h" #include "display/nr-filter-gaussian.h" +#include "display/nr-filter-types.h" #include "libnr/nr-pixblock.h" #include "libnr/nr-matrix.h" #include "prefs-utils.h" @@ -136,10 +137,10 @@ inline void _check_index(NRPixBlock const * const pb, int const location, int co } } -int FilterGaussian::render(NRPixBlock **pb, Matrix const &trans) +int FilterGaussian::render(FilterSlot &slot, Matrix const &trans) { /* in holds the input pixblock */ - NRPixBlock *in = pb[0]; + NRPixBlock *in = slot.get(_input); /* If to either direction, the standard deviation is zero, a transparent * black image should be returned */ @@ -148,7 +149,7 @@ int FilterGaussian::render(NRPixBlock **pb, Matrix const &trans) nr_pixblock_setup_fast(out, in->mode, in->area.x0, in->area.y0, in->area.x1, in->area.y1, true); out->empty = false; - pb[1] = out; + slot.set(_output, out); return 0; } @@ -397,7 +398,7 @@ int FilterGaussian::render(NRPixBlock **pb, Matrix const &trans) delete bufy; out->empty = FALSE; - pb[1] = out; + slot.set(_output, out); return 0; } diff --git a/src/display/nr-filter-gaussian.h b/src/display/nr-filter-gaussian.h index c3bf398c9..07ee2392b 100644 --- a/src/display/nr-filter-gaussian.h +++ b/src/display/nr-filter-gaussian.h @@ -13,6 +13,7 @@ */ #include "display/nr-filter-primitive.h" +#include "display/nr-filter-slot.h" #include "libnr/nr-pixblock.h" #include "libnr/nr-matrix.h" @@ -24,7 +25,7 @@ public: static FilterPrimitive *create(); virtual ~FilterGaussian(); - virtual int render(NRPixBlock **pb, Matrix const &trans); + virtual int render(FilterSlot &slot, Matrix const &trans); virtual int get_enlarge(Matrix const &m); /** diff --git a/src/display/nr-filter-primitive.cpp b/src/display/nr-filter-primitive.cpp index e69a499d4..f45f909f6 100644 --- a/src/display/nr-filter-primitive.cpp +++ b/src/display/nr-filter-primitive.cpp @@ -34,13 +34,13 @@ FilterPrimitive::~FilterPrimitive() // Nothing to do here } -int FilterPrimitive::render(NRPixBlock **pb, NRMatrix const *trans) { +int FilterPrimitive::render(FilterSlot &slot, NRMatrix const *trans) { if(trans) { - return this->render(pb, *trans); + return this->render(slot, *trans); } else { Matrix tmp; tmp.set_identity(); - return this->render(pb, tmp); + return this->render(slot, tmp); } } diff --git a/src/display/nr-filter-primitive.h b/src/display/nr-filter-primitive.h index 64625f4c2..7c8018fe2 100644 --- a/src/display/nr-filter-primitive.h +++ b/src/display/nr-filter-primitive.h @@ -12,6 +12,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include "display/nr-filter-slot.h" #include "libnr/nr-pixblock.h" #include "libnr/nr-matrix.h" #include "svg/svg-length.h" @@ -23,8 +24,8 @@ public: FilterPrimitive(); virtual ~FilterPrimitive(); - int render(NRPixBlock **pb, NRMatrix const *trans); - virtual int render(NRPixBlock **pb, Matrix const &trans) = 0; + int render(FilterSlot &slot, NRMatrix const *trans); + virtual int render(FilterSlot &slot, Matrix const &trans) = 0; virtual int get_enlarge(Matrix const &m); /** diff --git a/src/display/nr-filter-slot.cpp b/src/display/nr-filter-slot.cpp new file mode 100644 index 000000000..6072e7993 --- /dev/null +++ b/src/display/nr-filter-slot.cpp @@ -0,0 +1,160 @@ +#define __NR_FILTER_SLOT_CPP__ + +/* + * A container class for filter slots. Allows for simple getting and + * setting images in filter slots without having to bother with + * table indexes and such. + * + * Author: + * Niko Kiirala + * + * Copyright (C) 2006 Niko Kiirala + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include "libnr/nr-pixblock.h" +#include "display/nr-filter-types.h" +#include "display/nr-filter-slot.h" + +namespace NR { + +FilterSlot::FilterSlot() +{ + _slot_count = 2; + _slot = new NRPixBlock*[_slot_count]; + _slot_number = new int[_slot_count]; + + for (int i = 0 ; i < _slot_count ; i++) { + _slot[i] = NULL; + _slot_number[i] = NR_FILTER_SLOT_NOT_SET; + } + + _last_out = -1; +} + +FilterSlot::FilterSlot(int slots) +{ + _slot_count = slots; + _slot = new NRPixBlock*[_slot_count]; + _slot_number = new int[_slot_count]; + + for (int i = 0 ; i < _slot_count ; i++) { + _slot[i] = NULL; + _slot_number[i] = NR_FILTER_SLOT_NOT_SET; + } + + _last_out = -1; +} + +FilterSlot::~FilterSlot() +{ + for (int i = 0 ; i < _slot_count ; i++) { + if (_slot[i]) { + nr_pixblock_release(_slot[i]); + delete _slot[i]; + } + } + delete[] _slot; + delete[] _slot_number; +} + +NRPixBlock *FilterSlot::get(int slot_nr) +{ + int index = _get_index(slot_nr); + assert(index >= 0); + assert(slot_nr == NR_FILTER_SLOT_NOT_SET ||_slot_number[index] == slot_nr); + return _slot[index]; +} + +void FilterSlot::set(int slot_nr, NRPixBlock *pb) +{ + int index = _get_index(slot_nr); + assert(index >= 0); + assert(slot_nr == NR_FILTER_SLOT_NOT_SET ||_slot_number[index] == slot_nr); + + if(_slot[index]) { + nr_pixblock_release(_slot[index]); + delete _slot[index]; + } + _slot[index] = pb; + _last_out = index; +} + +int FilterSlot::get_slot_count() +{ + int seek = _slot_count; + do { + seek--; + } while (_slot[seek] == NULL); + + return seek + 1; +} + +int FilterSlot::_get_index(int slot_nr) +{ + assert(slot_nr >= 0 || + slot_nr == NR_FILTER_SLOT_NOT_SET || + slot_nr == NR_FILTER_SOURCEGRAPHIC || + slot_nr == NR_FILTER_SOURCEALPHA || + slot_nr == NR_FILTER_BACKGROUNDIMAGE || + slot_nr == NR_FILTER_BACKGROUNDALPHA || + slot_nr == NR_FILTER_FILLPAINT || + slot_nr == NR_FILTER_SOURCEPAINT); + + int index = -1; + if (slot_nr == NR_FILTER_SLOT_NOT_SET) { + return _last_out; + } + /* Search, if the slot already exists */ + for (int i = 0 ; i < _slot_count ; i++) { + if (_slot_number[i] == slot_nr) { + index = i; + break; + } + } + + /* If the slot doesn't already exist, create it */ + if (index == -1) { + int seek = _slot_count; + do { + seek--; + } while (_slot[seek] == NULL); + /* If there is no space for more slots, create more space */ + if (seek == _slot_count - 1) { + NRPixBlock **new_slot = new NRPixBlock*[_slot_count * 2]; + int *new_number = new int[_slot_count * 2]; + for (int i = 0 ; i < _slot_count ; i++) { + new_slot[i] = _slot[i]; + new_number[i] = _slot_number[i]; + } + for (int i = _slot_count ; i < _slot_count * 2 ; i++) { + _slot[i] = NULL; + _slot_number[i] = NR_FILTER_SLOT_NOT_SET; + } + delete[] _slot; + delete[] _slot_number; + _slot = new_slot; + _slot_number = new_number; + _slot_count *= 2; + } + /* Now that there is space, create the slot */ + _slot_number[seek + 1] = slot_nr; + index = seek + 1; + } + return index; +} + +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/display/nr-filter-slot.h b/src/display/nr-filter-slot.h new file mode 100644 index 000000000..74cf7e003 --- /dev/null +++ b/src/display/nr-filter-slot.h @@ -0,0 +1,54 @@ +#ifndef __NR_FILTER_SLOT_H__ +#define __NR_FILTER_SLOT_H__ + +/* + * A container class for filter slots. Allows for simple getting and + * setting images in filter slots without having to bother with + * table indexes and such. + * + * Author: + * Niko Kiirala + * + * Copyright (C) 2006 Niko Kiirala + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "libnr/nr-pixblock.h" + +namespace NR { + +class FilterSlot { +public: + FilterSlot(); + FilterSlot(int slots); + ~FilterSlot(); + + NRPixBlock *get(int slot); + void set(int slot, NRPixBlock *pb); + + int get_slot_count(); + +private: + NRPixBlock **_slot; + int *_slot_number; + int _slot_count; + + int _last_out; + + int _get_index(int slot); +}; + +} + +#endif // __NR_FILTER_SLOT_H__ +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/display/nr-filter-types.h b/src/display/nr-filter-types.h index a6f539d03..3eebe3731 100644 --- a/src/display/nr-filter-types.h +++ b/src/display/nr-filter-types.h @@ -29,7 +29,7 @@ enum { NR_FILTER_SOURCEGRAPHIC = -2, NR_FILTER_SOURCEALPHA = -3, NR_FILTER_BACKGROUNDIMAGE = -4, - NR_FILTER_BACKGROUNDAPLHA = -5, + NR_FILTER_BACKGROUNDALPHA = -5, NR_FILTER_FILLPAINT = -6, NR_FILTER_SOURCEPAINT = -7 }; diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index 35f348389..7e558dd6c 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -14,6 +14,8 @@ #include "display/nr-filter.h" #include "display/nr-filter-primitive.h" #include "display/nr-filter-gaussian.h" +#include "display/nr-filter-slot.h" +#include "display/nr-filter-types.h" #include "display/nr-arena-item.h" #include "libnr/nr-pixblock.h" @@ -47,7 +49,7 @@ Filter::Filter(int n) void Filter::_common_init() { _slot_count = 1; - _output_slot = -1; + _output_slot = NR_FILTER_SLOT_NOT_SET; _region_x.set(SVGLength::PERCENT, -10, 0); _region_y.set(SVGLength::PERCENT, -10, 0); @@ -70,24 +72,27 @@ Filter::~Filter() int Filter::render(NRArenaItem const *item, NRPixBlock *pb) { - NRPixBlock *slot[2]; - slot[0] = pb; - slot[1] = NULL; + FilterSlot slot(_slot_count); + NRPixBlock *in = new NRPixBlock; + nr_pixblock_setup_fast(in, pb->mode, + pb->area.x0, pb->area.y0, + pb->area.x1, pb->area.y1, true); + nr_blit_pixblock_pixblock(in, pb); + slot.set(NR_FILTER_SOURCEGRAPHIC, in); + in = NULL; // in is now handled by FilterSlot, we should not touch it _primitive[0]->render(slot, *item->ctm); + NRPixBlock *out = slot.get(_output_slot); - int size = (slot[0]->area.x1 - slot[0]->area.x0) - * (slot[0]->area.y1 - slot[0]->area.y0) - * NR_PIXBLOCK_BPP(slot[0]); - memset(NR_PIXBLOCK_PX(slot[0]), 0, size); + int size = (pb->area.x1 - pb->area.x0) + * (pb->area.y1 - pb->area.y0) + * NR_PIXBLOCK_BPP(pb); + memset(NR_PIXBLOCK_PX(pb), 0, size); - nr_blit_pixblock_pixblock(slot[0], slot[1]); - - slot[0]->visible_area = slot[0]->area; - - nr_pixblock_release(slot[1]); + nr_blit_pixblock_pixblock(pb, out); + _slot_count = slot.get_slot_count(); return 0; } -- 2.39.5