diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2016-03-01 20:18:48 +0100 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2016-03-01 21:57:41 +0100 |
commit | f8751e3c36525a4ce69242c36b89e7d7116ffac2 (patch) | |
tree | d9be3be26e8b3f3f1ff8dbbe6716ea6827e70a2d /source/pdf | |
parent | fbf50daa7e81ee111df3091048a9336ac29d371f (diff) | |
download | mupdf-f8751e3c36525a4ce69242c36b89e7d7116ffac2.tar.xz |
Don't use pdf_page struct when creating pages.
Diffstat (limited to 'source/pdf')
-rw-r--r-- | source/pdf/pdf-appearance.c | 12 | ||||
-rw-r--r-- | source/pdf/pdf-device.c | 86 | ||||
-rw-r--r-- | source/pdf/pdf-page.c | 186 |
3 files changed, 99 insertions, 185 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 */ } |