diff options
author | Ken Sharp <ken.sharp@artifex.com> | 2023-04-15 19:42:47 +0100 |
---|---|---|
committer | Ken Sharp <ken.sharp@artifex.com> | 2023-04-15 19:42:47 +0100 |
commit | e7e782eca2ac08b8b9de13fc68244701d2e42a72 (patch) | |
tree | de4e023a78e3d3c7c26e8dc5d7be2f041584905a | |
parent | 4d65fcef1b195a3cf1b7a9e315ca3d47e265d712 (diff) | |
download | ghostpdl-e7e782eca2ac08b8b9de13fc68244701d2e42a72.tar.gz |
GhostPDF - preserve initial document view from PDF Catalog
No bug report for this, but it's been annoying me for ages and so I'm
adding it as an enhancement and for some practice with pdfmark
generation.
Read the PageLayout, PageMode and OpenAction from the Root (Catalog)
dictionary and send them to pdfwrite.
-rw-r--r-- | pdf/pdf_doc.c | 115 | ||||
-rw-r--r-- | pdf/pdf_warnings.h | 1 |
2 files changed, 116 insertions, 0 deletions
diff --git a/pdf/pdf_doc.c b/pdf/pdf_doc.c index 02533d4c0..ca32e55aa 100644 --- a/pdf/pdf_doc.c +++ b/pdf/pdf_doc.c @@ -1676,6 +1676,111 @@ static int pdfi_doc_AcroForm(pdf_context *ctx) } +static int pdfi_doc_view(pdf_context *ctx) +{ + int code = 0; + pdf_dict *tempdict = NULL; + pdf_name *Mode = NULL; + pdf_obj *ActionDest = NULL; + + code = pdfi_dict_knownget_type(ctx, ctx->Root, "PageMode", PDF_NAME, (pdf_obj **)&Mode); + if (code < 0) + return code; + + if (code != 0) { + code = pdfi_dict_alloc(ctx, 1, &tempdict); + if (code < 0) + return code; + + pdfi_countup(tempdict); + + code = pdfi_dict_put(ctx, tempdict, "PageMode", (pdf_obj *)Mode); + if (code < 0) + goto exit; + + code = pdfi_pdfmark_from_dict(ctx, tempdict, NULL, "DOCVIEW"); + if (code < 0) + goto exit; + pdfi_countdown(tempdict); + tempdict = NULL; + } + + code = pdfi_dict_knownget_type(ctx, ctx->Root, "PageLayout", PDF_NAME, (pdf_obj **)&Mode); + if (code < 0) + return code; + + if (code != 0) { + code = pdfi_dict_alloc(ctx, 1, &tempdict); + if (code < 0) + return code; + + pdfi_countup(tempdict); + + code = pdfi_dict_put(ctx, tempdict, "PageLayout", (pdf_obj *)Mode); + if (code < 0) + goto exit; + + code = pdfi_pdfmark_from_dict(ctx, tempdict, NULL, "DOCVIEW"); + if (code < 0) + goto exit; + pdfi_countdown(tempdict); + tempdict = NULL; + } + + code = pdfi_dict_knownget(ctx, ctx->Root, "OpenAction", &ActionDest); + if (code < 0) + return code; + + if (code != 0) { + if (pdfi_type_of(ActionDest) == PDF_DICT) { + /* Dictionary means this is an action */ + code = pdfi_dict_alloc(ctx, 1, &tempdict); + if (code < 0) + return code; + + pdfi_countup(tempdict); + + code = pdfi_dict_put(ctx, tempdict, "A", (pdf_obj *)ActionDest); + if (code < 0) + goto exit; + + code = pdfi_pdfmark_modA(ctx, tempdict); + if (code < 0) goto exit; + + code = pdfi_pdfmark_from_dict(ctx, tempdict, NULL, "DOCVIEW"); + } else { + if (pdfi_type_of(ActionDest) == PDF_ARRAY) { + /* Array means this is a destination */ + code = pdfi_dict_alloc(ctx, 1, &tempdict); + if (code < 0) + return code; + + pdfi_countup(tempdict); + + code = pdfi_dict_put(ctx, tempdict, "Dest", (pdf_obj *)ActionDest); + if (code < 0) + goto exit; + code = pdfi_pdfmark_modDest(ctx, tempdict); + if (code < 0) + goto exit; + code = pdfi_pdfmark_from_dict(ctx, tempdict, NULL, "DOCVIEW"); + if (code < 0) + goto exit; + } else { + code = gs_note_error(gs_error_typecheck); + goto exit; + } + } + } + +exit: + pdfi_countdown(ActionDest); + pdfi_countdown(Mode); + pdfi_countdown(tempdict); + return code; +} + + /* See pdf_main.ps/process_trailer_attrs() * Some of this stuff is about pdfmarks, and some of it is just handling * random things in the trailer. @@ -1691,6 +1796,8 @@ int pdfi_doc_trailer(pdf_context *ctx) } if (ctx->device_state.writepdfmarks) { + code = pdfi_doc_view(ctx); + /* Handle Outlines */ code = pdfi_doc_Outlines(ctx); if (code < 0) { @@ -1699,6 +1806,14 @@ int pdfi_doc_trailer(pdf_context *ctx) goto exit; } + /* Handle Docview pdfmark stuff */ + code = pdfi_doc_view(ctx); + if (code < 0) { + pdfi_set_warning(ctx, code, NULL, W_PDF_BAD_VIEW, "pdfi_doc_view", NULL); + if (ctx->args.pdfstoponerror) + goto exit; + } + /* Handle Info */ code = pdfi_doc_Info(ctx); if (code < 0) { diff --git a/pdf/pdf_warnings.h b/pdf/pdf_warnings.h index da220dfae..0d3fca4f0 100644 --- a/pdf/pdf_warnings.h +++ b/pdf/pdf_warnings.h @@ -95,4 +95,5 @@ PARAM(W_PDF_FONTRESOURCE_TYPE, "A Font key in a Resources dictionary has a PARAM(W_PDF_UNBLANACED_BT, "A page ended after a BT had been executed and without a mtching ET"), PARAM(W_PDF_MISMATCH_GENERATION, "The generation number of an indirectly referenced object did not match the xref"), PARAM(W_PDF_BAD_RENDERINGINTENT, "A ri or /RI used an unknown named rendering intent"), +PARAM(W_PDF_BAD_VIEW, "Couldn't read the initial document view"), #undef PARAM |