From f8751e3c36525a4ce69242c36b89e7d7116ffac2 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Tue, 1 Mar 2016 20:18:48 +0100 Subject: Don't use pdf_page struct when creating pages. --- source/pdf/pdf-appearance.c | 12 ++- source/pdf/pdf-device.c | 86 +++++++------------- source/pdf/pdf-page.c | 186 ++++++++++++++------------------------------ source/tools/mudraw.c | 32 ++++---- source/tools/pdfcreate.c | 8 +- 5 files changed, 118 insertions(+), 206 deletions(-) (limited to 'source') 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; @@ -1037,42 +1037,39 @@ pdf_dev_end_tile(fz_context *ctx, fz_device *dev) pdf_dev_end_text(ctx, pdev); } +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); -- cgit v1.2.3