Code

3a2895ec61d45485a489ce330a2a31da7df77f1c
[inkscape.git] / src / display / nr-filter-slot.cpp
1 #define __NR_FILTER_SLOT_CPP__
3 /*
4  * A container class for filter slots. Allows for simple getting and
5  * setting images in filter slots without having to bother with
6  * table indexes and such.
7  *
8  * Author:
9  *   Niko Kiirala <niko@kiirala.com>
10  *
11  * Copyright (C) 2006 Niko Kiirala
12  *
13  * Released under GNU GPL, read the file 'COPYING' for more information
14  */
16 #include <assert.h>
18 #include "display/nr-arena-item.h"
19 #include "libnr/nr-pixblock.h"
20 #include "display/nr-filter-types.h"
21 #include "display/nr-filter-slot.h"
23 namespace NR {
25 FilterSlot::FilterSlot(int slots, NRArenaItem const *item)
26 {
27     _slot_count = ((slots > 0) ? slots : 2);
28     _slot = new NRPixBlock*[_slot_count];
29     _slot_number = new int[_slot_count];
31     for (int i = 0 ; i < _slot_count ; i++) {
32         _slot[i] = NULL;
33         _slot_number[i] = NR_FILTER_SLOT_NOT_SET;
34     }
36     _last_out = -1;
38     _arena_item = item;
39 }
41 FilterSlot::~FilterSlot()
42 {
43     for (int i = 0 ; i < _slot_count ; i++) {
44         if (_slot[i]) {
45             nr_pixblock_release(_slot[i]);
46             delete _slot[i];
47         }
48     }
49     delete[] _slot;
50     delete[] _slot_number;
51 }
53 NRPixBlock *FilterSlot::get(int slot_nr)
54 {
55     int index = _get_index(slot_nr);
56     assert(index >= 0);
58     /* If we didn't have the specified image, but we could create it
59      * from the other information we have, let's do that */
60     if (_slot[index] == NULL
61         && (slot_nr == NR_FILTER_SOURCEALPHA
62             || slot_nr == NR_FILTER_BACKGROUNDIMAGE
63             || slot_nr == NR_FILTER_BACKGROUNDALPHA
64             || slot_nr == NR_FILTER_FILLPAINT
65             || slot_nr == NR_FILTER_SOURCEPAINT))
66     {
67         /* If needed, fetch background */
68         if (slot_nr == NR_FILTER_BACKGROUNDIMAGE
69             || slot_nr == NR_FILTER_BACKGROUNDALPHA)
70         {
71             NRPixBlock *pb;
72             pb = nr_arena_item_get_background(_arena_item);
73             this->set(NR_FILTER_BACKGROUNDIMAGE, pb);
74         }
75         /* If only a alpha channel is needed, strip it from full image */
76         if (slot_nr == NR_FILTER_SOURCEALPHA) {
77             // TODO
78         }
79         if (slot_nr == NR_FILTER_BACKGROUNDALPHA) {
80             // TODO
81         }
82         /* When a paint is needed, fetch it from arena item */
83         if (slot_nr == NR_FILTER_FILLPAINT) {
84             // TODO
85         }
86         if (slot_nr == NR_FILTER_SOURCEPAINT) {
87             // TODO
88         }
89     }
91     assert(slot_nr == NR_FILTER_SLOT_NOT_SET ||_slot_number[index] == slot_nr);
92     return _slot[index];
93 }
95 void FilterSlot::set(int slot_nr, NRPixBlock *pb)
96 {
97     int index = _get_index(slot_nr);
98     assert(index >= 0);
99     assert(slot_nr == NR_FILTER_SLOT_NOT_SET ||_slot_number[index] == slot_nr);
101     if(_slot[index]) {
102         nr_pixblock_release(_slot[index]);
103         delete _slot[index];
104     }
105     _slot[index] = pb;
106     _last_out = index;
109 int FilterSlot::get_slot_count()
111     int seek = _slot_count;
112     do {
113         seek--;
114     } while (_slot[seek] == NULL);
115     
116     return seek + 1;
119 int FilterSlot::_get_index(int slot_nr)
121     assert(slot_nr >= 0 ||
122            slot_nr == NR_FILTER_SLOT_NOT_SET ||
123            slot_nr == NR_FILTER_SOURCEGRAPHIC ||
124            slot_nr == NR_FILTER_SOURCEALPHA ||
125            slot_nr == NR_FILTER_BACKGROUNDIMAGE ||
126            slot_nr == NR_FILTER_BACKGROUNDALPHA ||
127            slot_nr == NR_FILTER_FILLPAINT ||
128            slot_nr == NR_FILTER_SOURCEPAINT);
130     int index = -1;
131     if (slot_nr == NR_FILTER_SLOT_NOT_SET) {
132         return _last_out;
133     }
134     /* Search, if the slot already exists */
135     for (int i = 0 ; i < _slot_count ; i++) {
136         if (_slot_number[i] == slot_nr) {
137             index = i;
138             break;
139         }
140     }
142     /* If the slot doesn't already exist, create it */
143     if (index == -1) {
144         int seek = _slot_count;
145         do {
146             seek--;
147         } while (_slot[seek] == NULL && seek > 0);
148         /* If there is no space for more slots, create more space */
149         if (seek == _slot_count - 1) {
150             NRPixBlock **new_slot = new NRPixBlock*[_slot_count * 2];
151             int *new_number = new int[_slot_count * 2];
152             for (int i = 0 ; i < _slot_count ; i++) {
153                 new_slot[i] = _slot[i];
154                 new_number[i] = _slot_number[i];
155             }
156             for (int i = _slot_count ; i < _slot_count * 2 ; i++) {
157                 new_slot[i] = NULL;
158                 new_number[i] = NR_FILTER_SLOT_NOT_SET;
159             }
160             delete[] _slot;
161             delete[] _slot_number;
162             _slot = new_slot;
163             _slot_number = new_number;
164             _slot_count *= 2;
165         }
166         /* Now that there is space, create the slot */
167         _slot_number[seek + 1] = slot_nr;
168         index = seek + 1;
169     }
170     return index;
175 /*
176   Local Variables:
177   mode:c++
178   c-file-style:"stroustrup"
179   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
180   indent-tabs-mode:nil
181   fill-column:99
182   End:
183 */
184 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :