summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: a61f230)
raw | patch | inline | side by side (parent: a61f230)
author | kiirala <kiirala@users.sourceforge.net> | |
Wed, 26 Jul 2006 17:31:16 +0000 (17:31 +0000) | ||
committer | kiirala <kiirala@users.sourceforge.net> | |
Wed, 26 Jul 2006 17:31:16 +0000 (17:31 +0000) |
index 9657715ea72a874c8b7303952429e590e63eaac9..b4cc3930b1a5ad4807ee79bf040065c976801a35 100644 (file)
if (style && style->filter.set && style->filter.filter) {
group->filter = new NR::Filter();
}
+
+ if (style && style->enable_background.set
+ && style->enable_background.value == SP_CSS_BACKGROUND_NEW) {
+ group->background_new = true;
+ }
}
static unsigned int
index 57413ef227740b750e756026a2429c061726b3b6..7e03c51dd2cf10506c738fe52d698255485e0163 100644 (file)
item->px = NULL;
item->data = NULL;
item->filter = NULL;
+ item->background_pb = NULL;
+ item->background_new = false;
}
static void
@@ -552,11 +554,21 @@ unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area,
#endif
} else {
/* Determine, whether we need temporary buffer */
- if (item->clip || item->mask || ((item->opacity != 255) && !item->render_opacity && item->arena->rendermode != RENDERMODE_OUTLINE) || item->filter) {
+ if (item->clip || item->mask
+ || ((item->opacity != 255) && !item->render_opacity && item->arena->rendermode != RENDERMODE_OUTLINE)
+ || item->filter || item->background_new
+ || (item->parent && item->parent->background_pb) )
+ {
NRPixBlock ipb, mpb;
/* Setup and render item buffer */
nr_pixblock_setup_fast (&ipb, NR_PIXBLOCK_MODE_R8G8B8A8P, carea.x0, carea.y0, carea.x1, carea.y1, TRUE);
+ /* If background access is used, save the pixblock address.
+ * This address is set to NULL at the end of this block */
+ if (item->background_new
+ || (item->parent && item->parent->background_pb)) {
+ item->background_pb = &ipb;
+ }
ipb.visible_area = pb->visible_area;
state = NR_ARENA_ITEM_VIRTUAL (item, render) (item, &carea, &ipb, flags);
if (state & NR_ARENA_ITEM_STATE_INVALID) {
@@ -568,7 +580,7 @@ unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area,
}
ipb.empty = FALSE;
- /* Run filtering test, if a filter is set for this object */
+ /* Run filtering, if a filter is set for this object */
if(item->filter) {
item->filter->render(item, &ipb);
}
@@ -656,6 +668,8 @@ unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area,
/* Compose rendering pixblock int destination */
nr_blit_pixblock_pixblock_mask (dpb, &ipb, &mpb);
nr_pixblock_release (&mpb);
+ /* This pointer wouldn't be valid outside this block, so clear it */
+ item->background_pb = NULL;
} else {
/* Opacity only */
nr_blit_pixblock_pixblock_alpha (dpb, &ipb, item->opacity);
nr_arena_item_set_child_position (item->parent, item, ref);
}
+/** Returns a background image for use with filter effects. */
+NRPixBlock *nr_arena_item_get_background (NRArenaItem const *item, int depth)
+{
+ NRPixBlock *pb;
+ if (!item->background_pb) return NULL;
+ if (item->background_new) {
+ pb = new NRPixBlock();
+ nr_pixblock_setup_fast(pb, item->background_pb->mode,
+ item->background_pb->area.x0,
+ item->background_pb->area.y0,
+ item->background_pb->area.x1,
+ item->background_pb->area.y1, true);
+ } else if (item->parent) {
+ pb = nr_arena_item_get_background(item->parent, depth + 1);
+ } else return NULL;
+
+ if (depth > 0)
+ nr_blit_pixblock_pixblock(pb, item->background_pb);
+
+ return pb;
+}
+
/* Helpers */
NRArenaItem *
index d38e44929269d10ee78d139052b68e363b4f7c49..52408d1547f09892879ad9aa28e652e191c37f89 100644 (file)
/* Current Transformation Matrix */
NR::Matrix ctm;
+ /* These hold background buffer state for filter rendering */
+ NRPixBlock *background_pb;
+ bool background_new;
+
void init(NRArena *arena) {
this->arena = arena;
}
void nr_arena_item_set_mask (NRArenaItem *item, NRArenaItem *mask);
void nr_arena_item_set_order (NRArenaItem *item, int order);
+NRPixBlock *nr_arena_item_get_background (NRArenaItem const *item, int depth = 0);
+
/* Helpers */
NRArenaItem *nr_arena_item_attach (NRArenaItem *parent, NRArenaItem *child, NRArenaItem *prev, NRArenaItem *next);
index ad94bd0da875f73cbb9f13d54b323bab4db58e73..e2edcd0b843d7f45f295a91f6c1bc2686d049061 100644 (file)
FilterGaussian::FilterGaussian()
{
- _deviation_x = _deviation_y = prefs_get_double_attribute("options.filtertest", "value", 0.0);
+ _deviation_x = _deviation_y = prefs_get_double_attribute("options.filtertest", "value", 1.0);
}
FilterPrimitive *FilterGaussian::create()
/* in holds the input pixblock */
NRPixBlock *in = slot.get(_input);
- /* If to either direction, the standard deviation is zero, a transparent
- * black image should be returned */
- if (_deviation_x <= 0 || _deviation_y <= 0) {
+ /* If to either direction, the standard deviation is zero or
+ * input image is not defined,
+ * a transparent black image should be returned. */
+ if (_deviation_x <= 0 || _deviation_y <= 0 || in == NULL) {
NRPixBlock *out = new NRPixBlock;
+ if (in == NULL) {
+ // A bit guessing here, but source graphic is likely to be of
+ // right size
+ in = slot.get(NR_FILTER_SOURCEGRAPHIC);
+ }
nr_pixblock_setup_fast(out, in->mode, in->area.x0, in->area.y0,
in->area.x1, in->area.y1, true);
out->empty = false;
index 9ea721d3beb44ad3313abba7b3fc5adea2c1d12a..890cb96fe7ad81399c9c7a0422a24272373fc7a1 100644 (file)
}
void FilterPrimitive::set_input(int input, int slot) {
- if (slot == 0) _input = slot;
+ if (input == 0) _input = slot;
}
void FilterPrimitive::set_output(int slot) {
index 6072e7993b30891f126ff230aafcc073b172434c..3a2895ec61d45485a489ce330a2a31da7df77f1c 100644 (file)
*/
#include <assert.h>
+
+#include "display/nr-arena-item.h"
#include "libnr/nr-pixblock.h"
#include "display/nr-filter-types.h"
#include "display/nr-filter-slot.h"
namespace NR {
-FilterSlot::FilterSlot()
+FilterSlot::FilterSlot(int slots, NRArenaItem const *item)
{
- _slot_count = 2;
+ _slot_count = ((slots > 0) ? slots : 2);
_slot = new NRPixBlock*[_slot_count];
_slot_number = new int[_slot_count];
}
_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;
+ _arena_item = item;
}
FilterSlot::~FilterSlot()
{
int index = _get_index(slot_nr);
assert(index >= 0);
+
+ /* If we didn't have the specified image, but we could create it
+ * from the other information we have, let's do that */
+ if (_slot[index] == NULL
+ && (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))
+ {
+ /* If needed, fetch background */
+ if (slot_nr == NR_FILTER_BACKGROUNDIMAGE
+ || slot_nr == NR_FILTER_BACKGROUNDALPHA)
+ {
+ NRPixBlock *pb;
+ pb = nr_arena_item_get_background(_arena_item);
+ this->set(NR_FILTER_BACKGROUNDIMAGE, pb);
+ }
+ /* If only a alpha channel is needed, strip it from full image */
+ if (slot_nr == NR_FILTER_SOURCEALPHA) {
+ // TODO
+ }
+ if (slot_nr == NR_FILTER_BACKGROUNDALPHA) {
+ // TODO
+ }
+ /* When a paint is needed, fetch it from arena item */
+ if (slot_nr == NR_FILTER_FILLPAINT) {
+ // TODO
+ }
+ if (slot_nr == NR_FILTER_SOURCEPAINT) {
+ // TODO
+ }
+ }
+
assert(slot_nr == NR_FILTER_SLOT_NOT_SET ||_slot_number[index] == slot_nr);
return _slot[index];
}
int seek = _slot_count;
do {
seek--;
- } while (_slot[seek] == NULL);
+ } while (_slot[seek] == NULL && seek > 0);
/* If there is no space for more slots, create more space */
if (seek == _slot_count - 1) {
NRPixBlock **new_slot = new NRPixBlock*[_slot_count * 2];
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;
+ new_slot[i] = NULL;
+ new_number[i] = NR_FILTER_SLOT_NOT_SET;
}
delete[] _slot;
delete[] _slot_number;
index 13ce1afe20fff919619db5fc2b9d8ac4d2f97826..09190a9b0a105502d76df79a27d76aaea9f26dfc 100644 (file)
#include "libnr/nr-pixblock.h"
+struct NRArenaItem;
+
namespace NR {
class FilterSlot {
public:
- /** Creates a new FilterSlot object, with two slots. */
- FilterSlot();
- /** Creates a new FilterSlot object, with specified amount of slots */
- FilterSlot(int slots);
+ /** Creates a new FilterSlot object.
+ * First parameter specifies the amount of slots this SilterSlot
+ * should reserve beforehand. If a negative number is given,
+ * two slots will be reserved.
+ * Second parameter specifies the arena item, which should be used
+ * for background accesses from filters.
+ */
+ FilterSlot(int slots, NRArenaItem const *item);
/** Destroys the FilterSlot object and all its contents */
~FilterSlot();
int _last_out;
- /** Returns the table index of given slot. If that slot dows not exist,
+ NRArenaItem const *_arena_item;
+
+ /** Returns the table index of given slot. If that slot does not exist,
* it is created. Table index can be used to read the correct
* pixblock from _slot */
int _get_index(int slot);
index db1e9d8db596df27c093c8ce74d83e165534365f..bda64c50ce232068fee2c966dd6dbb19738e6e4e 100644 (file)
int Filter::render(NRArenaItem const *item, NRPixBlock *pb)
{
Matrix trans = *item->ctm;
- FilterSlot slot(_slot_count);
+ FilterSlot slot(_slot_count, item);
NRPixBlock *in = new NRPixBlock;
// First, if filter resolution is not set to automatic, we should