#ifndef _FITZ_H_ #define _FITZ_H_ /* * Include the standard libc headers. */ #include #include #include #include #include #include #include #include #include /* FLT_EPSILON */ #include /* O_RDONLY & co */ #define nil ((void*)0) #define nelem(x) (sizeof(x)/sizeof((x)[0])) /* * Some differences in libc can be smoothed over */ #ifdef _MSC_VER /* Microsoft Visual C */ #pragma warning( disable: 4244 ) /* conversion from X to Y, possible loss of data */ #pragma warning( disable: 4996 ) /* The POSIX name for this item is deprecated */ #pragma warning( disable: 4996 ) /* This function or variable may be unsafe */ #include int gettimeofday(struct timeval *tv, struct timezone *tz); #define snprintf _snprintf #define strtoll _strtoi64 #else /* Unix or close enough */ #include #ifndef O_BINARY #define O_BINARY 0 #endif #endif #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #ifndef M_SQRT2 #define M_SQRT2 1.41421356237309504880 #endif /* * Variadic macros, inline and restrict keywords */ #if __STDC_VERSION__ == 199901L /* C99 */ #define fz_throw(...) fz_throwimp(__FILE__, __LINE__, __func__, __VA_ARGS__) #define fz_rethrow(cause, ...) fz_rethrowimp(__FILE__, __LINE__, __func__, cause, __VA_ARGS__) #define fz_catch(cause, ...) fz_catchimp(__FILE__, __LINE__, __func__, cause, __VA_ARGS__) #elif _MSC_VER >= 1500 /* MSVC 9 or newer */ #define inline __inline #define restrict __restrict #define fz_throw(...) fz_throwimp(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__) #define fz_rethrow(cause, ...) fz_rethrowimp(__FILE__, __LINE__, __FUNCTION__, cause, __VA_ARGS__) #define fz_catch(cause, ...) fz_catchimp(__FILE__, __LINE__, __FUNCTION__, cause, __VA_ARGS__) #elif __GNUC__ >= 3 /* GCC 3 or newer */ #define inline __inline #define restrict __restrict #define fz_throw(fmt...) fz_throwimp(__FILE__, __LINE__, __FUNCTION__, fmt) #define fz_rethrow(cause, fmt...) fz_rethrowimp(__FILE__, __LINE__, __FUNCTION__, cause, fmt) #define fz_catch(cause, fmt...) fz_catchimp(__FILE__, __LINE__, __FUNCTION__, cause, fmt) #else /* Unknown or ancient */ #define inline #define restrict #define fz_throw fz_throwimpx #define fz_rethrow fz_rethrowimpx #define fz_catch fz_catchimpx #endif /* * GCC can do type checking of printf strings */ #ifndef __printflike #if __GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7 #define __printflike(fmtarg, firstvararg) \ __attribute__((__format__ (__printf__, fmtarg, firstvararg))) #else #define __printflike(fmtarg, firstvararg) #endif #endif /* * Error handling */ typedef int fz_error; void fz_warn(char *fmt, ...) __printflike(1, 2); fz_error fz_throwimp(const char *file, int line, const char *func, char *fmt, ...) __printflike(4, 5); fz_error fz_rethrowimp(const char *file, int line, const char *func, fz_error cause, char *fmt, ...) __printflike(5, 6); void fz_catchimp(const char *file, int line, const char *func, fz_error cause, char *fmt, ...) __printflike(5, 6); fz_error fz_throwimpx(char *fmt, ...) __printflike(1, 2); fz_error fz_rethrowimpx(fz_error cause, char *fmt, ...) __printflike(2, 3); void fz_catchimpx(fz_error cause, char *fmt, ...) __printflike(2, 3); #define fz_okay ((fz_error)0) /* * Basic runtime and utility functions */ #define ABS(x) ( (x) < 0 ? -(x) : (x) ) #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) ) ) /* memory allocation */ void *fz_malloc(int n); void *fz_realloc(void *p, int n); void fz_free(void *p); char *fz_strdup(char *s); /* runtime (hah!) test for endian-ness */ int fz_isbigendian(void); /* safe string functions */ 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); /* utf-8 encoding and decoding */ int chartorune(int *rune, char *str); int runetochar(char *str, int *rune); int runelen(int c); /* getopt */ extern int fz_getopt(int nargc, char * const * nargv, const char *ostr); extern int fz_optind; extern char *fz_optarg; /* * Generic hash-table with fixed-length keys. */ typedef struct fz_hashtable_s fz_hashtable; fz_hashtable * fz_newhash(int initialsize, int keylen); void fz_debughash(fz_hashtable *table); void fz_emptyhash(fz_hashtable *table); void fz_freehash(fz_hashtable *table); void *fz_hashfind(fz_hashtable *table, void *key); void fz_hashinsert(fz_hashtable *table, void *key, void *val); void fz_hashremove(fz_hashtable *table, void *key); int fz_hashlen(fz_hashtable *table); void *fz_hashgetkey(fz_hashtable *table, int idx); void *fz_hashgetval(fz_hashtable *table, int idx); /* * Math and geometry */ /* 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; } /* Expand a value A from the 0...255 range to the 0..256 range */ #define FZ_EXPAND(A) ((A)+((A)>>7)) /* 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) /* 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) 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; extern const fz_rect fz_unitrect; extern const fz_rect fz_emptyrect; extern const fz_rect fz_infiniterect; extern const fz_bbox fz_unitbbox; extern const fz_bbox fz_emptybbox; extern const fz_bbox fz_infinitebbox; #define fz_isemptyrect(r) ((r).x0 == (r).x1) #define fz_isinfiniterect(r) ((r).x0 > (r).x1) struct fz_matrix_s { float a, b, c, d, e, f; }; struct fz_point_s { float x, y; }; struct fz_rect_s { float x0, y0; float x1, y1; }; struct fz_bbox_s { int x0, y0; int x1, y1; }; extern const fz_matrix fz_identity; fz_matrix fz_concat(fz_matrix one, fz_matrix two); fz_matrix fz_scale(float sx, float sy); fz_matrix fz_rotate(float theta); fz_matrix fz_translate(float tx, float ty); fz_matrix fz_invertmatrix(fz_matrix m); int fz_isrectilinear(fz_matrix m); float fz_matrixexpansion(fz_matrix m); fz_bbox fz_roundrect(fz_rect r); fz_bbox fz_intersectbbox(fz_bbox a, fz_bbox b); fz_bbox fz_unionbbox(fz_bbox a, fz_bbox b); fz_point fz_transformpoint(fz_matrix m, fz_point p); fz_point fz_transformvector(fz_matrix m, fz_point p); fz_rect fz_transformrect(fz_matrix m, fz_rect r); /* * Basic crypto functions. * Independent of the rest of fitz. * For further encapsulation in filters, or not. */ /* md5 digests */ typedef struct fz_md5_s fz_md5; struct fz_md5_s { unsigned int state[4]; unsigned int count[2]; unsigned char buffer[64]; }; void fz_md5init(fz_md5 *state); void fz_md5update(fz_md5 *state, const unsigned char *input, const unsigned inlen); void fz_md5final(fz_md5 *state, unsigned char digest[16]); /* arc4 crypto */ typedef struct fz_arc4_s fz_arc4; struct fz_arc4_s { unsigned x; unsigned y; unsigned char state[256]; }; void fz_arc4init(fz_arc4 *state, const unsigned char *key, const unsigned len); unsigned char fz_arc4next(fz_arc4 *state); void fz_arc4encrypt(fz_arc4 *state, unsigned char *dest, const unsigned char *src, const unsigned len); /* AES block cipher implementation from XYSSL */ typedef struct fz_aes_s fz_aes; #define AES_DECRYPT 0 #define AES_ENCRYPT 1 struct fz_aes_s { int nr; /* number of rounds */ unsigned long *rk; /* AES round keys */ unsigned long buf[68]; /* unaligned data */ }; 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 ); /* * Dynamic objects. * The same type of objects as found in PDF and PostScript. * Used by the filters and the mupdf parser. */ typedef struct fz_obj_s fz_obj; typedef struct fz_keyval_s fz_keyval; struct pdf_xref_s; typedef enum fz_objkind_e { FZ_NULL, FZ_BOOL, FZ_INT, FZ_REAL, FZ_STRING, FZ_NAME, FZ_ARRAY, FZ_DICT, FZ_INDIRECT } fz_objkind; struct fz_keyval_s { fz_obj *k; fz_obj *v; }; struct fz_obj_s { int refs; fz_objkind kind; union { int b; int i; float f; struct { unsigned short len; char buf[1]; } s; char n[1]; struct { int len; int cap; fz_obj **items; } a; struct { char sorted; int len; int cap; fz_keyval *items; } d; struct { int num; int gen; struct pdf_xref_s *xref; fz_obj *obj; } r; } u; }; fz_obj * fz_newnull(void); fz_obj * fz_newbool(int b); fz_obj * fz_newint(int i); fz_obj * fz_newreal(float f); fz_obj * fz_newname(char *str); fz_obj * fz_newstring(char *str, int len); fz_obj * fz_newindirect(int num, int gen, struct pdf_xref_s *xref); fz_obj * fz_newarray(int initialcap); fz_obj * fz_newdict(int initialcap); fz_obj * fz_copyarray(fz_obj *array); fz_obj * fz_copydict(fz_obj *dict); fz_obj *fz_keepobj(fz_obj *obj); void fz_dropobj(fz_obj *obj); /* type queries */ int fz_isnull(fz_obj *obj); int fz_isbool(fz_obj *obj); int fz_isint(fz_obj *obj); int fz_isreal(fz_obj *obj); int fz_isname(fz_obj *obj); int fz_isstring(fz_obj *obj); int fz_isarray(fz_obj *obj); int fz_isdict(fz_obj *obj); int fz_isindirect(fz_obj *obj); int fz_objcmp(fz_obj *a, fz_obj *b); fz_obj *fz_resolveindirect(fz_obj *obj); /* silent failure, no error reporting */ int fz_tobool(fz_obj *obj); int fz_toint(fz_obj *obj); float fz_toreal(fz_obj *obj); char *fz_toname(fz_obj *obj); char *fz_tostrbuf(fz_obj *obj); int fz_tostrlen(fz_obj *obj); int fz_tonum(fz_obj *obj); int fz_togen(fz_obj *obj); int fz_arraylen(fz_obj *array); fz_obj *fz_arrayget(fz_obj *array, int i); void fz_arrayput(fz_obj *array, int i, fz_obj *obj); void fz_arraypush(fz_obj *array, fz_obj *obj); int fz_dictlen(fz_obj *dict); fz_obj *fz_dictgetkey(fz_obj *dict, int idx); fz_obj *fz_dictgetval(fz_obj *dict, int idx); fz_obj *fz_dictget(fz_obj *dict, fz_obj *key); fz_obj *fz_dictgets(fz_obj *dict, char *key); fz_obj *fz_dictgetsa(fz_obj *dict, char *key, char *abbrev); void fz_dictput(fz_obj *dict, fz_obj *key, fz_obj *val); void fz_dictputs(fz_obj *dict, char *key, fz_obj *val); void fz_dictdel(fz_obj *dict, fz_obj *key); void fz_dictdels(fz_obj *dict, char *key); void fz_sortdict(fz_obj *dict); int fz_sprintobj(char *s, int n, fz_obj *obj, int tight); int fz_fprintobj(FILE *fp, fz_obj *obj, int tight); void fz_debugobj(fz_obj *obj); char *fz_objkindstr(fz_obj *obj); /* * Data buffers for streams and filters. * * bp is the pointer to the allocated memory * rp is read-position (*in->rp++ to read data) * wp is write-position (*out->wp++ to write data) * ep is the sentinel * * Only the data between rp and wp is valid data. * * Writers set eof to true at the end. * Readers look at eof. * * A buffer owns the memory it has allocated, unless ownsdata is false, * in which case the creator of the buffer owns it. */ typedef struct fz_buffer_s fz_buffer; #define FZ_BUFSIZE (8 * 1024) struct fz_buffer_s { int refs; int ownsdata; unsigned char *bp; unsigned char *rp; unsigned char *wp; unsigned char *ep; int eof; }; fz_buffer * fz_newbuffer(int size); fz_buffer * fz_newbufferwithmemory(unsigned char *data, int size); void fz_resizebuffer(fz_buffer *buf, int size); void fz_rewindbuffer(fz_buffer *buf); void fz_growbuffer(fz_buffer *buf); fz_buffer *fz_keepbuffer(fz_buffer *buf); void fz_dropbuffer(fz_buffer *buf); /* * Data filters for encryption, compression and decompression. * * A filter has one method, process, that takes an input and an output buffer. * * It returns one of three statuses: * ioneedin -- input buffer exhausted, please give me more data (wp-rp) * ioneedout -- output buffer exhausted, please provide more space (ep-wp) * iodone -- finished, please never call me again. ever! * or... * any other error code -- oops, something blew up. * * To make using the filter easier, three variables are updated: * produced -- if we actually produced any new data * consumed -- like above * count -- number of bytes produced in total since the beginning * done -- remember if we've ever returned fz_iodone * * Most filters take fz_obj as a way to specify parameters. * In most cases, this is a dictionary that contains the same keys * that the corresponding PDF filter would expect. * * The pipeline filter is special, and needs some care when chaining * and unchaining new filters. */ typedef struct fz_filter_s fz_filter; #define fz_ioneedin ((fz_error)1) #define fz_ioneedout ((fz_error)2) #define fz_iodone ((fz_error)3) /* * Evil looking macro to create an initialize a filter struct. */ #define FZ_NEWFILTER(TYPE,VAR,NAME) \ fz_error fz_process ## NAME (fz_filter*,fz_buffer*,fz_buffer*); \ void fz_drop ## NAME (fz_filter*); \ TYPE *VAR; \ VAR = fz_malloc(sizeof(TYPE)); \ ((fz_filter*)VAR)->refs = 1; \ ((fz_filter*)VAR)->process = fz_process ## NAME ; \ ((fz_filter*)VAR)->drop = fz_drop ## NAME ; \ ((fz_filter*)VAR)->consumed = 0; \ ((fz_filter*)VAR)->produced = 0; \ ((fz_filter*)VAR)->count = 0; \ ((fz_filter*)VAR)->done = 0; struct fz_filter_s { int refs; fz_error (*process)(fz_filter *filter, fz_buffer *in, fz_buffer *out); void (*drop)(fz_filter *filter); int consumed; int produced; int count; int done; }; fz_error fz_process(fz_filter *f, fz_buffer *in, fz_buffer *out); fz_filter *fz_keepfilter(fz_filter *f); void fz_dropfilter(fz_filter *f); fz_filter * fz_newpipeline(fz_filter *head, fz_filter *tail); fz_filter * fz_chainpipeline(fz_filter *head, fz_filter *tail, fz_buffer *buf); void fz_unchainpipeline(fz_filter *pipe, fz_filter **oldfp, fz_buffer **oldbp); fz_filter * fz_newnullfilter(int len); fz_filter * fz_newcopyfilter(); fz_filter * fz_newarc4filter(unsigned char *key, unsigned keylen); fz_filter * fz_newaesdfilter(unsigned char *key, unsigned keylen); fz_filter * fz_newa85d(fz_obj *param); fz_filter * fz_newahxd(fz_obj *param); fz_filter * fz_newrld(fz_obj *param); fz_filter * fz_newdctd(fz_obj *param); fz_filter * fz_newfaxd(fz_obj *param); fz_filter * fz_newflated(fz_obj *param); fz_filter * fz_newlzwd(fz_obj *param); fz_filter * fz_newpredictd(fz_obj *param); fz_filter * fz_newjbig2d(fz_obj *param); fz_filter * fz_newjpxd(fz_obj *param); fz_error fz_setjbig2dglobalstream(fz_filter *filter, unsigned char *buf, int len); /* * Stream API for Fitz. * Read and write data to and from files, memory buffers and filters. */ typedef struct fz_stream_s fz_stream; enum { FZ_SFILE, FZ_SBUFFER, FZ_SFILTER }; struct fz_stream_s { int refs; int kind; int dead; fz_buffer *buffer; fz_filter *filter; fz_stream *chain; fz_error error; /* delayed error from readbyte and peekbyte */ int file; }; /* * Various stream creation functions. */ fz_stream * fz_openfile(int file); fz_stream * fz_openmemory(unsigned char *mem, int len); fz_stream * fz_openbuffer(fz_buffer *buf); fz_stream * fz_openfilter(fz_filter *flt, fz_stream *chain); /* * Functions that are common to both input and output streams. */ fz_stream *fz_keepstream(fz_stream *stm); void fz_dropstream(fz_stream *stm); int fz_tell(fz_stream *stm); fz_error fz_seek(fz_stream *stm, int offset, int whence); /* * Input stream functions. */ fz_error fz_readimp(fz_stream *stm); fz_error fz_read(int *np, fz_stream *stm, unsigned char *buf, int len); fz_error fz_readline(fz_stream *stm, char *buf, int max); fz_buffer * fz_readall(fz_stream *stm, int sizehint); /* * Error handling when reading with readbyte/peekbyte is non-standard. * The cause of an error is stuck into the stream struct, * and EOF is returned. Not good, but any other way is too painful. * So we have to be careful to check the error status eventually. */ fz_error fz_readerror(fz_stream *stm); int fz_readbytex(fz_stream *stm); int fz_peekbytex(fz_stream *stm); static inline int fz_readbyte(fz_stream *stm) { fz_buffer *buf = stm->buffer; if (buf->rp < buf->wp) return *buf->rp++; return fz_readbytex(stm); } static inline int fz_peekbyte(fz_stream *stm) { fz_buffer *buf = stm->buffer; if (buf->rp < buf->wp) return *buf->rp; return fz_peekbytex(stm); } static inline void fz_unreadbyte(fz_stream *stm) { fz_buffer *buf = stm->buffer; buf->rp--; } /* * Resources and other graphics related objects. */ enum { FZ_MAXCOLORS = 32 }; typedef enum fz_blendmode_e { /* PDF 1.4 -- standard separable */ FZ_BNORMAL, FZ_BMULTIPLY, FZ_BSCREEN, FZ_BOVERLAY, FZ_BDARKEN, FZ_BLIGHTEN, FZ_BCOLORDODGE, FZ_BCOLORBURN, FZ_BHARDLIGHT, FZ_BSOFTLIGHT, FZ_BDIFFERENCE, FZ_BEXCLUSION, /* PDF 1.4 -- standard non-separable */ FZ_BHUE, FZ_BSATURATION, FZ_BCOLOR, FZ_BLUMINOSITY, } fz_blendmode; extern const char *fz_blendnames[]; /* * Pixmaps have n components per pixel. the last is always alpha. * 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 { int refs; int x, y, w, h, n; fz_colorspace *colorspace; unsigned char *samples; }; fz_pixmap * fz_newpixmapwithrect(fz_colorspace *, fz_bbox bbox); fz_pixmap * fz_newpixmap(fz_colorspace *, int x, int y, int w, int h); fz_pixmap *fz_keeppixmap(fz_pixmap *pix); void fz_droppixmap(fz_pixmap *pix); void fz_clearpixmap(fz_pixmap *pix, int value); void fz_gammapixmap(fz_pixmap *pix, float gamma); fz_pixmap *fz_alphafromgray(fz_pixmap *gray, int luminosity); fz_bbox fz_boundpixmap(fz_pixmap *pix); fz_pixmap * fz_scalepixmap(fz_pixmap *src, int xdenom, int ydenom); fz_error fz_writepnm(fz_pixmap *pixmap, char *filename); fz_error fz_writepam(fz_pixmap *pixmap, char *filename, int savealpha); fz_error fz_writepng(fz_pixmap *pixmap, char *filename, int savealpha); /* * Colorspace resources. */ extern fz_colorspace *fz_devicegray; extern fz_colorspace *fz_devicergb; extern fz_colorspace *fz_devicebgr; extern fz_colorspace *fz_devicecmyk; struct fz_colorspace_s { int refs; char name[16]; int n; void (*toxyz)(fz_colorspace *, float *src, float *xyz); void (*fromxyz)(fz_colorspace *, float *xyz, float *dst); void (*freedata)(fz_colorspace *); void *data; }; fz_colorspace *fz_newcolorspace(char *name, int n); fz_colorspace *fz_keepcolorspace(fz_colorspace *cs); void fz_dropcolorspace(fz_colorspace *cs); void fz_convertcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv); void fz_convertpixmap(fz_pixmap *src, fz_pixmap *dst); /* * Fonts come in two variants: * Regular fonts are handled by FreeType. * Type 3 fonts have callbacks to the interpreter. */ struct fz_device_s; struct pdf_xref_s; typedef struct fz_font_s fz_font; char *ft_errorstring(int err); struct fz_font_s { int refs; char name[32]; void *ftface; /* has an FT_Face if used */ int ftsubstitute; /* ... substitute metrics */ int fthint; /* ... force hinting for DynaLab fonts */ fz_matrix t3matrix; fz_obj *t3resources; fz_buffer **t3procs; /* has 256 entries if used */ float *t3widths; /* has 256 entries if used */ void *t3xref; /* a pdf_xref for the callback */ fz_error (*t3run)(struct pdf_xref_s *xref, fz_obj *resources, fz_buffer *contents, struct fz_device_s *dev, fz_matrix ctm); fz_rect bbox; /* substitute metrics */ int widthcount; int *widthtable; }; fz_error fz_newfreetypefont(fz_font **fontp, char *name, int substitute); fz_error fz_loadfreetypefontfile(fz_font *font, char *path, int index); fz_error fz_loadfreetypefontbuffer(fz_font *font, unsigned char *data, int len, int index); fz_font * fz_newtype3font(char *name, fz_matrix matrix); fz_error fz_newfontfrombuffer(fz_font **fontp, unsigned char *data, int len, int index); fz_error fz_newfontfromfile(fz_font **fontp, char *path, int index); fz_font * fz_keepfont(fz_font *font); void fz_dropfont(fz_font *font); void fz_debugfont(fz_font *font); void fz_setfontbbox(fz_font *font, float xmin, float ymin, float xmax, float ymax); /* * Vector path buffer. * It can be stroked and dashed, or be filled. * It has a fill rule (nonzero or evenodd). * * When rendering, they are flattened, stroked and dashed straight * into the Global Edge List. */ typedef struct fz_path_s fz_path; typedef struct fz_strokestate_s fz_strokestate; typedef union fz_pathel_s fz_pathel; typedef enum fz_pathelkind_e { FZ_MOVETO, FZ_LINETO, FZ_CURVETO, FZ_CLOSEPATH } fz_pathelkind; union fz_pathel_s { fz_pathelkind k; float v; }; struct fz_strokestate_s { int linecap; int linejoin; float linewidth; float miterlimit; float dashphase; int dashlen; float dashlist[32]; }; struct fz_path_s { int len, cap; fz_pathel *els; }; fz_path *fz_newpath(void); void fz_moveto(fz_path*, float x, float y); void fz_lineto(fz_path*, float x, float y); void fz_curveto(fz_path*, float, float, float, float, float, float); void fz_curvetov(fz_path*, float, float, float, float); void fz_curvetoy(fz_path*, float, float, float, float); void fz_closepath(fz_path*); void fz_freepath(fz_path *path); fz_path *fz_clonepath(fz_path *old); fz_rect fz_boundpath(fz_path *path, fz_strokestate *stroke, fz_matrix ctm); void fz_debugpath(fz_path *, int indent); /* * 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. */ typedef struct fz_text_s fz_text; typedef struct fz_textel_s fz_textel; struct fz_textel_s { float x, y; int gid; /* -1 for one gid to many ucs mappings */ int ucs; /* -1 for one ucs to many gid mappings */ }; struct fz_text_s { fz_font *font; fz_matrix trm; int wmode; int len, cap; fz_textel *els; }; fz_text * fz_newtext(fz_font *face, fz_matrix trm, int wmode); void fz_addtext(fz_text *text, int gid, int ucs, float x, float y); void fz_endtext(fz_text *text); void fz_freetext(fz_text *text); void fz_debugtext(fz_text*, int indent); fz_rect fz_boundtext(fz_text *text, fz_matrix ctm); fz_text *fz_clonetext(fz_text *old); /* * The shading code uses gouraud shaded triangle meshes. */ typedef struct fz_shade_s fz_shade; struct fz_shade_s { int refs; fz_rect bbox; /* can be fz_infiniterect */ fz_colorspace *cs; fz_matrix matrix; /* matrix from pattern dict */ int usebackground; /* background color for fills but not 'sh' */ float background[FZ_MAXCOLORS]; int usefunction; float function[256][FZ_MAXCOLORS]; int meshlen; int meshcap; float *mesh; /* [x y t] or [x y c1 ... cn] */ }; fz_shade *fz_keepshade(fz_shade *shade); void fz_dropshade(fz_shade *shade); void fz_debugshade(fz_shade *shade); fz_rect fz_boundshade(fz_shade *shade, fz_matrix ctm); void fz_rendershade(fz_shade *shade, fz_matrix ctm, fz_pixmap *dst, fz_bbox bbox); /* * Glyph cache */ typedef struct fz_glyphcache_s fz_glyphcache; fz_glyphcache * fz_newglyphcache(void); fz_pixmap * fz_renderftglyph(fz_font *font, int cid, fz_matrix trm); fz_pixmap * fz_rendert3glyph(fz_font *font, int cid, fz_matrix trm); fz_pixmap * fz_renderftstrokedglyph(fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_strokestate *state); fz_pixmap * fz_renderglyph(fz_glyphcache*, fz_font*, int, fz_matrix); fz_pixmap * fz_renderstrokedglyph(fz_glyphcache*, fz_font*, int, fz_matrix, fz_matrix, fz_strokestate *stroke); void fz_freeglyphcache(fz_glyphcache *); /* * Scan converter */ typedef struct fz_edge_s fz_edge; typedef struct fz_gel_s fz_gel; typedef struct fz_ael_s fz_ael; struct fz_edge_s { int x, e, h, y; int adjup, adjdown; int xmove; int xdir, ydir; /* -1 or +1 */ }; struct fz_gel_s { fz_bbox clip; fz_bbox bbox; int cap; int len; fz_edge *edges; }; struct fz_ael_s { int cap; int len; fz_edge **edges; }; fz_gel * fz_newgel(void); void fz_insertgel(fz_gel *gel, float x0, float y0, float x1, float y1); fz_bbox fz_boundgel(fz_gel *gel); void fz_resetgel(fz_gel *gel, fz_bbox clip); void fz_sortgel(fz_gel *gel); void fz_freegel(fz_gel *gel); int fz_isrectgel(fz_gel *gel); fz_ael * fz_newael(void); void fz_freeael(fz_ael *ael); fz_error fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, fz_bbox clip, fz_pixmap *pix, unsigned char *colorbv, fz_pixmap *image, fz_matrix *invmat); void fz_fillpath(fz_gel *gel, fz_path *path, fz_matrix ctm, float flatness); void fz_strokepath(fz_gel *gel, fz_path *path, fz_strokestate *stroke, fz_matrix ctm, float flatness, float linewidth); void fz_dashpath(fz_gel *gel, fz_path *path, fz_strokestate *stroke, fz_matrix ctm, float flatness, float linewidth); /* * The device interface. */ enum { FZ_IGNOREIMAGE = 1, FZ_IGNORESHADE = 2, }; typedef struct fz_device_s fz_device; struct fz_device_s { int hints; void *user; void (*freeuser)(void *); void (*fillpath)(void *, fz_path *, int evenodd, fz_matrix, fz_colorspace *, float *color, float alpha); void (*strokepath)(void *, fz_path *, fz_strokestate *, fz_matrix, fz_colorspace *, float *color, float alpha); void (*clippath)(void *, fz_path *, int evenodd, fz_matrix); void (*clipstrokepath)(void *, fz_path *, fz_strokestate *, fz_matrix); void (*filltext)(void *, fz_text *, fz_matrix, fz_colorspace *, float *color, float alpha); void (*stroketext)(void *, fz_text *, fz_strokestate *, fz_matrix, fz_colorspace *, float *color, float alpha); void (*cliptext)(void *, fz_text *, fz_matrix, int accumulate); void (*clipstroketext)(void *, fz_text *, fz_strokestate *, fz_matrix); void (*ignoretext)(void *, fz_text *, fz_matrix); void (*fillshade)(void *, fz_shade *shd, fz_matrix ctm); void (*fillimage)(void *, fz_pixmap *img, fz_matrix ctm); void (*fillimagemask)(void *, fz_pixmap *img, fz_matrix ctm, fz_colorspace *, float *color, float alpha); void (*clipimagemask)(void *, fz_pixmap *img, fz_matrix ctm); void (*popclip)(void *); void (*beginmask)(void *, fz_rect, int luminosity, fz_colorspace *cs, float *bc); void (*endmask)(void *); void (*begingroup)(void *, fz_rect, int isolated, int knockout, fz_blendmode blendmode); void (*endgroup)(void *); }; fz_device *fz_newdevice(void *user); void fz_freedevice(fz_device *dev); fz_device *fz_newtracedevice(void); fz_device *fz_newbboxdevice(fz_bbox *bboxp); fz_device *fz_newdrawdevice(fz_glyphcache *cache, fz_pixmap *dest); /* * Text extraction device */ typedef struct fz_textspan_s fz_textspan; typedef struct fz_textchar_s fz_textchar; struct fz_textchar_s { int c; fz_bbox bbox; }; struct fz_textspan_s { fz_font *font; float size; int wmode; int len, cap; fz_textchar *text; fz_textspan *next; int eol; }; fz_textspan * fz_newtextspan(void); void fz_freetextspan(fz_textspan *line); void fz_debugtextspan(fz_textspan *line); void fz_debugtextspanxml(fz_textspan *span); fz_device *fz_newtextdevice(fz_textspan *text); /* * Display list device -- record and play back device commands. */ typedef struct fz_displaylist_s fz_displaylist; typedef struct fz_displaynode_s fz_displaynode; typedef enum fz_displaycommand_e { FZ_CMDFILLPATH, FZ_CMDSTROKEPATH, FZ_CMDCLIPPATH, FZ_CMDCLIPSTROKEPATH, FZ_CMDFILLTEXT, FZ_CMDSTROKETEXT, FZ_CMDCLIPTEXT, FZ_CMDCLIPSTROKETEXT, FZ_CMDIGNORETEXT, FZ_CMDFILLSHADE, FZ_CMDFILLIMAGE, FZ_CMDFILLIMAGEMASK, FZ_CMDCLIPIMAGEMASK, FZ_CMDPOPCLIP, FZ_CMDBEGINMASK, FZ_CMDENDMASK, FZ_CMDBEGINGROUP, FZ_CMDENDGROUP, } fz_displaycommand; struct fz_displaylist_s { fz_displaynode *first; fz_displaynode *last; }; struct fz_displaynode_s { fz_displaycommand cmd; fz_displaynode *next; fz_rect rect; union { fz_path *path; fz_text *text; fz_shade *shade; fz_pixmap *image; fz_blendmode blendmode; } item; fz_strokestate *stroke; int flag; /* evenodd, accumulate, isolated/knockout... */ fz_matrix ctm; fz_colorspace *colorspace; float alpha; float color[FZ_MAXCOLORS]; }; fz_displaylist *fz_newdisplaylist(void); void fz_freedisplaylist(fz_displaylist *list); fz_device *fz_newlistdevice(fz_displaylist *list); void fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix ctm); /* * Function pointers for plotting functions. * They can be replaced by cpu-optimized versions. */ void fz_accelerate(void); void fz_acceleratearch(void); void fz_decodetile(fz_pixmap *pix, float *decode); void fz_unpacktile(fz_pixmap *dst, unsigned char * restrict src, int n, int depth, int stride, int scale); void fz_blendpixmapswithmode(fz_pixmap *dst, fz_pixmap *src, fz_blendmode blendmode); void fz_blendpixmapswithmask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *msk); void fz_blendpixmapswithalpha(fz_pixmap *dst, fz_pixmap *src, float alpha); void fz_blendpixmaps(fz_pixmap *dst, fz_pixmap *src); void fz_blendmasks(unsigned char * restrict dp, unsigned char * restrict sp, int w); void fz_blendwithcolormask(unsigned char * restrict dp, unsigned char * restrict sp, unsigned char * restrict mp, int n, int w); void fz_blendnormal(unsigned char * restrict dp, unsigned char * restrict sp, int n, int w); void fz_blendwithmask(unsigned char * restrict dp, unsigned char * restrict sp, unsigned char * restrict mp, int n, int w); extern void (*fz_path_1o1)(unsigned char*restrict,unsigned char,int,unsigned char*restrict); extern void (*fz_path_w2i1o2)(unsigned char*,unsigned char*restrict,unsigned char,int,unsigned char*restrict); extern void (*fz_path_w4i1o4)(unsigned char*,unsigned char*restrict,unsigned char,int,unsigned char*restrict); extern void (*fz_img_non)(unsigned char*restrict,unsigned char,int,unsigned char*restrict,fz_pixmap*,fz_matrix*); extern void (*fz_img_1o1)(unsigned char*restrict,unsigned char,int,unsigned char*restrict,fz_pixmap*,int u, int v, int fa, int fb); extern void (*fz_img_4o4)(unsigned char*restrict,unsigned char,int,unsigned char*restrict,fz_pixmap*,int u, int v, int fa, int fb); extern void (*fz_img_2o2)(unsigned char*restrict,unsigned char,int,unsigned char*restrict,fz_pixmap*,int u, int v, int fa, int fb); extern void (*fz_img_w2i1o2)(unsigned char*,unsigned char*restrict,unsigned char,int,unsigned char*restrict,fz_pixmap*,int u, int v, int fa, int fb); extern void (*fz_img_w4i1o4)(unsigned char*,unsigned char*restrict,unsigned char,int,unsigned char*restrict,fz_pixmap*,int u, int v, int fa, int fb); extern void (*fz_srown)(unsigned char *restrict, unsigned char *restrict, int w, int denom, int n); extern void (*fz_srow1)(unsigned char *restrict, unsigned char *restrict, int w, int denom); extern void (*fz_srow2)(unsigned char *restrict, unsigned char *restrict, int w, int denom); extern void (*fz_srow4)(unsigned char *restrict, unsigned char *restrict, int w, int denom); extern void (*fz_srow5)(unsigned char *restrict, unsigned char *restrict, int w, int denom); extern void (*fz_scoln)(unsigned char *restrict, unsigned char *restrict, int w, int denom, int n); extern void (*fz_scol1)(unsigned char *restrict, unsigned char *restrict, int w, int denom); extern void (*fz_scol2)(unsigned char *restrict, unsigned char *restrict, int w, int denom); extern void (*fz_scol4)(unsigned char *restrict, unsigned char *restrict, int w, int denom); extern void (*fz_scol5)(unsigned char *restrict, unsigned char *restrict, int w, int denom); #endif