summaryrefslogtreecommitdiff
path: root/Build
diff options
context:
space:
mode:
authorPeter Breitenlohner <peb@mppmu.mpg.de>2013-09-24 12:19:06 +0000
committerPeter Breitenlohner <peb@mppmu.mpg.de>2013-09-24 12:19:06 +0000
commitb68e9d4dea7036d84321a93391c2f810766a41a0 (patch)
tree821235fdd65acf69ddee47af44a5dfd6889ce314 /Build
parent07ebfb83f578495e8f9e6826ca7a408470cf8b22 (diff)
dvipdf-x: Bug fix for xdvipdfm-res.test (tikz-bug)
git-svn-id: svn://tug.org/texlive/trunk@31738 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build')
-rw-r--r--Build/source/texk/dvipdf-x/ChangeLog10
-rw-r--r--Build/source/texk/dvipdf-x/spc_xtx.c2
-rw-r--r--Build/source/texk/dvipdf-x/tests/annot.dvibin552 -> 680 bytes
-rw-r--r--Build/source/texk/dvipdf-x/tests/annot.tex5
-rw-r--r--Build/source/texk/dvipdf-x/tests/bookm.tex2
-rw-r--r--Build/source/texk/dvipdf-x/tests/resrc.tex84
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/dpxutil.c7
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/dpxutil.h1
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/dvipdfmx.c4
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/epdf.c211
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/epdf.h7
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/mpost.c9
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/pdfcolor.c124
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/pdfcolor.h13
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/pdfdev.c144
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/pdfdev.h7
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/pdfdoc.c520
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/pdfdoc.h10
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/pdfdraw.c55
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/pdfdraw.h6
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/pdfnames.c247
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/pdfnames.h6
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/pdfobj.c394
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/pdfobj.h32
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/pdfximage.c125
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/pdfximage.h7
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/spc_pdfm.c4
-rw-r--r--Build/source/texk/dvipdf-x/xsrc/specials.c27
28 files changed, 1199 insertions, 864 deletions
diff --git a/Build/source/texk/dvipdf-x/ChangeLog b/Build/source/texk/dvipdf-x/ChangeLog
index f563f6a471c..b652d9641bb 100644
--- a/Build/source/texk/dvipdf-x/ChangeLog
+++ b/Build/source/texk/dvipdf-x/ChangeLog
@@ -1,3 +1,13 @@
+2013-09-24 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * spc_xtx.c, xsrc/dpxutil.[ch], xsrc/dvipdfmx.c, xsrc/epdf.[ch],
+ mpost.c, xsrc/pdfcolor.[ch], xsrc/pdfdev.[ch], xsrc/pdfdoc.[ch],
+ xsrc/pdfdraw.[ch], xsrc/pdfnames.[ch], xsrc/pdfobj.[ch],
+ xsrc/pdfximage.[ch], xsrc/spc_pdfm.c, xsrc/specials.c: Adapt to
+ dvipdfmx files in src/ and fix xdvipdfm-res.test (tikz-bug).
+
+ * tests/annot.{dvi,tex}: Test a broken link annotation.
+
2013-09-23 Peter Breitenlohner <peb@mppmu.mpg.de>
* src/pdfdoc.c, src/dvipdfmx.c, src/pdfencrypt.c:
diff --git a/Build/source/texk/dvipdf-x/spc_xtx.c b/Build/source/texk/dvipdf-x/spc_xtx.c
index cf4f668bc5c..ed0b667f8c2 100644
--- a/Build/source/texk/dvipdf-x/spc_xtx.c
+++ b/Build/source/texk/dvipdf-x/spc_xtx.c
@@ -164,7 +164,7 @@ spc_handler_xtx_grestore (struct spc_env *spe, struct spc_arg *args)
* starting a new page.
*/
pdf_dev_reset_fonts();
- pdf_dev_reset_color();
+ pdf_dev_reset_color(0);
return 0;
}
diff --git a/Build/source/texk/dvipdf-x/tests/annot.dvi b/Build/source/texk/dvipdf-x/tests/annot.dvi
index 7ea86daa1f5..0cea9bacc12 100644
--- a/Build/source/texk/dvipdf-x/tests/annot.dvi
+++ b/Build/source/texk/dvipdf-x/tests/annot.dvi
Binary files differ
diff --git a/Build/source/texk/dvipdf-x/tests/annot.tex b/Build/source/texk/dvipdf-x/tests/annot.tex
index c57f2ca5786..dd10e9fd223 100644
--- a/Build/source/texk/dvipdf-x/tests/annot.tex
+++ b/Build/source/texk/dvipdf-x/tests/annot.tex
@@ -1,9 +1,12 @@
%
\special{pdf:obj @tug <</S/URI /URI (http://www.tug.org)>>}
+Add some text and more text and still more text in order to get a link annotation
+extending
\special{pdf:bann <</Subtype/Link /A @tug>>}%
TUG on the web
-\special{pdf:eann}%
+\special{pdf:eann}
+over two lines.
\vskip 20 bp
diff --git a/Build/source/texk/dvipdf-x/tests/bookm.tex b/Build/source/texk/dvipdf-x/tests/bookm.tex
index 72745154473..d42e12a51f4 100644
--- a/Build/source/texk/dvipdf-x/tests/bookm.tex
+++ b/Build/source/texk/dvipdf-x/tests/bookm.tex
@@ -57,4 +57,4 @@
\noindent The second section
-\bye \ No newline at end of file
+\bye
diff --git a/Build/source/texk/dvipdf-x/tests/resrc.tex b/Build/source/texk/dvipdf-x/tests/resrc.tex
index d82af96a1b5..5c95c930e51 100644
--- a/Build/source/texk/dvipdf-x/tests/resrc.tex
+++ b/Build/source/texk/dvipdf-x/tests/resrc.tex
@@ -1,78 +1,6 @@
-%
-\special{papersize=10cm,10cm}
-
-\special{pdf:obj @pgfcolorspaces <<>>}
-
-\special{pdf:obj @pgfpatterns <<>>}
-
-\special{pdf:put @resources
- <</Pattern @pgfpatterns /Colorspace @pgfcolorspaces>>}
-
-\special{pdf:put @pgfcolorspaces
- <</pgfprgb [/Pattern /DeviceRGB]>>}
-
-\special{pdf:put @pgfpatterns
- <</pgfpat6 @pgf@paternobject@6>>}
-
-\special{pdf:stream @pgf@paternobject@6 (q 0.3985 w 3.08846 0.0 m Q)
- <</Type/Pattern>>}
-
-\bye
-
-\special{pdf:out 1
- <</Title(Contents)/A<</S/GoTo/D(contents)>>>>}
-\special{pdf:out 1
- <</Title(1 First section)/A<</S/GoTo/D(section.1)>>>>}
-\special{pdf:out 2
- <</Title(1.1 First subsection)/A<</S/GoTo/D(subsection.1.1)>>>>}
-\special{pdf:out 1
- <</Title(2 Second section)/A<</S/GoTo/D(section.2)>>>>}
-
-\noindent Contents
-\special{pdf:dest (contents) [@thispage /XYZ @xpos @ypos null]}
-
-\vskip 5mm
-
-\hbox to 60mm{%
-\special{pdf:bann<</Type/Annot/Subtype/Link/Border[0 0 0]/C[1 0 0]
- /A<</S/GoTo/D(section.1)>>>>}1 First section\special{pdf:eann}
-\hfill 2}
-
-\hbox to 60mm{\hskip 5mm%
-\special{pdf:bann<</Type/Annot/Subtype/Link/Border[0 0 0]/C[1 0 0]
- /A<</S/GoTo/D(subsection.1.1)>>>>}1.1 First subsection\special{pdf:eann}
-\hfill 3}
-
-\hbox to 60mm{%
-\special{pdf:bann<</Type/Annot/Subtype/Link/Border[0 0 0]/C[1 0 0]
- /A<</S/GoTo/D(section.2)>>>>}2 Second section\special{pdf:eann}
-\hfill 4}
-
-\vfill\break
-
-\noindent 1 First section
-\special{pdf:dest (section.1) [@thispage /XYZ @xpos @ypos null]}
-
-\vskip 5mm
-
-\noindent The first section
-
-\vfill\break
-
-\noindent 1.1 First subsection
-\special{pdf:dest (subsection.1.1) [@thispage /XYZ @xpos @ypos null]}
-
-\vskip 5mm
-
-\noindent The first subsection
-
-\vfill\break
-
-\noindent 2 Second section
-\special{pdf:dest (section.2) [@thispage /XYZ @xpos @ypos null]}
-
-\vskip 5mm
-
-\noindent The second section
-
-\bye \ No newline at end of file
+\documentclass[dvipdfmx]{article}
+\usepackage{tikz}
+\usetikzlibrary{patterns}
+\begin{document}
+\tikz \path[pattern=crosshatch] (0,0) -- (1,0) -- (0,1) -- cycle;
+\end{document}
diff --git a/Build/source/texk/dvipdf-x/xsrc/dpxutil.c b/Build/source/texk/dvipdf-x/xsrc/dpxutil.c
index 98ba7cde9d4..8f752f2dcab 100644
--- a/Build/source/texk/dvipdf-x/xsrc/dpxutil.c
+++ b/Build/source/texk/dvipdf-x/xsrc/dpxutil.c
@@ -204,6 +204,13 @@ ht_clear_table (struct ht_table *ht)
ht->hval_free_fn = NULL;
}
+long ht_table_size (struct ht_table *ht)
+{
+ ASSERT(ht);
+
+ return ht->count;
+}
+
static unsigned int
get_hash (const void *key, int keylen)
{
diff --git a/Build/source/texk/dvipdf-x/xsrc/dpxutil.h b/Build/source/texk/dvipdf-x/xsrc/dpxutil.h
index f902bb1f2aa..bd8c338d056 100644
--- a/Build/source/texk/dvipdf-x/xsrc/dpxutil.h
+++ b/Build/source/texk/dvipdf-x/xsrc/dpxutil.h
@@ -77,6 +77,7 @@ struct ht_table {
extern void ht_init_table (struct ht_table *ht,
hval_free_func hval_free_fn);
extern void ht_clear_table (struct ht_table *ht);
+extern long ht_table_size (struct ht_table *ht);
extern void *ht_lookup_table (struct ht_table *ht,
const void *key, int keylen);
extern void ht_append_table (struct ht_table *ht,
diff --git a/Build/source/texk/dvipdf-x/xsrc/dvipdfmx.c b/Build/source/texk/dvipdf-x/xsrc/dvipdfmx.c
index ca79fdf9c35..c31fad7170c 100644
--- a/Build/source/texk/dvipdf-x/xsrc/dvipdfmx.c
+++ b/Build/source/texk/dvipdf-x/xsrc/dvipdfmx.c
@@ -75,6 +75,7 @@ static long opt_flags = 0;
#define OPT_TPIC_TRANSPARENT_FILL (1 << 1)
#define OPT_CIDFONT_FIXEDPITCH (1 << 2)
#define OPT_FONTMAP_FIRST_MATCH (1 << 3)
+#define OPT_PDFDOC_NO_DEST_REMOVE (1 << 4)
static char ignore_colors = 0;
static double annot_grow = 0.0;
@@ -948,7 +949,8 @@ main (int argc, char *argv[])
* bookmark_open: Miximal depth of open bookmarks.
*/
pdf_open_document(pdf_filename, do_encryption,
- paper_width, paper_height, annot_grow, bookmark_open);
+ paper_width, paper_height, annot_grow, bookmark_open,
+ !(opt_flags & OPT_PDFDOC_NO_DEST_REMOVE));
/* Ignore_colors placed here since
* they are considered as device's capacity.
diff --git a/Build/source/texk/dvipdf-x/xsrc/epdf.c b/Build/source/texk/dvipdf-x/xsrc/epdf.c
index 53c9fdf554c..ebee0d275fb 100644
--- a/Build/source/texk/dvipdf-x/xsrc/epdf.c
+++ b/Build/source/texk/dvipdf-x/xsrc/epdf.c
@@ -31,34 +31,38 @@
* TrimBox, BleedBox, ArtBox, Rotate ...
*/
-#if HAVE_CONFIG_H
-#include "config.h"
+#ifdef 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"
+
+#ifdef XETEX
#include "pdfdraw.h"
#include "pdfparse.h"
+#endif
#include "pdfximage.h"
-#include "pdfdoc.h"
-
#include "epdf.h"
+#ifdef XETEX
#if HAVE_ZLIB
#include <zlib.h>
static int add_stream_flate (pdf_obj *dst, const void *data, long len);
#endif
-static int concat_stream (pdf_obj *dst, pdf_obj *src);
-
static int rect_equal (pdf_obj *rect1, pdf_obj *rect2);
+static int concat_stream (pdf_obj *dst, pdf_obj *src);
+
/*
* From PDFReference15_v6.pdf (p.119 and p.834)
*
@@ -391,109 +395,167 @@ pdf_get_page_content (pdf_obj* page)
return contents;
}
+#endif
int
-pdf_include_page (pdf_ximage *ximage, FILE *image_file)
+pdf_include_page (pdf_ximage *ximage, FILE *image_file, const char *filename)
{
+ pdf_file *pf;
xform_info info;
- pdf_obj *contents, *contents_dict;
- pdf_obj *page_tree;
- pdf_obj *matrix;
- pdf_obj *bbox = NULL, *resources = NULL;
+ pdf_obj *contents = NULL, *catalog;
+ pdf_obj *page = NULL, *resources = NULL, *markinfo = NULL;
long page_no;
- pdf_file *pf;
- char *ident = pdf_ximage_get_ident(ximage);
-
- pdf_ximage_init_form_info(&info);
- pf = pdf_open(ident, image_file);
+ 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);
+
/*
- * Get Page Tree.
+ * Get Page.
*/
page_no = pdf_ximage_get_page(ximage);
if (page_no == 0)
page_no = 1;
- page_tree = pdf_get_page_obj(pf, page_no, &bbox, &resources);
- if (page_tree == NULL) {
- pdf_close(pf);
- return -1;
- }
-
- if (bbox != NULL) {
- pdf_obj *tmp;
-
- tmp = pdf_deref_obj(pdf_get_array(bbox, 0));
- info.bbox.llx = pdf_number_value(tmp);
- pdf_release_obj(tmp);
- tmp = pdf_deref_obj(pdf_get_array(bbox, 1));
- info.bbox.lly = pdf_number_value(tmp);
- pdf_release_obj(tmp);
- tmp = pdf_deref_obj(pdf_get_array(bbox, 2));
- info.bbox.urx = pdf_number_value(tmp);
- pdf_release_obj(tmp);
- tmp = pdf_deref_obj(pdf_get_array(bbox, 3));
- info.bbox.ury = pdf_number_value(tmp);
+ page = pdf_doc_get_page(pf, page_no, 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);
+ page = NULL;
+
/*
* Handle page content stream.
- * page_tree is now set to the correct page.
*/
- contents = pdf_get_page_content(page_tree);
- pdf_release_obj(page_tree);
- if (contents == NULL) {
- pdf_close(pf);
- return -1;
+ {
+ 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 *tmp;
-
- tmp = pdf_import_object(resources);
+ 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);
- resources = tmp;
- tmp = pdf_import_object(bbox);
- pdf_release_obj(bbox);
- bbox = tmp;
}
pdf_close(pf);
- 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));
-
- pdf_add_dict(contents_dict, pdf_new_name("BBox"), bbox);
+ pdf_ximage_set_form(ximage, &info, contents);
- 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));
+ return 0;
- pdf_add_dict(contents_dict, pdf_new_name("Matrix"), matrix);
+ 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_add_dict(contents_dict, pdf_new_name("Resources"), resources);
+ pdf_close(pf);
- pdf_ximage_set_form(ximage, &info, contents);
+ return -1;
- return 0;
+ too_recent:
+ pdf_close(pf);
+ WARN("PDF version of input file more recent than in output file.");
+ WARN("Use \"-V\" switch to change output PDF version.");
+ return -1;
}
+#ifdef XETEX
typedef enum {
OP_SETCOLOR = 1,
OP_CLOSEandCLIP = 2,
@@ -904,3 +966,4 @@ concat_stream (pdf_obj *dst, pdf_obj *src)
return -1;
}
+#endif
diff --git a/Build/source/texk/dvipdf-x/xsrc/epdf.h b/Build/source/texk/dvipdf-x/xsrc/epdf.h
index 698b5140b8e..2740bfc3cd3 100644
--- a/Build/source/texk/dvipdf-x/xsrc/epdf.h
+++ b/Build/source/texk/dvipdf-x/xsrc/epdf.h
@@ -2,7 +2,7 @@
This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
- Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata,
+ Copyright (C) 2002-2013 by Jin-Hwan Cho and Shunsaku Hirata,
the dvipdfmx project team.
Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
@@ -35,7 +35,8 @@
#define pdfbox_art 5
extern int pdf_copy_clip (FILE *image_file, int page_index, double x_user, double y_user);
-//extern int pdf_include_page (pdf_ximage *ximage, FILE *file, int page_index, int pdf_box);
-extern int pdf_include_page (pdf_ximage *ximage, FILE *file);
+
+extern int pdf_include_page (pdf_ximage *ximage, FILE *file,
+ const char *filename);
#endif /* _EPDF_H_ */
diff --git a/Build/source/texk/dvipdf-x/xsrc/mpost.c b/Build/source/texk/dvipdf-x/xsrc/mpost.c
index dc56d7f4f47..2d610d1f158 100644
--- a/Build/source/texk/dvipdf-x/xsrc/mpost.c
+++ b/Build/source/texk/dvipdf-x/xsrc/mpost.c
@@ -1213,7 +1213,8 @@ do_operator (const char *token, double x_user, double y_user)
pdf_color_cmykcolor(&color,
values[0], values[1],
values[2], values[3]);
- pdf_dev_set_color(&color);
+ pdf_dev_set_strokingcolor(&color);
+ pdf_dev_set_nonstrokingcolor(&color);
}
break;
case SETGRAY:
@@ -1221,7 +1222,8 @@ do_operator (const char *token, double x_user, double y_user)
error = pop_get_numbers(values, 1);
if (!error) {
pdf_color_graycolor(&color, values[0]);
- pdf_dev_set_color(&color);
+ pdf_dev_set_strokingcolor(&color);
+ pdf_dev_set_nonstrokingcolor(&color);
}
break;
case SETRGBCOLOR:
@@ -1229,7 +1231,8 @@ do_operator (const char *token, double x_user, double y_user)
if (!error) {
pdf_color_rgbcolor(&color,
values[0], values[1], values[2]);
- pdf_dev_set_color(&color);
+ pdf_dev_set_strokingcolor(&color);
+ pdf_dev_set_nonstrokingcolor(&color);
}
break;
diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfcolor.c b/Build/source/texk/dvipdf-x/xsrc/pdfcolor.c
index 77c9c499ea5..559a4b97712 100644
--- a/Build/source/texk/dvipdf-x/xsrc/pdfcolor.c
+++ b/Build/source/texk/dvipdf-x/xsrc/pdfcolor.c
@@ -26,7 +26,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
#include "system.h"
@@ -36,7 +36,7 @@
#include "dpxfile.h"
#include "pdfdoc.h"
-#include "pdfdev.h"
+#include "pdfdraw.h"
#include "pdfcolor.h"
@@ -48,6 +48,17 @@ pdf_color_set_verbose (void)
verbose++;
}
+/* This function returns PDF_COLORSPACE_TYPE_GRAY,
+ * PDF_COLORSPACE_TYPE_RGB or PDF_COLORSPACE_TYPE_CMYK.
+ */
+int
+pdf_color_type (const pdf_color *color)
+{
+ ASSERT(color);
+
+ return -color->num_components;
+}
+
int
pdf_color_rgbcolor (pdf_color *color, double r, double g, double b)
{
@@ -133,39 +144,54 @@ pdf_color_copycolor (pdf_color *color1, const pdf_color *color2)
memcpy(color1, color2, sizeof(pdf_color));
}
+/* Brighten up a color. f == 0 means no change, f == 1 means white. */
+void
+pdf_color_brighten_color (pdf_color *dst, const pdf_color *src, double f)
+{
+ ASSERT(dst && src);
+
+ if (f == 1.0) {
+ pdf_color_white(dst);
+ } else {
+ double f0, f1;
+ int n;
+
+ n = dst->num_components = src->num_components;
+ f1 = n == 4 ? 0.0 : f; /* n == 4 is CMYK, others are RGB and Gray */
+ f0 = 1.0-f;
+
+ while (n--)
+ dst->values[n] = f0 * src->values[n] + f1;
+ }
+}
+
int
-pdf_color_is_white (pdf_color *color)
+pdf_color_is_white (const pdf_color *color)
{
- int is_white = 0;
+ int n;
+ double f;
ASSERT(color);
- switch (color->num_components) {
- case 1:
- if (color->values[0] == 1.0)
- is_white = 1;
- break;
- case 4:
- if (color->values[0] == 0.0 &&
- color->values[1] == 0.0 &&
- color->values[2] == 0.0 &&
- color->values[3] == 0.0) {
- is_white = 1;
- }
- break;
- case 3:
- if (color->values[0] == 1.0 &&
- color->values[1] == 1.0 &&
- color->values[2] == 1.0) {
- is_white = 1;
- }
- break;
- default:
- is_white = 0;
- break;
- }
+ n = color->num_components;
+ f = n == 4 ? 0.0 : 1.0; /* n == 4 is CMYK, others are RGB and Gray */
+
+ while (n--)
+ if (color->values[n] != f)
+ return 0;
+
+ return 1;
+}
- return is_white;
+int
+pdf_color_to_string (const pdf_color *color, char *buffer)
+{
+ int i, len = 0;
+
+ for (i = 0; i < color->num_components; i++) {
+ len += sprintf(buffer+len, " %g", ROUND(color->values[i], 0.001));
+ }
+ return len;
}
pdf_color current_fill = {
@@ -178,42 +204,26 @@ pdf_color current_stroke = {
{0.0, 0.0, 0.0, 0.0}
};
-#if 0
/*
* This routine is not a real color matching.
*/
-static int
-compare_color (const pdf_color *color1, const pdf_color *color2)
+int
+pdf_color_compare (const pdf_color *color1, const pdf_color *color2)
{
- if (color1->num_components != color2->num_components)
+ int n = color1->num_components;
+
+ if (n != color2->num_components)
return -1;
- switch (color1->num_components) {
- case 4:
- if (color1->values[0] == color2->values[0] &&
- color1->values[1] == color2->values[1] &&
- color1->values[2] == color2->values[2] &&
- color1->values[3] == color2->values[3])
- return 0;
- break;
- case 3:
- if (color1->values[0] == color2->values[0] &&
- color1->values[1] == color2->values[1] &&
- color1->values[2] == color2->values[2])
- return 0;
- break;
- case 1:
- if (color1->values[0] == color2->values[0])
- return 0;
- break;
- }
+ while (n--)
+ if (color1->values[n] != color2->values[n])
+ return -1;
- return -1;
+ return 0;
}
-#endif
int
-pdf_color_is_valid (pdf_color *color)
+pdf_color_is_valid (const pdf_color *color)
{
int i, num_components;
@@ -277,7 +287,7 @@ pdf_color_push (pdf_color *sc, pdf_color *fc)
color_stack.current++;
pdf_color_copycolor(&color_stack.stroke[color_stack.current], sc);
pdf_color_copycolor(&color_stack.fill[color_stack.current], fc);
- pdf_dev_reset_color();
+ pdf_dev_reset_color(0);
}
return;
}
@@ -289,7 +299,7 @@ pdf_color_pop (void)
WARN("Color stack underflow. Just ignore.");
} else {
color_stack.current--;
- pdf_dev_reset_color();
+ pdf_dev_reset_color(0);
}
return;
}
diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfcolor.h b/Build/source/texk/dvipdf-x/xsrc/pdfcolor.h
index 1d5e0f19116..e5edabd09c6 100644
--- a/Build/source/texk/dvipdf-x/xsrc/pdfcolor.h
+++ b/Build/source/texk/dvipdf-x/xsrc/pdfcolor.h
@@ -51,15 +51,24 @@ typedef struct
extern void pdf_color_set_verbose (void);
+extern int pdf_color_type (const pdf_color *color);
extern int pdf_color_rgbcolor (pdf_color *color,
double r, double g, double b);
extern int pdf_color_cmykcolor (pdf_color *color,
double c, double m, double y, double k);
extern int pdf_color_graycolor (pdf_color *color, double g);
+#define pdf_color_black(c) pdf_color_graycolor(c, 0.0);
+#define pdf_color_white(c) pdf_color_graycolor(c, 1.0);
+
extern void pdf_color_copycolor (pdf_color *color1, const pdf_color *color2);
+extern void pdf_color_brighten_color (pdf_color *dst, const pdf_color *src, double f);
+
+extern int pdf_color_compare (const pdf_color *color1, const pdf_color *color2);
+
+extern int pdf_color_is_white (const pdf_color *color);
+extern int pdf_color_is_valid (const pdf_color *color);
-extern int pdf_color_is_white (pdf_color *color);
-extern int pdf_color_is_valid (pdf_color *color);
+extern int pdf_color_to_string (const pdf_color *color, char *buffer);
/* Not check size */
extern pdf_obj *iccp_get_rendering_intent (const void *profile, long proflen);
diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfdev.c b/Build/source/texk/dvipdf-x/xsrc/pdfdev.c
index 41e6630c26e..441c959bcfa 100644
--- a/Build/source/texk/dvipdf-x/xsrc/pdfdev.c
+++ b/Build/source/texk/dvipdf-x/xsrc/pdfdev.c
@@ -1268,148 +1268,6 @@ pdf_dev_reset_fonts (void)
text_state.is_mb = 0;
}
-void
-pdf_dev_reset_color(void)
-{
- pdf_color *sc, *fc;
-
- if (pdf_dev_get_param(PDF_DEV_PARAM_COLORMODE)) {
- pdf_color_get_current(&sc, &fc);
- pdf_dev_set_strokingcolor(sc);
- pdf_dev_set_nonstrokingcolor(fc);
- }
- return;
-}
-
-static int
-color_to_string (pdf_color *color, char *buffer)
-{
- int i, len = 0;
-
- for (i = 0; i < color->num_components; i++) {
- len += sprintf(format_buffer+len, " %g", ROUND(color->values[i], 0.001));
- }
- return len;
-}
-
-void
-pdf_dev_set_color (pdf_color *color)
-{
- int len;
-
- if (!pdf_dev_get_param(PDF_DEV_PARAM_COLORMODE)) {
- WARN("Ignore color option was set. Just ignore.");
- return;
- } else if (!(color && pdf_color_is_valid(color))) {
- WARN("No valid color is specified. Just ignore.");
- return;
- }
-
- graphics_mode();
- len = color_to_string(color, format_buffer);
- format_buffer[len++] = ' ';
- switch (color->num_components) {
- case 3:
- format_buffer[len++] = 'R';
- format_buffer[len++] = 'G';
- break;
- case 4:
- format_buffer[len++] = 'K';
- break;
- case 1:
- format_buffer[len++] = 'G';
- break;
- default: /* already verified the given color */
- break;
- }
- strncpy(format_buffer+len, format_buffer, len);
- len = len << 1;
- switch (color->num_components) {
- case 3:
- format_buffer[len-2] = 'r';
- format_buffer[len-1] = 'g';
- break;
- case 4:
- format_buffer[len-1] = 'k';
- break;
- case 1:
- format_buffer[len-1] = 'g';
- break;
- default: /* already verified the given color */
- break;
- }
- pdf_doc_add_page_content(format_buffer, len);
- return;
-}
-
-void
-pdf_dev_set_strokingcolor (pdf_color *color)
-{
- int len;
-
- if (!pdf_dev_get_param(PDF_DEV_PARAM_COLORMODE)) {
- WARN("Ignore color option was set. Just ignore.");
- return;
- } else if (!(color && pdf_color_is_valid(color))) {
- WARN("No valid color is specified. Just ignore.");
- return;
- }
-
- graphics_mode();
- len = color_to_string(color, format_buffer);
- format_buffer[len++] = ' ';
- switch (color->num_components) {
- case 3:
- format_buffer[len++] = 'R';
- format_buffer[len++] = 'G';
- break;
- case 4:
- format_buffer[len++] = 'K';
- break;
- case 1:
- format_buffer[len++] = 'G';
- break;
- default: /* already verified the given color */
- break;
- }
- pdf_doc_add_page_content(format_buffer, len);
- return;
-}
-
-void
-pdf_dev_set_nonstrokingcolor (pdf_color *color)
-{
- int len;
-
- if (!pdf_dev_get_param(PDF_DEV_PARAM_COLORMODE)) {
- WARN("Ignore color option was set. Just ignore.");
- return;
- } else if (!(color && pdf_color_is_valid(color))) {
- WARN("No valid color is specified. Just ignore.");
- return;
- }
-
- graphics_mode();
- len = color_to_string(color, format_buffer);
- format_buffer[len++] = ' ';
- switch (color->num_components) {
- case 3:
- format_buffer[len++] = 'r';
- format_buffer[len++] = 'g';
- break;
- case 4:
- format_buffer[len++] = 'k';
- break;
- case 1:
- format_buffer[len++] = 'g';
- break;
- default: /* already verified the given color */
- break;
- }
- pdf_doc_add_page_content(format_buffer, len);
- return;
-}
-
/* Not working */
void
pdf_dev_set_origin (double phys_x, double phys_y)
@@ -1436,7 +1294,7 @@ pdf_dev_bop (const pdf_tmatrix *M)
pdf_dev_concat(M);
pdf_dev_reset_fonts();
- pdf_dev_reset_color();
+ pdf_dev_reset_color(0);
}
void
diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfdev.h b/Build/source/texk/dvipdf-x/xsrc/pdfdev.h
index 25bac2ecd47..20201309431 100644
--- a/Build/source/texk/dvipdf-x/xsrc/pdfdev.h
+++ b/Build/source/texk/dvipdf-x/xsrc/pdfdev.h
@@ -202,15 +202,10 @@ extern void pdf_dev_set_param (int param_type, int value);
* For pdf_doc, pdf_draw and others.
*/
-/* Force reselecting font and color:
+/* Force reselecting font:
* XFrom (content grabbing) and Metapost support want them.
*/
extern void pdf_dev_reset_fonts (void);
-extern void pdf_dev_reset_color (void);
-
-extern void pdf_dev_set_color (pdf_color *color);
-extern void pdf_dev_set_strokingcolor (pdf_color *color);
-extern void pdf_dev_set_nonstrokingcolor (pdf_color *color);
/* Initialization of transformation matrix with M and others.
* They are called within pdf_doc_begin_page() and pdf_doc_end_page().
diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfdoc.c b/Build/source/texk/dvipdf-x/xsrc/pdfdoc.c
index 05846ff9300..ca9aa40be42 100644
--- a/Build/source/texk/dvipdf-x/xsrc/pdfdoc.c
+++ b/Build/source/texk/dvipdf-x/xsrc/pdfdoc.c
@@ -26,8 +26,9 @@
* TODO: Many things...
* {begin,end}_{bead,article}, box stack, name tree (not limited to dests)...
*/
-#if HAVE_CONFIG_H
-#include "config.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
#endif
#include <time.h>
@@ -235,6 +236,9 @@ typedef struct pdf_doc
struct name_dict *names;
+ int check_gotos;
+ struct ht_table gotos;
+
struct {
int outline_open_depth;
double annot_grow;
@@ -367,9 +371,11 @@ doc_get_page_entry (pdf_doc *p, unsigned long page_no)
static void pdf_doc_init_page_tree (pdf_doc *p, double media_width, double media_height);
static void pdf_doc_close_page_tree (pdf_doc *p);
-static void pdf_doc_init_names (pdf_doc *p);
+static void pdf_doc_init_names (pdf_doc *p, int check_gotos);
static void pdf_doc_close_names (pdf_doc *p);
+static void pdf_doc_add_goto (pdf_obj *annot_dict);
+
static void pdf_doc_init_docinfo (pdf_doc *p);
static void pdf_doc_close_docinfo (pdf_doc *p);
@@ -525,8 +531,8 @@ pdf_doc_close_docinfo (pdf_doc *p)
}
}
- banner = NEW(strlen("xdvipdfmx")+strlen(VERSION)+4, char);
- sprintf(banner, "%s (%s)", "xdvipdfmx", VERSION);
+ banner = NEW(strlen("dvipdfmx")+strlen(VERSION)+4, char);
+ sprintf(banner, "%s (%s)", "dvipdfmx", VERSION);
pdf_add_dict(docinfo,
pdf_new_name("Producer"),
pdf_new_string(banner, strlen(banner)));
@@ -871,6 +877,242 @@ pdf_doc_close_page_tree (pdf_doc *p)
return;
}
+/*
+ * From PDFReference15_v6.pdf (p.119 and p.834)
+ *
+ * MediaBox rectangle (Required; inheritable)
+ *
+ * The media box defines the boundaries of the physical medium on which the
+ * page is to be printed. It may include any extended area surrounding the
+ * finished page for bleed, printing marks, or other such purposes. It may
+ * also include areas close to the edges of the medium that cannot be marked
+ * because of physical limitations of the output device. Content falling
+ * outside this boundary can safely be discarded without affecting the
+ * meaning of the PDF file.
+ *
+ * CropBox rectangle (Optional; inheritable)
+ *
+ * The crop box defines the region to which the contents of the page are to be
+ * clipped (cropped) when displayed or printed. Unlike the other boxes, the
+ * crop box has no defined meaning in terms of physical page geometry or
+ * intended use; it merely imposes clipping on the page contents. However,
+ * in the absence of additional information (such as imposition instructions
+ * specified in a JDF or PJTF job ticket), the crop box will determine how
+ * the page's contents are to be positioned on the output medium. The default
+ * value is the page's media box.
+ *
+ * BleedBox rectangle (Optional; PDF 1.3)
+ *
+ * The bleed box (PDF 1.3) defines the region to which the contents of the
+ * page should be clipped when output in a production environment. This may
+ * include any extra "bleed area" needed to accommodate the physical
+ * limitations of cutting, folding, and trimming equipment. The actual printed
+ * page may include printing marks that fall outside the bleed box.
+ * The default value is the page's crop box.
+ *
+ * TrimBox rectangle (Optional; PDF 1.3)
+ *
+ * The trim box (PDF 1.3) defines the intended dimensions of the finished page
+ * after trimming. It may be smaller than the media box, to allow for
+ * production-related content such as printing instructions, cut marks, or
+ * color bars. The default value is the page's crop box.
+ *
+ * ArtBox rectangle (Optional; PDF 1.3)
+ *
+ * The art box (PDF 1.3) defines the extent of the page's meaningful content
+ * (including potential white space) as intended by the page's creator.
+ * The default value is the page's crop box.
+ *
+ * Rotate integer (Optional; inheritable)
+ *
+ * The number of degrees by which the page should be rotated clockwise when
+ * displayed or printed. The value must be a multiple of 90. Default value: 0.
+ */
+
+pdf_obj *
+pdf_doc_get_page (pdf_file *pf, long page_no, long *count_p,
+ pdf_rect *bbox, pdf_obj **resources_p) {
+ pdf_obj *page_tree = NULL;
+ pdf_obj *resources = NULL, *box = NULL, *rotate = NULL;
+ pdf_obj *catalog;
+
+ catalog = pdf_file_get_catalog(pf);
+
+ page_tree = pdf_deref_obj(pdf_lookup_dict(catalog, "Pages"));
+
+ if (!PDF_OBJ_DICTTYPE(page_tree))
+ goto error;
+
+ {
+ long count;
+ pdf_obj *tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "Count"));
+ if (!PDF_OBJ_NUMBERTYPE(tmp)) {
+ if (tmp)
+ pdf_release_obj(tmp);
+ goto error;
+ }
+ count = pdf_number_value(tmp);
+ pdf_release_obj(tmp);
+ if (count_p)
+ *count_p = count;
+ if (page_no <= 0 || page_no > count) {
+ WARN("Page %ld does not exist.", page_no);
+ goto error_silent;
+ }
+ }
+
+ /*
+ * Seek correct page. Get MediaBox, CropBox and Resources.
+ * (Note that these entries can be inherited.)
+ */
+ {
+ pdf_obj *media_box = NULL, *crop_box = NULL, *kids, *tmp;
+ int depth = PDF_OBJ_MAX_DEPTH;
+ long page_idx = page_no-1, kids_length = 1, i = 0;
+
+ while (--depth && i != kids_length) {
+ if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "MediaBox")))) {
+ if (media_box)
+ pdf_release_obj(media_box);
+ media_box = tmp;
+ }
+
+ if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "CropBox")))) {
+ if (crop_box)
+ pdf_release_obj(crop_box);
+ crop_box = tmp;
+ }
+
+ if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "Rotate")))) {
+ if (rotate)
+ pdf_release_obj(rotate);
+ rotate = tmp;
+ }
+
+ if ((tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "Resources")))) {
+ if (resources)
+ pdf_release_obj(resources);
+ resources = tmp;
+ }
+
+ kids = pdf_deref_obj(pdf_lookup_dict(page_tree, "Kids"));
+ if (!kids)
+ break;
+ else if (!PDF_OBJ_ARRAYTYPE(kids)) {
+ pdf_release_obj(kids);
+ goto error;
+ }
+ kids_length = pdf_array_length(kids);
+
+ for (i = 0; i < kids_length; i++) {
+ long count;
+
+ pdf_release_obj(page_tree);
+ page_tree = pdf_deref_obj(pdf_get_array(kids, i));
+ if (!PDF_OBJ_DICTTYPE(page_tree))
+ goto error;
+
+ tmp = pdf_deref_obj(pdf_lookup_dict(page_tree, "Count"));
+ if (PDF_OBJ_NUMBERTYPE(tmp)) {
+ /* Pages object */
+ count = pdf_number_value(tmp);
+ pdf_release_obj(tmp);
+ } else if (!tmp)
+ /* Page object */
+ count = 1;
+ else {
+ pdf_release_obj(tmp);
+ goto error;
+ }
+
+ if (page_idx < count)
+ break;
+
+ page_idx -= count;
+ }
+
+ pdf_release_obj(kids);
+ }
+
+ if (!depth || kids_length == i) {
+ if (media_box)
+ pdf_release_obj(media_box);
+ if (crop_box)
+ pdf_release_obj(crop_box);
+ goto error;
+ }
+
+ if (crop_box)
+ box = crop_box;
+ else
+ if (!(box = pdf_deref_obj(pdf_lookup_dict(page_tree, "ArtBox"))) &&
+ !(box = pdf_deref_obj(pdf_lookup_dict(page_tree, "TrimBox"))) &&
+ !(box = pdf_deref_obj(pdf_lookup_dict(page_tree, "BleedBox"))) &&
+ media_box) {
+ box = media_box;
+ media_box = NULL;
+ }
+ if (media_box)
+ pdf_release_obj(media_box);
+ }
+
+ if (!PDF_OBJ_ARRAYTYPE(box) || pdf_array_length(box) != 4 ||
+ !PDF_OBJ_DICTTYPE(resources))
+ goto error;
+
+ if (PDF_OBJ_NUMBERTYPE(rotate)) {
+ if (pdf_number_value(rotate))
+ WARN("<< /Rotate %d >> found. (Not supported yet)",
+ (int) pdf_number_value(rotate));
+ pdf_release_obj(rotate);
+ rotate = NULL;
+ } else if (rotate)
+ goto error;
+
+ {
+ int i;
+
+ for (i = 4; i--; ) {
+ double x;
+ pdf_obj *tmp = pdf_deref_obj(pdf_get_array(box, i));
+ if (!PDF_OBJ_NUMBERTYPE(tmp)) {
+ pdf_release_obj(tmp);
+ goto error;
+ }
+ x = pdf_number_value(tmp);
+ switch (i) {
+ case 0: bbox->llx = x; break;
+ case 1: bbox->lly = x; break;
+ case 2: bbox->urx = x; break;
+ case 3: bbox->ury = x; break;
+ }
+ pdf_release_obj(tmp);
+ }
+ }
+
+ pdf_release_obj(box);
+
+ if (resources_p)
+ *resources_p = resources;
+ else if (resources)
+ pdf_release_obj(resources);
+
+ return page_tree;
+
+ error:
+ WARN("Cannot parse document. Broken PDF file?");
+ error_silent:
+ if (box)
+ pdf_release_obj(box);
+ if (rotate)
+ pdf_release_obj(rotate);
+ if (resources)
+ pdf_release_obj(resources);
+ if (page_tree)
+ pdf_release_obj(page_tree);
+
+ return NULL;
+}
#ifndef BOOKMARKS_OPEN_DEFAULT
#define BOOKMARKS_OPEN_DEFAULT 0
@@ -1118,6 +1360,8 @@ pdf_doc_bookmarks_add (pdf_obj *dict, int is_open)
p->outlines.current = item;
+ pdf_doc_add_goto(dict);
+
return;
}
@@ -1160,7 +1404,7 @@ static const char *name_dict_categories[] = {
#define NUM_NAME_CATEGORY (sizeof(name_dict_categories)/sizeof(name_dict_categories[0]))
static void
-pdf_doc_init_names (pdf_doc *p)
+pdf_doc_init_names (pdf_doc *p, int check_gotos)
{
int i;
@@ -1169,11 +1413,19 @@ pdf_doc_init_names (pdf_doc *p)
p->names = NEW(NUM_NAME_CATEGORY + 1, struct name_dict);
for (i = 0; i < NUM_NAME_CATEGORY; i++) {
p->names[i].category = name_dict_categories[i];
- p->names[i].data = NULL;
+ p->names[i].data = strcmp(name_dict_categories[i], "Dests") ?
+ NULL : pdf_new_name_tree();
+ /*
+ * We need a non-null entry for PDF destinations in order to find
+ * broken links even if no destination is defined in the DVI file.
+ */
}
p->names[NUM_NAME_CATEGORY].category = NULL;
p->names[NUM_NAME_CATEGORY].data = NULL;
+ p->check_gotos = check_gotos;
+ ht_init_table(&p->gotos, (void (*) (void *)) pdf_release_obj);
+
return;
}
@@ -1201,6 +1453,134 @@ pdf_doc_add_names (const char *category,
}
static void
+pdf_doc_add_goto (pdf_obj *annot_dict)
+{
+ pdf_obj *subtype = NULL, *A = NULL, *S = NULL, *D = NULL, *D_new, *dict;
+ const char *dest, *key;
+
+ if (!pdoc.check_gotos)
+ return;
+
+ /*
+ * An annotation dictionary coming from an annotation special
+ * must have a "Subtype". An annotation dictionary coming from
+ * an outline special has none.
+ */
+ subtype = pdf_deref_obj(pdf_lookup_dict(annot_dict, "Subtype"));
+ if (subtype) {
+ if (PDF_OBJ_UNDEFINED(subtype))
+ goto undefined;
+ else if (!PDF_OBJ_NAMETYPE(subtype))
+ goto error;
+ else if (strcmp(pdf_name_value(subtype), "Link"))
+ goto cleanup;
+ }
+
+ dict = annot_dict;
+ key = "Dest";
+ D = pdf_deref_obj(pdf_lookup_dict(annot_dict, key));
+ if (PDF_OBJ_UNDEFINED(D))
+ goto undefined;
+
+ A = pdf_deref_obj(pdf_lookup_dict(annot_dict, "A"));
+ if (A) {
+ if (PDF_OBJ_UNDEFINED(A))
+ goto undefined;
+ else if (D || !PDF_OBJ_DICTTYPE(A))
+ goto error;
+ else {
+ S = pdf_deref_obj(pdf_lookup_dict(A, "S"));
+ if (PDF_OBJ_UNDEFINED(S))
+ goto undefined;
+ else if (!PDF_OBJ_NAMETYPE(S))
+ goto error;
+ else if (strcmp(pdf_name_value(S), "GoTo"))
+ goto cleanup;
+
+ dict = A;
+ key = "D";
+ D = pdf_deref_obj(pdf_lookup_dict(A, key));
+ }
+ }
+
+ if (PDF_OBJ_STRINGTYPE(D))
+ dest = (char *) pdf_string_value(D);
+#if 0
+ /* Names as destinations are not supported by dvipdfmx */
+ else if (PDF_OBJ_NAMETYPE(D))
+ dest = pdf_name_value(D);
+#endif
+ else if (PDF_OBJ_ARRAYTYPE(D))
+ goto cleanup;
+ else if (PDF_OBJ_UNDEFINED(D))
+ goto undefined;
+ else
+ goto error;
+
+ D_new = ht_lookup_table(&pdoc.gotos, dest, strlen(dest));
+ if (!D_new) {
+ char buf[10];
+
+ /* We use hexadecimal notation for our numeric destinations.
+ * Other bases (e.g., 10+26 or 10+2*26) would be more efficient.
+ */
+ sprintf(buf, "%lx", ht_table_size(&pdoc.gotos));
+ D_new = pdf_new_string(buf, strlen(buf));
+ ht_append_table(&pdoc.gotos, dest, strlen(dest), D_new);
+ }
+
+ {
+ pdf_obj *key_obj = pdf_new_name(key);
+ if (!pdf_add_dict(dict, key_obj, pdf_link_obj(D_new)))
+ pdf_release_obj(key_obj);
+ }
+
+ cleanup:
+ if (subtype)
+ pdf_release_obj(subtype);
+ if (A)
+ pdf_release_obj(A);
+ if (S)
+ pdf_release_obj(S);
+ if (D)
+ pdf_release_obj(D);
+
+ return;
+
+ error:
+ WARN("Unknown PDF annotation format. Output file may be broken.");
+ goto cleanup;
+
+ undefined:
+ WARN("Cannot optimize PDF annotations. Output file may be broken."
+ " Please restart with option \"-C 0x10\"\n");
+ goto cleanup;
+}
+
+static void
+warn_undef_dests (struct ht_table *dests, struct ht_table *gotos)
+{
+ struct ht_iter iter;
+
+ if (ht_set_iter(gotos, &iter) < 0)
+ return;
+
+ do {
+ int keylen;
+ char *key = ht_iter_getkey(&iter, &keylen);
+ if (!ht_lookup_table(dests, key, keylen)) {
+ char *dest = NEW(keylen+1, char);
+ memcpy(dest, key, keylen);
+ dest[keylen] = 0;
+ WARN("PDF destination \"%s\" not defined.", dest);
+ RELEASE(dest);
+ }
+ } while (ht_iter_next(&iter) >= 0);
+
+ ht_clear_iter(&iter);
+}
+
+static void
pdf_doc_close_names (pdf_doc *p)
{
pdf_obj *tmp;
@@ -1208,15 +1588,30 @@ pdf_doc_close_names (pdf_doc *p)
for (i = 0; p->names[i].category != NULL; i++) {
if (p->names[i].data) {
+ struct ht_table *data = p->names[i].data;
pdf_obj *name_tree;
+ long count;
+
+ if (!pdoc.check_gotos || strcmp(p->names[i].category, "Dests"))
+ name_tree = pdf_names_create_tree(data, &count, NULL);
+ else {
+ name_tree = pdf_names_create_tree(data, &count, &pdoc.gotos);
+
+ if (verbose && count < data->count)
+ MESG("\nRemoved %ld unused PDF destinations\n", data->count-count);
+
+ if (count < pdoc.gotos.count)
+ warn_undef_dests(data, &pdoc.gotos);
+ }
- name_tree = pdf_names_create_tree(p->names[i].data);
- if (!p->root.names) {
- p->root.names = pdf_new_dict();
+ if (name_tree) {
+ if (!p->root.names)
+ p->root.names = pdf_new_dict();
+ pdf_add_dict(p->root.names,
+ pdf_new_name(p->names[i].category),
+ pdf_ref_obj(name_tree));
+ pdf_release_obj(name_tree);
}
- pdf_add_dict(p->root.names,
- pdf_new_name(p->names[i].category), pdf_ref_obj(name_tree));
- pdf_release_obj(name_tree);
pdf_delete_name_tree(&p->names[i].data);
}
}
@@ -1243,54 +1638,58 @@ pdf_doc_close_names (pdf_doc *p)
RELEASE(p->names);
p->names = NULL;
+ ht_clear_table(&p->gotos);
+
return;
}
void
-pdf_doc_add_annot (unsigned page_no, const pdf_rect *rect, pdf_obj *annot_dict)
+pdf_doc_add_annot (unsigned page_no, const pdf_rect *rect,
+ pdf_obj *annot_dict, int new_annot)
{
pdf_doc *p = &pdoc;
pdf_page *page;
pdf_obj *rect_array;
double annot_grow = p->opt.annot_grow;
+ double xpos, ypos;
+ pdf_rect mediabox, annbox;
page = doc_get_page_entry(p, page_no);
if (!page->annots)
page->annots = pdf_new_array();
-#if 1
- {
- pdf_rect mediabox;
-
- pdf_doc_get_mediabox(page_no, &mediabox);
- if (rect->llx < mediabox.llx ||
- rect->urx > mediabox.urx ||
- rect->lly < mediabox.lly ||
- rect->ury > mediabox.ury) {
- WARN("Annotation out of page boundary.");
- WARN("Current page's MediaBox: [%g %g %g %g]",
- mediabox.llx, mediabox.lly, mediabox.urx, mediabox.ury);
- WARN("Annotation: [%g %g %g %g]",
- rect->llx, rect->lly, rect->urx, rect->ury);
- WARN("Maybe incorrect paper size specified.");
- }
- if (rect->llx > rect->urx || rect->lly > rect->ury) {
- WARN("Rectangle with negative width/height: [%g %g %g %g]",
- rect->llx, rect->lly, rect->urx, rect->ury);
- }
+ pdf_doc_get_mediabox(page_no, &mediabox);
+ pdf_dev_get_coord(&xpos, &ypos);
+ annbox.llx = rect->llx - xpos; annbox.lly = rect->lly - ypos;
+ annbox.urx = rect->urx - xpos; annbox.ury = rect->ury - ypos;
+
+ if (annbox.llx < mediabox.llx || annbox.urx > mediabox.urx ||
+ annbox.lly < mediabox.lly || annbox.ury > mediabox.ury) {
+ WARN("Annotation out of page boundary.");
+ WARN("Current page's MediaBox: [%g %g %g %g]",
+ mediabox.llx, mediabox.lly, mediabox.urx, mediabox.ury);
+ WARN("Annotation: [%g %g %g %g]",
+ annbox.llx, annbox.lly, annbox.urx, annbox.ury);
+ WARN("Maybe incorrect paper size specified.");
+ }
+ if (annbox.llx > annbox.urx || annbox.lly > annbox.ury) {
+ WARN("Rectangle with negative width/height: [%g %g %g %g]",
+ annbox.llx, annbox.lly, annbox.urx, annbox.ury);
}
-#endif
rect_array = pdf_new_array();
- pdf_add_array(rect_array, pdf_new_number(ROUND(rect->llx - annot_grow, 0.001)));
- pdf_add_array(rect_array, pdf_new_number(ROUND(rect->lly - annot_grow, 0.001)));
- pdf_add_array(rect_array, pdf_new_number(ROUND(rect->urx + annot_grow, 0.001)));
- pdf_add_array(rect_array, pdf_new_number(ROUND(rect->ury + annot_grow, 0.001)));
+ pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.llx - annot_grow, 0.001)));
+ pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.lly - annot_grow, 0.001)));
+ pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.urx + annot_grow, 0.001)));
+ pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.ury + annot_grow, 0.001)));
pdf_add_dict (annot_dict, pdf_new_name("Rect"), rect_array);
pdf_add_array(page->annots, pdf_ref_obj(annot_dict));
+ if (new_annot)
+ pdf_doc_add_goto(annot_dict);
+
return;
}
@@ -1874,14 +2273,15 @@ pdf_doc_finish_page (pdf_doc *p)
}
-static pdf_color bgcolor = { 1, { 1.0 } };
+static pdf_color bgcolor;
+
void
pdf_doc_set_bgcolor (const pdf_color *color)
{
if (color)
- memcpy(&bgcolor, color, sizeof(pdf_color));
+ pdf_color_copycolor(&bgcolor, color);
else { /* as clear... */
- pdf_color_graycolor(&bgcolor, 1.0);
+ pdf_color_white(&bgcolor);
}
}
@@ -1910,10 +2310,8 @@ doc_fill_page_background (pdf_doc *p)
currentpage->contents = currentpage->background;
pdf_dev_gsave();
- //pdf_color_push();
pdf_dev_set_nonstrokingcolor(&bgcolor);
pdf_dev_rectfill(r.llx, r.lly, r.urx - r.llx, r.ury - r.lly);
- //pdf_color_pop();
pdf_dev_grestore();
currentpage->contents = saved_content;
@@ -1974,7 +2372,8 @@ void
pdf_open_document (const char *filename,
int do_encryption,
double media_width, double media_height,
- double annot_grow_amount, int bookmark_open_depth)
+ double annot_grow_amount, int bookmark_open_depth,
+ int check_gotos)
{
pdf_doc *p = &pdoc;
@@ -2001,14 +2400,17 @@ pdf_open_document (const char *filename,
pdf_doc_init_bookmarks(p, bookmark_open_depth);
pdf_doc_init_articles (p);
- pdf_doc_init_names (p);
+ pdf_doc_init_names (p, check_gotos);
pdf_doc_init_page_tree(p, media_width, media_height);
+ pdf_doc_set_bgcolor(NULL);
+
if (do_encryption) {
pdf_obj *encrypt = pdf_encrypt_obj();
- pdf_set_encrypt(encrypt, pdf_enc_id_array());
+ pdf_set_encrypt(encrypt);
pdf_release_obj(encrypt);
}
+ pdf_set_id(pdf_enc_id_array());
/* Create a default name for thumbnail image files */
if (manual_thumb_enabled) {
@@ -2137,6 +2539,8 @@ pdf_doc_begin_grabbing (const char *ident,
struct form_list_node *fnode;
xform_info info;
+ pdf_dev_push_gstate();
+
fnode = NEW(1, struct form_list_node);
fnode->prev = p->pending_forms;
@@ -2187,7 +2591,7 @@ pdf_doc_begin_grabbing (const char *ident,
* current font and color to the object stream.
*/
pdf_dev_reset_fonts();
- pdf_dev_reset_color();
+ pdf_dev_reset_color(1); /* force color operators to be added to stream */
return xobj_id;
}
@@ -2229,9 +2633,11 @@ pdf_doc_end_grabbing (pdf_obj *attrib)
if (attrib) pdf_release_obj(attrib);
p->pending_forms = fnode->prev;
+
+ pdf_dev_pop_gstate();
- /* Here we do not need pdf_dev_reset_color(). */
pdf_dev_reset_fonts();
+ pdf_dev_reset_color(0);
RELEASE(fnode);
@@ -2241,17 +2647,16 @@ pdf_doc_end_grabbing (pdf_obj *attrib)
static struct
{
int dirty;
+ int broken;
pdf_obj *annot_dict;
pdf_rect rect;
-} breaking_state = {0, NULL, {0.0, 0.0, 0.0, 0.0}};
+} breaking_state = {0, 0, NULL, {0.0, 0.0, 0.0, 0.0}};
static void
reset_box (void)
{
- breaking_state.rect.llx = 10000.0; /* large value */
- breaking_state.rect.lly = 10000.0; /* large value */
- breaking_state.rect.urx = 0.0; /* small value */
- breaking_state.rect.ury = 0.0; /* small value */
+ breaking_state.rect.llx = breaking_state.rect.lly = HUGE_VAL;
+ breaking_state.rect.urx = breaking_state.rect.ury = -HUGE_VAL;
breaking_state.dirty = 0;
}
@@ -2259,6 +2664,7 @@ void
pdf_doc_begin_annot (pdf_obj *dict)
{
breaking_state.annot_dict = dict;
+ breaking_state.broken = 0;
reset_box();
}
@@ -2278,9 +2684,11 @@ pdf_doc_break_annot (void)
/* Copy dict */
annot_dict = pdf_new_dict();
pdf_merge_dict(annot_dict, breaking_state.annot_dict);
- pdf_doc_add_annot(pdf_doc_current_page_number(),
- &(breaking_state.rect), annot_dict);
+ pdf_doc_add_annot(pdf_doc_current_page_number(), &(breaking_state.rect),
+ annot_dict, !breaking_state.broken);
pdf_release_obj(annot_dict);
+
+ breaking_state.broken = 1;
}
reset_box();
}
diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfdoc.h b/Build/source/texk/dvipdf-x/xsrc/pdfdoc.h
index 5e65da405e3..5772758af93 100644
--- a/Build/source/texk/dvipdf-x/xsrc/pdfdoc.h
+++ b/Build/source/texk/dvipdf-x/xsrc/pdfdoc.h
@@ -35,7 +35,8 @@ extern void pdf_doc_set_verbose (void);
extern void pdf_open_document (const char *filename,
int do_encryption,
double media_width, double media_height,
- double annot_grow_amount, int bookmark_open_depth);
+ double annot_grow_amount, int bookmark_open_depth,
+ int check_gotos);
extern void pdf_close_document (void);
@@ -55,6 +56,9 @@ extern pdf_obj *pdf_doc_get_reference (const char *category);
#define pdf_doc_names() pdf_doc_get_dictionary("Names")
#define pdf_doc_this_page() pdf_doc_get_dictionary("@THISPAGE")
+extern pdf_obj *pdf_doc_get_page (pdf_file *pf, long page_no, long *count_p,
+ pdf_rect *bbox, pdf_obj **resources_p);
+
extern long pdf_doc_current_page_number (void);
extern pdf_obj *pdf_doc_current_page_resources (void);
@@ -110,7 +114,9 @@ extern void pdf_doc_end_grabbing (pdf_obj *attrib);
/* Annotation */
extern void pdf_doc_add_annot (unsigned page_no,
- const pdf_rect *rect, pdf_obj *annot_dict);
+ const pdf_rect *rect,
+ pdf_obj *annot_dict,
+ int new_annot);
/* Annotation with auto- clip and line (or page) break */
extern void pdf_doc_begin_annot (pdf_obj *dict);
diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfdraw.c b/Build/source/texk/dvipdf-x/xsrc/pdfdraw.c
index 9f1f0713fc6..878fc164e09 100644
--- a/Build/source/texk/dvipdf-x/xsrc/pdfdraw.c
+++ b/Build/source/texk/dvipdf-x/xsrc/pdfdraw.c
@@ -1265,6 +1265,61 @@ pdf_dev_currentcolor (pdf_color *color, int is_fill)
}
#endif /* 0 */
+/*
+ * mask == 0 means stroking color, mask == 0x20 nonstroking color
+ *
+ * force == 1 means that operators will be generated even if
+ * the color is the same as the current graphics state color
+ */
+void
+pdf_dev_set_color (const pdf_color *color, char mask, int force)
+{
+ int len;
+
+ pdf_gstate *gs = m_stack_top(&gs_stack);
+ pdf_color *current = mask ? &gs->fillcolor : &gs->strokecolor;
+
+ ASSERT(pdf_color_is_valid(color));
+
+ if (!(pdf_dev_get_param(PDF_DEV_PARAM_COLORMODE) &&
+ (force || pdf_color_compare(color, current))))
+ /* If "color" is already the current color, then do nothing
+ * unless a color operator is forced
+ */
+ return;
+
+ graphics_mode();
+ len = pdf_color_to_string(color, fmt_buf);
+ fmt_buf[len++] = ' ';
+ switch (pdf_color_type(color)) {
+ case PDF_COLORSPACE_TYPE_RGB:
+ fmt_buf[len++] = 'R' | mask;
+ fmt_buf[len++] = 'G' | mask;
+ break;
+ case PDF_COLORSPACE_TYPE_CMYK:
+ fmt_buf[len++] = 'K' | mask;
+ break;
+ case PDF_COLORSPACE_TYPE_GRAY:
+ fmt_buf[len++] = 'G' | mask;
+ break;
+ default: /* already verified the given color */
+ break;
+ }
+ pdf_doc_add_page_content(fmt_buf, len); /* op: RG K G rg k g */
+
+ pdf_color_copycolor(current, color);
+}
+
+void
+pdf_dev_reset_color (int force)
+{
+ pdf_color *sc, *fc;
+
+ pdf_color_get_current(&sc, &fc);
+ pdf_dev_set_color(sc, 0, force);
+ pdf_dev_set_color(fc, 0x20, force);
+}
+
int
pdf_dev_concat (const pdf_tmatrix *M)
{
diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfdraw.h b/Build/source/texk/dvipdf-x/xsrc/pdfdraw.h
index f24540ef2bf..27fa74e1f8e 100644
--- a/Build/source/texk/dvipdf-x/xsrc/pdfdraw.h
+++ b/Build/source/texk/dvipdf-x/xsrc/pdfdraw.h
@@ -164,8 +164,10 @@ extern int pdf_dev_current_depth (void);
extern void pdf_dev_grestore_to (int depth);
#define pdf_dev_grestoreall() pdf_dev_grestore_to(0);
-extern int pdf_dev_currentcolor (pdf_color *color, int is_fill);
-extern int pdf_dev_setcolor (const pdf_color *color, int is_fill);
+extern void pdf_dev_set_color (const pdf_color *color, char mask, int force);
+#define pdf_dev_set_strokingcolor(c) pdf_dev_set_color(c, 0, 0);
+#define pdf_dev_set_nonstrokingcolor(c) pdf_dev_set_color(c, 0x20, 0);
+extern void pdf_dev_reset_color (int force);
extern void pdf_dev_set_fixed_point (double x, double y);
extern void pdf_dev_get_fixed_point (pdf_coord *p);
diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfnames.c b/Build/source/texk/dvipdf-x/xsrc/pdfnames.c
index 83eb997e249..864910b3411 100644
--- a/Build/source/texk/dvipdf-x/xsrc/pdfnames.c
+++ b/Build/source/texk/dvipdf-x/xsrc/pdfnames.c
@@ -22,8 +22,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#if HAVE_CONFIG_H
-#include "config.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
#endif
#include <ctype.h>
@@ -44,9 +44,8 @@
struct obj_data
{
- pdf_obj *object_ref;
pdf_obj *object;
- int reserve; /* 1 if object is not actually defined. */
+ int closed; /* 1 if object is closed */
};
char *
@@ -74,51 +73,17 @@ printable_key (const char *key, int keylen)
return (char *) pkey;
}
-static void
-flush_objects (struct ht_table *ht_tab)
-{
- struct ht_iter iter;
-
- if (ht_set_iter(ht_tab, &iter) >= 0) {
- do {
- char *key;
- int keylen;
- struct obj_data *value;
-
- key = ht_iter_getkey(&iter, &keylen);
- value = ht_iter_getval(&iter);
- if (value->reserve) {
- WARN("Unresolved object reference \"%s\" found!!!",
- printable_key(key, keylen));
- }
- if (value->object) {
- pdf_release_obj(value->object);
- }
- if (value->object_ref) {
- pdf_release_obj(value->object_ref);
- }
- value->object = NULL;
- value->object_ref = NULL;
- value->reserve = 0;
- } while (ht_iter_next(&iter) >= 0);
- ht_clear_iter(&iter);
- }
-}
-
static void CDECL
hval_free (void *hval)
{
struct obj_data *value;
value = (struct obj_data *) hval;
- if (value->object)
- pdf_release_obj(value->object);
- if (value->object_ref)
- pdf_release_obj(value->object_ref);
- value->object = NULL;
- value->object_ref = NULL;
- value->reserve = 0;
+ if (value->object) {
+ pdf_release_obj(value->object);
+ value->object = NULL;
+ }
RELEASE(value);
@@ -136,12 +101,37 @@ pdf_new_name_tree (void)
return names;
}
+static void
+check_objects_defined (struct ht_table *ht_tab)
+{
+ struct ht_iter iter;
+
+ if (ht_set_iter(ht_tab, &iter) >= 0) {
+ do {
+ char *key;
+ int keylen;
+ struct obj_data *value;
+
+ 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));
+ }
+ } while (ht_iter_next(&iter) >= 0);
+ ht_clear_iter(&iter);
+ }
+}
+
void
pdf_delete_name_tree (struct ht_table **names)
{
ASSERT(names && *names);
- flush_objects (*names);
+ check_objects_defined(*names);
+
ht_clear_table(*names);
RELEASE(*names);
*names = NULL;
@@ -163,64 +153,20 @@ pdf_names_add_object (struct ht_table *names,
value = ht_lookup_table(names, key, keylen);
if (!value) {
value = NEW(1, struct obj_data);
- value->object = object;
- value->object_ref = NULL;
- value->reserve = 0;
+ value->object = object;
+ value->closed = 0;
ht_append_table(names, key, keylen, value);
} else {
- if (value->reserve) {
- /* null object is used for undefined objects */
- pdf_copy_object(value->object, object);
- pdf_release_obj(object); /* PLEASE FIX THIS!!! */
+ ASSERT(value->object);
+ if (PDF_OBJ_UNDEFINED(value->object)) {
+ pdf_transfer_label(object, value->object);
+ pdf_release_obj(value->object);
+ value->object = object;
} else {
- if (value->object || value->object_ref) {
- if (pdf_obj_get_verbose()) {
- WARN("Object reference with key \"%s\" is in use.", printable_key(key, keylen));
- }
- pdf_release_obj(object);
- return -1;
- } else {
- value->object = object;
- }
- }
- value->reserve = 0;
- }
-
- return 0;
-}
-
-int
-pdf_names_add_reference (struct ht_table *names,
- const void *key, int keylen, pdf_obj *object_ref)
-{
- struct obj_data *value;
-
- ASSERT(names);
-
- if (!PDF_OBJ_INDIRECTTYPE(object_ref)) {
- WARN("Invalid type: @%s is not reference...",
- printable_key(key, keylen));
- return -1;
- }
-
- value = ht_lookup_table(names, key, keylen);
- if (!value) {
- value = NEW(1, struct obj_data);
- value->object = NULL;
- value->object_ref = object_ref;
- value->reserve = 0;
- ht_append_table(names, key, keylen, value);
- } else {
- if (value->object || value->object_ref) {
- WARN("Object reference \"%s\" is in use.",
- printable_key(key, keylen));
- WARN("Please close it before redefining.");
+ WARN("Object @%s already defined.", printable_key(key, keylen));
+ pdf_release_obj(object);
return -1;
- } else {
- value->object = NULL;
- value->object_ref = object_ref;
}
- value->reserve = 0;
}
return 0;
@@ -234,29 +180,24 @@ pdf_names_lookup_reference (struct ht_table *names,
const void *key, int keylen)
{
struct obj_data *value;
+ pdf_obj *object;
ASSERT(names);
value = ht_lookup_table(names, key, keylen);
- /* Reserve object label */
- if (!value) {
- value = NEW(1, struct obj_data);
- value->object = pdf_new_null(); /* dummy */
- value->object_ref = NULL;
- value->reserve = 1;
- ht_append_table(names, key, keylen, value);
- }
-
- if (!value->object_ref) {
- if (value->object)
- value->object_ref = pdf_ref_obj(value->object);
- else {
- WARN("Object @%s not defined or already closed.",
- printable_key(key, keylen));
- }
+ if (value) {
+ object = value->object;
+ } 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);
}
+ ASSERT(object);
- return pdf_link_obj(value->object_ref);
+ return pdf_ref_obj(object);
}
pdf_obj *
@@ -268,12 +209,9 @@ pdf_names_lookup_object (struct ht_table *names,
ASSERT(names);
value = ht_lookup_table(names, key, keylen);
- if (!value)
+ if (!value || PDF_OBJ_UNDEFINED(value->object))
return NULL;
- else if (!value->object) {
- WARN("Object @%s not defined or already closed.",
- printable_key(key, keylen));
- }
+ ASSERT(value->object);
return value->object;
}
@@ -287,21 +225,19 @@ pdf_names_close_object (struct ht_table *names,
ASSERT(names);
value = ht_lookup_table(names, key, keylen);
- if (!value) {
- WARN("Tried to release nonexistent reference: %s",
- printable_key(key, keylen));
+ if (!value ||PDF_OBJ_UNDEFINED(value->object) ) {
+ WARN("Cannot close undefined object @%s.", printable_key(key, keylen));
return -1;
}
+ ASSERT(value->object);
- if (value->object) {
- pdf_release_obj(value->object);
- value->object = NULL;
- } else {
- WARN("Trying to close object @%s twice?",
- printable_key(key, keylen));
+ if (value->closed) {
+ WARN("Object @%s already closed.", printable_key(key, keylen));
return -1;
}
+ value->closed = 1;
+
return 0;
}
@@ -415,7 +351,8 @@ build_name_tree (struct named_object *first, long num_leaves, int is_root)
}
static struct named_object *
-flat_table (struct ht_table *ht_tab, long *num_entries)
+flat_table (struct ht_table *ht_tab, long *num_entries,
+ struct ht_table *filter)
{
struct named_object *objects;
struct ht_iter iter;
@@ -423,64 +360,64 @@ flat_table (struct ht_table *ht_tab, long *num_entries)
ASSERT(ht_tab);
- *num_entries = count = ht_tab->count;
- objects = NEW(count, struct named_object);
+ objects = NEW(ht_tab->count, struct named_object);
+ count = 0;
if (ht_set_iter(ht_tab, &iter) >= 0) {
do {
char *key;
int keylen;
struct obj_data *value;
- count--;
key = ht_iter_getkey(&iter, &keylen);
+
+ if (filter) {
+ pdf_obj *new_obj = ht_lookup_table(filter, key, keylen);
+
+ if (!new_obj)
+ continue;
+
+ key = pdf_string_value(new_obj);
+ keylen = pdf_string_length(new_obj);
+ }
+
value = ht_iter_getval(&iter);
- if (value->reserve) {
- WARN("Named object \"%s\" not defined!!!",
+ ASSERT(value->object);
+ if (PDF_OBJ_UNDEFINED(value->object)) {
+ WARN("Object @%s\" not defined. Replaced by null.",
printable_key(key, keylen));
- WARN("Replacing with null.");
objects[count].key = (char *) key;
objects[count].keylen = keylen;
objects[count].value = pdf_new_null();
- } else if (value->object_ref) {
- objects[count].key = (char *) key;
- objects[count].keylen = keylen;
- objects[count].value = pdf_link_obj(value->object_ref);
} else if (value->object) {
objects[count].key = (char *) key;
objects[count].keylen = keylen;
objects[count].value = pdf_link_obj(value->object);
- } else {
- WARN("Named object \"%s\" not defined!!!",
- printable_key(key, keylen));
- WARN("Replacing with null.");
- objects[count].key = (char *) key;
- objects[count].keylen = keylen;
- objects[count].value = pdf_new_null();
}
- } while (ht_iter_next(&iter) >= 0 && count > 0);
+
+ count++;
+ } while (ht_iter_next(&iter) >= 0);
ht_clear_iter(&iter);
}
+ *num_entries = count;
+ objects = RENEW(objects, count, struct named_object);
+
return objects;
}
pdf_obj *
-pdf_names_create_tree (struct ht_table *names)
+pdf_names_create_tree (struct ht_table *names, long *count,
+ struct ht_table *filter)
{
pdf_obj *name_tree;
struct named_object *flat;
- long count;
- flat = flat_table(names, &count);
+ flat = flat_table(names, count, filter);
if (!flat)
name_tree = NULL;
else {
- if (count < 1)
- name_tree = NULL;
- else {
- qsort(flat, count, sizeof(struct named_object), cmp_key);
- name_tree = build_name_tree(flat, count, 1);
- }
+ qsort(flat, *count, sizeof(struct named_object), cmp_key);
+ name_tree = build_name_tree(flat, *count, 1);
RELEASE(flat);
}
diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfnames.h b/Build/source/texk/dvipdf-x/xsrc/pdfnames.h
index ca4a7dbc0bf..bcf3aec9d98 100644
--- a/Build/source/texk/dvipdf-x/xsrc/pdfnames.h
+++ b/Build/source/texk/dvipdf-x/xsrc/pdfnames.h
@@ -35,8 +35,6 @@ 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);
-extern int pdf_names_add_reference (struct ht_table *names,
- const void *key, int keylen, pdf_obj *object_ref);
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,
@@ -45,7 +43,9 @@ extern int pdf_names_close_object (struct ht_table *names,
const void *key, int keylen);
/* Really create name tree... */
-extern pdf_obj *pdf_names_create_tree (struct ht_table *names);
+extern pdf_obj *pdf_names_create_tree (struct ht_table *names,
+ long *count,
+ struct ht_table *filter);
extern char *printable_key (const char *key, int keylen);
diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfobj.c b/Build/source/texk/dvipdf-x/xsrc/pdfobj.c
index 6c8d66780f4..78fb8aff21c 100644
--- a/Build/source/texk/dvipdf-x/xsrc/pdfobj.c
+++ b/Build/source/texk/dvipdf-x/xsrc/pdfobj.c
@@ -22,8 +22,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#if HAVE_CONFIG_H
-#include "config.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
#endif
#include <ctype.h>
@@ -117,6 +117,7 @@ struct pdf_stream
struct pdf_indirect
{
pdf_file *pf;
+ pdf_obj *obj; /* used when PF == NULL */
unsigned long label;
unsigned short generation;
};
@@ -161,6 +162,7 @@ struct pdf_file
FILE *file;
pdf_obj *trailer;
xref_entry *xref_table;
+ pdf_obj *catalog;
long num_obj;
long file_size;
int version;
@@ -179,6 +181,8 @@ static pdf_obj *xref_stream;
/* Internal static routines */
+static int check_for_pdf_version (FILE *file);
+
static void pdf_flush_obj (pdf_obj *object, FILE *file);
static void pdf_label_obj (pdf_obj *object);
static void pdf_write_obj (pdf_obj *object, FILE *file);
@@ -190,6 +194,7 @@ static void release_objstm (pdf_obj *objstm);
static void pdf_out_char (FILE *file, char c);
static void pdf_out (FILE *file, const void *buffer, long length);
+static pdf_obj *pdf_new_ref (pdf_obj *object);
static void release_indirect (pdf_indirect *data);
static void write_indirect (pdf_indirect *indirect, FILE *file);
@@ -314,13 +319,12 @@ pdf_out_init (const char *filename, int do_encryption)
if (filename == NULL) { /* no filename: writing to stdout */
#ifdef WIN32
- setmode(fileno(stdout), _O_BINARY);
+ setmode(fileno(stdout), _O_BINARY);
#endif
pdf_output_file = stdout;
}
else
pdf_output_file = MFOPEN(filename, FOPEN_WBIN_MODE);
-
if (!pdf_output_file) {
if (strlen(filename) < 128)
ERROR("Unable to open \"%s\".", filename);
@@ -510,14 +514,20 @@ pdf_set_info (pdf_obj *object)
}
void
-pdf_set_encrypt (pdf_obj *encrypt, pdf_obj *id)
+pdf_set_id (pdf_obj *id)
+{
+ if (pdf_add_dict(trailer_dict, pdf_new_name("ID"), id)) {
+ ERROR ("ID already set!");
+ }
+}
+
+void
+pdf_set_encrypt (pdf_obj *encrypt)
{
if (pdf_add_dict(trailer_dict, pdf_new_name("Encrypt"), pdf_ref_obj(encrypt))) {
ERROR("Encrypt object already set!");
}
encrypt->flags |= OBJ_NO_ENCRYPT;
-
- pdf_add_dict(trailer_dict, pdf_new_name("ID"), id);
}
static
@@ -588,16 +598,13 @@ void pdf_out_white (FILE *file)
ERROR("typecheck: Invalid object type: %d %d (line %d)", (o) ? (o)->type : -1, (t), __LINE__);\
}
-#define INVALIDOBJ(o) ((o) == NULL || (o)->type <= 0 || (o)->type > PDF_INDIRECT)
+#define INVALIDOBJ(o) ((o) == NULL || (o)->type <= 0 || (o)->type > PDF_UNDEFINED)
-pdf_obj *
+static pdf_obj *
pdf_new_obj(int type)
{
pdf_obj *result;
- if (type > PDF_INDIRECT || type < PDF_UNDEFINED)
- ERROR("Invalid object type: %d", type);
-
result = NEW(1, pdf_obj);
result->type = type;
result->data = NULL;
@@ -606,6 +613,9 @@ pdf_new_obj(int type)
result->refcount = 1;
result->flags = 0;
+ if (INVALIDOBJ(result))
+ ERROR("Invalid object type: %d", type);
+
return result;
}
@@ -634,6 +644,21 @@ pdf_label_obj (pdf_obj *object)
}
/*
+ * Transfer the label assigned to the object src to the object dst.
+ * The object dst must not yet have been labeled.
+ */
+void
+pdf_transfer_label (pdf_obj *dst, pdf_obj *src)
+{
+ ASSERT(dst && !dst->label && src);
+
+ dst->label = src->label;
+ dst->generation = src->generation;
+ src->label = 0;
+ src->generation = 0;
+}
+
+/*
* This doesn't really copy the object, but allows it to be used without
* fear that somebody else will free it.
*/
@@ -664,10 +689,7 @@ pdf_ref_obj (pdf_obj *object)
if (PDF_OBJ_INDIRECTTYPE(object)) {
return pdf_link_obj(object);
} else {
- if (object->label == 0) {
- pdf_label_obj(object);
- }
- return pdf_new_indirect(NULL, object->label, object->generation);
+ return pdf_new_ref(object);
}
}
@@ -688,6 +710,20 @@ write_indirect (pdf_indirect *indirect, FILE *file)
pdf_out(file, format_buffer, length);
}
+/* The undefined object is used as a placeholder in pdfnames.c
+ * for objects which are referenced before they are defined.
+ */
+pdf_obj *
+pdf_new_undefined (void)
+{
+ pdf_obj *result;
+
+ result = pdf_new_obj(PDF_UNDEFINED);
+ result->data = NULL;
+
+ return result;
+}
+
pdf_obj *
pdf_new_null (void)
{
@@ -741,6 +777,7 @@ write_boolean (pdf_boolean *data, FILE *file)
}
}
+#if 0
void
pdf_set_boolean (pdf_obj *object, char value)
{
@@ -751,6 +788,7 @@ pdf_set_boolean (pdf_obj *object, char value)
data = object->data;
data->value = value;
}
+#endif
char
pdf_boolean_value (pdf_obj *object)
@@ -824,19 +862,17 @@ pdf_new_string (const void *str, unsigned length)
pdf_obj *result;
pdf_string *data;
+ ASSERT(str);
+
result = pdf_new_obj(PDF_STRING);
data = NEW(1, pdf_string);
result->data = data;
- if (length != 0) {
- data->length = length;
- data->string = NEW(length+1, unsigned char);
- memcpy(data->string, str, length);
- /* Shouldn't assume NULL terminated. */
- data->string[length] = '\0';
- } else {
- data->length = 0;
- data->string = NULL;
- }
+
+ data->length = length;
+ data->string = NEW(length+1, unsigned char);
+ memcpy(data->string, str, length);
+ /* Shouldn't assume NULL terminated. */
+ data->string[length] = '\0';
return result;
}
@@ -1070,6 +1106,7 @@ release_name (pdf_name *data)
RELEASE(data);
}
+#if 0
void
pdf_set_name (pdf_obj *object, const char *name)
{
@@ -1091,6 +1128,7 @@ pdf_set_name (pdf_obj *object, const char *name)
data->name = NULL;
}
}
+#endif
char *
pdf_name_value (pdf_obj *object)
@@ -1268,7 +1306,7 @@ pdf_shift_array (pdf_obj *array)
return result;
}
-#endif /* 0 */
+#endif
/* Prepend an object to an array */
void
@@ -1309,19 +1347,26 @@ pdf_pop_array (pdf_obj *array)
return result;
}
-#endif /* 0 */
+#endif
+
static void
write_dict (pdf_dict *dict, FILE *file)
{
+#if 0
pdf_out (file, "<<\n", 3); /* dropping \n saves few kb. */
+#else
+ pdf_out (file, "<<", 2);
+#endif
while (dict->key != NULL) {
pdf_write_obj(dict->key, file);
if (pdf_need_white(PDF_NAME, (dict->value)->type)) {
pdf_out_white(file);
}
pdf_write_obj(dict->value, file);
+#if 0
pdf_out_char (file, '\n'); /* removing this saves few kb. */
+#endif
dict = dict->next;
}
pdf_out(file, ">>", 2);
@@ -1442,7 +1487,7 @@ pdf_put_dict (pdf_obj *dict, const char *key, pdf_obj *value)
data->value = value;
}
}
-#endif /* 0 */
+#endif
/* pdf_merge_dict makes a link for each item in dict2 before stealing it */
void
@@ -1902,7 +1947,7 @@ pdf_stream_get_flags (pdf_obj *stream)
return data->_flags;
}
-#endif /* 0 */
+#endif
static void
pdf_write_obj (pdf_obj *object, FILE *file)
@@ -1912,7 +1957,7 @@ pdf_write_obj (pdf_obj *object, FILE *file)
return;
}
- if (INVALIDOBJ(object))
+ if (INVALIDOBJ(object) || PDF_OBJ_UNDEFINED(object))
ERROR("pdf_write_obj: Invalid object, type = %d\n", object->type);
if (file == stderr)
@@ -2102,102 +2147,6 @@ pdf_release_obj (pdf_obj *object)
}
}
-/* Copy object data without changing object label. */
-void
-pdf_copy_object (pdf_obj *dst, pdf_obj *src)
-{
- if (!dst || !src)
- return;
-
- switch (dst->type) {
- case PDF_BOOLEAN: release_boolean(dst->data); break;
- case PDF_NULL: release_null(dst->data); break;
- case PDF_NUMBER: release_number(dst->data); break;
- case PDF_STRING: release_string(dst->data); break;
- case PDF_NAME: release_name(dst->data); break;
- case PDF_ARRAY: release_array(dst->data); break;
- case PDF_DICT: release_dict(dst->data); break;
- case PDF_STREAM: release_stream(dst->data); break;
- case PDF_INDIRECT: release_indirect(dst->data); break;
- }
-
- dst->type = src->type;
- switch (src->type) {
- case PDF_BOOLEAN:
- dst->data = NEW(1, pdf_boolean);
- pdf_set_boolean(dst, pdf_boolean_value(src));
- break;
- case PDF_NULL:
- dst->data = NULL;
- break;
- case PDF_NUMBER:
- dst->data = NEW(1, pdf_number);
- pdf_set_number(dst, pdf_number_value(src));
- break;
- case PDF_STRING:
- dst->data = NEW(1, pdf_string);
- pdf_set_string(dst,
- pdf_string_value(src),
- pdf_string_length(src));
- break;
- case PDF_NAME:
- dst->data = NEW(1, pdf_name);
- pdf_set_name(dst, pdf_name_value(src));
- break;
- case PDF_ARRAY:
- {
- pdf_array *data;
- unsigned long i;
-
- dst->data = data = NEW(1, pdf_array);
- data->size = 0;
- data->max = 0;
- data->values = NULL;
- for (i = 0; i < pdf_array_length(src); i++) {
- pdf_add_array(dst, pdf_link_obj(pdf_get_array(src, i)));
- }
- }
- break;
- case PDF_DICT:
- {
- pdf_dict *data;
-
- dst->data = data = NEW(1, pdf_dict);
- data->key = NULL;
- data->value = NULL;
- data->next = NULL;
- pdf_merge_dict(dst, src);
- }
- break;
- case PDF_STREAM:
- {
- pdf_stream *data;
-
- dst->data = data = NEW(1, pdf_stream);
- data->dict = pdf_new_dict();
- data->_flags = ((pdf_stream *)src->data)->_flags;
- data->stream_length = 0;
- data->max_length = 0;
-
- pdf_add_stream(dst, pdf_stream_dataptr(src), pdf_stream_length(src));
- pdf_merge_dict(data->dict, pdf_stream_dict(src));
- }
- break;
- case PDF_INDIRECT:
- {
- pdf_indirect *data;
-
- dst->data = data = NEW(1, pdf_indirect);
- data->pf = ((pdf_indirect *) (src->data))->pf;
- data->label = ((pdf_indirect *) (src->data))->label;
- data->generation = ((pdf_indirect *) (src->data))->generation;
- }
- break;
- }
-
- return;
-}
-
static int
backup_line (FILE *pdf_input_file)
{
@@ -2328,6 +2277,7 @@ pdf_new_indirect (pdf_file *pf, unsigned long obj_num, unsigned short obj_gen)
indirect = NEW(1, pdf_indirect);
indirect->pf = pf;
+ indirect->obj = NULL;
indirect->label = obj_num;
indirect->generation = obj_gen;
@@ -2562,27 +2512,53 @@ pdf_get_object (pdf_file *pf, unsigned long obj_num, unsigned short obj_gen)
}
#define OBJ_FILE(o) (((pdf_indirect *)((o)->data))->pf)
+#define OBJ_OBJ(o) (((pdf_indirect *)((o)->data))->obj)
#define OBJ_NUM(o) (((pdf_indirect *)((o)->data))->label)
#define OBJ_GEN(o) (((pdf_indirect *)((o)->data))->generation)
+static pdf_obj *
+pdf_new_ref (pdf_obj *object)
+{
+ pdf_obj *result;
+
+ if (object->label == 0) {
+ pdf_label_obj(object);
+ }
+ result = pdf_new_indirect(NULL, object->label, object->generation);
+ OBJ_OBJ(result) = object;
+ return result;
+}
+
/* pdf_deref_obj always returns a link instead of the original */
/* It never return the null object, but the NULL pointer instead */
pdf_obj *
pdf_deref_obj (pdf_obj *obj)
{
+ int count = PDF_OBJ_MAX_DEPTH;
+
if (obj)
obj = pdf_link_obj(obj);
- while (PDF_OBJ_INDIRECTTYPE(obj)) {
+ while (PDF_OBJ_INDIRECTTYPE(obj) && --count) {
pdf_file *pf = OBJ_FILE(obj);
- unsigned long obj_num = OBJ_NUM(obj);
- unsigned short obj_gen = OBJ_GEN(obj);
- if (!pf)
- ERROR("Tried to deref a non-file object");
- pdf_release_obj(obj);
- obj = pdf_get_object(pf, obj_num, obj_gen);
+ if (pf) {
+ unsigned long obj_num = OBJ_NUM(obj);
+ unsigned short obj_gen = OBJ_GEN(obj);
+ pdf_release_obj(obj);
+ obj = pdf_get_object(pf, obj_num, obj_gen);
+ } else {
+ pdf_obj *next_obj = OBJ_OBJ(obj);
+ if (!next_obj) {
+ ERROR("Undefined object reference");
+ }
+ pdf_release_obj(obj);
+ obj = pdf_link_obj(next_obj);
+ }
}
+ if (!count)
+ ERROR("Loop in object hierarchy detected. Broken PDF file?");
+
if (PDF_OBJ_NULLTYPE(obj)) {
pdf_release_obj(obj);
return NULL;
@@ -2740,7 +2716,7 @@ parse_xrefstm_subsec (pdf_file *pf,
static int
parse_xref_stream (pdf_file *pf, long xref_pos, pdf_obj **trailer)
{
- pdf_obj *xrefstm, *size_obj, *W_obj, *index;
+ pdf_obj *xrefstm, *size_obj, *W_obj, *index_obj;
unsigned long size;
long length;
int W[3], i, wsum = 0;
@@ -2780,17 +2756,17 @@ parse_xref_stream (pdf_file *pf, long xref_pos, pdf_obj **trailer)
p = pdf_stream_dataptr(xrefstm);
- index = pdf_lookup_dict(*trailer, "Index");
- if (index) {
+ index_obj = pdf_lookup_dict(*trailer, "Index");
+ if (index_obj) {
unsigned int index_len;
- if (!PDF_OBJ_ARRAYTYPE(index) ||
- ((index_len = pdf_array_length(index)) % 2 ))
+ if (!PDF_OBJ_ARRAYTYPE(index_obj) ||
+ ((index_len = pdf_array_length(index_obj)) % 2 ))
goto error;
i = 0;
while (i < index_len) {
- pdf_obj *first = pdf_get_array(index, i++);
- size_obj = pdf_get_array(index, i++);
+ pdf_obj *first = pdf_get_array(index_obj, i++);
+ size_obj = pdf_get_array(index_obj, i++);
if (!PDF_OBJ_NUMBERTYPE(first) ||
!PDF_OBJ_NUMBERTYPE(size_obj) ||
parse_xrefstm_subsec(pf, &p, &length, W, wsum,
@@ -2819,7 +2795,6 @@ parse_xref_stream (pdf_file *pf, long xref_pos, pdf_obj **trailer)
return 0;
}
-/* TODO: parse Version entry */
static pdf_obj *
read_xref (pdf_file *pf)
{
@@ -2904,6 +2879,7 @@ pdf_file_new (FILE *file)
pf->file = file;
pf->trailer = NULL;
pf->xref_table = NULL;
+ pf->catalog = NULL;
pf->num_obj = 0;
pf->version = 0;
@@ -2929,8 +2905,15 @@ pdf_file_free (pdf_file *pf)
pdf_release_obj(pf->xref_table[i].indirect);
}
- RELEASE(pf->xref_table);
- pdf_release_obj(pf->trailer);
+ RELEASE(pf->xref_table);
+ if (pf->trailer) {
+ pdf_release_obj(pf->trailer);
+ pf->trailer = NULL;
+ }
+ if (pf->catalog) {
+ pdf_release_obj(pf->catalog);
+ pf->catalog = NULL;
+ }
RELEASE(pf);
}
@@ -2942,45 +2925,90 @@ pdf_files_init (void)
ht_init_table(pdf_files, (void (*)(void *)) pdf_file_free);
}
+int
+pdf_file_get_version (pdf_file *pf)
+{
+ ASSERT(pf);
+ return pf->version;
+}
+
pdf_obj *
pdf_file_get_trailer (pdf_file *pf)
{
ASSERT(pf);
- return pdf_link_obj(pf->trailer);
+ return pf->trailer;
+}
+
+pdf_obj *
+pdf_file_get_catalog (pdf_file *pf)
+{
+ ASSERT(pf);
+ return pf->catalog;
}
pdf_file *
-pdf_open (char *ident, FILE *file)
+pdf_open (const char *ident, FILE *file)
{
- pdf_file *pf = NULL;
+ pdf_file *pf;
ASSERT(pdf_files);
- if (ident)
- pf = (pdf_file *) ht_lookup_table(pdf_files, ident, strlen(ident));
+ pf = (pdf_file *) ht_lookup_table(pdf_files, ident, strlen(ident));
if (pf) {
pf->file = file;
} else {
- int version = check_for_pdf(file);
- if (!version) {
- WARN("pdf_open: Not a PDF 1.[1-5] file.");
+ int version;
+ pdf_obj *new_version;
+
+ version = check_for_pdf_version(file);
+ if (version < 0) {
+ WARN("Not a PDF file.");
return NULL;
}
pf = pdf_file_new(file);
pf->version = version;
- if (!(pf->trailer = read_xref(pf))) {
- pdf_file_free(pf);
- return NULL;
+ if (!(pf->trailer = read_xref(pf)))
+ goto error;
+
+ if (pdf_lookup_dict(pf->trailer, "Encrypt")) {
+ WARN("PDF document is encrypted.");
+ goto error;
+ }
+
+ pf->catalog = pdf_deref_obj(pdf_lookup_dict(pf->trailer, "Root"));
+ if (!PDF_OBJ_DICTTYPE(pf->catalog)) {
+ WARN("Cannot read PDF document catalog. Broken PDF file?");
+ goto error;
}
- if (ident)
- ht_append_table(pdf_files, ident, strlen(ident), pf);
+ new_version = pdf_deref_obj(pdf_lookup_dict(pf->catalog, "Version"));
+ if (new_version) {
+ unsigned int minor;
+
+ if (!PDF_OBJ_NAMETYPE(new_version) ||
+ sscanf(pdf_name_value(new_version), "1.%u", &minor) != 1) {
+ pdf_release_obj(new_version);
+ WARN("Illegal Version entry in document catalog. Broken PDF file?");
+ goto error;
+ }
+
+ if (pf->version < minor)
+ pf->version = minor;
+
+ pdf_release_obj(new_version);
+ }
+
+ ht_append_table(pdf_files, ident, strlen(ident), pf);
}
return pf;
+
+ error:
+ pdf_file_free(pf);
+ return NULL;
}
void
@@ -2998,24 +3026,21 @@ pdf_files_close (void)
RELEASE(pdf_files);
}
-int
-check_for_pdf (FILE *file)
+static int
+check_for_pdf_version (FILE *file)
{
- int result = 0;
+ unsigned int minor;
rewind(file);
- if (fread(work_buffer, sizeof(char), strlen("%PDF-1.x"), file) ==
- strlen("%PDF-1.x") &&
- !strncmp(work_buffer, "%PDF-1.", strlen("%PDF-1."))) {
- if (work_buffer[7] >= '0' && work_buffer[7] <= '0' + pdf_version)
- result = 1;
- else {
- WARN("Version of PDF file (1.%c) is newer than version limit specification.",
- work_buffer[7]);
- }
- }
- return result;
+ return (ungetc(fgetc(file), file) == '%' &&
+ fscanf(file, "%%PDF-1.%u", &minor) == 1) ? minor : -1;
+}
+
+int
+check_for_pdf (FILE *file)
+{
+ return (check_for_pdf_version(file) >= 0);
}
static int CDECL
@@ -3035,6 +3060,8 @@ import_dict (pdf_obj *key, pdf_obj *value, void *pdata)
return 0;
}
+static pdf_obj loop_marker = { PDF_OBJ_INVALID, 0, 0, 0, 0, NULL };
+
static pdf_obj *
pdf_import_indirect (pdf_obj *object)
{
@@ -3052,15 +3079,16 @@ pdf_import_indirect (pdf_obj *object)
}
if ((ref = pf->xref_table[obj_num].indirect)) {
+ if (ref == &loop_marker)
+ ERROR("Loop in object hierarchy detected. Broken PDF file?");
return pdf_link_obj(ref);
} else {
pdf_obj *obj, *tmp;
obj = pdf_get_object(pf, obj_num, obj_gen);
- if (!obj) {
- WARN("Could not read object: %lu %u", obj_num, obj_gen);
- return NULL;
- }
+
+ /* We mark the reference to be able to detect loops */
+ pf->xref_table[obj_num].indirect = &loop_marker;
tmp = pdf_import_object(obj);
@@ -3146,25 +3174,17 @@ pdf_import_object (pdf_obj *object)
}
+/* returns 0 if indirect references point to the same object */
int
pdf_compare_reference (pdf_obj *ref1, pdf_obj *ref2)
{
pdf_indirect *data1, *data2;
- if (!PDF_OBJ_INDIRECTTYPE(ref1) ||
- !PDF_OBJ_INDIRECTTYPE(ref2)) {
- ERROR("Not indirect reference...");
- }
+ ASSERT(PDF_OBJ_INDIRECTTYPE(ref1) && PDF_OBJ_INDIRECTTYPE(ref2));
data1 = (pdf_indirect *) ref1->data;
data2 = (pdf_indirect *) ref2->data;
- if (data1->pf != data2->pf)
- return (int) (data1->pf - data2->pf);
- if (data1->label != data2->label)
- return (int) (data1->label - data2->label);
- if (data1->generation != data2->generation)
- return (int) (data1->generation - data2->generation);
-
- return 0;
+ return data1->pf != data2->pf || data1->label != data2->label
+ || data1->generation != data2->generation;
}
diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfobj.h b/Build/source/texk/dvipdf-x/xsrc/pdfobj.h
index 036e9f53ef4..e95a1bf8196 100644
--- a/Build/source/texk/dvipdf-x/xsrc/pdfobj.h
+++ b/Build/source/texk/dvipdf-x/xsrc/pdfobj.h
@@ -38,12 +38,15 @@
#define PDF_STREAM 7
#define PDF_NULL 8
#define PDF_INDIRECT 9
+#define PDF_UNDEFINED 10
#define PDF_OBJ_INVALID 0
-#define PDF_UNDEFINED PDF_OBJ_INVALID
#define STREAM_COMPRESS (1 << 0)
+/* A deeper object hierarchy will be considered as (illegal) loop. */
+#define PDF_OBJ_MAX_DEPTH 30
+
typedef struct pdf_obj pdf_obj;
typedef struct pdf_file pdf_file;
@@ -58,7 +61,6 @@ extern void pdf_out_flush (void);
extern void pdf_set_version (unsigned version);
extern unsigned pdf_get_version (void);
-extern pdf_obj *pdf_new_obj (int type);
extern void pdf_release_obj (pdf_obj *object);
extern int pdf_obj_typeof (pdf_obj *object);
@@ -71,17 +73,23 @@ extern int pdf_obj_typeof (pdf_obj *object);
#define PDF_OBJ_DICTTYPE(o) ((o) && pdf_obj_typeof((o)) == PDF_DICT)
#define PDF_OBJ_STREAMTYPE(o) ((o) && pdf_obj_typeof((o)) == PDF_STREAM)
#define PDF_OBJ_INDIRECTTYPE(o) ((o) && pdf_obj_typeof((o)) == PDF_INDIRECT)
+#define PDF_OBJ_UNDEFINED(o) ((o) && pdf_obj_typeof((o)) == PDF_UNDEFINED)
#define PDF_OBJ_TYPEOF(o) pdf_obj_typeof((o))
extern pdf_obj *pdf_ref_obj (pdf_obj *object);
extern pdf_obj *pdf_link_obj (pdf_obj *object);
+extern void pdf_transfer_label (pdf_obj *dst, pdf_obj *src);
+
+extern pdf_obj *pdf_new_undefined (void);
extern pdf_obj *pdf_new_null (void);
extern pdf_obj *pdf_new_boolean (char value);
+#if 0
extern void pdf_set_boolean (pdf_obj *object, char value);
+#endif
extern char pdf_boolean_value (pdf_obj *object);
extern pdf_obj *pdf_new_number (double value);
@@ -95,7 +103,9 @@ extern unsigned pdf_string_length (pdf_obj *object);
/* Name does not include the / */
extern pdf_obj *pdf_new_name (const char *name);
+#if 0
extern void pdf_set_name (pdf_obj *object, const char *name);
+#endif
extern char *pdf_name_value (pdf_obj *object);
extern pdf_obj *pdf_new_array (void);
@@ -107,7 +117,7 @@ extern pdf_obj *pdf_new_array (void);
extern void pdf_add_array (pdf_obj *array, pdf_obj *object);
#if 0
extern void pdf_put_array (pdf_obj *array, unsigned idx, pdf_obj *object);
-#endif /* 0 */
+#endif
extern pdf_obj *pdf_get_array (pdf_obj *array, long idx);
extern unsigned pdf_array_length (pdf_obj *array);
@@ -115,7 +125,7 @@ extern void pdf_unshift_array (pdf_obj *array, pdf_obj *object);
#if 0
extern pdf_obj *pdf_shift_array (pdf_obj *array);
extern pdf_obj *pdf_pop_array (pdf_obj *array);
-#endif /* 0 */
+#endif
extern pdf_obj *pdf_new_dict (void);
extern void pdf_remove_dict (pdf_obj *dict, const char *key);
@@ -132,8 +142,8 @@ extern pdf_obj *pdf_dict_keys (pdf_obj *dict);
*/
extern int pdf_add_dict (pdf_obj *dict, pdf_obj *key, pdf_obj *value);
#if 0
-extern void pdf_put_dict (pdf_obj *dict, const char *key, pdf_obj *value);
-#endif /* 0 */
+extern void pdf_put_dict (pdf_obj *dict, const char *key, pdf_obj *value);
+#endif
/* Apply proc(key, value, pdata) for each key-value pairs in dict, stop if proc()
* returned non-zero value (and that value is returned). PDF object is passed for
@@ -158,7 +168,7 @@ extern long pdf_stream_length (pdf_obj *stream);
#if 0
extern void pdf_stream_set_flags (pdf_obj *stream, int flags);
extern int pdf_stream_get_flags (pdf_obj *stream);
-#endif /* 0 */
+#endif
extern const void *pdf_stream_dataptr (pdf_obj *stream);
#if 0
@@ -175,15 +185,18 @@ extern int pdf_compare_reference (pdf_obj *ref1, pdf_obj *ref2);
extern void pdf_set_compression (int level);
extern void pdf_set_info (pdf_obj *obj);
+extern void pdf_set_id (pdf_obj *id);
extern void pdf_set_root (pdf_obj *obj);
-extern void pdf_set_encrypt (pdf_obj *encrypt, pdf_obj *id);
+extern void pdf_set_encrypt (pdf_obj *encrypt);
extern void pdf_files_init (void);
extern void pdf_files_close (void);
extern int check_for_pdf (FILE *file);
-extern pdf_file *pdf_open (char *ident, FILE *file);
+extern pdf_file *pdf_open (const char *ident, FILE *file);
extern void pdf_close (pdf_file *pf);
extern pdf_obj *pdf_file_get_trailer (pdf_file *pf);
+extern int pdf_file_get_version (pdf_file *pf);
+extern pdf_obj *pdf_file_get_catalog (pdf_file *pf);
extern pdf_obj *pdf_deref_obj (pdf_obj *object);
extern pdf_obj *pdf_import_object (pdf_obj *object);
@@ -191,6 +204,5 @@ extern pdf_obj *pdf_import_object (pdf_obj *object);
extern int pdfobj_escape_str (char *buffer, int size, const unsigned char *s, int len);
extern pdf_obj *pdf_new_indirect (pdf_file *pf, unsigned long label, unsigned short generation);
-extern void pdf_copy_object (pdf_obj *dst, pdf_obj *src);
#endif /* _PDFOBJ_H_ */
diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfximage.c b/Build/source/texk/dvipdf-x/xsrc/pdfximage.c
index f16829f18ba..6f3e6d3558f 100644
--- a/Build/source/texk/dvipdf-x/xsrc/pdfximage.c
+++ b/Build/source/texk/dvipdf-x/xsrc/pdfximage.c
@@ -22,8 +22,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#if HAVE_CONFIG_H
-#include "config.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
#endif
#include "system.h"
@@ -48,7 +48,7 @@
/* From psimage.h */
static int check_for_ps (FILE *fp);
-static int ps_include_page (pdf_ximage *ximage, const char *file_name);
+static int ps_include_page (pdf_ximage *ximage);
#define IMAGE_TYPE_UNKNOWN -1
@@ -71,7 +71,7 @@ struct pdf_ximage_
{
char *ident;
char res_name[16];
- long page_no, page_count;
+ long page_no;
int subtype;
@@ -82,7 +82,7 @@ struct pdf_ximage_
pdf_obj *resource;
pdf_obj *attr_dict;
- char tempfile;
+ char tempfile;
};
@@ -111,14 +111,16 @@ static struct ic_ _ic = {
};
static void
-pdf_init_ximage_struct (pdf_ximage *I, const char *ident, const char *filename, pdf_obj *dict)
+pdf_init_ximage_struct (pdf_ximage *I,
+ const char *ident, const char *filename,
+ long page_no, pdf_obj *dict)
{
if (ident) {
I->ident = NEW(strlen(ident)+1, char);
strcpy(I->ident, ident);
} else
I ->ident = NULL;
- I->page_no = I->page_count = 0;
+ I->page_no = page_no;
if (filename) {
I->filename = NEW(strlen(filename)+1, char);
strcpy(I->filename, filename);
@@ -161,7 +163,7 @@ pdf_clean_ximage_struct (pdf_ximage *I)
pdf_release_obj(I->resource);
if (I->attr_dict)
pdf_release_obj(I->attr_dict);
- pdf_init_ximage_struct(I, NULL, NULL, NULL);
+ pdf_init_ximage_struct(I, NULL, NULL, 0, NULL);
}
@@ -208,6 +210,7 @@ pdf_close_images (void)
_opts.cmdtmpl = NULL;
}
+
static int
source_image_type (FILE *fp)
{
@@ -260,8 +263,7 @@ load_image (const char *ident, const char *fullname, int format, FILE *fp,
}
I = &ic->ximages[id];
- pdf_init_ximage_struct(I, ident, ident, dict);
- pdf_ximage_set_page(I, page_no, 0);
+ pdf_init_ximage_struct(I, ident, fullname, page_no, dict);
switch (format) {
case IMAGE_TYPE_JPEG:
@@ -290,8 +292,14 @@ load_image (const char *ident, const char *fullname, int format, FILE *fp,
case IMAGE_TYPE_PDF:
if (_opts.verbose)
MESG("[PDF]");
- if (pdf_include_page(I, fp) < 0)
- goto error;
+ {
+ int result = pdf_include_page(I, fp, fullname);
+ if (result > 0)
+ /* PDF version too recent */
+ result = ps_include_page(I);
+ if (result < 0)
+ goto error;
+ }
if (_opts.verbose)
MESG(",Page:%ld", I->page_no);
I->subtype = PDF_XOBJECT_TYPE_FORM;
@@ -300,7 +308,7 @@ load_image (const char *ident, const char *fullname, int format, FILE *fp,
default:
if (_opts.verbose)
MESG(format == IMAGE_TYPE_EPS ? "[PS]" : "[UNKNOWN]");
- if (ps_include_page(I, fullname) < 0)
+ if (ps_include_page(I) < 0)
goto error;
if (_opts.verbose)
MESG(",Page:%ld", I->page_no);
@@ -339,24 +347,31 @@ pdf_ximage_findresource (const char *ident, long page_no, pdf_obj *dict)
struct ic_ *ic = &_ic;
int id = -1;
pdf_ximage *I;
- char *fullname;
+ char *fullname, *f = NULL;
int format;
FILE *fp;
for (id = 0; id < ic->count; id++) {
I = &ic->ximages[id];
- if (I->ident && !strcmp(ident, I->ident) &&
- I->page_no == page_no + (page_no < 0 ? I->page_count+1 : 0) &&
- I->attr_dict == dict) {
- return id;
+ if (I->ident && !strcmp(ident, I->ident)) {
+ f = I->filename;
+ if (I->page_no == page_no && I->attr_dict == dict) {
+ return id;
+ }
}
}
- /* try loading image */
- fullname = dpx_find_file(ident, "_pic_", "");
- if (!fullname) {
- WARN("Error locating image file \"%s\"", ident);
- return -1;
+ if (f) {
+ /* we already have converted this file; f is the temporary file name */
+ fullname = NEW(strlen(f)+1, char);
+ strcpy(fullname, f);
+ } else {
+ /* try loading image */
+ fullname = dpx_find_file(ident, "_pic_", "");
+ if (!fullname) {
+ WARN("Error locating image file \"%s\"", ident);
+ return -1;
+ }
}
fp = dpx_fopen(fullname, FOPEN_RBIN_MODE);
@@ -472,12 +487,6 @@ pdf_ximage_init_image_info (ximage_info *info)
info->xdensity = info->ydensity = 1.0;
}
-char *
-pdf_ximage_get_ident (pdf_ximage *I)
-{
- return I->ident;
-}
-
void
pdf_ximage_set_image (pdf_ximage *I, void *image_info, pdf_obj *resource)
{
@@ -534,14 +543,6 @@ pdf_ximage_get_page (pdf_ximage *I)
return I->page_no;
}
-void
-pdf_ximage_set_page (pdf_ximage *I, long page_no, long page_count)
-{
- I->page_no = page_no;
- I->page_count = page_count;
-}
-
-
#define CHECK_ID(c,n) do {\
if ((n) < 0 || (n) >= (c)->count) {\
ERROR("Invalid XObject ID: %d", (n));\
@@ -581,7 +582,7 @@ pdf_ximage_defineresource (const char *ident,
I = &ic->ximages[id];
- pdf_init_ximage_struct(I, ident, NULL, NULL);
+ pdf_init_ximage_struct(I, ident, NULL, 0, NULL);
switch (subtype) {
case PDF_XOBJECT_TYPE_IMAGE:
@@ -614,6 +615,37 @@ pdf_ximage_get_resname (int id)
return I->res_name;
}
+int
+pdf_ximage_get_subtype (int id)
+{
+ struct ic_ *ic = &_ic;
+ pdf_ximage *I;
+
+ CHECK_ID(ic, id);
+
+ I = GET_IMAGE(ic, id);
+
+ return I->subtype;
+}
+
+void
+pdf_ximage_set_attr (int id, long width, long height, double xdensity, double ydensity, double llx, double lly, double urx, double ury)
+{
+ struct ic_ *ic = &_ic;
+ pdf_ximage *I;
+
+ CHECK_ID(ic, id);
+
+ I = GET_IMAGE(ic, id);
+ I->attr.width = width;
+ I->attr.height = height;
+ I->attr.xdensity = xdensity;
+ I->attr.ydensity = ydensity;
+ I->attr.bbox.llx = llx;
+ I->attr.bbox.lly = lly;
+ I->attr.bbox.urx = urx;
+ I->attr.bbox.ury = ury;
+}
/* depth...
* Dvipdfm treat "depth" as "yoffset" for pdf:image and pdf:uxobj
@@ -835,9 +867,10 @@ char *get_distiller_template (void)
}
static int
-ps_include_page (pdf_ximage *ximage, const char *filename)
+ps_include_page (pdf_ximage *ximage)
{
char *distiller_template = _opts.cmdtmpl;
+ char *filename = ximage->filename;
char *temp;
FILE *fp;
int error = 0;
@@ -855,17 +888,6 @@ ps_include_page (pdf_ximage *ximage, const char *filename)
return -1;
}
-#ifdef MIKTEX
- {
- char *p;
- for (p = (char *)filename; *p; p++) {
- if (*p == '\\') *p = '/';
- }
- for (p = (char *)temp; *p; p++) {
- if (*p == '\\') *p = '/';
- }
- }
-#endif
if (keep_cache != -1 && stat(temp, &stat_t)==0 && stat(filename, &stat_o)==0
&& stat_t.st_mtime > stat_o.st_mtime) {
/* cache exist */
@@ -895,8 +917,7 @@ ps_include_page (pdf_ximage *ximage, const char *filename)
return -1;
}
pdf_set_ximage_tempfile(ximage, temp);
-// error = pdf_include_page(ximage, fp, 0, pdfbox_crop);
- error = pdf_include_page(ximage, fp);
+ error = pdf_include_page(ximage, fp, temp);
MFCLOSE(fp);
/* See pdf_close_images for why we cannot delete temporary files here. */
diff --git a/Build/source/texk/dvipdf-x/xsrc/pdfximage.h b/Build/source/texk/dvipdf-x/xsrc/pdfximage.h
index b1746aa3383..6341605b57a 100644
--- a/Build/source/texk/dvipdf-x/xsrc/pdfximage.h
+++ b/Build/source/texk/dvipdf-x/xsrc/pdfximage.h
@@ -59,6 +59,7 @@ extern void pdf_init_images (void);
extern void pdf_close_images (void);
extern char *pdf_ximage_get_resname (int xobj_id);
+extern int pdf_ximage_get_subtype (int xobj_id);
extern pdf_obj *pdf_ximage_get_reference (int xobj_id);
@@ -70,10 +71,8 @@ extern int pdf_ximage_defineresource (const char *ident, int subtype,
/* Called by pngimage, jpegimage, epdf, mpost, etc. */
extern void pdf_ximage_init_image_info (ximage_info *info);
extern void pdf_ximage_init_form_info (xform_info *info);
-extern char *pdf_ximage_get_ident (pdf_ximage *ximage);
extern void pdf_ximage_set_image (pdf_ximage *ximage, void *info, pdf_obj *resource);
extern void pdf_ximage_set_form (pdf_ximage *ximage, void *info, pdf_obj *resource);
-extern void pdf_ximage_set_page (pdf_ximage *ximage, long page_no, long page_count);
extern long pdf_ximage_get_page (pdf_ximage *I);
/* from psimage.h */
@@ -89,4 +88,8 @@ pdf_ximage_scale_image (int id,
/* from dvipdfmx.c */
extern void pdf_ximage_disable_ebb (void);
+
+/* from spc_pdfm.c */
+extern int pdf_ximage_get_subtype (int xobj_id);
+extern void pdf_ximage_set_attr (int xobj_id, long width, long height, double xdensity, double ydensity, double llx, double lly, double urx, double ury);
#endif /* _PDFXIMAGE_H_ */
diff --git a/Build/source/texk/dvipdf-x/xsrc/spc_pdfm.c b/Build/source/texk/dvipdf-x/xsrc/spc_pdfm.c
index 7aa8863ae9b..c7b25c5cc8b 100644
--- a/Build/source/texk/dvipdf-x/xsrc/spc_pdfm.c
+++ b/Build/source/texk/dvipdf-x/xsrc/spc_pdfm.c
@@ -670,7 +670,7 @@ spc_handler_pdfm_annot (struct spc_env *spe, struct spc_arg *args)
if (ident)
spc_push_object(ident, pdf_link_obj(annot_dict));
/* This add reference. */
- pdf_doc_add_annot(pdf_doc_current_page_number(), &rect, annot_dict);
+ pdf_doc_add_annot(pdf_doc_current_page_number(), &rect, annot_dict, 1);
if (ident) {
spc_flush_object(ident);
@@ -832,7 +832,7 @@ spc_handler_pdfm_etrans (struct spc_env *spe, struct spc_arg *args)
* starting a new page.
*/
pdf_dev_reset_fonts();
- pdf_dev_reset_color();
+ pdf_dev_reset_color(0);
return 0;
}
diff --git a/Build/source/texk/dvipdf-x/xsrc/specials.c b/Build/source/texk/dvipdf-x/xsrc/specials.c
index 0b9800eb81b..e1cc2bb7a9f 100644
--- a/Build/source/texk/dvipdf-x/xsrc/specials.c
+++ b/Build/source/texk/dvipdf-x/xsrc/specials.c
@@ -22,8 +22,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#if HAVE_CONFIG_H
-#include "config.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
#endif
#include <stdarg.h>
@@ -286,31 +286,12 @@ spc_lookup_object (const char *key)
void
spc_push_object (const char *key, pdf_obj *value)
{
- int error = 0;
+ ASSERT(named_objects);
if (!key || !value)
return;
- if (PDF_OBJ_INDIRECTTYPE(value)) {
- pdf_names_add_reference(named_objects,
- key, strlen(key), value);
- } else {
- error = pdf_names_add_object(named_objects,
- key, strlen(key), value);
- if (!error) {
- /* _FIXME_:
- * Objects created by pdf:obj must always
- * be written to output regardless of if
- * they are actually used in document.
- */
- pdf_obj *obj_ref = pdf_names_lookup_reference(named_objects,
- key, strlen(key));
- if (obj_ref)
- pdf_release_obj(obj_ref);
- }
- }
-
- return;
+ pdf_names_add_object(named_objects, key, strlen(key), value);
}
void