Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7640 views
1
#include "mupdf/fitz.h"
2
3
enum
4
{
5
FZ_DOCUMENT_HANDLER_MAX = 10
6
};
7
8
#define DEFW (450)
9
#define DEFH (600)
10
#define DEFEM (12)
11
12
struct fz_document_handler_context_s
13
{
14
int refs;
15
int count;
16
const fz_document_handler *handler[FZ_DOCUMENT_HANDLER_MAX];
17
};
18
19
void fz_new_document_handler_context(fz_context *ctx)
20
{
21
ctx->handler = fz_malloc_struct(ctx, fz_document_handler_context);
22
ctx->handler->refs = 1;
23
}
24
25
fz_document_handler_context *fz_keep_document_handler_context(fz_context *ctx)
26
{
27
if (!ctx || !ctx->handler)
28
return NULL;
29
ctx->handler->refs++;
30
return ctx->handler;
31
}
32
33
void fz_drop_document_handler_context(fz_context *ctx)
34
{
35
if (!ctx || !ctx->handler)
36
return;
37
38
if (--ctx->handler->refs != 0)
39
return;
40
41
fz_free(ctx, ctx->handler);
42
ctx->handler = NULL;
43
}
44
45
void fz_register_document_handler(fz_context *ctx, const fz_document_handler *handler)
46
{
47
fz_document_handler_context *dc;
48
int i;
49
50
if (!ctx || !handler)
51
return;
52
53
dc = ctx->handler;
54
if (dc == NULL)
55
fz_throw(ctx, FZ_ERROR_GENERIC, "Document handler list not found");
56
57
for (i = 0; i < dc->count; i++)
58
if (dc->handler[i] == handler)
59
return;
60
61
if (dc->count >= FZ_DOCUMENT_HANDLER_MAX)
62
fz_throw(ctx, FZ_ERROR_GENERIC, "Too many document handlers");
63
64
dc->handler[dc->count++] = handler;
65
}
66
67
static inline int fz_tolower(int c)
68
{
69
if (c >= 'A' && c <= 'Z')
70
return c + 32;
71
return c;
72
}
73
74
int fz_strcasecmp(const char *a, const char *b)
75
{
76
while (fz_tolower(*a) == fz_tolower(*b))
77
{
78
if (*a++ == 0)
79
return 0;
80
b++;
81
}
82
return fz_tolower(*a) - fz_tolower(*b);
83
}
84
85
fz_document *
86
fz_open_document_with_stream(fz_context *ctx, const char *magic, fz_stream *stream)
87
{
88
int i, score;
89
int best_i, best_score;
90
fz_document_handler_context *dc;
91
92
if (ctx == NULL || magic == NULL || stream == NULL)
93
return NULL;
94
95
dc = ctx->handler;
96
if (dc->count == 0)
97
fz_throw(ctx, FZ_ERROR_GENERIC, "No document handlers registered");
98
99
best_i = -1;
100
best_score = 0;
101
for (i = 0; i < dc->count; i++)
102
{
103
score = dc->handler[i]->recognize(ctx, magic);
104
if (best_score < score)
105
{
106
best_score = score;
107
best_i = i;
108
}
109
}
110
111
if (best_i >= 0)
112
return dc->handler[best_i]->open_with_stream(ctx, stream);
113
114
return NULL;
115
}
116
117
fz_document *
118
fz_open_document(fz_context *ctx, const char *filename)
119
{
120
int i, score;
121
int best_i, best_score;
122
fz_document_handler_context *dc;
123
124
if (ctx == NULL || filename == NULL)
125
return NULL;
126
127
dc = ctx->handler;
128
if (dc->count == 0)
129
fz_throw(ctx, FZ_ERROR_GENERIC, "No document handlers registered");
130
131
best_i = -1;
132
best_score = 0;
133
for (i = 0; i < dc->count; i++)
134
{
135
score = dc->handler[i]->recognize(ctx, filename);
136
if (best_score < score)
137
{
138
best_score = score;
139
best_i = i;
140
}
141
}
142
143
if (best_i >= 0)
144
return dc->handler[best_i]->open(ctx, filename);
145
146
return NULL;
147
}
148
149
void *
150
fz_new_document(fz_context *ctx, int size)
151
{
152
fz_document *doc = fz_calloc(ctx, 1, size);
153
doc->refs = 1;
154
return doc;
155
}
156
157
fz_document *
158
fz_keep_document(fz_context *ctx, fz_document *doc)
159
{
160
++doc->refs;
161
return doc;
162
}
163
164
void
165
fz_drop_document(fz_context *ctx, fz_document *doc)
166
{
167
if (doc && --doc->refs == 0 && doc->close)
168
doc->close(ctx, doc);
169
}
170
171
static void
172
fz_ensure_layout(fz_context *ctx, fz_document *doc)
173
{
174
if (doc && doc->layout && !doc->did_layout)
175
{
176
doc->layout(ctx, doc, DEFW, DEFH, DEFEM);
177
doc->did_layout = 1;
178
}
179
}
180
181
int
182
fz_needs_password(fz_context *ctx, fz_document *doc)
183
{
184
if (doc && doc->needs_password)
185
return doc->needs_password(ctx, doc);
186
return 0;
187
}
188
189
int
190
fz_authenticate_password(fz_context *ctx, fz_document *doc, const char *password)
191
{
192
if (doc && doc->authenticate_password)
193
return doc->authenticate_password(ctx, doc, password);
194
return 1;
195
}
196
197
int
198
fz_has_permission(fz_context *ctx, fz_document *doc, fz_permission p)
199
{
200
if (doc && doc->has_permission)
201
return doc->has_permission(ctx, doc, p);
202
return 1;
203
}
204
205
fz_outline *
206
fz_load_outline(fz_context *ctx, fz_document *doc)
207
{
208
if (doc && doc->load_outline)
209
return doc->load_outline(ctx, doc);
210
return NULL;
211
}
212
213
void
214
fz_layout_document(fz_context *ctx, fz_document *doc, float w, float h, float em)
215
{
216
if (doc && doc->layout)
217
{
218
doc->layout(ctx, doc, w, h, em);
219
doc->did_layout = 1;
220
}
221
}
222
223
int
224
fz_count_pages(fz_context *ctx, fz_document *doc)
225
{
226
fz_ensure_layout(ctx, doc);
227
if (doc && doc->count_pages)
228
return doc->count_pages(ctx, doc);
229
return 0;
230
}
231
232
int
233
fz_lookup_metadata(fz_context *ctx, fz_document *doc, const char *key, char *buf, int size)
234
{
235
if (buf && size > 0)
236
buf[0] = 0;
237
if (doc && doc->lookup_metadata)
238
return doc->lookup_metadata(ctx, doc, key, buf, size);
239
return -1;
240
}
241
242
void
243
fz_write_document(fz_context *ctx, fz_document *doc, char *filename, fz_write_options *opts)
244
{
245
if (doc && doc->write)
246
doc->write(ctx, doc, filename, opts);
247
}
248
249
fz_page *
250
fz_load_page(fz_context *ctx, fz_document *doc, int number)
251
{
252
fz_ensure_layout(ctx, doc);
253
if (doc && doc->load_page)
254
return doc->load_page(ctx, doc, number);
255
return NULL;
256
}
257
258
fz_link *
259
fz_load_links(fz_context *ctx, fz_page *page)
260
{
261
if (page && page->load_links && page)
262
return page->load_links(ctx, page);
263
return NULL;
264
}
265
266
fz_rect *
267
fz_bound_page(fz_context *ctx, fz_page *page, fz_rect *r)
268
{
269
if (page && page->bound_page && page && r)
270
return page->bound_page(ctx, page, r);
271
if (r)
272
*r = fz_empty_rect;
273
return r;
274
}
275
276
fz_annot *
277
fz_first_annot(fz_context *ctx, fz_page *page)
278
{
279
if (page && page->first_annot && page)
280
return page->first_annot(ctx, page);
281
return NULL;
282
}
283
284
fz_annot *
285
fz_next_annot(fz_context *ctx, fz_page *page, fz_annot *annot)
286
{
287
if (page && page->next_annot && annot)
288
return page->next_annot(ctx, page, annot);
289
return NULL;
290
}
291
292
fz_rect *
293
fz_bound_annot(fz_context *ctx, fz_page *page, fz_annot *annot, fz_rect *rect)
294
{
295
if (page && page->bound_annot && annot && rect)
296
return page->bound_annot(ctx, page, annot, rect);
297
if (rect)
298
*rect = fz_empty_rect;
299
return rect;
300
}
301
302
void
303
fz_run_page_contents(fz_context *ctx, fz_page *page, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie)
304
{
305
if (page && page->run_page_contents && page)
306
{
307
fz_try(ctx)
308
{
309
page->run_page_contents(ctx, page, dev, transform, cookie);
310
}
311
fz_catch(ctx)
312
{
313
if (fz_caught(ctx) != FZ_ERROR_ABORT)
314
fz_rethrow(ctx);
315
}
316
}
317
}
318
319
void
320
fz_run_annot(fz_context *ctx, fz_page *page, fz_annot *annot, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie)
321
{
322
if (page && page->run_annot && page && annot)
323
{
324
fz_try(ctx)
325
{
326
page->run_annot(ctx, page, annot, dev, transform, cookie);
327
}
328
fz_catch(ctx)
329
{
330
if (fz_caught(ctx) != FZ_ERROR_ABORT)
331
fz_rethrow(ctx);
332
}
333
}
334
}
335
336
void
337
fz_run_page(fz_context *ctx, fz_page *page, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie)
338
{
339
fz_annot *annot;
340
fz_rect mediabox;
341
342
fz_bound_page(ctx, page, &mediabox);
343
fz_begin_page(ctx, dev, &mediabox, transform);
344
345
fz_run_page_contents(ctx, page, dev, transform, cookie);
346
347
if (cookie && cookie->progress_max != -1)
348
{
349
int count = 1;
350
for (annot = fz_first_annot(ctx, page); annot; annot = fz_next_annot(ctx, page, annot))
351
count++;
352
cookie->progress_max += count;
353
}
354
355
for (annot = fz_first_annot(ctx, page); annot; annot = fz_next_annot(ctx, page, annot))
356
{
357
/* Check the cookie for aborting */
358
if (cookie)
359
{
360
if (cookie->abort)
361
break;
362
cookie->progress++;
363
}
364
365
fz_run_annot(ctx, page, annot, dev, transform, cookie);
366
}
367
368
fz_end_page(ctx, dev);
369
}
370
371
void *
372
fz_new_page(fz_context *ctx, int size)
373
{
374
fz_page *page = Memento_label(fz_calloc(ctx, 1, size), "fz_page");
375
page->refs = 1;
376
return page;
377
}
378
379
fz_page *
380
fz_keep_page(fz_context *ctx, fz_page *page)
381
{
382
if (page)
383
++page->refs;
384
return page;
385
}
386
387
void
388
fz_drop_page(fz_context *ctx, fz_page *page)
389
{
390
if (page) {
391
if (--page->refs == 0 && page->drop_page_imp)
392
{
393
page->drop_page_imp(ctx, page);
394
fz_free(ctx, page);
395
}
396
}
397
}
398
399
fz_transition *
400
fz_page_presentation(fz_context *ctx, fz_page *page, float *duration)
401
{
402
float dummy;
403
if (duration)
404
*duration = 0;
405
else
406
duration = &dummy;
407
if (page && page->page_presentation && page)
408
return page->page_presentation(ctx, page, duration);
409
return NULL;
410
}
411
412