summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2023-04-15 19:42:47 +0100
committerKen Sharp <ken.sharp@artifex.com>2023-04-15 19:42:47 +0100
commite7e782eca2ac08b8b9de13fc68244701d2e42a72 (patch)
treede4e023a78e3d3c7c26e8dc5d7be2f041584905a
parent4d65fcef1b195a3cf1b7a9e315ca3d47e265d712 (diff)
downloadghostpdl-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.c115
-rw-r--r--pdf/pdf_warnings.h1
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