diff options
Diffstat (limited to 'Build/source/texk/dvipdf-x/src/epdf.c')
-rw-r--r-- | Build/source/texk/dvipdf-x/src/epdf.c | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/Build/source/texk/dvipdf-x/src/epdf.c b/Build/source/texk/dvipdf-x/src/epdf.c new file mode 100644 index 00000000000..17fdcf3ee26 --- /dev/null +++ b/Build/source/texk/dvipdf-x/src/epdf.c @@ -0,0 +1,208 @@ +/* + + This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +*/ + +/* + * Concatinating content streams are only supported for streams that only uses + * single FlateDecode filter, i.e., + * + * /Filter /FlateDecode or /Filter [/FlateDecode] + * + * TrimBox, BleedBox, ArtBox, Rotate ... + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include "mem.h" +#include "mfileio.h" +#include "error.h" + +#include "dvipdfmx.h" + +#include "pdfobj.h" +#include "pdfdev.h" +#include "pdfdoc.h" + +#include "pdfximage.h" + +#include "epdf.h" + +int +pdf_include_page (pdf_ximage *ximage, FILE *image_file, const char *filename) +{ + pdf_file *pf; + xform_info info; + pdf_obj *contents = NULL, *catalog; + pdf_obj *page = NULL, *resources = NULL, *markinfo = NULL; + + pf = pdf_open(filename, image_file); + if (!pf) + return -1; + + if (pdf_file_get_version(pf) > pdf_get_version()) + goto too_recent; + + pdf_ximage_init_form_info(&info); + + page = pdf_doc_get_page(pf, pdf_ximage_get_page(ximage), NULL, + &info.bbox, &resources); + + if(!page) + goto error_silent; + + catalog = pdf_file_get_catalog(pf); + markinfo = pdf_deref_obj(pdf_lookup_dict(catalog, "MarkInfo")); + if (markinfo) { + pdf_obj *tmp = pdf_deref_obj(pdf_lookup_dict(markinfo, "Marked")); + pdf_release_obj(markinfo); + if (!PDF_OBJ_BOOLEANTYPE(tmp)) { + if (tmp) + pdf_release_obj(tmp); + goto error; + } else if (pdf_boolean_value(tmp)) + WARN("File contains tagged PDF. Ignoring tags."); + pdf_release_obj(tmp); + } + + contents = pdf_deref_obj(pdf_lookup_dict(page, "Contents")); + pdf_release_obj(page); + + /* + * Handle page content stream. + */ + { + pdf_obj *content_new; + + if (!contents) { + /* + * Empty page + */ + content_new = pdf_new_stream(0); + /* TODO: better don't include anything if the page is empty */ + } else if (PDF_OBJ_STREAMTYPE(contents)) { + /* + * We must import the stream because its dictionary + * may contain indirect references. + */ + content_new = pdf_import_object(contents); + } else if (PDF_OBJ_ARRAYTYPE(contents)) { + /* + * Concatenate all content streams. + */ + int idx, len = pdf_array_length(contents); + content_new = pdf_new_stream(STREAM_COMPRESS); + for (idx = 0; idx < len; idx++) { + pdf_obj *content_seg = pdf_deref_obj(pdf_get_array(contents, idx)); + if (!PDF_OBJ_STREAMTYPE(content_seg) || + pdf_concat_stream(content_new, content_seg) < 0) { + pdf_release_obj(content_seg); + pdf_release_obj(content_new); + goto error; + } + pdf_release_obj(content_seg); + } + } else + goto error; + + if (contents) + pdf_release_obj(contents); + contents = content_new; + } + + /* + * Add entries to contents stream dictionary. + */ + { + pdf_obj *contents_dict, *bbox, *matrix; + + contents_dict = pdf_stream_dict(contents); + pdf_add_dict(contents_dict, + pdf_new_name("Type"), + pdf_new_name("XObject")); + pdf_add_dict(contents_dict, + pdf_new_name("Subtype"), + pdf_new_name("Form")); + pdf_add_dict(contents_dict, + pdf_new_name("FormType"), + pdf_new_number(1.0)); + + bbox = pdf_new_array(); + pdf_add_array(bbox, pdf_new_number(info.bbox.llx)); + pdf_add_array(bbox, pdf_new_number(info.bbox.lly)); + pdf_add_array(bbox, pdf_new_number(info.bbox.urx)); + pdf_add_array(bbox, pdf_new_number(info.bbox.ury)); + + pdf_add_dict(contents_dict, pdf_new_name("BBox"), bbox); + + matrix = pdf_new_array(); + pdf_add_array(matrix, pdf_new_number(1.0)); + pdf_add_array(matrix, pdf_new_number(0.0)); + pdf_add_array(matrix, pdf_new_number(0.0)); + pdf_add_array(matrix, pdf_new_number(1.0)); + pdf_add_array(matrix, pdf_new_number(0.0)); + pdf_add_array(matrix, pdf_new_number(0.0)); + + pdf_add_dict(contents_dict, pdf_new_name("Matrix"), matrix); + + pdf_add_dict(contents_dict, + pdf_new_name("Resources"), + pdf_import_object(resources)); + pdf_release_obj(resources); + } + + pdf_close(pf); + + pdf_ximage_set_form(ximage, &info, contents); + + return 0; + + error: + WARN("Cannot parse document. Broken PDF file?"); + error_silent: + if (resources) + pdf_release_obj(resources); + if (markinfo) + pdf_release_obj(markinfo); + if (page) + pdf_release_obj(page); + if (contents) + pdf_release_obj(contents); + + pdf_close(pf); + + return -1; + + too_recent: + pdf_close(pf); + WARN("PDF version of input file more recent than in output file."); + if (compat_mode) { + WARN("Converting. Use \"-V\" switch to change output PDF version."); + return 1; + } else { + WARN("Use \"-V\" switch to change output PDF version."); + return -1; + } +} |