Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7858 views
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
7
/*
8
Contexts
9
*/
10
11
typedef struct fz_alloc_context_s fz_alloc_context;
12
typedef struct fz_error_context_s fz_error_context;
13
typedef struct fz_id_context_s fz_id_context;
14
typedef struct fz_warn_context_s fz_warn_context;
15
typedef struct fz_font_context_s fz_font_context;
16
typedef struct fz_colorspace_context_s fz_colorspace_context;
17
typedef struct fz_aa_context_s fz_aa_context;
18
typedef struct fz_locks_context_s fz_locks_context;
19
typedef struct fz_store_s fz_store;
20
typedef struct fz_glyph_cache_s fz_glyph_cache;
21
typedef struct fz_document_handler_context_s fz_document_handler_context;
22
typedef struct fz_context_s fz_context;
23
24
struct fz_alloc_context_s
25
{
26
void *user;
27
void *(*malloc)(void *, unsigned int);
28
void *(*realloc)(void *, void *, unsigned int);
29
void (*free)(void *, void *);
30
};
31
32
struct fz_error_context_s
33
{
34
int top;
35
struct {
36
int code;
37
fz_jmp_buf buffer;
38
} stack[256];
39
int errcode;
40
char message[256];
41
};
42
43
void fz_var_imp(void *);
44
#define fz_var(var) fz_var_imp((void *)&(var))
45
46
/*
47
Exception macro definitions. Just treat these as a black box - pay no
48
attention to the man behind the curtain.
49
*/
50
51
#define fz_try(ctx) \
52
if (fz_push_try(ctx->error) && \
53
((ctx->error->stack[ctx->error->top].code = fz_setjmp(ctx->error->stack[ctx->error->top].buffer)) == 0))\
54
{ do {
55
56
#define fz_always(ctx) \
57
} while (0); \
58
} \
59
if (ctx->error->stack[ctx->error->top].code < 3) \
60
{ \
61
ctx->error->stack[ctx->error->top].code++; \
62
do { \
63
64
#define fz_catch(ctx) \
65
} while(0); \
66
} \
67
if (ctx->error->stack[ctx->error->top--].code > 1)
68
69
int fz_push_try(fz_error_context *ex);
70
FZ_NORETURN void fz_throw(fz_context *, int errcode, const char *, ...) __printflike(3, 4);
71
FZ_NORETURN void fz_rethrow(fz_context *);
72
FZ_NORETURN void fz_rethrow_message(fz_context *, const char *, ...) __printflike(2, 3);
73
void fz_warn(fz_context *ctx, const char *fmt, ...) __printflike(2, 3);
74
const char *fz_caught_message(fz_context *ctx);
75
int fz_caught(fz_context *ctx);
76
void fz_rethrow_if(fz_context *ctx, int errcode);
77
78
enum
79
{
80
FZ_ERROR_NONE = 0,
81
FZ_ERROR_GENERIC = 1,
82
FZ_ERROR_SYNTAX = 2,
83
FZ_ERROR_TRYLATER = 3,
84
FZ_ERROR_ABORT = 4,
85
FZ_ERROR_COUNT
86
};
87
88
/*
89
fz_flush_warnings: Flush any repeated warnings.
90
91
Repeated warnings are buffered, counted and eventually printed
92
along with the number of repetitions. Call fz_flush_warnings
93
to force printing of the latest buffered warning and the
94
number of repetitions, for example to make sure that all
95
warnings are printed before exiting an application.
96
97
Does not throw exceptions.
98
*/
99
void fz_flush_warnings(fz_context *ctx);
100
101
struct fz_context_s
102
{
103
fz_alloc_context *alloc;
104
fz_locks_context *locks;
105
fz_id_context *id;
106
fz_error_context *error;
107
fz_warn_context *warn;
108
fz_font_context *font;
109
fz_colorspace_context *colorspace;
110
fz_aa_context *aa;
111
fz_store *store;
112
fz_glyph_cache *glyph_cache;
113
fz_document_handler_context *handler;
114
};
115
116
/*
117
Specifies the maximum size in bytes of the resource store in
118
fz_context. Given as argument to fz_new_context.
119
120
FZ_STORE_UNLIMITED: Let resource store grow unbounded.
121
122
FZ_STORE_DEFAULT: A reasonable upper bound on the size, for
123
devices that are not memory constrained.
124
*/
125
enum {
126
FZ_STORE_UNLIMITED = 0,
127
FZ_STORE_DEFAULT = 256 << 20,
128
};
129
130
/*
131
fz_new_context: Allocate context containing global state.
132
133
The global state contains an exception stack, resource store,
134
etc. Most functions in MuPDF take a context argument to be
135
able to reference the global state. See fz_drop_context for
136
freeing an allocated context.
137
138
alloc: Supply a custom memory allocator through a set of
139
function pointers. Set to NULL for the standard library
140
allocator. The context will keep the allocator pointer, so the
141
data it points to must not be modified or freed during the
142
lifetime of the context.
143
144
locks: Supply a set of locks and functions to lock/unlock
145
them, intended for multi-threaded applications. Set to NULL
146
when using MuPDF in a single-threaded applications. The
147
context will keep the locks pointer, so the data it points to
148
must not be modified or freed during the lifetime of the
149
context.
150
151
max_store: Maximum size in bytes of the resource store, before
152
it will start evicting cached resources such as fonts and
153
images. FZ_STORE_UNLIMITED can be used if a hard limit is not
154
desired. Use FZ_STORE_DEFAULT to get a reasonable size.
155
156
Does not throw exceptions, but may return NULL.
157
*/
158
fz_context *fz_new_context_imp(fz_alloc_context *alloc, fz_locks_context *locks, unsigned int max_store, const char *version);
159
160
#define fz_new_context(alloc, locks, max_store) fz_new_context_imp(alloc, locks, max_store, FZ_VERSION)
161
162
/*
163
fz_clone_context: Make a clone of an existing context.
164
165
This function is meant to be used in multi-threaded
166
applications where each thread requires its own context, yet
167
parts of the global state, for example caching, is shared.
168
169
ctx: Context obtained from fz_new_context to make a copy of.
170
ctx must have had locks and lock/functions setup when created.
171
The two contexts will share the memory allocator, resource
172
store, locks and lock/unlock functions. They will each have
173
their own exception stacks though.
174
175
Does not throw exception, but may return NULL.
176
*/
177
fz_context *fz_clone_context(fz_context *ctx);
178
179
/*
180
fz_drop_context: Free a context and its global state.
181
182
The context and all of its global state is freed, and any
183
buffered warnings are flushed (see fz_flush_warnings). If NULL
184
is passed in nothing will happen.
185
186
Does not throw exceptions.
187
*/
188
void fz_drop_context(fz_context *ctx);
189
190
/*
191
fz_aa_level: Get the number of bits of antialiasing we are
192
using. Between 0 and 8.
193
*/
194
int fz_aa_level(fz_context *ctx);
195
196
/*
197
fz_set_aa_level: Set the number of bits of antialiasing we should use.
198
199
bits: The number of bits of antialiasing to use (values are clamped
200
to within the 0 to 8 range).
201
*/
202
void fz_set_aa_level(fz_context *ctx, int bits);
203
204
/*
205
Locking functions
206
207
MuPDF is kept deliberately free of any knowledge of particular
208
threading systems. As such, in order for safe multi-threaded
209
operation, we rely on callbacks to client provided functions.
210
211
A client is expected to provide FZ_LOCK_MAX number of mutexes,
212
and a function to lock/unlock each of them. These may be
213
recursive mutexes, but do not have to be.
214
215
If a client does not intend to use multiple threads, then it
216
may pass NULL instead of a lock structure.
217
218
In order to avoid deadlocks, we have one simple rule
219
internally as to how we use locks: We can never take lock n
220
when we already hold any lock i, where 0 <= i <= n. In order
221
to verify this, we have some debugging code, that can be
222
enabled by defining FITZ_DEBUG_LOCKING.
223
*/
224
225
struct fz_locks_context_s
226
{
227
void *user;
228
void (*lock)(void *user, int lock);
229
void (*unlock)(void *user, int lock);
230
};
231
232
enum {
233
FZ_LOCK_ALLOC = 0,
234
FZ_LOCK_FILE, /* Unused now */
235
FZ_LOCK_FREETYPE,
236
FZ_LOCK_GLYPHCACHE,
237
FZ_LOCK_MAX
238
};
239
240
/*
241
Memory Allocation and Scavenging:
242
243
All calls to MuPDFs allocator functions pass through to the
244
underlying allocators passed in when the initial context is
245
created, after locks are taken (using the supplied locking function)
246
to ensure that only one thread at a time calls through.
247
248
If the underlying allocator fails, MuPDF attempts to make room for
249
the allocation by evicting elements from the store, then retrying.
250
251
Any call to allocate may then result in several calls to the underlying
252
allocator, and result in elements that are only referred to by the
253
store being freed.
254
*/
255
256
/*
257
fz_malloc: Allocate a block of memory (with scavenging)
258
259
size: The number of bytes to allocate.
260
261
Returns a pointer to the allocated block. May return NULL if size is
262
0. Throws exception on failure to allocate.
263
*/
264
void *fz_malloc(fz_context *ctx, unsigned int size);
265
266
/*
267
fz_calloc: Allocate a zeroed block of memory (with scavenging)
268
269
count: The number of objects to allocate space for.
270
271
size: The size (in bytes) of each object.
272
273
Returns a pointer to the allocated block. May return NULL if size
274
and/or count are 0. Throws exception on failure to allocate.
275
*/
276
void *fz_calloc(fz_context *ctx, unsigned int count, unsigned int size);
277
278
/*
279
fz_malloc_struct: Allocate storage for a structure (with scavenging),
280
clear it, and (in Memento builds) tag the pointer as belonging to a
281
struct of this type.
282
283
CTX: The context.
284
285
STRUCT: The structure type.
286
287
Returns a pointer to allocated (and cleared) structure. Throws
288
exception on failure to allocate.
289
*/
290
#define fz_malloc_struct(CTX, STRUCT) \
291
((STRUCT *)Memento_label(fz_calloc(CTX,1,sizeof(STRUCT)), #STRUCT))
292
293
/*
294
fz_malloc_array: Allocate a block of (non zeroed) memory (with
295
scavenging). Equivalent to fz_calloc without the memory clearing.
296
297
count: The number of objects to allocate space for.
298
299
size: The size (in bytes) of each object.
300
301
Returns a pointer to the allocated block. May return NULL if size
302
and/or count are 0. Throws exception on failure to allocate.
303
*/
304
void *fz_malloc_array(fz_context *ctx, unsigned int count, unsigned int size);
305
306
/*
307
fz_resize_array: Resize a block of memory (with scavenging).
308
309
p: The existing block to resize
310
311
count: The number of objects to resize to.
312
313
size: The size (in bytes) of each object.
314
315
Returns a pointer to the resized block. May return NULL if size
316
and/or count are 0. Throws exception on failure to resize (original
317
block is left unchanged).
318
*/
319
void *fz_resize_array(fz_context *ctx, void *p, unsigned int count, unsigned int size);
320
321
/*
322
fz_strdup: Duplicate a C string (with scavenging)
323
324
s: The string to duplicate.
325
326
Returns a pointer to a duplicated string. Throws exception on failure
327
to allocate.
328
*/
329
char *fz_strdup(fz_context *ctx, const char *s);
330
331
/*
332
fz_free: Frees an allocation.
333
334
Does not throw exceptions.
335
*/
336
void fz_free(fz_context *ctx, void *p);
337
338
/*
339
fz_malloc_no_throw: Allocate a block of memory (with scavenging)
340
341
size: The number of bytes to allocate.
342
343
Returns a pointer to the allocated block. May return NULL if size is
344
0. Returns NULL on failure to allocate.
345
*/
346
void *fz_malloc_no_throw(fz_context *ctx, unsigned int size);
347
348
/*
349
fz_calloc_no_throw: Allocate a zeroed block of memory (with scavenging)
350
351
count: The number of objects to allocate space for.
352
353
size: The size (in bytes) of each object.
354
355
Returns a pointer to the allocated block. May return NULL if size
356
and/or count are 0. Returns NULL on failure to allocate.
357
*/
358
void *fz_calloc_no_throw(fz_context *ctx, unsigned int count, unsigned int size);
359
360
/*
361
fz_malloc_array_no_throw: Allocate a block of (non zeroed) memory
362
(with scavenging). Equivalent to fz_calloc_no_throw without the
363
memory clearing.
364
365
count: The number of objects to allocate space for.
366
367
size: The size (in bytes) of each object.
368
369
Returns a pointer to the allocated block. May return NULL if size
370
and/or count are 0. Returns NULL on failure to allocate.
371
*/
372
void *fz_malloc_array_no_throw(fz_context *ctx, unsigned int count, unsigned int size);
373
374
/*
375
fz_resize_array_no_throw: Resize a block of memory (with scavenging).
376
377
p: The existing block to resize
378
379
count: The number of objects to resize to.
380
381
size: The size (in bytes) of each object.
382
383
Returns a pointer to the resized block. May return NULL if size
384
and/or count are 0. Returns NULL on failure to resize (original
385
block is left unchanged).
386
*/
387
void *fz_resize_array_no_throw(fz_context *ctx, void *p, unsigned int count, unsigned int size);
388
389
/*
390
fz_strdup_no_throw: Duplicate a C string (with scavenging)
391
392
s: The string to duplicate.
393
394
Returns a pointer to a duplicated string. Returns NULL on failure
395
to allocate.
396
*/
397
char *fz_strdup_no_throw(fz_context *ctx, const char *s);
398
399
/*
400
fz_gen_id: Generate an id (guaranteed unique within this family of
401
contexts).
402
*/
403
int fz_gen_id(fz_context *ctx);
404
405
struct fz_warn_context_s
406
{
407
char message[256];
408
int count;
409
};
410
411
fz_context *fz_clone_context_internal(fz_context *ctx);
412
413
void fz_new_aa_context(fz_context *ctx);
414
void fz_drop_aa_context(fz_context *ctx);
415
void fz_copy_aa_context(fz_context *dst, fz_context *src);
416
417
void fz_new_document_handler_context(fz_context *ctx);
418
void fz_drop_document_handler_context(fz_context *ctx);
419
fz_document_handler_context *fz_keep_document_handler_context(fz_context *ctx);
420
421
/* Default allocator */
422
extern fz_alloc_context fz_alloc_default;
423
424
/* Default locks */
425
extern fz_locks_context fz_locks_default;
426
427
#if defined(MEMENTO) || defined(DEBUG)
428
#define FITZ_DEBUG_LOCKING
429
#endif
430
431
#ifdef FITZ_DEBUG_LOCKING
432
433
void fz_assert_lock_held(fz_context *ctx, int lock);
434
void fz_assert_lock_not_held(fz_context *ctx, int lock);
435
void fz_lock_debug_lock(fz_context *ctx, int lock);
436
void fz_lock_debug_unlock(fz_context *ctx, int lock);
437
438
#else
439
440
#define fz_assert_lock_held(A,B) do { } while (0)
441
#define fz_assert_lock_not_held(A,B) do { } while (0)
442
#define fz_lock_debug_lock(A,B) do { } while (0)
443
#define fz_lock_debug_unlock(A,B) do { } while (0)
444
445
#endif /* !FITZ_DEBUG_LOCKING */
446
447
static inline void
448
fz_lock(fz_context *ctx, int lock)
449
{
450
fz_lock_debug_lock(ctx, lock);
451
ctx->locks->lock(ctx->locks->user, lock);
452
}
453
454
static inline void
455
fz_unlock(fz_context *ctx, int lock)
456
{
457
fz_lock_debug_unlock(ctx, lock);
458
ctx->locks->unlock(ctx->locks->user, lock);
459
}
460
461
static inline void *
462
fz_keep_imp(fz_context *ctx, void *p, int *refs)
463
{
464
if (p)
465
{
466
fz_lock(ctx, FZ_LOCK_ALLOC);
467
if (*refs > 0)
468
++*refs;
469
fz_unlock(ctx, FZ_LOCK_ALLOC);
470
}
471
return p;
472
}
473
474
static inline void *
475
fz_keep_imp8(fz_context *ctx, void *p, int8_t *refs)
476
{
477
if (p)
478
{
479
fz_lock(ctx, FZ_LOCK_ALLOC);
480
if (*refs > 0)
481
++*refs;
482
fz_unlock(ctx, FZ_LOCK_ALLOC);
483
}
484
return p;
485
}
486
487
static inline int
488
fz_drop_imp(fz_context *ctx, void *p, int *refs)
489
{
490
if (p)
491
{
492
int drop;
493
fz_lock(ctx, FZ_LOCK_ALLOC);
494
if (*refs > 0)
495
drop = --*refs == 0;
496
else
497
drop = 0;
498
fz_unlock(ctx, FZ_LOCK_ALLOC);
499
return drop;
500
}
501
return 0;
502
}
503
504
static inline int
505
fz_drop_imp8(fz_context *ctx, void *p, int8_t *refs)
506
{
507
if (p)
508
{
509
int drop;
510
fz_lock(ctx, FZ_LOCK_ALLOC);
511
if (*refs > 0)
512
drop = --*refs == 0;
513
else
514
drop = 0;
515
fz_unlock(ctx, FZ_LOCK_ALLOC);
516
return drop;
517
}
518
return 0;
519
}
520
521
#endif
522
523