summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2016-03-01 20:18:48 +0100
committerTor Andersson <tor.andersson@artifex.com>2016-03-01 21:57:41 +0100
commitf8751e3c36525a4ce69242c36b89e7d7116ffac2 (patch)
treed9be3be26e8b3f3f1ff8dbbe6716ea6827e70a2d /source
parentfbf50daa7e81ee111df3091048a9336ac29d371f (diff)
downloadmupdf-f8751e3c36525a4ce69242c36b89e7d7116ffac2.tar.xz
Don't use pdf_page struct when creating pages.
Diffstat (limited to 'source')
-rw-r--r--source/pdf/pdf-appearance.c12
-rw-r--r--source/pdf/pdf-device.c86
-rw-r--r--source/pdf/pdf-page.c186
-rw-r--r--source/tools/mudraw.c32
-rw-r--r--source/tools/pdfcreate.c8
5 files changed, 118 insertions, 206 deletions
diff --git a/source/pdf/pdf-appearance.c b/source/pdf/pdf-appearance.c
index 1ac3a68f..375b3b1d 100644
--- a/source/pdf/pdf-appearance.c
+++ b/source/pdf/pdf-appearance.c
@@ -1582,6 +1582,9 @@ void pdf_set_annot_appearance(fz_context *ctx, pdf_document *doc, pdf_annot *ann
fz_device *dev = NULL;
pdf_xobject *xobj = NULL;
+ pdf_obj *resources;
+ fz_buffer *contents;
+
fz_invert_matrix(&ctm, page_ctm);
fz_var(dev);
@@ -1612,10 +1615,17 @@ void pdf_set_annot_appearance(fz_context *ctx, pdf_document *doc, pdf_annot *ann
pdf_dict_put_drop(ctx, ap_obj, PDF_NAME_Matrix, pdf_new_matrix(ctx, doc, &mat));
}
- dev = pdf_new_pdf_device(ctx, doc, ap_obj, pdf_dict_get(ctx, ap_obj, PDF_NAME_Resources), &mat, NULL);
+ resources = pdf_dict_get(ctx, ap_obj, PDF_NAME_Resources);
+
+ contents = fz_new_buffer(ctx, 0);
+
+ dev = pdf_new_pdf_device(ctx, doc, &trect, contents, resources);
fz_run_display_list(ctx, disp_list, dev, &ctm, &fz_infinite_rect, NULL);
fz_drop_device(ctx, dev);
+ pdf_update_stream(ctx, doc, ap_obj, contents, 0);
+ fz_drop_buffer(ctx, contents);
+
/* Mark the appearance as changed - required for partial update */
xobj = pdf_load_xobject(ctx, doc, ap_obj);
if (xobj)
diff --git a/source/pdf/pdf-device.c b/source/pdf/pdf-device.c
index baed991a..bd11ecc9 100644
--- a/source/pdf/pdf-device.c
+++ b/source/pdf/pdf-device.c
@@ -70,7 +70,7 @@ struct pdf_device_s
fz_device super;
pdf_document *doc;
- pdf_obj *contents;
+ fz_rect *mediabox;
pdf_obj *resources;
fz_buffer *buffer;
@@ -1038,41 +1038,38 @@ pdf_dev_end_tile(fz_context *ctx, fz_device *dev)
}
static void
+pdf_dev_begin_page(fz_context *ctx, fz_device *dev, const fz_rect *mediabox, const fz_matrix *ctm)
+{
+ pdf_device *pdev = (pdf_device*)dev;
+ gstate *gs = CURRENT_GSTATE(pdev);
+ pdev->mediabox->x0 = 0;
+ pdev->mediabox->y0 = 0;
+ pdev->mediabox->x1 = mediabox->x1 - mediabox->x0;
+ pdev->mediabox->y1 = mediabox->y1 - mediabox->y0;
+ fz_buffer_printf(ctx, gs->buf, "1 0 0 -1 %f %f cm\n", 0 - mediabox->x0, mediabox->y1);
+}
+
+static void
+pdf_dev_end_page(fz_context *ctx, fz_device *dev)
+{
+}
+
+static void
pdf_dev_drop_imp(fz_context *ctx, fz_device *dev)
{
pdf_device *pdev = (pdf_device*)dev;
- pdf_document *doc = pdev->doc;
int i;
pdf_dev_end_text(ctx, pdev);
for (i = pdev->num_gstates-1; i >= 0; i--)
- {
fz_drop_stroke_state(ctx, pdev->gstates[i].stroke_state);
- }
for (i = pdev->num_cid_fonts-1; i >= 0; i--)
- {
fz_drop_font(ctx, pdev->cid_fonts[i]);
- }
for (i = pdev->num_groups - 1; i >= 0; i--)
- {
pdf_drop_obj(ctx, pdev->groups[i].ref);
- }
-
- if (pdev->contents)
- {
- pdf_update_stream(ctx, doc, pdev->contents, pdev->gstates[0].buf, 0);
- pdf_drop_obj(ctx, pdev->contents);
- }
-
- if (pdev->buffer != pdev->gstates[0].buf)
- {
- fz_drop_buffer(ctx, pdev->gstates[0].buf);
- }
-
- pdf_drop_obj(ctx, pdev->resources);
fz_free(ctx, pdev->cid_fonts);
fz_free(ctx, pdev->image_indices);
@@ -1081,12 +1078,15 @@ pdf_dev_drop_imp(fz_context *ctx, fz_device *dev)
fz_free(ctx, pdev->gstates);
}
-fz_device *pdf_new_pdf_device(fz_context *ctx, pdf_document *doc, pdf_obj *contents, pdf_obj *resources, const fz_matrix *ctm, fz_buffer *buf)
+fz_device *pdf_new_pdf_device(fz_context *ctx, pdf_document *doc, fz_rect *mediabox, fz_buffer *buf, pdf_obj *resources)
{
pdf_device *dev = fz_new_device(ctx, sizeof *dev);
dev->super.drop_imp = pdf_dev_drop_imp;
+ dev->super.begin_page = pdf_dev_begin_page;
+ dev->super.end_page = pdf_dev_end_page;
+
dev->super.fill_path = pdf_dev_fill_path;
dev->super.stroke_path = pdf_dev_stroke_path;
dev->super.clip_path = pdf_dev_clip_path;
@@ -1119,11 +1119,11 @@ fz_device *pdf_new_pdf_device(fz_context *ctx, pdf_document *doc, pdf_obj *conte
if (!buf)
buf = fz_new_buffer(ctx, 256);
dev->doc = doc;
- dev->contents = pdf_keep_obj(ctx, contents);
+ dev->mediabox = mediabox;
dev->resources = pdf_keep_obj(ctx, resources);
dev->gstates = fz_malloc_struct(ctx, gstate);
dev->gstates[0].buf = buf;
- dev->gstates[0].ctm = *ctm;
+ dev->gstates[0].ctm = fz_identity; // XXX
dev->gstates[0].colorspace[0] = fz_device_gray(ctx);
dev->gstates[0].colorspace[1] = fz_device_gray(ctx);
dev->gstates[0].color[0][0] = 1;
@@ -1146,38 +1146,10 @@ fz_device *pdf_new_pdf_device(fz_context *ctx, pdf_document *doc, pdf_obj *conte
return (fz_device*)dev;
}
-fz_device *pdf_page_write(fz_context *ctx, pdf_document *doc, pdf_page *page)
+fz_device *pdf_page_write(fz_context *ctx, pdf_document *doc,
+ fz_rect *pmediabox, fz_buffer **pcontents, pdf_obj **presources)
{
- pdf_obj *resources = pdf_dict_get(ctx, page->me, PDF_NAME_Resources);
- fz_matrix ctm;
- pdf_obj *obj;
-
- fz_pre_translate(fz_scale(&ctm, 1, -1), 0, page->mediabox.y0-page->mediabox.y1);
-
- if (resources == NULL)
- {
- resources = pdf_new_dict(ctx, doc, 0);
- pdf_dict_put_drop(ctx, page->me, PDF_NAME_Resources, resources);
- }
-
- /* We always make a new object for page->contents here, in case
- * the existing one is an array, or is shared. */
- obj = pdf_new_dict(ctx, doc, 0);
- fz_try(ctx)
- {
- pdf_obj *new_contents = pdf_add_object(ctx, doc, obj);
- pdf_dict_put(ctx, page->me, PDF_NAME_Contents, new_contents);
- pdf_drop_obj(ctx, page->contents);
- page->contents = new_contents;
- }
- fz_always(ctx)
- {
- pdf_drop_obj(ctx, obj);
- }
- fz_catch(ctx)
- {
- fz_rethrow(ctx);
- }
-
- return pdf_new_pdf_device(ctx, doc, page->contents, resources, &ctm, NULL);
+ *presources = pdf_new_dict(ctx, doc, 0);
+ *pcontents = fz_new_buffer(ctx, 0);
+ return pdf_new_pdf_device(ctx, doc, pmediabox, *pcontents, *presources);
}
diff --git a/source/pdf/pdf-page.c b/source/pdf/pdf-page.c
index 7242b16a..a74c388a 100644
--- a/source/pdf/pdf-page.c
+++ b/source/pdf/pdf-page.c
@@ -621,153 +621,85 @@ pdf_delete_page(fz_context *ctx, pdf_document *doc, int at)
}
void
-pdf_insert_page(fz_context *ctx, pdf_document *doc, pdf_page *page, int at)
+pdf_delete_page_range(fz_context *ctx, pdf_document *doc, int start, int end)
{
- int count = pdf_count_pages(ctx, doc);
- pdf_obj *parent, *kids;
- pdf_obj *page_ref;
- int i;
-
- page_ref = pdf_add_object(ctx, doc, page->me);
+ while (start < end)
+ pdf_delete_page(ctx, doc, start++);
+}
+pdf_obj *
+pdf_add_page(fz_context *ctx, pdf_document *doc, const fz_rect *mediabox, int rotate, fz_buffer *contents, pdf_obj *resources)
+{
+ pdf_obj *page_obj = pdf_new_dict(ctx, doc, 5);
fz_try(ctx)
{
- if (count == 0)
- {
- pdf_obj *root = pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root);
- parent = pdf_dict_get(ctx, root, PDF_NAME_Pages);
- if (!parent)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find page tree");
-
- kids = pdf_dict_get(ctx, parent, PDF_NAME_Kids);
- if (!kids)
- fz_throw(ctx, FZ_ERROR_GENERIC, "malformed page tree");
-
- pdf_array_insert(ctx, kids, page_ref, 0);
- }
- else if (at >= count)
- {
- if (at == INT_MAX)
- at = count;
-
- if (at > count)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot insert page beyond end of page tree");
+ pdf_dict_put_drop(ctx, page_obj, PDF_NAME_Type, PDF_NAME_Page);
+ pdf_dict_put_drop(ctx, page_obj, PDF_NAME_MediaBox, pdf_new_rect(ctx, doc, mediabox));
+ pdf_dict_put_drop(ctx, page_obj, PDF_NAME_Rotate, pdf_new_int(ctx, doc, rotate));
+ pdf_dict_put_drop(ctx, page_obj, PDF_NAME_Contents, pdf_add_stream(ctx, doc, contents));
- /* append after last page */
- pdf_lookup_page_loc(ctx, doc, count - 1, &parent, &i);
- kids = pdf_dict_get(ctx, parent, PDF_NAME_Kids);
- pdf_array_insert(ctx, kids, page_ref, i + 1);
- }
+ if (pdf_is_indirect(ctx, resources))
+ pdf_dict_put(ctx, page_obj, PDF_NAME_Resources, resources);
else
- {
- /* insert before found page */
- pdf_lookup_page_loc(ctx, doc, at, &parent, &i);
- kids = pdf_dict_get(ctx, parent, PDF_NAME_Kids);
- pdf_array_insert(ctx, kids, page_ref, i);
- }
-
- pdf_dict_put(ctx, page->me, PDF_NAME_Parent, parent);
-
- /* Adjust page counts */
- while (parent)
- {
- int count = pdf_to_int(ctx, pdf_dict_get(ctx, parent, PDF_NAME_Count));
- pdf_dict_put_drop(ctx, parent, PDF_NAME_Count, pdf_new_int(ctx, doc, count + 1));
- parent = pdf_dict_get(ctx, parent, PDF_NAME_Parent);
- }
-
- }
- fz_always(ctx)
- {
- pdf_drop_obj(ctx, page_ref);
+ pdf_dict_put_drop(ctx, page_obj, PDF_NAME_Resources, pdf_add_object(ctx, doc, resources));
}
fz_catch(ctx)
{
+ pdf_drop_obj(ctx, page_obj);
fz_rethrow(ctx);
}
-
- doc->page_count = 0; /* invalidate cached value */
+ return pdf_add_object_drop(ctx, doc, page_obj);
}
void
-pdf_delete_page_range(fz_context *ctx, pdf_document *doc, int start, int end)
+pdf_insert_page(fz_context *ctx, pdf_document *doc, int at, pdf_obj *page_ref)
{
- while (start < end)
- pdf_delete_page(ctx, doc, start++);
-}
-
-pdf_page *
-pdf_create_page(fz_context *ctx, pdf_document *doc, const fz_rect *mediabox, int rotate,
- fz_buffer *contents, pdf_obj *resources)
-{
- pdf_page *page = NULL;
- pdf_obj *pageobj, *obj;
- float userunit = 1;
- fz_matrix ctm, tmp;
- fz_rect realbox;
+ int count = pdf_count_pages(ctx, doc);
+ pdf_obj *parent, *kids;
+ int i;
- page = pdf_new_page(ctx, doc);
- obj = NULL;
- fz_var(obj);
+ if (at < 0)
+ at = count;
+ if (at == INT_MAX)
+ at = count;
+ if (at > count)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot insert page beyond end of page tree");
- fz_try(ctx)
+ if (count == 0)
{
- page->me = pageobj = pdf_new_dict(ctx, doc, 4);
-
- pdf_dict_put_drop(ctx, pageobj, PDF_NAME_Type, PDF_NAME_Page);
-
- page->mediabox.x0 = fz_min(mediabox->x0, mediabox->x1) * userunit;
- page->mediabox.y0 = fz_min(mediabox->y0, mediabox->y1) * userunit;
- page->mediabox.x1 = fz_max(mediabox->x0, mediabox->x1) * userunit;
- page->mediabox.y1 = fz_max(mediabox->y0, mediabox->y1) * userunit;
- pdf_dict_put_drop(ctx, pageobj, PDF_NAME_MediaBox, pdf_new_rect(ctx, doc, &page->mediabox));
-
- /* Snap page->rotate to 0, 90, 180 or 270 */
- if (page->rotate < 0)
- page->rotate = 360 - ((-page->rotate) % 360);
- if (page->rotate >= 360)
- page->rotate = page->rotate % 360;
- page->rotate = 90 * ((page->rotate + 45) / 90);
- if (page->rotate > 360)
- page->rotate = 0;
- pdf_dict_put_drop(ctx, pageobj, PDF_NAME_Rotate, pdf_new_int(ctx, doc, page->rotate));
-
- fz_pre_rotate(fz_scale(&ctm, 1, -1), -page->rotate);
- realbox = page->mediabox;
- fz_transform_rect(&realbox, &ctm);
- fz_pre_scale(fz_translate(&tmp, -realbox.x0, -realbox.y0), userunit, userunit);
- fz_concat(&ctm, &ctm, &tmp);
- page->ctm = ctm;
-
- if (contents != NULL)
- {
- obj = pdf_new_dict(ctx, doc, 4);
- page->contents = pdf_add_object(ctx, doc, obj);
- pdf_update_stream(ctx, doc, page->contents, contents, 0);
- pdf_drop_obj(ctx, obj);
- obj = NULL;
- pdf_dict_put(ctx, pageobj, PDF_NAME_Contents, page->contents);
- }
-
- if (resources != NULL)
- {
- if (pdf_is_indirect(ctx, resources))
- pdf_dict_put(ctx, pageobj, PDF_NAME_Resources, resources);
- else
- {
- pdf_obj *ref = pdf_add_object(ctx, doc, resources);
- pdf_dict_put(ctx, pageobj, PDF_NAME_Resources, ref);
- pdf_drop_obj(ctx, ref);
- }
- }
+ pdf_obj *root = pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root);
+ parent = pdf_dict_get(ctx, root, PDF_NAME_Pages);
+ if (!parent)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find page tree");
+ kids = pdf_dict_get(ctx, parent, PDF_NAME_Kids);
+ if (!kids)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "malformed page tree");
+ pdf_array_insert(ctx, kids, page_ref, 0);
}
- fz_catch(ctx)
+ else if (at == count)
+ {
+ /* append after last page */
+ pdf_lookup_page_loc(ctx, doc, count - 1, &parent, &i);
+ kids = pdf_dict_get(ctx, parent, PDF_NAME_Kids);
+ pdf_array_insert(ctx, kids, page_ref, i + 1);
+ }
+ else
{
- pdf_drop_obj(ctx, page->me);
- pdf_drop_obj(ctx, obj);
- fz_free(ctx, page);
- fz_rethrow_message(ctx, "Failed to create page");
+ /* insert before found page */
+ pdf_lookup_page_loc(ctx, doc, at, &parent, &i);
+ kids = pdf_dict_get(ctx, parent, PDF_NAME_Kids);
+ pdf_array_insert(ctx, kids, page_ref, i);
}
- return page;
+ pdf_dict_put(ctx, page_ref, PDF_NAME_Parent, parent);
+
+ /* Adjust page counts */
+ while (parent)
+ {
+ int count = pdf_to_int(ctx, pdf_dict_get(ctx, parent, PDF_NAME_Count));
+ pdf_dict_put_drop(ctx, parent, PDF_NAME_Count, pdf_new_int(ctx, doc, count + 1));
+ parent = pdf_dict_get(ctx, parent, PDF_NAME_Parent);
+ }
+
+ doc->page_count = 0; /* invalidate cached value */
}
diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c
index 56bf0f8d..bc8ca1fb 100644
--- a/source/tools/mudraw.c
+++ b/source/tools/mudraw.c
@@ -378,29 +378,29 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
else if (output_format == OUT_PDF)
{
- fz_matrix ctm;
- fz_rect bounds, tbounds;
- pdf_page *newpage;
-
- fz_bound_page(ctx, page, &bounds);
- fz_rotate(&ctm, rotation);
- tbounds = bounds;
- fz_transform_rect(&tbounds, &ctm);
-
- newpage = pdf_create_page(ctx, pdfout, &bounds, 0, NULL, NULL);
+ fz_buffer *contents;
+ pdf_obj *resources;
+ fz_rect mediabox;
+ dev = pdf_page_write(ctx, pdfout, &mediabox, &contents, &resources);
fz_try(ctx)
{
- dev = pdf_page_write(ctx, pdfout, newpage);
+ pdf_obj *page_obj;
+
if (list)
- fz_run_display_list(ctx, list, dev, &ctm, &tbounds, &cookie);
+ fz_run_display_list(ctx, list, dev, &fz_identity, NULL, &cookie);
else
- fz_run_page(ctx, page, dev, &ctm, &cookie);
- fz_drop_device(ctx, dev);
- dev = NULL;
+ fz_run_page(ctx, page, dev, &fz_identity, &cookie);
+
+ fz_bound_page(ctx, page, &mediabox);
+ page_obj = pdf_add_page(ctx, pdfout, &mediabox, rotation, contents, resources);
+ pdf_insert_page(ctx, pdfout, -1, page_obj);
+ pdf_drop_obj(ctx, page_obj);
}
fz_always(ctx)
{
+ pdf_drop_obj(ctx, resources);
+ fz_drop_buffer(ctx, contents);
fz_drop_device(ctx, dev);
dev = NULL;
}
@@ -410,8 +410,6 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
fz_drop_page(ctx, page);
fz_rethrow(ctx);
}
- pdf_insert_page(ctx, pdfout, newpage, INT_MAX);
- fz_drop_page(ctx, &newpage->super);
}
else if (output_format == OUT_SVG)
diff --git a/source/tools/pdfcreate.c b/source/tools/pdfcreate.c
index 47572d7d..4ebc87fe 100644
--- a/source/tools/pdfcreate.c
+++ b/source/tools/pdfcreate.c
@@ -91,7 +91,7 @@ static void create_page(char *input)
fz_buffer *contents;
pdf_obj *resources;
- pdf_page *page;
+ pdf_obj *page;
resources = pdf_new_dict(ctx, doc, 2);
contents = fz_new_buffer(ctx, 1024);
@@ -133,9 +133,9 @@ static void create_page(char *input)
}
fz_drop_stream(ctx, stm);
- page = pdf_create_page(ctx, doc, &mediabox, rotate, contents, resources);
- pdf_insert_page(ctx, doc, page, INT_MAX);
- pdf_drop_page(ctx, page);
+ page = pdf_add_page(ctx, doc, &mediabox, rotate, contents, resources);
+ pdf_insert_page(ctx, doc, -1, page);
+ pdf_drop_obj(ctx, page);
fz_drop_buffer(ctx, contents);
pdf_drop_obj(ctx, resources);