diff options
-rw-r--r-- | fitz/fitz-internal.h | 5 | ||||
-rw-r--r-- | fitz/fitz.h | 2 | ||||
-rw-r--r-- | fitz/stm_buffer.c | 20 | ||||
-rw-r--r-- | pdf/base_object.c | 88 | ||||
-rw-r--r-- | pdf/mupdf-internal.h | 8 | ||||
-rw-r--r-- | pdf/mupdf.h | 2 | ||||
-rw-r--r-- | pdf/pdf_lex.c | 52 | ||||
-rw-r--r-- | pdf/pdf_xobject.c | 115 | ||||
-rw-r--r-- | pdf/pdf_xref.c | 12 |
9 files changed, 303 insertions, 1 deletions
diff --git a/fitz/fitz-internal.h b/fitz/fitz-internal.h index bd19886c..97bbfa5c 100644 --- a/fitz/fitz-internal.h +++ b/fitz/fitz-internal.h @@ -410,6 +410,11 @@ void fz_grow_buffer(fz_context *ctx, fz_buffer *buf); */ void fz_trim_buffer(fz_context *ctx, fz_buffer *buf); +/* + fz_buffer_printf: print formatted to a buffer, growing if necessary +*/ +void fz_buffer_printf(fz_context *ctx, fz_buffer *buffer, char *fmt, ...); + struct fz_stream_s { fz_context *ctx; diff --git a/fitz/fitz.h b/fitz/fitz.h index 04215c71..286aee55 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -377,7 +377,7 @@ void *fz_calloc(fz_context *ctx, unsigned int count, unsigned int size); exception on failure to allocate. */ #define fz_malloc_struct(CTX, STRUCT) \ - Memento_label(fz_calloc(CTX,1,sizeof(STRUCT)), #STRUCT) + ((STRUCT *)Memento_label(fz_calloc(CTX,1,sizeof(STRUCT)), #STRUCT)) /* fz_malloc_array: Allocate a block of (non zeroed) memory (with diff --git a/fitz/stm_buffer.c b/fitz/stm_buffer.c index 4be0165a..9b7a542c 100644 --- a/fitz/stm_buffer.c +++ b/fitz/stm_buffer.c @@ -78,3 +78,23 @@ fz_buffer_storage(fz_context *ctx, fz_buffer *buf, unsigned char **datap) *datap = (buf ? buf->data : NULL); return (buf ? buf->len : 0); } + +void +fz_buffer_printf(fz_context *ctx, fz_buffer *buffer, char *fmt, ...) +{ + int count; + int done = 0; + va_list args; + va_start(args, fmt); + + while(!done) + { + count = vsnprintf(buffer->data + buffer->len, buffer->cap - buffer->len, fmt, args); + done = (count >= 0 && count < buffer->cap - buffer->len); + if (!done) + fz_grow_buffer(ctx, buffer); + } + + buffer->len += count; + va_end(args); +} diff --git a/pdf/base_object.c b/pdf/base_object.c index 97cb97cc..fbc40817 100644 --- a/pdf/base_object.c +++ b/pdf/base_object.c @@ -561,6 +561,94 @@ pdf_array_contains(pdf_obj *arr, pdf_obj *obj) return 0; } +pdf_obj *pdf_new_rect(fz_context *ctx, fz_rect *rect) +{ + pdf_obj *arr = NULL; + pdf_obj *item = NULL; + + fz_try(ctx) + { + arr = pdf_new_array(ctx, 4); + + item = pdf_new_real(ctx, rect->x0); + pdf_array_put(arr, 0, item); + pdf_drop_obj(item); + item = NULL; + + item = pdf_new_real(ctx, rect->y0); + pdf_array_put(arr, 1, item); + pdf_drop_obj(item); + item = NULL; + + item = pdf_new_real(ctx, rect->x1 - rect->x0); + pdf_array_put(arr, 2, item); + pdf_drop_obj(item); + item = NULL; + + item = pdf_new_real(ctx, rect->y1 - rect->y0); + pdf_array_put(arr, 3, item); + pdf_drop_obj(item); + item = NULL; + } + fz_catch(ctx) + { + pdf_drop_obj(item); + pdf_drop_obj(arr); + fz_rethrow(ctx); + } + + return arr; +} + +pdf_obj *pdf_new_matrix(fz_context *ctx, fz_matrix *mtx) +{ + pdf_obj *arr = NULL; + pdf_obj *item = NULL; + + fz_try(ctx) + { + arr = pdf_new_array(ctx, 6); + + item = pdf_new_real(ctx, mtx->a); + pdf_array_put(arr, 0, item); + pdf_drop_obj(item); + item = NULL; + + item = pdf_new_real(ctx, mtx->b); + pdf_array_put(arr, 1, item); + pdf_drop_obj(item); + item = NULL; + + item = pdf_new_real(ctx, mtx->c); + pdf_array_put(arr, 2, item); + pdf_drop_obj(item); + item = NULL; + + item = pdf_new_real(ctx, mtx->d); + pdf_array_put(arr, 3, item); + pdf_drop_obj(item); + item = NULL; + + item = pdf_new_real(ctx, mtx->e); + pdf_array_put(arr, 4, item); + pdf_drop_obj(item); + item = NULL; + + item = pdf_new_real(ctx, mtx->f); + pdf_array_put(arr, 5, item); + pdf_drop_obj(item); + item = NULL; + } + fz_catch(ctx) + { + pdf_drop_obj(item); + pdf_drop_obj(arr); + fz_rethrow(ctx); + } + + return arr; +} + /* dicts may only have names as keys! */ static int keyvalcmp(const void *ap, const void *bp) diff --git a/pdf/mupdf-internal.h b/pdf/mupdf-internal.h index 3e4a4729..a66871dd 100644 --- a/pdf/mupdf-internal.h +++ b/pdf/mupdf-internal.h @@ -134,6 +134,11 @@ pdf_obj *pdf_parse_stm_obj(pdf_document *doc, fz_stream *f, pdf_lexbuf *buf); pdf_obj *pdf_parse_ind_obj(pdf_document *doc, fz_stream *f, pdf_lexbuf *buf, int *num, int *gen, int *stm_ofs); /* + pdf_print_token: print a lexed token to a buffer, growing if necessary +*/ +void pdf_print_token(fz_context *ctx, fz_buffer *buf, int tok, pdf_lexbuf *lex); + +/* * xref and object / stream api */ @@ -203,6 +208,7 @@ void pdf_repair_xref(pdf_document *doc, pdf_lexbuf *buf); void pdf_repair_obj_stms(pdf_document *doc); void pdf_print_xref(pdf_document *); void pdf_resize_xref(pdf_document *doc, int newcap); +pdf_obj *pdf_new_stream_indirection(pdf_document *doc, pdf_obj *obj); /* * Encryption @@ -285,8 +291,10 @@ struct pdf_xobject_s }; pdf_xobject *pdf_load_xobject(pdf_document *doc, pdf_obj *obj); +pdf_obj *pdf_new_xobject(pdf_document *doc, fz_rect *bbox); pdf_xobject *pdf_keep_xobject(fz_context *ctx, pdf_xobject *xobj); void pdf_drop_xobject(fz_context *ctx, pdf_xobject *xobj); +void pdf_xobject_set_contents(fz_context *ctx, pdf_xobject *from, fz_buffer *buffer); /* * CMap diff --git a/pdf/mupdf.h b/pdf/mupdf.h index b88f7423..07bfa12d 100644 --- a/pdf/mupdf.h +++ b/pdf/mupdf.h @@ -23,6 +23,8 @@ pdf_obj *pdf_new_indirect(fz_context *ctx, int num, int gen, void *doc); pdf_obj *pdf_new_array(fz_context *ctx, int initialcap); pdf_obj *pdf_new_dict(fz_context *ctx, int initialcap); +pdf_obj *pdf_new_rect(fz_context *ctx, fz_rect *rect); +pdf_obj *pdf_new_matrix(fz_context *ctx, fz_matrix *mtx); pdf_obj *pdf_copy_array(fz_context *ctx, pdf_obj *array); pdf_obj *pdf_copy_dict(fz_context *ctx, pdf_obj *dict); diff --git a/pdf/pdf_lex.c b/pdf/pdf_lex.c index 6774167a..c6ab6604 100644 --- a/pdf/pdf_lex.c +++ b/pdf/pdf_lex.c @@ -461,3 +461,55 @@ pdf_lex(fz_stream *f, pdf_lexbuf *buf) } } } + +void pdf_print_token(fz_context *ctx, fz_buffer *fzbuf, int tok, pdf_lexbuf *buf) +{ + switch(tok) + { + case PDF_TOK_NAME: + fz_buffer_printf(ctx, fzbuf, "/%s", buf->scratch); + break; + case PDF_TOK_STRING: + { + int i; + fz_buffer_printf(ctx, fzbuf, "<"); + for (i = 0; i < buf->len; i++) + fz_buffer_printf(ctx, fzbuf, "%02X", buf->scratch[i]); + fz_buffer_printf(ctx, fzbuf, ">"); + } + break; + case PDF_TOK_OPEN_DICT: + fz_buffer_printf(ctx, fzbuf, "<<"); + break; + case PDF_TOK_CLOSE_DICT: + fz_buffer_printf(ctx, fzbuf, ">>"); + break; + case PDF_TOK_OPEN_ARRAY: + fz_buffer_printf(ctx, fzbuf, "["); + break; + case PDF_TOK_CLOSE_ARRAY: + fz_buffer_printf(ctx, fzbuf, "]"); + break; + case PDF_TOK_OPEN_BRACE: + fz_buffer_printf(ctx, fzbuf, "{"); + break; + case PDF_TOK_CLOSE_BRACE: + fz_buffer_printf(ctx, fzbuf, "}"); + break; + case PDF_TOK_INT: + fz_buffer_printf(ctx, fzbuf, "%d", buf->i); + break; + case PDF_TOK_REAL: + { + char sbuf[256]; + sprintf(sbuf, "%g", buf->f); + if (strchr(sbuf, 'e')) /* bad news! */ + sprintf(sbuf, fabsf(buf->f) > 1 ? "%1.1f" : "%1.8f", buf->f); + fz_buffer_printf(ctx, fzbuf, "%s", sbuf); + } + break; + default: + fz_buffer_printf(ctx, fzbuf, "%s", buf->scratch); + break; + } +} diff --git a/pdf/pdf_xobject.c b/pdf/pdf_xobject.c index ffa86184..655bc7fa 100644 --- a/pdf/pdf_xobject.c +++ b/pdf/pdf_xobject.c @@ -110,3 +110,118 @@ pdf_load_xobject(pdf_document *xref, pdf_obj *dict) return form; } + +pdf_obj * +pdf_new_xobject(pdf_document *xref, fz_rect *bbox) +{ + pdf_obj *idict = NULL; + pdf_obj *dict = NULL; + pdf_xobject *form = NULL; + pdf_obj *obj = NULL; + pdf_obj *res = NULL; + pdf_obj *procset = NULL; + fz_context *ctx = xref->ctx; + + fz_var(idict); + fz_var(dict); + fz_var(form); + fz_var(obj); + fz_var(res); + fz_var(procset); + fz_try(ctx) + { + dict = pdf_new_dict(ctx, 0); + + obj = pdf_new_rect(ctx, bbox); + pdf_dict_puts(dict, "BBox", obj); + pdf_drop_obj(obj); + obj = NULL; + + obj = pdf_new_int(ctx, 1); + pdf_dict_puts(dict, "FormType", obj); + pdf_drop_obj(obj); + obj = NULL; + + obj = pdf_new_int(ctx, 0); + pdf_dict_puts(dict, "Length", obj); + pdf_drop_obj(obj); + obj = NULL; + + obj = pdf_new_matrix(ctx, &fz_identity); + pdf_dict_puts(dict, "Matrix", obj); + pdf_drop_obj(obj); + obj = NULL; + + res = pdf_new_dict(ctx, 0); + procset = pdf_new_array(ctx, 2); + obj = fz_new_name(ctx, "PDF"); + pdf_array_put(procset, 0, obj); + pdf_drop_obj(obj); + obj = NULL; + obj = fz_new_name(ctx, "Text"); + pdf_array_put(procset, 1, obj); + pdf_drop_obj(obj); + obj = NULL; + pdf_dict_puts(res, "ProcSet", procset); + pdf_drop_obj(procset); + procset = NULL; + pdf_dict_puts(dict, "Resources", res); + + obj = fz_new_name(ctx, "Form"); + pdf_dict_puts(dict, "Subtype", obj); + pdf_drop_obj(obj); + obj = NULL; + + obj = fz_new_name(ctx, "XObject"); + pdf_dict_puts(dict, "Type", obj); + pdf_drop_obj(obj); + obj = NULL; + + form = fz_malloc_struct(ctx, pdf_xobject); + FZ_INIT_STORABLE(form, 1, pdf_free_xobject_imp); + form->resources = NULL; + form->contents = NULL; + form->colorspace = NULL; + form->me = NULL; + + form->bbox = *bbox; + + form->matrix = fz_identity; + + form->isolated = 0; + form->knockout = 0; + form->transparency = 0; + + form->resources = res; + res = NULL; + + idict = pdf_new_stream_indirection(xref, dict); + pdf_drop_obj(dict); + dict = NULL; + + pdf_store_item(ctx, idict, form, pdf_xobject_size(form)); + + form->me = pdf_keep_obj(idict); + + pdf_drop_xobject(ctx, form); + form = NULL; + } + fz_catch(ctx) + { + pdf_drop_obj(procset); + pdf_drop_obj(res); + pdf_drop_obj(obj); + pdf_drop_obj(dict); + pdf_drop_obj(idict); + pdf_drop_xobject(ctx, form); + fz_throw(ctx, "failed to create xobject)"); + } + + return idict; +} + +void pdf_xobject_set_contents(fz_context *ctx, pdf_xobject *form, fz_buffer *buffer) +{ + fz_drop_buffer(ctx, form->contents); + form->contents = fz_keep_buffer(ctx, buffer); +} diff --git a/pdf/pdf_xref.c b/pdf/pdf_xref.c index 89333107..30f4bd69 100644 --- a/pdf/pdf_xref.c +++ b/pdf/pdf_xref.c @@ -1115,6 +1115,18 @@ pdf_update_object(pdf_document *xref, int num, int gen, pdf_obj *newobj) x->ofs = 0; } +pdf_obj * +pdf_new_stream_indirection(pdf_document *xref, pdf_obj *obj) +{ + int num = xref->len; + pdf_resize_xref(xref, xref->len + 1); + pdf_update_object(xref, num, 0, obj); + /* Set stm_ofs, so that obj is treated as a stream */ + xref->table[num].stm_ofs = 1; + + return pdf_new_indirect(xref->ctx, num, 0, xref); +} + /* * Convenience function to open a file then call pdf_open_document_with_stream. */ |