summaryrefslogtreecommitdiff
path: root/pdf
diff options
context:
space:
mode:
authorPaul Gardiner <paul@glidos.net>2012-05-07 14:35:01 +0100
committerPaul Gardiner <paul@glidos.net>2012-05-07 14:35:01 +0100
commit994bd7d7a1cf652cffa313c10466abe0165448b3 (patch)
tree870b0c23766256e53c45603ef9f2b9d280f29470 /pdf
parent63fc310d23f3fd3b54739a44208f3317add18caf (diff)
downloadmupdf-994bd7d7a1cf652cffa313c10466abe0165448b3.tar.xz
A few general utility functions added for the sake of the forms work
Diffstat (limited to 'pdf')
-rw-r--r--pdf/base_object.c88
-rw-r--r--pdf/mupdf-internal.h8
-rw-r--r--pdf/mupdf.h2
-rw-r--r--pdf/pdf_lex.c52
-rw-r--r--pdf/pdf_xobject.c115
-rw-r--r--pdf/pdf_xref.c12
6 files changed, 277 insertions, 0 deletions
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.
*/