1 #ifndef MUPDF_FITZ_CONTEXT_H
2 #define MUPDF_FITZ_CONTEXT_H
3
4 #include "mupdf/fitz/version.h"
5 #include "mupdf/fitz/system.h"
6 #include "mupdf/fitz/geometry.h"
7
8 typedef struct fz_font_context fz_font_context;
9 typedef struct fz_colorspace_context fz_colorspace_context;
10 typedef struct fz_style_context fz_style_context;
11 typedef struct fz_tuning_context fz_tuning_context;
12 typedef struct fz_store fz_store;
13 typedef struct fz_glyph_cache fz_glyph_cache;
14 typedef struct fz_document_handler_context fz_document_handler_context;
15 typedef struct fz_context fz_context;
16
17 /**
18 Allocator structure; holds callbacks and private data pointer.
19 */
20 typedef struct
21 {
22 void *user;
23 void *(*malloc)(void *, size_t);
24 void *(*realloc)(void *, void *, size_t);
25 void (*free)(void *, void *);
26 } fz_alloc_context;
27
28 /**
29 Exception macro definitions. Just treat these as a black box -
30 pay no attention to the man behind the curtain.
31 */
32
33 #define fz_var(var) fz_var_imp((void *)&(var))
34 #define fz_try(ctx) if (!fz_setjmp(*fz_push_try(ctx))) if (fz_do_try(ctx)) do
35 #define fz_always(ctx) while (0); if (fz_do_always(ctx)) do
36 #define fz_catch(ctx) while (0); if (fz_do_catch(ctx))
37
38 FZ_NORETURN void fz_vthrow(fz_context *ctx, int errcode, const char *, va_list ap);
39 FZ_NORETURN void fz_throw(fz_context *ctx, int errcode, const char *, ...) FZ_PRINTFLIKE(3,4);
40 FZ_NORETURN void fz_rethrow(fz_context *ctx);
41 void fz_vwarn(fz_context *ctx, const char *fmt, va_list ap);
42 void fz_warn(fz_context *ctx, const char *fmt, ...) FZ_PRINTFLIKE(2,3);
43 const char *fz_caught_message(fz_context *ctx);
44 int fz_caught(fz_context *ctx);
45 void fz_rethrow_if(fz_context *ctx, int errcode);
46
47 enum
48 {
49 FZ_ERROR_NONE = 0,
50 FZ_ERROR_MEMORY = 1,
51 FZ_ERROR_GENERIC = 2,
52 FZ_ERROR_SYNTAX = 3,
53 FZ_ERROR_MINOR = 4,
54 FZ_ERROR_TRYLATER = 5,
55 FZ_ERROR_ABORT = 6,
56 FZ_ERROR_COUNT
57 };
58
59 /**
60 Flush any repeated warnings.
61
62 Repeated warnings are buffered, counted and eventually printed
63 along with the number of repetitions. Call fz_flush_warnings
64 to force printing of the latest buffered warning and the
65 number of repetitions, for example to make sure that all
66 warnings are printed before exiting an application.
67 */
68 void fz_flush_warnings(fz_context *ctx);
69
70 /**
71 Locking functions
72
73 MuPDF is kept deliberately free of any knowledge of particular
74 threading systems. As such, in order for safe multi-threaded
75 operation, we rely on callbacks to client provided functions.
76
77 A client is expected to provide FZ_LOCK_MAX number of mutexes,
78 and a function to lock/unlock each of them. These may be
79 recursive mutexes, but do not have to be.
80
81 If a client does not intend to use multiple threads, then it
82 may pass NULL instead of a lock structure.
83
84 In order to avoid deadlocks, we have one simple rule
85 internally as to how we use locks: We can never take lock n
86 when we already hold any lock i, where 0 <= i <= n. In order
87 to verify this, we have some debugging code, that can be
88 enabled by defining FITZ_DEBUG_LOCKING.
89 */
90
91 typedef struct
92 {
93 void *user;
94 void (*lock)(void *user, int lock);
95 void (*unlock)(void *user, int lock);
96 } fz_locks_context;
97
98 enum {
99 FZ_LOCK_ALLOC = 0,
100 FZ_LOCK_FREETYPE,
101 FZ_LOCK_GLYPHCACHE,
102 FZ_LOCK_MAX
103 };
104
105 #if defined(MEMENTO) || !defined(NDEBUG)
106 #define FITZ_DEBUG_LOCKING
107 #endif
108
109 #ifdef FITZ_DEBUG_LOCKING
110
111 void fz_assert_lock_held(fz_context *ctx, int lock);
112 void fz_assert_lock_not_held(fz_context *ctx, int lock);
113 void fz_lock_debug_lock(fz_context *ctx, int lock);
114 void fz_lock_debug_unlock(fz_context *ctx, int lock);
115
116 #else
117
118 #define fz_assert_lock_held(A,B) do { } while (0)
119 #define fz_assert_lock_not_held(A,B) do { } while (0)
120 #define fz_lock_debug_lock(A,B) do { } while (0)
121 #define fz_lock_debug_unlock(A,B) do { } while (0)
122
123 #endif /* !FITZ_DEBUG_LOCKING */
124
125 /**
126 Specifies the maximum size in bytes of the resource store in
127 fz_context. Given as argument to fz_new_context.
128
129 FZ_STORE_UNLIMITED: Let resource store grow unbounded.
130
131 FZ_STORE_DEFAULT: A reasonable upper bound on the size, for
132 devices that are not memory constrained.
133 */
134 enum {
135 FZ_STORE_UNLIMITED = 0,
136 FZ_STORE_DEFAULT = 256 << 20,
137 };
138
139 /**
140 Allocate context containing global state.
141
142 The global state contains an exception stack, resource store,
143 etc. Most functions in MuPDF take a context argument to be
144 able to reference the global state. See fz_drop_context for
145 freeing an allocated context.
146
147 alloc: Supply a custom memory allocator through a set of
148 function pointers. Set to NULL for the standard library
149 allocator. The context will keep the allocator pointer, so the
150 data it points to must not be modified or freed during the
151 lifetime of the context.
152
153 locks: Supply a set of locks and functions to lock/unlock
154 them, intended for multi-threaded applications. Set to NULL
155 when using MuPDF in a single-threaded applications. The
156 context will keep the locks pointer, so the data it points to
157 must not be modified or freed during the lifetime of the
158 context.
159
160 max_store: Maximum size in bytes of the resource store, before
161 it will start evicting cached resources such as fonts and
162 images. FZ_STORE_UNLIMITED can be used if a hard limit is not
163 desired. Use FZ_STORE_DEFAULT to get a reasonable size.
164
165 May return NULL.
166 */
167 #define fz_new_context(alloc, locks, max_store) fz_new_context_imp(alloc, locks, max_store, FZ_VERSION)
168
169 /**
170 Make a clone of an existing context.
171
172 This function is meant to be used in multi-threaded
173 applications where each thread requires its own context, yet
174 parts of the global state, for example caching, are shared.
175
176 ctx: Context obtained from fz_new_context to make a copy of.
177 ctx must have had locks and lock/functions setup when created.
178 The two contexts will share the memory allocator, resource
179 store, locks and lock/unlock functions. They will each have
180 their own exception stacks though.
181
182 May return NULL.
183 */
184 fz_context *fz_clone_context(fz_context *ctx);
185
186 /**
187 Free a context and its global state.
188
189 The context and all of its global state is freed, and any
190 buffered warnings are flushed (see fz_flush_warnings). If NULL
191 is passed in nothing will happen.
192 */
193 void fz_drop_context(fz_context *ctx);
194
195 /**
196 Set the user field in the context.
197
198 NULL initially, this field can be set to any opaque value
199 required by the user. It is copied on clones.
200 */
201 void fz_set_user_context(fz_context *ctx, void *user);
202
203 /**
204 Read the user field from the context.
205 */
206 void *fz_user_context(fz_context *ctx);
207
208 /**
209 FIXME: Better not to expose fz_default_error_callback, and
210 fz_default_warning callback and to allow 'NULL' to be used
211 int fz_set_xxxx_callback to mean "defaults".
212
213 FIXME: Do we need/want functions like
214 fz_error_callback(ctx, message) to allow callers to inject
215 stuff into the error/warning streams?
216 */
217 /**
218 The default error callback. Declared publicly just so that the
219 error callback can be set back to this after it has been
220 overridden.
221 */
222 void fz_default_error_callback(void *user, const char *message);
223
224 /**
225 The default warning callback. Declared publicly just so that
226 the warning callback can be set back to this after it has been
227 overridden.
228 */
229 void fz_default_warning_callback(void *user, const char *message);
230
231 /**
232 Set the error callback. This will be called as part of the
233 exception handling.
234
235 The callback must not throw exceptions!
236 */
237 void fz_set_error_callback(fz_context *ctx, void (*print)(void *user, const char *message), void *user);
238
239 /**
240 Set the warning callback. This will be called as part of the
241 exception handling.
242
243 The callback must not throw exceptions!
244 */
245 void fz_set_warning_callback(fz_context *ctx, void (*print)(void *user, const char *message), void *user);
246
247 /**
248 In order to tune MuPDF's behaviour, certain functions can
249 (optionally) be provided by callers.
250 */
251
252 /**
253 Given the width and height of an image,
254 the subsample factor, and the subarea of the image actually
255 required, the caller can decide whether to decode the whole
256 image or just a subarea.
257
258 arg: The caller supplied opaque argument.
259
260 w, h: The width/height of the complete image.
261
262 l2factor: The log2 factor for subsampling (i.e. image will be
263 decoded to (w>>l2factor, h>>l2factor)).
264
265 subarea: The actual subarea required for the current operation.
266 The tuning function is allowed to increase this in size if
267 required.
268 */
269 typedef void (fz_tune_image_decode_fn)(void *arg, int w, int h, int l2factor, fz_irect *subarea);
270
271 /**
272 Given the source width and height of
273 image, together with the actual required width and height,
274 decide whether we should use mitchell scaling.
275
276 arg: The caller supplied opaque argument.
277
278 dst_w, dst_h: The actual width/height required on the target
279 device.
280
281 src_w, src_h: The source width/height of the image.
282
283 Return 0 not to use the Mitchell scaler, 1 to use the Mitchell
284 scaler. All other values reserved.
285 */
286 typedef int (fz_tune_image_scale_fn)(void *arg, int dst_w, int dst_h, int src_w, int src_h);
287
288 /**
289 Set the tuning function to use for
290 image decode.
291
292 image_decode: Function to use.
293
294 arg: Opaque argument to be passed to tuning function.
295 */
296 void fz_tune_image_decode(fz_context *ctx, fz_tune_image_decode_fn *image_decode, void *arg);
297
298 /**
299 Set the tuning function to use for
300 image scaling.
301
302 image_scale: Function to use.
303
304 arg: Opaque argument to be passed to tuning function.
305 */
306 void fz_tune_image_scale(fz_context *ctx, fz_tune_image_scale_fn *image_scale, void *arg);
307
308 /**
309 Get the number of bits of antialiasing we are
310 using (for graphics). Between 0 and 8.
311 */
312 int fz_aa_level(fz_context *ctx);
313
314 /**
315 Set the number of bits of antialiasing we should
316 use (for both text and graphics).
317
318 bits: The number of bits of antialiasing to use (values are
319 clamped to within the 0 to 8 range).
320 */
321 void fz_set_aa_level(fz_context *ctx, int bits);
322
323 /**
324 Get the number of bits of antialiasing we are
325 using for text. Between 0 and 8.
326 */
327 int fz_text_aa_level(fz_context *ctx);
328
329 /**
330 Set the number of bits of antialiasing we
331 should use for text.
332
333 bits: The number of bits of antialiasing to use (values are
334 clamped to within the 0 to 8 range).
335 */
336 void fz_set_text_aa_level(fz_context *ctx, int bits);
337
338 /**
339 Get the number of bits of antialiasing we are
340 using for graphics. Between 0 and 8.
341 */
342 int fz_graphics_aa_level(fz_context *ctx);
343
344 /**
345 Set the number of bits of antialiasing we
346 should use for graphics.
347
348 bits: The number of bits of antialiasing to use (values are
349 clamped to within the 0 to 8 range).
350 */
351 void fz_set_graphics_aa_level(fz_context *ctx, int bits);
352
353 /**
354 Get the minimum line width to be
355 used for stroked lines.
356
357 min_line_width: The minimum line width to use (in pixels).
358 */
359 float fz_graphics_min_line_width(fz_context *ctx);
360
361 /**
362 Set the minimum line width to be
363 used for stroked lines.
364
365 min_line_width: The minimum line width to use (in pixels).
366 */
367 void fz_set_graphics_min_line_width(fz_context *ctx, float min_line_width);
368
369 /**
370 Get the user stylesheet source text.
371 */
372 const char *fz_user_css(fz_context *ctx);
373
374 /**
375 Set the user stylesheet source text for use with HTML and EPUB.
376 */
377 void fz_set_user_css(fz_context *ctx, const char *text);
378
379 /**
380 Return whether to respect document styles in HTML and EPUB.
381 */
382 int fz_use_document_css(fz_context *ctx);
383
384 /**
385 Toggle whether to respect document styles in HTML and EPUB.
386 */
387 void fz_set_use_document_css(fz_context *ctx, int use);
388
389 /**
390 Enable icc profile based operation.
391 */
392 void fz_enable_icc(fz_context *ctx);
393
394 /**
395 Disable icc profile based operation.
396 */
397 void fz_disable_icc(fz_context *ctx);
398
399 /**
400 Memory Allocation and Scavenging:
401
402 All calls to MuPDF's allocator functions pass through to the
403 underlying allocators passed in when the initial context is
404 created, after locks are taken (using the supplied locking
405 function) to ensure that only one thread at a time calls
406 through.
407
408 If the underlying allocator fails, MuPDF attempts to make room
409 for the allocation by evicting elements from the store, then
410 retrying.
411
412 Any call to allocate may then result in several calls to the
413 underlying allocator, and result in elements that are only
414 referred to by the store being freed.
415 */
416
417 /**
418 Allocate memory for a structure, clear it, and tag the pointer
419 for Memento.
420
421 Throws exception in the event of failure to allocate.
422 */
423 #define fz_malloc_struct(CTX, TYPE) \
424 ((TYPE*)Memento_label(fz_calloc(CTX, 1, sizeof(TYPE)), #TYPE))
425
426 /**
427 Allocate uninitialized memory for an array of structures, and
428 tag the pointer for Memento. Does NOT clear the memory!
429
430 Throws exception in the event of failure to allocate.
431 */
432 #define fz_malloc_array(CTX, COUNT, TYPE) \
433 ((TYPE*)Memento_label(fz_malloc(CTX, (COUNT) * sizeof(TYPE)), #TYPE "[]"))
434 #define fz_realloc_array(CTX, OLD, COUNT, TYPE) \
435 ((TYPE*)Memento_label(fz_realloc(CTX, OLD, (COUNT) * sizeof(TYPE)), #TYPE "[]"))
436
437 /**
438 Allocate uninitialized memory of a given size.
439 Does NOT clear the memory!
440
441 May return NULL for size = 0.
442
443 Throws exception in the event of failure to allocate.
444 */
445 void *fz_malloc(fz_context *ctx, size_t size);
446
447 /**
448 Allocate array of memory of count entries of size bytes.
449 Clears the memory to zero.
450
451 Throws exception in the event of failure to allocate.
452 */
453 void *fz_calloc(fz_context *ctx, size_t count, size_t size);
454
455 /**
456 Reallocates a block of memory to given size. Existing contents
457 up to min(old_size,new_size) are maintained. The rest of the
458 block is uninitialised.
459
460 fz_realloc(ctx, NULL, size) behaves like fz_malloc(ctx, size).
461
462 fz_realloc(ctx, p, 0); behaves like fz_free(ctx, p).
463
464 Throws exception in the event of failure to allocate.
465 */
466 void *fz_realloc(fz_context *ctx, void *p, size_t size);
467
468 /**
469 Free a previously allocated block of memory.
470
471 fz_free(ctx, NULL) does nothing.
472
473 Never throws exceptions.
474 */
475 void fz_free(fz_context *ctx, void *p);
476
477 /**
478 fz_malloc equivalent that returns NULL rather than throwing
479 exceptions.
480 */
481 void *fz_malloc_no_throw(fz_context *ctx, size_t size);
482
483 /**
484 fz_calloc equivalent that returns NULL rather than throwing
485 exceptions.
486 */
487 void *fz_calloc_no_throw(fz_context *ctx, size_t count, size_t size);
488
489 /**
490 fz_realloc equivalent that returns NULL rather than throwing
491 exceptions.
492 */
493 void *fz_realloc_no_throw(fz_context *ctx, void *p, size_t size);
494
495 /**
496 Portable strdup implementation, using fz allocators.
497 */
498 char *fz_strdup(fz_context *ctx, const char *s);
499
500 /**
501 Fill block with len bytes of pseudo-randomness.
502 */
503 void fz_memrnd(fz_context *ctx, uint8_t *block, int len);
504
505
506 /* Implementation details: subject to change. */
507
508 /* Implementations exposed for speed, but considered private. */
509
510 void fz_var_imp(void *);
511 fz_jmp_buf *fz_push_try(fz_context *ctx);
512 int fz_do_try(fz_context *ctx);
513 int fz_do_always(fz_context *ctx);
514 int fz_do_catch(fz_context *ctx);
515
516 typedef struct
517 {
518 int state, code;
519 fz_jmp_buf buffer;
520 } fz_error_stack_slot;
521
522 typedef struct
523 {
524 fz_error_stack_slot *top;
525 fz_error_stack_slot stack[256];
526 int errcode;
527 void *print_user;
528 void (*print)(void *user, const char *message);
529 char message[256];
530 } fz_error_context;
531
532 typedef struct
533 {
534 void *print_user;
535 void (*print)(void *user, const char *message);
536 int count;
537 char message[256];
538 } fz_warn_context;
539
540 typedef struct
541 {
542 int hscale;
543 int vscale;
544 int scale;
545 int bits;
546 int text_bits;
547 float min_line_width;
548 } fz_aa_context;
549
550 struct fz_context
551 {
552 void *user;
553 fz_alloc_context alloc;
554 fz_locks_context locks;
555 fz_error_context error;
556 fz_warn_context warn;
557
558 /* unshared contexts */
559 fz_aa_context aa;
560 uint16_t seed48[7];
561 #if FZ_ENABLE_ICC
562 int icc_enabled;
563 #endif
564
565 /* TODO: should these be unshared? */
566 fz_document_handler_context *handler;
567 fz_style_context *style;
568 fz_tuning_context *tuning;
569
570 /* shared contexts */
571 fz_font_context *font;
572 fz_colorspace_context *colorspace;
573 fz_store *store;
574 fz_glyph_cache *glyph_cache;
575 };
576
577 fz_context *fz_new_context_imp(const fz_alloc_context *alloc, const fz_locks_context *locks, size_t max_store, const char *version);
578
579 /**
580 Lock one of the user supplied mutexes.
581 */
582 static inline void
fz_lock(fz_context * ctx,int lock)583 fz_lock(fz_context *ctx, int lock)
584 {
585 fz_lock_debug_lock(ctx, lock);
586 ctx->locks.lock(ctx->locks.user, lock);
587 }
588
589 /**
590 Unlock one of the user supplied mutexes.
591 */
592 static inline void
fz_unlock(fz_context * ctx,int lock)593 fz_unlock(fz_context *ctx, int lock)
594 {
595 fz_lock_debug_unlock(ctx, lock);
596 ctx->locks.unlock(ctx->locks.user, lock);
597 }
598
599 /* Lock-safe reference counting functions */
600
601 static inline void *
fz_keep_imp(fz_context * ctx,void * p,int * refs)602 fz_keep_imp(fz_context *ctx, void *p, int *refs)
603 {
604 if (p)
605 {
606 (void)Memento_checkIntPointerOrNull(refs);
607 fz_lock(ctx, FZ_LOCK_ALLOC);
608 if (*refs > 0)
609 {
610 (void)Memento_takeRef(p);
611 ++*refs;
612 }
613 fz_unlock(ctx, FZ_LOCK_ALLOC);
614 }
615 return p;
616 }
617
618 static inline void *
fz_keep_imp8(fz_context * ctx,void * p,int8_t * refs)619 fz_keep_imp8(fz_context *ctx, void *p, int8_t *refs)
620 {
621 if (p)
622 {
623 (void)Memento_checkBytePointerOrNull(refs);
624 fz_lock(ctx, FZ_LOCK_ALLOC);
625 if (*refs > 0)
626 {
627 (void)Memento_takeRef(p);
628 ++*refs;
629 }
630 fz_unlock(ctx, FZ_LOCK_ALLOC);
631 }
632 return p;
633 }
634
635 static inline void *
fz_keep_imp16(fz_context * ctx,void * p,int16_t * refs)636 fz_keep_imp16(fz_context *ctx, void *p, int16_t *refs)
637 {
638 if (p)
639 {
640 (void)Memento_checkShortPointerOrNull(refs);
641 fz_lock(ctx, FZ_LOCK_ALLOC);
642 if (*refs > 0)
643 {
644 (void)Memento_takeRef(p);
645 ++*refs;
646 }
647 fz_unlock(ctx, FZ_LOCK_ALLOC);
648 }
649 return p;
650 }
651
652 static inline int
fz_drop_imp(fz_context * ctx,void * p,int * refs)653 fz_drop_imp(fz_context *ctx, void *p, int *refs)
654 {
655 if (p)
656 {
657 int drop;
658 (void)Memento_checkIntPointerOrNull(refs);
659 fz_lock(ctx, FZ_LOCK_ALLOC);
660 if (*refs > 0)
661 {
662 (void)Memento_dropIntRef(p);
663 drop = --*refs == 0;
664 }
665 else
666 drop = 0;
667 fz_unlock(ctx, FZ_LOCK_ALLOC);
668 return drop;
669 }
670 return 0;
671 }
672
673 static inline int
fz_drop_imp8(fz_context * ctx,void * p,int8_t * refs)674 fz_drop_imp8(fz_context *ctx, void *p, int8_t *refs)
675 {
676 if (p)
677 {
678 int drop;
679 (void)Memento_checkBytePointerOrNull(refs);
680 fz_lock(ctx, FZ_LOCK_ALLOC);
681 if (*refs > 0)
682 {
683 (void)Memento_dropByteRef(p);
684 drop = --*refs == 0;
685 }
686 else
687 drop = 0;
688 fz_unlock(ctx, FZ_LOCK_ALLOC);
689 return drop;
690 }
691 return 0;
692 }
693
694 static inline int
fz_drop_imp16(fz_context * ctx,void * p,int16_t * refs)695 fz_drop_imp16(fz_context *ctx, void *p, int16_t *refs)
696 {
697 if (p)
698 {
699 int drop;
700 (void)Memento_checkShortPointerOrNull(refs);
701 fz_lock(ctx, FZ_LOCK_ALLOC);
702 if (*refs > 0)
703 {
704 (void)Memento_dropShortRef(p);
705 drop = --*refs == 0;
706 }
707 else
708 drop = 0;
709 fz_unlock(ctx, FZ_LOCK_ALLOC);
710 return drop;
711 }
712 return 0;
713 }
714
715 #endif
716