[gs-commits] ghostpdl branch, pdfi, updated. jbig2dec-0.14-2212-gf86f9fe
[email protected] (Nancy Durgin)
| Newsgroups | gmane.comp.printing.ghostscript.cvs |
|---|---|
| Message-ID | <[email protected]> |
The ghostpdl branch, pdfi has been updated
via f86f9fef1d8e43847342faa49a77d3560b9b14e4 (commit)
via 9c1278b0f7de3711dc1f149cc768d0d6f9168939 (commit)
via b6813b09ba430f7a467a6339529cda9a50b4d955 (commit)
from f47e65a1b8ca8f7e3e40505a0c8778620593c069 (commit)
----------------------------------------------------------------------
commit f86f9fef1d8e43847342faa49a77d3560b9b14e4
Author: Nancy Durgin <[email protected]>
Date: Tue Sep 17 10:54:40 2019 -0700
Implement code to handle OC in content sequences
Implement opcodes BMC, BDC, EMC
This is an incomplete implementation, just enough to match what the gs
code does, which is just supporting the OC functionality.
Basically this implements "OFFlevels".
The gs implementation uses a dictionary to keep track of which levels are
turned off. I used an array for this (with ability to expand it if
needed). Couldn't use pdf_dict because it has no 'undef' capability, and
actually the current implementation is really just an array anyway.
Add support for OFFlevels to these marking operators:
Fill, stroke, image, shading
Put in a TODO comment for TJ (for ken)
Also, minor refactor to fill/eofill.
diff --git a/pdf/ghostpdf.c b/pdf/ghostpdf.c
index cec8ca4..49a0dff 100644
--- a/pdf/ghostpdf.c
+++ b/pdf/ghostpdf.c
@@ -31,6 +31,7 @@
#include "pdf_colour.h"
#include "pdf_font.h"
#include "pdf_text.h"
+#include "pdf_optcontent.h"
/* This routine is slightly misnamed, as it also checks ColorSpaces for spot colours.
* This is done at the page level, so we maintain a dictionary of the spot colours
@@ -1639,6 +1640,7 @@ static int pdfi_render_page(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_oc_init(ctx);
pdfi_gsave(ctx);
diff --git a/pdf/ghostpdf.h b/pdf/ghostpdf.h
index ff18550..d8e2651 100644
--- a/pdf/ghostpdf.h
+++ b/pdf/ghostpdf.h
@@ -305,6 +305,10 @@ typedef struct pdf_context_s
/* Optional things from Root */
pdf_dict *OCProperties;
+ /* Optional/Marked Content stuff */
+ void *OFFlevels;
+ uint64_t BMClevel;
+
/* Interpreter level PDF objects */
uint32_t stack_size;
pdf_obj **stack_bot;
diff --git a/pdf/pdf_image.c b/pdf/pdf_image.c
index 6c87f6a..5c72118 100644
--- a/pdf/pdf_image.c
+++ b/pdf/pdf_image.c
@@ -1107,6 +1107,9 @@ pdfi_do_image(pdf_context *ctx, pdf_dict *page_dict, pdf_dict *stream_dict, pdf_
if (code < 0)
goto cleanupExit;
+ /* Don't render this if turned off */
+ if (pdfi_oc_is_off(ctx))
+ goto cleanupExit;
/* If there is an OC dictionary, see if we even need to render this */
if (image_info.OC) {
if (!pdfi_oc_is_ocg_visible(ctx, image_info.OC))
diff --git a/pdf/pdf_int.c b/pdf/pdf_int.c
index 4a8c84a..6e87b9e 100644
--- a/pdf/pdf_int.c
+++ b/pdf/pdf_int.c
@@ -34,6 +34,7 @@
#include "pdf_dict.h"
#include "pdf_array.h"
#include "pdf_trans.h"
+#include "pdf_optcontent.h"
/***********************************************************************************/
/* Functions to create the various kinds of 'PDF objects', Created objects have a */
@@ -3025,17 +3026,11 @@ static int pdfi_interpret_stream_operator(pdf_context *ctx, pdf_stream *source,
break;
case K3('B','D','C'): /* begin marked content sequence with property list */
pdfi_pop(ctx, 1);
- if (pdfi_count_stack(ctx) >= 2) {
- pdfi_pop(ctx, 2);
- } else
- pdfi_clearstack(ctx);
+ code = pdfi_op_BDC(ctx, stream_dict, page_dict);
break;
case K3('B','M','C'): /* begin marked content sequence */
pdfi_pop(ctx, 1);
- if (pdfi_count_stack(ctx) >= 1) {
- pdfi_pop(ctx, 1);
- } else
- pdfi_clearstack(ctx);
+ code = pdfi_op_BMC(ctx);
break;
case K2('B','T'): /* begin text */
pdfi_pop(ctx, 1);
@@ -3093,6 +3088,9 @@ static int pdfi_interpret_stream_operator(pdf_context *ctx, pdf_stream *source,
code = pdfi_ET(ctx);
break;
case K3('E','M','C'): /* end marked content sequence */
+ pdfi_pop(ctx, 1);
+ code = pdfi_op_EMC(ctx);
+ break;
case K2('E','X'): /* end compatibility section */
pdfi_pop(ctx, 1);
break;
diff --git a/pdf/pdf_optcontent.c b/pdf/pdf_optcontent.c
index b9fdd47..61f3461 100644
--- a/pdf/pdf_optcontent.c
+++ b/pdf/pdf_optcontent.c
@@ -309,3 +309,184 @@ pdfi_oc_is_ocg_visible(pdf_context *ctx, pdf_dict *ocdict)
}
return is_visible;
}
+
+#define INIT_CONTENT_LEVELS 100
+typedef struct {
+ byte *flags;
+ uint64_t num_off;
+ uint64_t max_flags;
+} pdfi_oc_levels_t;
+
+static int pdfi_oc_levels_init(pdf_context *ctx, pdfi_oc_levels_t **levels)
+{
+ byte *data;
+ pdfi_oc_levels_t *new;
+
+ *levels = NULL;
+
+ new = (pdfi_oc_levels_t *)gs_alloc_bytes(ctx->memory, sizeof(pdfi_oc_levels_t),
+ "pdfi_oc_levels_init (levels)");
+ if (!new)
+ return_error(gs_error_VMerror);
+
+ data = (byte *)gs_alloc_bytes(ctx->memory, INIT_CONTENT_LEVELS, "pdfi_oc_levels_init (data)");
+ if (!data) {
+ gs_free_object(ctx->memory, new, "pdfi_oc_levels_init (levels (error))");
+ return_error(gs_error_VMerror);
+ }
+ memset(data, 0, INIT_CONTENT_LEVELS);
+
+ new->flags = data;
+ new->num_off = 0;
+ new->max_flags = INIT_CONTENT_LEVELS;
+ *levels = new;
+
+ return 0;
+}
+
+static int pdfi_oc_levels_free(pdf_context *ctx, pdfi_oc_levels_t *levels)
+{
+ gs_free_object(ctx->memory, levels->flags, "pdfi_oc_levels_free (flags)");
+ gs_free_object(ctx->memory, levels, "pdfi_oc_levels_free (levels)");
+
+ return 0;
+}
+
+static int pdfi_oc_levels_set(pdf_context *ctx, pdfi_oc_levels_t *levels, uint64_t index)
+{
+ byte *new = NULL;
+ uint64_t newmax;
+
+ if (index > levels->max_flags) {
+ /* Expand the flags buffer */
+ newmax = levels->max_flags + INIT_CONTENT_LEVELS;
+ if (index > newmax)
+ return_error(gs_error_Fatal); /* shouldn't happen */
+ new = gs_alloc_bytes(ctx->memory, newmax, "pdfi_oc_levels_set (new data)");
+ if (!new)
+ return_error(gs_error_VMerror);
+ memset(new, 0, newmax);
+ memcpy(new, levels->flags, levels->max_flags);
+ gs_free_object(ctx->memory, levels->flags, "pdfi_oc_levels_set (old data)");
+ levels->flags = new;
+ }
+
+ if (levels->flags[index] == 0)
+ levels->num_off ++;
+ levels->flags[index] = 1;
+ return 0;
+}
+
+static int pdfi_oc_levels_clear(pdf_context *ctx, pdfi_oc_levels_t *levels, uint64_t index)
+{
+ if (index > levels->max_flags)
+ return -1;
+ if (levels->flags[index] != 0)
+ levels->num_off --;
+ levels->flags[index] = 0;
+ return 0;
+}
+
+
+/* Test if content is turned off for this element.
+ */
+bool pdfi_oc_is_off(pdf_context *ctx)
+{
+ pdfi_oc_levels_t *levels = (pdfi_oc_levels_t *)ctx->OFFlevels;
+ uint64_t num_off = levels->num_off;
+
+ return (num_off != 0);
+}
+
+int pdfi_oc_init(pdf_context *ctx)
+{
+ int code;
+
+ ctx->BMClevel = 0;
+ if (ctx->OFFlevels) {
+ pdfi_oc_levels_free(ctx, ctx->OFFlevels);
+ ctx->OFFlevels = NULL;
+ }
+ code = pdfi_oc_levels_init(ctx, (pdfi_oc_levels_t **)&ctx->OFFlevels);
+ if (code < 0)
+ return code;
+
+ return 0;
+}
+
+/* begin marked content sequence */
+/* TODO: Incomplete implementation, it is ignoring the argument */
+int pdfi_op_BMC(pdf_context *ctx)
+{
+ if (pdfi_count_stack(ctx) >= 1) {
+ pdfi_pop(ctx, 1);
+ } else
+ pdfi_clearstack(ctx);
+ ctx->BMClevel ++;
+ return 0;
+}
+
+/* begin marked content sequence with property list */
+/* TODO: Incomplete implementation, only tries to do something sensible for OC */
+int pdfi_op_BDC(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
+{
+ pdf_name *tag = NULL;
+ pdf_name *properties = NULL;
+ pdf_dict *oc_dict = NULL;
+ int code = 0;
+ bool ocg_is_visible;
+
+ if (pdfi_count_stack(ctx) < 2) {
+ /* TODO: Flag error? */
+ pdfi_clearstack(ctx);
+ return 0;
+ }
+
+ ctx->BMClevel ++;
+
+ /* Check if second arg is OC and handle it if so */
+ tag = (pdf_name *)ctx->stack_top[-2];
+ if (tag->type != PDF_NAME)
+ goto exit;
+ if (!pdfi_name_is(tag, "OC"))
+ goto exit;
+
+ /* Check if first arg is a name and handle it if so */
+ /* TODO: spec says it could also be an inline dict that we should be able to handle,
+ * but I am just matching what gs does for now, and it doesn't handle that case.
+ */
+ properties = (pdf_name *)ctx->stack_top[-1];
+ if (tag->type != PDF_NAME)
+ goto exit;
+
+ /* If it's a name, look it up in Properties */
+ code = pdfi_find_resource(ctx, (unsigned char *)"Properties", properties,
+ stream_dict, page_dict, (pdf_obj **)&oc_dict);
+ if (code != 0)
+ goto exit;
+ if (oc_dict->type != PDF_DICT)
+ goto exit;
+
+ /* Now we have an OC dict, see if it's visible */
+ ocg_is_visible = pdfi_oc_is_ocg_visible(ctx, oc_dict);
+ if (!ocg_is_visible)
+ code = pdfi_oc_levels_set(ctx, ctx->OFFlevels, ctx->BMClevel);
+
+ exit:
+ pdfi_pop(ctx, 2); /* pop args */
+ pdfi_countdown(oc_dict);
+ return code;
+}
+
+/* end marked content sequence */
+int pdfi_op_EMC(pdf_context *ctx)
+{
+ int code;
+
+ code = pdfi_oc_levels_clear(ctx, ctx->OFFlevels, ctx->BMClevel);
+
+ /* TODO: Should we flag error on too many EMC? */
+ if (ctx->BMClevel > 0)
+ ctx->BMClevel --;
+ return code;
+}
diff --git a/pdf/pdf_optcontent.h b/pdf/pdf_optcontent.h
index 53880ae..71d5366 100644
--- a/pdf/pdf_optcontent.h
+++ b/pdf/pdf_optcontent.h
@@ -18,4 +18,10 @@
bool pdfi_oc_is_ocg_visible(pdf_context *ctx, pdf_dict *ocdict);
+int pdfi_oc_init(pdf_context *ctx);
+bool pdfi_oc_is_off(pdf_context *ctx);
+int pdfi_op_BMC(pdf_context *ctx);
+int pdfi_op_BDC(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict);
+int pdfi_op_EMC(pdf_context *ctx);
+
#endif
diff --git a/pdf/pdf_path.c b/pdf/pdf_path.c
index 6059035..2d39b88 100644
--- a/pdf/pdf_path.c
+++ b/pdf/pdf_path.c
@@ -21,6 +21,7 @@
#include "pdf_stack.h"
#include "pdf_trans.h"
#include "gstypes.h"
+#include "pdf_optcontent.h"
int pdfi_moveto (pdf_context *ctx)
{
@@ -126,7 +127,7 @@ int pdfi_lineto (pdf_context *ctx)
return 0;
}
-int pdfi_fill(pdf_context *ctx)
+static int pdfi_fill_inner(pdf_context *ctx, bool use_eofill)
{
int code, code1;
pdfi_trans_state_t state;
@@ -134,10 +135,18 @@ int pdfi_fill(pdf_context *ctx)
if (ctx->TextBlockDepth != 0)
ctx->pdf_warnings |= W_PDF_OPINVALIDINTEXT;
+ if (pdfi_oc_is_off(ctx)) {
+ code = gs_newpath(ctx->pgs);
+ return code;
+ }
+
gs_swapcolors(ctx->pgs);
code = pdfi_trans_setup(ctx, &state, TRANSPARENCY_Caller_Fill, gs_getfillconstantalpha(ctx->pgs));
if (code == 0) {
- code = gs_fill(ctx->pgs);
+ if (use_eofill)
+ code = gs_eofill(ctx->pgs);
+ else
+ code = gs_fill(ctx->pgs);
code1 = pdfi_trans_teardown(ctx, &state);
if (code == 0)
code = code1;
@@ -149,27 +158,14 @@ int pdfi_fill(pdf_context *ctx)
return 0;
}
+int pdfi_fill(pdf_context *ctx)
+{
+ return pdfi_fill_inner(ctx, false);
+}
+
int pdfi_eofill(pdf_context *ctx)
{
- int code, code1;
- pdfi_trans_state_t state;
-
- if (ctx->TextBlockDepth != 0)
- ctx->pdf_warnings |= W_PDF_OPINVALIDINTEXT;
-
- gs_swapcolors(ctx->pgs);
- code = pdfi_trans_setup(ctx, &state, TRANSPARENCY_Caller_EOFill, gs_getfillconstantalpha(ctx->pgs));
- if (code == 0) {
- code = gs_eofill(ctx->pgs);
- code1 = pdfi_trans_teardown(ctx, &state);
- if (code == 0)
- code = code1;
- }
- gs_swapcolors(ctx->pgs);
- if(code < 0 && ctx->pdfstoponerror)
- return code;
- else
- return 0;
+ return pdfi_fill_inner(ctx, true);
}
int pdfi_stroke(pdf_context *ctx)
@@ -180,6 +176,11 @@ int pdfi_stroke(pdf_context *ctx)
if (ctx->TextBlockDepth != 0)
ctx->pdf_warnings |= W_PDF_OPINVALIDINTEXT;
+ if (pdfi_oc_is_off(ctx)) {
+ code = gs_newpath(ctx->pgs);
+ return code;
+ }
+
code = pdfi_trans_setup(ctx, &state, TRANSPARENCY_Caller_Stroke, gs_getstrokeconstantalpha(ctx->pgs));
if (code == 0) {
code = gs_stroke(ctx->pgs);
@@ -410,6 +411,11 @@ static int pdfi_B_inner(pdf_context *ctx, bool use_eofill)
if (ctx->TextBlockDepth != 0)
ctx->pdf_warnings |= W_PDF_OPINVALIDINTEXT;
+ if (pdfi_oc_is_off(ctx)) {
+ code = gs_newpath(ctx->pgs);
+ return code;
+ }
+
if (ctx->page_has_transparency) {
code = gs_setopacityalpha(ctx->pgs, 1.0);
if (code < 0)
diff --git a/pdf/pdf_shading.c b/pdf/pdf_shading.c
index dd09710..3ce5c4c 100644
--- a/pdf/pdf_shading.c
+++ b/pdf/pdf_shading.c
@@ -26,6 +26,7 @@
#include "pdf_loop_detect.h"
#include "pdf_colour.h"
#include "pdf_trans.h"
+#include "pdf_optcontent.h"
#include "gxshade.h"
#include "gsptype2.h"
@@ -748,6 +749,9 @@ int pdfi_shading(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
if (ctx->TextBlockDepth != 0)
ctx->pdf_warnings |= W_PDF_OPINVALIDINTEXT;
+ if (pdfi_oc_is_off(ctx))
+ return 0;
+
n = (pdf_name *)ctx->stack_top[-1];
if (n->type != PDF_NAME)
return_error(gs_error_typecheck);
diff --git a/pdf/pdf_text.c b/pdf/pdf_text.c
index 1bf4c1a..6bb70c1 100644
--- a/pdf/pdf_text.c
+++ b/pdf/pdf_text.c
@@ -521,6 +521,10 @@ int pdfi_TJ(pdf_context *ctx)
gs_matrix saved, Trm;
gs_point initial_point, current_point;
+ /* TODO: for ken -- check pdfi_oc_is_off() and skip the actual rendering...
+ * (see gs code pdf_ops.ps/TJ OFFlevels for appropriate logic)
+ */
+
if (ctx->TextBlockDepth == 0) {
ctx->pdf_warnings |= W_PDF_TEXTOPNOBT;
}
----------------------------------------------------------------------
commit 9c1278b0f7de3711dc1f149cc768d0d6f9168939
Author: Nancy Durgin <[email protected]>
Date: Tue Sep 17 09:41:55 2019 -0700
Add pdf_optcontent.c and .h, move code around
Move ocg stuff from pdf_page to pdf_optcontent
Now pdf_page.[ch] is empty... I think pdf_optcontent is a better place
for this, but not deleting pdf_page for now in case they turn out to
be useful for something?
Have image debug print out the object number
This is a bunch of code moving and renaming, no functional differences.
diff --git a/pdf/pdf.mak b/pdf/pdf.mak
index d066027..a9d0082 100644
--- a/pdf/pdf.mak
+++ b/pdf/pdf.mak
@@ -128,6 +128,9 @@ $(PDFOBJ)pdf_device.$(OBJ): $(PDFSRC)pdf_device.c $(PDFINCLUDES) $(PDF_MAK) $(MA
$(PDFOBJ)pdf_misc.$(OBJ): $(PDFSRC)pdf_misc.c $(PDFINCLUDES) $(PDF_MAK) $(MAKEDIRS)
$(PDFCCC) $(PDFSRC)pdf_misc.c $(PDFO_)pdf_misc.$(OBJ)
+$(PDFOBJ)pdf_optcontent.$(OBJ): $(PDFSRC)pdf_optcontent.c $(PDFINCLUDES) $(PDF_MAK) $(MAKEDIRS)
+ $(PDFCCC) $(PDFSRC)pdf_optcontent.c $(PDFO_)pdf_optcontent.$(OBJ)
+
$(PDFGEN)pdfimpl.c: $(PLSRC)plimpl.c $(PDF_MAK) $(MAKEDIRS)
$(CP_) $(PLSRC)plimpl.c $(PDFGEN)pdfimpl.c
@@ -174,6 +177,7 @@ PDF_OBJS=\
$(PDFOBJ)pdf_trans.$(OBJ)\
$(PDFOBJ)pdf_device.$(OBJ)\
$(PDFOBJ)pdf_misc.$(OBJ)\
+ $(PDFOBJ)pdf_optcontent.$(OBJ)\
# NB - note this is a bit squirrely. Right now the pjl interpreter is
diff --git a/pdf/pdf_image.c b/pdf/pdf_image.c
index 47c7966..6c87f6a 100644
--- a/pdf/pdf_image.c
+++ b/pdf/pdf_image.c
@@ -27,6 +27,7 @@
#include "pdf_colour.h"
#include "pdf_trans.h"
#include "pdf_misc.h"
+#include "pdf_optcontent.h"
#include "stream.h" /* for stell() */
#include "gsiparm4.h"
@@ -1108,7 +1109,7 @@ pdfi_do_image(pdf_context *ctx, pdf_dict *page_dict, pdf_dict *stream_dict, pdf_
/* If there is an OC dictionary, see if we even need to render this */
if (image_info.OC) {
- if (!pdfi_page_is_ocg_visible(ctx, image_info.OC))
+ if (!pdfi_oc_is_ocg_visible(ctx, image_info.OC))
goto cleanupExit;
}
@@ -1461,7 +1462,7 @@ int pdfi_do_image_or_form(pdf_context *ctx, pdf_dict *stream_dict,
int code;
pdf_name *n = NULL;
- dbgmprintf(ctx->memory, "pdfi_do_image_or_form BEGIN\n");
+ dbgmprintf1(ctx->memory, "pdfi_do_image_or_form BEGIN (OBJ = %ld)\n", xobject_dict->object_num);
code = pdfi_trans_set_params(ctx, gs_getfillconstantalpha(ctx->pgs));
if (code < 0)
return code;
diff --git a/pdf/pdf_page.c b/pdf/pdf_optcontent.c
similarity index 92%
copy from pdf/pdf_page.c
copy to pdf/pdf_optcontent.c
index 6596bff..b9fdd47 100644
--- a/pdf/pdf_page.c
+++ b/pdf/pdf_optcontent.c
@@ -13,23 +13,16 @@
CA 94945, U.S.A., +1(415)492-9861, for further information.
*/
-/* Page-level operations for the PDF interpreter */
+/* Optional Content routines */
#include "pdf_int.h"
#include "pdf_stack.h"
-#include "pdf_page.h"
-#include "pdf_file.h"
+#include "pdf_misc.h"
+#include "pdf_gstate.h"
#include "pdf_dict.h"
#include "pdf_array.h"
-#include "pdf_loop_detect.h"
-#include "pdf_colour.h"
-#include "pdf_trans.h"
-#include "pdf_misc.h"
+#include "pdf_optcontent.h"
-#include "gsiparm4.h"
-#include "gsiparm3.h"
-
-#include "gstrans.h"
/* Find the default value for an ocdict, based on contents of OCProperties */
/* NOTE: the spec says that if BaseState is present, it won't be set to "OFF",
@@ -97,7 +90,7 @@ pdfi_get_default_OCG_val(pdf_context *ctx, pdf_dict *ocdict)
/* Check Usage for an OCG */
static bool
-pdfi_page_check_OCG_usage(pdf_context *ctx, pdf_dict *ocdict)
+pdfi_oc_check_OCG_usage(pdf_context *ctx, pdf_dict *ocdict)
{
bool is_visible = true;
int code;
@@ -147,7 +140,7 @@ typedef enum {
} ocmd_p_type;
static bool
-pdfi_page_check_OCMD_array(pdf_context *ctx, pdf_array *array, ocmd_p_type type)
+pdfi_oc_check_OCMD_array(pdf_context *ctx, pdf_array *array, ocmd_p_type type)
{
bool is_visible;
uint64_t i;
@@ -214,7 +207,7 @@ pdfi_page_check_OCMD_array(pdf_context *ctx, pdf_array *array, ocmd_p_type type)
}
static bool
-pdfi_page_check_OCMD(pdf_context *ctx, pdf_dict *ocdict)
+pdfi_oc_check_OCMD(pdf_context *ctx, pdf_dict *ocdict)
{
bool is_visible = true;
int code;
@@ -269,7 +262,7 @@ pdfi_page_check_OCMD(pdf_context *ctx, pdf_dict *ocdict)
break;
}
} else {
- is_visible = pdfi_page_check_OCMD_array(ctx, OCGs_array, Ptype);
+ is_visible = pdfi_oc_check_OCMD_array(ctx, OCGs_array, Ptype);
}
cleanup:
@@ -282,7 +275,7 @@ pdfi_page_check_OCMD(pdf_context *ctx, pdf_dict *ocdict)
/* Check if an OCG or OCMD is visible, passing in OC dict */
bool
-pdfi_page_is_ocg_visible(pdf_context *ctx, pdf_dict *ocdict)
+pdfi_oc_is_ocg_visible(pdf_context *ctx, pdf_dict *ocdict)
{
pdf_name *type = NULL;
bool is_visible = true;
@@ -295,11 +288,11 @@ pdfi_page_is_ocg_visible(pdf_context *ctx, pdf_dict *ocdict)
goto cleanup;
if (pdfi_name_is(type, "OCMD")) {
- is_visible = pdfi_page_check_OCMD(ctx, ocdict);
+ is_visible = pdfi_oc_check_OCMD(ctx, ocdict);
} else if (pdfi_name_is(type, "OCG")) {
is_visible = pdfi_get_default_OCG_val(ctx, ocdict);
if (is_visible)
- is_visible = pdfi_page_check_OCG_usage(ctx, ocdict);
+ is_visible = pdfi_oc_check_OCG_usage(ctx, ocdict);
} else {
char str[100];
memcpy(str, (const char *)type->data, type->length);
diff --git a/pdf/pdf_page.h b/pdf/pdf_optcontent.h
similarity index 77%
copy from pdf/pdf_page.h
copy to pdf/pdf_optcontent.h
index 4262f29..53880ae 100644
--- a/pdf/pdf_page.h
+++ b/pdf/pdf_optcontent.h
@@ -13,11 +13,9 @@
CA 94945, U.S.A., +1(415)492-9861, for further information.
*/
-/* Page-level operations for the PDF interpreter */
+#ifndef PDF_OPTCONTENT
+#define PDF_OPTCONTENT
-#ifndef PDF_PAGE_OPERATORS
-#define PDF_PAGE_OPERATORS
-
-bool pdfi_page_is_ocg_visible(pdf_context *ctx, pdf_dict *ocdict);
+bool pdfi_oc_is_ocg_visible(pdf_context *ctx, pdf_dict *ocdict);
#endif
diff --git a/pdf/pdf_page.c b/pdf/pdf_page.c
index 6596bff..b8aef1a 100644
--- a/pdf/pdf_page.c
+++ b/pdf/pdf_page.c
@@ -31,288 +31,6 @@
#include "gstrans.h"
-/* Find the default value for an ocdict, based on contents of OCProperties */
-/* NOTE: the spec says that if BaseState is present, it won't be set to "OFF",
- * but this doesn't seem to be the case (Bug 691491). Also, the spec
- * says the ON and OFF arrays are redundant in certain cases. We just
- * look at everything anyway.
- * Default is going to be visible unless anything here indicates that it
- * should be turned off.
+/* NOTE: I used to have the OC stuff here, moved it to pdf_optcontent.c
+ * Maybe this file will have other things at some point, else it could be deleted.
*/
-static bool
-pdfi_get_default_OCG_val(pdf_context *ctx, pdf_dict *ocdict)
-{
- bool is_visible = true;
- pdf_dict *D = NULL;
- pdf_obj *BaseState = NULL;
- pdf_array *OFF = NULL;
- pdf_array *ON = NULL;
- int code;
-
- if (ctx->OCProperties == NULL)
- return is_visible;
-
- code = pdfi_dict_knownget_type(ctx, ctx->OCProperties, "D", PDF_DICT, (pdf_obj **)&D);
- if (code <= 0)
- goto cleanup;
-
- code = pdfi_dict_knownget_type(ctx, D, "BaseState", PDF_NAME, &BaseState);
- if (code < 0) {
- goto cleanup;
- }
- if (code > 0) {
- if (pdfi_name_is((pdf_name *)BaseState, "OFF")) {
- is_visible = false;
- }
- }
-
- if (!is_visible) {
- code = pdfi_dict_knownget_type(ctx, D, "ON", PDF_ARRAY, (pdf_obj **)&ON);
- if (code < 0)
- goto cleanup;
- if (code > 0) {
- if (pdfi_array_known(ctx, ON, (pdf_obj *)ocdict, NULL))
- is_visible = true;
- }
- }
-
- if (is_visible) {
- code = pdfi_dict_knownget_type(ctx, D, "OFF", PDF_ARRAY, (pdf_obj **)&OFF);
- if (code < 0)
- goto cleanup;
- if (code > 0) {
- if (pdfi_array_known(ctx, OFF, (pdf_obj *)ocdict, NULL))
- is_visible = false;
- }
- }
-
-
- cleanup:
- pdfi_countdown(BaseState);
- pdfi_countdown(D);
- pdfi_countdown(OFF);
- pdfi_countdown(ON);
- return is_visible;
-}
-
-/* Check Usage for an OCG */
-static bool
-pdfi_page_check_OCG_usage(pdf_context *ctx, pdf_dict *ocdict)
-{
- bool is_visible = true;
- int code;
- pdf_dict *Usage = NULL;
- pdf_dict *dict = NULL;
- pdf_obj *name = NULL;
-
- /* Check Usage to see if it has additional info */
- code = pdfi_dict_knownget_type(ctx, ocdict, "Usage", PDF_DICT, (pdf_obj **)&Usage);
- if (code <= 0) {
- /* No Usage, so we're done */
- goto cleanup;
- }
-
- if (ctx->printed) {
- code = pdfi_dict_knownget_type(ctx, ocdict, "Print", PDF_DICT, (pdf_obj **)&dict);
- if (code <= 0)
- goto cleanup;
- code = pdfi_dict_knownget_type(ctx, dict, "PrintState", PDF_NAME, &name);
- if (code <= 0)
- goto cleanup;
- } else {
- code = pdfi_dict_knownget_type(ctx, ocdict, "View", PDF_DICT, (pdf_obj **)&dict);
- if (code <= 0)
- goto cleanup;
- code = pdfi_dict_knownget_type(ctx, dict, "ViewState", PDF_NAME, &name);
- if (code <= 0)
- goto cleanup;
- }
- if (pdfi_name_strcmp((pdf_name *)name, "OFF")) {
- is_visible = false;
- }
-
- cleanup:
- pdfi_countdown(Usage);
- pdfi_countdown(dict);
- pdfi_countdown(name);
-
- return is_visible;
-}
-
-typedef enum {
- P_AnyOn,
- P_AllOn,
- P_AllOff,
- P_AnyOff
-} ocmd_p_type;
-
-static bool
-pdfi_page_check_OCMD_array(pdf_context *ctx, pdf_array *array, ocmd_p_type type)
-{
- bool is_visible;
- uint64_t i;
- int code;
-
- /* Setup default */
- switch (type) {
- case P_AnyOn:
- case P_AnyOff:
- is_visible = false;
- break;
- case P_AllOn:
- case P_AllOff:
- is_visible = true;
- break;
- }
-
- for (i=0; i<pdfi_array_size(array); i++) {
- bool vis;
- pdf_obj *val = NULL;
-
- code = pdfi_array_peek(ctx, array, i, &val);
- if (code < 0) continue;
- if (val->type != PDF_DICT) {
- dmprintf1(ctx->memory, "WARNING: OCMD array contains item type %d, expected PDF_DICT or PDF_NULL\n", val->type);
- continue;
- }
-
- vis = pdfi_get_default_OCG_val(ctx, (pdf_dict *)val);
- switch (type) {
- case P_AnyOn:
- /* visible if any is on */
- if (vis) {
- is_visible = true;
- goto cleanup;
- }
- break;
- case P_AllOn:
- /* visible if all on */
- if (!vis) {
- is_visible = false;
- goto cleanup;
- }
- break;
- case P_AllOff:
- /* visible if all are off */
- if (vis) {
- is_visible = false;
- goto cleanup;
- }
- break;
- case P_AnyOff:
- /* visible if any is off */
- if (!vis) {
- is_visible = true;
- goto cleanup;
- }
- break;
- }
- }
-
- cleanup:
- return is_visible;
-}
-
-static bool
-pdfi_page_check_OCMD(pdf_context *ctx, pdf_dict *ocdict)
-{
- bool is_visible = true;
- int code;
- pdf_obj *VE = NULL;
- pdf_obj *obj = NULL;
- pdf_obj *Pname = NULL;
- pdf_dict *OCGs_dict = NULL; /* alias, don't need to free */
- pdf_array *OCGs_array = NULL; /* alias, don't need to free */
- ocmd_p_type Ptype = P_AnyOn;
-
- /* TODO: We don't support this, so log a warning and ignore */
- code = pdfi_dict_knownget_type(ctx, ocdict, "VE", PDF_ARRAY, &VE);
- if (code > 0) {
- dmprintf(ctx->memory, "WARNING: OCMD contains VE, which is not supported (ignoring)\n");
- }
-
- code = pdfi_dict_knownget(ctx, ocdict, "OCGs", &obj);
- if (code <= 0)
- goto cleanup;
- if (obj->type == PDF_ARRAY) {
- OCGs_array = (pdf_array *)obj;
- } else if (obj->type == PDF_DICT) {
- OCGs_dict = (pdf_dict *)obj;
- } else {
- goto cleanup;
- }
-
- code = pdfi_dict_knownget_type(ctx, ocdict, "P", PDF_NAME, &Pname);
- if (code < 0)
- goto cleanup;
- if (code == 0 || pdfi_name_is((pdf_name *)Pname, "AnyOn")) {
- Ptype = P_AnyOn;
- } else if (pdfi_name_is((pdf_name *)Pname, "AllOn")) {
- Ptype = P_AllOn;
- } else if (pdfi_name_is((pdf_name *)Pname, "AnyOff")) {
- Ptype = P_AnyOff;
- } else if (pdfi_name_is((pdf_name *)Pname, "AllOff")) {
- Ptype = P_AllOff;
- } else {
- Ptype = P_AnyOn;
- }
-
- if (OCGs_dict) {
- switch (Ptype) {
- case P_AnyOn:
- case P_AllOn:
- is_visible = pdfi_get_default_OCG_val(ctx, OCGs_dict);
- break;
- case P_AllOff:
- case P_AnyOff:
- is_visible = !pdfi_get_default_OCG_val(ctx, OCGs_dict);
- break;
- }
- } else {
- is_visible = pdfi_page_check_OCMD_array(ctx, OCGs_array, Ptype);
- }
-
- cleanup:
- pdfi_countdown(VE);
- pdfi_countdown(obj);
- pdfi_countdown(Pname);
-
- return is_visible;
-}
-
-/* Check if an OCG or OCMD is visible, passing in OC dict */
-bool
-pdfi_page_is_ocg_visible(pdf_context *ctx, pdf_dict *ocdict)
-{
- pdf_name *type = NULL;
- bool is_visible = true;
- int code;
-
- /* Type can be either OCMD or OCG.
- */
- code = pdfi_dict_knownget_type(ctx, ocdict, "Type", PDF_NAME, (pdf_obj **)&type);
- if (code <= 0)
- goto cleanup;
-
- if (pdfi_name_is(type, "OCMD")) {
- is_visible = pdfi_page_check_OCMD(ctx, ocdict);
- } else if (pdfi_name_is(type, "OCG")) {
- is_visible = pdfi_get_default_OCG_val(ctx, ocdict);
- if (is_visible)
- is_visible = pdfi_page_check_OCG_usage(ctx, ocdict);
- } else {
- char str[100];
- memcpy(str, (const char *)type->data, type->length);
- str[type->length] = '\0';
- dmprintf1(ctx->memory, "WARNING: OC dict type is %s, expected OCG or OCMD\n", str);
- }
-
- cleanup:
- pdfi_countdown(type);
-
- if (ctx->pdfdebug) {
- dmprintf2(ctx->memory, "OCG: OC Dict %ld %s visible\n", ocdict->object_num,
- is_visible ? "IS" : "IS NOT");
- }
- return is_visible;
-}
diff --git a/pdf/pdf_page.h b/pdf/pdf_page.h
index 4262f29..c1213e3 100644
--- a/pdf/pdf_page.h
+++ b/pdf/pdf_page.h
@@ -18,6 +18,6 @@
#ifndef PDF_PAGE_OPERATORS
#define PDF_PAGE_OPERATORS
-bool pdfi_page_is_ocg_visible(pdf_context *ctx, pdf_dict *ocdict);
+/* NOTE: used to have OC stuff here, moved to pdf_optcontent.h */
#endif
----------------------------------------------------------------------
commit b6813b09ba430f7a467a6339529cda9a50b4d955
Author: Nancy Durgin <[email protected]>
Date: Thu Sep 12 14:01:19 2019 -0700
Cleaned up some code
diff --git a/pdf/pdf_image.c b/pdf/pdf_image.c
index 4f7600b..47c7966 100644
--- a/pdf/pdf_image.c
+++ b/pdf/pdf_image.c
@@ -859,7 +859,7 @@ pdfi_do_image_smask(pdf_context *ctx, pdf_stream *source, pdfi_image_info_t *ima
pdf_array *a = NULL;
gs_offset_t savedoffset = 0;
double f;
- int code;
+ int code, code1;
pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
/* TODO: We should check for the /PreserveSMask device parameter here. If this is
@@ -868,6 +868,7 @@ pdfi_do_image_smask(pdf_context *ctx, pdf_stream *source, pdfi_image_info_t *ima
*/
dbgmprintf(ctx->memory, "pdfi_do_image_smask BEGIN\n");
+
gs_trans_mask_params_init(¶ms, TRANSPARENCY_MASK_Luminosity);
code = pdfi_dict_knownget_type(ctx, (pdf_dict *)image_info->SMask, "Matte",
@@ -909,16 +910,12 @@ pdfi_do_image_smask(pdf_context *ctx, pdf_stream *source, pdfi_image_info_t *ima
image_info->page_dict, (pdf_dict *)image_info->SMask);
pdfi_seek(ctx, ctx->main_stream, savedoffset, SEEK_SET);
- if (code < 0) {
- (void)pdfi_grestore(ctx);
- (void)gs_end_transparency_mask(ctx->pgs, 0);
- } else {
- code = pdfi_grestore(ctx);
- if (code < 0)
- (void)gs_end_transparency_mask(ctx->pgs, 0);
- else
- code = gs_end_transparency_mask(ctx->pgs, 0);
- }
+ code1 = pdfi_grestore(ctx);
+ if (code < 0)
+ code = code1;
+ code1 = gs_end_transparency_mask(ctx->pgs, TRANSPARENCY_CHANNEL_Opacity);
+ if (code < 0)
+ code = code1;
exit:
pdfi_countdown(a);
Summary of changes:
pdf/ghostpdf.c | 2 +
pdf/ghostpdf.h | 4 +
pdf/pdf.mak | 4 +
pdf/pdf_image.c | 27 ++--
pdf/pdf_int.c | 14 +-
pdf/{pdf_page.c => pdf_optcontent.c} | 210 +++++++++++++++++++++---
pdf/{pdf_fontTT.h => pdf_optcontent.h} | 13 +-
pdf/pdf_page.c | 286 +--------------------------------
pdf/pdf_page.h | 2 +-
pdf/pdf_path.c | 48 +++---
pdf/pdf_shading.c | 4 +
pdf/pdf_text.c | 4 +
12 files changed, 268 insertions(+), 350 deletions(-)
copy pdf/{pdf_page.c => pdf_optcontent.c} (59%)
copy pdf/{pdf_fontTT.h => pdf_optcontent.h} (63%)