Mercurial > hgrepos > Python2 > PyMuPDF
diff mupdf-source/source/fitz/device.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mupdf-source/source/fitz/device.c Mon Sep 15 11:43:07 2025 +0200 @@ -0,0 +1,910 @@ +// 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 <string.h> + +fz_device * +fz_new_device_of_size(fz_context *ctx, int size) +{ + fz_device *dev = Memento_label(fz_calloc(ctx, 1, size), "fz_device"); + dev->refs = 1; + return dev; +} + +static void +fz_disable_device(fz_context *ctx, fz_device *dev) +{ + dev->close_device = NULL; + dev->fill_path = NULL; + dev->stroke_path = NULL; + dev->clip_path = NULL; + dev->clip_stroke_path = NULL; + dev->fill_text = NULL; + dev->stroke_text = NULL; + dev->clip_text = NULL; + dev->clip_stroke_text = NULL; + dev->ignore_text = NULL; + dev->fill_shade = NULL; + dev->fill_image = NULL; + dev->fill_image_mask = NULL; + dev->clip_image_mask = NULL; + dev->pop_clip = NULL; + dev->begin_mask = NULL; + dev->end_mask = NULL; + dev->begin_group = NULL; + dev->end_group = NULL; + dev->begin_tile = NULL; + dev->end_tile = NULL; + dev->render_flags = NULL; + dev->set_default_colorspaces = NULL; + dev->begin_layer = NULL; + dev->end_layer = NULL; + dev->begin_structure = NULL; + dev->end_structure = NULL; + dev->begin_metatext = NULL; + dev->end_metatext = NULL; +} + +void +fz_close_device(fz_context *ctx, fz_device *dev) +{ + if (dev == NULL) + return; + + fz_try(ctx) + { + if (dev->close_device) + dev->close_device(ctx, dev); + } + fz_always(ctx) + fz_disable_device(ctx, dev); + fz_catch(ctx) + fz_rethrow(ctx); +} + +fz_device * +fz_keep_device(fz_context *ctx, fz_device *dev) +{ + return fz_keep_imp(ctx, dev, &dev->refs); +} + +void +fz_drop_device(fz_context *ctx, fz_device *dev) +{ + if (fz_drop_imp(ctx, dev, &dev->refs)) + { + if (dev->close_device) + fz_warn(ctx, "dropping unclosed device"); + if (dev->drop_device) + dev->drop_device(ctx, dev); + fz_free(ctx, dev->container); + fz_free(ctx, dev); + } +} + +void +fz_enable_device_hints(fz_context *ctx, fz_device *dev, int hints) +{ + dev->hints |= hints; +} + +void +fz_disable_device_hints(fz_context *ctx, fz_device *dev, int hints) +{ + dev->hints &= ~hints; +} + +static void +push_clip_stack(fz_context *ctx, fz_device *dev, fz_rect rect, int type) +{ + if (dev->container_len == dev->container_cap) + { + int newmax = dev->container_cap * 2; + if (newmax == 0) + newmax = 4; + dev->container = fz_realloc_array(ctx, dev->container, newmax, fz_device_container_stack); + dev->container_cap = newmax; + } + if (dev->container_len == 0) + dev->container[0].scissor = rect; + else + { + dev->container[dev->container_len].scissor = fz_intersect_rect(dev->container[dev->container_len-1].scissor, rect); + } + dev->container[dev->container_len].type = type; + dev->container[dev->container_len].user = 0; + dev->container_len++; +} + +static void +pop_clip_stack(fz_context *ctx, fz_device *dev, int type) +{ + if (dev->container_len == 0 || dev->container[dev->container_len-1].type != type) + { + fz_disable_device(ctx, dev); + fz_throw(ctx, FZ_ERROR_ARGUMENT, "device calls unbalanced"); + } + dev->container_len--; +} + +static void +pop_push_clip_stack(fz_context *ctx, fz_device *dev, int pop_type, int push_type) +{ + if (dev->container_len == 0 || dev->container[dev->container_len-1].type != pop_type) + { + fz_disable_device(ctx, dev); + fz_throw(ctx, FZ_ERROR_ARGUMENT, "device calls unbalanced"); + } + dev->container[dev->container_len-1].type = push_type; +} + +void +fz_fill_path(fz_context *ctx, fz_device *dev, const fz_path *path, int even_odd, fz_matrix ctm, + fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params) +{ + if (dev->fill_path) + { + fz_try(ctx) + dev->fill_path(ctx, dev, path, even_odd, ctm, colorspace, color, alpha, color_params); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_stroke_path(fz_context *ctx, fz_device *dev, const fz_path *path, const fz_stroke_state *stroke, fz_matrix ctm, + fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params) +{ + if (dev->stroke_path) + { + fz_try(ctx) + dev->stroke_path(ctx, dev, path, stroke, ctm, colorspace, color, alpha, color_params); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_clip_path(fz_context *ctx, fz_device *dev, const fz_path *path, int even_odd, fz_matrix ctm, fz_rect scissor) +{ + fz_rect bbox = fz_bound_path(ctx, path, NULL, ctm); + bbox = fz_intersect_rect(bbox, scissor); + push_clip_stack(ctx, dev, bbox, fz_device_container_stack_is_clip); + + if (dev->clip_path) + { + fz_try(ctx) + dev->clip_path(ctx, dev, path, even_odd, ctm, scissor); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_clip_stroke_path(fz_context *ctx, fz_device *dev, const fz_path *path, const fz_stroke_state *stroke, fz_matrix ctm, fz_rect scissor) +{ + fz_rect bbox = fz_bound_path(ctx, path, stroke, ctm); + bbox = fz_intersect_rect(bbox, scissor); + push_clip_stack(ctx, dev, bbox, fz_device_container_stack_is_clip); + + if (dev->clip_stroke_path) + { + fz_try(ctx) + dev->clip_stroke_path(ctx, dev, path, stroke, ctm, scissor); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_fill_text(fz_context *ctx, fz_device *dev, const fz_text *text, fz_matrix ctm, + fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params) +{ + if (dev->fill_text) + { + fz_try(ctx) + dev->fill_text(ctx, dev, text, ctm, colorspace, color, alpha, color_params); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, fz_matrix ctm, + fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params) +{ + if (dev->stroke_text) + { + fz_try(ctx) + dev->stroke_text(ctx, dev, text, stroke, ctm, colorspace, color, alpha, color_params); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, fz_matrix ctm, fz_rect scissor) +{ + fz_rect bbox = fz_bound_text(ctx, text, NULL, ctm); + bbox = fz_intersect_rect(bbox, scissor); + push_clip_stack(ctx, dev, bbox, fz_device_container_stack_is_clip); + + if (dev->clip_text) + { + fz_try(ctx) + dev->clip_text(ctx, dev, text, ctm, scissor); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, fz_matrix ctm, fz_rect scissor) +{ + fz_rect bbox = fz_bound_text(ctx, text, stroke, ctm); + bbox = fz_intersect_rect(bbox, scissor); + push_clip_stack(ctx, dev, bbox, fz_device_container_stack_is_clip); + + if (dev->clip_stroke_text) + { + fz_try(ctx) + dev->clip_stroke_text(ctx, dev, text, stroke, ctm, scissor); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_ignore_text(fz_context *ctx, fz_device *dev, const fz_text *text, fz_matrix ctm) +{ + if (dev->ignore_text) + { + fz_try(ctx) + dev->ignore_text(ctx, dev, text, ctm); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_pop_clip(fz_context *ctx, fz_device *dev) +{ + pop_clip_stack(ctx, dev, fz_device_container_stack_is_clip); + + if (dev->pop_clip) + { + fz_try(ctx) + dev->pop_clip(ctx, dev); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_fill_shade(fz_context *ctx, fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha, fz_color_params color_params) +{ + if (dev->fill_shade) + { + fz_try(ctx) + dev->fill_shade(ctx, dev, shade, ctm, alpha, color_params); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_fill_image(fz_context *ctx, fz_device *dev, fz_image *image, fz_matrix ctm, float alpha, fz_color_params color_params) +{ + if (image->colorspace == NULL) + fz_throw(ctx, FZ_ERROR_ARGUMENT, "argument to fill image must be a color image"); + if (dev->fill_image) + { + fz_try(ctx) + dev->fill_image(ctx, dev, image, ctm, alpha, color_params); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_fill_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, fz_matrix ctm, + fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params) +{ + if (dev->fill_image_mask) + { + fz_try(ctx) + dev->fill_image_mask(ctx, dev, image, ctm, colorspace, color, alpha, color_params); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_clip_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, fz_matrix ctm, fz_rect scissor) +{ + fz_rect bbox = fz_transform_rect(fz_unit_rect, ctm); + bbox = fz_intersect_rect(bbox, scissor); + push_clip_stack(ctx, dev, bbox, fz_device_container_stack_is_clip); + + if (dev->clip_image_mask) + { + fz_try(ctx) + dev->clip_image_mask(ctx, dev, image, ctm, scissor); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_begin_mask(fz_context *ctx, fz_device *dev, fz_rect area, int luminosity, fz_colorspace *colorspace, const float *bc, fz_color_params color_params) +{ + push_clip_stack(ctx, dev, area, fz_device_container_stack_is_mask); + + if (dev->begin_mask) + { + fz_try(ctx) + dev->begin_mask(ctx, dev, area, luminosity, colorspace, bc, color_params); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_end_mask_tr(fz_context *ctx, fz_device *dev, fz_function *fn) +{ + pop_push_clip_stack(ctx, dev, fz_device_container_stack_is_mask, fz_device_container_stack_is_clip); + + if (dev->end_mask) + { + fz_try(ctx) + dev->end_mask(ctx, dev, fn); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_end_mask(fz_context *ctx, fz_device *dev) +{ + fz_end_mask_tr(ctx, dev, NULL); +} + +void +fz_begin_group(fz_context *ctx, fz_device *dev, fz_rect area, fz_colorspace *cs, int isolated, int knockout, int blendmode, float alpha) +{ + push_clip_stack(ctx, dev, area, fz_device_container_stack_is_group); + + if (dev->begin_group) + { + fz_try(ctx) + dev->begin_group(ctx, dev, area, cs, isolated, knockout, blendmode, alpha); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_end_group(fz_context *ctx, fz_device *dev) +{ + pop_clip_stack(ctx, dev, fz_device_container_stack_is_group); + + if (dev->end_group) + { + fz_try(ctx) + dev->end_group(ctx, dev); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_begin_tile(fz_context *ctx, fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm) +{ + (void)fz_begin_tile_id(ctx, dev, area, view, xstep, ystep, ctm, 0); +} + +int +fz_begin_tile_id(fz_context *ctx, fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm, int id) +{ + return fz_begin_tile_tid(ctx, dev, area, view, xstep, ystep, ctm, id, 0); +} + +int +fz_begin_tile_tid(fz_context *ctx, fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm, int id, int doc_id) +{ + int result = 0; + + push_clip_stack(ctx, dev, area, fz_device_container_stack_is_tile); + + if (xstep < 0) + xstep = -xstep; + if (ystep < 0) + ystep = -ystep; + if (dev->begin_tile) + { + fz_try(ctx) + result = dev->begin_tile(ctx, dev, area, view, xstep, ystep, ctm, id, doc_id); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } + + return result; +} + +void +fz_end_tile(fz_context *ctx, fz_device *dev) +{ + pop_clip_stack(ctx, dev, fz_device_container_stack_is_tile); + + if (dev->end_tile) + { + fz_try(ctx) + dev->end_tile(ctx, dev); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_render_flags(fz_context *ctx, fz_device *dev, int set, int clear) +{ + if (dev->render_flags) + { + fz_try(ctx) + dev->render_flags(ctx, dev, set, clear); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void +fz_set_default_colorspaces(fz_context *ctx, fz_device *dev, fz_default_colorspaces *default_cs) +{ + if (dev->set_default_colorspaces) + { + fz_try(ctx) + dev->set_default_colorspaces(ctx, dev, default_cs); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void fz_begin_layer(fz_context *ctx, fz_device *dev, const char *layer_name) +{ + if (dev->begin_layer) + { + fz_try(ctx) + dev->begin_layer(ctx, dev, layer_name); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void fz_end_layer(fz_context *ctx, fz_device *dev) +{ + if (dev->end_layer) + { + fz_try(ctx) + dev->end_layer(ctx, dev); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void fz_begin_structure(fz_context *ctx, fz_device *dev, fz_structure str, const char *raw, int idx) +{ + if (dev->begin_structure) + { + fz_try(ctx) + dev->begin_structure(ctx, dev, str, raw, idx); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void fz_end_structure(fz_context *ctx, fz_device *dev) +{ + if (dev->end_structure) + { + fz_try(ctx) + dev->end_structure(ctx, dev); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void fz_begin_metatext(fz_context *ctx, fz_device *dev, fz_metatext meta, const char *meta_text) +{ + if (dev->begin_metatext) + { + fz_try(ctx) + dev->begin_metatext(ctx, dev, meta, meta_text); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +void fz_end_metatext(fz_context *ctx, fz_device *dev) +{ + if (dev->end_metatext) + { + fz_try(ctx) + dev->end_metatext(ctx, dev); + fz_catch(ctx) + { + fz_disable_device(ctx, dev); + fz_rethrow(ctx); + } + } +} + +fz_rect +fz_device_current_scissor(fz_context *ctx, fz_device *dev) +{ + if (dev->container_len > 0) + return dev->container[dev->container_len-1].scissor; + return fz_infinite_rect; +} + +const char * +fz_structure_to_string(fz_structure type) +{ + switch (type) + { + default: + return "Invalid"; + case FZ_STRUCTURE_DOCUMENT: + return "Document"; + case FZ_STRUCTURE_PART: + return "Part"; + case FZ_STRUCTURE_ART: + return "Art"; + case FZ_STRUCTURE_SECT: + return "Sect"; + case FZ_STRUCTURE_DIV: + return "Div"; + case FZ_STRUCTURE_BLOCKQUOTE: + return "BlockQuote"; + case FZ_STRUCTURE_CAPTION: + return "Caption"; + case FZ_STRUCTURE_TOC: + return "TOC"; + case FZ_STRUCTURE_TOCI: + return "TOCI"; + case FZ_STRUCTURE_INDEX: + return "Index"; + case FZ_STRUCTURE_NONSTRUCT: + return "NonDtruct"; + case FZ_STRUCTURE_PRIVATE: + return "Private"; + /* Grouping elements (PDF 2.0 - Table 364) */ + case FZ_STRUCTURE_DOCUMENTFRAGMENT: + return "DocumentFragment"; + /* Grouping elements (PDF 2.0 - Table 365) */ + case FZ_STRUCTURE_ASIDE: + return "Aside"; + /* Grouping elements (PDF 2.0 - Table 366) */ + case FZ_STRUCTURE_TITLE: + return "Title"; + case FZ_STRUCTURE_FENOTE: + return "FENote"; + /* Grouping elements (PDF 2.0 - Table 367) */ + case FZ_STRUCTURE_SUB: + return "Sub"; + + /* Paragraphlike elements (PDF 1.7 - Table 10.21) */ + case FZ_STRUCTURE_P: + return "P"; + case FZ_STRUCTURE_H: + return "H"; + case FZ_STRUCTURE_H1: + return "H1"; + case FZ_STRUCTURE_H2: + return "H2"; + case FZ_STRUCTURE_H3: + return "H3"; + case FZ_STRUCTURE_H4: + return "H4"; + case FZ_STRUCTURE_H5: + return "H5"; + case FZ_STRUCTURE_H6: + return "H6"; + + /* List elements (PDF 1.7 - Table 10.23) */ + case FZ_STRUCTURE_LIST: + return "L"; + case FZ_STRUCTURE_LISTITEM: + return "LI"; + case FZ_STRUCTURE_LABEL: + return "Lbl"; + case FZ_STRUCTURE_LISTBODY: + return "LBody"; + + /* Table elements (PDF 1.7 - Table 10.24) */ + case FZ_STRUCTURE_TABLE: + return "Table"; + case FZ_STRUCTURE_TR: + return "TR"; + case FZ_STRUCTURE_TH: + return "TH"; + case FZ_STRUCTURE_TD: + return "TD"; + case FZ_STRUCTURE_THEAD: + return "THead"; + case FZ_STRUCTURE_TBODY: + return "TBody"; + case FZ_STRUCTURE_TFOOT: + return "TFoot"; + + /* Inline elements (PDF 1.7 - Table 10.25) */ + case FZ_STRUCTURE_SPAN: + return "Span"; + case FZ_STRUCTURE_QUOTE: + return "Quote"; + case FZ_STRUCTURE_NOTE: + return "Note"; + case FZ_STRUCTURE_REFERENCE: + return "Reference"; + case FZ_STRUCTURE_BIBENTRY: + return "BibEntry"; + case FZ_STRUCTURE_CODE: + return "Code"; + case FZ_STRUCTURE_LINK: + return "Link"; + case FZ_STRUCTURE_ANNOT: + return "Annot"; + /* Inline elements (PDF 2.0 - Table 368) */ + case FZ_STRUCTURE_EM: + return "Em"; + case FZ_STRUCTURE_STRONG: + return "Strong"; + + /* Ruby inline element (PDF 1.7 - Table 10.26) */ + case FZ_STRUCTURE_RUBY: + return "Ruby"; + case FZ_STRUCTURE_RB: + return "RB"; + case FZ_STRUCTURE_RT: + return "RT"; + case FZ_STRUCTURE_RP: + return "RP"; + + /* Warichu inline element (PDF 1.7 - Table 10.26) */ + case FZ_STRUCTURE_WARICHU: + return "Warichu"; + case FZ_STRUCTURE_WT: + return "WT"; + case FZ_STRUCTURE_WP: + return "WP"; + + /* Illustration elements (PDF 1.7 - Table 10.27) */ + case FZ_STRUCTURE_FIGURE: + return "Figure"; + case FZ_STRUCTURE_FORMULA: + return "Formula"; + case FZ_STRUCTURE_FORM: + return "Form"; + + /* Artifact structure type (PDF 2.0 - Table 375) */ + case FZ_STRUCTURE_ARTIFACT: + return "Artifact"; + } +} + +fz_structure +fz_structure_from_string(const char *str) +{ + if (!strcmp(str, "Document")) return FZ_STRUCTURE_DOCUMENT; + if (!strcmp(str, "Part")) return FZ_STRUCTURE_PART; + if (!strcmp(str, "Art")) return FZ_STRUCTURE_ART; + if (!strcmp(str, "Sect")) return FZ_STRUCTURE_SECT; + if (!strcmp(str, "Div")) return FZ_STRUCTURE_DIV; + if (!strcmp(str, "BlockQuote")) return FZ_STRUCTURE_BLOCKQUOTE; + if (!strcmp(str, "Caption")) return FZ_STRUCTURE_CAPTION; + if (!strcmp(str, "TOC")) return FZ_STRUCTURE_TOC; + if (!strcmp(str, "TOCI")) return FZ_STRUCTURE_TOCI; + if (!strcmp(str, "Index")) return FZ_STRUCTURE_INDEX; + if (!strcmp(str, "NonStruct")) return FZ_STRUCTURE_NONSTRUCT; + if (!strcmp(str, "Private")) return FZ_STRUCTURE_PRIVATE; + if (!strcmp(str, "P")) return FZ_STRUCTURE_P; + if (!strcmp(str, "H")) return FZ_STRUCTURE_H; + if (!strcmp(str, "H1")) return FZ_STRUCTURE_H1; + if (!strcmp(str, "H2")) return FZ_STRUCTURE_H2; + if (!strcmp(str, "H3")) return FZ_STRUCTURE_H3; + if (!strcmp(str, "H4")) return FZ_STRUCTURE_H4; + if (!strcmp(str, "H5")) return FZ_STRUCTURE_H5; + if (!strcmp(str, "H6")) return FZ_STRUCTURE_H6; + if (!strcmp(str, "L")) return FZ_STRUCTURE_LIST; + if (!strcmp(str, "LI")) return FZ_STRUCTURE_LISTITEM; + if (!strcmp(str, "Lbl")) return FZ_STRUCTURE_LABEL; + if (!strcmp(str, "LBody")) return FZ_STRUCTURE_LISTBODY; + if (!strcmp(str, "Table")) return FZ_STRUCTURE_TABLE; + if (!strcmp(str, "TR")) return FZ_STRUCTURE_TR; + if (!strcmp(str, "TH")) return FZ_STRUCTURE_TH; + if (!strcmp(str, "TD")) return FZ_STRUCTURE_TD; + if (!strcmp(str, "THead")) return FZ_STRUCTURE_THEAD; + if (!strcmp(str, "TBody")) return FZ_STRUCTURE_TBODY; + if (!strcmp(str, "TFoot")) return FZ_STRUCTURE_TFOOT; + if (!strcmp(str, "Span")) return FZ_STRUCTURE_SPAN; + if (!strcmp(str, "Quote")) return FZ_STRUCTURE_QUOTE; + if (!strcmp(str, "Note")) return FZ_STRUCTURE_NOTE; + if (!strcmp(str, "Reference")) return FZ_STRUCTURE_REFERENCE; + if (!strcmp(str, "BibEntry")) return FZ_STRUCTURE_BIBENTRY; + if (!strcmp(str, "Code")) return FZ_STRUCTURE_CODE; + if (!strcmp(str, "Link")) return FZ_STRUCTURE_LINK; + if (!strcmp(str, "Annot")) return FZ_STRUCTURE_ANNOT; + if (!strcmp(str, "Ruby")) return FZ_STRUCTURE_RUBY; + if (!strcmp(str, "RB")) return FZ_STRUCTURE_RB; + if (!strcmp(str, "RT")) return FZ_STRUCTURE_RT; + if (!strcmp(str, "RP")) return FZ_STRUCTURE_RP; + if (!strcmp(str, "Warichu")) return FZ_STRUCTURE_WARICHU; + if (!strcmp(str, "WT")) return FZ_STRUCTURE_WT; + if (!strcmp(str, "WP")) return FZ_STRUCTURE_WP; + if (!strcmp(str, "Figure")) return FZ_STRUCTURE_FIGURE; + if (!strcmp(str, "Formula")) return FZ_STRUCTURE_FORMULA; + if (!strcmp(str, "Form")) return FZ_STRUCTURE_FORM; + return FZ_STRUCTURE_INVALID; +} + +fz_function * +fz_keep_function(fz_context *ctx, fz_function *func) +{ + return fz_keep_storable(ctx, &func->storable); +} + +void +fz_drop_function(fz_context *ctx, fz_function *func) +{ + fz_drop_storable(ctx, &func->storable); +} + +size_t +fz_function_size(fz_context *ctx, fz_function *func) +{ + return (func ? func->size : 0); +} + +void +fz_eval_function(fz_context *ctx, fz_function *func, const float *in, int inlen, float *out, int outlen) +{ + float fakein[FZ_FUNCTION_MAX_M]; + float fakeout[FZ_FUNCTION_MAX_N]; + int i; + + if (inlen < func->m) + { + for (i = 0; i < inlen; ++i) + fakein[i] = in[i]; + for (; i < func->m; ++i) + fakein[i] = 0; + in = fakein; + } + + if (outlen < func->n) + { + func->eval(ctx, func, in, fakeout); + for (i = 0; i < outlen; ++i) + out[i] = fakeout[i]; + } + else + { + func->eval(ctx, func, in, out); + for (i = func->n; i < outlen; ++i) + out[i] = 0; + } +} + +fz_function * +fz_new_function_of_size(fz_context *ctx, int size, size_t size2, int m, int n, fz_function_eval_fn *eval, fz_store_drop_fn *drop) +{ + fz_function *fn = fz_calloc(ctx, 1, size); + + FZ_INIT_STORABLE(fn, 1, drop); + fn->eval = eval; + fn->m = m; + fn->n = n; + + return fn; +}
