Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7638 views
1
#include "pdfapp.h"
2
3
#include <ctype.h>
4
5
/*
6
A useful bit of bash script to call this is:
7
for f in ../ghostpcl/tests_private/pdf/forms/v1.3/ *.pdf ; do g=${f%.*} ; echo $g ; win32/debug/mujstest-v8.exe -o $g-%d.png -p ../ghostpcl/ $g.mjs > $g.log 2>&1 ; done
8
9
Remove the space from "/ *.pdf" before running - can't leave that
10
in here, as it causes a warning about a possibly malformed comment.
11
*/
12
13
static pdfapp_t gapp;
14
static int file_open = 0;
15
static char filename[1024] = "";
16
static char *scriptname;
17
static char *output = "out%03d.png";
18
static char *prefix = NULL;
19
static int shotcount = 0;
20
static int verbosity = 0;
21
22
#define LONGLINE 4096
23
24
static char getline_buffer[LONGLINE];
25
26
void winwarn(pdfapp_t *app, char *msg)
27
{
28
fprintf(stderr, "warning: %s\n", msg);
29
}
30
31
void winerror(pdfapp_t *app, char *msg)
32
{
33
fprintf(stderr, "%s\n", msg);
34
exit(1);
35
}
36
37
void winalert(pdfapp_t *app, pdf_alert_event *alert)
38
{
39
fprintf(stderr, "Alert %s: %s\n", alert->title, alert->message);
40
switch (alert->button_group_type)
41
{
42
case PDF_ALERT_BUTTON_GROUP_OK:
43
case PDF_ALERT_BUTTON_GROUP_OK_CANCEL:
44
alert->button_pressed = PDF_ALERT_BUTTON_OK;
45
break;
46
case PDF_ALERT_BUTTON_GROUP_YES_NO:
47
case PDF_ALERT_BUTTON_GROUP_YES_NO_CANCEL:
48
alert->button_pressed = PDF_ALERT_BUTTON_YES;
49
break;
50
}
51
}
52
53
void winadvancetimer(pdfapp_t *app, float duration)
54
{
55
}
56
57
void winprint(pdfapp_t *app)
58
{
59
fprintf(stderr, "The MuPDF library supports printing, but this application currently does not\n");
60
}
61
62
static char pd_password[256] = "";
63
static char td_textinput[LONGLINE] = "";
64
65
char *winpassword(pdfapp_t *app, char *filename)
66
{
67
if (pd_password[0] == 0)
68
return NULL;
69
return pd_password;
70
}
71
72
char *wintextinput(pdfapp_t *app, char *inittext, int retry)
73
{
74
if (retry)
75
return NULL;
76
77
if (td_textinput[0] != 0)
78
return td_textinput;
79
return inittext;
80
}
81
82
int winchoiceinput(pdfapp_t *app, int nopts, char *opts[], int *nvals, char *vals[])
83
{
84
return 0;
85
}
86
87
void winhelp(pdfapp_t*app)
88
{
89
}
90
91
void winclose(pdfapp_t *app)
92
{
93
pdfapp_close(app);
94
exit(0);
95
}
96
97
int winsavequery(pdfapp_t *app)
98
{
99
return DISCARD;
100
}
101
102
int wingetsavepath(pdfapp_t *app, char *buf, int len)
103
{
104
return 0;
105
}
106
107
void winreplacefile(char *source, char *target)
108
{
109
}
110
111
void wincopyfile(char *source, char *target)
112
{
113
}
114
115
void wincursor(pdfapp_t *app, int curs)
116
{
117
}
118
119
void wintitle(pdfapp_t *app, char *title)
120
{
121
}
122
123
void windrawrect(pdfapp_t *app, int x0, int y0, int x1, int y1)
124
{
125
}
126
127
void windrawstring(pdfapp_t *app, int x, int y, char *s)
128
{
129
}
130
131
void winresize(pdfapp_t *app, int w, int h)
132
{
133
}
134
135
void winrepaint(pdfapp_t *app)
136
{
137
}
138
139
void winrepaintsearch(pdfapp_t *app)
140
{
141
}
142
143
void winfullscreen(pdfapp_t *app, int state)
144
{
145
}
146
147
/*
148
* Event handling
149
*/
150
151
void windocopy(pdfapp_t *app)
152
{
153
}
154
155
void winreloadpage(pdfapp_t *app)
156
{
157
}
158
159
void winopenuri(pdfapp_t *app, char *buf)
160
{
161
}
162
163
static void
164
usage(void)
165
{
166
fprintf(stderr, "mujstest: Scriptable tester for mupdf + js\n");
167
fprintf(stderr, "\nSyntax: mujstest -o <filename> [ -p <prefix> ] [-v] <scriptfile>\n");
168
fprintf(stderr, "\n<filename> should sensibly be of the form file-%%d.png\n");
169
fprintf(stderr, "\n<prefix> is a path prefix to apply to filenames within the script\n");
170
fprintf(stderr, "\n-v\tverbose\n");
171
fprintf(stderr, "\nscriptfile contains a list of commands:\n");
172
fprintf(stderr, "\tPASSWORD <password>\tSet the password\n");
173
fprintf(stderr, "\tOPEN <filename>\tOpen a file\n");
174
fprintf(stderr, "\tGOTO <page>\tJump to a particular page\n");
175
fprintf(stderr, "\tSCREENSHOT\tSave a screenshot\n");
176
fprintf(stderr, "\tRESIZE <w> <h>\tResize the screen to a given size\n");
177
fprintf(stderr, "\tCLICK <x> <y> <btn>\tClick at a given position\n");
178
fprintf(stderr, "\tTEXT <string>\tSet a value to be entered\n");
179
exit(1);
180
}
181
182
static char *
183
my_getline(FILE *file)
184
{
185
int c;
186
char *d = getline_buffer;
187
int space = sizeof(getline_buffer)-1;
188
189
/* Skip over any prefix of whitespace */
190
do
191
{
192
c = fgetc(file);
193
}
194
while (isspace(c));
195
196
if (c < 0)
197
return NULL;
198
199
/* Read the line in */
200
do
201
{
202
*d++ = (char)c;
203
c = fgetc(file);
204
}
205
while (c >= 32 && space--);
206
207
/* If we ran out of space, skip the rest of the line */
208
if (space == 0)
209
{
210
while (c >= 32)
211
c = fgetc(file);
212
}
213
214
*d = 0;
215
216
return getline_buffer;
217
}
218
219
static int
220
match(char **line, const char *match)
221
{
222
char *s = *line;
223
224
if (s == NULL)
225
return 0;
226
227
while (isspace(*(unsigned char *)s))
228
s++;
229
230
while (*s == *match)
231
{
232
if (*s == 0)
233
{
234
*line = s;
235
return 1;
236
}
237
s++;
238
match++;
239
}
240
241
if (*match != 0)
242
return 0;
243
244
/* We matched! Skip over any whitespace */
245
while (isspace(*(unsigned char *)s))
246
s++;
247
248
*line = s;
249
250
/* Trim whitespace off the end of the line */
251
/* Run to the end of the line */
252
while (*s)
253
s++;
254
255
/* Run back until we find where we started, or non whitespace */
256
while (s != *line && isspace((unsigned char)s[-1]))
257
s--;
258
259
/* Remove the suffix of whitespace */
260
*s = 0;
261
262
return 1;
263
}
264
265
static void unescape_string(char *d, const char *s)
266
{
267
char c;
268
269
while ((c = *s++) != 0)
270
{
271
if (c == '\\')
272
{
273
c = *s++;
274
switch(c)
275
{
276
case 'n':
277
c = '\n';
278
break;
279
case 'r':
280
c = '\r';
281
break;
282
case 't':
283
c = '\t';
284
break;
285
}
286
}
287
*d++ = c;
288
}
289
*d = 0;
290
}
291
292
int
293
main(int argc, char *argv[])
294
{
295
fz_context *ctx;
296
FILE *script = NULL;
297
int c;
298
299
while ((c = fz_getopt(argc, argv, "o:p:v")) != -1)
300
{
301
switch(c)
302
{
303
case 'o': output = fz_optarg; break;
304
case 'p': prefix = fz_optarg; break;
305
case 'v': verbosity ^= 1; break;
306
default: usage(); break;
307
}
308
}
309
310
if (fz_optind == argc)
311
usage();
312
313
ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT);
314
if (!ctx)
315
{
316
fprintf(stderr, "cannot initialise context\n");
317
exit(1);
318
}
319
pdfapp_init(ctx, &gapp);
320
gapp.scrw = 640;
321
gapp.scrh = 480;
322
gapp.colorspace = fz_device_rgb(ctx);
323
324
fz_try(ctx)
325
{
326
while (fz_optind < argc)
327
{
328
scriptname = argv[fz_optind++];
329
script = fopen(scriptname, "rb");
330
if (script == NULL)
331
fz_throw(ctx, FZ_ERROR_GENERIC, "cannot open script: %s", scriptname);
332
333
do
334
{
335
char *line = my_getline(script);
336
if (line == NULL)
337
continue;
338
if (verbosity)
339
fprintf(stderr, "'%s'\n", line);
340
if (match(&line, "%"))
341
{
342
/* Comment */
343
}
344
else if (match(&line, "PASSWORD"))
345
{
346
strcpy(pd_password, line);
347
}
348
else if (match(&line, "OPEN"))
349
{
350
char path[1024];
351
if (file_open)
352
pdfapp_close(&gapp);
353
strcpy(filename, line);
354
if (prefix)
355
{
356
sprintf(path, "%s%s", prefix, line);
357
}
358
else
359
{
360
strcpy(path, line);
361
}
362
pdfapp_open(&gapp, path, 0);
363
file_open = 1;
364
}
365
else if (match(&line, "GOTO"))
366
{
367
pdfapp_gotopage(&gapp, atoi(line)-1);
368
}
369
else if (match(&line, "SCREENSHOT"))
370
{
371
char text[1024];
372
373
sprintf(text, output, ++shotcount);
374
if (strstr(text, ".pgm") || strstr(text, ".ppm") || strstr(text, ".pnm"))
375
fz_write_pnm(ctx, gapp.image, text);
376
else
377
fz_write_png(ctx, gapp.image, text, 0);
378
}
379
else if (match(&line, "RESIZE"))
380
{
381
int w, h;
382
sscanf(line, "%d %d", &w, &h);
383
pdfapp_onresize(&gapp, w, h);
384
}
385
else if (match(&line, "CLICK"))
386
{
387
float x, y, b;
388
int n;
389
n = sscanf(line, "%f %f %f", &x, &y, &b);
390
if (n < 1)
391
x = 0.0f;
392
if (n < 2)
393
y = 0.0f;
394
if (n < 3)
395
b = 1;
396
/* state = 1 = transition down */
397
pdfapp_onmouse(&gapp, (int)x, (int)y, b, 0, 1);
398
/* state = -1 = transition up */
399
pdfapp_onmouse(&gapp, (int)x, (int)y, b, 0, -1);
400
}
401
else if (match(&line, "TEXT"))
402
{
403
unescape_string(td_textinput, line);
404
}
405
else
406
{
407
fprintf(stderr, "Unmatched: %s\n", line);
408
}
409
}
410
while (!feof(script));
411
412
fclose(script);
413
}
414
}
415
fz_catch(ctx)
416
{
417
fprintf(stderr, "error: cannot execute '%s'\n", scriptname);
418
}
419
420
if (file_open)
421
pdfapp_close(&gapp);
422
423
fz_drop_context(ctx);
424
425
return 0;
426
}
427
428