Mercurial > hgrepos > Python2 > PyMuPDF
view mupdf-source/source/pdf/pdf-run.c @ 40:aa33339d6b8a upstream
ADD: MuPDF v1.26.10: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.5.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Sat, 11 Oct 2025 11:31:38 +0200 |
| parents | b50eed0cc0ef |
| children |
line wrap: on
line source
// Copyright (C) 2004-2025 Artifex Software, Inc. // // This file is part of MuPDF. // // MuPDF is free software: you can redistribute it and/or modify it under the // terms of the GNU Affero General Public License as published by the Free // Software Foundation, either version 3 of the License, or (at your option) // any later version. // // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more // details. // // You should have received a copy of the GNU Affero General Public License // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html> // // Alternative licensing terms are available from the licensor. // For commercial licensing, see <https://www.artifex.com/> or contact // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, // CA 94129, USA, for further information. #include "mupdf/fitz.h" #include "pdf-annot-imp.h" static void pdf_run_annot_with_usage(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_annot *annot, fz_device *dev, fz_matrix ctm, const char *usage, fz_cookie *cookie) { fz_matrix page_ctm; fz_rect mediabox; pdf_processor *proc = NULL; fz_default_colorspaces *default_cs = NULL; int flags; int resources_pushed = 0; int struct_parent_num; pdf_obj *struct_parent; fz_var(proc); fz_var(default_cs); fz_var(resources_pushed); if (cookie && page->super.incomplete) cookie->incomplete = 1; pdf_annot_push_local_xref(ctx, annot); /* Widgets only get displayed if they have both a T and a TF flag, * apparently */ if (pdf_name_eq(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME(Subtype)), PDF_NAME(Widget))) { pdf_obj *ft = pdf_dict_get_inheritable(ctx, annot->obj, PDF_NAME(FT)); pdf_obj *t = pdf_dict_get_inheritable(ctx, annot->obj, PDF_NAME(T)); if (ft == NULL || t == NULL) { pdf_annot_pop_local_xref(ctx, annot); return; } } fz_try(ctx) { default_cs = pdf_load_default_colorspaces(ctx, doc, page); if (default_cs) fz_set_default_colorspaces(ctx, dev, default_cs); pdf_page_transform(ctx, page, &mediabox, &page_ctm); flags = pdf_dict_get_int(ctx, annot->obj, PDF_NAME(F)); if (flags & PDF_ANNOT_IS_NO_ROTATE) { int rotate = pdf_dict_get_inheritable_int(ctx, page->obj, PDF_NAME(Rotate)); fz_rect rect = pdf_dict_get_rect(ctx, annot->obj, PDF_NAME(Rect)); fz_point tp = fz_transform_point_xy(rect.x0, rect.y1, page_ctm); page_ctm = fz_concat(page_ctm, fz_translate(-tp.x, -tp.y)); page_ctm = fz_concat(page_ctm, fz_rotate(-rotate)); page_ctm = fz_concat(page_ctm, fz_translate(tp.x, tp.y)); } ctm = fz_concat(page_ctm, ctm); struct_parent = pdf_dict_getl(ctx, page->obj, PDF_NAME(StructParent), NULL); struct_parent_num = pdf_to_int_default(ctx, struct_parent, -1); proc = pdf_new_run_processor(ctx, page->doc, dev, ctm, struct_parent_num, usage, NULL, default_cs, cookie, NULL, NULL); pdf_processor_push_resources(ctx, proc, pdf_page_resources(ctx, annot->page)); resources_pushed = 1; pdf_process_annot(ctx, proc, annot, cookie); pdf_close_processor(ctx, proc); } fz_always(ctx) { if (resources_pushed) pdf_processor_pop_resources(ctx, proc); pdf_drop_processor(ctx, proc); fz_drop_default_colorspaces(ctx, default_cs); pdf_annot_pop_local_xref(ctx, annot); } fz_catch(ctx) fz_rethrow(ctx); } static fz_rect pdf_page_cropbox(fz_context *ctx, pdf_page *page) { pdf_obj *obj = pdf_dict_get_inheritable(ctx, page->obj, PDF_NAME(CropBox)); if (!obj) obj = pdf_dict_get_inheritable(ctx, page->obj, PDF_NAME(MediaBox)); return pdf_to_rect(ctx, obj); } static fz_rect pdf_page_mediabox(fz_context *ctx, pdf_page *page) { return pdf_dict_get_inheritable_rect(ctx, page->obj, PDF_NAME(MediaBox)); } static void pdf_run_page_contents_with_usage_imp(fz_context *ctx, pdf_document *doc, pdf_page *page, fz_device *dev, fz_matrix ctm, const char *usage, fz_cookie *cookie) { fz_matrix page_ctm; pdf_obj *resources; pdf_obj *contents; fz_rect fitzbox; fz_rect mediabox, cropbox; pdf_processor *proc = NULL; fz_default_colorspaces *default_cs = NULL; fz_colorspace *colorspace = NULL; fz_path *path = NULL; int struct_parent_num; pdf_obj *struct_parent; fz_var(proc); fz_var(colorspace); fz_var(default_cs); fz_var(path); if (cookie && page->super.incomplete) cookie->incomplete = 1; fz_try(ctx) { default_cs = pdf_load_default_colorspaces(ctx, doc, page); if (default_cs) fz_set_default_colorspaces(ctx, dev, default_cs); pdf_page_transform(ctx, page, &fitzbox, &page_ctm); ctm = fz_concat(page_ctm, ctm); fitzbox = fz_transform_rect(fitzbox, ctm); resources = pdf_page_resources(ctx, page); contents = pdf_page_contents(ctx, page); mediabox = pdf_page_mediabox(ctx, page); cropbox = pdf_page_cropbox(ctx, page); if (page->transparency) { pdf_obj *group = pdf_page_group(ctx, page); if (group) { pdf_obj *cs = pdf_dict_get(ctx, group, PDF_NAME(CS)); if (cs) { fz_try(ctx) colorspace = pdf_load_colorspace(ctx, cs); fz_catch(ctx) { fz_rethrow_if(ctx, FZ_ERROR_TRYLATER); fz_rethrow_if(ctx, FZ_ERROR_SYSTEM); fz_report_error(ctx); fz_warn(ctx, "Ignoring Page blending colorspace."); } if (!fz_is_valid_blend_colorspace(ctx, colorspace)) { fz_warn(ctx, "Ignoring invalid Page blending colorspace: %s.", colorspace->name); fz_drop_colorspace(ctx, colorspace); colorspace = NULL; } } } else colorspace = fz_keep_colorspace(ctx, fz_default_output_intent(ctx, default_cs)); fz_begin_group(ctx, dev, fitzbox, colorspace, 1, 0, 0, 1); } struct_parent = pdf_dict_get(ctx, page->obj, PDF_NAME(StructParents)); struct_parent_num = pdf_to_int_default(ctx, struct_parent, -1); /* Clip content to CropBox if it is smaller than the MediaBox */ if (cropbox.x0 > mediabox.x0 || cropbox.x1 < mediabox.x1 || cropbox.y0 > mediabox.y0 || cropbox.y1 < mediabox.y1) { path = fz_new_path(ctx); fz_rectto(ctx, path, cropbox.x0, cropbox.y0, cropbox.x1, cropbox.y1); fz_clip_path(ctx, dev, path, 1, ctm, fz_infinite_rect); } proc = pdf_new_run_processor(ctx, page->doc, dev, ctm, struct_parent_num, usage, NULL, default_cs, cookie, NULL, NULL); pdf_process_contents(ctx, proc, doc, resources, contents, cookie, NULL); pdf_close_processor(ctx, proc); if (cropbox.x0 > mediabox.x0 || cropbox.x1 < mediabox.x1 || cropbox.y0 > mediabox.y0 || cropbox.y1 < mediabox.y1) { fz_pop_clip(ctx, dev); } if (page->transparency) { fz_end_group(ctx, dev); } } fz_always(ctx) { fz_drop_path(ctx, path); pdf_drop_processor(ctx, proc); fz_drop_colorspace(ctx, colorspace); fz_drop_default_colorspaces(ctx, default_cs); } fz_catch(ctx) { fz_rethrow(ctx); } } void pdf_run_page_contents_with_usage(fz_context *ctx, pdf_page *page, fz_device *dev, fz_matrix ctm, const char *usage, fz_cookie *cookie) { pdf_document *doc = page->doc; int nocache; nocache = !!(dev->hints & FZ_NO_CACHE); if (nocache) pdf_mark_xref(ctx, doc); fz_try(ctx) { pdf_run_page_contents_with_usage_imp(ctx, doc, page, dev, ctm, usage, cookie); } fz_always(ctx) { if (nocache) pdf_clear_xref_to_mark(ctx, doc); } fz_catch(ctx) { fz_rethrow(ctx); } } void pdf_run_page_contents(fz_context *ctx, pdf_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie) { pdf_run_page_contents_with_usage(ctx, page, dev, ctm, "View", cookie); } void pdf_run_annot(fz_context *ctx, pdf_annot *annot, fz_device *dev, fz_matrix ctm, fz_cookie *cookie) { pdf_page *page = annot->page; pdf_document *doc; int nocache; if (!page) fz_throw(ctx, FZ_ERROR_ARGUMENT, "annotation not bound to any page"); doc = page->doc; nocache = !!(dev->hints & FZ_NO_CACHE); if (nocache) pdf_mark_xref(ctx, doc); fz_try(ctx) { pdf_run_annot_with_usage(ctx, doc, page, annot, dev, ctm, "View", cookie); } fz_always(ctx) { if (nocache) pdf_clear_xref_to_mark(ctx, doc); } fz_catch(ctx) { fz_rethrow(ctx); } } static void pdf_run_page_widgets_with_usage_imp(fz_context *ctx, pdf_document *doc, pdf_page *page, fz_device *dev, fz_matrix ctm, const char *usage, fz_cookie *cookie) { pdf_annot *widget; if (cookie && cookie->progress_max != (size_t)-1) { int count = 1; for (widget = page->widgets; widget; widget = widget->next) count++; cookie->progress_max += count; } for (widget = page->widgets; widget; widget = widget->next) { /* Check the cookie for aborting */ if (cookie) { if (cookie->abort) break; cookie->progress++; } pdf_run_annot_with_usage(ctx, doc, page, widget, dev, ctm, usage, cookie); } } static void pdf_run_page_annots_with_usage_imp(fz_context *ctx, pdf_document *doc, pdf_page *page, fz_device *dev, fz_matrix ctm, const char *usage, fz_cookie *cookie) { pdf_annot *annot; if (cookie && cookie->progress_max != (size_t)-1) { int count = 1; for (annot = page->annots; annot; annot = annot->next) count++; cookie->progress_max += count; } for (annot = page->annots; annot; annot = annot->next) { /* Check the cookie for aborting */ if (cookie) { if (cookie->abort) break; cookie->progress++; } pdf_run_annot_with_usage(ctx, doc, page, annot, dev, ctm, usage, cookie); } } void pdf_run_page_annots_with_usage(fz_context *ctx, pdf_page *page, fz_device *dev, fz_matrix ctm, const char *usage, fz_cookie *cookie) { pdf_document *doc = page->doc; int nocache; nocache = !!(dev->hints & FZ_NO_CACHE); if (nocache) pdf_mark_xref(ctx, doc); fz_try(ctx) { pdf_run_page_annots_with_usage_imp(ctx, doc, page, dev, ctm, usage, cookie); } fz_always(ctx) { if (nocache) pdf_clear_xref_to_mark(ctx, doc); } fz_catch(ctx) { fz_rethrow(ctx); } } void pdf_run_page_annots(fz_context *ctx, pdf_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie) { pdf_run_page_annots_with_usage(ctx, page, dev, ctm, "View", cookie); } void pdf_run_page_widgets_with_usage(fz_context *ctx, pdf_page *page, fz_device *dev, fz_matrix ctm, const char *usage, fz_cookie *cookie) { pdf_document *doc = page->doc; int nocache; nocache = !!(dev->hints & FZ_NO_CACHE); if (nocache) pdf_mark_xref(ctx, doc); fz_try(ctx) { pdf_run_page_widgets_with_usage_imp(ctx, doc, page, dev, ctm, usage, cookie); } fz_always(ctx) { if (nocache) pdf_clear_xref_to_mark(ctx, doc); } fz_catch(ctx) { fz_rethrow(ctx); } } void pdf_run_page_widgets(fz_context *ctx, pdf_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie) { pdf_run_page_widgets_with_usage(ctx, page, dev, ctm, "View", cookie); } void pdf_run_page_with_usage(fz_context *ctx, pdf_page *page, fz_device *dev, fz_matrix ctm, const char *usage, fz_cookie *cookie) { pdf_document *doc = page->doc; int nocache = !!(dev->hints & FZ_NO_CACHE); if (nocache) pdf_mark_xref(ctx, doc); fz_try(ctx) { pdf_run_page_contents_with_usage_imp(ctx, doc, page, dev, ctm, usage, cookie); pdf_run_page_annots_with_usage_imp(ctx, doc, page, dev, ctm, usage, cookie); pdf_run_page_widgets_with_usage_imp(ctx, doc, page, dev, ctm, usage, cookie); } fz_always(ctx) { if (nocache) pdf_clear_xref_to_mark(ctx, doc); } fz_catch(ctx) { fz_rethrow(ctx); } } void pdf_run_page(fz_context *ctx, pdf_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie) { pdf_run_page_with_usage(ctx, page, dev, ctm, "View", cookie); } void pdf_run_glyph(fz_context *ctx, pdf_document *doc, pdf_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate, fz_default_colorspaces *default_cs, void *fill_gstate, void *stroke_gstate) { pdf_processor *proc; proc = pdf_new_run_processor(ctx, doc, dev, ctm, -1, "View", gstate, default_cs, NULL, fill_gstate, stroke_gstate); fz_try(ctx) { pdf_process_glyph(ctx, proc, doc, resources, contents); pdf_close_processor(ctx, proc); } fz_always(ctx) pdf_drop_processor(ctx, proc); fz_catch(ctx) fz_rethrow(ctx); } fz_structure pdf_structure_type(fz_context *ctx, pdf_obj *role_map, pdf_obj *tag) { /* Perform Structure mapping to go from tag to standard. */ if (role_map) { pdf_obj *o = pdf_dict_get(ctx, role_map, tag); if (o) tag = o; } if (pdf_name_eq(ctx, tag, PDF_NAME(Document))) return FZ_STRUCTURE_DOCUMENT; if (pdf_name_eq(ctx, tag, PDF_NAME(Part))) return FZ_STRUCTURE_PART; if (pdf_name_eq(ctx, tag, PDF_NAME(Art))) return FZ_STRUCTURE_ART; if (pdf_name_eq(ctx, tag, PDF_NAME(Sect))) return FZ_STRUCTURE_SECT; if (pdf_name_eq(ctx, tag, PDF_NAME(Div))) return FZ_STRUCTURE_DIV; if (pdf_name_eq(ctx, tag, PDF_NAME(BlockQuote))) return FZ_STRUCTURE_BLOCKQUOTE; if (pdf_name_eq(ctx, tag, PDF_NAME(Caption))) return FZ_STRUCTURE_CAPTION; if (pdf_name_eq(ctx, tag, PDF_NAME(TOC))) return FZ_STRUCTURE_TOC; if (pdf_name_eq(ctx, tag, PDF_NAME(TOCI))) return FZ_STRUCTURE_TOCI; if (pdf_name_eq(ctx, tag, PDF_NAME(Index))) return FZ_STRUCTURE_INDEX; if (pdf_name_eq(ctx, tag, PDF_NAME(NonStruct))) return FZ_STRUCTURE_NONSTRUCT; if (pdf_name_eq(ctx, tag, PDF_NAME(Private))) return FZ_STRUCTURE_PRIVATE; /* Grouping elements (PDF 2.0 - Table 364) */ if (pdf_name_eq(ctx, tag, PDF_NAME(DocumentFragment))) return FZ_STRUCTURE_DOCUMENTFRAGMENT; /* Grouping elements (PDF 2.0 - Table 365) */ if (pdf_name_eq(ctx, tag, PDF_NAME(Aside))) return FZ_STRUCTURE_ASIDE; /* Grouping elements (PDF 2.0 - Table 366) */ if (pdf_name_eq(ctx, tag, PDF_NAME(Title))) return FZ_STRUCTURE_TITLE; if (pdf_name_eq(ctx, tag, PDF_NAME(FENote))) return FZ_STRUCTURE_FENOTE; /* Grouping elements (PDF 2.0 - Table 367) */ if (pdf_name_eq(ctx, tag, PDF_NAME(Sub))) return FZ_STRUCTURE_SUB; /* Paragraphlike elements (PDF 1.7 - Table 10.21) */ if (pdf_name_eq(ctx, tag, PDF_NAME(P))) return FZ_STRUCTURE_P; if (pdf_name_eq(ctx, tag, PDF_NAME(H))) return FZ_STRUCTURE_H; if (pdf_name_eq(ctx, tag, PDF_NAME(H1))) return FZ_STRUCTURE_H1; if (pdf_name_eq(ctx, tag, PDF_NAME(H2))) return FZ_STRUCTURE_H2; if (pdf_name_eq(ctx, tag, PDF_NAME(H3))) return FZ_STRUCTURE_H3; if (pdf_name_eq(ctx, tag, PDF_NAME(H4))) return FZ_STRUCTURE_H4; if (pdf_name_eq(ctx, tag, PDF_NAME(H5))) return FZ_STRUCTURE_H5; if (pdf_name_eq(ctx, tag, PDF_NAME(H6))) return FZ_STRUCTURE_H6; /* List elements (PDF 1.7 - Table 10.23) */ if (pdf_name_eq(ctx, tag, PDF_NAME(L))) return FZ_STRUCTURE_LIST; if (pdf_name_eq(ctx, tag, PDF_NAME(LI))) return FZ_STRUCTURE_LISTITEM; if (pdf_name_eq(ctx, tag, PDF_NAME(Lbl))) return FZ_STRUCTURE_LABEL; if (pdf_name_eq(ctx, tag, PDF_NAME(LBody))) return FZ_STRUCTURE_LISTBODY; /* Table elements (PDF 1.7 - Table 10.24) */ if (pdf_name_eq(ctx, tag, PDF_NAME(Table))) return FZ_STRUCTURE_TABLE; if (pdf_name_eq(ctx, tag, PDF_NAME(TR))) return FZ_STRUCTURE_TR; if (pdf_name_eq(ctx, tag, PDF_NAME(TH))) return FZ_STRUCTURE_TH; if (pdf_name_eq(ctx, tag, PDF_NAME(TD))) return FZ_STRUCTURE_TD; if (pdf_name_eq(ctx, tag, PDF_NAME(THead))) return FZ_STRUCTURE_THEAD; if (pdf_name_eq(ctx, tag, PDF_NAME(TBody))) return FZ_STRUCTURE_TBODY; if (pdf_name_eq(ctx, tag, PDF_NAME(TFoot))) return FZ_STRUCTURE_TFOOT; /* Inline elements (PDF 1.7 - Table 10.25) */ if (pdf_name_eq(ctx, tag, PDF_NAME(Span))) return FZ_STRUCTURE_SPAN; if (pdf_name_eq(ctx, tag, PDF_NAME(Quote))) return FZ_STRUCTURE_QUOTE; if (pdf_name_eq(ctx, tag, PDF_NAME(Note))) return FZ_STRUCTURE_NOTE; if (pdf_name_eq(ctx, tag, PDF_NAME(Reference))) return FZ_STRUCTURE_REFERENCE; if (pdf_name_eq(ctx, tag, PDF_NAME(BibEntry))) return FZ_STRUCTURE_BIBENTRY; if (pdf_name_eq(ctx, tag, PDF_NAME(Code))) return FZ_STRUCTURE_CODE; if (pdf_name_eq(ctx, tag, PDF_NAME(Link))) return FZ_STRUCTURE_LINK; if (pdf_name_eq(ctx, tag, PDF_NAME(Annot))) return FZ_STRUCTURE_ANNOT; /* Inline elements (PDF 2.0 - Table 368) */ if (pdf_name_eq(ctx, tag, PDF_NAME(Em))) return FZ_STRUCTURE_EM; if (pdf_name_eq(ctx, tag, PDF_NAME(Strong))) return FZ_STRUCTURE_STRONG; /* Ruby inline element (PDF 1.7 - Table 10.26) */ if (pdf_name_eq(ctx, tag, PDF_NAME(Ruby))) return FZ_STRUCTURE_RUBY; if (pdf_name_eq(ctx, tag, PDF_NAME(RB))) return FZ_STRUCTURE_RB; if (pdf_name_eq(ctx, tag, PDF_NAME(RT))) return FZ_STRUCTURE_RT; if (pdf_name_eq(ctx, tag, PDF_NAME(RP))) return FZ_STRUCTURE_RP; /* Warichu inline element (PDF 1.7 - Table 10.26) */ if (pdf_name_eq(ctx, tag, PDF_NAME(Warichu))) return FZ_STRUCTURE_WARICHU; if (pdf_name_eq(ctx, tag, PDF_NAME(WT))) return FZ_STRUCTURE_WT; if (pdf_name_eq(ctx, tag, PDF_NAME(WP))) return FZ_STRUCTURE_WP; /* Illustration elements (PDF 1.7 - Table 10.27) */ if (pdf_name_eq(ctx, tag, PDF_NAME(Figure))) return FZ_STRUCTURE_FIGURE; if (pdf_name_eq(ctx, tag, PDF_NAME(Formula))) return FZ_STRUCTURE_FORMULA; if (pdf_name_eq(ctx, tag, PDF_NAME(Form))) return FZ_STRUCTURE_FORM; /* Artifact structure type (PDF 2.0 - Table 375) */ if (pdf_name_eq(ctx, tag, PDF_NAME(Artifact))) return FZ_STRUCTURE_ARTIFACT; return FZ_STRUCTURE_INVALID; } /* The recursive descent of the structure tree uses an fz_try at each level. * At the risk of creating a foot cannon... "no one will need more than ~64 * levels of structure tree". */ static void run_ds(fz_context *ctx, fz_device *dev, pdf_obj *role_map, pdf_obj *obj, int idx, fz_cookie *cookie) { pdf_obj *k; int i, n; /* Check the cookie for aborting */ if (cookie) { if (cookie->abort) return; cookie->progress++; } if (pdf_is_number(ctx, obj)) { /* A marked-content identifier denoting a marked content sequence. WHAT? */ return; } if (pdf_mark_obj(ctx, obj)) return; fz_try(ctx) { fz_structure standard; pdf_obj *tag = pdf_dict_get(ctx, obj, PDF_NAME(S)); if (!tag) break; standard = pdf_structure_type(ctx, role_map, tag); if (standard == FZ_STRUCTURE_INVALID) break; fz_begin_structure(ctx, dev, standard, pdf_to_name(ctx, tag), idx); k = pdf_dict_get(ctx, obj, PDF_NAME(K)); if (k) { n = pdf_array_len(ctx, k); if (n == 0) run_ds(ctx, dev, role_map, k, 0, cookie); else { for (i = 0; i < n; i++) run_ds(ctx, dev, role_map, pdf_array_get(ctx, k, i), i, cookie); } } fz_end_structure(ctx, dev); } fz_always(ctx) pdf_unmark_obj(ctx, obj); fz_catch(ctx) fz_rethrow(ctx); } void pdf_run_document_structure(fz_context *ctx, pdf_document *doc, fz_device *dev, fz_cookie *cookie) { int nocache; int marked = 0; pdf_obj *st, *rm, *k; fz_var(marked); nocache = !!(dev->hints & FZ_NO_CACHE); if (nocache) pdf_mark_xref(ctx, doc); fz_try(ctx) { st = pdf_dict_get(ctx, pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME(Root)), PDF_NAME(StructTreeRoot)); rm = pdf_dict_get(ctx, st, PDF_NAME(RoleMap)); if (pdf_mark_obj(ctx, st)) break; marked = 1; k = pdf_dict_get(ctx, st, PDF_NAME(K)); if (k) { int n = pdf_array_len(ctx, k); if (n == 0) run_ds(ctx, dev, rm, k, 0, cookie); else { int i; for (i = 0; i < n; i++) run_ds(ctx, dev, rm, pdf_array_get(ctx, k, i), i, cookie); } } } fz_always(ctx) { if (marked) pdf_unmark_obj(ctx, st); if (nocache) pdf_clear_xref_to_mark(ctx, doc); } fz_catch(ctx) fz_rethrow(ctx); }
