summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipdfm-x/pdfnames.c
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2020-07-20 20:56:58 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2020-07-20 20:56:58 +0000
commitdbfd3d35c0325197dec305820484818e46f8ac13 (patch)
treea85efc199f7dc07a4ac77be05e0aac00b6b72566 /Build/source/texk/dvipdfm-x/pdfnames.c
parent42232d1095a8b15d33ecf3448250569fc6ed6915 (diff)
support forward reference of image objects (S. Hirata)
git-svn-id: svn://tug.org/texlive/trunk@55887 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/dvipdfm-x/pdfnames.c')
-rw-r--r--Build/source/texk/dvipdfm-x/pdfnames.c84
1 files changed, 61 insertions, 23 deletions
diff --git a/Build/source/texk/dvipdfm-x/pdfnames.c b/Build/source/texk/dvipdfm-x/pdfnames.c
index ae9584145d6..c6df49c0d43 100644
--- a/Build/source/texk/dvipdfm-x/pdfnames.c
+++ b/Build/source/texk/dvipdfm-x/pdfnames.c
@@ -1,6 +1,6 @@
/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
- Copyright (C) 2002-2016 by Jin-Hwan Cho and Shunsaku Hirata,
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
the dvipdfmx project team.
Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
@@ -44,6 +44,7 @@
struct obj_data
{
+ pdf_obj *reference;
pdf_obj *object;
int closed; /* 1 if object is closed */
};
@@ -80,9 +81,13 @@ hval_free (void *hval)
value = (struct obj_data *) hval;
+ if (value->reference) {
+ pdf_release_obj(value->reference);
+ value->reference = NULL;
+ }
if (value->object) {
pdf_release_obj(value->object);
- value->object = NULL;
+ value->object = NULL;
}
RELEASE(value);
@@ -114,11 +119,10 @@ check_objects_defined (struct ht_table *ht_tab)
key = ht_iter_getkey(&iter, &keylen);
value = ht_iter_getval(&iter);
- ASSERT(value->object);
if (PDF_OBJ_UNDEFINED(value->object)) {
- pdf_names_add_object(ht_tab, key, keylen, pdf_new_null());
- WARN("Object @%s used, but not defined. Replaced by null.",
- printable_key(key, keylen));
+ pdf_names_add_object(ht_tab, key, keylen, pdf_new_null());
+ WARN("Object @%s used, but not defined. Replaced by null.",
+ printable_key(key, keylen));
}
} while (ht_iter_next(&iter) >= 0);
ht_clear_iter(&iter);
@@ -138,8 +142,7 @@ pdf_delete_name_tree (struct ht_table **names)
}
int
-pdf_names_add_object (struct ht_table *names,
- const void *key, int keylen, pdf_obj *object)
+pdf_names_add_object (struct ht_table *names, const void *key, int keylen, pdf_obj *object)
{
struct obj_data *value;
@@ -154,11 +157,11 @@ pdf_names_add_object (struct ht_table *names,
if (!value) {
value = NEW(1, struct obj_data);
value->object = object;
+ value->reference = NULL;
value->closed = 0;
ht_append_table(names, key, keylen, value);
} else {
- ASSERT(value->object);
- if (PDF_OBJ_UNDEFINED(value->object)) {
+ if (value->object && PDF_OBJ_UNDEFINED(value->object)) {
pdf_transfer_label(object, value->object);
pdf_release_obj(value->object);
value->object = object;
@@ -172,38 +175,71 @@ pdf_names_add_object (struct ht_table *names,
return 0;
}
+pdf_obj *
+pdf_names_reserve (struct ht_table *names, const void *key, int keylen)
+{
+ pdf_obj *obj_ref = NULL;
+ struct obj_data *value;
+
+ ASSERT(names);
+
+ if (!key || keylen < 1) {
+ WARN("Null string used for name tree key.");
+ return NULL;
+ }
+
+ value = ht_lookup_table(names, key, keylen);
+ if (!value) {
+ value = NEW(1, struct obj_data);
+ value->object = pdf_new_undefined();
+ value->reference = NULL;
+ value->closed = 0;
+ ht_append_table(names, key, keylen, value);
+ obj_ref = pdf_ref_obj(value->object);
+ } else {
+ if (value->object && PDF_OBJ_UNDEFINED(value->object)) {
+ if (!value->reference)
+ value->reference = pdf_ref_obj(value->object);
+ obj_ref = pdf_link_obj(value->reference);
+ } else {
+ WARN("Object @%s already defined.", printable_key(key, keylen));
+ obj_ref = NULL;
+ }
+ }
+
+ return obj_ref;
+}
+
/*
* The following routine returns copies, not the original object.
*/
pdf_obj *
-pdf_names_lookup_reference (struct ht_table *names,
- const void *key, int keylen)
+pdf_names_lookup_reference (struct ht_table *names, const void *key, int keylen)
{
struct obj_data *value;
- pdf_obj *object;
+ pdf_obj *obj_ref;
ASSERT(names);
value = ht_lookup_table(names, key, keylen);
if (value) {
- object = value->object;
- ASSERT(object);
+ if (!value->reference)
+ value->reference = pdf_ref_obj(value->object);
+ obj_ref = pdf_link_obj(value->reference);
} else {
/* A null object as dummy would create problems because as value
* of a dictionary entry, a null object is be equivalent to no entry
* at all. This matters for optimization of PDF destinations.
*/
- object = pdf_new_undefined();
- pdf_names_add_object(names, key, keylen, object);
+ obj_ref = pdf_names_reserve(names, key, keylen);
}
- return pdf_ref_obj(object);
+ return obj_ref;
}
pdf_obj *
-pdf_names_lookup_object (struct ht_table *names,
- const void *key, int keylen)
+pdf_names_lookup_object (struct ht_table *names, const void *key, int keylen)
{
struct obj_data *value;
@@ -212,14 +248,14 @@ pdf_names_lookup_object (struct ht_table *names,
value = ht_lookup_table(names, key, keylen);
if (!value || PDF_OBJ_UNDEFINED(value->object))
return NULL;
- ASSERT(value->object);
+ if (value->closed)
+ WARN("Object \"%s\" already closed.", printable_key(key, keylen));
return value->object;
}
int
-pdf_names_close_object (struct ht_table *names,
- const void *key, int keylen)
+pdf_names_close_object (struct ht_table *names, const void *key, int keylen)
{
struct obj_data *value;
@@ -237,6 +273,8 @@ pdf_names_close_object (struct ht_table *names,
return -1;
}
+ pdf_release_obj(value->object);
+ value->object = NULL;
value->closed = 1;
return 0;