summaryrefslogtreecommitdiff
path: root/source/pdf/pdf-interpret.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/pdf/pdf-interpret.c')
-rw-r--r--source/pdf/pdf-interpret.c226
1 files changed, 6 insertions, 220 deletions
diff --git a/source/pdf/pdf-interpret.c b/source/pdf/pdf-interpret.c
index 58999373..4a8a2a46 100644
--- a/source/pdf/pdf-interpret.c
+++ b/source/pdf/pdf-interpret.c
@@ -81,220 +81,6 @@ load_font_or_hail_mary(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, pdf_obj
return desc;
}
-static int
-ocg_intents_include(fz_context *ctx, pdf_ocg_descriptor *desc, char *name)
-{
- int i, len;
-
- if (strcmp(name, "All") == 0)
- return 1;
-
- /* In the absence of a specified intent, it's 'View' */
- if (!desc->intent)
- return (strcmp(name, "View") == 0);
-
- if (pdf_is_name(ctx, desc->intent))
- {
- char *intent = pdf_to_name(ctx, desc->intent);
- if (strcmp(intent, "All") == 0)
- return 1;
- return (strcmp(intent, name) == 0);
- }
- if (!pdf_is_array(ctx, desc->intent))
- return 0;
-
- len = pdf_array_len(ctx, desc->intent);
- for (i=0; i < len; i++)
- {
- char *intent = pdf_to_name(ctx, pdf_array_get(ctx, desc->intent, i));
- if (strcmp(intent, "All") == 0)
- return 1;
- if (strcmp(intent, name) == 0)
- return 1;
- }
- return 0;
-}
-
-static int
-pdf_is_hidden_ocg(fz_context *ctx, pdf_ocg_descriptor *desc, pdf_obj *rdb, const char *event, pdf_obj *ocg)
-{
- char event_state[16];
- pdf_obj *obj, *obj2, *type;
-
- /* Avoid infinite recursions */
- if (pdf_obj_marked(ctx, ocg))
- return 0;
-
- /* If no event, everything is visible */
- if (!event)
- return 0;
-
- /* If no ocg descriptor, everything is visible */
- if (!desc)
- return 0;
-
- /* If we've been handed a name, look it up in the properties. */
- if (pdf_is_name(ctx, ocg))
- {
- ocg = pdf_dict_get(ctx, pdf_dict_get(ctx, rdb, PDF_NAME_Properties), ocg);
- }
- /* If we haven't been given an ocg at all, then we're visible */
- if (!ocg)
- return 0;
-
- fz_strlcpy(event_state, event, sizeof event_state);
- fz_strlcat(event_state, "State", sizeof event_state);
-
- type = pdf_dict_get(ctx, ocg, PDF_NAME_Type);
-
- if (pdf_name_eq(ctx, type, PDF_NAME_OCG))
- {
- /* An Optional Content Group */
- int default_value = 0;
- int num = pdf_to_num(ctx, ocg);
- int len = desc->len;
- int i;
- pdf_obj *es;
-
- /* by default an OCG is visible, unless it's explicitly hidden */
- for (i = 0; i < len; i++)
- {
- if (desc->ocgs[i].num == num)
- {
- default_value = desc->ocgs[i].state == 0;
- break;
- }
- }
-
- /* Check Intents; if our intent is not part of the set given
- * by the current config, we should ignore it. */
- obj = pdf_dict_get(ctx, ocg, PDF_NAME_Intent);
- if (pdf_is_name(ctx, obj))
- {
- /* If it doesn't match, it's hidden */
- if (ocg_intents_include(ctx, desc, pdf_to_name(ctx, obj)) == 0)
- return 1;
- }
- else if (pdf_is_array(ctx, obj))
- {
- int match = 0;
- len = pdf_array_len(ctx, obj);
- for (i=0; i<len; i++) {
- match |= ocg_intents_include(ctx, desc, pdf_to_name(ctx, pdf_array_get(ctx, obj, i)));
- if (match)
- break;
- }
- /* If we don't match any, it's hidden */
- if (match == 0)
- return 1;
- }
- else
- {
- /* If it doesn't match, it's hidden */
- if (ocg_intents_include(ctx, desc, "View") == 0)
- return 1;
- }
-
- /* FIXME: Currently we do a very simple check whereby we look
- * at the Usage object (an Optional Content Usage Dictionary)
- * and check to see if the corresponding 'event' key is on
- * or off.
- *
- * Really we should only look at Usage dictionaries that
- * correspond to entries in the AS list in the OCG config.
- * Given that we don't handle Zoom or User, or Language
- * dicts, this is not really a problem. */
- obj = pdf_dict_get(ctx, ocg, PDF_NAME_Usage);
- if (!pdf_is_dict(ctx, obj))
- return default_value;
- /* FIXME: Should look at Zoom (and return hidden if out of
- * max/min range) */
- /* FIXME: Could provide hooks to the caller to check if
- * User is appropriate - if not return hidden. */
- obj2 = pdf_dict_gets(ctx, obj, event);
- es = pdf_dict_gets(ctx, obj2, event_state);
- if (pdf_name_eq(ctx, es, PDF_NAME_OFF))
- {
- return 1;
- }
- if (pdf_name_eq(ctx, es, PDF_NAME_ON))
- {
- return 0;
- }
- return default_value;
- }
- else if (pdf_name_eq(ctx, type, PDF_NAME_OCMD))
- {
- /* An Optional Content Membership Dictionary */
- pdf_obj *name;
- int combine, on;
-
- obj = pdf_dict_get(ctx, ocg, PDF_NAME_VE);
- if (pdf_is_array(ctx, obj)) {
- /* FIXME: Calculate visibility from array */
- return 0;
- }
- name = pdf_dict_get(ctx, ocg, PDF_NAME_P);
- /* Set combine; Bit 0 set => AND, Bit 1 set => true means
- * Off, otherwise true means On */
- if (pdf_name_eq(ctx, name, PDF_NAME_AllOn))
- {
- combine = 1;
- }
- else if (pdf_name_eq(ctx, name, PDF_NAME_AnyOff))
- {
- combine = 2;
- }
- else if (pdf_name_eq(ctx, name, PDF_NAME_AllOff))
- {
- combine = 3;
- }
- else /* Assume it's the default (AnyOn) */
- {
- combine = 0;
- }
-
- if (pdf_mark_obj(ctx, ocg))
- return 0; /* Should never happen */
- fz_try(ctx)
- {
- obj = pdf_dict_get(ctx, ocg, PDF_NAME_OCGs);
- on = combine & 1;
- if (pdf_is_array(ctx, obj)) {
- int i, len;
- len = pdf_array_len(ctx, obj);
- for (i = 0; i < len; i++)
- {
- int hidden = pdf_is_hidden_ocg(ctx, desc, rdb, event, pdf_array_get(ctx, obj, i));
- if ((combine & 1) == 0)
- hidden = !hidden;
- if (combine & 2)
- on &= hidden;
- else
- on |= hidden;
- }
- }
- else
- {
- on = pdf_is_hidden_ocg(ctx, desc, rdb, event, obj);
- if ((combine & 1) == 0)
- on = !on;
- }
- }
- fz_always(ctx)
- {
- pdf_unmark_obj(ctx, ocg);
- }
- fz_catch(ctx)
- {
- fz_rethrow(ctx);
- }
- return !on;
- }
- /* No idea what sort of object this is - be visible */
- return 0;
-}
-
static fz_image *
parse_inline_image(fz_context *ctx, pdf_csi *csi, fz_stream *stm)
{
@@ -530,7 +316,7 @@ pdf_process_Do(fz_context *ctx, pdf_processor *proc, pdf_csi *csi)
if (!pdf_is_name(ctx, subtype))
fz_throw(ctx, FZ_ERROR_GENERIC, "no XObject subtype specified");
- if (pdf_is_hidden_ocg(ctx, csi->doc->ocg, csi->rdb, proc->event, pdf_dict_get(ctx, xobj, PDF_NAME_OC)))
+ if (pdf_is_hidden_ocg(ctx, csi->doc->ocg, csi->rdb, proc->usage, pdf_dict_get(ctx, xobj, PDF_NAME_OC)))
return;
if (pdf_name_eq(ctx, subtype, PDF_NAME_Form))
@@ -726,7 +512,7 @@ pdf_process_BDC(fz_context *ctx, pdf_processor *proc, pdf_csi *csi)
if (!pdf_name_eq(ctx, pdf_dict_get(ctx, cooked, PDF_NAME_Type), PDF_NAME_OCG))
return;
- if (pdf_is_hidden_ocg(ctx, csi->doc->ocg, csi->rdb, proc->event, cooked))
+ if (pdf_is_hidden_ocg(ctx, csi->doc->ocg, csi->rdb, proc->usage, cooked))
++proc->hidden;
}
@@ -1263,18 +1049,18 @@ pdf_process_annot(fz_context *ctx, pdf_processor *proc, pdf_document *doc, pdf_p
if (flags & (PDF_ANNOT_IS_INVISIBLE | PDF_ANNOT_IS_HIDDEN))
return;
- if (proc->event)
+ if (proc->usage)
{
- if (!strcmp(proc->event, "Print") && !(flags & PDF_ANNOT_IS_PRINT))
+ if (!strcmp(proc->usage, "Print") && !(flags & PDF_ANNOT_IS_PRINT))
return;
- if (!strcmp(proc->event, "View") && (flags & PDF_ANNOT_IS_NO_VIEW))
+ if (!strcmp(proc->usage, "View") && (flags & PDF_ANNOT_IS_NO_VIEW))
return;
}
/* TODO: NoZoom and NoRotate */
/* XXX what resources, if any, to use for this check? */
- if (pdf_is_hidden_ocg(ctx, doc->ocg, NULL, proc->event, pdf_dict_get(ctx, annot->obj, PDF_NAME_OC)))
+ if (pdf_is_hidden_ocg(ctx, doc->ocg, NULL, proc->usage, pdf_dict_get(ctx, annot->obj, PDF_NAME_OC)))
return;
if (proc->op_q && proc->op_cm && proc->op_Do_form && proc->op_Q && annot->ap)