From dbfd3d35c0325197dec305820484818e46f8ac13 Mon Sep 17 00:00:00 2001 From: Akira Kakuto Date: Mon, 20 Jul 2020 20:56:58 +0000 Subject: support forward reference of image objects (S. Hirata) git-svn-id: svn://tug.org/texlive/trunk@55887 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/dvipdfm-x/ChangeLog | 9 ++ Build/source/texk/dvipdfm-x/configure | 22 +-- Build/source/texk/dvipdfm-x/configure.ac | 2 +- Build/source/texk/dvipdfm-x/pdfdoc.c | 15 +- Build/source/texk/dvipdfm-x/pdfdoc.h | 5 +- Build/source/texk/dvipdfm-x/pdfnames.c | 84 ++++++++--- Build/source/texk/dvipdfm-x/pdfnames.h | 7 +- Build/source/texk/dvipdfm-x/pdfobj.c | 4 +- Build/source/texk/dvipdfm-x/pdfximage.c | 245 +++++++++++++++++++++++-------- Build/source/texk/dvipdfm-x/pdfximage.h | 12 +- Build/source/texk/dvipdfm-x/spc_dvips.c | 8 +- Build/source/texk/dvipdfm-x/spc_html.c | 4 +- Build/source/texk/dvipdfm-x/spc_misc.c | 4 +- Build/source/texk/dvipdfm-x/spc_pdfm.c | 79 +--------- Build/source/texk/dvipdfm-x/specials.c | 26 +--- 15 files changed, 307 insertions(+), 219 deletions(-) (limited to 'Build') diff --git a/Build/source/texk/dvipdfm-x/ChangeLog b/Build/source/texk/dvipdfm-x/ChangeLog index 46dd130ed8c..d71cee39b55 100644 --- a/Build/source/texk/dvipdfm-x/ChangeLog +++ b/Build/source/texk/dvipdfm-x/ChangeLog @@ -1,3 +1,12 @@ +2020-07-21 Shunsaku Hirata + + * pdfdoc.[ch], pdfnames.[ch], pdfobj.c, pdfximage.[ch], + spc_dvips.c, spc_html.c, spc_misc.c, spc_pdfm.c, specials.c: + "Forward reference" of image objects is also supported. + Object reference by name is now available globally but not + only for the "special" module. + * configure.ac: Version 20200721. + 2020-07-19 Shunsaku Hirata * pdfdraw.c: Avoid invoking gs operation for an empty ExtGState. diff --git a/Build/source/texk/dvipdfm-x/configure b/Build/source/texk/dvipdfm-x/configure index e8017850ab3..90c88272bd3 100755 --- a/Build/source/texk/dvipdfm-x/configure +++ b/Build/source/texk/dvipdfm-x/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for dvipdfm-x (TeX Live) 20200711. +# Generated by GNU Autoconf 2.69 for dvipdfm-x (TeX Live) 20200721. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='dvipdfm-x (TeX Live)' PACKAGE_TARNAME='dvipdfm-x--tex-live-' -PACKAGE_VERSION='20200711' -PACKAGE_STRING='dvipdfm-x (TeX Live) 20200711' +PACKAGE_VERSION='20200721' +PACKAGE_STRING='dvipdfm-x (TeX Live) 20200721' PACKAGE_BUGREPORT='dvipdfmx@tug.org' PACKAGE_URL='' @@ -1350,7 +1350,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures dvipdfm-x (TeX Live) 20200711 to adapt to many kinds of systems. +\`configure' configures dvipdfm-x (TeX Live) 20200721 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1421,7 +1421,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of dvipdfm-x (TeX Live) 20200711:";; + short | recursive ) echo "Configuration of dvipdfm-x (TeX Live) 20200721:";; esac cat <<\_ACEOF @@ -1551,7 +1551,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -dvipdfm-x (TeX Live) configure 20200711 +dvipdfm-x (TeX Live) configure 20200721 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2390,7 +2390,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by dvipdfm-x (TeX Live) $as_me 20200711, which was +It was created by dvipdfm-x (TeX Live) $as_me 20200721, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -8077,7 +8077,7 @@ fi # Define the identity of the package. PACKAGE='dvipdfm-x--tex-live-' - VERSION='20200711' + VERSION='20200721' cat >>confdefs.h <<_ACEOF @@ -14746,7 +14746,7 @@ Usage: $0 [OPTIONS] Report bugs to ." lt_cl_version="\ -dvipdfm-x (TeX Live) config.lt 20200711 +dvipdfm-x (TeX Live) config.lt 20200721 configured by $0, generated by GNU Autoconf 2.69. Copyright (C) 2011 Free Software Foundation, Inc. @@ -16636,7 +16636,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by dvipdfm-x (TeX Live) $as_me 20200711, which was +This file was extended by dvipdfm-x (TeX Live) $as_me 20200721, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -16706,7 +16706,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -dvipdfm-x (TeX Live) config.status 20200711 +dvipdfm-x (TeX Live) config.status 20200721 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/Build/source/texk/dvipdfm-x/configure.ac b/Build/source/texk/dvipdfm-x/configure.ac index 93078b5fe33..eea48de57cc 100644 --- a/Build/source/texk/dvipdfm-x/configure.ac +++ b/Build/source/texk/dvipdfm-x/configure.ac @@ -8,7 +8,7 @@ dnl This file is free software; the copyright holder dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl -AC_INIT([dvipdfm-x (TeX Live)], [20200711], [dvipdfmx@tug.org]) +AC_INIT([dvipdfm-x (TeX Live)], [20200721], [dvipdfmx@tug.org]) AC_PREREQ([2.65]) AC_CONFIG_SRCDIR([agl.c]) AC_CONFIG_AUX_DIR([../../build-aux]) diff --git a/Build/source/texk/dvipdfm-x/pdfdoc.c b/Build/source/texk/dvipdfm-x/pdfdoc.c index 1658e6415f8..98f8625cfd4 100644 --- a/Build/source/texk/dvipdfm-x/pdfdoc.c +++ b/Build/source/texk/dvipdfm-x/pdfdoc.c @@ -99,7 +99,7 @@ read_thumbnail (const char *thumb_filename) } MFCLOSE(fp); - xobj_id = pdf_ximage_findresource(thumb_filename, options); + xobj_id = pdf_ximage_load_image(thumb_filename, thumb_filename, options); if (xobj_id < 0) { WARN("Could not read thumbnail file \"%s\".", thumb_filename); image_ref = NULL; @@ -110,6 +110,8 @@ read_thumbnail (const char *thumb_filename) return image_ref; } +/* Sorry no appropriate place to put this... */ +struct ht_table *global_names = NULL; typedef struct pdf_form { @@ -2561,6 +2563,9 @@ pdf_open_document (const char *filename, pdf_init_device(settings.device.dvi2pts, settings.device.precision, settings.device.ignore_colors); + + global_names = pdf_new_name_tree(); + return; } @@ -2569,6 +2574,8 @@ pdf_close_document (void) { pdf_doc *p = &pdoc; + pdf_delete_name_tree(&global_names); + pdf_close_device(); /* @@ -2704,10 +2711,12 @@ pdf_doc_begin_grabbing (const char *ident, info.bbox.urx = cropbox->urx; info.bbox.ury = cropbox->ury; - /* Use reference since content itself isn't available yet. */ + /* Use reference since content itself isn't available yet. + * - 2020/07/21 Changed... "forward reference" support requires object itself. + */ xobj_id = pdf_ximage_defineresource(ident, PDF_XOBJECT_TYPE_FORM, - &info, pdf_ref_obj(form->contents)); + &info, pdf_link_obj(form->contents)); p->pending_forms = fnode; diff --git a/Build/source/texk/dvipdfm-x/pdfdoc.h b/Build/source/texk/dvipdfm-x/pdfdoc.h index 0e6f287db42..855563d2d1c 100644 --- a/Build/source/texk/dvipdfm-x/pdfdoc.h +++ b/Build/source/texk/dvipdfm-x/pdfdoc.h @@ -1,6 +1,6 @@ /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2007-2018 by Jin-Hwan Cho and Shunsaku Hirata, + Copyright (C) 2007-2020 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team. Copyright (C) 1998, 1999 by Mark A. Wicks @@ -164,4 +164,7 @@ extern void pdf_doc_set_pagelabel (int page_start, #include "pdfcolor.h" extern void pdf_doc_set_bgcolor(const pdf_color *color); +/* Sorry no appropriate place to put this... */ +extern struct ht_table *global_names; + #endif /* _PDFDOC_H_ */ diff --git a/Build/source/texk/dvipdfm-x/pdfnames.c b/Build/source/texk/dvipdfm-x/pdfnames.c index ae9584145d6..c6df49c0d43 100644 --- a/Build/source/texk/dvipdfm-x/pdfnames.c +++ b/Build/source/texk/dvipdfm-x/pdfnames.c @@ -1,6 +1,6 @@ /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2002-2016 by Jin-Hwan Cho and Shunsaku Hirata, + Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team. Copyright (C) 1998, 1999 by Mark A. Wicks @@ -44,6 +44,7 @@ struct obj_data { + pdf_obj *reference; pdf_obj *object; int closed; /* 1 if object is closed */ }; @@ -80,9 +81,13 @@ hval_free (void *hval) value = (struct obj_data *) hval; + if (value->reference) { + pdf_release_obj(value->reference); + value->reference = NULL; + } if (value->object) { pdf_release_obj(value->object); - value->object = NULL; + value->object = NULL; } RELEASE(value); @@ -114,11 +119,10 @@ check_objects_defined (struct ht_table *ht_tab) key = ht_iter_getkey(&iter, &keylen); value = ht_iter_getval(&iter); - ASSERT(value->object); if (PDF_OBJ_UNDEFINED(value->object)) { - pdf_names_add_object(ht_tab, key, keylen, pdf_new_null()); - WARN("Object @%s used, but not defined. Replaced by null.", - printable_key(key, keylen)); + pdf_names_add_object(ht_tab, key, keylen, pdf_new_null()); + WARN("Object @%s used, but not defined. Replaced by null.", + printable_key(key, keylen)); } } while (ht_iter_next(&iter) >= 0); ht_clear_iter(&iter); @@ -138,8 +142,7 @@ pdf_delete_name_tree (struct ht_table **names) } int -pdf_names_add_object (struct ht_table *names, - const void *key, int keylen, pdf_obj *object) +pdf_names_add_object (struct ht_table *names, const void *key, int keylen, pdf_obj *object) { struct obj_data *value; @@ -154,11 +157,11 @@ pdf_names_add_object (struct ht_table *names, if (!value) { value = NEW(1, struct obj_data); value->object = object; + value->reference = NULL; value->closed = 0; ht_append_table(names, key, keylen, value); } else { - ASSERT(value->object); - if (PDF_OBJ_UNDEFINED(value->object)) { + if (value->object && PDF_OBJ_UNDEFINED(value->object)) { pdf_transfer_label(object, value->object); pdf_release_obj(value->object); value->object = object; @@ -172,38 +175,71 @@ pdf_names_add_object (struct ht_table *names, return 0; } +pdf_obj * +pdf_names_reserve (struct ht_table *names, const void *key, int keylen) +{ + pdf_obj *obj_ref = NULL; + struct obj_data *value; + + ASSERT(names); + + if (!key || keylen < 1) { + WARN("Null string used for name tree key."); + return NULL; + } + + value = ht_lookup_table(names, key, keylen); + if (!value) { + value = NEW(1, struct obj_data); + value->object = pdf_new_undefined(); + value->reference = NULL; + value->closed = 0; + ht_append_table(names, key, keylen, value); + obj_ref = pdf_ref_obj(value->object); + } else { + if (value->object && PDF_OBJ_UNDEFINED(value->object)) { + if (!value->reference) + value->reference = pdf_ref_obj(value->object); + obj_ref = pdf_link_obj(value->reference); + } else { + WARN("Object @%s already defined.", printable_key(key, keylen)); + obj_ref = NULL; + } + } + + return obj_ref; +} + /* * The following routine returns copies, not the original object. */ pdf_obj * -pdf_names_lookup_reference (struct ht_table *names, - const void *key, int keylen) +pdf_names_lookup_reference (struct ht_table *names, const void *key, int keylen) { struct obj_data *value; - pdf_obj *object; + pdf_obj *obj_ref; ASSERT(names); value = ht_lookup_table(names, key, keylen); if (value) { - object = value->object; - ASSERT(object); + if (!value->reference) + value->reference = pdf_ref_obj(value->object); + obj_ref = pdf_link_obj(value->reference); } else { /* A null object as dummy would create problems because as value * of a dictionary entry, a null object is be equivalent to no entry * at all. This matters for optimization of PDF destinations. */ - object = pdf_new_undefined(); - pdf_names_add_object(names, key, keylen, object); + obj_ref = pdf_names_reserve(names, key, keylen); } - return pdf_ref_obj(object); + return obj_ref; } pdf_obj * -pdf_names_lookup_object (struct ht_table *names, - const void *key, int keylen) +pdf_names_lookup_object (struct ht_table *names, const void *key, int keylen) { struct obj_data *value; @@ -212,14 +248,14 @@ pdf_names_lookup_object (struct ht_table *names, value = ht_lookup_table(names, key, keylen); if (!value || PDF_OBJ_UNDEFINED(value->object)) return NULL; - ASSERT(value->object); + if (value->closed) + WARN("Object \"%s\" already closed.", printable_key(key, keylen)); return value->object; } int -pdf_names_close_object (struct ht_table *names, - const void *key, int keylen) +pdf_names_close_object (struct ht_table *names, const void *key, int keylen) { struct obj_data *value; @@ -237,6 +273,8 @@ pdf_names_close_object (struct ht_table *names, return -1; } + pdf_release_obj(value->object); + value->object = NULL; value->closed = 1; return 0; diff --git a/Build/source/texk/dvipdfm-x/pdfnames.h b/Build/source/texk/dvipdfm-x/pdfnames.h index c077c8df7ad..5b4e3599864 100644 --- a/Build/source/texk/dvipdfm-x/pdfnames.h +++ b/Build/source/texk/dvipdfm-x/pdfnames.h @@ -1,6 +1,6 @@ /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2002-2016 by Jin-Hwan Cho and Shunsaku Hirata, + Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team. Copyright (C) 1998, 1999 by Mark A. Wicks @@ -32,14 +32,15 @@ extern struct ht_table *pdf_new_name_tree (void); extern void pdf_delete_name_tree (struct ht_table **names); extern int pdf_names_add_object (struct ht_table *names, - const void *key, int keylen, pdf_obj *object); + const void *key, int keylen, pdf_obj *object); extern pdf_obj *pdf_names_lookup_reference (struct ht_table *names, const void *key, int keylen); extern pdf_obj *pdf_names_lookup_object (struct ht_table *names, const void *key, int keylen); extern int pdf_names_close_object (struct ht_table *names, const void *key, int keylen); - +extern pdf_obj *pdf_names_reserve (struct ht_table *names, + const void *key, int keylen); /* Really create name tree... */ extern pdf_obj *pdf_names_create_tree (struct ht_table *names, int *count, diff --git a/Build/source/texk/dvipdfm-x/pdfobj.c b/Build/source/texk/dvipdfm-x/pdfobj.c index 12ee734c07b..7cae7295356 100644 --- a/Build/source/texk/dvipdfm-x/pdfobj.c +++ b/Build/source/texk/dvipdfm-x/pdfobj.c @@ -4268,7 +4268,9 @@ pdf_compare_object (pdf_obj *obj1, pdf_obj *obj2) { int r = 0; - if (!obj1 && obj2) { + if (!obj1 && !obj2) { + return 0; + } else if (!obj1 && obj2) { return 1; } else if (obj1 && !obj2) { return 1; diff --git a/Build/source/texk/dvipdfm-x/pdfximage.c b/Build/source/texk/dvipdfm-x/pdfximage.c index be8e9a4da55..27894763c4b 100644 --- a/Build/source/texk/dvipdfm-x/pdfximage.c +++ b/Build/source/texk/dvipdfm-x/pdfximage.c @@ -37,6 +37,8 @@ #include "pdfdoc.h" #include "pdfdev.h" #include "pdfdraw.h" +#include "pdfnames.h" +#include "specials.h" #include "epdf.h" #include "mpost.h" @@ -90,9 +92,11 @@ struct pdf_ximage_ struct attr_ attr; char *filename; + char *fullname; pdf_obj *reference; pdf_obj *resource; + int reserved; }; @@ -120,12 +124,14 @@ static void pdf_init_ximage_struct (pdf_ximage *I) { I->ident = NULL; - I->filename = NULL; + I->filename = NULL; + I->fullname = NULL; I->subtype = -1; memset(I->res_name, 0, 16); I->reference = NULL; I->resource = NULL; + I->reserved = 0; I->attr.width = I->attr.height = 0; I->attr.xdensity = I->attr.ydensity = 1.0; @@ -141,12 +147,12 @@ pdf_init_ximage_struct (pdf_ximage *I) } static void -pdf_set_ximage_tempfile (pdf_ximage *I, const char *filename) +pdf_set_ximage_tempfile (pdf_ximage *I, const char *fullname) { - if (I->filename) - RELEASE(I->filename); - I->filename = NEW(strlen(filename)+1, char); - strcpy(I->filename, filename); + if (I->fullname) + RELEASE(I->fullname); + I->fullname = NEW(strlen(fullname)+1, char); + strcpy(I->fullname, fullname); I->attr.tempfile = 1; } @@ -157,6 +163,8 @@ pdf_clean_ximage_struct (pdf_ximage *I) RELEASE(I->ident); if (I->filename) RELEASE(I->filename); + if (I->fullname) + RELEASE(I->fullname); if (I->reference) pdf_release_obj(I->reference); if (I->resource) @@ -196,8 +204,8 @@ pdf_close_images (void) if (dpx_conf.verbose_level > 1 && dpx_conf.file.keep_cache != 1) MESG("pdf_image>> deleting temporary file \"%s\"\n", I->filename); - dpx_delete_temp_file(I->filename, false); /* temporary filename freed here */ - I->filename = NULL; + dpx_delete_temp_file(I->fullname, false); /* temporary filename freed here */ + I->fullname = NULL; } pdf_clean_ximage_struct(I); } @@ -253,28 +261,45 @@ source_image_type (FILE *fp) } static int -load_image (const char *ident, const char *fullname, int format, FILE *fp, +load_image (const char *ident, const char *filename, const char *fullname, int format, FILE *fp, load_options options) { struct ic_ *ic = &_ic; - int id = -1; /* ret */ + int id = -1, reserved = 0; pdf_ximage *I; - id = ic->count; - if (ic->count >= ic->capacity) { - ic->capacity += 16; - ic->ximages = RENEW(ic->ximages, ic->capacity, pdf_ximage); - } - - I = &ic->ximages[id]; - pdf_init_ximage_struct(I); if (ident) { - I->ident = NEW(strlen(ident)+1, char); - strcpy(I->ident, ident); + for (id = 0; id < ic->count; id++) { + I = &ic->ximages[id]; + if (I->ident && !strcmp(ident, I->ident)) { + if (I->reserved) { + reserved = 1; + break; + } + } + } + } + if (!reserved) { + id = ic->count; + if (ic->count >= ic->capacity) { + ic->capacity += 16; + ic->ximages = RENEW(ic->ximages, ic->capacity, pdf_ximage); + } + I = &ic->ximages[id]; + pdf_init_ximage_struct(I); + if (ident) { + I->ident = NEW(strlen(ident)+1, char); + strcpy(I->ident, ident); + } + ic->count++; + } + if (filename) { + I->filename = NEW(strlen(filename)+1, char); + strcpy(I->filename, filename); } if (fullname) { - I->filename = NEW(strlen(fullname)+1, char); - strcpy(I->filename, fullname); + I->fullname = NEW(strlen(fullname)+1, char); + strcpy(I->fullname, fullname); } I->attr.page_no = options.page_no; @@ -352,8 +377,6 @@ load_image (const char *ident, const char *fullname, int format, FILE *fp, goto error; } - ic->count++; - return id; error: @@ -371,30 +394,30 @@ int utf8name_failed = 0; #endif /* WIN32 */ int -pdf_ximage_findresource (const char *ident, load_options options) +pdf_ximage_load_image (const char *ident, const char *filename, load_options options) { struct ic_ *ic = &_ic; - int id = -1; + int i, id = -1; pdf_ximage *I; char *fullname, *f = NULL; int format; FILE *fp; - /* I don't understand why there is comparision against I->attr.dict here... - * I->attr.dict and options.dict are simply pointers to PDF dictionaries. - */ - for (id = 0; id < ic->count; id++) { - I = &ic->ximages[id]; - if (I->ident && !strcmp(ident, I->ident)) { - f = I->filename; - if (I->attr.page_no == options.page_no /* Not sure */ - && I->attr.dict == options.dict /* ????? */ - && I->attr.bbox_type == options.bbox_type) { - return id; - } - } + for (i = 0; i < ic->count; i++) { + I = &ic->ximages[i]; + if (I->filename && !strcmp(filename, I->filename)) { + id = i; + break; } - + } + if (id >= 0) { + if (I->attr.page_no == options.page_no && + !pdf_compare_object(I->attr.dict, options.dict) && /* ????? */ + I->attr.bbox_type == options.bbox_type) { + return id; + } + f = I->filename; + } if (f) { /* we already have converted this file; f is the temporary file name */ fullname = NEW(strlen(f)+1, char); @@ -404,13 +427,13 @@ pdf_ximage_findresource (const char *ident, load_options options) #if defined(WIN32) utf8name_failed = 0; #endif /* WIN32 */ - fullname = dpx_find_file(ident, "_pic_", ""); + fullname = dpx_find_file(filename, "_pic_", ""); #if defined(WIN32) if (!fullname && file_system_codepage != win32_codepage) { int tmpcp = file_system_codepage; utf8name_failed = 1; file_system_codepage = win32_codepage; - fullname = dpx_find_file(ident, "_pic_", ""); + fullname = dpx_find_file(filename, "_pic_", ""); file_system_codepage = tmpcp; } #endif /* WIN32 */ @@ -418,7 +441,6 @@ pdf_ximage_findresource (const char *ident, load_options options) #if defined(WIN32) utf8name_failed = 0; #endif /* WIN32 */ - WARN("Error locating image file \"%s\"", ident); return -1; } } @@ -430,7 +452,7 @@ pdf_ximage_findresource (const char *ident, load_options options) return -1; } if (dpx_conf.verbose_level > 0) { - MESG("(Image:%s", ident); + MESG("(Image:%s", filename); if (dpx_conf.verbose_level > 1) MESG("[%s]", fullname); } @@ -440,7 +462,7 @@ pdf_ximage_findresource (const char *ident, load_options options) case IMAGE_TYPE_MPS: if (dpx_conf.verbose_level > 0) MESG("[MPS]"); - id = mps_include_page(ident, fp); + id = mps_include_page(filename, fp); if (id < 0) { WARN("Try again with the distiller."); format = IMAGE_TYPE_EPS; @@ -448,7 +470,7 @@ pdf_ximage_findresource (const char *ident, load_options options) } else break; default: - id = load_image(ident, fullname, format, fp, options); + id = load_image(ident, filename, fullname, format, fp, options); break; } dpx_fclose(fp); @@ -459,11 +481,28 @@ pdf_ximage_findresource (const char *ident, load_options options) MESG(")"); if (id < 0) - WARN("pdf: image inclusion failed for \"%s\".", ident); + WARN("pdf: image inclusion failed for \"%s\".", filename); return id; } +int +pdf_ximage_findresource (const char *ident) +{ + struct ic_ *ic = &_ic; + int id = -1; + pdf_ximage *I; + + for (id = 0; id < ic->count; id++) { + I = &ic->ximages[id]; + if (I->ident && !strcmp(ident, I->ident)) { + return id; + } + } + + return -1; +} + /* Reference: PDF Reference 1.5 v6, pp.321--322 * * TABLE 4.42 Additional entries specific to a type 1 form dictionary @@ -552,8 +591,6 @@ pdf_ximage_set_image (pdf_ximage *I, void *image_info, pdf_obj *resource) I->attr.xdensity = info->xdensity; I->attr.ydensity = info->ydensity; - I->reference = pdf_ref_obj(resource); - dict = pdf_stream_dict(resource); pdf_add_dict(dict, pdf_new_name("Type"), pdf_new_name("XObject")); pdf_add_dict(dict, pdf_new_name("Subtype"), pdf_new_name("Image")); @@ -565,6 +602,17 @@ pdf_ximage_set_image (pdf_ximage *I, void *image_info, pdf_obj *resource) if (I->attr.dict) pdf_merge_dict(dict, I->attr.dict); + if (I->ident) { + pdf_names_add_object(global_names, I->ident, strlen(I->ident), pdf_link_obj(resource)); + if (I->reference) + pdf_release_obj(I->reference); + /* Need to create object reference before closing it */ + I->reference = pdf_names_lookup_reference(global_names, I->ident, strlen(I->ident)); + pdf_names_close_object(global_names, I->ident, strlen(I->ident)); + I->reserved = 0; + } else { + I->reference = pdf_ref_obj(resource); + } pdf_release_obj(resource); /* Caller don't know we are using reference. */ I->resource = NULL; } @@ -594,8 +642,17 @@ pdf_ximage_set_form (pdf_ximage *I, void *form_info, pdf_obj *resource) I->attr.bbox.urx = max4(p1.x, p2.x, p3.x, p4.x); I->attr.bbox.ury = max4(p1.y, p2.y, p3.y, p4.y); - I->reference = pdf_ref_obj(resource); - + if (I->ident) { + pdf_names_add_object(global_names, I->ident, strlen(I->ident), pdf_link_obj(resource)); + if (I->reference) + pdf_release_obj(I->reference); + /* Need to create object reference before closing it */ + I->reference = pdf_names_lookup_reference(global_names, I->ident, strlen(I->ident)); + pdf_names_close_object(global_names, I->ident, strlen(I->ident)); + I->reserved = 0; + } else { + I->reference = pdf_ref_obj(resource); + } pdf_release_obj(resource); /* Caller don't know we are using reference. */ I->resource = NULL; } @@ -622,7 +679,7 @@ pdf_ximage_get_reference (int id) CHECK_ID(ic, id); I = GET_IMAGE(ic, id); - if (!I->reference) + if (!I->reference && I->resource) I->reference = pdf_ref_obj(I->resource); return pdf_link_obj(I->reference); @@ -634,22 +691,33 @@ pdf_ximage_defineresource (const char *ident, int subtype, void *info, pdf_obj *resource) { struct ic_ *ic = &_ic; - int id; + int id, reserved = 0; pdf_ximage *I; - id = ic->count; - if (ic->count >= ic->capacity) { - ic->capacity += 16; - ic->ximages = RENEW(ic->ximages, ic->capacity, pdf_ximage); + if (ident) { + for (id = 0; id < ic->count; id++) { + I = &ic->ximages[id]; + if (I->ident && !strcmp(ident, I->ident) && I->reserved) { + reserved = 1; + break; + } + } } - I = &ic->ximages[id]; - - pdf_init_ximage_struct(I); + if (!reserved) { + id = ic->count; + if (ic->count >= ic->capacity) { + ic->capacity += 16; + ic->ximages = RENEW(ic->ximages, ic->capacity, pdf_ximage); + } + I = &ic->ximages[id]; + pdf_init_ximage_struct(I); - if (ident) { - I->ident = NEW(strlen(ident)+1, char); - strcpy(I->ident, ident); + if (ident) { + I->ident = NEW(strlen(ident)+1, char); + strcpy(I->ident, ident); + } + ic->count++; } switch (subtype) { @@ -664,11 +732,46 @@ pdf_ximage_defineresource (const char *ident, default: ERROR("Unknown XObject subtype: %d", subtype); } - ic->count++; return id; } +int +pdf_ximage_reserve (const char *ident) +{ + struct ic_ *ic = &_ic; + int id; + pdf_ximage *I; + + for (id = 0; id < ic->count; id++) { + I = &ic->ximages[id]; + if (I->ident && !strcmp(ident, I->ident)) { + WARN("XObject ID \"%s\" already used!", ident); + return -1; + } + } + + id = ic->count; + if (ic->count >= ic->capacity) { + ic->capacity += 16; + ic->ximages = RENEW(ic->ximages, ic->capacity, pdf_ximage); + } + + I = &ic->ximages[id]; + + pdf_init_ximage_struct(I); + + if (ident) { + I->ident = NEW(strlen(ident)+1, char); + strcpy(I->ident, ident); + } + I->reference = pdf_names_reserve(global_names, ident, strlen(ident)); + sprintf(I->res_name, "Fm%d", id); + I->reserved = 1; + ic->count++; + + return id; +} char * pdf_ximage_get_resname (int id) @@ -908,6 +1011,18 @@ pdf_ximage_scale_image (int id, r->ury = I->attr.bbox.ury; } break; + default: /* maybe reserved */ + if (p->flags & INFO_HAS_USER_BBOX) { + r->llx = p->bbox.llx; + r->lly = p->bbox.lly; + r->urx = p->bbox.urx; + r->ury = p->bbox.ury; + } else { /* I->attr.bbox from the image bounding box */ + r->llx = 0.0; + r->lly = 0.0; + r->urx = 1.0; + r->ury = 1.0; + } } return 0; @@ -1069,7 +1184,7 @@ pdf_error_cleanup_cache (void) for (i = 0; i < ic->count; i++) { I = &ic->ximages[i]; if (I->attr.tempfile) { - dpx_delete_temp_file(I->filename, false); /* temporary filename freed here */ + dpx_delete_temp_file(I->fullname, false); /* temporary filename freed here */ } } } diff --git a/Build/source/texk/dvipdfm-x/pdfximage.h b/Build/source/texk/dvipdfm-x/pdfximage.h index fa29663ff70..70e15f2679c 100644 --- a/Build/source/texk/dvipdfm-x/pdfximage.h +++ b/Build/source/texk/dvipdfm-x/pdfximage.h @@ -64,14 +64,10 @@ extern void pdf_close_images (void); extern char *pdf_ximage_get_resname (int xobj_id); extern pdf_obj *pdf_ximage_get_reference (int xobj_id); -/* Please use different interface than findresource... - * This is not intended to be used for specifying page number and others. - * Only pdf:image special in spc_pdfm.c want optinal dict! - */ -extern int pdf_ximage_findresource (const char *ident, - load_options options); -extern int pdf_ximage_defineresource (const char *ident, int subtype, - void *cdata, pdf_obj *resource); +extern int pdf_ximage_findresource (const char *ident); +extern int pdf_ximage_load_image (const char *ident, const char *filename, load_options options); +extern int pdf_ximage_defineresource (const char *ident, int subtype, void *cdata, pdf_obj *resource); +extern int pdf_ximage_reserve (const char *ident); /* Called by pngimage, jpegimage, epdf, mpost, etc. */ extern void pdf_ximage_init_image_info (ximage_info *info); diff --git a/Build/source/texk/dvipdfm-x/spc_dvips.c b/Build/source/texk/dvipdfm-x/spc_dvips.c index e5a17990a2a..18fdef3d019 100644 --- a/Build/source/texk/dvipdfm-x/spc_dvips.c +++ b/Build/source/texk/dvipdfm-x/spc_dvips.c @@ -1,6 +1,6 @@ /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2002-2019 by Jin-Hwan Cho and Shunsaku Hirata, + Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team. Copyright (C) 1998, 1999 by Mark A. Wicks @@ -164,7 +164,7 @@ spc_handler_ps_file (struct spc_env *spe, struct spc_arg *args) return -1; } - form_id = pdf_ximage_findresource(filename, options); + form_id = pdf_ximage_load_image(NULL, filename, options); if (form_id < 0) { spc_warn(spe, "Failed to read image file: %s", filename); RELEASE(filename); @@ -198,7 +198,7 @@ spc_handler_ps_plotfile (struct spc_env *spe, struct spc_arg *args) return -1; } - form_id = pdf_ximage_findresource(filename, options); + form_id = pdf_ximage_load_image(NULL, filename, options); if (form_id < 0) { spc_warn(spe, "Could not open PS file: %s", filename); error = -1; @@ -709,7 +709,7 @@ spc_handler_ps_tricks_render (struct spc_env *spe, struct spc_arg *args) return error; } - form_id = pdf_ximage_findresource(gs_out, options); + form_id = pdf_ximage_load_image(NULL, gs_out, options); if (form_id < 0) { spc_warn(spe, "Failed to read converted PSTricks image file."); RELEASE(gs_in); diff --git a/Build/source/texk/dvipdfm-x/spc_html.c b/Build/source/texk/dvipdfm-x/spc_html.c index 83c6e0a28af..5e71201eb7c 100644 --- a/Build/source/texk/dvipdfm-x/spc_html.c +++ b/Build/source/texk/dvipdfm-x/spc_html.c @@ -1,6 +1,6 @@ /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2002-2017 by Jin-Hwan Cho and Shunsaku Hirata, + Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team. Copyright (C) 1998, 1999 by Mark A. Wicks @@ -645,7 +645,7 @@ spc_html__img_empty (struct spc_env *spe, pdf_obj *attr) return error; } - id = pdf_ximage_findresource(pdf_string_value(src), options); + id = pdf_ximage_load_image(NULL, pdf_string_value(src), options); if (id < 0) { spc_warn(spe, "Could not find/load image: %s", pdf_string_value(src)); error = -1; diff --git a/Build/source/texk/dvipdfm-x/spc_misc.c b/Build/source/texk/dvipdfm-x/spc_misc.c index 26a3a70ba4f..94c3206ab15 100644 --- a/Build/source/texk/dvipdfm-x/spc_misc.c +++ b/Build/source/texk/dvipdfm-x/spc_misc.c @@ -1,6 +1,6 @@ /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2002-2016 by Jin-Hwan Cho and Shunsaku Hirata, + Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team. Copyright (C) 1998, 1999 by Mark A. Wicks @@ -110,7 +110,7 @@ spc_handler_postscriptbox (struct spc_env *spe, struct spc_arg *ap) } MFCLOSE(fp); - form_id = pdf_ximage_findresource(filename, options); + form_id = pdf_ximage_load_image(NULL, filename, options); if (form_id < 0) { spc_warn(spe, "Failed to load image file: %s", filename); return -1; diff --git a/Build/source/texk/dvipdfm-x/spc_pdfm.c b/Build/source/texk/dvipdfm-x/spc_pdfm.c index 6873887e6b8..7d068ba4718 100644 --- a/Build/source/texk/dvipdfm-x/spc_pdfm.c +++ b/Build/source/texk/dvipdfm-x/spc_pdfm.c @@ -75,7 +75,6 @@ struct spc_pdf_ { pdf_obj *annot_dict; /* pending annotation dict */ int lowest_level; /* current min level of outlines */ - struct ht_table *resourcemap; /* see remark below (somewhere) */ struct tounicode cd; /* For to-UTF16-BE conversion :( */ pdf_obj *pageresources; /* Add to all page resource dict */ }; @@ -83,50 +82,10 @@ struct spc_pdf_ static struct spc_pdf_ _pdf_stat = { NULL, 255, - NULL, { -1, 0, NULL }, NULL }; -/* PLEASE REMOVE THIS */ -static void -hval_free (void *vp) -{ - RELEASE(vp); -} - - -static int -addresource (struct spc_pdf_ *sd, const char *ident, int res_id) -{ - struct resource_map *r; - - if (!ident || res_id < 0) - return -1; - - r = NEW(1, struct resource_map); - r->type = 0; /* unused */ - r->res_id = res_id; - - ht_append_table(sd->resourcemap, ident, strlen(ident), r); - spc_push_object(ident, pdf_ximage_get_reference(res_id)); - - return 0; -} - -static int -findresource (struct spc_pdf_ *sd, const char *ident) -{ - struct resource_map *r; - - if (!ident) - return -1; - - r = ht_lookup_table(sd->resourcemap, ident, strlen(ident)); - - return (r ? r->res_id : -1); -} - static int spc_handler_pdfm__init (void *dp) @@ -144,9 +103,6 @@ spc_handler_pdfm__init (void *dp) sd->annot_dict = NULL; sd->lowest_level = 255; - sd->resourcemap = NEW(1, struct ht_table); - ht_init_table(sd->resourcemap, hval_free); - sd->cd.taintkeys = pdf_new_array(); for (i = 0; default_taintkeys[i] != NULL; i++) { pdf_add_array(sd->cd.taintkeys, @@ -168,12 +124,6 @@ spc_handler_pdfm__clean (void *dp) } sd->lowest_level = 255; sd->annot_dict = NULL; - if (sd->resourcemap) { - ht_clear_table(sd->resourcemap); - RELEASE(sd->resourcemap); - } - sd->resourcemap = NULL; - if (sd->cd.taintkeys) pdf_release_obj(sd->cd.taintkeys); sd->cd.taintkeys = NULL; @@ -1253,7 +1203,6 @@ spc_handler_pdfm_bead (struct spc_env *spe, struct spc_arg *args) static int spc_handler_pdfm_image (struct spc_env *spe, struct spc_arg *args) { - struct spc_pdf_ *sd = &_pdf_stat; int xobj_id; char *ident = NULL; pdf_obj *fspec; @@ -1263,12 +1212,7 @@ spc_handler_pdfm_image (struct spc_env *spe, struct spc_arg *args) skip_white(&args->curptr, args->endptr); if (args->curptr[0] == '@') { ident = parse_opt_ident(&args->curptr, args->endptr); - xobj_id = findresource(sd, ident); - if (xobj_id >= 0) { - spc_warn(spe, "Object reference name for image \"%s\" already used.", ident); - RELEASE(ident); - return -1; - } + skip_white(&args->curptr, args->endptr); } /* 2015/12/29 @@ -1305,7 +1249,7 @@ spc_handler_pdfm_image (struct spc_env *spe, struct spc_arg *args) options.dict = parse_pdf_object(&args->curptr, args->endptr, NULL); } - xobj_id = pdf_ximage_findresource(pdf_string_value(fspec), options); + xobj_id = pdf_ximage_load_image(ident, pdf_string_value(fspec), options); if (xobj_id < 0) { spc_warn(spe, "Could not find image resource..."); @@ -1322,7 +1266,6 @@ spc_handler_pdfm_image (struct spc_env *spe, struct spc_arg *args) if ((dpx_conf.compat_mode == dpx_mode_compat_mode) && pdf_ximage_get_subtype(xobj_id) == PDF_XOBJECT_TYPE_IMAGE) pdf_ximage_set_attr(xobj_id, 1, 1, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0); - addresource(sd, ident, xobj_id); RELEASE(ident); } @@ -1511,6 +1454,7 @@ spc_handler_pdfm_close (struct spc_env *spe, struct spc_arg *args) spc_flush_object(ident); RELEASE(ident); } else { /* Close all? */ + spc_warn(spe, "pdf:close without an argument no longer supported!"); spc_clear_objects(); } @@ -1867,8 +1811,6 @@ spc_handler_pdfm_bform (struct spc_env *spe, struct spc_arg *args) spc_warn(spe, "Couldn't start form object."); return -1; } - - spc_push_object(ident, pdf_ximage_get_reference(xobj_id)); RELEASE(ident); return 0; @@ -1927,11 +1869,9 @@ spc_handler_pdfm_eform (struct spc_env *spe, struct spc_arg *args) static int spc_handler_pdfm_uxobj (struct spc_env *spe, struct spc_arg *args) { - struct spc_pdf_ *sd = &_pdf_stat; int xobj_id; char *ident; transform_info ti; - load_options options = {1, 0, NULL}; skip_white(&args->curptr, args->endptr); @@ -1949,18 +1889,9 @@ spc_handler_pdfm_uxobj (struct spc_env *spe, struct spc_arg *args) } } - /* Dvipdfmx was suddenly changed to use file name to identify - * external images. We can't use ident to find image resource - * here. - */ - xobj_id = findresource(sd, ident); + xobj_id = pdf_ximage_findresource(ident); if (xobj_id < 0) { - xobj_id = pdf_ximage_findresource(ident, options); - if (xobj_id < 0) { - spc_warn(spe, "Specified (image) object doesn't exist: %s", ident); - RELEASE(ident); - return -1; - } + xobj_id = pdf_ximage_reserve(ident); } pdf_dev_put_image(xobj_id, &ti, spe->x_user, spe->y_user); diff --git a/Build/source/texk/dvipdfm-x/specials.c b/Build/source/texk/dvipdfm-x/specials.c index b2bc929099a..54941f5f183 100644 --- a/Build/source/texk/dvipdfm-x/specials.c +++ b/Build/source/texk/dvipdfm-x/specials.c @@ -123,7 +123,6 @@ spc_set_phantom (struct spc_env *spe, double height, double depth) dvi_set_phantom_height(height, depth); } -static struct ht_table *named_objects = NULL; /* reserved keys */ static const char *_rkeys[] = { @@ -177,8 +176,6 @@ spc_lookup_reference (const char *key) pdf_coord cp; int k; - ASSERT(named_objects); - if (!key) return NULL; @@ -223,7 +220,7 @@ spc_lookup_reference (const char *key) if (ispageref(key)) value = pdf_doc_ref_page(atoi(key + 4)); else { - value = pdf_names_lookup_reference(named_objects, key, strlen(key)); + value = pdf_names_lookup_reference(global_names, key, strlen(key)); } break; } @@ -242,8 +239,6 @@ spc_lookup_object (const char *key) pdf_coord cp; int k; - ASSERT(named_objects); - if (!key) return NULL; @@ -278,7 +273,7 @@ spc_lookup_object (const char *key) value = pdf_doc_docinfo(); break; default: - value = pdf_names_lookup_object(named_objects, key, strlen(key)); + value = pdf_names_lookup_object(global_names, key, strlen(key)); break; } @@ -294,25 +289,22 @@ spc_lookup_object (const char *key) void spc_push_object (const char *key, pdf_obj *value) { - ASSERT(named_objects); - if (!key || !value) return; - pdf_names_add_object(named_objects, key, strlen(key), value); + pdf_names_add_object(global_names, key, strlen(key), value); } void spc_flush_object (const char *key) { - pdf_names_close_object(named_objects, key, strlen(key)); + pdf_names_close_object(global_names, key, strlen(key)); } void spc_clear_objects (void) { - pdf_delete_name_tree(&named_objects); - named_objects = pdf_new_name_tree(); + /* Do nothing... */ } @@ -489,10 +481,6 @@ spc_exec_at_begin_document (void) int error = 0; int i; - ASSERT(!named_objects); - - named_objects = pdf_new_name_tree(); - for (i = 0; known_specials[i].key != NULL; i++) { if (known_specials[i].bodhk_func) { error = known_specials[i].bodhk_func(); @@ -514,10 +502,6 @@ spc_exec_at_end_document (void) } } - if (named_objects) { - pdf_delete_name_tree(&named_objects); - } - return error; } -- cgit v1.2.3