#include "mupdf/pdf.h" void * pdf_new_processor(fz_context *ctx, int size) { return Memento_label(fz_calloc(ctx, 1, size), "pdf_processor"); } void pdf_drop_processor(fz_context *ctx, pdf_processor *proc) { if (proc && proc->drop_imp) proc->drop_imp(ctx, proc); fz_free(ctx, proc); } static void pdf_init_csi(fz_context *ctx, pdf_csi *csi, pdf_document *doc, pdf_obj *rdb, pdf_lexbuf *buf, fz_cookie *cookie) { memset(csi, 0, sizeof *csi); csi->doc = doc; csi->rdb = rdb; csi->buf = buf; csi->cookie = cookie; } static void pdf_clear_stack(fz_context *ctx, pdf_csi *csi) { int i; pdf_drop_obj(ctx, csi->obj); csi->obj = NULL; csi->name[0] = 0; csi->string_len = 0; for (i = 0; i < csi->top; i++) csi->stack[i] = 0; csi->top = 0; } static pdf_font_desc * load_font_or_hail_mary(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, pdf_obj *font, int depth, fz_cookie *cookie) { pdf_font_desc *desc; fz_try(ctx) { desc = pdf_load_font(ctx, doc, rdb, font, depth); } fz_catch(ctx) { if (fz_caught(ctx) == FZ_ERROR_TRYLATER && cookie && cookie->incomplete_ok) { desc = NULL; cookie->incomplete++; } else { fz_rethrow(ctx); } } if (desc == NULL) desc = pdf_load_hail_mary_font(ctx, doc); 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 gen = pdf_to_gen(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 && desc->ocgs[i].gen == gen) { 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