From da50c6f300e565c8eedf4ce252c44b5ddbb95cee Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Wed, 9 Nov 2016 17:41:43 +0000 Subject: Add pdf_layer configuration API. Add API to: * allow enumeration of layer configs (OCCDs) within PDF files. * allow selection of layer configs. * allow enumeration of the "UI" (or "Human readable") form of layer configs. * allow selection/toggling of entries in the UI. --- source/pdf/pdf-imp.h | 9 + source/pdf/pdf-interpret.c | 226 +------------- source/pdf/pdf-layer.c | 715 +++++++++++++++++++++++++++++++++++++++++++++ source/pdf/pdf-op-run.c | 4 +- source/pdf/pdf-run.c | 20 +- source/pdf/pdf-xref.c | 161 +--------- 6 files changed, 746 insertions(+), 389 deletions(-) create mode 100644 source/pdf/pdf-imp.h create mode 100644 source/pdf/pdf-layer.c (limited to 'source/pdf') diff --git a/source/pdf/pdf-imp.h b/source/pdf/pdf-imp.h new file mode 100644 index 00000000..37605c51 --- /dev/null +++ b/source/pdf/pdf-imp.h @@ -0,0 +1,9 @@ +#ifndef MUPDF_PDF_IMP_H +#define MUPDF_PDF_IMP_H + +#include "mupdf/pdf.h" + +void pdf_read_ocg(fz_context *ctx, pdf_document *doc); +void pdf_drop_ocg(fz_context *ctx, pdf_document *doc); + +#endif 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