Code

German translation update
[inkscape.git] / src / libnr / nr-blit.cpp
1 #define __NR_BLIT_C__
3 /*
4  * Pixel buffer rendering library
5  *
6  * Authors:
7  *   Lauris Kaplinski <lauris@kaplinski.com>
8  *
9  * This code is in public domain
10  */
12 #include "nr-pixops.h"
13 #include "nr-compose.h"
14 #include "nr-blit.h"
16 void
17 nr_blit_pixblock_pixblock_alpha (NRPixBlock *d, NRPixBlock *s, unsigned int alpha)
18 {
19         NRRectL clip;
20         unsigned char *dpx, *spx;
21         int dbpp, sbpp;
22         int w, h;
24         if (alpha == 0) return;
25         if (s->empty) return;
26         /* fixme: */
27         if (s->mode == NR_PIXBLOCK_MODE_A8) return;
28         /* fixme: */
29         if (s->mode == NR_PIXBLOCK_MODE_R8G8B8) return;
31         /*
32          * Possible variants as of now:
33          *
34          * 0. SRC EP - DST EP *
35          * 1. SRC EP - DST EN *
36          * 2. SRC EP - DST  P *
37          * 3. SRC EP - DST  N *
38          * 4. SRC EN - DST EP *
39          * 5. SRC EN - DST EN *
40          * 6. SRC EN - DST  P *
41          * 7. SRC EN - DST  N *
42          * 8. SRC  P - DST EP *
43          * 9. SRC  P - DST EN *
44          * A. SRC  P - DST  P *
45          * B. SRC  P - DST  N *
46          * C. SRC  N - DST EP *
47          * D. SRC  N - DST EN *
48          * E. SRC  N - DST  P *
49          * F. SRC  N - DST  N *
50          *
51          */
53         nr_rect_l_intersect (&clip, &d->area, &s->area);
55         if (nr_rect_l_test_empty(clip)) return;
57         /* Pointers */
58         dbpp = NR_PIXBLOCK_BPP (d);
59         dpx = NR_PIXBLOCK_PX (d) + (clip.y0 - d->area.y0) * d->rs + dbpp * (clip.x0 - d->area.x0);
60         sbpp = NR_PIXBLOCK_BPP (s);
61         spx = NR_PIXBLOCK_PX (s) + (clip.y0 - s->area.y0) * s->rs + sbpp * (clip.x0 - s->area.x0);
62         w = clip.x1 - clip.x0;
63         h = clip.y1 - clip.y0;
65         switch (d->mode) {
66         case NR_PIXBLOCK_MODE_A8:
67                 /* No rendering into alpha at moment */
68                 break;
69         case NR_PIXBLOCK_MODE_R8G8B8:
70                 if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
71                         nr_R8G8B8_R8G8B8_R8G8B8A8_P (dpx, w, h, d->rs, spx, s->rs, alpha);
72                 } else {
73                         nr_R8G8B8_R8G8B8_R8G8B8A8_N (dpx, w, h, d->rs, spx, s->rs, alpha);
74                 }
75                 break;
76         case NR_PIXBLOCK_MODE_R8G8B8A8P:
77                 if (d->empty) {
78                         if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
79                                 /* Case 8 */
80                                 nr_R8G8B8A8_P_EMPTY_R8G8B8A8_P (dpx, w, h, d->rs, spx, s->rs, alpha);
81                         } else {
82                                 /* Case C */
83                                 nr_R8G8B8A8_P_EMPTY_R8G8B8A8_N (dpx, w, h, d->rs, spx, s->rs, alpha);
84                         }
85                 } else {
86                         if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
87                                 /* case A */
88                                 nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P (dpx, w, h, d->rs, spx, s->rs, alpha);
89                         } else {
90                                 /* case E */
91                                 nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N (dpx, w, h, d->rs, spx, s->rs, alpha);
92                         }
93                 }
94                 break;
95         case NR_PIXBLOCK_MODE_R8G8B8A8N:
96                 if (d->empty) {
97                         if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
98                                 /* Case 9 */
99                                 nr_R8G8B8A8_N_EMPTY_R8G8B8A8_P (dpx, w, h, d->rs, spx, s->rs, alpha);
100                         } else {
101                                 /* Case D */
102                                 nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N (dpx, w, h, d->rs, spx, s->rs, alpha);
103                         }
104                 } else {
105                         if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
106                                 /* case B */
107                                 nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P (dpx, w, h, d->rs, spx, s->rs, alpha);
108                         } else {
109                                 /* case F */
110                                 nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N (dpx, w, h, d->rs, spx, s->rs, alpha);
111                         }
112                 }
113                 break;
114         }
117 void
118 nr_blit_pixblock_pixblock_mask (NRPixBlock *d, NRPixBlock *s, NRPixBlock *m)
120         NRRectL clip;
121         unsigned char *dpx, *spx, *mpx;
122         int dbpp, sbpp;
123         int w, h;
125         if (s->empty) return;
126         /* fixme: */
127         if (s->mode == NR_PIXBLOCK_MODE_A8) return;
128         /* fixme: */
129         if (s->mode == NR_PIXBLOCK_MODE_R8G8B8) return;
131         /*
132          * Possible variants as of now:
133          *
134          * 0. SRC EP - DST EP *
135          * 1. SRC EP - DST EN *
136          * 2. SRC EP - DST  P *
137          * 3. SRC EP - DST  N *
138          * 4. SRC EN - DST EP *
139          * 5. SRC EN - DST EN *
140          * 6. SRC EN - DST  P *
141          * 7. SRC EN - DST  N *
142          * 8. SRC  P - DST EP *
143          * 9. SRC  P - DST EN *
144          * A. SRC  P - DST  P *
145          * B. SRC  P - DST  N *
146          * C. SRC  N - DST EP *
147          * D. SRC  N - DST EN *
148          * E. SRC  N - DST  P *
149          * F. SRC  N - DST  N *
150          *
151          */
153         nr_rect_l_intersect (&clip, &d->area, &s->area);
154         nr_rect_l_intersect (&clip, &clip, &m->area);
156         if (nr_rect_l_test_empty(clip)) return;
158         /* Pointers */
159         dbpp = NR_PIXBLOCK_BPP (d);
160         dpx = NR_PIXBLOCK_PX (d) + (clip.y0 - d->area.y0) * d->rs + dbpp * (clip.x0 - d->area.x0);
161         sbpp = NR_PIXBLOCK_BPP (s);
162         spx = NR_PIXBLOCK_PX (s) + (clip.y0 - s->area.y0) * s->rs + sbpp * (clip.x0 - s->area.x0);
163         mpx = NR_PIXBLOCK_PX (m) + (clip.y0 - m->area.y0) * m->rs + 1 * (clip.x0 - m->area.x0);
164         w = clip.x1 - clip.x0;
165         h = clip.y1 - clip.y0;
167         switch (d->mode) {
168         case NR_PIXBLOCK_MODE_A8:
169                 /* No rendering into alpha at moment */
170                 break;
171         case NR_PIXBLOCK_MODE_R8G8B8:
172                 if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
173                         nr_R8G8B8_R8G8B8_R8G8B8A8_P_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
174                 } else {
175                         nr_R8G8B8_R8G8B8_R8G8B8A8_N_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
176                 }
177                 break;
178         case NR_PIXBLOCK_MODE_R8G8B8A8P:
179                 if (d->empty) {
180                         if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
181                                 /* Case 8 */
182                                 nr_R8G8B8A8_P_EMPTY_R8G8B8A8_P_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
183                         } else {
184                                 /* Case C */
185                                 nr_R8G8B8A8_P_EMPTY_R8G8B8A8_N_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
186                         }
187                 } else {
188                         if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
189                                 /* case A */
190                                 nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
191                         } else {
192                                 /* case E */
193                                 nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
194                         }
195                 }
196                 break;
197         case NR_PIXBLOCK_MODE_R8G8B8A8N:
198                 if (d->empty) {
199                         if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
200                                 /* Case 9 */
201                                 nr_R8G8B8A8_N_EMPTY_R8G8B8A8_P_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
202                         } else {
203                                 /* Case D */
204                                 nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
205                         }
206                 } else {
207                         if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
208                                 /* case B */
209                                 nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
210                         } else {
211                                 /* case F */
212                                 nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs);
213                         }
214                 }
215                 break;
216         }
219 void
220 nr_blit_pixblock_mask_rgba32 (NRPixBlock *d, NRPixBlock *m, unsigned long rgba)
222         if (!(rgba & 0xff)) return;
224         if (m) {
225                 NRRectL clip;
226                 unsigned char *dpx, *mpx;
227                 int w, h;
229                 if (m->mode != NR_PIXBLOCK_MODE_A8) return;
231                 if (!nr_rect_l_test_intersect(d->area, m->area)) return;
233                 nr_rect_l_intersect (&clip, &d->area, &m->area);
235                 /* Pointers */
236                 dpx = NR_PIXBLOCK_PX (d) + (clip.y0 - d->area.y0) * d->rs + NR_PIXBLOCK_BPP (d) * (clip.x0 - d->area.x0);
237                 mpx = NR_PIXBLOCK_PX (m) + (clip.y0 - m->area.y0) * m->rs + (clip.x0 - m->area.x0);
238                 w = clip.x1 - clip.x0;
239                 h = clip.y1 - clip.y0;
241                 if (d->empty) {
242                         if (d->mode == NR_PIXBLOCK_MODE_R8G8B8) {
243                                 nr_R8G8B8_R8G8B8_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba);
244                         } else if (d->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
245                                 nr_R8G8B8A8_P_EMPTY_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba);
246                         } else {
247                                 nr_R8G8B8A8_N_EMPTY_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba);
248                         }
249                         d->empty = 0;
250                 } else {
251                         if (d->mode == NR_PIXBLOCK_MODE_R8G8B8) {
252                                 nr_R8G8B8_R8G8B8_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba);
253                         } else if (d->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
254                                 nr_R8G8B8A8_P_R8G8B8A8_P_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba);
255                         } else {
256                                 nr_R8G8B8A8_N_R8G8B8A8_N_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba);
257                         }
258                 }
259         } else {
260                 unsigned int r, g, b, a;
261                 int x, y;
262                 r = NR_RGBA32_R (rgba);
263                 g = NR_RGBA32_G (rgba);
264                 b = NR_RGBA32_B (rgba);
265                 a = NR_RGBA32_A (rgba);
266                 for (y = d->area.y0; y < d->area.y1; y++) {
267                         unsigned char *p;
268                         p = NR_PIXBLOCK_PX (d) + (y - d->area.y0) * d->rs;
269                         for (x = d->area.x0; x < d->area.x1; x++) {
270                                 unsigned int da;
271                                 switch (d->mode) {
272                                 case NR_PIXBLOCK_MODE_R8G8B8:
273                                         p[0] = NR_COMPOSEN11_1111 (r, a, p[0]);
274                                         p[1] = NR_COMPOSEN11_1111 (g, a, p[1]);
275                                         p[2] = NR_COMPOSEN11_1111 (b, a, p[2]);
276                                         p += 3;
277                                         break;
278                                 case NR_PIXBLOCK_MODE_R8G8B8A8P:
279                                         p[0] = NR_COMPOSENPP_1111 (r, a, p[0]);
280                                         p[1] = NR_COMPOSENPP_1111 (g, a, p[1]);
281                                         p[2] = NR_COMPOSENPP_1111 (b, a, p[2]);
282                                         p[3] = NR_COMPOSEA_111(a, p[3]);
283                                         p += 4;
284                                         break;
285                                 case NR_PIXBLOCK_MODE_R8G8B8A8N:
286                                         da = NR_COMPOSEA_112(a, p[3]);
287                                         p[0] = NR_COMPOSENNN_111121 (r, a, p[0], p[3], da);
288                                         p[1] = NR_COMPOSENNN_111121 (g, a, p[1], p[3], da);
289                                         p[2] = NR_COMPOSENNN_111121 (b, a, p[2], p[3], da);
290                                         p[3] = NR_NORMALIZE_21(da);
291                                         p += 4;
292                                         break;
293                                 default:
294                                         break;
295                                 }
296                         }
297                 }
298         }