summaryrefslogtreecommitdiff
path: root/pdf
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2023-03-14 09:15:43 +0000
committerKen Sharp <ken.sharp@artifex.com>2023-03-14 09:17:41 +0000
commit4cdbfdfdaa819bea5471bea73b1b71d97cf97087 (patch)
treec73bd8e1f6d96f46645f97cd9cb28244f97aa4e1 /pdf
parente5dc5ea584310e17e6add78bd34624bd7decb1ff (diff)
downloadghostpdl-4cdbfdfdaa819bea5471bea73b1b71d97cf97087.tar.gz
GhostPDF - Fix annotation visibility detection, improve -dPrinted.
Bug #706441 "AcroForm field Btn with no AP not implemented" The title is misleading. The actual problem is that when checking to determine the 'visibility' of an annotation, the NoView bit was being checked with the wrong bit set in the mask. This led to the annotation not being visible and not rendering. From there; the old PDF interpreter used the presence of an OutputFile on the command line to determine whether or not the output should be treated as 'printer' or 'viewer'. The display device doesn't take an OutputFIle so we treat that as a viewer. We weren't taking that action at all internally. So pass OutputFile in from the PostScript world if it is present, and look for it on the command line if we are stand-alone. Start by assuming we are a printer. If we find an OutputFile, and have not encountered a 'Printed' switch, then assume we are a printer. Secondly; deal with the warnings. These are real but are the wrong place for a warning. The problem is that we have an annotation which has an /AP dictionary: << /D <</Off 723 0 R/renew 724 0 R>> /N <</renew 722 0 R>> >> We pick up the Normal (/N) key/value and see that the value is a dictionary. So we consult the annotation for a /AS (appearance state) which in this case is defined as: /AS/Off So we then try to find the /Off state in the sub-dictionary. There isn't one. The specification has nothing to say about what we should do here. I've chosen to replace the appearance with a null object and alter the drawing routine to simply silently ignore this case. Final note; the code is now behaving as it is expected to, but the file in bug #706441 will still be missing a number of buttons when rendered, because these buttons are only drawn when the application is a viewer. In order to have them render Ghostscript must be invoked with : -dPrinted=false
Diffstat (limited to 'pdf')
-rw-r--r--pdf/ghostpdf.c4
-rw-r--r--pdf/pdf_annot.c7
-rw-r--r--pdf/pdftop.c6
3 files changed, 13 insertions, 4 deletions
diff --git a/pdf/ghostpdf.c b/pdf/ghostpdf.c
index 70a061b66..db62784b6 100644
--- a/pdf/ghostpdf.c
+++ b/pdf/ghostpdf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2018-2022 Artifex Software, Inc.
+/* Copyright (C) 2018-2023 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -1821,7 +1821,7 @@ pdf_context *pdfi_create_context(gs_memory_t *mem)
ctx->args.showannots = true;
ctx->args.preserveannots = true;
/* NOTE: For testing certain annotations on cluster, might want to set this to false */
- ctx->args.printed = true; /* TODO: Should be true if OutputFile is set, false otherwise */
+ ctx->args.printed = false; /* True if OutputFile is set, false otherwise see pdftop.c, pdf_impl_set_param() */
/* Initially, prefer the XrefStm in a hybrid file */
ctx->prefer_xrefstm = true;
diff --git a/pdf/pdf_annot.c b/pdf/pdf_annot.c
index 41e37332e..93f5410fc 100644
--- a/pdf/pdf_annot.c
+++ b/pdf/pdf_annot.c
@@ -273,6 +273,8 @@ static int pdfi_annot_draw_AP(pdf_context *ctx, pdf_dict *annot, pdf_obj *NormAP
if (NormAP == NULL)
return 0;
+ if (pdfi_type_of(NormAP) == PDF_NULL)
+ return 0;
if (pdfi_type_of(NormAP) != PDF_STREAM)
return_error(gs_error_typecheck);
@@ -1614,6 +1616,7 @@ static int pdfi_annot_get_NormAP(pdf_context *ctx, pdf_dict *annot, pdf_obj **No
code = pdfi_dict_get_by_key(ctx, (pdf_dict *)baseAP, AS, (pdf_obj **)&AP);
if (code < 0) {
/* Apparently this is not an error, just silently don't have an AP */
+ *NormAP = (pdf_obj *)TOKEN_null;
code = 0;
goto exit;
}
@@ -3944,8 +3947,8 @@ static bool pdfi_annot_visible(pdf_context *ctx, pdf_dict *annot, pdf_name *subt
/* Even if Print flag (bit 3) is off, will print if 3D */
is_visible = ((F & 0x4) != 0) || is_3D;
} else {
- /* Not NoView (bit 7) */
- is_visible = (F & 0x80) == 0;
+ /* Not NoView (bit 6) */
+ is_visible = (F & 0x20) == 0;
}
exit:
diff --git a/pdf/pdftop.c b/pdf/pdftop.c
index 1bef0955f..8670f7970 100644
--- a/pdf/pdftop.c
+++ b/pdf/pdftop.c
@@ -485,6 +485,7 @@ pdf_impl_set_param(pl_interp_implementation_t *impl,
int code;
int len;
bool discard_isname;
+ bool Printed_set = false;
param_init_enumerator(&enumerator);
if ((code = param_get_next_key(plist, &enumerator, &key)) == 0) {
@@ -594,6 +595,7 @@ pdf_impl_set_param(pl_interp_implementation_t *impl,
code = plist_value_get_bool(&pvalue, &ctx->args.printed);
if (code < 0)
return code;
+ Printed_set = true;
}
if (argis(param, "DITHERPPI")) {
code = plist_value_get_bool(&pvalue, &ctx->args.ditherppi);
@@ -719,6 +721,10 @@ pdf_impl_set_param(pl_interp_implementation_t *impl,
if (code < 0)
return code;
}
+ if (argis(param, "OutputFile")) {
+ if (!Printed_set)
+ ctx->args.printed = true;
+ }
}
exit: