[gs-commits] ghostpdl branch, pdfi, updated. jbig2dec-0.14-2622-g6a2c040
[email protected] (Nancy Durgin) Wed, 27 Nov 2019 20:51:20 +0000 (UTC)
| Newsgroups | gmane.comp.printing.ghostscript.cvs |
|---|---|
| Message-ID | <[email protected]> |
The ghostpdl branch, pdfi has been updated
via 6a2c04019be27f199ba107fba125bf04bf8dd1c6 (commit)
via ffe4e1104dcf1579779364ae71bd2cd8a137f3d9 (commit)
from 20de60fb65962ca37cb8d9e9fe45b80a18f8405f (commit)
----------------------------------------------------------------------
commit 6a2c04019be27f199ba107fba125bf04bf8dd1c6
Author: Nancy Durgin <[email protected]>
Date: Thu Nov 21 15:02:43 2019 -0800
Code to support Annotations
Some refactoring and added some variables to context.
Working on "/Link".
A bunch of stuff implemented. Renders simple border, but many things
not implemented yet.
Fixes fts_02_0203.pdf
diff --git a/pdf/ghostpdf.h b/pdf/ghostpdf.h
index 65d99fc..863955b 100644
--- a/pdf/ghostpdf.h
+++ b/pdf/ghostpdf.h
@@ -200,6 +200,8 @@ typedef struct pdf_context_s
bool printed;
bool showacroform;
bool showannots;
+ bool dopdfmarks;
+ bool preserveannots;
bool nouserunit;
bool renderttnotdef;
bool pdfinfo;
@@ -293,6 +295,12 @@ typedef struct pdf_context_s
/* Does this page need overprint support? */
bool page_needs_OP;
+ /* Does current output device handle pdfmark */
+ bool writepdfmarks;
+
+ /* Should annotations be preserved or marked for current output device? */
+ bool annotations_preserved;
+
double PageSize[4];
double UserUnit;
diff --git a/pdf/pdf_annot.c b/pdf/pdf_annot.c
index 42698c0..3438140 100644
--- a/pdf/pdf_annot.c
+++ b/pdf/pdf_annot.c
@@ -29,19 +29,450 @@
#include "pdf_misc.h"
#include "pdf_optcontent.h"
#include "pdf_annot.h"
+#include "pdf_colour.h"
+#include "gspath2.h"
+
+typedef bool (*annot_func)(pdf_context *ctx, pdf_dict *annot, bool *render_done);
+
+typedef struct {
+ const char *subtype;
+ annot_func func;
+} annot_dispatch_t;
+
+
+static int pdfi_annot_start_transparency(pdf_context *ctx, pdf_dict *annot)
+{
+ int code;
+
+ if (!ctx->page_has_transparency)
+ return 0;
+
+ /* TODO: ps code does something with /BM which is apparently the Blend Mode,
+ * but I am not sure that the value is actually used properly. Look into it.
+ * (see pdf_draw.ps/startannottransparency)
+ */
+ code = gs_clippath(ctx->pgs);
+ if (code < 0)
+ return code;
+ code = pdfi_trans_begin_simple_group(ctx, false, false, false);
+ (void)gs_newpath(ctx->pgs);
+ return code;
+}
+
+static int pdfi_annot_end_transparency(pdf_context *ctx, pdf_dict *annot)
+{
+ if (!ctx->page_has_transparency)
+ return 0;
+
+ return pdfi_trans_end_simple_group(ctx);
+}
+
+/* See pdf_draw.ps/calc_annot_scale */
+static int pdfi_annot_calcscale(pdf_context *ctx, pdf_dict *annot, double *xscale, double *yscale)
+{
+ /* TODO: Implement this */
+
+ *xscale = 1.0;
+ *yscale = 1.0;
+ return 0;
+}
+
+/* See pdf_draw.ps/drawwidget */
+static int pdfi_annot_draw_widget(pdf_context *ctx, pdf_dict *annot, double xscale, double yscale)
+{
+ /* TODO: Implement this */
+
+ return 0;
+}
+
+static int pdfi_annot_setcolor(pdf_context *ctx, pdf_dict *annot, bool *drawit)
+{
+ int code = 0;
+ pdf_array *C = NULL;
+
+ *drawit = true;
+
+ code = pdfi_dict_knownget_type(ctx, annot, "C", PDF_ARRAY, (pdf_obj **)&C);
+ if (code < 0) goto exit;
+
+ if (code == 0) {
+ code = pdfi_gs_setgray(ctx, 0);
+ } else {
+ if (pdfi_array_size(C) == 0) {
+ code = 0;
+ *drawit = false;
+ } else {
+ code = pdfi_setcolor_from_array(ctx, C);
+ }
+ }
+
+ exit:
+ if (code < 0)
+ *drawit = false;
+ pdfi_countdown(C);
+ return code;
+}
+
+static int pdfi_annot_strokeborder(pdf_context *ctx, pdf_dict *annot, double width, pdf_array *dash)
+{
+ int code = 0;
+ bool drawit;
+ gs_rect rect;
+ pdf_array *Rect = NULL;
+
+ if (width <= 0)
+ return 0;
+
+ code = pdfi_gsave(ctx);
+
+ code = pdfi_annot_setcolor(ctx, annot, &drawit);
+ if (code < 0) goto exit;
+ if (!drawit) goto exit;
+
+ code = pdfi_setdash_impl(ctx, dash, 0);
+ if (code < 0) goto exit;
+ code = gs_setlinewidth(ctx->pgs, width);
+ if (code < 0) goto exit;
+
+ code = pdfi_dict_knownget_type(ctx, annot, "Rect", PDF_ARRAY, (pdf_obj **)&Rect);
+ if (code < 0) goto exit;
+
+ code = pdfi_array_to_gs_rect(ctx, Rect, &rect);
+ if (code < 0) goto exit;
+
+ pdfi_normalize_rect(ctx, &rect);
+
+ /* Stroke the rectangle */
+ /* Adjust rectangle by the width */
+ rect.p.x += width/2;
+ rect.p.y += width/2;
+ rect.q.x -= width/2;
+ rect.q.y -= width/2;
+ code = gs_rectstroke(ctx->pgs, &rect, 1, NULL);
+
+ exit:
+ (void)pdfi_grestore(ctx);
+ pdfi_countdown(Rect);
+ return code;
+}
+
+/* Draw border from a Border array
+ * Note: Border can be null
+ */
+static int pdfi_annot_draw_Border(pdf_context *ctx, pdf_dict *annot, pdf_array *Border)
+{
+ pdf_array *dash = NULL;
+ int code = 0;
+ uint64_t size = 0;
+ double width = 0;
+
+ if (Border)
+ size = pdfi_array_size(Border);
+ if (Border && size < 3) {
+ /* TODO: set warning flag */
+ dbgmprintf(ctx->memory, "WARNING: Annotation Border array invalid\n");
+ goto exit;
+ }
+ if (!Border) {
+ code = pdfi_array_alloc(ctx, 0, &dash);
+ if (code < 0) goto exit;
+ width = 1;
+ } else {
+ if (size > 3) {
+ code = pdfi_array_get_type(ctx, Border, 3, PDF_ARRAY, (pdf_obj **)&dash);
+ if (code < 0) {
+ /* TODO: set warning flag */
+ dbgmprintf(ctx->memory, "WARNING: Annotation Border Dash array invalid\n");
+ code = pdfi_array_alloc(ctx, 0, &dash);
+ if (code < 0) goto exit;
+ }
+ } else {
+ code = pdfi_array_alloc(ctx, 0, &dash);
+ if (code < 0) goto exit;
+ }
+ code = pdfi_array_get_number(ctx, Border, 2, &width);
+ if (code < 0) goto exit;
+ }
+
+ /* At this point we have a dash array (which could be length 0) and a width */
+ code = pdfi_annot_strokeborder(ctx, annot, width, dash);
+
+ exit:
+ pdfi_countdown(dash);
+ return code;
+}
+
+/* Draw border from a BS dict */
+static int pdfi_annot_draw_BS(pdf_context *ctx, pdf_dict *annot, pdf_dict *BS)
+{
+ double W;
+ int code = 0;
+ pdf_name *S = NULL;
+ pdf_array *dash = NULL;
+
+ /* Get the width */
+ code = pdfi_dict_knownget_number(ctx, BS, "W", &W);
+ if (code < 0) goto exit;
+ if (code == 0)
+ W = 1; /* Default */
+
+ /* TODO: Some junk about scaling to UserUnit */
+ /* ... */
+
+ /* Lookup border style */
+ code = pdfi_dict_knownget_type(ctx, BS, "S", PDF_NAME, (pdf_obj **)&S);
+ if (code < 0) goto exit;
+
+ if (code > 0 && pdfi_name_is(S, "D")) {
+ /* Handle Dash array */
+ code = pdfi_dict_knownget_type(ctx, BS, "D", PDF_ARRAY, (pdf_obj **)&dash);
+ if (code < 0) goto exit;
+
+ /* If there is no Dash array, then create one containing a 3 (the default) */
+ if (code == 0) {
+ code = pdfi_array_alloc(ctx, 1, &dash);
+ if (code < 0) goto exit;
+
+ code = pdfi_array_put_int(ctx, dash, 0, 3);
+ if (code < 0) goto exit;
+ }
+ } else {
+ /* Empty array */
+ code = pdfi_array_alloc(ctx, 0, &dash);
+ if (code < 0) goto exit;
+ }
+
+ /* At this point we have a dash array (which could be length 0) and a width */
+ code = pdfi_annot_strokeborder(ctx, annot, W, dash);
+
+ exit:
+ pdfi_countdown(S);
+ pdfi_countdown(dash);
+ return code;
+}
+
+/* Draw the border
+ * This spec seems to be scattered around. There might be:
+ * /Border -- an array of 3-4 elements, where the optional 4th element is a "dash array"
+ * (default value: [0 0 1])
+ * /BS -- a Border Style dictionary
+ * Spec says /Border would be ignored in favor of /BS
+ *
+ */
+static int pdfi_annot_draw_border(pdf_context *ctx, pdf_dict *annot)
+{
+ int code, code1;
+ pdf_dict *BS = NULL;
+ pdf_array *Border = NULL;
+
+ code = pdfi_dict_knownget_type(ctx, annot, "BS", PDF_DICT, (pdf_obj **)&BS);
+ if (code < 0) goto exit;
+ code = pdfi_dict_knownget_type(ctx, annot, "Border", PDF_ARRAY, (pdf_obj **)&Border);
+ if (code < 0) goto exit;
+
+ code = pdfi_gsave(ctx);
+ if (code < 0) goto exit;
+
+ if (BS) {
+ code = pdfi_annot_draw_BS(ctx, annot, BS);
+ } else {
+ /* Note: Border can be null */
+ code = pdfi_annot_draw_Border(ctx, annot, Border);
+ }
+ code1 = pdfi_grestore(ctx);
+ if (code == 0) code = code1;
+
+ exit:
+ pdfi_countdown(BS);
+ pdfi_countdown(Border);
+ return code;
+}
+
+static bool pdfi_annot_draw_Link(pdf_context *ctx, pdf_dict *annot, bool *render_done)
+{
+ int code;
+ int code1;
+ double xscale, yscale;
+
+ dbgmprintf(ctx->memory, "ANNOT: Drawing Link\n");
+
+ code = pdfi_annot_start_transparency(ctx, annot);
+ if (code < 0)
+ return code;
+
+ code = pdfi_annot_draw_border(ctx, annot);
+ if (code < 0) goto exit;
+
+ code = pdfi_annot_calcscale(ctx, annot, &xscale, &yscale);
+ if (code < 0) goto exit;
+
+ if (xscale * yscale > 0.0) {
+ code = pdfi_annot_draw_widget(ctx, annot, xscale, yscale);
+ } else {
+ dbgmprintf(ctx->memory, "ANNOT: Ignoring annotation with scale factor of 0\n");
+ }
+
+ exit:
+ code1 = pdfi_annot_end_transparency(ctx, annot);
+ if (code < 0) code = code1;
+
+ *render_done = true;
+ return code;
+}
+
+static bool pdfi_annot_draw_Ink(pdf_context *ctx, pdf_dict *annot, bool *render_done)
+{
+ return false;
+}
+
+static bool pdfi_annot_draw_Widget(pdf_context *ctx, pdf_dict *annot, bool *render_done)
+{
+ return false;
+}
+
+annot_dispatch_t annot_dispatch[] = {
+ {"Link", pdfi_annot_draw_Link},
+ {"Ink", pdfi_annot_draw_Ink},
+ { NULL, NULL},
+};
+
+/* Check if annotation is visible
+ * (from ps code:)
+%
+% The PDF annotation F (flags) integer is bit encoded.
+% Bit 1 (LSB) Invisible: 1 --> Do not display if no handler.
+% Note: We have no handlers but we ignore this bit.
+% Bit 2 Hidden: 1 --> Do not display. We will not display if this bit is set.
+% Bit 3 Print: 1 --> Display if printing. We will display if this bit set
+% (and not hidden) and Printed is true
+% Bit 4 NoZoom: 1 --> Do not zoom annotation even if image is zoomed.
+% Bit 5 NoRotate: 1 --> Do not rotate annotation even if image is rotated.
+% Bit 6 NoView: 0 --> Display if this is a 'viewer'. We will display
+% if this bit is not set (and not hidden) and Printed is false
+% Bit 7 Read Only - 1 --> No interaction. We ignore this bit
+%
+% AR8 and AR9 print 3D annotations even if Print flag is off. Bug 691486.
+%
+*/
+static bool pdfi_annot_visible(pdf_context *ctx, pdf_dict *annot, pdf_name *subtype)
+{
+ int code;
+ bool is_3D = false;
+ bool is_visible = true;
+ int64_t F;
+
+ if (pdfi_name_is(subtype, "3D"))
+ is_3D = true;
+
+ code = pdfi_dict_get_int(ctx, annot, "F", &F);
+ if (code < 0)
+ F = 0;
+
+ if ((F & 0x2) != 0) { /* Bit 2 -- Hidden */
+ is_visible = false; /* Hidden */
+ goto exit;
+ }
+
+ if (ctx->printed) {
+ /* 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;
+ }
+
+ exit:
+ return is_visible;
+}
+
+/* Check to see if subtype is on the ShowAnnotTypes list
+ * Defaults to true if there is no list
+ */
+static bool pdfi_annot_check_type(pdf_context *ctx, pdf_name *subtype)
+{
+ /* TODO: Need to implement */
+ return true;
+}
+
+static int pdfi_annot_preserve(pdf_context *ctx, pdf_dict *annot)
+{
+ return 0;
+}
+
+static int pdfi_annot_draw(pdf_context *ctx, pdf_dict *annot)
+{
+ pdf_name *Subtype = NULL;
+ int code;
+ annot_dispatch_t *dispatch_ptr;
+ bool render_done = false;
+
+ code = pdfi_dict_get_type(ctx, annot, "Subtype", PDF_NAME, (pdf_obj **)&Subtype);
+ if (code != 0) {
+ /* TODO: Set warning flag */
+ dbgmprintf(ctx->memory, "WARNING: Ignoring annotation with missing Subtype\n");
+ code = 0;
+ goto exit;
+ }
+
+ /* See if annotation is visible */
+ if (!pdfi_annot_visible(ctx, annot, Subtype))
+ goto exit;
+
+ /* See if we are rendering this type of annotation */
+ if (!pdfi_annot_check_type(ctx, Subtype))
+ goto exit;
+
+ code = pdfi_gsave(ctx);
+ if (code < 0)
+ goto exit;
+
+ /* Draw the annotation */
+ for (dispatch_ptr = annot_dispatch; dispatch_ptr->subtype; dispatch_ptr ++) {
+ if (pdfi_name_is(Subtype, dispatch_ptr->subtype)) {
+ code = dispatch_ptr->func(ctx, annot, &render_done);
+ break;
+ }
+ }
+ if (!render_done)
+ code = pdfi_annot_draw_Widget(ctx, annot, &render_done);
+
+ (void)pdfi_grestore(ctx);
+
+ exit:
+ pdfi_countdown(Subtype);
+ return code;
+}
int pdfi_do_annotations(pdf_context *ctx, pdf_dict *page_dict)
{
int code = 0;
pdf_array *Annots = NULL;
+ pdf_dict *annot = NULL;
+ int i;
if (!ctx->showannots)
return 0;
code = pdfi_dict_knownget_type(ctx, page_dict, "Annots", PDF_ARRAY, (pdf_obj **)&Annots);
- if (code == 0)
+ if (code <= 0)
return code;
+ for (i = 0; i < pdfi_array_size(Annots); i++) {
+ code = pdfi_array_get_type(ctx, Annots, i, PDF_DICT, (pdf_obj **)&annot);
+ if (code < 0)
+ continue;
+ if (ctx->preserveannots && ctx->annotations_preserved)
+ code = pdfi_annot_preserve(ctx, annot);
+ else
+ code = pdfi_annot_draw(ctx, annot);
+ if (code < 0)
+ goto exit;
+ pdfi_countdown(annot);
+ annot = NULL;
+ }
+
+ exit:
+ pdfi_countdown(annot);
pdfi_countdown(Annots);
return code;
}
diff --git a/pdf/pdf_colour.c b/pdf/pdf_colour.c
index ba811e9..690c875 100644
--- a/pdf/pdf_colour.c
+++ b/pdf/pdf_colour.c
@@ -298,7 +298,7 @@ int pdfi_ri(pdf_context *ctx)
* functions to 'wrap' these with code to check for replacement of Patterns.
* This comment is duplicated in pdf_pattern.c
*/
-static int pdfi_gs_setgray(pdf_context *ctx, double d)
+int pdfi_gs_setgray(pdf_context *ctx, double d)
{
/* PDF Reference 1.7 p423, any colour operators in a CharProc, following a d1, should be ignored */
if (ctx->inside_CharProc && ctx->CharProc_is_d1)
@@ -565,6 +565,47 @@ int pdfi_setcmykfill(pdf_context *ctx)
return 0;
}
+/* Do a setcolor using values in an array
+ * Will do gray, rgb, cmyk for sizes 1,3,4
+ * Anything else is an error
+ */
+int pdfi_setcolor_from_array(pdf_context *ctx, pdf_array *array)
+{
+ int code = 0;
+ uint64_t size;
+ double values[4];
+ int i;
+
+ size = pdfi_array_size(array);
+ if (size != 1 && size != 3 && size != 4) {
+ code = gs_note_error(gs_error_rangecheck);
+ goto exit;
+ }
+
+ for (i=0; i<size; i++) {
+ code = pdfi_array_get_number(ctx, array, i, &values[i]);
+ if (code < 0)
+ goto exit;
+ }
+
+ switch (size) {
+ case 1:
+ code = pdfi_gs_setgray(ctx, values[0]);
+ break;
+ case 3:
+ code = pdfi_gs_setrgbcolor(ctx, values[0], values[1], values[2]);
+ break;
+ case 4:
+ code = pdfi_gs_setcmykcolor(ctx, values[0], values[1], values[2], values[3]);
+ break;
+ default:
+ break;
+ }
+
+ exit:
+ return code;
+}
+
/* Get colors from top of stack into a client color */
static int
pdfi_get_color_from_stack(pdf_context *ctx, gs_client_color *cc, int ncomps)
diff --git a/pdf/pdf_colour.h b/pdf/pdf_colour.h
index ebb0d20..7539121 100644
--- a/pdf/pdf_colour.h
+++ b/pdf/pdf_colour.h
@@ -33,6 +33,9 @@ int pdfi_setfillcolor(pdf_context *ctx);
int pdfi_setcolorN(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict, bool is_fill);
int pdfi_ri(pdf_context *ctx);
+int pdfi_setcolor_from_array(pdf_context *ctx, pdf_array *array);
+int pdfi_gs_setgray(pdf_context *ctx, double d);
+
/* For potential use by other types of object (images etc) */
int pdfi_setcolorspace(pdf_context *ctx, pdf_obj *space, pdf_dict *stream_dict, pdf_dict *page_dict);
int pdfi_create_colorspace(pdf_context *ctx, pdf_obj *space, pdf_dict *stream_dict, pdf_dict *page_dict, gs_color_space **ppcs, bool inline_image);
diff --git a/pdf/pdf_device.c b/pdf/pdf_device.c
index 8ac470b..fc41027 100644
--- a/pdf/pdf_device.c
+++ b/pdf/pdf_device.c
@@ -36,6 +36,7 @@ static int pdfi_device_check_param(gx_device *dev, const char *param, gs_c_param
return 0;
}
+/* Check value of boolean device parameter */
bool pdfi_device_check_param_bool(gx_device *dev, const char *param)
{
int code;
@@ -52,3 +53,35 @@ bool pdfi_device_check_param_bool(gx_device *dev, const char *param)
gs_c_param_list_release(&list);
return value;
}
+
+/* Checks whether a parameter exists for the device */
+bool pdfi_device_check_param_exists(gx_device *dev, const char *param)
+{
+ int code;
+ gs_c_param_list list;
+
+ code = pdfi_device_check_param(dev, param, &list);
+ if (code < 0)
+ return false;
+ gs_c_param_list_release(&list);
+ return true;
+}
+
+/* Config some device-related variables */
+void pdfi_device_set_flags(pdf_context *ctx)
+{
+ bool has_pdfmark;
+ bool has_ForOPDFRead;
+
+ has_pdfmark = pdfi_device_check_param_exists(ctx->pgs->device, "pdfmark");
+ has_ForOPDFRead = pdfi_device_check_param_bool(ctx->pgs->device, "ForOPDFRead");
+
+ /* Cache these so they don't have to constantly be calculated */
+ ctx->writepdfmarks = has_pdfmark || ctx->dopdfmarks;
+ ctx->annotations_preserved = ctx->writepdfmarks && !has_ForOPDFRead;
+
+ dbgmprintf2(ctx->memory, "Device writepdfmarks=%s, annotations_preserved=%s\n",
+ ctx->writepdfmarks ? "TRUE" : "FALSE",
+ ctx->annotations_preserved ? "TRUE" : "FALSE");
+
+}
diff --git a/pdf/pdf_device.h b/pdf/pdf_device.h
index 72187a3..c482738 100644
--- a/pdf/pdf_device.h
+++ b/pdf/pdf_device.h
@@ -17,5 +17,7 @@
#define PDF_DEVICE
bool pdfi_device_check_param_bool(gx_device *dev, const char *param);
+bool pdfi_device_check_param_exists(gx_device *dev, const char *param);
+void pdfi_device_set_flags(pdf_context *ctx);
#endif
diff --git a/pdf/pdf_gstate.c b/pdf/pdf_gstate.c
index fa91fa7..2dfc239 100644
--- a/pdf/pdf_gstate.c
+++ b/pdf/pdf_gstate.c
@@ -414,7 +414,7 @@ int pdfi_setflat(pdf_context *ctx)
return 0;
}
-static int setdash_impl(pdf_context *ctx, pdf_array *a, double phase_d)
+int pdfi_setdash_impl(pdf_context *ctx, pdf_array *a, double phase_d)
{
float *dash_array;
double temp;
@@ -481,7 +481,7 @@ int pdfi_setdash(pdf_context *ctx)
return 0;
}
- code = setdash_impl(ctx, a, phase_d);
+ code = pdfi_setdash_impl(ctx, a, phase_d);
pdfi_pop(ctx, 2);
if(code < 0 && ctx->pdfstoponerror)
return code;
@@ -598,7 +598,7 @@ static int GS_D(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict
return code;
}
- code = setdash_impl(ctx, a1, d);
+ code = pdfi_setdash_impl(ctx, a1, d);
pdfi_countdown(a1);
pdfi_countdown(a);
return code;
diff --git a/pdf/pdf_gstate.h b/pdf/pdf_gstate.h
index e2333b4..c610803 100644
--- a/pdf/pdf_gstate.h
+++ b/pdf/pdf_gstate.h
@@ -43,6 +43,7 @@ int pdfi_setflat(pdf_context *ctx);
int pdfi_setdash(pdf_context *ctx);
int pdfi_setmiterlimit(pdf_context *ctx);
int pdfi_setgstate(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict);
+int pdfi_setdash_impl(pdf_context *ctx, pdf_array *a, double phase_d);
int pdfi_free_DefaultQState(pdf_context *ctx);
int pdfi_set_DefaultQState(pdf_context *ctx, gs_gstate *pgs);
diff --git a/pdf/pdf_page.c b/pdf/pdf_page.c
index 6fea12d..504f57b 100644
--- a/pdf/pdf_page.c
+++ b/pdf/pdf_page.c
@@ -28,6 +28,7 @@
#include "pdf_gstate.h"
#include "pdf_misc.h"
#include "pdf_optcontent.h"
+#include "pdf_device.h"
#include "pdf_annot.h"
static int pdfi_process_page_contents(pdf_context *ctx, pdf_dict *page_dict)
@@ -149,6 +150,8 @@ static int pdfi_process_one_page(pdf_context *ctx, pdf_dict *page_dict)
if (code > 0)
code = code1;
+ /* TODO: Handle "ShowAcroForm" goes here */
+
return code;
}
@@ -424,6 +427,7 @@ int pdfi_page_render(pdf_context *ctx, uint64_t page_num)
* This needs to be before transparency device is pushed, if applicable
*/
pdfi_trans_set_needs_OP(ctx);
+ pdfi_device_set_flags(ctx);
pdfi_oc_init(ctx);
pdfi_gsave(ctx);
diff --git a/pdf/pdftop.c b/pdf/pdftop.c
index eb56227..ad0ab23 100644
--- a/pdf/pdftop.c
+++ b/pdf/pdftop.c
@@ -408,10 +408,15 @@ pdf_impl_set_param(pl_interp_implementation_t *impl,
ctx->showacroform = boolval;
return 0;
}
+ ctx->showannots = true;;
if (!strncmp(param, "ShowAnnots", 10)) {
ctx->showannots = boolval;
return 0;
}
+ if (!strncmp(param, "PreserveAnnots", 14)) {
+ ctx->preserveannots = boolval;
+ return 0;
+ }
if (!strncmp(param, "NoUserUnit", 10)) {
ctx->nouserunit = boolval;
return 0;
@@ -424,6 +429,10 @@ pdf_impl_set_param(pl_interp_implementation_t *impl,
ctx->pdfinfo = boolval;
return 0;
}
+ if (!strncmp(param, "DOPDFMARKS", 10)) {
+ ctx->dopdfmarks = boolval;
+ return 0;
+ }
return 0;
}
----------------------------------------------------------------------
commit ffe4e1104dcf1579779364ae71bd2cd8a137f3d9
Author: Nancy Durgin <[email protected]>
Date: Tue Nov 26 14:25:58 2019 -0800
Change to not propagate Annotation errors
While checking spots, need to ignore errors
Fixes tests_private/pdf/sumatra/use_after_free_caused_by_pdf_load_obj_stm.pdf
diff --git a/pdf/pdf_check.c b/pdf/pdf_check.c
index 8c9c269..0bf46b8 100644
--- a/pdf/pdf_check.c
+++ b/pdf/pdf_check.c
@@ -837,6 +837,9 @@ static int pdfi_check_Annots_for_transparency(pdf_context *ctx, pdf_array *annot
pdfi_countdown(annot);
annot = NULL;
}
+ if (code < 0 && ctx->pdfstoponerror)
+ goto exit;
+ code = 0;
}
exit:
pdfi_countdown(annot);
Summary of changes:
pdf/ghostpdf.h | 8 +
pdf/pdf_annot.c | 433 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
pdf/pdf_check.c | 3 +
pdf/pdf_colour.c | 43 +++++-
pdf/pdf_colour.h | 3 +
pdf/pdf_device.c | 33 +++++
pdf/pdf_device.h | 2 +
pdf/pdf_gstate.c | 6 +-
pdf/pdf_gstate.h | 1 +
pdf/pdf_page.c | 4 +
pdf/pdftop.c | 9 ++
11 files changed, 540 insertions(+), 5 deletions(-)