diff options
Diffstat (limited to 'fitz/fitz.h')
-rw-r--r-- | fitz/fitz.h | 2567 |
1 files changed, 1444 insertions, 1123 deletions
diff --git a/fitz/fitz.h b/fitz/fitz.h index d2672031..26751824 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -1,9 +1,9 @@ -#ifndef _FITZ_H_ -#define _FITZ_H_ +#ifndef FITZ_H +#define FITZ_H /* - * Include the standard libc headers. - */ + Include the standard libc headers. +*/ #include <stdio.h> #include <stdlib.h> @@ -15,13 +15,27 @@ #include <assert.h> #include <errno.h> #include <limits.h> /* INT_MAX & co */ -#include <float.h> /* FLT_EPSILON */ +#include <float.h> /* FLT_EPSILON, FLT_MAX & co */ #include <fcntl.h> /* O_RDONLY & co */ #include <setjmp.h> #include "memento.h" +/* + Some versions of setjmp/longjmp (notably MacOSX and ios) store/restore + signal handlers too. We don't alter signal handlers within mupdf, so + there is no need for us to store/restore - hence we use the + non-restoring variants. This makes a large speed difference. +*/ +#ifdef __APPLE__ +#define fz_setjmp _setjmp +#define fz_longjmp _longjmp +#else +#define fz_setjmp setjmp +#define fz_longjmp longjmp +#endif + #ifdef __ANDROID__ #include <android/log.h> #define LOG_TAG "libmupdf" @@ -38,10 +52,11 @@ #define MIN(a,b) ( (a) < (b) ? (a) : (b) ) #define MAX(a,b) ( (a) > (b) ? (a) : (b) ) #define CLAMP(x,a,b) ( (x) > (b) ? (b) : ( (x) < (a) ? (a) : (x) ) ) +#define DIV_BY_ZERO(a, b, min, max) (((a) < 0) ^ ((b) < 0) ? (min) : (max)) /* - * Some differences in libc can be smoothed over - */ + Some differences in libc can be smoothed over +*/ #ifdef _MSC_VER /* Microsoft Visual C */ @@ -54,7 +69,7 @@ int gettimeofday(struct timeval *tv, struct timezone *tz); #define snprintf _snprintf -#define strtoll _strtoi64 +#define isnan _isnan #else /* Unix or close enough */ @@ -75,8 +90,8 @@ int gettimeofday(struct timeval *tv, struct timezone *tz); #endif /* - * Variadic macros, inline and restrict keywords - */ + Variadic macros, inline and restrict keywords +*/ #if __STDC_VERSION__ == 199901L /* C99 */ #elif _MSC_VER >= 1500 /* MSVC 9 or newer */ @@ -91,8 +106,8 @@ int gettimeofday(struct timeval *tv, struct timezone *tz); #endif /* - * GCC can do type checking of printf strings - */ + GCC can do type checking of printf strings +*/ #ifndef __printflike #if __GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7 @@ -103,7 +118,9 @@ int gettimeofday(struct timeval *tv, struct timezone *tz); #endif #endif -/* Contexts */ +/* + Contexts +*/ typedef struct fz_alloc_context_s fz_alloc_context; typedef struct fz_error_context_s fz_error_context; @@ -123,9 +140,6 @@ struct fz_alloc_context_s void (*free)(void *, void *); }; -/* Default allocator */ -extern fz_alloc_context fz_alloc_default; - struct fz_error_context_s { int top; @@ -140,139 +154,13 @@ void fz_var_imp(void *); #define fz_var(var) fz_var_imp((void *)&(var)) /* - -MuPDF uses a set of exception handling macros to simplify error return -and cleanup. Conceptually, they work a lot like C++'s try/catch system, -but do not require any special compiler support. - -The basic formulation is as follows: - - fz_try(ctx) - { - // Try to perform a task. Never 'return', 'goto' or 'longjmp' out - // of here. 'break' may be used to safely exit (just) the try block - // scope. - } - fz_always(ctx) - { - // Any code here is always executed, regardless of whether an - // exception was thrown within the try or not. Never 'return', 'goto' - // or longjmp out from here. 'break' may be used to safely exit (just) - // the always block scope. - } - fz_catch(ctx) - { - // This code is called (after any always block) only if something - // within the fz_try block (including any functions it called) threw - // an exception. The code here is expected to handle the exception - // (maybe record/report the error, cleanup any stray state etc) and - // can then either exit the block, or pass on the exception to a - // higher level (enclosing) fz_try block (using fz_throw, or - // fz_rethrow). - } - -The fz_always block is optional, and can safely be omitted. - -The macro based nature of this system has 3 main limitations: - -1) Never return from within try (or 'goto' or longjmp out of it). - This upsets the internal housekeeping of the macros and will cause - problems later on. The code will detect such things happening, but - by then it is too late to give a helpful error report as to where the - original infraction occurred. - -2) The fz_try(ctx) { ... } fz_always(ctx) { ... } fz_catch(ctx) { ... } - is not one atomic C statement. That is to say, if you do: - - if (condition) - fz_try(ctx) { ... } - fz_catch(ctx) { ... } - - then you will not get what you want. Use the following instead: - - if (condition) { - fz_try(ctx) { ... } - fz_catch(ctx) { ... } - } - -3) The macros are implemented using setjmp and longjmp, and so the standard - C restrictions on the use of those functions apply to fz_try/fz_catch - too. In particular, any "truly local" variable that is set between the - start of fz_try and something in fz_try throwing an exception may become - undefined as part of the process of throwing that exception. - - As a way of mitigating this problem, we provide an fz_var() macro that - tells the compiler to ensure that that variable is not unset by the - act of throwing the exception. - -A model piece of code using these macros then might be: - - house build_house(plans *p) - { - material m = NULL; - walls w = NULL; - roof r = NULL; - house h = NULL; - tiles t = make_tiles(); - - fz_var(w); - fz_var(r); - fz_var(h); - - fz_try(ctx) - { - fz_try(ctx) - { - m = make_bricks(); - } - fz_catch(ctx) - { - // No bricks available, make do with straw? - m = make_straw(); - } - w = make_walls(m, p); - r = make_roof(m, t); - h = combine(w, r); // Note, NOT: return combine(w,r); - } - fz_always(ctx) - { - drop_walls(w); - drop_roof(r); - drop_material(m); - drop_tiles(t); - } - fz_catch(ctx) - { - fz_throw(ctx, "build_house failed"); - } - return h; - } - -Things to note about this: - -a) If make_tiles throws an exception, this will immediately be handled - by some higher level exception handler. If it succeeds, t will be - set before fz_try starts, so there is no need to fz_var(t); - -b) We try first off to make some bricks as our building material. If - this fails, we fall back to straw. If this fails, we'll end up in - the fz_catch, and the process will fail neatly. - -c) We assume in this code that combine takes new reference to both the - walls and the roof it uses, and therefore that w and r need to be - cleaned up in all cases. - -d) We assume the standard C convention that it is safe to destroy - NULL things. - + Exception macro definitions. Just treat these as a black box - pay no + attention to the man behind the curtain. */ -/* Exception macro definitions. Just treat these as a black box - pay no - * attention to the man behind the curtain. */ - #define fz_try(ctx) \ if (fz_push_try(ctx->error), \ - (ctx->error->stack[ctx->error->top].code = setjmp(ctx->error->stack[ctx->error->top].buffer)) == 0) \ + (ctx->error->stack[ctx->error->top].code = fz_setjmp(ctx->error->stack[ctx->error->top].buffer)) == 0) \ { do { #define fz_always(ctx) \ @@ -285,78 +173,22 @@ d) We assume the standard C convention that it is safe to destroy } \ if (ctx->error->stack[ctx->error->top--].code) -/* - -We also include a couple of other formulations of the macros, with -different strengths and weaknesses. These will be removed shortly, but -I want them in git for at least 1 revision so I have a record of them. - -A formulation of try/always/catch that lifts limitation 2 above, but -has problems when try/catch are nested in the same function; the inner -nestings need to use fz_always_(ctx, label) and fz_catch_(ctx, label) -instead. This was held as too high a price to pay to drop limitation 2. - -#define fz_try(ctx) \ - if (fz_push_try(ctx->error), \ - (ctx->error->stack[ctx->error->top].code = setjmp(ctx->error->stack[ctx->error->top].buffer)) == 0) \ - { do { - -#define fz_always_(ctx, label) \ - } while (0); \ - goto ALWAYS_LABEL_ ## label ; \ - } \ - else if (ctx->error->stack[ctx->error->top].code) \ - { ALWAYS_LABEL_ ## label : \ - do { - -#define fz_catch_(ctx, label) \ - } while(0); \ - if (ctx->error->stack[ctx->error->top--].code) \ - goto CATCH_LABEL_ ## label; \ - } \ - else if (ctx->error->top--, 1) \ - CATCH_LABEL ## label: - -#define fz_always(ctx) fz_always_(ctx, TOP) -#define fz_catch(ctx) fz_catch_(ctx, TOP) - -Another alternative formulation, that again removes limitation 2, but at -the cost of an always block always costing us 1 extra longjmp per -execution. Again this was felt to be too high a cost to use. - -#define fz_try(ctx) \ - if (fz_push_try(ctx->error), \ - (ctx->error->stack[ctx->error->top].code = setjmp(ctx->error->stack[ctx->error->top].buffer)) == 0) \ - { do { - -#define fz_always(ctx) \ - } while (0); \ - longjmp(ctx->error->stack[ctx->error->top].buffer, 3); \ - } \ - else if (ctx->error->stack[ctx->error->top].code & 1) \ - { do { - -#define fz_catch(ctx) \ - } while(0); \ - if (ctx->error->stack[ctx->error->top].code == 1) \ - longjmp(ctx->error->stack[ctx->error->top].buffer, 2); \ - ctx->error->top--;\ - } \ - else if (ctx->error->top--, 1) - -*/ - void fz_push_try(fz_error_context *ex); void fz_throw(fz_context *, char *, ...) __printflike(2, 3); void fz_rethrow(fz_context *); +void fz_warn(fz_context *ctx, char *fmt, ...) __printflike(2, 3); -struct fz_warn_context_s -{ - char message[256]; - int count; -}; +/* + fz_flush_warnings: Flush any repeated warnings. -void fz_warn(fz_context *ctx, char *fmt, ...) __printflike(2, 3); + Repeated warnings are buffered, counted and eventually printed + along with the number of repetitions. Call fz_flush_warnings + to force printing of the latest buffered warning and the + number of repetitions, for example to make sure that all + warnings are printed before exiting an application. + + Does not throw exceptions. +*/ void fz_flush_warnings(fz_context *ctx); struct fz_context_s @@ -371,42 +203,118 @@ struct fz_context_s fz_glyph_cache *glyph_cache; }; +/* + Specifies the maximum size in bytes of the resource store in + fz_context. Given as argument to fz_new_context. + + FZ_STORE_UNLIMITED: Let resource store grow unbounded. + + FZ_STORE_DEFAULT: A reasonable upper bound on the size, for + devices that are not memory constrained. +*/ +enum { + FZ_STORE_UNLIMITED = 0, + FZ_STORE_DEFAULT = 256 << 20, +}; + +/* + fz_new_context: Allocate context containing global state. + + The global state contains an exception stack, resource store, + etc. Most functions in MuPDF take a context argument to be + able to reference the global state. See fz_free_context for + freeing an allocated context. + + alloc: Supply a custom memory allocator through a set of + function pointers. Set to NULL for the standard library + allocator. The context will keep the allocator pointer, so the + data it points to must not be modified or freed during the + lifetime of the context. + + locks: Supply a set of locks and functions to lock/unlock + them, intended for multi-threaded applications. Set to NULL + when using MuPDF in a single-threaded applications. The + context will keep the locks pointer, so the data it points to + must not be modified or freed during the lifetime of the + context. + + max_store: Maximum size in bytes of the resource store, before + it will start evicting cached resources such as fonts and + images. FZ_STORE_UNLIMITED can be used if a hard limit is not + desired. Use FZ_STORE_DEFAULT to get a reasonable size. + + Does not throw exceptions, but may return NULL. +*/ fz_context *fz_new_context(fz_alloc_context *alloc, fz_locks_context *locks, unsigned int max_store); + +/* + fz_clone_context: Make a clone of an existing context. + + This function is meant to be used in multi-threaded + applications where each thread requires its own context, yet + parts of the global state, for example caching, is shared. + + ctx: Context obtained from fz_new_context to make a copy of. + ctx must have had locks and lock/functions setup when created. + The two contexts will share the memory allocator, resource + store, locks and lock/unlock functions. They will each have + their own exception stacks though. + + Does not throw exception, but may return NULL. +*/ fz_context *fz_clone_context(fz_context *ctx); -fz_context *fz_clone_context_internal(fz_context *ctx); + +/* + fz_free_context: Free a context and its global state. + + The context and all of its global state is freed, and any + buffered warnings are flushed (see fz_flush_warnings). If NULL + is passed in nothing will happen. + + Does not throw exceptions. +*/ void fz_free_context(fz_context *ctx); -void fz_new_aa_context(fz_context *ctx); -void fz_free_aa_context(fz_context *ctx); - -/* Locking functions - * - * MuPDF is kept deliberately free of any knowledge of particular threading - * systems. As such, in order for safe multi-threaded operation, we rely on - * callbacks to client provided functions. - * - * A client is expected to provide FZ_LOCK_MAX mutexes, and a function to - * lock/unlock each of them. These may be recursive mutexes, but do not have - * to be. - * - * If a client does not intend to use multiple threads, then it may pass - * NULL instead of the address of a lock structure. - * - * In order to avoid deadlocks, we have 1 simple rules internally as to how - * we use locks: We can never take lock n when we already hold any lock i, - * where 0 <= i <= n. In order to verify this, we have some debugging code - * built in, that is enabled by defining FITZ_DEBUG_LOCKING. - */ +/* + fz_aa_level: Get the number of bits of antialiasing we are + using. Between 0 and 8. +*/ +int fz_aa_level(fz_context *ctx); -#if defined(MEMENTO) || defined(DEBUG) -#define FITZ_DEBUG_LOCKING -#endif +/* + fz_set_aa_level: Set the number of bits of antialiasing we should use. + + bits: The number of bits of antialiasing to use (values are clamped + to within the 0 to 8 range). +*/ +void fz_set_aa_level(fz_context *ctx, int bits); + +/* + Locking functions + + MuPDF is kept deliberately free of any knowledge of particular + threading systems. As such, in order for safe multi-threaded + operation, we rely on callbacks to client provided functions. + + A client is expected to provide FZ_LOCK_MAX number of mutexes, + and a function to lock/unlock each of them. These may be + recursive mutexes, but do not have to be. + + If a client does not intend to use multiple threads, then it + may pass NULL instead of a lock structure. + + In order to avoid deadlocks, we have one simple rule + internally as to how we use locks: We can never take lock n + when we already hold any lock i, where 0 <= i <= n. In order + to verify this, we have some debugging code, that can be + enabled by defining FITZ_DEBUG_LOCKING. +*/ struct fz_locks_context_s { void *user; - void (*lock)(void *, int); - void (*unlock)(void *, int); + void (*lock)(void *user, int lock); + void (*unlock)(void *user, int lock); }; enum { @@ -417,1076 +325,1257 @@ enum { FZ_LOCK_MAX }; -/* Default locks */ -extern fz_locks_context fz_locks_default; +/* + Memory Allocation and Scavenging: -#ifdef FITZ_DEBUG_LOCKING + All calls to MuPDFs allocator functions pass through to the + underlying allocators passed in when the initial context is + created, after locks are taken (using the supplied locking function) + to ensure that only one thread at a time calls through. -void fz_assert_lock_held(fz_context *ctx, int lock); -void fz_assert_lock_not_held(fz_context *ctx, int lock); -void fz_lock_debug_lock(fz_context *ctx, int lock); -void fz_lock_debug_unlock(fz_context *ctx, int lock); + If the underlying allocator fails, MuPDF attempts to make room for + the allocation by evicting elements from the store, then retrying. -#else + Any call to allocate may then result in several calls to the underlying + allocator, and result in elements that are only referred to by the + store being freed. +*/ -#define fz_assert_lock_held(A,B) do { } while (0) -#define fz_assert_lock_not_held(A,B) do { } while (0) -#define fz_lock_debug_lock(A,B) do { } while (0) -#define fz_lock_debug_unlock(A,B) do { } while (0) +/* + fz_malloc: Allocate a block of memory (with scavenging) -#endif /* !FITZ_DEBUG_LOCKING */ + size: The number of bytes to allocate. -static inline void -fz_lock(fz_context *ctx, int lock) -{ - fz_lock_debug_lock(ctx, lock); - ctx->locks->lock(ctx->locks->user, lock); -} + Returns a pointer to the allocated block. May return NULL if size is + 0. Throws exception on failure to allocate. +*/ +void *fz_malloc(fz_context *ctx, unsigned int size); -static inline void -fz_unlock(fz_context *ctx, int lock) -{ - fz_lock_debug_unlock(ctx, lock); - ctx->locks->unlock(ctx->locks->user, lock); -} +/* + fz_calloc: Allocate a zeroed block of memory (with scavenging) + + count: The number of objects to allocate space for. + size: The size (in bytes) of each object. + + Returns a pointer to the allocated block. May return NULL if size + and/or count are 0. Throws exception on failure to allocate. +*/ +void *fz_calloc(fz_context *ctx, unsigned int count, unsigned int size); /* - * Basic runtime and utility functions - */ + fz_malloc_array: Allocate a block of (non zeroed) memory (with + scavenging). Equivalent to fz_calloc without the memory clearing. -/* memory allocation */ + count: The number of objects to allocate space for. -/* The following throw exceptions on failure to allocate */ -void *fz_malloc(fz_context *ctx, unsigned int size); -void *fz_calloc(fz_context *ctx, unsigned int count, unsigned int size); + size: The size (in bytes) of each object. + + Returns a pointer to the allocated block. May return NULL if size + and/or count are 0. Throws exception on failure to allocate. +*/ void *fz_malloc_array(fz_context *ctx, unsigned int count, unsigned int size); + +/* + fz_resize_array: Resize a block of memory (with scavenging). + + p: The existing block to resize + + count: The number of objects to resize to. + + size: The size (in bytes) of each object. + + Returns a pointer to the resized block. May return NULL if size + and/or count are 0. Throws exception on failure to resize (original + block is left unchanged). +*/ void *fz_resize_array(fz_context *ctx, void *p, unsigned int count, unsigned int size); + +/* + fz_strdup: Duplicate a C string (with scavenging) + + s: The string to duplicate. + + Returns a pointer to a duplicated string. Throws exception on failure + to allocate. +*/ char *fz_strdup(fz_context *ctx, char *s); +/* + fz_free: Frees an allocation. + + Does not throw exceptions. +*/ void fz_free(fz_context *ctx, void *p); -/* The following returns NULL on failure to allocate */ +/* + fz_malloc_no_throw: Allocate a block of memory (with scavenging) + + size: The number of bytes to allocate. + + Returns a pointer to the allocated block. May return NULL if size is + 0. Returns NULL on failure to allocate. +*/ void *fz_malloc_no_throw(fz_context *ctx, unsigned int size); -void *fz_malloc_array_no_throw(fz_context *ctx, unsigned int count, unsigned int size); + +/* + fz_calloc_no_throw: Allocate a zeroed block of memory (with scavenging) + + count: The number of objects to allocate space for. + + size: The size (in bytes) of each object. + + Returns a pointer to the allocated block. May return NULL if size + and/or count are 0. Returns NULL on failure to allocate. +*/ void *fz_calloc_no_throw(fz_context *ctx, unsigned int count, unsigned int size); + +/* + fz_malloc_array_no_throw: Allocate a block of (non zeroed) memory + (with scavenging). Equivalent to fz_calloc_no_throw without the + memory clearing. + + count: The number of objects to allocate space for. + + size: The size (in bytes) of each object. + + Returns a pointer to the allocated block. May return NULL if size + and/or count are 0. Returns NULL on failure to allocate. +*/ +void *fz_malloc_array_no_throw(fz_context *ctx, unsigned int count, unsigned int size); + +/* + fz_resize_array_no_throw: Resize a block of memory (with scavenging). + + p: The existing block to resize + + count: The number of objects to resize to. + + size: The size (in bytes) of each object. + + Returns a pointer to the resized block. May return NULL if size + and/or count are 0. Returns NULL on failure to resize (original + block is left unchanged). +*/ void *fz_resize_array_no_throw(fz_context *ctx, void *p, unsigned int count, unsigned int size); + +/* + fz_strdup_no_throw: Duplicate a C string (with scavenging) + + s: The string to duplicate. + + Returns a pointer to a duplicated string. Returns NULL on failure + to allocate. +*/ char *fz_strdup_no_throw(fz_context *ctx, char *s); -/* alloc and zero a struct, and tag it for memento */ -#define fz_malloc_struct(CTX, STRUCT) \ - Memento_label(fz_calloc(CTX,1,sizeof(STRUCT)), #STRUCT) +/* + Safe string functions +*/ +/* + fz_strsep: Given a pointer to a C string (or a pointer to NULL) break + it at the first occurence of a delimiter char (from a given set). -/* runtime (hah!) test for endian-ness */ -int fz_is_big_endian(void); + stringp: Pointer to a C string pointer (or NULL). Updated on exit to + point to the first char of the string after the delimiter that was + found. The string pointed to by stringp will be corrupted by this + call (as the found delimiter will be overwritten by 0). -/* safe string functions */ + delim: A C string of acceptable delimiter characters. + + Returns a pointer to a C string containing the chars of stringp up + to the first delimiter char (or the end of the string), or NULL. +*/ char *fz_strsep(char **stringp, const char *delim); -int fz_strlcpy(char *dst, const char *src, int n); -int fz_strlcat(char *dst, const char *src, int n); -/* Range checking atof */ -float fz_atof(const char *s); +/* + fz_strlcpy: Copy at most n-1 chars of a string into a destination + buffer with null termination, returning the real length of the + initial string (excluding terminator). -/* utf-8 encoding and decoding */ -int chartorune(int *rune, char *str); -int runetochar(char *str, int *rune); -int runelen(int c); + dst: Destination buffer, at least n bytes long. -/* getopt */ -extern int fz_getopt(int nargc, char * const *nargv, const char *ostr); -extern int fz_optind; -extern char *fz_optarg; + src: C string (non-NULL). + + n: Size of dst buffer in bytes. + + Returns the length (excluding terminator) of src. +*/ +int fz_strlcpy(char *dst, const char *src, int n); /* - * Generic hash-table with fixed-length keys. - */ + fz_strlcat: Concatenate 2 strings, with a maximum length. -typedef struct fz_hash_table_s fz_hash_table; + dst: pointer to first string in a buffer of n bytes. -fz_hash_table *fz_new_hash_table(fz_context *ctx, int initialsize, int keylen); -void fz_debug_hash(fz_context *ctx, fz_hash_table *table); -void fz_empty_hash(fz_context *ctx, fz_hash_table *table); -void fz_free_hash(fz_context *ctx, fz_hash_table *table); + src: pointer to string to concatenate. -void *fz_hash_find(fz_context *ctx, fz_hash_table *table, void *key); -void *fz_hash_insert(fz_context *ctx, fz_hash_table *table, void *key, void *val); -void fz_hash_remove(fz_context *ctx, fz_hash_table *table, void *key); + n: Size (in bytes) of buffer that dst is in. -int fz_hash_len(fz_context *ctx, fz_hash_table *table); -void *fz_hash_get_key(fz_context *ctx, fz_hash_table *table, int idx); -void *fz_hash_get_val(fz_context *ctx, fz_hash_table *table, int idx); + Returns the real length that a concatenated dst + src would have been + (not including terminator). +*/ +int fz_strlcat(char *dst, const char *src, int n); /* - * Math and geometry - */ + fz_chartorune: UTF8 decode a string of chars to a rune. -/* Multiply scaled two integers in the 0..255 range */ -static inline int fz_mul255(int a, int b) -{ - /* see Jim Blinn's book "Dirty Pixels" for how this works */ - int x = a * b + 128; - x += x >> 8; - return x >> 8; -} + rune: Pointer to an int to assign the decoded 'rune' to. -/* Expand a value A from the 0...255 range to the 0..256 range */ -#define FZ_EXPAND(A) ((A)+((A)>>7)) + str: Pointer to a UTF8 encoded string -/* Combine values A (in any range) and B (in the 0..256 range), - * to give a single value in the same range as A was. */ -#define FZ_COMBINE(A,B) (((A)*(B))>>8) + Returns the number of bytes consumed. Does not throw exceptions. +*/ +int fz_chartorune(int *rune, char *str); -/* Combine values A and C (in the same (any) range) and B and D (in the - * 0..256 range), to give a single value in the same range as A and C were. */ -#define FZ_COMBINE2(A,B,C,D) (FZ_COMBINE((A), (B)) + FZ_COMBINE((C), (D))) +/* + runetochar: UTF8 encode a run to a string of chars. -/* Blend SRC and DST (in the same range) together according to - * AMOUNT (in the 0...256 range). */ -#define FZ_BLEND(SRC, DST, AMOUNT) ((((SRC)-(DST))*(AMOUNT) + ((DST)<<8))>>8) + str: Pointer to a place to put the UTF8 encoded string. -typedef struct fz_matrix_s fz_matrix; -typedef struct fz_point_s fz_point; -typedef struct fz_rect_s fz_rect; -typedef struct fz_bbox_s fz_bbox; + rune: Pointer to a 'rune'. -extern const fz_rect fz_unit_rect; -extern const fz_rect fz_empty_rect; -extern const fz_rect fz_infinite_rect; + Returns the number of bytes the rune took to output. Does not throw + exceptions. +*/ +int fz_runetochar(char *str, int rune); -extern const fz_bbox fz_unit_bbox; -extern const fz_bbox fz_empty_bbox; -extern const fz_bbox fz_infinite_bbox; +/* + fz_runelen: Count many chars are required to represent a rune. -#define fz_is_empty_rect(r) ((r).x0 == (r).x1) -#define fz_is_infinite_rect(r) ((r).x0 > (r).x1) -#define fz_is_empty_bbox(b) ((b).x0 == (b).x1) -#define fz_is_infinite_bbox(b) ((b).x0 > (b).x1) + rune: The rune to encode. -struct fz_matrix_s -{ - float a, b, c, d, e, f; -}; + Returns the number of bytes required to represent this run in UTF8. +*/ +int fz_runelen(int rune); +/* getopt */ +extern int fz_getopt(int nargc, char * const *nargv, const char *ostr); +extern int fz_optind; +extern char *fz_optarg; + +/* + fz_point is a point in a two-dimensional space. +*/ +typedef struct fz_point_s fz_point; struct fz_point_s { float x, y; }; +/* + fz_rect is a rectangle represented by two diagonally opposite + corners at arbitrary coordinates. + + Rectangles are always axis-aligned with the X- and Y- axes. + The relationship between the coordinates are that x0 <= x1 and + y0 <= y1 in all cases except for infinte rectangles. The area + of a rectangle is defined as (x1 - x0) * (y1 - y0). If either + x0 > x1 or y0 > y1 is true for a given rectangle then it is + defined to be infinite. + + To check for empty or infinite rectangles use fz_is_empty_rect + and fz_is_infinite_rect. Compare to fz_bbox which has corners + at integer coordinates. + + x0, y0: The top left corner. + + x1, y1: The botton right corner. +*/ +typedef struct fz_rect_s fz_rect; struct fz_rect_s { float x0, y0; float x1, y1; }; +/* + fz_bbox is a bounding box similar to a fz_rect, except that + all corner coordinates are rounded to integer coordinates. + To check for empty or infinite bounding boxes use + fz_is_empty_bbox and fz_is_infinite_bbox. + + x0, y0: The top left corner. + + x1, y1: The bottom right corner. +*/ +typedef struct fz_bbox_s fz_bbox; struct fz_bbox_s { int x0, y0; int x1, y1; }; +/* + A rectangle with sides of length one. + + The bottom left corner is at (0, 0) and the top right corner + is at (1, 1). +*/ +extern const fz_rect fz_unit_rect; + +/* + A bounding box with sides of length one. See fz_unit_rect. +*/ +extern const fz_bbox fz_unit_bbox; + +/* + An empty rectangle with an area equal to zero. + + Both the top left and bottom right corner are at (0, 0). +*/ +extern const fz_rect fz_empty_rect; + +/* + An empty bounding box. See fz_empty_rect. +*/ +extern const fz_bbox fz_empty_bbox; + +/* + An infinite rectangle with negative area. + + The corner (x0, y0) is at (1, 1) while the corner (x1, y1) is + at (-1, -1). +*/ +extern const fz_rect fz_infinite_rect; + +/* + An infinite bounding box. See fz_infinite_rect. +*/ +extern const fz_bbox fz_infinite_bbox; + +/* + fz_is_empty_rect: Check if rectangle is empty. + + An empty rectangle is defined as one whose area is zero. +*/ +#define fz_is_empty_rect(r) ((r).x0 == (r).x1 || (r).y0 == (r).y1) + +/* + fz_is_empty_bbox: Check if bounding box is empty. + + Same definition of empty bounding boxes as for empty + rectangles. See fz_is_empty_rect. +*/ +#define fz_is_empty_bbox(b) ((b).x0 == (b).x1 || (b).y0 == (b).y1) + +/* + fz_is_infinite: Check if rectangle is infinite. + + An infinite rectangle is defined as one where either of the + two relationships between corner coordinates are not true. +*/ +#define fz_is_infinite_rect(r) ((r).x0 > (r).x1 || (r).y0 > (r).y1) + +/* + fz_is_infinite_bbox: Check if bounding box is infinite. + + Same definition of infinite bounding boxes as for infinite + rectangles. See fz_is_infinite_rect. +*/ +#define fz_is_infinite_bbox(b) ((b).x0 > (b).x1 || (b).y0 > (b).y1) + +/* + fz_matrix is a a row-major 3x3 matrix used for representing + transformations of coordinates throughout MuPDF. + + Since all points reside in a two-dimensional space, one vector + is always a constant unit vector; hence only some elements may + vary in a matrix. Below is how the elements map between + different representations. + + / a b 0 \ + | c d 0 | normally represented as [ a b c d e f ]. + \ e f 1 / +*/ +typedef struct fz_matrix_s fz_matrix; +struct fz_matrix_s +{ + float a, b, c, d, e, f; +}; + + +/* + fz_identity: Identity transform matrix. +*/ extern const fz_matrix fz_identity; -fz_matrix fz_concat(fz_matrix one, fz_matrix two); +/* + fz_concat: Multiply two matrices. + + The order of the two matrices are important since matrix + multiplication is not commutative. + + Does not throw exceptions. +*/ +fz_matrix fz_concat(fz_matrix left, fz_matrix right); + +/* + fz_scale: Create a scaling matrix. + + The returned matrix is of the form [ sx 0 0 sy 0 0 ]. + + sx, sy: Scaling factors along the X- and Y-axes. A scaling + factor of 1.0 will not cause any scaling along the relevant + axis. + + Does not throw exceptions. +*/ fz_matrix fz_scale(float sx, float sy); + +/* + fz_shear: Create a shearing matrix. + + The returned matrix is of the form [ 1 sy sx 1 0 0 ]. + + sx, sy: Shearing factors. A shearing factor of 0.0 will not + cause any shearing along the relevant axis. + + Does not throw exceptions. +*/ fz_matrix fz_shear(float sx, float sy); -fz_matrix fz_rotate(float theta); + +/* + fz_rotate: Create a rotation matrix. + + The returned matrix is of the form + [ cos(deg) sin(deg) -sin(deg) cos(deg) 0 0 ]. + + degrees: Degrees of counter clockwise rotation. Values less + than zero and greater than 360 are handled as expected. + + Does not throw exceptions. +*/ +fz_matrix fz_rotate(float degrees); + +/* + fz_translate: Create a translation matrix. + + The returned matrix is of the form [ 1 0 0 1 tx ty ]. + + tx, ty: Translation distances along the X- and Y-axes. A + translation of 0 will not cause any translation along the + relevant axis. + + Does not throw exceptions. +*/ fz_matrix fz_translate(float tx, float ty); -fz_matrix fz_invert_matrix(fz_matrix m); + +/* + fz_invert_matrix: Create an inverse matrix. + + matrix: Matrix to invert. A degenerate matrix, where the + determinant is equal to zero, can not be inverted and the + original matrix is returned instead. + + Does not throw exceptions. +*/ +fz_matrix fz_invert_matrix(fz_matrix matrix); + +/* + fz_is_rectilinear: Check if a transformation is rectilinear. + + Rectilinear means that no shearing is present and that any + rotations present are a multiple of 90 degrees. Usually this + is used to make sure that axis-aligned rectangles before the + transformation are still axis-aligned rectangles afterwards. + + Does not throw exceptions. +*/ int fz_is_rectilinear(fz_matrix m); -float fz_matrix_expansion(fz_matrix m); -float fz_matrix_max_expansion(fz_matrix m); -fz_bbox fz_round_rect(fz_rect r); -fz_bbox fz_intersect_bbox(fz_bbox a, fz_bbox b); -fz_rect fz_intersect_rect(fz_rect a, fz_rect b); -fz_bbox fz_union_bbox(fz_bbox a, fz_bbox b); -fz_rect fz_union_rect(fz_rect a, fz_rect b); +/* + fz_matrix_expansion: Calculate average scaling factor of matrix. +*/ +float fz_matrix_expansion(fz_matrix m); /* sumatrapdf */ + +/* + fz_round_rect: Convert a rect into a bounding box. -fz_point fz_transform_point(fz_matrix m, fz_point p); -fz_point fz_transform_vector(fz_matrix m, fz_point p); -fz_rect fz_transform_rect(fz_matrix m, fz_rect r); -fz_bbox fz_transform_bbox(fz_matrix m, fz_bbox b); + Coordinates in a bounding box are integers, so rounding of the + rects coordinates takes place. The top left corner is rounded + upwards and left while the bottom right corner is rounded + downwards and to the right. Overflows or underflowing + coordinates are clamped to INT_MIN/INT_MAX. -void fz_gridfit_matrix(fz_matrix *m); + Does not throw exceptions. +*/ +fz_bbox fz_round_rect(fz_rect rect); /* - * Basic crypto functions. - * Independent of the rest of fitz. - * For further encapsulation in filters, or not. - */ + fz_intersect_rect: Compute intersection of two rectangles. -/* md5 digests */ + Compute the largest axis-aligned rectangle that covers the + area covered by both given rectangles. If either rectangle is + empty then the intersection is also empty. If either rectangle + is infinite then the intersection is simply the non-infinite + rectangle. Should both rectangles be infinite, then the + intersection is also infinite. -typedef struct fz_md5_s fz_md5; + Does not throw exceptions. +*/ +fz_rect fz_intersect_rect(fz_rect a, fz_rect b); -struct fz_md5_s -{ - unsigned int state[4]; - unsigned int count[2]; - unsigned char buffer[64]; -}; +/* + fz_intersect_bbox: Compute intersection of two bounding boxes. -void fz_md5_init(fz_md5 *state); -void fz_md5_update(fz_md5 *state, const unsigned char *input, unsigned inlen); -void fz_md5_final(fz_md5 *state, unsigned char digest[16]); + Similar to fz_intersect_rect but operates on two bounding + boxes instead of two rectangles. -/* sha-256 digests */ + Does not throw exceptions. +*/ +fz_bbox fz_intersect_bbox(fz_bbox a, fz_bbox b); -typedef struct fz_sha256_s fz_sha256; +/* + fz_union_rect: Compute union of two rectangles. -struct fz_sha256_s -{ - unsigned int state[8]; - unsigned int count[2]; - union { - unsigned char u8[64]; - unsigned int u32[16]; - } buffer; -}; + Compute the smallest axis-aligned rectangle that encompasses + both given rectangles. If either rectangle is infinite then + the union is also infinite. If either rectangle is empty then + the union is simply the non-empty rectangle. Should both + rectangles be empty, then the union is also empty. -void fz_sha256_init(fz_sha256 *state); -void fz_sha256_update(fz_sha256 *state, const unsigned char *input, unsigned int inlen); -void fz_sha256_final(fz_sha256 *state, unsigned char digest[32]); + Does not throw exceptions. +*/ +fz_rect fz_union_rect(fz_rect a, fz_rect b); -/* arc4 crypto */ +/* + fz_union_bbox: Compute union of two bounding boxes. -typedef struct fz_arc4_s fz_arc4; + Similar to fz_union_rect but operates on two bounding boxes + instead of two rectangles. -struct fz_arc4_s -{ - unsigned x; - unsigned y; - unsigned char state[256]; -}; + Does not throw exceptions. +*/ +fz_bbox fz_union_bbox(fz_bbox a, fz_bbox b); -void fz_arc4_init(fz_arc4 *state, const unsigned char *key, unsigned len); -void fz_arc4_encrypt(fz_arc4 *state, unsigned char *dest, const unsigned char *src, unsigned len); +/* + fz_transform_point: Apply a transformation to a point. -/* AES block cipher implementation from XYSSL */ + transform: Transformation matrix to apply. See fz_concat, + fz_scale, fz_rotate and fz_translate for how to create a + matrix. -typedef struct fz_aes_s fz_aes; + Does not throw exceptions. +*/ +fz_point fz_transform_point(fz_matrix transform, fz_point point); -#define AES_DECRYPT 0 -#define AES_ENCRYPT 1 +/* + fz_transform_vector: Apply a transformation to a vector. -struct fz_aes_s -{ - int nr; /* number of rounds */ - unsigned long *rk; /* AES round keys */ - unsigned long buf[68]; /* unaligned data */ -}; + transform: Transformation matrix to apply. See fz_concat, + fz_scale and fz_rotate for how to create a matrix. Any + translation will be ignored. -void aes_setkey_enc( fz_aes *ctx, const unsigned char *key, int keysize ); -void aes_setkey_dec( fz_aes *ctx, const unsigned char *key, int keysize ); -void aes_crypt_cbc( fz_aes *ctx, int mode, int length, - unsigned char iv[16], - const unsigned char *input, - unsigned char *output ); + Does not throw exceptions. +*/ +fz_point fz_transform_vector(fz_matrix transform, fz_point vector); /* - * Dynamic objects. - * The same type of objects as found in PDF and PostScript. - * Used by the filters and the mupdf parser. - */ + fz_transform_rect: Apply a transform to a rectangle. -typedef struct fz_obj_s fz_obj; - -extern fz_obj *(*fz_resolve_indirect)(fz_obj *obj); - -fz_obj *fz_new_null(fz_context *ctx); -fz_obj *fz_new_bool(fz_context *ctx, int b); -fz_obj *fz_new_int(fz_context *ctx, int i); -fz_obj *fz_new_real(fz_context *ctx, float f); -fz_obj *fz_new_name(fz_context *ctx, char *str); -fz_obj *fz_new_string(fz_context *ctx, char *str, int len); -fz_obj *fz_new_indirect(fz_context *ctx, int num, int gen, void *doc); - -fz_obj *fz_new_array(fz_context *ctx, int initialcap); -fz_obj *fz_new_dict(fz_context *ctx, int initialcap); -fz_obj *fz_copy_array(fz_context *ctx, fz_obj *array); -fz_obj *fz_copy_dict(fz_context *ctx, fz_obj *dict); - -fz_obj *fz_keep_obj(fz_obj *obj); -void fz_drop_obj(fz_obj *obj); - -/* type queries */ -int fz_is_null(fz_obj *obj); -int fz_is_bool(fz_obj *obj); -int fz_is_int(fz_obj *obj); -int fz_is_real(fz_obj *obj); -int fz_is_name(fz_obj *obj); -int fz_is_string(fz_obj *obj); -int fz_is_array(fz_obj *obj); -int fz_is_dict(fz_obj *obj); -int fz_is_indirect(fz_obj *obj); - -int fz_objcmp(fz_obj *a, fz_obj *b); - -/* dict marking and unmarking functions - to avoid infinite recursions */ -int fz_dict_marked(fz_obj *obj); -int fz_dict_mark(fz_obj *obj); -void fz_dict_unmark(fz_obj *obj); - -/* safe, silent failure, no error reporting on type mismatches */ -int fz_to_bool(fz_obj *obj); -int fz_to_int(fz_obj *obj); -float fz_to_real(fz_obj *obj); -char *fz_to_name(fz_obj *obj); -char *fz_to_str_buf(fz_obj *obj); -fz_obj *fz_to_dict(fz_obj *obj); -int fz_to_str_len(fz_obj *obj); -int fz_to_num(fz_obj *obj); -int fz_to_gen(fz_obj *obj); - -int fz_array_len(fz_obj *array); -fz_obj *fz_array_get(fz_obj *array, int i); -void fz_array_put(fz_obj *array, int i, fz_obj *obj); -void fz_array_push(fz_obj *array, fz_obj *obj); -void fz_array_insert(fz_obj *array, fz_obj *obj); -int fz_array_contains(fz_obj *array, fz_obj *obj); - -int fz_dict_len(fz_obj *dict); -fz_obj *fz_dict_get_key(fz_obj *dict, int idx); -fz_obj *fz_dict_get_val(fz_obj *dict, int idx); -fz_obj *fz_dict_get(fz_obj *dict, fz_obj *key); -fz_obj *fz_dict_gets(fz_obj *dict, char *key); -fz_obj *fz_dict_getsa(fz_obj *dict, char *key, char *abbrev); -void fz_dict_put(fz_obj *dict, fz_obj *key, fz_obj *val); -void fz_dict_puts(fz_obj *dict, char *key, fz_obj *val); -void fz_dict_del(fz_obj *dict, fz_obj *key); -void fz_dict_dels(fz_obj *dict, char *key); -void fz_sort_dict(fz_obj *dict); - -int fz_fprint_obj(FILE *fp, fz_obj *obj, int tight); -void fz_debug_obj(fz_obj *obj); -void fz_debug_ref(fz_obj *obj); - -void fz_set_str_len(fz_obj *obj, int newlen); /* private */ -void *fz_get_indirect_document(fz_obj *obj); /* private */ - -/* - * Data buffers. - */ + After the four corner points of the axis-aligned rectangle + have been transformed it may not longer be axis-aligned. So a + new axis-aligned rectangle is created covering at least the + area of the transformed rectangle. + transform: Transformation matrix to apply. See fz_concat, + fz_scale and fz_rotate for how to create a matrix. + + rect: Rectangle to be transformed. The two special cases + fz_empty_rect and fz_infinite_rect, may be used but are + returned unchanged as expected. + + Does not throw exceptions. +*/ +fz_rect fz_transform_rect(fz_matrix transform, fz_rect rect); + +/* + fz_transform_bbox: Transform a given bounding box. + + Similar to fz_transform_rect, but operates on a bounding box + instead of a rectangle. + + Does not throw exceptions. +*/ +fz_bbox fz_transform_bbox(fz_matrix matrix, fz_bbox bbox); + +/* + fz_buffer is a wrapper around a dynamically allocated array of bytes. + + Buffers have a capacity (the number of bytes storage immediately + available) and a current size. +*/ typedef struct fz_buffer_s fz_buffer; -struct fz_buffer_s -{ - int refs; - unsigned char *data; - int cap, len; -}; +/* + fz_keep_buffer: Increment the reference count for a buffer. -fz_buffer *fz_new_buffer(fz_context *ctx, int size); + buf: The buffer to increment the reference count for. + + Returns a pointer to the buffer. Does not throw exceptions. +*/ fz_buffer *fz_keep_buffer(fz_context *ctx, fz_buffer *buf); + +/* + fz_drop_buffer: Decrement the reference count for a buffer. + + buf: The buffer to decrement the reference count for. +*/ void fz_drop_buffer(fz_context *ctx, fz_buffer *buf); -void fz_resize_buffer(fz_context *ctx, fz_buffer *buf, int size); -void fz_grow_buffer(fz_context *ctx, fz_buffer *buf); +/* + fz_buffer_storage: Retrieve information on the storage currently used + by a buffer. + + data: Pointer to place to retrieve data pointer. + + Returns length of stream. +*/ +int fz_buffer_storage(fz_context *ctx, fz_buffer *buf, unsigned char **data); /* - * Resource store - */ + fz_stream is a buffered reader capable of seeking in both + directions. -typedef struct fz_storable_s fz_storable; + Streams are reference counted, so references must be dropped + by a call to fz_close. -typedef struct fz_item_s fz_item; + Only the data between rp and wp is valid. +*/ +typedef struct fz_stream_s fz_stream; -typedef void (fz_store_free_fn)(fz_context *, fz_storable *); +/* + fz_open_file: Open the named file and wrap it in a stream. -struct fz_storable_s { - int refs; - fz_store_free_fn *free; -}; + filename: Path to a file as it would be given to open(2). +*/ +fz_stream *fz_open_file(fz_context *ctx, const char *filename); -#define FZ_INIT_STORABLE(S_,RC,FREE) \ - do { fz_storable *S = &(S_)->storable; S->refs = (RC); \ - S->free = (FREE); \ - } while (0) +/* + fz_open_file_w: Open the named file and wrap it in a stream. -enum { - FZ_STORE_UNLIMITED = 0, - FZ_STORE_DEFAULT = 256 << 20, -}; + This function is only available when compiling for Win32. -void fz_new_store_context(fz_context *ctx, unsigned int max); -void fz_drop_store_context(fz_context *ctx); -fz_store *fz_store_keep(fz_context *ctx); -void fz_debug_store(fz_context *ctx); + filename: Wide character path to the file as it would be given + to _wopen(). +*/ +fz_stream *fz_open_file_w(fz_context *ctx, const wchar_t *filename); -void *fz_keep_storable(fz_context *, fz_storable *); -void fz_drop_storable(fz_context *, fz_storable *); +/* + fz_open_fd: Wrap an open file descriptor in a stream. -void fz_store_item(fz_context *ctx, fz_obj *key, void *val, unsigned int itemsize); -void *fz_find_item(fz_context *ctx, fz_store_free_fn *freefn, fz_obj *key); -void fz_remove_item(fz_context *ctx, fz_store_free_fn *freefn, fz_obj *key); -void fz_empty_store(fz_context *ctx); -int fz_store_scavenge(fz_context *ctx, unsigned int size, int *phase); + file: An open file descriptor supporting bidirectional + seeking. The stream will take ownership of the file + descriptor, so it may not be modified or closed after the call + to fz_open_fd. When the stream is closed it will also close + the file descriptor. +*/ +fz_stream *fz_open_fd(fz_context *ctx, int file); /* - * Buffered reader. - * Only the data between rp and wp is valid data. - */ + fz_open_memory: Open a block of memory as a stream. -typedef struct fz_stream_s fz_stream; + data: Pointer to start of data block. Ownership of the data block is + NOT passed in. -struct fz_stream_s -{ - fz_context *ctx; - int refs; - int error; - int eof; - int pos; - int avail; - int bits; - int locked; - unsigned char *bp, *rp, *wp, *ep; - void *state; - int (*read)(fz_stream *stm, unsigned char *buf, int len); - void (*close)(fz_context *ctx, void *state); - void (*seek)(fz_stream *stm, int offset, int whence); - unsigned char buf[4096]; -}; + len: Number of bytes in data block. -fz_stream *fz_open_fd(fz_context *ctx, int file); -fz_stream *fz_open_file(fz_context *ctx, const char *filename); -fz_stream *fz_open_file_w(fz_context *ctx, const wchar_t *filename); /* only on win32 */ -fz_stream *fz_open_buffer(fz_context *ctx, fz_buffer *buf); + Returns pointer to newly created stream. May throw exceptions on + failure to allocate. +*/ fz_stream *fz_open_memory(fz_context *ctx, unsigned char *data, int len); -void fz_close(fz_stream *stm); -void fz_lock_stream(fz_stream *stm); -fz_stream *fz_new_stream(fz_context *ctx, void*, int(*)(fz_stream*, unsigned char*, int), void(*)(fz_context *, void *)); -fz_stream *fz_keep_stream(fz_stream *stm); -void fz_fill_buffer(fz_stream *stm); +/* + fz_open_buffer: Open a buffer as a stream. + + buf: The buffer to open. Ownership of the buffer is NOT passed in + (this function takes it's own reference). + Returns pointer to newly created stream. May throw exceptions on + failure to allocate. +*/ +fz_stream *fz_open_buffer(fz_context *ctx, fz_buffer *buf); + +/* + fz_close: Close an open stream. + + Drops a reference for the stream. Once no references remain + the stream will be closed, as will any file descriptor the + stream is using. + + Does not throw exceptions. +*/ +void fz_close(fz_stream *stm); + +/* + fz_tell: return the current reading position within a stream +*/ int fz_tell(fz_stream *stm); + +/* + fz_seek: Seek within a stream. + + stm: The stream to seek within. + + offset: The offset to seek to. + + whence: From where the offset is measured (see fseek). +*/ void fz_seek(fz_stream *stm, int offset, int whence); -int fz_read(fz_stream *stm, unsigned char *buf, int len); -void fz_read_line(fz_stream *stm, char *buf, int max); -fz_buffer *fz_read_all(fz_stream *stm, int initial); +/* + fz_read: Read from a stream into a given data block. -static inline int fz_read_byte(fz_stream *stm) -{ - if (stm->rp == stm->wp) - { - fz_fill_buffer(stm); - return stm->rp < stm->wp ? *stm->rp++ : EOF; - } - return *stm->rp++; -} + stm: The stream to read from. -static inline int fz_peek_byte(fz_stream *stm) -{ - if (stm->rp == stm->wp) - { - fz_fill_buffer(stm); - return stm->rp < stm->wp ? *stm->rp : EOF; - } - return *stm->rp; -} + data: The data block to read into. -static inline void fz_unread_byte(fz_stream *stm) -{ - if (stm->rp > stm->bp) - stm->rp--; -} + len: The length of the data block (in bytes). -static inline int fz_is_eof(fz_stream *stm) -{ - if (stm->rp == stm->wp) - { - if (stm->eof) - return 1; - return fz_peek_byte(stm) == EOF; - } - return 0; -} + Returns the number of bytes read. May throw exceptions. +*/ +int fz_read(fz_stream *stm, unsigned char *data, int len); -static inline unsigned int fz_read_bits(fz_stream *stm, int n) -{ - unsigned int x; +/* + fz_read_all: Read all of a stream into a buffer. - if (n <= stm->avail) - { - stm->avail -= n; - x = (stm->bits >> stm->avail) & ((1 << n) - 1); - } - else - { - x = stm->bits & ((1 << stm->avail) - 1); - n -= stm->avail; - stm->avail = 0; + stm: The stream to read from - while (n > 8) - { - x = (x << 8) | fz_read_byte(stm); - n -= 8; - } + initial: Suggested initial size for the buffer. - if (n > 0) - { - stm->bits = fz_read_byte(stm); - stm->avail = 8 - n; - x = (x << n) | (stm->bits >> stm->avail); - } - } + Returns a buffer created from reading from the stream. May throw + exceptions on failure to allocate. +*/ +fz_buffer *fz_read_all(fz_stream *stm, int initial); - return x; -} +/* + Bitmaps have 1 bit per component. Only used for creating halftoned + versions of contone buffers, and saving out. Samples are stored msb + first, akin to pbms. +*/ +typedef struct fz_bitmap_s fz_bitmap; -static inline void fz_sync_bits(fz_stream *stm) -{ - stm->avail = 0; -} +/* + fz_keep_bitmap: Take a reference to a bitmap. -static inline int fz_is_eof_bits(fz_stream *stm) -{ - return fz_is_eof(stm) && (stm->avail == 0 || stm->bits == EOF); -} + bit: The bitmap to increment the reference for. + + Returns bit. Does not throw exceptions. +*/ +fz_bitmap *fz_keep_bitmap(fz_context *ctx, fz_bitmap *bit); /* - * Data filters. - */ + fz_drop_bitmap: Drop a reference and free a bitmap. -fz_stream *fz_open_copy(fz_stream *chain); -fz_stream *fz_open_null(fz_stream *chain, int len); -fz_stream *fz_open_arc4(fz_stream *chain, unsigned char *key, unsigned keylen); -fz_stream *fz_open_aesd(fz_stream *chain, unsigned char *key, unsigned keylen); -fz_stream *fz_open_a85d(fz_stream *chain); -fz_stream *fz_open_ahxd(fz_stream *chain); -fz_stream *fz_open_rld(fz_stream *chain); -fz_stream *fz_open_dctd(fz_stream *chain, int color_transform); -fz_stream *fz_open_faxd(fz_stream *chain, - int k, int end_of_line, int encoded_byte_align, - int columns, int rows, int end_of_block, int black_is_1); -fz_stream *fz_open_flated(fz_stream *chain); -fz_stream *fz_open_lzwd(fz_stream *chain, int early_change); -fz_stream *fz_open_predict(fz_stream *chain, int predictor, int columns, int colors, int bpc); -fz_stream *fz_open_jbig2d(fz_stream *chain, fz_buffer *global); - -/* - * Resources and other graphics related objects. - */ + Decrement the reference count for the bitmap. When no + references remain the pixmap will be freed. -enum { FZ_MAX_COLORS = 32 }; + Does not throw exceptions. +*/ +void fz_drop_bitmap(fz_context *ctx, fz_bitmap *bit); -int fz_find_blendmode(char *name); -char *fz_blendmode_name(int blendmode); +/* + An fz_colorspace object represents an abstract colorspace. While + this should be treated as a black box by callers of the library at + this stage, know that it encapsulates knowledge of how to convert + colors to and from the colorspace, any lookup tables generated, the + number of components in the colorspace etc. +*/ +typedef struct fz_colorspace_s fz_colorspace; /* - * Pixmaps have n components per pixel. the last is always alpha. - * premultiplied alpha when rendering, but non-premultiplied for colorspace - * conversions and rescaling. - */ + fz_find_device_colorspace: Find a standard colorspace based upon + it's name. +*/ +fz_colorspace *fz_find_device_colorspace(fz_context *ctx, char *name); +/* + fz_device_gray: Abstract colorspace representing device specific + gray. +*/ +extern fz_colorspace *fz_device_gray; + +/* + fz_device_rgb: Abstract colorspace representing device specific + rgb. +*/ +extern fz_colorspace *fz_device_rgb; + +/* + fz_device_bgr: Abstract colorspace representing device specific + bgr. +*/ +extern fz_colorspace *fz_device_bgr; + +/* + fz_device_cmyk: Abstract colorspace representing device specific + CMYK. +*/ +extern fz_colorspace *fz_device_cmyk; + +/* + Pixmaps represent a set of pixels for a 2 dimensional region of a + plane. Each pixel has n components per pixel, the last of which is + always alpha. The data is in premultiplied alpha when rendering, but + non-premultiplied for colorspace conversions and rescaling. +*/ typedef struct fz_pixmap_s fz_pixmap; -typedef struct fz_colorspace_s fz_colorspace; -struct fz_pixmap_s -{ - fz_storable storable; - int x, y, w, h, n; - fz_pixmap *mask; /* explicit soft/image mask */ - int interpolate; - int xres, yres; - fz_colorspace *colorspace; - unsigned char *samples; - int free_samples; -}; +/* + fz_pixmap_bbox: Return a bounding box for a pixmap. -fz_bbox fz_bound_pixmap(fz_pixmap *pix); + Returns an exact bounding box for the supplied pixmap. +*/ +fz_bbox fz_pixmap_bbox(fz_context *ctx, fz_pixmap *pix); -fz_pixmap *fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h, unsigned char *samples); -fz_pixmap *fz_new_pixmap_with_rect(fz_context *ctx, fz_colorspace *, fz_bbox bbox); -fz_pixmap *fz_new_pixmap_with_rect_and_data(fz_context *ctx, fz_colorspace *, fz_bbox bbox, unsigned char *samples); -fz_pixmap *fz_new_pixmap(fz_context *ctx, fz_colorspace *, int w, int h); -fz_pixmap *fz_keep_pixmap(fz_context *ctx, fz_pixmap *pix); -void fz_drop_pixmap(fz_context *ctx, fz_pixmap *pix); -void fz_free_pixmap_imp(fz_context *ctx, fz_storable *pix); -void fz_clear_pixmap(fz_context *ctx, fz_pixmap *pix); -void fz_clear_pixmap_with_value(fz_context *ctx, fz_pixmap *pix, int value); -void fz_clear_pixmap_rect_with_value(fz_context *ctx, fz_pixmap *pix, int value, fz_bbox r); -void fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, fz_bbox r); -void fz_premultiply_pixmap(fz_context *ctx, fz_pixmap *pix); -void fz_unmultiply_pixmap(fz_context *ctx, fz_pixmap *pix); -fz_pixmap *fz_alpha_from_gray(fz_context *ctx, fz_pixmap *gray, int luminosity); -void fz_invert_pixmap(fz_context *ctx, fz_pixmap *pix); -void fz_gamma_pixmap(fz_context *ctx, fz_pixmap *pix, float gamma); -unsigned int fz_pixmap_size(fz_context *ctx, fz_pixmap *pix); +/* + fz_pixmap_width: Return the width of the pixmap in pixels. +*/ +int fz_pixmap_width(fz_context *ctx, fz_pixmap *pix); -fz_pixmap *fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_bbox *clip); +/* + fz_pixmap_height: Return the height of the pixmap in pixels. +*/ +int fz_pixmap_height(fz_context *ctx, fz_pixmap *pix); -void fz_write_pnm(fz_context *ctx, fz_pixmap *pixmap, char *filename); -void fz_write_pam(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha); -void fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha); +/* + fz_new_pixmap: Create a new pixmap, with it's origin at (0,0) + + cs: The colorspace to use for the pixmap, or NULL for an alpha + plane/mask. -fz_pixmap *fz_load_jpx(fz_context *ctx, unsigned char *data, int size, fz_colorspace *cs); -fz_pixmap *fz_load_jpeg(fz_context *doc, unsigned char *data, int size); -fz_pixmap *fz_load_png(fz_context *doc, unsigned char *data, int size); -fz_pixmap *fz_load_tiff(fz_context *doc, unsigned char *data, int size); + w: The width of the pixmap (in pixels) + + h: The height of the pixmap (in pixels) + + Returns a pointer to the new pixmap. Throws exception on failure to + allocate. +*/ +fz_pixmap *fz_new_pixmap(fz_context *ctx, fz_colorspace *cs, int w, int h); /* - * Bitmaps have 1 component per bit. Only used for creating halftoned versions - * of contone buffers, and saving out. Samples are stored msb first, akin to - * pbms. - */ + fz_new_pixmap_with_bbox: Create a pixmap of a given size, + location and pixel format. -typedef struct fz_bitmap_s fz_bitmap; + The bounding box specifies the size of the created pixmap and + where it will be located. The colorspace determines the number + of components per pixel. Alpha is always present. Pixmaps are + reference counted, so drop references using fz_drop_pixmap. -struct fz_bitmap_s -{ - int refs; - int w, h, stride, n; - unsigned char *samples; -}; + colorspace: Colorspace format used for the created pixmap. The + pixmap will keep a reference to the colorspace. -fz_bitmap *fz_new_bitmap(fz_context *ctx, int w, int h, int n); -fz_bitmap *fz_keep_bitmap(fz_context *ctx, fz_bitmap *bit); -void fz_clear_bitmap(fz_context *ctx, fz_bitmap *bit); -void fz_drop_bitmap(fz_context *ctx, fz_bitmap *bit); + bbox: Bounding box specifying location/size of created pixmap. -void fz_write_pbm(fz_context *ctx, fz_bitmap *bitmap, char *filename); + Returns a pointer to the new pixmap. Throws exception on failure to + allocate. +*/ +fz_pixmap *fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, fz_bbox bbox); /* - * A halftone is a set of threshold tiles, one per component. Each threshold - * tile is a pixmap, possibly of varying sizes and phases. - */ + fz_new_pixmap_with_data: Create a new pixmap, with it's origin at + (0,0) using the supplied data block. -typedef struct fz_halftone_s fz_halftone; + cs: The colorspace to use for the pixmap, or NULL for an alpha + plane/mask. -struct fz_halftone_s -{ - int refs; - int n; - fz_pixmap *comp[1]; -}; + w: The width of the pixmap (in pixels) -fz_halftone *fz_new_halftone(fz_context *ctx, int num_comps); -fz_halftone *fz_get_default_halftone(fz_context *ctx, int num_comps); -fz_halftone *fz_keep_halftone(fz_context *ctx, fz_halftone *half); -void fz_drop_halftone(fz_context *ctx, fz_halftone *half); + h: The height of the pixmap (in pixels) -fz_bitmap *fz_halftone_pixmap(fz_context *ctx, fz_pixmap *pix, fz_halftone *ht); + samples: The data block to keep the samples in. + + Returns a pointer to the new pixmap. Throws exception on failure to + allocate. +*/ +fz_pixmap *fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h, unsigned char *samples); /* - * Colorspace resources. - */ + fz_new_pixmap_with_bbox_and_data: Create a pixmap of a given size, + location and pixel format, using the supplied data block. -extern fz_colorspace *fz_device_gray; -extern fz_colorspace *fz_device_rgb; -extern fz_colorspace *fz_device_bgr; -extern fz_colorspace *fz_device_cmyk; + The bounding box specifies the size of the created pixmap and + where it will be located. The colorspace determines the number + of components per pixel. Alpha is always present. Pixmaps are + reference counted, so drop references using fz_drop_pixmap. -struct fz_colorspace_s -{ - fz_storable storable; - unsigned int size; - char name[16]; - int n; - void (*to_rgb)(fz_context *ctx, fz_colorspace *, float *src, float *rgb); - void (*from_rgb)(fz_context *ctx, fz_colorspace *, float *rgb, float *dst); - void (*free_data)(fz_context *Ctx, fz_colorspace *); - void *data; -}; + colorspace: Colorspace format used for the created pixmap. The + pixmap will keep a reference to the colorspace. -fz_colorspace *fz_new_colorspace(fz_context *ctx, char *name, int n); -fz_colorspace *fz_keep_colorspace(fz_context *ctx, fz_colorspace *colorspace); -void fz_drop_colorspace(fz_context *ctx, fz_colorspace *colorspace); -void fz_free_colorspace_imp(fz_context *ctx, fz_storable *colorspace); + bbox: Bounding box specifying location/size of created pixmap. -void fz_convert_color(fz_context *ctx, fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv); -void fz_convert_pixmap(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst); + samples: The data block to keep the samples in. -fz_colorspace *fz_find_device_colorspace(char *name); + Returns a pointer to the new pixmap. Throws exception on failure to + allocate. +*/ +fz_pixmap *fz_new_pixmap_with_bbox_and_data(fz_context *ctx, fz_colorspace *colorspace, fz_bbox bbox, unsigned char *samples); /* - * Fonts come in two variants: - * Regular fonts are handled by FreeType. - * Type 3 fonts have callbacks to the interpreter. - */ + fz_keep_pixmap: Take a reference to a pixmap. -typedef struct fz_device_s fz_device; + pix: The pixmap to increment the reference for. -typedef struct fz_font_s fz_font; -char *ft_error_string(int err); + Returns pix. Does not throw exceptions. +*/ +fz_pixmap *fz_keep_pixmap(fz_context *ctx, fz_pixmap *pix); -struct fz_font_s -{ - int refs; - char name[32]; - - void *ft_face; /* has an FT_Face if used */ - int ft_substitute; /* ... substitute metrics */ - int ft_bold; /* ... synthesize bold */ - int ft_italic; /* ... synthesize italic */ - int ft_hint; /* ... force hinting for DynaLab fonts */ - - /* origin of font data */ - char *ft_file; - unsigned char *ft_data; - int ft_size; - - fz_matrix t3matrix; - fz_obj *t3resources; - fz_buffer **t3procs; /* has 256 entries if used */ - float *t3widths; /* has 256 entries if used */ - char *t3flags; /* has 256 entries if used */ - void *t3doc; /* a pdf_document for the callback */ - void (*t3run)(void *doc, fz_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate); - - fz_rect bbox; /* font bbox is used only for t3 fonts */ - - /* per glyph bounding box cache */ - int use_glyph_bbox; - int bbox_count; - fz_rect *bbox_table; - - /* substitute metrics */ - int width_count; - int *width_table; /* in 1000 units */ -}; +/* + fz_drop_pixmap: Drop a reference and free a pixmap. -void fz_new_font_context(fz_context *ctx); -fz_font_context *fz_keep_font_context(fz_context *ctx); -void fz_drop_font_context(fz_context *ctx); + Decrement the reference count for the pixmap. When no + references remain the pixmap will be freed. -fz_font *fz_new_type3_font(fz_context *ctx, char *name, fz_matrix matrix); + Does not throw exceptions. +*/ +void fz_drop_pixmap(fz_context *ctx, fz_pixmap *pix); -fz_font *fz_new_font_from_memory(fz_context *ctx, unsigned char *data, int len, int index, int use_glyph_bbox); -fz_font *fz_new_font_from_file(fz_context *ctx, char *path, int index, int use_glyph_bbox); +/* + fz_pixmap_colorspace: Return the colorspace of a pixmap -fz_font *fz_keep_font(fz_context *ctx, fz_font *font); -void fz_drop_font(fz_context *ctx, fz_font *font); + Returns colorspace. Does not throw exceptions. +*/ +fz_colorspace *fz_pixmap_colorspace(fz_context *ctx, fz_pixmap *pix); -void fz_debug_font(fz_context *ctx, fz_font *font); +/* + fz_pixmap_components: Return the number of components in a pixmap. -void fz_set_font_bbox(fz_context *ctx, fz_font *font, float xmin, float ymin, float xmax, float ymax); -fz_rect fz_bound_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm); -int fz_glyph_cacheable(fz_context *ctx, fz_font *font, int gid); + Returns the number of components. Does not throw exceptions. +*/ +int fz_pixmap_components(fz_context *ctx, fz_pixmap *pix); /* - * Vector path buffer. - * It can be stroked and dashed, or be filled. - * It has a fill rule (nonzero or even_odd). - * - * When rendering, they are flattened, stroked and dashed straight - * into the Global Edge List. - */ + fz_pixmap_samples: Returns a pointer to the pixel data of a pixmap. -typedef struct fz_path_s fz_path; -typedef struct fz_stroke_state_s fz_stroke_state; + Returns the pointer. Does not throw exceptions. +*/ +unsigned char *fz_pixmap_samples(fz_context *ctx, fz_pixmap *pix); -typedef union fz_path_item_s fz_path_item; +/* + fz_clear_pixmap_with_value: Clears a pixmap with the given value. -typedef enum fz_path_item_kind_e -{ - FZ_MOVETO, - FZ_LINETO, - FZ_CURVETO, - FZ_CLOSE_PATH -} fz_path_item_kind; + pix: The pixmap to clear. -typedef enum fz_linecap_e -{ - FZ_LINECAP_BUTT = 0, - FZ_LINECAP_ROUND = 1, - FZ_LINECAP_SQUARE = 2, - FZ_LINECAP_TRIANGLE = 3 -} fz_linecap; + value: Values in the range 0 to 255 are valid. Each component + sample for each pixel in the pixmap will be set to this value, + while alpha will always be set to 255 (non-transparent). -typedef enum fz_linejoin_e -{ - FZ_LINEJOIN_MITER = 0, - FZ_LINEJOIN_ROUND = 1, - FZ_LINEJOIN_BEVEL = 2, - FZ_LINEJOIN_MITER_XPS = 3 -} fz_linejoin; + Does not throw exceptions. +*/ +void fz_clear_pixmap_with_value(fz_context *ctx, fz_pixmap *pix, int value); -union fz_path_item_s -{ - fz_path_item_kind k; - float v; -}; +/* + fz_clear_pixmap_with_value: Sets all components (including alpha) of + all pixels in a pixmap to 0. -struct fz_path_s -{ - int len, cap; - fz_path_item *items; - int last; -}; + pix: The pixmap to clear. -struct fz_stroke_state_s -{ - fz_linecap start_cap, dash_cap, end_cap; - fz_linejoin linejoin; - float linewidth; - float miterlimit; - float dash_phase; - int dash_len; - float dash_list[32]; -}; + Does not throw exceptions. +*/ +void fz_clear_pixmap(fz_context *ctx, fz_pixmap *pix); -fz_path *fz_new_path(fz_context *ctx); -void fz_moveto(fz_context*, fz_path*, float x, float y); -void fz_lineto(fz_context*, fz_path*, float x, float y); -void fz_curveto(fz_context*,fz_path*, float, float, float, float, float, float); -void fz_curvetov(fz_context*,fz_path*, float, float, float, float); -void fz_curvetoy(fz_context*,fz_path*, float, float, float, float); -void fz_closepath(fz_context*,fz_path*); -void fz_free_path(fz_context *ctx, fz_path *path); +/* + fz_invert_pixmap: Invert all the pixels in a pixmap. All components + of all pixels are inverted (except alpha, which is unchanged). -void fz_transform_path(fz_context *ctx, fz_path *path, fz_matrix transform); + Does not throw exceptions. +*/ +void fz_invert_pixmap(fz_context *ctx, fz_pixmap *pix); -fz_path *fz_clone_path(fz_context *ctx, fz_path *old); +/* + fz_invert_pixmap: Invert all the pixels in a given rectangle of a + pixmap. All components of all pixels in the rectangle are inverted + (except alpha, which is unchanged). -fz_rect fz_bound_path(fz_context *ctx, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm); -void fz_debug_path(fz_context *ctx, fz_path *, int indent); + Does not throw exceptions. +*/ +void fz_invert_pixmap_rect(fz_pixmap *image, fz_bbox rect); /* - * Glyph cache - */ + fz_gamma_pixmap: Apply gamma correction to a pixmap. All components + of all pixels are modified (except alpha, which is unchanged). -void fz_new_glyph_cache_context(fz_context *ctx); -fz_glyph_cache *fz_keep_glyph_cache(fz_context *ctx); -void fz_drop_glyph_cache_context(fz_context *ctx); -void fz_purge_glyph_cache(fz_context *ctx); - -fz_pixmap *fz_render_ft_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm); -fz_pixmap *fz_render_t3_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, fz_colorspace *model); -fz_pixmap *fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *state); -fz_pixmap *fz_render_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_colorspace *model); -fz_pixmap *fz_render_stroked_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_matrix, fz_stroke_state *stroke); -void fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gid, fz_matrix trm, void *gstate); - -/* - * Text buffer. - * - * The trm field contains the a, b, c and d coefficients. - * The e and f coefficients come from the individual elements, - * together they form the transform matrix for the glyph. - * - * Glyphs are referenced by glyph ID. - * The Unicode text equivalent is kept in a separate array - * with indexes into the glyph array. - */ + gamma: The gamma value to apply; 1.0 for no change. -typedef struct fz_text_s fz_text; -typedef struct fz_text_item_s fz_text_item; + Does not throw exceptions. +*/ +void fz_gamma_pixmap(fz_context *ctx, fz_pixmap *pix, float gamma); -struct fz_text_item_s -{ - float x, y; - int gid; /* -1 for one gid to many ucs mappings */ - int ucs; /* -1 for one ucs to many gid mappings */ -}; +/* + fz_unmultiply_pixmap: Convert a pixmap from premultiplied to + non-premultiplied format. -struct fz_text_s -{ - fz_font *font; - fz_matrix trm; - int wmode; - int len, cap; - fz_text_item *items; -}; + Does not throw exceptions. +*/ +void fz_unmultiply_pixmap(fz_context *ctx, fz_pixmap *pix); + +/* + fz_convert_pixmap: Convert from one pixmap to another (assumed to be + the same size, but possibly with a different colorspace). + + dst: the source pixmap. -fz_text *fz_new_text(fz_context *ctx, fz_font *face, fz_matrix trm, int wmode); -void fz_add_text(fz_context *ctx, fz_text *text, int gid, int ucs, float x, float y); -void fz_free_text(fz_context *ctx, fz_text *text); -fz_rect fz_bound_text(fz_context *ctx, fz_text *text, fz_matrix ctm); -fz_text *fz_clone_text(fz_context *ctx, fz_text *old); -void fz_debug_text(fz_context *ctx, fz_text*, int indent); + src: the destination pixmap. +*/ +void fz_convert_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src); /* - * The shading code uses gouraud shaded triangle meshes. - */ + fz_write_pixmap: Save a pixmap out. -enum -{ - FZ_LINEAR, - FZ_RADIAL, - FZ_MESH, -}; + name: The prefix for the name of the pixmap. The pixmap will be saved + as "name.png" if the pixmap is RGB or Greyscale, "name.pam" otherwise. -typedef struct fz_shade_s fz_shade; + rgb: If non zero, the pixmap is converted to rgb (if possible) before + saving. +*/ +void fz_write_pixmap(fz_context *ctx, fz_pixmap *img, char *name, int rgb); -struct fz_shade_s -{ - fz_storable storable; +/* + fz_write_pnm: Save a pixmap as a pnm - fz_rect bbox; /* can be fz_infinite_rect */ - fz_colorspace *colorspace; + filename: The filename to save as (including extension). +*/ +void fz_write_pnm(fz_context *ctx, fz_pixmap *pixmap, char *filename); - fz_matrix matrix; /* matrix from pattern dict */ - int use_background; /* background color for fills but not 'sh' */ - float background[FZ_MAX_COLORS]; +/* + fz_write_pam: Save a pixmap as a pam - int use_function; - float function[256][FZ_MAX_COLORS + 1]; + filename: The filename to save as (including extension). +*/ +void fz_write_pam(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha); - int type; /* linear, radial, mesh */ - int extend[2]; +/* + fz_write_png: Save a pixmap as a png - int mesh_len; - int mesh_cap; - float *mesh; /* [x y 0], [x y r], [x y t] or [x y c1 ... cn] */ -}; + filename: The filename to save as (including extension). +*/ +void fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha); + +/* + fz_write_pbm: Save a bitmap as a pbm + + filename: The filename to save as (including extension). +*/ +void fz_write_pbm(fz_context *ctx, fz_bitmap *bitmap, char *filename); -fz_shade *fz_keep_shade(fz_context *ctx, fz_shade *shade); -void fz_drop_shade(fz_context *ctx, fz_shade *shade); -void fz_free_shade_imp(fz_context *ctx, fz_storable *shade); -void fz_debug_shade(fz_context *ctx, fz_shade *shade); +/* + fz_md5_pixmap: Return the md5 digest for a pixmap -fz_rect fz_bound_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm); -void fz_paint_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_bbox bbox); + filename: The filename to save as (including extension). +*/ +void fz_md5_pixmap(fz_pixmap *pixmap, unsigned char digest[16]); /* - * Scan converter + Images are storable objects from which we can obtain fz_pixmaps. + These may be implemented as simple wrappers around a pixmap, or as + more complex things that decode at different subsample settings on + demand. */ +typedef struct fz_image_s fz_image; -int fz_get_aa_level(fz_context *ctx); -void fz_set_aa_level(fz_context *ctx, int bits); +/* + fz_image_to_pixmap: Called to get a handle to a pixmap from an image. -typedef struct fz_gel_s fz_gel; + image: The image to retrieve a pixmap from. -fz_gel *fz_new_gel(fz_context *ctx); -void fz_insert_gel(fz_gel *gel, float x0, float y0, float x1, float y1); -void fz_reset_gel(fz_gel *gel, fz_bbox clip); -void fz_sort_gel(fz_gel *gel); -fz_bbox fz_bound_gel(fz_gel *gel); -void fz_free_gel(fz_gel *gel); -int fz_is_rect_gel(fz_gel *gel); + w: The desired width (in pixels). This may be completely ignored, but + may serve as an indication of a suitable subsample factor to use for + image types that support this. -void fz_scan_convert(fz_gel *gel, int eofill, fz_bbox clip, fz_pixmap *pix, unsigned char *colorbv); + h: The desired height (in pixels). This may be completely ignored, but + may serve as an indication of a suitable subsample factor to use for + image types that support this. -void fz_flatten_fill_path(fz_gel *gel, fz_path *path, fz_matrix ctm, float flatness); -void fz_flatten_stroke_path(fz_gel *gel, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, float flatness, float linewidth); -void fz_flatten_dash_path(fz_gel *gel, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, float flatness, float linewidth); + Returns a non NULL pixmap pointer. May throw exceptions. +*/ +fz_pixmap *fz_image_to_pixmap(fz_context *ctx, fz_image *image, int w, int h); /* - * The device interface. - */ + fz_drop_image: Drop a reference to an image. -enum -{ - /* Hints */ - FZ_IGNORE_IMAGE = 1, - FZ_IGNORE_SHADE = 2, - - /* Flags */ - FZ_DEVFLAG_MASK = 1, - FZ_DEVFLAG_COLOR = 2, - FZ_DEVFLAG_UNCACHEABLE = 4, - FZ_DEVFLAG_FILLCOLOR_UNDEFINED = 8, - FZ_DEVFLAG_STROKECOLOR_UNDEFINED = 16, - FZ_DEVFLAG_STARTCAP_UNDEFINED = 32, - FZ_DEVFLAG_DASHCAP_UNDEFINED = 64, - FZ_DEVFLAG_ENDCAP_UNDEFINED = 128, - FZ_DEVFLAG_LINEJOIN_UNDEFINED = 256, - FZ_DEVFLAG_MITERLIMIT_UNDEFINED = 512, - FZ_DEVFLAG_LINEWIDTH_UNDEFINED = 1024, - /* Arguably we should have a bit for the dash pattern itself being - * undefined, but that causes problems; do we assume that it should - * always be set to non-dashing at the start of every glyph? */ -}; + image: The image to drop a reference to. +*/ +void fz_drop_image(fz_context *ctx, fz_image *image); -struct fz_device_s -{ - int hints; - int flags; +/* + fz_keep_image: Increment the reference count of an image. - void *user; - void (*free_user)(fz_device *); - fz_context *ctx; - - void (*fill_path)(fz_device *, fz_path *, int even_odd, fz_matrix, fz_colorspace *, float *color, float alpha); - void (*stroke_path)(fz_device *, fz_path *, fz_stroke_state *, fz_matrix, fz_colorspace *, float *color, float alpha); - void (*clip_path)(fz_device *, fz_path *, fz_rect *rect, int even_odd, fz_matrix); - void (*clip_stroke_path)(fz_device *, fz_path *, fz_rect *rect, fz_stroke_state *, fz_matrix); - - void (*fill_text)(fz_device *, fz_text *, fz_matrix, fz_colorspace *, float *color, float alpha); - void (*stroke_text)(fz_device *, fz_text *, fz_stroke_state *, fz_matrix, fz_colorspace *, float *color, float alpha); - void (*clip_text)(fz_device *, fz_text *, fz_matrix, int accumulate); - void (*clip_stroke_text)(fz_device *, fz_text *, fz_stroke_state *, fz_matrix); - void (*ignore_text)(fz_device *, fz_text *, fz_matrix); - - void (*fill_shade)(fz_device *, fz_shade *shd, fz_matrix ctm, float alpha); - void (*fill_image)(fz_device *, fz_pixmap *img, fz_matrix ctm, float alpha); - void (*fill_image_mask)(fz_device *, fz_pixmap *img, fz_matrix ctm, fz_colorspace *, float *color, float alpha); - void (*clip_image_mask)(fz_device *, fz_pixmap *img, fz_rect *rect, fz_matrix ctm); - - void (*pop_clip)(fz_device *); - - void (*begin_mask)(fz_device *, fz_rect, int luminosity, fz_colorspace *, float *bc); - void (*end_mask)(fz_device *); - void (*begin_group)(fz_device *, fz_rect, int isolated, int knockout, int blendmode, float alpha); - void (*end_group)(fz_device *); - - void (*begin_tile)(fz_device *, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm); - void (*end_tile)(fz_device *); -}; + image: The image to take a reference to. -void fz_fill_path(fz_device *dev, fz_path *path, int even_odd, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha); -void fz_stroke_path(fz_device *dev, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha); -void fz_clip_path(fz_device *dev, fz_path *path, fz_rect *rect, int even_odd, fz_matrix ctm); -void fz_clip_stroke_path(fz_device *dev, fz_path *path, fz_rect *rect, fz_stroke_state *stroke, fz_matrix ctm); -void fz_fill_text(fz_device *dev, fz_text *text, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha); -void fz_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha); -void fz_clip_text(fz_device *dev, fz_text *text, fz_matrix ctm, int accumulate); -void fz_clip_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm); -void fz_ignore_text(fz_device *dev, fz_text *text, fz_matrix ctm); -void fz_pop_clip(fz_device *dev); -void fz_fill_shade(fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha); -void fz_fill_image(fz_device *dev, fz_pixmap *image, fz_matrix ctm, float alpha); -void fz_fill_image_mask(fz_device *dev, fz_pixmap *image, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha); -void fz_clip_image_mask(fz_device *dev, fz_pixmap *image, fz_rect *rect, fz_matrix ctm); -void fz_begin_mask(fz_device *dev, fz_rect area, int luminosity, fz_colorspace *colorspace, float *bc); -void fz_end_mask(fz_device *dev); -void fz_begin_group(fz_device *dev, fz_rect area, int isolated, int knockout, int blendmode, float alpha); -void fz_end_group(fz_device *dev); -void fz_begin_tile(fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm); -void fz_end_tile(fz_device *dev); - -fz_device *fz_new_device(fz_context *ctx, void *user); + Returns a pointer to the image. +*/ +fz_image *fz_keep_image(fz_context *ctx, fz_image *image); + +/* + A halftone is a set of threshold tiles, one per component. Each + threshold tile is a pixmap, possibly of varying sizes and phases. + Currently, we only provide one 'default' halftone tile for operating + on 1 component plus alpha pixmaps (where the alpha is ignored). This + is signified by an fz_halftone pointer to NULL. +*/ +typedef struct fz_halftone_s fz_halftone; + +/* + fz_halftone_pixmap: Make a bitmap from a pixmap and a halftone. + + pix: The pixmap to generate from. Currently must be a single color + component + alpha (where the alpha is assumed to be solid). + + ht: The halftone to use. NULL implies the default halftone. + + Returns the resultant bitmap. Throws exceptions in the case of + failure to allocate. +*/ +fz_bitmap *fz_halftone_pixmap(fz_context *ctx, fz_pixmap *pix, fz_halftone *ht); + +/* + An abstract font handle. Currently there are no public API functions + for handling these. +*/ +typedef struct fz_font_s fz_font; + +/* + The different format handlers (pdf, xps etc) interpret pages to a + device. These devices can then process the stream of calls they + recieve in various ways: + The trace device outputs debugging information for the calls. + The draw device will render them. + The list device stores them in a list to play back later. + The text device performs text extraction and searching. + The bbox device calculates the bounding box for the page. + Other devices can (and will) be written in future. +*/ +typedef struct fz_device_s fz_device; + +/* + fz_free_device: Free a devices of any type and its resources. +*/ void fz_free_device(fz_device *dev); +/* + fz_new_trace_device: Create a device to print a debug trace of + all device calls. +*/ fz_device *fz_new_trace_device(fz_context *ctx); + +/* + fz_new_bbox_device: Create a device to compute the bounding + box of all marks on a page. + + The returned bounding box will be the union of all bounding + boxes of all objects on a page. +*/ fz_device *fz_new_bbox_device(fz_context *ctx, fz_bbox *bboxp); + +/* + fz_new_draw_device: Create a device to draw on a pixmap. + + dest: Target pixmap for the draw device. See fz_new_pixmap* + for how to obtain a pixmap. The pixmap is not cleared by the + draw device, see fz_clear_pixmap* for how to clear it prior to + calling fz_new_draw_device. Free the device by calling + fz_free_device. +*/ fz_device *fz_new_draw_device(fz_context *ctx, fz_pixmap *dest); -fz_device *fz_new_draw_device_type3(fz_context *ctx, fz_pixmap *dest); /* - * Text extraction device + Text extraction device: Used for searching, format conversion etc. */ -typedef struct fz_text_span_s fz_text_span; +typedef struct fz_text_style_s fz_text_style; typedef struct fz_text_char_s fz_text_char; +typedef struct fz_text_span_s fz_text_span; +typedef struct fz_text_line_s fz_text_line; +typedef struct fz_text_block_s fz_text_block; + +typedef struct fz_text_sheet_s fz_text_sheet; +typedef struct fz_text_page_s fz_text_page; + +struct fz_text_style_s +{ + int id; + fz_font *font; + float size; + int wmode; + int script; + /* etc... */ + fz_text_style *next; +}; + +struct fz_text_sheet_s +{ + int maxid; + fz_text_style *style; +}; struct fz_text_char_s { + fz_rect bbox; int c; - fz_bbox bbox; }; struct fz_text_span_s { - fz_font *font; - float size; - int wmode; + fz_rect bbox; int len, cap; fz_text_char *text; - fz_text_span *next; - int eol; + fz_text_style *style; }; -fz_text_span *fz_new_text_span(fz_context *ctx); -void fz_free_text_span(fz_context *ctx, fz_text_span *line); -void fz_debug_text_span(fz_text_span *line); -void fz_debug_text_span_xml(fz_text_span *span); +struct fz_text_line_s +{ + fz_rect bbox; + int len, cap; + fz_text_span *spans; +}; -fz_device *fz_new_text_device(fz_context *ctx, fz_text_span *text); +struct fz_text_block_s +{ + fz_rect bbox; + int len, cap; + fz_text_line *lines; +}; + +struct fz_text_page_s +{ + fz_rect mediabox; + int len, cap; + fz_text_block *blocks; +}; + +/* + fz_new_text_device: Create a device to extract the text on a page. + + Gather and sort the text on a page into spans of uniform style, + arranged into lines and blocks by reading order. The reading order + is determined by various heuristics, so may not be accurate. +*/ +fz_device *fz_new_text_device(fz_context *ctx, fz_text_sheet *sheet, fz_text_page *page); + +/* + fz_new_text_sheet: Create an empty style sheet. + + The style sheet is filled out by the text device, creating + one style for each unique font, color, size combination that + is used. +*/ +fz_text_sheet *fz_new_text_sheet(fz_context *ctx); +void fz_free_text_sheet(fz_context *ctx, fz_text_sheet *sheet); + +/* + fz_new_text_page: Create an empty text page. + + The text page is filled out by the text device to contain the blocks, + lines and spans of text on the page. +*/ +fz_text_page *fz_new_text_page(fz_context *ctx, fz_rect mediabox); +void fz_free_text_page(fz_context *ctx, fz_text_page *page); + +void fz_print_text_sheet(fz_context *ctx, FILE *out, fz_text_sheet *sheet); +void fz_print_text_page_html(fz_context *ctx, FILE *out, fz_text_page *page); +void fz_print_text_page_xml(fz_context *ctx, FILE *out, fz_text_page *page); +void fz_print_text_page(fz_context *ctx, FILE *out, fz_text_page *page); /* * Cookie support - simple communication channel between app/library. @@ -1494,6 +1583,40 @@ fz_device *fz_new_text_device(fz_context *ctx, fz_text_span *text); typedef struct fz_cookie_s fz_cookie; +/* + Provide two-way communication between application and library. + Intended for multi-threaded applications where one thread is + rendering pages and another thread wants read progress + feedback or abort a job that takes a long time to finish. The + communication is unsynchronized without locking. + + abort: The appliation should set this field to 0 before + calling fz_run_page to render a page. At any point when the + page is being rendered the application my set this field to 1 + which will cause the rendering to finish soon. This field is + checked periodically when the page is rendered, but exactly + when is not known, therefore there is no upper bound on + exactly when the the rendering will abort. If the application + did not provide a set of locks to fz_new_context, it must also + await the completion of fz_run_page before issuing another + call to fz_run_page. Note that once the application has set + this field to 1 after it called fz_run_page it may not change + the value again. + + progress: Communicates rendering progress back to the + application and is read only. Increments as a page is being + rendered. The value starts out at 0 and is limited to less + than or equal to progress_max, unless progress_max is -1. + + progress_max: Communicates the known upper bound of rendering + back to the application and is read only. The maximum value + that the progress field may take. If there is no known upper + bound on how long the rendering may take this value is -1 and + progress is not limited. Note that the value of progress_max + may change from -1 to a positive value once an upper bound is + known, so take this into consideration when comparing the + value of progress to that of progress_max. +*/ struct fz_cookie_s { int abort; @@ -1502,67 +1625,81 @@ struct fz_cookie_s }; /* - * Display list device -- record and play back device commands. - */ + Display list device -- record and play back device commands. +*/ +/* + fz_display_list is a list containing drawing commands (text, + images, etc.). The intent is two-fold: as a caching-mechanism + to reduce parsing of a page, and to be used as a data + structure in multi-threading where one thread parses the page + and another renders pages. + + Create a displaylist with fz_new_display_list, hand it over to + fz_new_list_device to have it populated, and later replay the + list (once or many times) by calling fz_run_display_list. When + the list is no longer needed free it with fz_free_display_list. +*/ typedef struct fz_display_list_s fz_display_list; +/* + fz_new_display_list: Create an empty display list. + + A display list contains drawing commands (text, images, etc.). + Use fz_new_list_device for populating the list. +*/ fz_display_list *fz_new_display_list(fz_context *ctx); -void fz_free_display_list(fz_context *ctx, fz_display_list *list); + +/* + fz_new_list_device: Create a rendering device for a display list. + + When the device is rendering a page it will populate the + display list with drawing commsnds (text, images, etc.). The + display list can later be reused to render a page many times + without having to re-interpret the page from the document file + for each rendering. Once the device is no longer needed, free + it with fz_free_device. + + list: A display list that the list device takes ownership of. +*/ fz_device *fz_new_list_device(fz_context *ctx, fz_display_list *list); -void fz_run_display_list(fz_display_list *list, fz_device *dev, fz_matrix ctm, fz_bbox area, fz_cookie *cookie); /* - * Plotting functions. - */ + fz_run_display_list: (Re)-run a display list through a device. -void fz_decode_tile(fz_pixmap *pix, float *decode); -void fz_decode_indexed_tile(fz_pixmap *pix, float *decode, int maxval); -void fz_unpack_tile(fz_pixmap *dst, unsigned char * restrict src, int n, int depth, int stride, int scale); + list: A display list, created by fz_new_display_list and + populated with objects from a page by running fz_run_page on a + device obtained from fz_new_list_device. -void fz_paint_solid_alpha(unsigned char * restrict dp, int w, int alpha); -void fz_paint_solid_color(unsigned char * restrict dp, int n, int w, unsigned char *color); + dev: Device obtained from fz_new_*_device. -void fz_paint_span(unsigned char * restrict dp, unsigned char * restrict sp, int n, int w, int alpha); -void fz_paint_span_with_color(unsigned char * restrict dp, unsigned char * restrict mp, int n, int w, unsigned char *color); + ctm: Transform to apply to display list contents. May include + for example scaling and rotation, see fz_scale, fz_rotate and + fz_concat. Set to fz_identity if no transformation is desired. -void fz_paint_image(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, int alpha); -void fz_paint_image_with_color(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, unsigned char *colorbv); + area: Only the part of the contents of the display list + visible within this area will be considered when the list is + run through the device. This does not imply for tile objects + contained in the display list. -void fz_paint_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha); -void fz_paint_pixmap_with_mask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *msk); -void fz_paint_pixmap_with_rect(fz_pixmap *dst, fz_pixmap *src, int alpha, fz_bbox bbox); + cookie: Communication mechanism between caller and library + running the page. Intended for multi-threaded applications, + while single-threaded applications set cookie to NULL. The + caller may abort an ongoing page run. Cookie also communicates + progress information back to the caller. The fields inside + cookie are continually updated while the page is being run. +*/ +void fz_run_display_list(fz_display_list *list, fz_device *dev, fz_matrix ctm, fz_bbox area, fz_cookie *cookie); -void fz_blend_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha, int blendmode, int isolated, fz_pixmap *shape); -void fz_blend_pixel(unsigned char dp[3], unsigned char bp[3], unsigned char sp[3], int blendmode); +/* + fz_free_display_list: Frees a display list. -enum -{ - /* PDF 1.4 -- standard separable */ - FZ_BLEND_NORMAL, - FZ_BLEND_MULTIPLY, - FZ_BLEND_SCREEN, - FZ_BLEND_OVERLAY, - FZ_BLEND_DARKEN, - FZ_BLEND_LIGHTEN, - FZ_BLEND_COLOR_DODGE, - FZ_BLEND_COLOR_BURN, - FZ_BLEND_HARD_LIGHT, - FZ_BLEND_SOFT_LIGHT, - FZ_BLEND_DIFFERENCE, - FZ_BLEND_EXCLUSION, - - /* PDF 1.4 -- standard non-separable */ - FZ_BLEND_HUE, - FZ_BLEND_SATURATION, - FZ_BLEND_COLOR, - FZ_BLEND_LUMINOSITY, - - /* For packing purposes */ - FZ_BLEND_MODEMASK = 15, - FZ_BLEND_ISOLATED = 16, - FZ_BLEND_KNOCKOUT = 32 -}; + list: Display list to be freed. Any objects put into the + display list by a list device will also be freed. + + Does not throw exceptions. +*/ +void fz_free_display_list(fz_context *ctx, fz_display_list *list); /* Links */ @@ -1590,6 +1727,35 @@ enum { fz_link_flag_r_is_zoom = 64 /* rb.x is actually a zoom figure */ }; +/* + fz_link_dest: XXX + + kind: Set to one of FZ_LINK_* to tell what what type of link + destination this is, and where in the union to look for + information. XXX + + gotor.page: Page number, 0 is the first page of the document. XXX + + gotor.flags: A bitfield consisting of fz_link_flag_* telling + what parts of gotor.lt and gotor.rb are valid, whether + fitting to width/height should be used, or if an arbitrary + zoom factor is used. XXX + + gotor.lt: The top left corner of the destination bounding box. XXX + gotor.rb: The bottom right corner of the destination bounding box. XXX + + gotor.file_spec: XXX + + gotor.new_window: XXX + + uri.uri: XXX + uri.is_map: XXX + + launch.file_spec: XXX + launch.new_window: XXX + + named.named: XXX +*/ struct fz_link_dest_s { fz_link_kind kind; @@ -1626,6 +1792,25 @@ struct fz_link_dest_s ld; }; +/* + fz_link is a list of interactive links on a page. + + There is no relation between the order of the links in the + list and the order they appear on the page. The list of links + for a given page can be obtained from fz_load_links. + + A link is reference counted. Dropping a reference to a link is + done by calling fz_drop_link. + + rect: The hot zone. The area that can be clicked in + untransformed coordinates. + + dest: Link destinations come in two forms: Page and area that + an application should display when this link is activated. Or + as an URI that can be given to a browser. + + next: A pointer to the next link on the same page. +*/ struct fz_link_s { int refs; @@ -1636,13 +1821,37 @@ struct fz_link_s fz_link *fz_new_link(fz_context *ctx, fz_rect bbox, fz_link_dest dest); fz_link *fz_keep_link(fz_context *ctx, fz_link *link); + +/* + fz_drop_link: Drop and free a list of links. + + Does not throw exceptions. +*/ void fz_drop_link(fz_context *ctx, fz_link *link); + void fz_free_link_dest(fz_context *ctx, fz_link_dest *dest); /* Outline */ typedef struct fz_outline_s fz_outline; +/* + fz_outline is a tree of the outline of a document (also known + as table of contents). + + title: Title of outline item using UTF-8 encoding. May be NULL + if the outline item has no text string. + + dest: Destination in the document to be displayed when this + outline item is activated. May be FZ_LINK_NONE if the outline + item does not have a destination. + + next: The next outline item at the same level as this outline + item. May be NULL if no more outline items exist at this level. + + down: The outline items immediate children in the hierarchy. + May be NULL if no children exist. +*/ struct fz_outline_s { char *title; @@ -1651,43 +1860,155 @@ struct fz_outline_s fz_outline *down; }; -void fz_debug_outline_xml(fz_context *ctx, fz_outline *outline, int level); -void fz_debug_outline(fz_context *ctx, fz_outline *outline, int level); -void fz_free_outline(fz_context *ctx, fz_outline *outline); +/* + fz_print_outline_xml: Dump the given outlines as (pseudo) XML. + + out: The file handle to output to. -/* Document interface */ + outline: The outlines to output. +*/ +void fz_print_outline_xml(fz_context *ctx, FILE *out, fz_outline *outline); +/* + fz_print_outline: Dump the given outlines to as text. + + out: The file handle to output to. + + outline: The outlines to output. +*/ +void fz_print_outline(fz_context *ctx, FILE *out, fz_outline *outline); + +/* + fz_free_outline: Free hierarchical outline. + + Free an outline obtained from fz_load_outline. + + Does not throw exceptions. +*/ +void fz_free_outline(fz_context *ctx, fz_outline *outline); + +/* + Document interface +*/ typedef struct fz_document_s fz_document; -typedef struct fz_page_s fz_page; /* doesn't have a definition -- always cast to *_page */ +typedef struct fz_page_s fz_page; -struct fz_document_s -{ - void (*close)(fz_document *); - int (*needs_password)(fz_document *doc); - int (*authenticate_password)(fz_document *doc, char *password); - fz_outline *(*load_outline)(fz_document *doc); - int (*count_pages)(fz_document *doc); - fz_page *(*load_page)(fz_document *doc, int number); - fz_link *(*load_links)(fz_document *doc, fz_page *page); - fz_rect (*bound_page)(fz_document *doc, fz_page *page); - void (*run_page)(fz_document *doc, fz_page *page, fz_device *dev, fz_matrix transform, fz_cookie *cookie); - void (*free_page)(fz_document *doc, fz_page *page); -}; +/* + fz_open_document: Open a PDF, XPS or CBZ document. + + Open a document file and read its basic structure so pages and + objects can be located. MuPDF will try to repair broken + documents (without actually changing the file contents). + The returned fz_document is used when calling most other + document related functions. Note that it wraps the context, so + those functions implicitly can access the global state in + context. + + filename: a path to a file as it would be given to open(2). +*/ fz_document *fz_open_document(fz_context *ctx, char *filename); +/* + fz_close_document: Close and free an open document. + + The resource store in the context associated with fz_document + is emptied, and any allocations for the document are freed. + + Does not throw exceptions. +*/ void fz_close_document(fz_document *doc); +/* + fz_needs_password: Check if a document is encrypted with a + non-blank password. + + Does not throw exceptions. +*/ int fz_needs_password(fz_document *doc); + +/* + fz_authenticate_password: Test if the given password can + decrypt the document. + + password: The password string to be checked. Some document + specifications do not specify any particular text encoding, so + neither do we. + + Does not throw exceptions. +*/ int fz_authenticate_password(fz_document *doc, char *password); +/* + fz_load_outline: Load the hierarchical document outline. + + Should be freed by fz_free_outline. +*/ fz_outline *fz_load_outline(fz_document *doc); +/* + fz_count_pages: Return the number of pages in document + + May return 0 for documents with no pages. +*/ int fz_count_pages(fz_document *doc); + +/* + fz_load_page: Load a page. + + After fz_load_page is it possible to retrieve the size of the + page using fz_bound_page, or to render the page using + fz_run_page_*. Free the page by calling fz_free_page. + + number: page number, 0 is the first page of the document. +*/ fz_page *fz_load_page(fz_document *doc, int number); + +/* + fz_load_links: Load the list of links for a page. + + Returns a linked list of all the links on the page, each with + its clickable region and link destination. Each link is + reference counted so drop and free the list of links by + calling fz_drop_link on the pointer return from fz_load_links. + + page: Page obtained from fz_load_page. +*/ fz_link *fz_load_links(fz_document *doc, fz_page *page); + +/* + fz_bound_page: Determine the size of a page at 72 dpi. + + Does not throw exceptions. +*/ fz_rect fz_bound_page(fz_document *doc, fz_page *page); + +/* + fz_run_page: Run a page through a device. + + page: Page obtained from fz_load_page. + + dev: Device obtained from fz_new_*_device. + + transform: Transform to apply to page. May include for example + scaling and rotation, see fz_scale, fz_rotate and fz_concat. + Set to fz_identity if no transformation is desired. + + cookie: Communication mechanism between caller and library + rendering the page. Intended for multi-threaded applications, + while single-threaded applications set cookie to NULL. The + caller may abort an ongoing rendering of a page. Cookie also + communicates progress information back to the caller. The + fields inside cookie are continually updated while the page is + rendering. +*/ void fz_run_page(fz_document *doc, fz_page *page, fz_device *dev, fz_matrix transform, fz_cookie *cookie); + +/* + fz_free_page: Free a loaded page. + + Does not throw exceptions. +*/ void fz_free_page(fz_document *doc, fz_page *page); #endif |