3a2895ec61d45485a489ce330a2a31da7df77f1c
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;
107 }
109 int FilterSlot::get_slot_count()
110 {
111 int seek = _slot_count;
112 do {
113 seek--;
114 } while (_slot[seek] == NULL);
116 return seek + 1;
117 }
119 int FilterSlot::_get_index(int slot_nr)
120 {
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;
171 }
173 }
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 :