]> git.ipfire.org Git - thirdparty/cups.git/blob - pdftops/SplashScreen.cxx
Load cups into easysw/current.
[thirdparty/cups.git] / pdftops / SplashScreen.cxx
1 //========================================================================
2 //
3 // SplashScreen.cc
4 //
5 //========================================================================
6
7 #include <config.h>
8
9 #ifdef USE_GCC_PRAGMAS
10 #pragma implementation
11 #endif
12
13 #include <string.h>
14 #include "gmem.h"
15 #include "SplashMath.h"
16 #include "SplashScreen.h"
17
18 //------------------------------------------------------------------------
19 // SplashScreen
20 //------------------------------------------------------------------------
21
22 // This generates a 45 degree screen using a circular dot spot
23 // function. DPI = resolution / ((size / 2) * sqrt(2)).
24 // Gamma correction (gamma = 1 / 1.33) is also computed here.
25 SplashScreen::SplashScreen(int sizeA) {
26 SplashCoord *dist;
27 SplashCoord u, v, d, val;
28 int size2, x, y, x1, y1, i;
29
30 size2 = sizeA >> 1;
31 if (size2 < 1) {
32 size2 = 1;
33 }
34 size = size2 << 1;
35
36 // initialize the threshold matrix
37 mat = (SplashCoord *)gmallocn(size * size, sizeof(SplashCoord));
38 for (y = 0; y < size; ++y) {
39 for (x = 0; x < size; ++x) {
40 mat[y * size + x] = -1;
41 }
42 }
43
44 // build the distance matrix
45 dist = (SplashCoord *)gmallocn(size * size2, sizeof(SplashCoord));
46 for (y = 0; y < size2; ++y) {
47 for (x = 0; x < size2; ++x) {
48 if (x + y < size2 - 1) {
49 u = (SplashCoord)x + 0.5 - 0;
50 v = (SplashCoord)y + 0.5 - 0;
51 } else {
52 u = (SplashCoord)x + 0.5 - (SplashCoord)size2;
53 v = (SplashCoord)y + 0.5 - (SplashCoord)size2;
54 }
55 dist[y * size2 + x] = u*u + v*v;
56 }
57 }
58 for (y = 0; y < size2; ++y) {
59 for (x = 0; x < size2; ++x) {
60 if (x < y) {
61 u = (SplashCoord)x + 0.5 - 0;
62 v = (SplashCoord)y + 0.5 - (SplashCoord)size2;
63 } else {
64 u = (SplashCoord)x + 0.5 - (SplashCoord)size2;
65 v = (SplashCoord)y + 0.5 - 0;
66 }
67 dist[(size2 + y) * size2 + x] = u*u + v*v;
68 }
69 }
70
71 // build the threshold matrix
72 minVal = 1;
73 maxVal = 0;
74 x1 = y1 = 0; // make gcc happy
75 for (i = 1; i <= size * size2; ++i) {
76 d = size * size2;
77 for (y = 0; y < size; ++y) {
78 for (x = 0; x < size2; ++x) {
79 if (mat[y * size + x] < 0 &&
80 dist[y * size2 + x] < d) {
81 x1 = x;
82 y1 = y;
83 d = dist[y1 * size2 + x1];
84 }
85 }
86 }
87 u = (SplashCoord)1 - (SplashCoord)i / (SplashCoord)(size * size2 + 1);
88 val = splashPow(u, 1.33);
89 if (val < minVal) {
90 minVal = val;
91 }
92 if (val > maxVal) {
93 maxVal = val;
94 }
95 mat[y1 * size + x1] = val;
96 if (y1 < size2) {
97 mat[(y1 + size2) * size + x1 + size2] = val;
98 } else {
99 mat[(y1 - size2) * size + x1 + size2] = val;
100 }
101 }
102
103 gfree(dist);
104 }
105
106 SplashScreen::SplashScreen(SplashScreen *screen) {
107 int n;
108
109 size = screen->size;
110 n = size * size * sizeof(SplashCoord);
111 mat = (SplashCoord *)gmalloc(n);
112 memcpy(mat, screen->mat, n);
113 minVal = screen->minVal;
114 maxVal = screen->maxVal;
115 }
116
117 SplashScreen::~SplashScreen() {
118 gfree(mat);
119 }
120
121 int SplashScreen::test(int x, int y, SplashCoord value) {
122 int xx, yy;
123
124 if (value < minVal) {
125 return 0;
126 }
127 if (value >= maxVal) {
128 return 1;
129 }
130 if ((xx = x % size) < 0) {
131 xx = -xx;
132 }
133 if ((yy = y % size) < 0) {
134 yy = -yy;
135 }
136 return value < mat[yy * size + xx] ? 0 : 1;
137 }
138
139 GBool SplashScreen::isStatic(SplashCoord value) {
140 return value < minVal || value >= maxVal;
141 }