Change the translation of the "Help" menu item to "?", so that the menu can be displa...
[reactos.git] / rosapps / smartpdf / fitz / mupdf / pdf_shade1.c
1 #include <fitz.h>
2 #include <mupdf.h>
3
4 /* this mess is jeong's */
5
6 #define BIGNUM 32000
7
8 #define NSEGS 32
9 #define MAX_RAD_SEGS 36
10
11 fz_error *
12 pdf_loadtype1shade(fz_shade *shade, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
13 {
14 fz_error *error;
15 fz_obj *obj;
16 fz_matrix matrix;
17 pdf_function *func;
18
19 int xx, yy;
20 float x, y;
21 float xn, yn;
22 float x0, y0, x1, y1;
23 int n;
24
25 pdf_logshade("load type1 shade {\n");
26
27 obj = fz_dictgets(dict, "Domain");
28 if (obj) {
29 x0 = fz_toreal(fz_arrayget(obj, 0));
30 x1 = fz_toreal(fz_arrayget(obj, 1));
31 y0 = fz_toreal(fz_arrayget(obj, 2));
32 y1 = fz_toreal(fz_arrayget(obj, 3));
33 }
34 else {
35 x0 = 0;
36 x1 = 1.0;
37 y0 = 0;
38 y1 = 1.0;
39 }
40
41 pdf_logshade("domain %g %g %g %g\n", x0, x1, y0, y1);
42
43 obj = fz_dictgets(dict, "Matrix");
44 if (obj)
45 {
46 matrix = pdf_tomatrix(obj);
47 pdf_logshade("matrix [%g %g %g %g %g %g]\n",
48 matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f);
49 }
50 else
51 matrix = fz_identity();
52
53 obj = fz_dictgets(dict, "Function");
54 error = pdf_loadfunction(&func, xref, obj);
55 if (error)
56 return error;
57
58 shade->usefunction = 0;
59
60 if (error)
61 return error;
62
63 shade->meshlen = NSEGS * NSEGS * 2;
64 shade->mesh = fz_malloc(sizeof(float) * (2 + shade->cs->n) * 3 * shade->meshlen);
65 if (!shade->mesh)
66 return fz_outofmem;
67
68 n = 0;
69 for (yy = 0; yy < NSEGS; ++yy)
70 {
71 y = y0 + (y1 - y0) * yy / (float)NSEGS;
72 yn = y0 + (y1 - y0) * (yy + 1) / (float)NSEGS;
73 for (xx = 0; xx < NSEGS; ++xx)
74 {
75 x = x0 + (x1 - x0) * (xx / (float)NSEGS);
76 xn = x0 + (x1 - x0) * (xx + 1) / (float)NSEGS;
77
78 #define ADD_VERTEX(xx, yy) \
79 {\
80 fz_point p;\
81 float cp[2], cv[FZ_MAXCOLORS];\
82 int c;\
83 p.x = xx;\
84 p.y = yy;\
85 p = fz_transformpoint(matrix, p);\
86 shade->mesh[n++] = p.x;\
87 shade->mesh[n++] = p.y;\
88 \
89 cp[0] = xx;\
90 cp[1] = yy;\
91 error = pdf_evalfunction(func, cp, 2, cv, shade->cs->n);\
92 \
93 for (c = 0; c < shade->cs->n; ++c) {\
94 shade->mesh[n++] = cv[c];\
95 }\
96 }\
97
98 ADD_VERTEX(x, y);
99 ADD_VERTEX(xn, y);
100 ADD_VERTEX(xn, yn);
101
102 ADD_VERTEX(x, y);
103 ADD_VERTEX(xn, yn);
104 ADD_VERTEX(x, yn);
105 }
106 }
107
108 pdf_logshade("}\n");
109
110 return nil;
111 }
112
113 fz_error *
114 pdf_loadtype2shade(fz_shade *shade, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
115 {
116 fz_point p1, p2, p3, p4;
117 fz_point ep1, ep2, ep3, ep4;
118 float x0, y0, x1, y1;
119 float t0, t1;
120 int e0, e1;
121 fz_obj *obj;
122 float theta;
123 float dist;
124 int n;
125
126 pdf_logshade("load type2 shade {\n");
127
128 obj = fz_dictgets(dict, "Coords");
129 x0 = fz_toreal(fz_arrayget(obj, 0));
130 y0 = fz_toreal(fz_arrayget(obj, 1));
131 x1 = fz_toreal(fz_arrayget(obj, 2));
132 y1 = fz_toreal(fz_arrayget(obj, 3));
133
134 pdf_logshade("coords %g %g %g %g\n", x0, y0, x1, y1);
135
136 obj = fz_dictgets(dict, "Domain");
137 if (obj) {
138 t0 = fz_toreal(fz_arrayget(obj, 0));
139 t1 = fz_toreal(fz_arrayget(obj, 1));
140 } else {
141 t0 = 0.;
142 t1 = 1.;
143 }
144
145 obj = fz_dictgets(dict, "Extend");
146 if (obj) {
147 e0 = fz_tobool(fz_arrayget(obj, 0));
148 e1 = fz_tobool(fz_arrayget(obj, 1));
149 } else {
150 e0 = 0;
151 e1 = 0;
152 }
153
154 pdf_logshade("domain %g %g\n", t0, t1);
155 pdf_logshade("extend %d %d\n", e0, e1);
156
157 pdf_loadshadefunction(shade, xref, dict, t0, t1);
158
159 shade->meshlen = 2 + e0 * 2 + e1 * 2;
160 shade->mesh = fz_malloc(sizeof(float) * 3*3 * shade->meshlen);
161 if (!shade->mesh)
162 return fz_outofmem;
163
164 theta = atan2(y1 - y0, x1 - x0);
165 theta += M_PI / 2.0;
166
167 pdf_logshade("theta=%g\n", theta);
168
169 dist = hypot(x1 - x0, y1 - y0);
170
171 p1.x = x0 + BIGNUM * cos(theta);
172 p1.y = y0 + BIGNUM * sin(theta);
173 p2.x = x1 + BIGNUM * cos(theta);
174 p2.y = y1 + BIGNUM * sin(theta);
175 p3.x = x0 - BIGNUM * cos(theta);
176 p3.y = y0 - BIGNUM * sin(theta);
177 p4.x = x1 - BIGNUM * cos(theta);
178 p4.y = y1 - BIGNUM * sin(theta);
179
180 ep1.x = p1.x - (x1 - x0) / dist * BIGNUM;
181 ep1.y = p1.y - (y1 - y0) / dist * BIGNUM;
182 ep2.x = p2.x + (x1 - x0) / dist * BIGNUM;
183 ep2.y = p2.y + (y1 - y0) / dist * BIGNUM;
184 ep3.x = p3.x - (x1 - x0) / dist * BIGNUM;
185 ep3.y = p3.y - (y1 - y0) / dist * BIGNUM;
186 ep4.x = p4.x + (x1 - x0) / dist * BIGNUM;
187 ep4.y = p4.y + (y1 - y0) / dist * BIGNUM;
188
189 pdf_logshade("p1 %g %g\n", p1.x, p1.y);
190 pdf_logshade("p2 %g %g\n", p2.x, p2.y);
191 pdf_logshade("p3 %g %g\n", p3.x, p3.y);
192 pdf_logshade("p4 %g %g\n", p4.x, p4.y);
193
194 n = 0;
195
196 pdf_setmeshvalue(shade->mesh, n++, p1.x, p1.y, 0);
197 pdf_setmeshvalue(shade->mesh, n++, p2.x, p2.y, 1);
198 pdf_setmeshvalue(shade->mesh, n++, p4.x, p4.y, 1);
199 pdf_setmeshvalue(shade->mesh, n++, p1.x, p1.y, 0);
200 pdf_setmeshvalue(shade->mesh, n++, p4.x, p4.y, 1);
201 pdf_setmeshvalue(shade->mesh, n++, p3.x, p3.y, 0);
202
203 if (e0) {
204 pdf_setmeshvalue(shade->mesh, n++, ep1.x, ep1.y, 0);
205 pdf_setmeshvalue(shade->mesh, n++, p1.x, p1.y, 0);
206 pdf_setmeshvalue(shade->mesh, n++, p3.x, p3.y, 0);
207 pdf_setmeshvalue(shade->mesh, n++, ep1.x, ep1.y, 0);
208 pdf_setmeshvalue(shade->mesh, n++, p3.x, p3.y, 0);
209 pdf_setmeshvalue(shade->mesh, n++, ep3.x, ep3.y, 0);
210 }
211
212 if (e1) {
213 pdf_setmeshvalue(shade->mesh, n++, p2.x, p2.y, 1);
214 pdf_setmeshvalue(shade->mesh, n++, ep2.x, ep2.y, 1);
215 pdf_setmeshvalue(shade->mesh, n++, ep4.x, ep4.y, 1);
216 pdf_setmeshvalue(shade->mesh, n++, p2.x, p2.y, 1);
217 pdf_setmeshvalue(shade->mesh, n++, ep4.x, ep4.y, 1);
218 pdf_setmeshvalue(shade->mesh, n++, p4.x, p4.y, 1);
219 }
220
221 pdf_logshade("}\n");
222
223 return nil;
224 }
225
226 static int
227 buildannulusmesh(float* mesh, int pos,
228 float x0, float y0, float r0, float x1, float y1, float r1,
229 float c0, float c1, int nomesh)
230 {
231 int n = pos * 3;
232 float dist = hypot(x1 - x0, y1 - y0);
233 float step;
234 float theta;
235 int i;
236
237 if (dist != 0)
238 theta = asin((r1 - r0) / dist) + M_PI/2.0 + atan2(y1 - y0, x1 - x0);
239 else
240 theta = 0;
241
242 if (!(theta >= 0 && theta <= M_PI))
243 theta = 0;
244
245 step = M_PI * 2.f / (float)MAX_RAD_SEGS;
246
247 for (i = 0; i < MAX_RAD_SEGS; theta -= step, ++i)
248 {
249 fz_point pt1, pt2, pt3, pt4;
250
251 pt1.x = cos (theta) * r1 + x1;
252 pt1.y = sin (theta) * r1 + y1;
253 pt2.x = cos (theta) * r0 + x0;
254 pt2.y = sin (theta) * r0 + y0;
255 pt3.x = cos (theta+step) * r1 + x1;
256 pt3.y = sin (theta+step) * r1 + y1;
257 pt4.x = cos (theta+step) * r0 + x0;
258 pt4.y = sin (theta+step) * r0 + y0;
259
260 if (r0 > 0) {
261 if (!nomesh) {
262 pdf_setmeshvalue(mesh, n++, pt1.x, pt1.y, c1);
263 pdf_setmeshvalue(mesh, n++, pt2.x, pt2.y, c0);
264 pdf_setmeshvalue(mesh, n++, pt4.x, pt4.y, c0);
265 }
266 pos++;
267 }
268
269 if (r1 > 0) {
270 if (!nomesh) {
271 pdf_setmeshvalue(mesh, n++, pt1.x, pt1.y, c1);
272 pdf_setmeshvalue(mesh, n++, pt3.x, pt3.y, c1);
273 pdf_setmeshvalue(mesh, n++, pt4.x, pt4.y, c0);
274 }
275 pos++;
276 }
277 }
278
279 return pos;
280 }
281
282 fz_error *
283 pdf_loadtype3shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref)
284 {
285 fz_obj *obj;
286 float x0, y0, r0, x1, y1, r1;
287 float t0, t1;
288 int e0, e1;
289 float ex0, ey0, er0;
290 float ex1, ey1, er1;
291 float rs;
292 int i;
293
294 pdf_logshade("load type3 shade {\n");
295
296 obj = fz_dictgets(shading, "Coords");
297 x0 = fz_toreal(fz_arrayget(obj, 0));
298 y0 = fz_toreal(fz_arrayget(obj, 1));
299 r0 = fz_toreal(fz_arrayget(obj, 2));
300 x1 = fz_toreal(fz_arrayget(obj, 3));
301 y1 = fz_toreal(fz_arrayget(obj, 4));
302 r1 = fz_toreal(fz_arrayget(obj, 5));
303
304 pdf_logshade("coords %g %g %g %g %g %g\n", x0, y0, r0, x1, y1, r1);
305
306 obj = fz_dictgets(shading, "Domain");
307 if (obj) {
308 t0 = fz_toreal(fz_arrayget(obj, 0));
309 t1 = fz_toreal(fz_arrayget(obj, 1));
310 } else {
311 t0 = 0.;
312 t1 = 1.;
313 }
314
315 obj = fz_dictgets(shading, "Extend");
316 if (obj) {
317 e0 = fz_tobool(fz_arrayget(obj, 0));
318 e1 = fz_tobool(fz_arrayget(obj, 1));
319 } else {
320 e0 = 0;
321 e1 = 0;
322 }
323
324 pdf_logshade("domain %g %g\n", t0, t1);
325 pdf_logshade("extend %d %d\n", e0, e1);
326
327 pdf_loadshadefunction(shade, xref, shading, t0, t1);
328
329 if (r0 < r1)
330 rs = r0 / (r0 - r1);
331 else
332 rs = -BIGNUM;
333
334 ex0 = x0 + (x1 - x0) * rs;
335 ey0 = y0 + (y1 - y0) * rs;
336 er0 = r0 + (r1 - r0) * rs;
337
338 if (r0 > r1)
339 rs = r1 / (r1 - r0);
340 else
341 rs = -BIGNUM;
342
343 ex1 = x1 + (x0 - x1) * rs;
344 ey1 = y1 + (y0 - y1) * rs;
345 er1 = r1 + (r0 - r1) * rs;
346
347 for (i=0; i<2; ++i)
348 {
349 int pos = 0;
350 if (e0)
351 pos = buildannulusmesh(shade->mesh, pos, ex0, ey0, er0, x0, y0, r0, 0, 0, 1-i);
352 pos = buildannulusmesh(shade->mesh, pos, x0, y0, r0, x1, y1, r1, 0, 1., 1-i);
353 if (e1)
354 pos = buildannulusmesh(shade->mesh, pos, x1, y1, r1, ex1, ey1, er1, 1., 1., 1-i);
355
356 if (i == 0)
357 {
358 shade->meshlen = pos;
359 shade->mesh = fz_malloc(sizeof(float) * 9 * shade->meshlen);
360 if (!shade->mesh)
361 return fz_outofmem;
362 }
363 }
364
365 pdf_logshade("}\n");
366
367 return nil;
368 }
369