Code

fix by dvlierop2 for snapping bugs 1579556 and 1579587
[inkscape.git] / src / libnr / nr-pixblock-pattern.cpp
1 #define __NR_PIXBLOCK_PATTERN_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  */
13 #include <glib/gmem.h>
14 #include "nr-pixops.h"
15 #include "nr-pixblock-pattern.h"
17 #define NR_NOISE_SIZE 1024
19 void
20 nr_pixblock_render_gray_noise (NRPixBlock *pb, NRPixBlock *mask)
21 {
22         static unsigned char *noise = NULL;
23         static unsigned int seed = 0;
24         unsigned int v;
25         NRRectL clip;
26         int x, y, bpp;
28         if (mask) {
29                 if (mask->empty) return;
30                 nr_rect_l_intersect (&clip, &pb->area, &mask->area);
31                 if (nr_rect_l_test_empty (&clip)) return;
32         } else {
33                 clip = pb->area;
34         }
36         if (!noise) {
37                 int i;
38                 noise = g_new (unsigned char, NR_NOISE_SIZE);
39                 for (i = 0; i < NR_NOISE_SIZE; i++) noise[i] = (rand () / (RAND_MAX >> 8)) & 0xff;
40         }
42         bpp = NR_PIXBLOCK_BPP (pb);
44         v = (rand () / (RAND_MAX >> 8)) & 0xff;
46         if (mask) {
47                 for (y = clip.y0; y < clip.y1; y++) {
48                         unsigned char *d, *m;
49                         d = NR_PIXBLOCK_PX (pb) + (y - pb->area.y0) * pb->rs + (clip.x0 - pb->area.x0) * bpp;
50                         m = NR_PIXBLOCK_PX (mask) + (y - mask->area.y0) * pb->rs + (clip.x0 - mask->area.x0);
51                         for (x = clip.x0; x < clip.x1; x++) {
52                                 v = v ^ noise[seed];
53                                 switch (pb->mode) {
54                                 case NR_PIXBLOCK_MODE_A8:
55                                         d[0] = NR_COMPOSEA_111(m[0], d[0]);
56                                         break;
57                                 case NR_PIXBLOCK_MODE_R8G8B8:
58                                         d[0] = NR_COMPOSEN11_1111 (v, m[0], d[0]);
59                                         d[1] = NR_COMPOSEN11_1111 (v, m[0], d[1]);
60                                         d[2] = NR_COMPOSEN11_1111 (v, m[0], d[2]);
61                                         break;
62                                 case NR_PIXBLOCK_MODE_R8G8B8A8N:
63                                         if (m[0] != 0) {
64                                                 unsigned int ca;
65                                                 ca = NR_COMPOSEA_112(m[0], d[3]);
66                                                 d[0] = NR_COMPOSENNN_111121 (v, m[0], d[0], d[3], ca);
67                                                 d[1] = NR_COMPOSENNN_111121 (v, m[0], d[1], d[3], ca);
68                                                 d[2] = NR_COMPOSENNN_111121 (v, m[0], d[2], d[3], ca);
69                                                 d[3] = NR_NORMALIZE_21(ca);
70                                         }
71                                         break;
72                                 case NR_PIXBLOCK_MODE_R8G8B8A8P:
73                                         d[0] = NR_COMPOSENPP_1111 (v, m[0], d[0]);
74                                         d[1] = NR_COMPOSENPP_1111 (v, m[0], d[1]);
75                                         d[2] = NR_COMPOSENPP_1111 (v, m[0], d[2]);
76                                         d[3] = NR_COMPOSEA_111(d[3], m[0]);
77                                         break;
78                                 default:
79                                         break;
80                                 }
81                                 d += bpp;
82                                 m += 1;
83                                 if (++seed >= NR_NOISE_SIZE) {
84                                         int i;
85                                         i = (rand () / (RAND_MAX / NR_NOISE_SIZE)) % NR_NOISE_SIZE;
86                                         noise[i] ^= v;
87                                         seed = i % (NR_NOISE_SIZE >> 2);
88                                 }
89                         }
90                 }
91         } else {
92                 for (y = clip.y0; y < clip.y1; y++) {
93                         unsigned char *d;
94                         d = NR_PIXBLOCK_PX (pb) + (y - pb->area.y0) * pb->rs + (clip.x0 - pb->area.x0) * bpp;
95                         for (x = clip.x0; x < clip.x1; x++) {
96                                 v = v ^ noise[seed];
97                                 switch (pb->mode) {
98                                 case NR_PIXBLOCK_MODE_A8:
99                                         d[0] = 255;
100                                         break;
101                                 case NR_PIXBLOCK_MODE_R8G8B8:
102                                         d[0] = v;
103                                         d[1] = v;
104                                         d[2] = v;
105                                         break;
106                                 case NR_PIXBLOCK_MODE_R8G8B8A8N:
107                                 case NR_PIXBLOCK_MODE_R8G8B8A8P:
108                                         d[0] = v;
109                                         d[1] = v;
110                                         d[2] = v;
111                                         d[3] = 255;
112                                 default:
113                                         break;
114                                 }
115                                 d += bpp;
116                                 if (++seed >= NR_NOISE_SIZE) {
117                                         int i;
118                                         i = (rand () / (RAND_MAX / NR_NOISE_SIZE)) % NR_NOISE_SIZE;
119                                         noise[i] ^= v;
120                                         seed = i % (NR_NOISE_SIZE >> 2);
121                                 }
122                         }
123                 }
124         }
126         pb->empty = 0;