summaryrefslogtreecommitdiff
path: root/Build/source
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2020-07-25 22:06:35 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2020-07-25 22:06:35 +0000
commitc44cc0e342ab0ab537882d1f6b312a770c519f18 (patch)
treebfe3d00b70fbc5b3301a19178818804d17548577 /Build/source
parent66279a58ec36789c4d363e2d4598176d99f43c66 (diff)
Place static variables into a single struct. Various minor improvements (S. Hirata).
git-svn-id: svn://tug.org/texlive/trunk@55945 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source')
-rw-r--r--Build/source/texk/dvipdfm-x/ChangeLog16
-rw-r--r--Build/source/texk/dvipdfm-x/cmap_write.c18
-rwxr-xr-xBuild/source/texk/dvipdfm-x/configure22
-rw-r--r--Build/source/texk/dvipdfm-x/configure.ac2
-rw-r--r--Build/source/texk/dvipdfm-x/dpxconf.c4
-rw-r--r--Build/source/texk/dvipdfm-x/dpxconf.h3
-rw-r--r--Build/source/texk/dvipdfm-x/dpxutil.c88
-rw-r--r--Build/source/texk/dvipdfm-x/dpxutil.h5
-rw-r--r--Build/source/texk/dvipdfm-x/dvi.c90
-rw-r--r--Build/source/texk/dvipdfm-x/dvipdfmx.c246
-rw-r--r--Build/source/texk/dvipdfm-x/pdfdev.c1414
-rw-r--r--Build/source/texk/dvipdfm-x/pdfdev.h67
-rw-r--r--Build/source/texk/dvipdfm-x/pdfdoc.c80
-rw-r--r--Build/source/texk/dvipdfm-x/pdfdoc.h6
-rw-r--r--Build/source/texk/dvipdfm-x/pdfencrypt.c385
-rw-r--r--Build/source/texk/dvipdfm-x/pdfencrypt.h21
-rw-r--r--Build/source/texk/dvipdfm-x/pdfobj.c1216
-rw-r--r--Build/source/texk/dvipdfm-x/pdfobj.h33
-rw-r--r--Build/source/texk/dvipdfm-x/pdfparse.c146
-rw-r--r--Build/source/texk/dvipdfm-x/pdfparse.h13
-rw-r--r--Build/source/texk/dvipdfm-x/pdfximage.c1
-rw-r--r--Build/source/texk/dvipdfm-x/spc_pdfm.c98
-rw-r--r--Build/source/texk/dvipdfm-x/xbb.c2
23 files changed, 2135 insertions, 1841 deletions
diff --git a/Build/source/texk/dvipdfm-x/ChangeLog b/Build/source/texk/dvipdfm-x/ChangeLog
index d6d4bec2d8b..9a3ee71ebcc 100644
--- a/Build/source/texk/dvipdfm-x/ChangeLog
+++ b/Build/source/texk/dvipdfm-x/ChangeLog
@@ -1,3 +1,19 @@
+2020-07-26 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * cmap_write.c: Change ariable names.
+ * dvipdfmx.c: Remove unused variables. Modify init sequence.
+ Page size specified as a command line option overwrites
+ settings specified by pagesize specials.
+ * pdfdev.[ch], pdfdoc.[ch], pdfencrypt.[ch], pdfobj.[ch]:
+ File static variables are now placed in a single struct.
+ * pdfparse.[ch], spc_pdfm.c: PDF parse object function is
+ called with a callback function to be called when an object of
+ unknown type is encountered.
+ * pdfximage.c: Do not include an unnecessary file.
+ * dpxconf.[ch], xbb.c: Add is_xbb in dpx_conf.
+ * dpxutil.[ch], dvi.c, dvipdfmx.c: Add dpx_util_read_length().
+ * configure.ac: Version 20200726.
+
2020-07-24 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
* cidtype0.c: Fix a bug introduced in rev.37144 that generated
diff --git a/Build/source/texk/dvipdfm-x/cmap_write.c b/Build/source/texk/dvipdfm-x/cmap_write.c
index 314a9e9526a..3af5f9acbe7 100644
--- a/Build/source/texk/dvipdfm-x/cmap_write.c
+++ b/Build/source/texk/dvipdfm-x/cmap_write.c
@@ -1,6 +1,6 @@
/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
- Copyright (C) 2002-2019 by Jin-Hwan Cho and Shunsaku Hirata,
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
the dvipdfmx project team.
This program is free software; you can redistribute it and/or modify
@@ -240,14 +240,14 @@ write_map (mapDef *mtab, int count,
/* duplicated from pdfobj.c */
static void
-write_string (char **outptr, char *endptr, const char *strptr)
+write_string (char **outptr, char *endptr, const char *string_data)
{
- const char *s;
char *p;
+ const char *s;
int i, length;
- s = strptr;
- length = strptr ? strlen(strptr) : 0;
+ s = string_data;
+ length = string_data ? strlen(string_data) : 0;
p = *outptr;
*p++ = '(';
@@ -275,14 +275,14 @@ write_string (char **outptr, char *endptr, const char *strptr)
}
static void
-write_name (char **outptr, char *endptr, const char *name)
+write_name (char **outptr, char *endptr, const char *name_data)
{
- const char *s;
char *p;
+ const char *s;
int i, length;
- s = name;
- length = name ? strlen(name) : 0;
+ s = name_data;
+ length = name_data ? strlen(name_data) : 0;
p = *outptr;
#ifndef is_delim
/* Avoid '{' and '}' for PostScript compatibility? */
diff --git a/Build/source/texk/dvipdfm-x/configure b/Build/source/texk/dvipdfm-x/configure
index 90c88272bd3..1ff118c0dd1 100755
--- a/Build/source/texk/dvipdfm-x/configure
+++ b/Build/source/texk/dvipdfm-x/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for dvipdfm-x (TeX Live) 20200721.
+# Generated by GNU Autoconf 2.69 for dvipdfm-x (TeX Live) 20200726.
#
# Report bugs to <dvipdfmx@tug.org>.
#
@@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='dvipdfm-x (TeX Live)'
PACKAGE_TARNAME='dvipdfm-x--tex-live-'
-PACKAGE_VERSION='20200721'
-PACKAGE_STRING='dvipdfm-x (TeX Live) 20200721'
+PACKAGE_VERSION='20200726'
+PACKAGE_STRING='dvipdfm-x (TeX Live) 20200726'
PACKAGE_BUGREPORT='dvipdfmx@tug.org'
PACKAGE_URL=''
@@ -1350,7 +1350,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures dvipdfm-x (TeX Live) 20200721 to adapt to many kinds of systems.
+\`configure' configures dvipdfm-x (TeX Live) 20200726 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1421,7 +1421,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of dvipdfm-x (TeX Live) 20200721:";;
+ short | recursive ) echo "Configuration of dvipdfm-x (TeX Live) 20200726:";;
esac
cat <<\_ACEOF
@@ -1551,7 +1551,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-dvipdfm-x (TeX Live) configure 20200721
+dvipdfm-x (TeX Live) configure 20200726
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2390,7 +2390,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by dvipdfm-x (TeX Live) $as_me 20200721, which was
+It was created by dvipdfm-x (TeX Live) $as_me 20200726, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -8077,7 +8077,7 @@ fi
# Define the identity of the package.
PACKAGE='dvipdfm-x--tex-live-'
- VERSION='20200721'
+ VERSION='20200726'
cat >>confdefs.h <<_ACEOF
@@ -14746,7 +14746,7 @@ Usage: $0 [OPTIONS]
Report bugs to <bug-libtool@gnu.org>."
lt_cl_version="\
-dvipdfm-x (TeX Live) config.lt 20200721
+dvipdfm-x (TeX Live) config.lt 20200726
configured by $0, generated by GNU Autoconf 2.69.
Copyright (C) 2011 Free Software Foundation, Inc.
@@ -16636,7 +16636,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by dvipdfm-x (TeX Live) $as_me 20200721, which was
+This file was extended by dvipdfm-x (TeX Live) $as_me 20200726, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -16706,7 +16706,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-dvipdfm-x (TeX Live) config.status 20200721
+dvipdfm-x (TeX Live) config.status 20200726
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/Build/source/texk/dvipdfm-x/configure.ac b/Build/source/texk/dvipdfm-x/configure.ac
index eea48de57cc..aa3acacecf5 100644
--- a/Build/source/texk/dvipdfm-x/configure.ac
+++ b/Build/source/texk/dvipdfm-x/configure.ac
@@ -8,7 +8,7 @@ dnl This file is free software; the copyright holder
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl
-AC_INIT([dvipdfm-x (TeX Live)], [20200721], [dvipdfmx@tug.org])
+AC_INIT([dvipdfm-x (TeX Live)], [20200726], [dvipdfmx@tug.org])
AC_PREREQ([2.65])
AC_CONFIG_SRCDIR([agl.c])
AC_CONFIG_AUX_DIR([../../build-aux])
diff --git a/Build/source/texk/dvipdfm-x/dpxconf.c b/Build/source/texk/dvipdfm-x/dpxconf.c
index d8279489b2b..ab7f6693ac8 100644
--- a/Build/source/texk/dvipdfm-x/dpxconf.c
+++ b/Build/source/texk/dvipdfm-x/dpxconf.c
@@ -1,6 +1,6 @@
/* This is DVIPDFMx, an eXtended version of DVIPDFM by Mark A. Wicks.
- Copyright (C) 2002-2018 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>
@@ -30,7 +30,7 @@
#include "dpxconf.h"
-struct _dpx_conf dpx_conf = {0, dpx_mode_normal_mode, 0, {0}};
+struct _dpx_conf dpx_conf = {0, 0, dpx_mode_normal_mode, 0, {0}};
#ifndef HAVE_LIBPAPER
const struct paper paperspecs[] = {
diff --git a/Build/source/texk/dvipdfm-x/dpxconf.h b/Build/source/texk/dvipdfm-x/dpxconf.h
index 8a6b775692d..e0785a1e42d 100644
--- a/Build/source/texk/dvipdfm-x/dpxconf.h
+++ b/Build/source/texk/dvipdfm-x/dpxconf.h
@@ -1,6 +1,6 @@
/* This is DVIPDFMx, an eXtended version of DVIPDFM by Mark A. Wicks.
- Copyright (C) 2002-2018 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>
@@ -31,6 +31,7 @@ enum dpx_mode {
};
extern struct _dpx_conf {
+ int is_xbb;
int verbose_level;
enum dpx_mode compat_mode;
int ignore_font_license;
diff --git a/Build/source/texk/dvipdfm-x/dpxutil.c b/Build/source/texk/dvipdfm-x/dpxutil.c
index bc21c86aeec..10a5387a4e8 100644
--- a/Build/source/texk/dvipdfm-x/dpxutil.c
+++ b/Build/source/texk/dvipdfm-x/dpxutil.c
@@ -1,6 +1,6 @@
/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
- Copyright (C) 2002-2019 by Jin-Hwan Cho and Shunsaku Hirata,
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
the dvipdfmx project team.
Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
@@ -69,6 +69,92 @@ max4 (double x1, double x2, double x3, double x4)
return v;
}
+/* Duplicate from pdfparse.c */
+static void
+skip_white (const char **pp, const char *endptr)
+{
+ while (*pp < endptr &&
+ (**pp == ' ' || **pp == '\t' || **pp == '\f' ||
+ **pp == '\r' || **pp == '\n' || **pp == '\0')) {
+ (*pp)++;
+ }
+}
+
+/* This need to allow 'true' prefix for unit and length value must be divided
+ * by current magnification.
+ */
+int
+dpx_util_read_length (double *vp, double mag, const char **pp, const char *endptr)
+{
+ char *q;
+ const char *p = *pp;
+ double v, u = 1.0;
+ const char *_ukeys[] = {
+#define K_UNIT__PT 0
+#define K_UNIT__IN 1
+#define K_UNIT__CM 2
+#define K_UNIT__MM 3
+#define K_UNIT__BP 4
+#define K_UNIT__PC 5
+#define K_UNIT__DD 6
+#define K_UNIT__CC 7
+#define K_UNIT__SP 8
+ "pt", "in", "cm", "mm", "bp", "pc", "dd", "cc", "sp",
+ NULL
+ };
+ int k, error = 0;
+
+ q = parse_float_decimal(&p, endptr);
+ if (!q) {
+ *vp = 0.0; *pp = p;
+ return -1;
+ }
+
+ v = atof(q);
+ RELEASE(q);
+
+ skip_white(&p, endptr);
+ q = parse_c_ident(&p, endptr);
+ if (q) {
+ char *qq = q; /* remember this for RELEASE, because q may be advanced */
+ if (strlen(q) >= strlen("true") &&
+ !memcmp(q, "true", strlen("true"))) {
+ u /= mag != 0.0 ? mag : 1.0; /* inverse magnify */
+ q += strlen("true");
+ }
+ if (strlen(q) == 0) { /* "true" was a separate word from the units */
+ RELEASE(qq);
+ skip_white(&p, endptr);
+ qq = q = parse_c_ident(&p, endptr);
+ }
+ if (q) {
+ for (k = 0; _ukeys[k] && strcmp(_ukeys[k], q); k++);
+ switch (k) {
+ case K_UNIT__PT: u *= 72.0 / 72.27; break;
+ case K_UNIT__IN: u *= 72.0; break;
+ case K_UNIT__CM: u *= 72.0 / 2.54 ; break;
+ case K_UNIT__MM: u *= 72.0 / 25.4 ; break;
+ case K_UNIT__BP: u *= 1.0 ; break;
+ case K_UNIT__PC: u *= 12.0 * 72.0 / 72.27 ; break;
+ case K_UNIT__DD: u *= 1238.0 / 1157.0 * 72.0 / 72.27 ; break;
+ case K_UNIT__CC: u *= 12.0 * 1238.0 / 1157.0 * 72.0 / 72.27 ; break;
+ case K_UNIT__SP: u *= 72.0 / (72.27 * 65536) ; break;
+ default:
+ WARN("Unknown unit of measure: %s", q);
+ error = -1;
+ break;
+ }
+ RELEASE(qq);
+ }
+ else {
+ WARN("Missing unit of measure after \"true\"");
+ error = -1;
+ }
+ }
+
+ *vp = v * u; *pp = p;
+ return error;
+}
#if defined(_MSC_VER)
#define strtoll _strtoi64
diff --git a/Build/source/texk/dvipdfm-x/dpxutil.h b/Build/source/texk/dvipdfm-x/dpxutil.h
index 8268659917f..11aaa1f18d8 100644
--- a/Build/source/texk/dvipdfm-x/dpxutil.h
+++ b/Build/source/texk/dvipdfm-x/dpxutil.h
@@ -1,6 +1,6 @@
/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
- Copyright (C) 2002-2018 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>
@@ -35,6 +35,9 @@
extern double min4(double v1, double v2, double v3, double v4);
extern double max4(double v1, double v2, double v3, double v4);
+extern int dpx_util_read_length (double *vp, double mag,
+ const char **curptr, const char *endptr);
+
#define INVALID_EPOCH_VALUE ((time_t)-1)
extern time_t dpx_util_get_unique_time_if_given (void);
extern int dpx_util_format_asn_date (char *date_string, int need_timezone);
diff --git a/Build/source/texk/dvipdfm-x/dvi.c b/Build/source/texk/dvipdfm-x/dvi.c
index 5317bfb8182..a4afab61bdb 100644
--- a/Build/source/texk/dvipdfm-x/dvi.c
+++ b/Build/source/texk/dvipdfm-x/dvi.c
@@ -2249,83 +2249,7 @@ dvi_vf_finish (void)
/* Scan various specials */
#include "dpxutil.h"
-
-/* This need to allow 'true' prefix for unit and
- * length value must be divided by current magnification.
- */
-static int
-read_length (double *vp, double mag, const char **pp, const char *endptr)
-{
- char *q;
- const char *p = *pp;
- double v, u = 1.0;
- const char *_ukeys[] = {
-#define K_UNIT__PT 0
-#define K_UNIT__IN 1
-#define K_UNIT__CM 2
-#define K_UNIT__MM 3
-#define K_UNIT__BP 4
-#define K_UNIT__PC 5
-#define K_UNIT__DD 6
-#define K_UNIT__CC 7
-#define K_UNIT__SP 8
- "pt", "in", "cm", "mm", "bp", "pc", "dd", "cc", "sp",
- NULL
- };
- int k, error = 0;
-
- q = parse_float_decimal(&p, endptr);
- if (!q) {
- *vp = 0.0; *pp = p;
- return -1;
- }
-
- v = atof(q);
- RELEASE(q);
-
- skip_white(&p, endptr);
- q = parse_c_ident(&p, endptr);
- if (q) {
- char *qq = q; /* remember this for RELEASE, because q may be advanced */
- if (strlen(q) >= strlen("true") &&
- !memcmp(q, "true", strlen("true"))) {
- u /= mag != 0.0 ? mag : 1.0; /* inverse magnify */
- q += strlen("true");
- }
- if (strlen(q) == 0) { /* "true" was a separate word from the units */
- RELEASE(qq);
- skip_white(&p, endptr);
- qq = q = parse_c_ident(&p, endptr);
- }
- if (q) {
- for (k = 0; _ukeys[k] && strcmp(_ukeys[k], q); k++);
- switch (k) {
- case K_UNIT__PT: u *= 72.0 / 72.27; break;
- case K_UNIT__IN: u *= 72.0; break;
- case K_UNIT__CM: u *= 72.0 / 2.54 ; break;
- case K_UNIT__MM: u *= 72.0 / 25.4 ; break;
- case K_UNIT__BP: u *= 1.0 ; break;
- case K_UNIT__PC: u *= 12.0 * 72.0 / 72.27 ; break;
- case K_UNIT__DD: u *= 1238.0 / 1157.0 * 72.0 / 72.27 ; break;
- case K_UNIT__CC: u *= 12.0 * 1238.0 / 1157.0 * 72.0 / 72.27 ; break;
- case K_UNIT__SP: u *= 72.0 / (72.27 * 65536) ; break;
- default:
- WARN("Unknown unit of measure: %s", q);
- error = -1;
- break;
- }
- RELEASE(qq);
- }
- else {
- WARN("Missing unit of measure after \"true\"");
- error = -1;
- }
- }
-
- *vp = v * u; *pp = p;
- return error;
-}
-
+/* For MAX_PWD_LEN */
#include "pdfencrypt.h"
static int
@@ -2486,19 +2410,19 @@ scan_special (double *wd, double *ht, double *xo, double *yo, int *lm,
else {
skip_white(&p, endptr);
if (!strcmp(kp, "width")) {
- error = read_length(&tmp, dvi_tell_mag(), &p, endptr);
+ error = dpx_util_read_length(&tmp, dvi_tell_mag(), &p, endptr);
if (!error)
*wd = tmp * dvi_tell_mag();
} else if (!strcmp(kp, "height")) {
- error = read_length(&tmp, dvi_tell_mag(), &p, endptr);
+ error = dpx_util_read_length(&tmp, dvi_tell_mag(), &p, endptr);
if (!error)
*ht = tmp * dvi_tell_mag();
} else if (!strcmp(kp, "xoffset")) {
- error = read_length(&tmp, dvi_tell_mag(), &p, endptr);
+ error = dpx_util_read_length(&tmp, dvi_tell_mag(), &p, endptr);
if (!error)
*xo = tmp * dvi_tell_mag();
} else if (!strcmp(kp, "yoffset")) {
- error = read_length(&tmp, dvi_tell_mag(), &p, endptr);
+ error = dpx_util_read_length(&tmp, dvi_tell_mag(), &p, endptr);
if (!error)
*yo = tmp * dvi_tell_mag();
} else if (!strcmp(kp, "default")) {
@@ -2519,7 +2443,7 @@ scan_special (double *wd, double *ht, double *xo, double *yo, int *lm,
qchr = *p; p++;
skip_white(&p, endptr);
}
- error = read_length(&tmp, 1.0, &p, endptr);
+ error = dpx_util_read_length(&tmp, 1.0, &p, endptr);
if (!error) {
double tmp1;
@@ -2527,7 +2451,7 @@ scan_special (double *wd, double *ht, double *xo, double *yo, int *lm,
if (p < endptr && *p == ',') {
p++; skip_white(&p, endptr);
}
- error = read_length(&tmp1, 1.0, &p, endptr);
+ error = dpx_util_read_length(&tmp1, 1.0, &p, endptr);
if (!error) {
*wd = tmp;
*ht = tmp1;
diff --git a/Build/source/texk/dvipdfm-x/dvipdfmx.c b/Build/source/texk/dvipdfm-x/dvipdfmx.c
index f67c7deb7dd..32c9acf8b14 100644
--- a/Build/source/texk/dvipdfm-x/dvipdfmx.c
+++ b/Build/source/texk/dvipdfm-x/dvipdfmx.c
@@ -2,7 +2,7 @@
DVIPDFMx, an eXtended version of DVIPDFM by Mark A. Wicks.
- Copyright (C) 2002-2020 by Jin-Hwan Cho, Matthias Franz, Shunsaku Hirata,
+ Copyright (C) 2002-2020 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata,
the DVIPDFMx project team.
Copyright (c) 2006 SIL. (xdvipdfmx extensions for XeTeX support)
@@ -70,8 +70,11 @@ const char *my_name = "ApTeX";
const char *my_name;
#endif /* LIBDPX */
-static int verbose = 0;
+/* Verbosity level */
+static int verbose = 0;
+static int really_quiet = 0;
+/* Compatibility option flags */
static int opt_flags = 0;
#define OPT_TPIC_TRANSPARENT_FILL (1 << 1)
#define OPT_CIDFONT_FIXEDPITCH (1 << 2)
@@ -80,54 +83,54 @@ static int opt_flags = 0;
#define OPT_PDFOBJ_NO_PREDICTOR (1 << 5)
#define OPT_PDFOBJ_NO_OBJSTM (1 << 6)
+/* Basic PDF output settings */
static int pdf_version_major = 1;
static int pdf_version_minor = 5;
static int compression_level = 9;
-static char ignore_colors = 0;
-static double annot_grow = 0.0;
-static int bookmark_open = 0;
-static double mag = 1.0;
-static int font_dpi = 600;
-static int enable_thumbnail = 0;
-static int really_quiet = 0;
-/*
- * Precision is essentially limited to 0.01pt.
- * See, dev_set_string() in pdfdev.c.
- */
+/* PDF document navigation feature settings */
+static double annot_grow = 0.0;
+static int bookmark_open = 0;
+static double mag = 1.0;
+static int enable_thumbnail = 0;
+
+static int font_dpi = 600;
+
+/* PDF output device settings */
static int pdfdecimaldigits = 3;
+static char ignore_colors = 0;
-/* Image cache life in hours */
-/* 0 means erase all old images and leave new images */
-/* -1 means erase all old images and also erase new images */
-/* -2 means ignore image cache (default) */
+/* Image cache life in hours
+ * 0 means erase all old images and leave new images
+ * -1 means erase all old images and also erase new images
+ * -2 means ignore image cache (default)
+ */
static int image_cache_life = -2;
/* Image format conversion filter template */
static char *filter_template = NULL;
/* Encryption */
-static int do_encryption = 0;
-static int key_bits = 40;
-static int32_t permission = 0x003C;
+static int do_encryption = 0;
+static int key_bits = 40;
+static int32_t permission = 0x003C;
/* Page device */
-double paper_width = 595.0;
-double paper_height = 842.0;
-static double x_offset = 72.0;
-static double y_offset = 72.0;
-int landscape_mode = 0;
-static int translate_origin = 0;
+double paper_width = 595.0;
+double paper_height = 842.0;
+static double x_offset = 72.0;
+static double y_offset = 72.0;
+int landscape_mode = 0;
+static int translate_origin = 0;
-/* Command line option takes precedence */
-static int has_paper_option = 0;
-static int has_encrypt_option = 0;
+static int has_paper_option = 0;
-char *dvi_filename = NULL, *pdf_filename = NULL;
+/* Input and output filenames */
+static char *dvi_filename = NULL, *pdf_filename = NULL;
static void read_config_file (const char *config);
static void
-set_default_pdf_filename(void)
+set_default_pdf_filename (void)
{
const char *dvi_base;
const char *suffix;
@@ -251,79 +254,6 @@ usage (void)
exit(1);
}
-
-static int
-read_length (double *vp, const char **pp, const char *endptr)
-{
- char *q;
- const char *p = *pp;
- double v, u = 1.0;
- const char *_ukeys[] = {
-#define K_UNIT__PT 0
-#define K_UNIT__IN 1
-#define K_UNIT__CM 2
-#define K_UNIT__MM 3
-#define K_UNIT__BP 4
-#define K_UNIT__PC 5
-#define K_UNIT__DD 6
-#define K_UNIT__CC 7
-#define K_UNIT__SP 8
- "pt", "in", "cm", "mm", "bp", "pc", "dd", "cc", "sp",
- NULL
- };
- int k, error = 0;
-
- q = parse_float_decimal(&p, endptr);
- if (!q) {
- *vp = 0.0; *pp = p;
- return -1;
- }
-
- v = atof(q);
- RELEASE(q);
-
- skip_white(&p, endptr);
- q = parse_c_ident(&p, endptr);
- if (q) {
- char *qq = q;
- if (strlen(q) >= strlen("true") &&
- !memcmp(q, "true", strlen("true"))) {
- q += strlen("true"); /* just skip "true" */
- }
- if (strlen(q) == 0) {
- RELEASE(qq);
- skip_white(&p, endptr);
- qq = q = parse_c_ident(&p, endptr);
- }
- if (q) {
- for (k = 0; _ukeys[k] && strcmp(_ukeys[k], q); k++);
- switch (k) {
- case K_UNIT__PT: u *= 72.0 / 72.27; break;
- case K_UNIT__IN: u *= 72.0; break;
- case K_UNIT__CM: u *= 72.0 / 2.54 ; break;
- case K_UNIT__MM: u *= 72.0 / 25.4 ; break;
- case K_UNIT__BP: u *= 1.0 ; break;
- case K_UNIT__PC: u *= 12.0 * 72.0 / 72.27 ; break;
- case K_UNIT__DD: u *= 1238.0 / 1157.0 * 72.0 / 72.27 ; break;
- case K_UNIT__CC: u *= 12.0 * 1238.0 / 1157.0 * 72.0 / 72.27 ; break;
- case K_UNIT__SP: u *= 72.0 / (72.27 * 65536) ; break;
- default:
- WARN("Unknown unit of measure: %s", q);
- error = -1;
- break;
- }
- RELEASE(qq);
- }
- else {
- WARN("Missing unit of measure after \"true\"");
- error = -1;
- }
- }
-
- *vp = v * u; *pp = p;
- return error;
-}
-
static void
select_paper (const char *paperspec)
{
@@ -340,9 +270,9 @@ select_paper (const char *paperspec)
endptr = p + strlen(p);
if (!comma)
ERROR("Unrecognized paper format: %s", paperspec);
- error = read_length(&paper_width, &p, comma);
+ error = dpx_util_read_length(&paper_width, 1.0, &p, comma);
p = comma + 1;
- error = read_length(&paper_height, &p, endptr);
+ error = dpx_util_read_length(&paper_height, 1.0, &p, endptr);
}
if (error || paper_width <= 0.0 || paper_height <= 0.0)
ERROR("Invalid paper size: %s (%.2fx%.2f)", paperspec, paper_width, paper_height);
@@ -618,17 +548,17 @@ do_args_second_pass (int argc, char *argv[], const char *source, int unsafe)
case 'g':
nnextptr = nextptr = optarg;
- read_length(&annot_grow, &nnextptr, nextptr + strlen(nextptr));
+ dpx_util_read_length(&annot_grow, 1.0, &nnextptr, nextptr + strlen(nextptr));
break;
case 'x':
nnextptr = nextptr = optarg;
- read_length(&x_offset, &nnextptr, nextptr + strlen(nextptr));
+ dpx_util_read_length(&x_offset, 1.0, &nnextptr, nextptr + strlen(nextptr));
break;
case 'y':
nnextptr = nextptr = optarg;
- read_length(&y_offset, &nnextptr, nextptr + strlen(nextptr));
+ dpx_util_read_length(&y_offset, 1.0, &nnextptr, nextptr + strlen(nextptr));
break;
case 'o':
@@ -699,7 +629,6 @@ do_args_second_pass (int argc, char *argv[], const char *source, int unsafe)
case 'S':
do_encryption = 1;
- has_encrypt_option = 1;
break;
case 'K':
@@ -935,20 +864,34 @@ do_dvi_pages (void)
int lm;
MESG("[%d", page_no+1);
- /* Users want to change page size even after page is started! */
+ /* FIXME: incompatibility here.... In older versions of dvipdfmx page sizes
+ * are inherited from the previous page but in the current implementation
+ * pagesize special only takes effect to the current page.
+ * The following line resets page sizes to the paper size...
+ */
page_width = paper_width; page_height = paper_height;
w = page_width; h = page_height; lm = landscape_mode;
xo = x_offset; yo = y_offset;
dvi_scan_specials(page_no,
&w, &h, &xo, &yo, &lm,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
- if (lm != landscape_mode) { /* already swapped for the first page */
+ /* No need for encryption options */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ /* No trailer IDs */
+ NULL, NULL, NULL);
+ if (lm != landscape_mode) {
+ /* The first page was already scanned once and SWAP() was applied there.
+ * Do not apply SWAP() twice!
+ * FIXME: SWAP() not applied to paper_width and paper_height. Why?
+ */
SWAP(w, h);
landscape_mode = lm;
}
- if (page_width != w || page_height != h) {
- page_width = w;
- page_height = h;
+ /* Specified as a command line option */
+ if (!has_paper_option) {
+ if (page_width != w || page_height != h) {
+ page_width = w;
+ page_height = h;
+ }
}
if (x_offset != xo || y_offset != yo) {
x_offset = xo;
@@ -1095,27 +1038,26 @@ main (int argc, char *argv[])
STREQ (argv[1], "--ebb"))) {
argc--;
base = argv++[1]+2;
- } else
+ } else {
base = kpse_program_basename (argv[0]);
-
+ }
+
if (FILESTRCASEEQ (base, "extractbb") || FILESTRCASEEQ (base, "xbb")) {
my_name = "extractbb";
return extractbb (argc, argv);
- }
- if (FILESTRCASEEQ (base, "ebb")) {
+ } else if (FILESTRCASEEQ (base, "ebb")) {
my_name = "ebb";
dpx_conf.compat_mode = dpx_mode_compat_mode;
return extractbb (argc, argv);
- }
- if (FILESTRCASEEQ (base, "dvipdfm"))
+ } else if (FILESTRCASEEQ (base, "dvipdfm")) {
dpx_conf.compat_mode = dpx_mode_compat_mode;
- if (FILESTRCASEEQ (base, "dvipdfmx"))
+ } else if (FILESTRCASEEQ (base, "dvipdfmx")) {
my_name = "dvipdfmx";
- else
+ } else {
my_name = "xdvipdfmx";
-
- opterr = 0;
+ }
+ opterr = 0;
/* Special-case single option --mvorigin, --help, --showpaper, or --version,
* to avoid possible diagnostics about config files, etc.
* Also handle -q and -v that cannot be set in config file.
@@ -1130,6 +1072,12 @@ main (int argc, char *argv[])
read_config_file(DPX_CONFIG_FILE);
+ /* Current implementation seems to be assuming that paper size read from config
+ * is for "default" and explicitly specified one via command-line option must be
+ * used for all pages regardless of papersize specials.
+ */
+ has_paper_option = 0;
+
#ifndef MIKTEX
kpse_init_prog("", font_dpi, NULL, NULL);
kpse_set_program_enabled(kpse_pk_format, true, kpse_src_texmf_cnf);
@@ -1157,7 +1105,6 @@ main (int argc, char *argv[])
y_offset = 0.0;
dvi2pts = 0.01; /* dvi2pts controls accuracy. */
} else {
- /* Dependency between DVI and PDF side is rather complicated... */
dvi2pts = dvi_init(dvi_filename, mag);
if (dvi2pts == 0.0)
ERROR("dvi_init() failed!");
@@ -1180,9 +1127,24 @@ main (int argc, char *argv[])
}
}
-/* moved to here because image caching was not effective */
+ /* moved to here because image caching was not effective */
dpx_delete_old_cache(image_cache_life);
+ /* Setup Options */
+ settings.ver_major = pdf_version_major;
+ settings.ver_minor = pdf_version_minor;
+
+ /* PDF trailer ID. */
+ if (!has_id) {
+#define PRODUCER \
+"%s-%s, Copyright 2002-2020 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata"
+ char producer[256];
+
+ sprintf(producer, PRODUCER, my_name, VERSION);
+ compute_id_string(id1, producer, dvi_filename, pdf_filename);
+ memcpy(id2, id1, 16);
+ }
+
/* Encryption and Other Settings */
{
memset(&settings.encrypt, 0, sizeof(struct pdf_enc_setting));
@@ -1195,6 +1157,8 @@ main (int argc, char *argv[])
settings.encrypt.oplain = oplain;
}
+ /* PDF object settings */
+ settings.object.compression_level = compression_level;
if (opt_flags & OPT_PDFOBJ_NO_OBJSTM) {
settings.object.enable_objstm = 0;
} else {
@@ -1205,7 +1169,9 @@ main (int argc, char *argv[])
} else {
settings.object.enable_predictor = 1;
}
- /* Set default paper size here so that all page's can inherite it.
+
+ /* PDF document settings
+ * Set default paper size here so that all page's can inherite it.
* annot_grow: Margin of annotation.
* bookmark_open: Miximal depth of open bookmarks.
*/
@@ -1217,32 +1183,14 @@ main (int argc, char *argv[])
settings.annot_grow_amount = annot_grow;
settings.outline_open_depth = bookmark_open;
settings.check_gotos = !(opt_flags & OPT_PDFDOC_NO_DEST_REMOVE);
+ settings.enable_manual_thumb = enable_thumbnail;
+ /* PDF page output settings */
settings.device.dvi2pts = dvi2pts;
settings.device.precision = pdfdecimaldigits;
settings.device.ignore_colors = ignore_colors;
set_distiller_template(filter_template);
- /* This must come before pdf_open_document where initialization
- * of pdf_enc takes place.
- */
- {
- int version = pdf_version_major * 10 + pdf_version_minor;
- pdf_set_version(version);
- }
- pdf_set_compression(compression_level);
- if (enable_thumbnail)
- pdf_doc_enable_manual_thumbnails();
-
- if (!has_id) {
-#define PRODUCER \
-"%s-%s, Copyright 2002-2015 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata"
- char producer[256];
-
- sprintf(producer, PRODUCER, my_name, VERSION);
- compute_id_string(id1, producer, dvi_filename, pdf_filename);
- memcpy(id2, id1, 16);
- }
/* Initialize PDF document creation routine. */
pdf_open_document(pdf_filename, creator, id1, id2, settings);
diff --git a/Build/source/texk/dvipdfm-x/pdfdev.c b/Build/source/texk/dvipdfm-x/pdfdev.c
index a8e19e5282e..27d7192f20f 100644
--- a/Build/source/texk/dvipdfm-x/pdfdev.c
+++ b/Build/source/texk/dvipdfm-x/pdfdev.c
@@ -53,33 +53,245 @@
#include "pdfdev.h"
-/* Not working yet... */
-double
-pdf_dev_scale (void)
+struct dev_param
{
- return 1.0;
-}
+ /* Text composition (direction) mode is ignored (always same
+ * as font's writing mode) if autorotate is unset (value zero).
+ */
+ int autorotate;
+
+ /*
+ * Ignore color migrated to here. This is device's capacity.
+ * colormode 0 for ignore colors
+ */
+ int colormode;
+
+};
+
+/*
+ * Text handling routines.
+ */
+
+/* Motion state:
+ * GRAPHICS_MODE Initial state (not within BT/ET block nor in string)
+ * TEXT_MODE Text section is started via BT operator but not
+ * in string.
+ * STRING_MODE In string. A string or array of strings are currently
+ * in process. May started '[', '<' or '('.
+ */
+#define GRAPHICS_MODE 1
+#define TEXT_MODE 2
+#define STRING_MODE 3
+
+/*
+ * In PDF, vertical text positioning is always applied when current font
+ * is vertical font. While ASCII pTeX manages current writing direction
+ * and font's WMode separately.
+ *
+ * 000/101 WMODE_HH/VV h(v) font, h(v) direction.
+ * 001 WMODE_HV -90 deg. rotated
+ * 100 WMODE_VH +90 deg. rotated
+ * 011 WMODE_HD +90 deg. rotated
+ * 111 WMODE_VD 180 deg. rotated
+
+ * In MetaPost PostScript file processing (mp_mode = 1), only HH/VV mode
+ * is applied.
+ */
+#define TEXT_WMODE_HH 0
+#define TEXT_WMODE_HV 1
+#define TEXT_WMODE_VH 4
+#define TEXT_WMODE_VV 5
+#define TEXT_WMODE_HD 3
+#define TEXT_WMODE_VD 7
+
+#define ANGLE_CHANGES(m1,m2) ((abs((m1)-(m2)) % 5) == 0 ? 0 : 1)
+#define ROTATE_TEXT(m) ((m) != TEXT_WMODE_HH && (m) != TEXT_WMODE_VV)
+
+struct text_state {
+
+ /* Current font.
+ * This is index within dev_fonts.
+ */
+ int font_id;
+
+ /* Dvipdfmx does compression of text by doing text positioning
+ * in relative motion and uses string array [(foo) -250 (bar)]
+ * with kerning (negative kern is used for white space as suited
+ * for TeX). This is offset within current string.
+ */
+ spt_t offset;
+
+ /* This is reference point of strings.
+ * It may include error correction induced by rounding.
+ */
+ spt_t ref_x;
+ spt_t ref_y;
+
+ /* Using text raise and leading is highly recommended for
+ * text extraction to work properly. But not implemented yet.
+ * We can't do consice output for \TeX without this.
+ */
+ spt_t raise; /* unused */
+ spt_t leading; /* unused */
+
+ /* This is not always text matrix but rather font matrix.
+ * We do not use horizontal scaling in PDF text state parameter
+ * since they always apply scaling in fixed direction regardless
+ * of writing mode.
+ */
+ struct {
+ double slant;
+ double extend;
+ int rotate; /* TEXT_WMODE_XX */
+ } matrix;
+
+ /* Fake bold parameter:
+ * If bold_param is positive, use text rendering mode
+ * fill-then-stroke with stroking line width specified
+ * by bold_param.
+ */
+ double bold_param;
+
+ /* Text composition (direction) mode. */
+ int dir_mode;
+
+ /* internal */
+
+ /* Flag indicating text matrix to be forcibly reset.
+ * Enabled if synthetic font features (slant, extend, etc)
+ * are used for current font or when text rotation mode
+ * changes.
+ */
+ int force_reset;
+
+ /* This information is duplicated from dev[font_id].format.
+ * Set to 1 if font is composite (Type0) font.
+ */
+ int is_mb;
+};
+
+#define PDF_FONTTYPE_SIMPLE 1
+#define PDF_FONTTYPE_BITMAP 2
+#define PDF_FONTTYPE_COMPOSITE 3
+
+struct dev_font {
+ /* Needs to be big enough to hold name "Fxxx"
+ * where xxx is number of largest font
+ */
+ char short_name[7]; /* Resource name */
+ int used_on_this_page;
+
+ char *tex_name; /* String identifier of this font */
+ spt_t sptsize; /* Point size */
+
+ /* Returned values from font/encoding layer:
+ *
+ * The font_id and enc_id is font and encoding (CMap) identifier
+ * used in pdf_font or encoding/cmap layer.
+ * The PDF object "resource" is an indirect reference object
+ * pointing font resource of this font. The used_chars is somewhat
+ * misleading, this is actually used_glyphs in CIDFont for Type0
+ * and is 65536/8 bytes binary data with each bits representing
+ * whether the glyph is in-use or not. It is 256 char array for
+ * simple font.
+ */
+ int font_id;
+ int enc_id;
+
+ /* if >= 0, index of a dev_font that really has the resource and used_chars */
+ int real_font_index;
+
+ pdf_obj *resource;
+ char *used_chars;
+
+ /* Font format:
+ * simple, composite or bitmap.
+ */
+ int format;
+
+ /* Writing mode:
+ * Non-zero for vertical. Duplicated from CMap.
+ */
+ int wmode;
+
+ /* Syntetic Font:
+ *
+ * We use text matrix for creating extended or slanted font,
+ * but not with font's FontMatrix since TrueType and Type0
+ * font don't support them.
+ */
+ double extend;
+ double slant;
+ double bold; /* Boldness prameter */
+
+ /* Compatibility */
+ int mapc; /* Nasty workaround for Omega */
+
+ /* There are no font metric format supporting four-bytes
+ * charcter code. So we should provide an option to specify
+ * UCS group and plane.
+ */
+ int ucs_group;
+ int ucs_plane;
+
+ int is_unicode;
+};
/*
* Unit conversion, formatting and others.
*/
#define TEX_ONE_HUNDRED_BP 6578176
-static struct {
- double dvi2pts;
+struct dev_unit {
+ double dvi2pts; /* multiplier for DVI unit to bpt conversion */
int min_bp_val; /* Shortest resolvable distance in the output PDF. */
int precision; /* Number of decimal digits (in fractional part) kept. */
-} dev_unit = {
- 0.0,
- 658,
- 2
};
+#define FORMAT_BUF_SIZE 4096
+struct pdf_dev {
+ int motion_state;
+ struct dev_param param;
+ struct dev_unit unit;
+ struct text_state text_state;
+ struct dev_font *fonts;
+ int num_dev_fonts;
+ int max_dev_fonts;
+ int num_phys_fonts;
+ char format_buffer[FORMAT_BUF_SIZE+1];
+
+ /* Just to support pdf:bcontent special...
+ * Text position adjustment inside the pdf:bcontent and pdf:econtent.
+ */
+ pdf_coord *dev_coords;
+ int num_dev_coords;
+ int max_dev_coords;
+};
-double
-dev_unit_dviunit (void)
+/*
+ * For a moment declare as static variable here
+ * 2020/07/23 Most of the static variables put into single struct pdev
+ */
+static pdf_dev pdev;
+
+static pdf_dev *
+current_device (void)
{
- return (1.0/dev_unit.dvi2pts);
+ return &pdev;
+}
+
+static void
+dev_out (pdf_dev *p, const char *str, size_t len)
+{
+ pdf_doc_add_page_content(str, len);
+}
+
+static double
+pdf_dev_unit_dviunit (pdf_dev *p)
+{
+ ASSERT(p);
+
+ return (1.0 / p->unit.dvi2pts);
}
#define DEV_PRECISION_MAX 8
@@ -91,8 +303,8 @@ static double ten_pow_inv[10] = {
1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, 0.00000001, 0.000000001
};
-#define bpt2spt(b) ( (spt_t) round( (b) / dev_unit.dvi2pts ) )
-#define spt2bpt(s) ( (s) * dev_unit.dvi2pts )
+#define bpt2spt(p, b) ( (spt_t) round( (b) / (p)->unit.dvi2pts ) )
+#define spt2bpt(p, s) ( (s) * (p)->unit.dvi2pts )
#define dround_at(v,p) (ROUND( (v), ten_pow_inv[(p)] ))
static int
@@ -194,28 +406,36 @@ p_dtoa (double value, int prec, char *buf)
}
static int
-dev_sprint_bp (char *buf, spt_t value, spt_t *error)
+dev_sprint_bp (pdf_dev *p, char *buf, spt_t value, spt_t *error)
{
double value_in_bp;
double error_in_bp;
- int prec = dev_unit.precision;
+ int prec;
+
+ ASSERT(p);
+
+ prec = p->unit.precision;
- value_in_bp = spt2bpt(value);
+ value_in_bp = spt2bpt(p, value);
if (error) {
error_in_bp = value_in_bp - dround_at(value_in_bp, prec);
- *error = bpt2spt(error_in_bp);
+ *error = bpt2spt(p, error_in_bp);
}
return p_dtoa(value_in_bp, prec, buf);
}
/* They are affected by precision (set at device initialization). */
-int
-pdf_sprint_matrix (char *buf, const pdf_tmatrix *M)
+static size_t
+pdf_dev_sprint_matrix (pdf_dev *p, char *buf, const pdf_tmatrix *M)
{
- int len;
- int prec2 = MIN(dev_unit.precision + 2, DEV_PRECISION_MAX);
- int prec0 = MAX(dev_unit.precision, 2);
+ size_t len;
+ int prec0, prec2;
+
+ ASSERT(p);
+
+ prec2 = MIN(p->unit.precision + 2, DEV_PRECISION_MAX);
+ prec0 = MAX(p->unit.precision, 2);
len = p_dtoa(M->a, prec2, buf);
buf[len++] = ' ';
@@ -233,52 +453,59 @@ pdf_sprint_matrix (char *buf, const pdf_tmatrix *M)
return len;
}
-int
-pdf_sprint_rect (char *buf, const pdf_rect *rect)
+static size_t
+pdf_dev_sprint_rect (pdf_dev *p, char *buf, const pdf_rect *rect)
{
- int len;
+ size_t len;
+
+ ASSERT(p);
- len = p_dtoa(rect->llx, dev_unit.precision, buf);
+ len = p_dtoa(rect->llx, p->unit.precision, buf);
buf[len++] = ' ';
- len += p_dtoa(rect->lly, dev_unit.precision, buf+len);
+ len += p_dtoa(rect->lly, p->unit.precision, buf+len);
buf[len++] = ' ';
- len += p_dtoa(rect->urx, dev_unit.precision, buf+len);
+ len += p_dtoa(rect->urx, p->unit.precision, buf+len);
buf[len++] = ' ';
- len += p_dtoa(rect->ury, dev_unit.precision, buf+len);
+ len += p_dtoa(rect->ury, p->unit.precision, buf+len);
buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */
return len;
}
-int
-pdf_sprint_coord (char *buf, const pdf_coord *p)
+static size_t
+pdf_dev_sprint_coord (pdf_dev *p, char *buf, const pdf_coord *c)
{
- int len;
+ size_t len;
+
+ ASSERT(p);
- len = p_dtoa(p->x, dev_unit.precision, buf);
+ len = p_dtoa(c->x, p->unit.precision, buf);
buf[len++] = ' ';
- len += p_dtoa(p->y, dev_unit.precision, buf+len);
+ len += p_dtoa(c->y, p->unit.precision, buf+len);
buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */
return len;
}
-int
-pdf_sprint_length (char *buf, double value)
+static size_t
+pdf_dev_sprint_length (pdf_dev *p, char *buf, double value)
{
- int len;
+ size_t len;
+
+ ASSERT(p);
- len = p_dtoa(value, dev_unit.precision, buf);
+ len = p_dtoa(value, p->unit.precision, buf);
buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */
return len;
}
-
-int
-pdf_sprint_number (char *buf, double value)
+static size_t
+pdf_dev_sprint_number (pdf_dev *p, char *buf, double value)
{
- int len;
+ size_t len;
+
+ ASSERT(p);
len = p_dtoa(value, DEV_PRECISION_MAX, buf);
buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */
@@ -286,228 +513,21 @@ pdf_sprint_number (char *buf, double value)
return len;
}
-
-static struct
-{
- /* Text composition (direction) mode is ignored (always same
- * as font's writing mode) if autorotate is unset (value zero).
- */
- int autorotate;
-
- /*
- * Ignore color migrated to here. This is device's capacity.
- * colormode 0 for ignore colors
- */
- int colormode;
-
-} dev_param = {
- 1, /* autorotate */
- 1, /* colormode */
-};
-
-/*
- * Text handling routines.
- */
-
-/* Motion state:
- * GRAPHICS_MODE Initial state (not within BT/ET block nor in string)
- * TEXT_MODE Text section is started via BT operator but not
- * in string.
- * STRING_MODE In string. A string or array of strings are currently
- * in process. May started '[', '<' or '('.
- */
-#define GRAPHICS_MODE 1
-#define TEXT_MODE 2
-#define STRING_MODE 3
-
-static int motion_state = GRAPHICS_MODE;
-
-#define FORMAT_BUF_SIZE 4096
-static char format_buffer[FORMAT_BUF_SIZE];
-
-/*
- * In PDF, vertical text positioning is always applied when current font
- * is vertical font. While ASCII pTeX manages current writing direction
- * and font's WMode separately.
- *
- * 000/101 WMODE_HH/VV h(v) font, h(v) direction.
- * 001 WMODE_HV -90 deg. rotated
- * 100 WMODE_VH +90 deg. rotated
- * 011 WMODE_HD +90 deg. rotated
- * 111 WMODE_VD 180 deg. rotated
-
- * In MetaPost PostScript file processing (mp_mode = 1), only HH/VV mode
- * is applied.
- */
-#define TEXT_WMODE_HH 0
-#define TEXT_WMODE_HV 1
-#define TEXT_WMODE_VH 4
-#define TEXT_WMODE_VV 5
-#define TEXT_WMODE_HD 3
-#define TEXT_WMODE_VD 7
-
-#define ANGLE_CHANGES(m1,m2) ((abs((m1)-(m2)) % 5) == 0 ? 0 : 1)
-#define ROTATE_TEXT(m) ((m) != TEXT_WMODE_HH && (m) != TEXT_WMODE_VV)
-
-static struct {
-
- /* Current font.
- * This is index within dev_fonts.
- */
- int font_id;
-
- /* Dvipdfmx does compression of text by doing text positioning
- * in relative motion and uses string array [(foo) -250 (bar)]
- * with kerning (negative kern is used for white space as suited
- * for TeX). This is offset within current string.
- */
- spt_t offset;
-
- /* This is reference point of strings.
- * It may include error correction induced by rounding.
- */
- spt_t ref_x;
- spt_t ref_y;
-
- /* Using text raise and leading is highly recommended for
- * text extraction to work properly. But not implemented yet.
- * We can't do consice output for \TeX without this.
- */
- spt_t raise; /* unused */
- spt_t leading; /* unused */
-
- /* This is not always text matrix but rather font matrix.
- * We do not use horizontal scaling in PDF text state parameter
- * since they always apply scaling in fixed direction regardless
- * of writing mode.
- */
- struct {
- double slant;
- double extend;
- int rotate; /* TEXT_WMODE_XX */
- } matrix;
-
- /* Fake bold parameter:
- * If bold_param is positive, use text rendering mode
- * fill-then-stroke with stroking line width specified
- * by bold_param.
- */
- double bold_param;
-
- /* Text composition (direction) mode. */
- int dir_mode;
-
- /* internal */
-
- /* Flag indicating text matrix to be forcibly reset.
- * Enabled if synthetic font features (slant, extend, etc)
- * are used for current font or when text rotation mode
- * changes.
- */
- int force_reset;
-
- /* This information is duplicated from dev[font_id].format.
- * Set to 1 if font is composite (Type0) font.
- */
- int is_mb;
-} text_state = {
- -1, /* font */
- 0, /* offset */
- 0, 0, /* ref_x, ref_y */
- 0, 0, /* raise, leading */
- {0.0, 1.0, 0},
-
- 0.0, /* Experimental boldness param */
-
- 0, /* dir_mode */
-
- /* internal */
- 0, /* force_reset */
- 0 /* is_mb */
-};
-
-#define PDF_FONTTYPE_SIMPLE 1
-#define PDF_FONTTYPE_BITMAP 2
-#define PDF_FONTTYPE_COMPOSITE 3
-
-struct dev_font {
- /* Needs to be big enough to hold name "Fxxx"
- * where xxx is number of largest font
- */
- char short_name[7]; /* Resource name */
- int used_on_this_page;
-
- char *tex_name; /* String identifier of this font */
- spt_t sptsize; /* Point size */
-
- /* Returned values from font/encoding layer:
- *
- * The font_id and enc_id is font and encoding (CMap) identifier
- * used in pdf_font or encoding/cmap layer.
- * The PDF object "resource" is an indirect reference object
- * pointing font resource of this font. The used_chars is somewhat
- * misleading, this is actually used_glyphs in CIDFont for Type0
- * and is 65536/8 bytes binary data with each bits representing
- * whether the glyph is in-use or not. It is 256 char array for
- * simple font.
- */
- int font_id;
- int enc_id;
-
- /* if >= 0, index of a dev_font that really has the resource and used_chars */
- int real_font_index;
-
- pdf_obj *resource;
- char *used_chars;
-
- /* Font format:
- * simple, composite or bitmap.
- */
- int format;
-
- /* Writing mode:
- * Non-zero for vertical. Duplicated from CMap.
- */
- int wmode;
-
- /* Syntetic Font:
- *
- * We use text matrix for creating extended or slanted font,
- * but not with font's FontMatrix since TrueType and Type0
- * font don't support them.
- */
- double extend;
- double slant;
- double bold; /* Boldness prameter */
-
- /* Compatibility */
- int mapc; /* Nasty workaround for Omega */
-
- /* There are no font metric format supporting four-bytes
- * charcter code. So we should provide an option to specify
- * UCS group and plane.
- */
- int ucs_group;
- int ucs_plane;
-
- int is_unicode;
-};
-static struct dev_font *dev_fonts = NULL;
-
-static int num_dev_fonts = 0;
-static int max_dev_fonts = 0;
-static int num_phys_fonts = 0;
-
-#define CURRENTFONT() ((text_state.font_id < 0) ? NULL : &(dev_fonts[text_state.font_id]))
-#define GET_FONT(n) (&(dev_fonts[(n)]))
-
+/* Text handling */
+#define CURRENTFONT(p) (((p)->text_state.font_id < 0) ? \
+ NULL : &((p)->fonts[(p)->text_state.font_id]))
+#define GET_FONT(p, n) (&((p)->fonts[(n)]))
static void
-dev_set_text_matrix (spt_t xpos, spt_t ypos, double slant, double extend, int rotate)
+dev_set_text_matrix (pdf_dev *p,
+ spt_t xpos, spt_t ypos,
+ double slant, double extend, int rotate)
{
pdf_tmatrix tm;
int len = 0;
+ ASSERT(p);
+
/* slant is negated for vertical font so that right-side
* is always lower. */
switch (rotate) {
@@ -542,22 +562,22 @@ dev_set_text_matrix (spt_t xpos, spt_t ypos, double slant, double extend, int ro
tm.c = 0.0; tm.d = -extend;
break;
}
- tm.e = xpos * dev_unit.dvi2pts;
- tm.f = ypos * dev_unit.dvi2pts;
-
- format_buffer[len++] = ' ';
- len += pdf_sprint_matrix(format_buffer+len, &tm);
- format_buffer[len++] = ' ';
- format_buffer[len++] = 'T';
- format_buffer[len++] = 'm';
-
- pdf_doc_add_page_content(format_buffer, len); /* op: Tm */
-
- text_state.ref_x = xpos;
- text_state.ref_y = ypos;
- text_state.matrix.slant = slant;
- text_state.matrix.extend = extend;
- text_state.matrix.rotate = rotate;
+ tm.e = xpos * p->unit.dvi2pts;
+ tm.f = ypos * p->unit.dvi2pts;
+
+ p->format_buffer[len++] = ' ';
+ len += pdf_dev_sprint_matrix(p, p->format_buffer+len, &tm);
+ p->format_buffer[len++] = ' ';
+ p->format_buffer[len++] = 'T';
+ p->format_buffer[len++] = 'm';
+
+ dev_out(p, p->format_buffer, len); /* op: Tm */
+
+ p->text_state.ref_x = xpos;
+ p->text_state.ref_y = ypos;
+ p->text_state.matrix.slant = slant;
+ p->text_state.matrix.extend = extend;
+ p->text_state.matrix.rotate = rotate;
}
/*
@@ -566,81 +586,88 @@ dev_set_text_matrix (spt_t xpos, spt_t ypos, double slant, double extend, int ro
*/
static void
-reset_text_state (void)
+reset_text_state (pdf_dev *p)
{
+ ASSERT(p);
+
/*
* We need to reset the line matrix to handle slanted fonts.
*/
- pdf_doc_add_page_content(" BT", 3); /* op: BT */
+ dev_out(p, " BT", 3); /* op: BT */
/*
* text_state.matrix is identity at top of page.
* This sometimes write unnecessary "Tm"s when transition from
* GRAPHICS_MODE to TEXT_MODE occurs.
*/
- if (text_state.force_reset ||
- text_state.matrix.slant != 0.0 ||
- text_state.matrix.extend != 1.0 ||
- ROTATE_TEXT(text_state.matrix.rotate)) {
- dev_set_text_matrix(0, 0,
- text_state.matrix.slant,
- text_state.matrix.extend,
- text_state.matrix.rotate);
+ if (p->text_state.force_reset ||
+ p->text_state.matrix.slant != 0.0 ||
+ p->text_state.matrix.extend != 1.0 ||
+ ROTATE_TEXT(p->text_state.matrix.rotate)) {
+ dev_set_text_matrix(p, 0, 0,
+ p->text_state.matrix.slant,
+ p->text_state.matrix.extend,
+ p->text_state.matrix.rotate);
}
- text_state.ref_x = 0;
- text_state.ref_y = 0;
- text_state.offset = 0;
- text_state.force_reset = 0;
+ p->text_state.ref_x = 0;
+ p->text_state.ref_y = 0;
+ p->text_state.offset = 0;
+ p->text_state.force_reset = 0;
}
static void
-text_mode (void)
+pdf_dev_text_mode (pdf_dev *p)
{
- switch (motion_state) {
+ ASSERT(p);
+
+ switch (p->motion_state) {
case TEXT_MODE:
break;
case STRING_MODE:
- pdf_doc_add_page_content(text_state.is_mb ? ">]TJ" : ")]TJ", 4); /* op: TJ */
+ dev_out(p, p->text_state.is_mb ? ">]TJ" : ")]TJ", 4); /* op: TJ */
break;
case GRAPHICS_MODE:
- reset_text_state();
+ reset_text_state(p);
break;
}
- motion_state = TEXT_MODE;
- text_state.offset = 0;
+ p->motion_state = TEXT_MODE;
+ p->text_state.offset = 0;
}
-void
-graphics_mode (void)
+static void
+pdf_dev_graphics_mode (pdf_dev *p)
{
- switch (motion_state) {
+ switch (p->motion_state) {
case GRAPHICS_MODE:
break;
case STRING_MODE:
- pdf_doc_add_page_content(text_state.is_mb ? ">]TJ" : ")]TJ", 4); /* op: TJ */
+ dev_out(p, p->text_state.is_mb ? ">]TJ" : ")]TJ", 4); /* op: TJ */
/* continue */
case TEXT_MODE:
- if (text_state.bold_param != 0.0) {
+ if (p->text_state.bold_param != 0.0) {
/* fake-bold "2 Tr" is still active */
- pdf_doc_add_page_content(" 0 Tr", 5); /* op: Tr */
- text_state.bold_param = 0.0;
- }
- pdf_doc_add_page_content(" ET", 3); /* op: ET */
- text_state.force_reset = 0;
- text_state.font_id = -1;
+ dev_out(p, " 0 Tr", 5); /* op: Tr */
+ p->text_state.bold_param = 0.0;
+ }
+ dev_out(p, " ET", 3); /* op: ET */
+ p->text_state.force_reset = 0;
+ p->text_state.font_id = -1;
break;
}
- motion_state = GRAPHICS_MODE;
+ p->motion_state = GRAPHICS_MODE;
}
static void
-start_string (spt_t xpos, spt_t ypos, double slant, double extend, int rotate)
+start_string (pdf_dev *p,
+ spt_t xpos, spt_t ypos, double slant, double extend, int rotate)
{
spt_t delx, dely, error_delx, error_dely;
spt_t desired_delx, desired_dely;
int len = 0;
- delx = xpos - text_state.ref_x;
- dely = ypos - text_state.ref_y;
+ ASSERT(p);
+
+ delx = xpos - p->text_state.ref_x;
+ dely = ypos - p->text_state.ref_y;
/*
* Precompensating for line transformation matrix.
*
@@ -697,10 +724,10 @@ start_string (spt_t xpos, spt_t ypos, double slant, double extend, int rotate)
* We must care about rotation here but not extend/slant...
* The extend and slant actually is font matrix.
*/
- format_buffer[len++] = ' ';
- len += dev_sprint_bp(format_buffer+len, desired_delx, &error_dely);
- format_buffer[len++] = ' ';
- len += dev_sprint_bp(format_buffer+len, desired_dely, &error_delx);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_delx, &error_dely);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_dely, &error_delx);
error_delx = -error_delx;
break;
case TEXT_WMODE_HV:
@@ -716,10 +743,10 @@ start_string (spt_t xpos, spt_t ypos, double slant, double extend, int rotate)
/*
* e = (e_user_y, -e_user_x)
*/
- format_buffer[len++] = ' ';
- len += dev_sprint_bp(format_buffer+len, desired_delx, &error_dely);
- format_buffer[len++] = ' ';
- len += dev_sprint_bp(format_buffer+len, desired_dely, &error_delx);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_delx, &error_dely);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_dely, &error_delx);
error_dely = -error_dely;
break;
case TEXT_WMODE_HH:
@@ -731,10 +758,10 @@ start_string (spt_t xpos, spt_t ypos, double slant, double extend, int rotate)
desired_delx = (spt_t)((delx - dely*slant)/extend);
desired_dely = dely;
- format_buffer[len++] = ' ';
- len += dev_sprint_bp(format_buffer+len, desired_delx, &error_delx);
- format_buffer[len++] = ' ';
- len += dev_sprint_bp(format_buffer+len, desired_dely, &error_dely);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_delx, &error_delx);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_dely, &error_dely);
break;
case TEXT_WMODE_VV:
/* Vertical font in vertical mode:
@@ -745,10 +772,10 @@ start_string (spt_t xpos, spt_t ypos, double slant, double extend, int rotate)
desired_delx = delx;
desired_dely = (spt_t)((dely + delx*slant)/extend);
- format_buffer[len++] = ' ';
- len += dev_sprint_bp(format_buffer+len, desired_delx, &error_delx);
- format_buffer[len++] = ' ';
- len += dev_sprint_bp(format_buffer+len, desired_dely, &error_dely);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_delx, &error_delx);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_dely, &error_dely);
break;
case TEXT_WMODE_HD:
/* Horizontal font in down-to-up mode: rot = +90
@@ -760,10 +787,10 @@ start_string (spt_t xpos, spt_t ypos, double slant, double extend, int rotate)
desired_delx = -(spt_t)(-(dely + delx*slant)/extend);
desired_dely = -delx;
- format_buffer[len++] = ' ';
- len += dev_sprint_bp(format_buffer+len, desired_delx, &error_dely);
- format_buffer[len++] = ' ';
- len += dev_sprint_bp(format_buffer+len, desired_dely, &error_delx);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_delx, &error_dely);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_dely, &error_delx);
error_delx = -error_delx;
error_dely = -error_dely;
break;
@@ -776,48 +803,50 @@ start_string (spt_t xpos, spt_t ypos, double slant, double extend, int rotate)
desired_delx = -delx;
desired_dely = -(spt_t)((dely + delx*slant)/extend);
- format_buffer[len++] = ' ';
- len += dev_sprint_bp(format_buffer+len, desired_delx, &error_delx);
- format_buffer[len++] = ' ';
- len += dev_sprint_bp(format_buffer+len, desired_dely, &error_dely);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_delx, &error_delx);
+ p->format_buffer[len++] = ' ';
+ len += dev_sprint_bp(p, p->format_buffer+len, desired_dely, &error_dely);
error_delx = -error_delx;
error_dely = -error_dely;
break;
}
- pdf_doc_add_page_content(format_buffer, len); /* op: */
+ dev_out(p, p->format_buffer, len); /* op: */
/*
* dvipdfm wrongly using "TD" in place of "Td".
* The TD operator set leading, but we are not using T* etc.
*/
- pdf_doc_add_page_content(text_state.is_mb ? " Td[<" : " Td[(", 5); /* op: Td */
+ dev_out(p, p->text_state.is_mb ? " Td[<" : " Td[(", 5); /* op: Td */
/* Error correction */
- text_state.ref_x = xpos - error_delx;
- text_state.ref_y = ypos - error_dely;
+ p->text_state.ref_x = xpos - error_delx;
+ p->text_state.ref_y = ypos - error_dely;
- text_state.offset = 0;
+ p->text_state.offset = 0;
}
static void
-string_mode (spt_t xpos, spt_t ypos, double slant, double extend, int rotate)
+pdf_dev_string_mode (pdf_dev *p, spt_t xpos, spt_t ypos, double slant, double extend, int rotate)
{
- switch (motion_state) {
+ ASSERT(p);
+
+ switch (p->motion_state) {
case STRING_MODE:
break;
case GRAPHICS_MODE:
- reset_text_state();
+ reset_text_state(p);
/* continue */
case TEXT_MODE:
- if (text_state.force_reset) {
- dev_set_text_matrix(xpos, ypos, slant, extend, rotate);
- pdf_doc_add_page_content(text_state.is_mb ? "[<" : "[(", 2); /* op: */
- text_state.force_reset = 0;
+ if (p->text_state.force_reset) {
+ dev_set_text_matrix(p, xpos, ypos, slant, extend, rotate);
+ dev_out(p, p->text_state.is_mb ? "[<" : "[(", 2); /* op: */
+ p->text_state.force_reset = 0;
} else {
- start_string(xpos, ypos, slant, extend, rotate);
+ start_string(p, xpos, ypos, slant, extend, rotate);
}
break;
}
- motion_state = STRING_MODE;
+ p->motion_state = STRING_MODE;
}
/*
@@ -833,7 +862,7 @@ string_mode (spt_t xpos, spt_t ypos, double slant, double extend, int rotate)
*/
static int
-dev_set_font (int font_id)
+pdf_dev_set_font (pdf_dev *p, int font_id)
{
struct dev_font *font;
struct dev_font *real_font;
@@ -842,35 +871,37 @@ dev_set_font (int font_id)
int len;
int vert_dir, vert_font;
+ ASSERT(p);
+
/* text_mode() must come before text_state.is_mb is changed. */
- text_mode();
+ pdf_dev_text_mode(p);
- font = GET_FONT(font_id);
+ font = GET_FONT(p, font_id);
ASSERT(font); /* Caller should check font_id. */
if (font->real_font_index >= 0)
- real_font = GET_FONT(font->real_font_index);
+ real_font = GET_FONT(p, font->real_font_index);
else
real_font = font;
- text_state.is_mb = (font->format == PDF_FONTTYPE_COMPOSITE) ? 1 : 0;
+ p->text_state.is_mb = (font->format == PDF_FONTTYPE_COMPOSITE) ? 1 : 0;
vert_font = font->wmode ? 1 : 0;
- if (dev_param.autorotate) {
- vert_dir = text_state.dir_mode;
+ if (p->param.autorotate) {
+ vert_dir = p->text_state.dir_mode;
} else {
vert_dir = vert_font;
}
text_rotate = (vert_font << 2)|vert_dir;
- if (font->slant != text_state.matrix.slant ||
- font->extend != text_state.matrix.extend ||
- ANGLE_CHANGES(text_rotate, text_state.matrix.rotate)) {
- text_state.force_reset = 1;
+ if (font->slant != p->text_state.matrix.slant ||
+ font->extend != p->text_state.matrix.extend ||
+ ANGLE_CHANGES(text_rotate, p->text_state.matrix.rotate)) {
+ p->text_state.force_reset = 1;
}
- text_state.matrix.slant = font->slant;
- text_state.matrix.extend = font->extend;
- text_state.matrix.rotate = text_rotate;
+ p->text_state.matrix.slant = font->slant;
+ p->text_state.matrix.extend = font->extend;
+ p->text_state.matrix.rotate = text_rotate;
if (!real_font->resource) {
real_font->resource = pdf_get_font_reference(real_font->font_id);
@@ -884,66 +915,33 @@ dev_set_font (int font_id)
real_font->used_on_this_page = 1;
}
- font_scale = (double) font->sptsize * dev_unit.dvi2pts;
- len = sprintf(format_buffer, " /%s", real_font->short_name); /* space not necessary. */
- format_buffer[len++] = ' ';
- len += p_dtoa(font_scale, MIN(dev_unit.precision+1, DEV_PRECISION_MAX), format_buffer+len);
- format_buffer[len++] = ' ';
- format_buffer[len++] = 'T';
- format_buffer[len++] = 'f';
- pdf_doc_add_page_content(format_buffer, len); /* op: Tf */
-
- if (font->bold > 0.0 || font->bold != text_state.bold_param) {
+ font_scale = (double) font->sptsize * p->unit.dvi2pts;
+ len = sprintf(p->format_buffer, " /%s", real_font->short_name); /* space not necessary. */
+ p->format_buffer[len++] = ' ';
+ len += p_dtoa(font_scale, MIN(p->unit.precision+1, DEV_PRECISION_MAX),
+ p->format_buffer+len);
+ p->format_buffer[len++] = ' ';
+ p->format_buffer[len++] = 'T';
+ p->format_buffer[len++] = 'f';
+ dev_out(p, p->format_buffer, len); /* op: Tf */
+
+ if (font->bold > 0.0 || font->bold != p->text_state.bold_param) {
if (font->bold <= 0.0)
- len = sprintf(format_buffer, " 0 Tr");
+ len = sprintf(p->format_buffer, " 0 Tr");
else
- len = sprintf(format_buffer, " 2 Tr %.6f w", font->bold); /* _FIXME_ */
- pdf_doc_add_page_content(format_buffer, len); /* op: Tr w */
+ len = sprintf(p->format_buffer, " 2 Tr %.6f w", font->bold); /* _FIXME_ */
+ dev_out(p, p->format_buffer, len); /* op: Tr w */
}
- text_state.bold_param = font->bold;
+ p->text_state.bold_param = font->bold;
- text_state.font_id = font_id;
+ p->text_state.font_id = font_id;
return 0;
}
-
-/* Access text state parameters.
+/* These tmp buffers can't be removed since the pointer to this can be
+ * used as the return value of handle_multibyte_string(): str_ptr can point these.
*/
-#if 0
-int
-pdf_dev_currentfont (void)
-{
- return text_state.font_id;
-}
-
-double
-pdf_dev_get_font_ptsize (int font_id)
-{
- struct dev_font *font;
-
- font = GET_FONT(font_id);
- if (font) {
- return font->sptsize * dev_unit.dvi2pts;
- }
-
- return 1.0;
-}
-#endif
-
-int
-pdf_dev_get_font_wmode (int font_id)
-{
- struct dev_font *font;
-
- font = GET_FONT(font_id);
- if (font) {
- return font->wmode;
- }
-
- return 0;
-}
-
static unsigned char sbuf0[FORMAT_BUF_SIZE];
static unsigned char sbuf1[FORMAT_BUF_SIZE];
@@ -1048,37 +1046,6 @@ handle_multibyte_string (struct dev_font *font,
return 0;
}
-
-static pdf_coord *dev_coords = NULL;
-static int num_dev_coords = 0;
-static int max_dev_coords = 0;
-
-void pdf_dev_get_coord(double *xpos, double *ypos)
-{
- if (num_dev_coords > 0) {
- *xpos = dev_coords[num_dev_coords-1].x;
- *ypos = dev_coords[num_dev_coords-1].y;
- } else {
- *xpos = *ypos = 0.0;
- }
-}
-
-void pdf_dev_push_coord(double xpos, double ypos)
-{
- if (num_dev_coords >= max_dev_coords) {
- max_dev_coords += 4;
- dev_coords = RENEW(dev_coords, max_dev_coords, pdf_coord);
- }
- dev_coords[num_dev_coords].x = xpos;
- dev_coords[num_dev_coords].y = ypos;
- num_dev_coords++;
-}
-
-void pdf_dev_pop_coord(void)
-{
- if (num_dev_coords > 0) num_dev_coords--;
-}
-
/*
* ctype:
* -1 input string contains 2-byte Freetype glyph index values
@@ -1097,35 +1064,36 @@ pdf_dev_set_string (spt_t xpos, spt_t ypos,
spt_t width,
int font_id, int ctype)
{
- struct dev_font *font;
- struct dev_font *real_font;
+ pdf_dev *p = current_device();
+ struct dev_font *font;
+ struct dev_font *real_font;
const unsigned char *str_ptr; /* Pointer to the reencoded string. */
- int length, i, len = 0;
- spt_t kern, delh, delv;
- spt_t text_xorigin;
- spt_t text_yorigin;
+ int length, i, len = 0;
+ spt_t kern, delh, delv;
+ spt_t text_xorigin;
+ spt_t text_yorigin;
- if (font_id < 0 || font_id >= num_dev_fonts) {
- ERROR("Invalid font: %d (%d)", font_id, num_dev_fonts);
+ if (font_id < 0 || font_id >= p->num_dev_fonts) {
+ ERROR("Invalid font: %d (%d)", font_id, p->num_dev_fonts);
return;
}
- if (font_id != text_state.font_id) {
- dev_set_font(font_id);
+ if (font_id != p->text_state.font_id) {
+ pdf_dev_set_font(p, font_id);
}
- font = CURRENTFONT();
+ font = CURRENTFONT(p);
if (!font) {
ERROR("Currentfont not set.");
return;
}
if (font->real_font_index >= 0)
- real_font = GET_FONT(font->real_font_index);
+ real_font = GET_FONT(p, font->real_font_index);
else
real_font = font;
- text_xorigin = text_state.ref_x;
- text_yorigin = text_state.ref_y;
+ text_xorigin = p->text_state.ref_x;
+ text_yorigin = p->text_state.ref_y;
str_ptr = instr_ptr;
length = instr_len;
@@ -1148,9 +1116,9 @@ pdf_dev_set_string (spt_t xpos, spt_t ypos,
}
}
- if (num_dev_coords > 0) {
- xpos -= bpt2spt(dev_coords[num_dev_coords-1].x);
- ypos -= bpt2spt(dev_coords[num_dev_coords-1].y);
+ if (p->num_dev_coords > 0) {
+ xpos -= bpt2spt(p, p->dev_coords[p->num_dev_coords-1].x);
+ ypos -= bpt2spt(p, p->dev_coords[p->num_dev_coords-1].y);
}
/*
@@ -1168,17 +1136,17 @@ pdf_dev_set_string (spt_t xpos, spt_t ypos,
* (in 1000 units per em) but dvipdfmx does not take into account of this...
*/
- if (text_state.dir_mode==0) {
+ if (p->text_state.dir_mode==0) {
/* Left-to-right */
- delh = text_xorigin + text_state.offset - xpos;
+ delh = text_xorigin + p->text_state.offset - xpos;
delv = ypos - text_yorigin;
- } else if (text_state.dir_mode==1) {
+ } else if (p->text_state.dir_mode==1) {
/* Top-to-bottom */
- delh = ypos - text_yorigin + text_state.offset;
+ delh = ypos - text_yorigin + p->text_state.offset;
delv = xpos - text_xorigin;
} else {
/* Bottom-to-top */
- delh = ypos + text_yorigin + text_state.offset;
+ delh = ypos + text_yorigin + p->text_state.offset;
delv = xpos + text_xorigin;
}
@@ -1192,10 +1160,10 @@ pdf_dev_set_string (spt_t xpos, spt_t ypos,
*/
#define WORD_SPACE_MAX(f) (spt_t) (3.0 * (f)->extend * (f)->sptsize)
- if (text_state.force_reset ||
- labs(delv) > dev_unit.min_bp_val ||
+ if (p->text_state.force_reset ||
+ labs(delv) > p->unit.min_bp_val ||
labs(delh) > WORD_SPACE_MAX(font)) {
- text_mode();
+ pdf_dev_text_mode(p);
kern = 0;
} else {
kern = (spt_t) (1000.0 / font->extend * delh / font->sptsize);
@@ -1205,28 +1173,28 @@ pdf_dev_set_string (spt_t xpos, spt_t ypos,
* single text block. There are point_size/1000 rounding error per character.
* If you really care about accuracy, you should compensate this here too.
*/
- if (motion_state != STRING_MODE)
- string_mode(xpos, ypos,
- font->slant, font->extend, text_state.matrix.rotate);
+ if (p->motion_state != STRING_MODE)
+ pdf_dev_string_mode(p, xpos, ypos,
+ font->slant, font->extend, p->text_state.matrix.rotate);
else if (kern != 0) {
/*
* Same issues as earlier. Use floating point for simplicity.
* This routine needs to be fast, so we don't call sprintf() or strcpy().
*/
- text_state.offset -=
+ p->text_state.offset -=
(spt_t) (kern * font->extend * (font->sptsize / 1000.0));
- format_buffer[len++] = text_state.is_mb ? '>' : ')';
+ p->format_buffer[len++] = p->text_state.is_mb ? '>' : ')';
if (font->wmode)
- len += p_itoa(-kern, format_buffer + len);
+ len += p_itoa(-kern, p->format_buffer + len);
else {
- len += p_itoa( kern, format_buffer + len);
+ len += p_itoa( kern, p->format_buffer + len);
}
- format_buffer[len++] = text_state.is_mb ? '<' : '(';
- pdf_doc_add_page_content(format_buffer, len); /* op: */
+ p->format_buffer[len++] = p->text_state.is_mb ? '<' : '(';
+ dev_out(p, p->format_buffer, len); /* op: */
len = 0;
}
- if (text_state.is_mb) {
+ if (p->text_state.is_mb) {
if (FORMAT_BUF_SIZE - len < 2 * length)
ERROR("Buffer overflow...");
for (i = 0; i < length; i++) {
@@ -1234,68 +1202,94 @@ pdf_dev_set_string (spt_t xpos, spt_t ypos,
first = (str_ptr[i] >> 4) & 0x0f;
second = str_ptr[i] & 0x0f;
- format_buffer[len++] = ((first >= 10) ? first + 'W' : first + '0');
- format_buffer[len++] = ((second >= 10) ? second + 'W' : second + '0');
+ p->format_buffer[len++] = ((first >= 10) ? first + 'W' : first + '0');
+ p->format_buffer[len++] = ((second >= 10) ? second + 'W' : second + '0');
}
} else {
- len += pdfobj_escape_str(format_buffer + len,
+ len += pdfobj_escape_str(p->format_buffer + len,
FORMAT_BUF_SIZE - len, str_ptr, length);
}
/* I think if you really care about speed, you should avoid memcopy here. */
- pdf_doc_add_page_content(format_buffer, len); /* op: */
+ dev_out(p, p->format_buffer, len); /* op: */
- text_state.offset += width;
+ p->text_state.offset += width;
}
void
pdf_init_device (double dvi2pts, int precision, int black_and_white)
{
+ pdf_dev *p = current_device();
+
+ p->motion_state = GRAPHICS_MODE;
+ p->unit.dvi2pts = 0.0;
+ p->unit.min_bp_val = 658;
+ p->unit.precision = 2;
+ p->param.autorotate = 1;
+ p->param.colormode = 1;
+ p->text_state.font_id = -1;
+ p->text_state.offset = 0;
+ p->text_state.matrix.slant = 0;
+ p->text_state.matrix.extend = 0;
+ p->text_state.matrix.rotate = 0;
+ p->text_state.bold_param = 0;
+ p->text_state.dir_mode = 0;
+ p->text_state.force_reset = 0;
+ p->text_state.is_mb = 0;
+
if (precision < 0 ||
precision > DEV_PRECISION_MAX)
WARN("Number of decimal digits out of range [0-%d].",
DEV_PRECISION_MAX);
if (precision < 0) {
- dev_unit.precision = 0;
+ p->unit.precision = 0;
} else if (precision > DEV_PRECISION_MAX) {
- dev_unit.precision = DEV_PRECISION_MAX;
+ p->unit.precision = DEV_PRECISION_MAX;
} else {
- dev_unit.precision = precision;
+ p->unit.precision = precision;
}
- dev_unit.dvi2pts = dvi2pts;
- dev_unit.min_bp_val = (int) ROUND(1.0/(ten_pow[dev_unit.precision]*dvi2pts), 1);
- if (dev_unit.min_bp_val < 0)
- dev_unit.min_bp_val = -dev_unit.min_bp_val;
+ p->unit.dvi2pts = dvi2pts;
+ p->unit.min_bp_val = (int) ROUND(1.0/(ten_pow[p->unit.precision]*dvi2pts), 1);
+ if (p->unit.min_bp_val < 0)
+ p->unit.min_bp_val = -p->unit.min_bp_val;
- dev_param.colormode = (black_and_white ? 0 : 1);
+ p->param.colormode = (black_and_white ? 0 : 1);
- graphics_mode();
+ pdf_dev_graphics_mode(p);
pdf_color_clear_stack();
pdf_dev_init_gstates();
- num_dev_fonts = max_dev_fonts = 0;
- dev_fonts = NULL;
- num_dev_coords = max_dev_coords = 0;
- dev_coords = NULL;
+ p->num_dev_fonts = p->max_dev_fonts = 0;
+ p->fonts = NULL;
+ p->num_dev_coords = 0;
+ p->max_dev_coords = 0;
+ p->dev_coords = NULL;
+
+ return;
}
void
pdf_close_device (void)
{
- if (dev_fonts) {
+ pdf_dev *p = current_device();
+
+ if (p->fonts) {
int i;
- for (i = 0; i < num_dev_fonts; i++) {
- if (dev_fonts[i].tex_name)
- RELEASE(dev_fonts[i].tex_name);
- if (dev_fonts[i].resource)
- pdf_release_obj(dev_fonts[i].resource);
- dev_fonts[i].tex_name = NULL;
- dev_fonts[i].resource = NULL;
+ for (i = 0; i < p->num_dev_fonts; i++) {
+ if (p->fonts[i].tex_name)
+ RELEASE(p->fonts[i].tex_name);
+ if (p->fonts[i].resource)
+ pdf_release_obj(p->fonts[i].resource);
+ p->fonts[i].tex_name = NULL;
+ p->fonts[i].resource = NULL;
}
- RELEASE(dev_fonts);
+ RELEASE(p->fonts);
+ p->fonts = NULL;
}
- if (dev_coords) RELEASE(dev_coords);
+ if (p->dev_coords)
+ RELEASE(p->dev_coords);
+ p->dev_coords = NULL;
pdf_dev_clear_gstates();
}
@@ -1307,22 +1301,23 @@ pdf_close_device (void)
void
pdf_dev_reset_fonts (int newpage)
{
- int i;
+ pdf_dev *p = current_device();
+ int i;
- for (i = 0; i < num_dev_fonts; i++) {
- dev_fonts[i].used_on_this_page = 0;
+ for (i = 0; i < p->num_dev_fonts; i++) {
+ p->fonts[i].used_on_this_page = 0;
}
- text_state.font_id = -1;
+ p->text_state.font_id = -1;
- text_state.matrix.slant = 0.0;
- text_state.matrix.extend = 1.0;
- text_state.matrix.rotate = TEXT_WMODE_HH;
+ p->text_state.matrix.slant = 0.0;
+ p->text_state.matrix.extend = 1.0;
+ p->text_state.matrix.rotate = TEXT_WMODE_HH;
if (newpage)
- text_state.bold_param = 0.0;
+ p->text_state.bold_param = 0.0;
- text_state.is_mb = 0;
+ p->text_state.is_mb = 0;
}
void
@@ -1335,29 +1330,14 @@ pdf_dev_reset_color (int force)
pdf_dev_set_color(fc, 0x20, force);
}
-#if 0
-/* Not working */
-void
-pdf_dev_set_origin (double phys_x, double phys_y)
-{
- pdf_tmatrix M0, M1;
-
- pdf_dev_currentmatrix(&M0);
- pdf_dev_currentmatrix(&M1);
- pdf_invertmatrix(&M1);
- M0.e = phys_x; M0.f = phys_y;
- pdf_concatmatrix(&M1, &M0);
-
- pdf_dev_concat(&M1);
-}
-#endif
-
void
pdf_dev_bop (const pdf_tmatrix *M)
{
- graphics_mode();
+ pdf_dev *p = current_device();
+
+ pdf_dev_graphics_mode(p);
- text_state.force_reset = 0;
+ p->text_state.force_reset = 0;
pdf_dev_gsave();
pdf_dev_concat(M);
@@ -1370,9 +1350,10 @@ pdf_dev_bop (const pdf_tmatrix *M)
void
pdf_dev_eop (void)
{
- int depth;
+ pdf_dev *p = current_device();
+ int depth;
- graphics_mode();
+ pdf_dev_graphics_mode(p);
depth = pdf_dev_current_depth();
if (depth != 1) {
@@ -1433,6 +1414,7 @@ print_fontmap (const char *font_name, fontmap_rec *mrec)
int
pdf_dev_locate_font (const char *font_name, spt_t ptsize)
{
+ pdf_dev *p = current_device();
int i;
fontmap_rec *mrec;
struct dev_font *font;
@@ -1445,11 +1427,11 @@ pdf_dev_locate_font (const char *font_name, spt_t ptsize)
return -1;
}
- for (i = 0; i < num_dev_fonts; i++) {
- if (strcmp(font_name, dev_fonts[i].tex_name) == 0) {
- if (ptsize == dev_fonts[i].sptsize)
+ for (i = 0; i < p->num_dev_fonts; i++) {
+ if (strcmp(font_name, p->fonts[i].tex_name) == 0) {
+ if (ptsize == p->fonts[i].sptsize)
return i; /* found a dev_font that matches the request */
- if (dev_fonts[i].format != PDF_FONTTYPE_BITMAP)
+ if (p->fonts[i].format != PDF_FONTTYPE_BITMAP)
break; /* new dev_font will share pdf resource with /i/ */
}
}
@@ -1458,12 +1440,12 @@ pdf_dev_locate_font (const char *font_name, spt_t ptsize)
* Make sure we have room for a new one, even though we may not
* actually create one.
*/
- if (num_dev_fonts >= max_dev_fonts) {
- max_dev_fonts += 16;
- dev_fonts = RENEW(dev_fonts, max_dev_fonts, struct dev_font);
+ if (p->num_dev_fonts >= p->max_dev_fonts) {
+ p->max_dev_fonts += 16;
+ p->fonts = RENEW(p->fonts, p->max_dev_fonts, struct dev_font);
}
- font = &dev_fonts[num_dev_fonts];
+ font = &p->fonts[p->num_dev_fonts];
/* New font */
mrec = pdf_lookup_fontmap_record(font_name);
@@ -1471,20 +1453,20 @@ pdf_dev_locate_font (const char *font_name, spt_t ptsize)
if (dpx_conf.verbose_level > 1)
print_fontmap(font_name, mrec);
- font->font_id = pdf_font_findresource(font_name, ptsize * dev_unit.dvi2pts, mrec);
+ font->font_id = pdf_font_findresource(font_name, ptsize * p->unit.dvi2pts, mrec);
if (font->font_id < 0)
return -1;
/* We found device font here. */
- if (i < num_dev_fonts) {
+ if (i < p->num_dev_fonts) {
font->real_font_index = i;
- strcpy(font->short_name, dev_fonts[i].short_name);
+ strcpy(font->short_name, p->fonts[i].short_name);
}
else {
font->real_font_index = -1;
font->short_name[0] = 'F';
- p_itoa(num_phys_fonts + 1, &font->short_name[1]); /* NULL terminated here */
- num_phys_fonts++;
+ p_itoa(p->num_phys_fonts + 1, &font->short_name[1]); /* NULL terminated here */
+ p->num_phys_fonts++;
}
font->used_on_this_page = 0;
@@ -1543,33 +1525,33 @@ pdf_dev_locate_font (const char *font_name, spt_t ptsize)
}
}
- return num_dev_fonts++;
+ return p->num_dev_fonts++;
}
/* This does not remember current stroking width. */
static int
-dev_sprint_line (char *buf, spt_t width,
+dev_sprint_line (pdf_dev *p, char *buf, spt_t width,
spt_t p0_x, spt_t p0_y, spt_t p1_x, spt_t p1_y)
{
int len = 0;
double w;
- w = width * dev_unit.dvi2pts;
+ w = width * p->unit.dvi2pts;
- len += p_dtoa(w, MIN(dev_unit.precision+1, DEV_PRECISION_MAX), buf+len);
+ len += p_dtoa(w, MIN(p->unit.precision+1, DEV_PRECISION_MAX), buf+len);
buf[len++] = ' ';
buf[len++] = 'w';
buf[len++] = ' ';
- len += dev_sprint_bp(buf+len, p0_x, NULL);
+ len += dev_sprint_bp(p, buf+len, p0_x, NULL);
buf[len++] = ' ';
- len += dev_sprint_bp(buf+len, p0_y, NULL);
+ len += dev_sprint_bp(p, buf+len, p0_y, NULL);
buf[len++] = ' ';
buf[len++] = 'm';
buf[len++] = ' ';
- len += dev_sprint_bp(buf+len, p1_x, NULL);
+ len += dev_sprint_bp(p, buf+len, p1_x, NULL);
buf[len++] = ' ';
- len += dev_sprint_bp(buf+len, p1_y, NULL);
+ len += dev_sprint_bp(p, buf+len, p1_y, NULL);
buf[len++] = ' ';
buf[len++] = 'l';
buf[len++] = ' ';
@@ -1583,35 +1565,36 @@ dev_sprint_line (char *buf, spt_t width,
void
pdf_dev_set_rule (spt_t xpos, spt_t ypos, spt_t width, spt_t height)
{
- int len = 0;
- double width_in_bp;
+ pdf_dev *p = current_device();
+ int len = 0;
+ double width_in_bp;
- if (num_dev_coords > 0) {
- xpos -= bpt2spt(dev_coords[num_dev_coords-1].x);
- ypos -= bpt2spt(dev_coords[num_dev_coords-1].y);
+ if (p->num_dev_coords > 0) {
+ xpos -= bpt2spt(p, p->dev_coords[p->num_dev_coords-1].x);
+ ypos -= bpt2spt(p, p->dev_coords[p->num_dev_coords-1].y);
}
- graphics_mode();
+ pdf_dev_graphics_mode(p);
- format_buffer[len++] = ' ';
- format_buffer[len++] = 'q';
- format_buffer[len++] = ' ';
+ p->format_buffer[len++] = ' ';
+ p->format_buffer[len++] = 'q';
+ p->format_buffer[len++] = ' ';
/* Don't use too thick line. */
- width_in_bp = ((width < height) ? width : height) * dev_unit.dvi2pts;
+ width_in_bp = ((width < height) ? width : height) * p->unit.dvi2pts;
if (width_in_bp < 0.0 || /* Shouldn't happen */
width_in_bp > PDF_LINE_THICKNESS_MAX) {
pdf_rect rect;
- rect.llx = dev_unit.dvi2pts * xpos;
- rect.lly = dev_unit.dvi2pts * ypos;
- rect.urx = dev_unit.dvi2pts * width;
- rect.ury = dev_unit.dvi2pts * height;
- len += pdf_sprint_rect(format_buffer+len, &rect);
- format_buffer[len++] = ' ';
- format_buffer[len++] = 'r';
- format_buffer[len++] = 'e';
- format_buffer[len++] = ' ';
- format_buffer[len++] = 'f';
+ rect.llx = p->unit.dvi2pts * xpos;
+ rect.lly = p->unit.dvi2pts * ypos;
+ rect.urx = p->unit.dvi2pts * width;
+ rect.ury = p->unit.dvi2pts * height;
+ len += pdf_dev_sprint_rect(p, p->format_buffer+len, &rect);
+ p->format_buffer[len++] = ' ';
+ p->format_buffer[len++] = 'r';
+ p->format_buffer[len++] = 'e';
+ p->format_buffer[len++] = ' ';
+ p->format_buffer[len++] = 'f';
} else {
if (width > height) {
/* NOTE:
@@ -1619,22 +1602,22 @@ pdf_dev_set_rule (spt_t xpos, spt_t ypos, spt_t width, spt_t height)
* device resolution. See, PDF Reference Manual 4th ed., sec. 4.3.2,
* "Details of Graphics State Parameters", p. 185.
*/
- if (height < dev_unit.min_bp_val) {
+ if (height < p->unit.min_bp_val) {
WARN("Too thin line: height=%ld (%g bp)", height, width_in_bp);
WARN("Please consider using \"-d\" option.");
}
- len += dev_sprint_line(format_buffer+len,
+ len += dev_sprint_line(p, p->format_buffer+len,
height,
xpos,
ypos + height/2,
xpos + width,
ypos + height/2);
} else {
- if (width < dev_unit.min_bp_val) {
+ if (width < p->unit.min_bp_val) {
WARN("Too thin line: width=%ld (%g bp)", width, width_in_bp);
WARN("Please consider using \"-d\" option.");
}
- len += dev_sprint_line(format_buffer+len,
+ len += dev_sprint_line(p, p->format_buffer+len,
width,
xpos + width/2,
ypos,
@@ -1642,9 +1625,9 @@ pdf_dev_set_rule (spt_t xpos, spt_t ypos, spt_t width, spt_t height)
ypos + height);
}
}
- format_buffer[len++] = ' ';
- format_buffer[len++] = 'Q';
- pdf_doc_add_page_content(format_buffer, len); /* op: q re f Q */
+ p->format_buffer[len++] = ' ';
+ p->format_buffer[len++] = 'Q';
+ dev_out(p, p->format_buffer, len); /* op: q re f Q */
}
/* Rectangle in device space coordinate. */
@@ -1653,16 +1636,17 @@ pdf_dev_set_rect (pdf_rect *rect,
spt_t x_user, spt_t y_user,
spt_t width, spt_t height, spt_t depth)
{
+ pdf_dev *p = current_device();
double dev_x, dev_y;
pdf_coord p0, p1, p2, p3;
double min_x, min_y, max_x, max_y;
- dev_x = x_user * dev_unit.dvi2pts;
- dev_y = y_user * dev_unit.dvi2pts;
- if (text_state.dir_mode) {
- p0.x = dev_x - dev_unit.dvi2pts * depth;
- p0.y = dev_y - dev_unit.dvi2pts * width;
- p1.x = dev_x + dev_unit.dvi2pts * height;
+ dev_x = x_user * p->unit.dvi2pts;
+ dev_y = y_user * p->unit.dvi2pts;
+ if (p->text_state.dir_mode) {
+ p0.x = dev_x - p->unit.dvi2pts * depth;
+ p0.y = dev_y - p->unit.dvi2pts * width;
+ p1.x = dev_x + p->unit.dvi2pts * height;
p1.y = p0.y;
p2.x = p1.x;
p2.y = dev_y;
@@ -1670,11 +1654,11 @@ pdf_dev_set_rect (pdf_rect *rect,
p3.y = p2.y;
} else {
p0.x = dev_x;
- p0.y = dev_y - dev_unit.dvi2pts * depth;
- p1.x = dev_x + dev_unit.dvi2pts * width;
+ p0.y = dev_y - p->unit.dvi2pts * depth;
+ p1.x = dev_x + p->unit.dvi2pts * width;
p1.y = p0.y;
p2.x = p1.x;
- p2.y = dev_y + dev_unit.dvi2pts * height;
+ p2.y = dev_y + p->unit.dvi2pts * height;
p3.x = p0.x;
p3.y = p2.y;
}
@@ -1711,20 +1695,22 @@ pdf_dev_set_rect (pdf_rect *rect,
int
pdf_dev_get_dirmode (void)
{
- return text_state.dir_mode;
+ pdf_dev *p = current_device();
+ return p->text_state.dir_mode;
}
void
pdf_dev_set_dirmode (int text_dir)
{
+ pdf_dev *p = current_device();
struct dev_font *font;
int text_rotate;
int vert_dir, vert_font;
- font = CURRENTFONT();
+ font = CURRENTFONT(p);
vert_font = (font && font->wmode) ? 1 : 0;
- if (dev_param.autorotate) {
+ if (p->param.autorotate) {
vert_dir = text_dir;
} else {
vert_dir = vert_font;
@@ -1732,48 +1718,51 @@ pdf_dev_set_dirmode (int text_dir)
text_rotate = (vert_font << 2)|vert_dir;
if (font &&
- ANGLE_CHANGES(text_rotate, text_state.matrix.rotate)) {
- text_state.force_reset = 1;
+ ANGLE_CHANGES(text_rotate, p->text_state.matrix.rotate)) {
+ p->text_state.force_reset = 1;
}
- text_state.matrix.rotate = text_rotate;
- text_state.dir_mode = text_dir;
+ p->text_state.matrix.rotate = text_rotate;
+ p->text_state.dir_mode = text_dir;
}
static void
-dev_set_param_autorotate (int auto_rotate)
+dev_set_param_autorotate (pdf_dev *p, int auto_rotate)
{
struct dev_font *font;
int text_rotate, vert_font, vert_dir;
- font = CURRENTFONT();
+ ASSERT(p);
+
+ font = CURRENTFONT(p);
vert_font = (font && font->wmode) ? 1 : 0;
if (auto_rotate) {
- vert_dir = text_state.dir_mode;
+ vert_dir = p->text_state.dir_mode;
} else {
vert_dir = vert_font;
}
text_rotate = (vert_font << 2)|vert_dir;
- if (ANGLE_CHANGES(text_rotate, text_state.matrix.rotate)) {
- text_state.force_reset = 1;
+ if (ANGLE_CHANGES(text_rotate, p->text_state.matrix.rotate)) {
+ p->text_state.force_reset = 1;
}
- text_state.matrix.rotate = text_rotate;
- dev_param.autorotate = auto_rotate;
+ p->text_state.matrix.rotate = text_rotate;
+ p->param.autorotate = auto_rotate;
}
int
pdf_dev_get_param (int param_type)
{
+ pdf_dev *p = current_device();
int value = 0;
switch (param_type) {
case PDF_DEV_PARAM_AUTOROTATE:
- value = dev_param.autorotate;
+ value = p->param.autorotate;
break;
case PDF_DEV_PARAM_COLORMODE:
- value = dev_param.colormode;
+ value = p->param.colormode;
break;
default:
ERROR("Unknown device parameter: %d", param_type);
@@ -1785,12 +1774,14 @@ pdf_dev_get_param (int param_type)
void
pdf_dev_set_param (int param_type, int value)
{
+ pdf_dev *p = current_device();
+
switch (param_type) {
case PDF_DEV_PARAM_AUTOROTATE:
- dev_set_param_autorotate(value);
+ dev_set_param_autorotate(p, value);
break;
case PDF_DEV_PARAM_COLORMODE:
- dev_param.colormode = value; /* 0 for B&W */
+ p->param.colormode = value; /* 0 for B&W */
break;
default:
ERROR("Unknown device parameter: %d", param_type);
@@ -1802,56 +1793,52 @@ pdf_dev_set_param (int param_type, int value)
int
pdf_dev_put_image (int id,
- transform_info *p,
+ transform_info *ti,
double ref_x,
double ref_y)
{
+ pdf_dev *p = current_device();
char *res_name;
pdf_tmatrix M, M1;
pdf_rect r;
int len = 0;
- if (num_dev_coords > 0) {
- ref_x -= dev_coords[num_dev_coords-1].x;
- ref_y -= dev_coords[num_dev_coords-1].y;
+ if (p->num_dev_coords > 0) {
+ ref_x -= p->dev_coords[p->num_dev_coords-1].x;
+ ref_y -= p->dev_coords[p->num_dev_coords-1].y;
}
- pdf_copymatrix(&M, &(p->matrix));
+ pdf_copymatrix(&M, &(ti->matrix));
M.e += ref_x; M.f += ref_y;
/* Just rotate by -90, but not tested yet. Any problem if M has scaling? */
- if (dev_param.autorotate &&
- text_state.dir_mode) {
+ if (p->param.autorotate &&
+ p->text_state.dir_mode) {
double tmp;
tmp = -M.a; M.a = M.b; M.b = tmp;
tmp = -M.c; M.c = M.d; M.d = tmp;
}
- graphics_mode();
+ pdf_dev_graphics_mode(p);
pdf_dev_gsave();
- pdf_ximage_scale_image(id, &M1, &r, p);
+ pdf_ximage_scale_image(id, &M1, &r, ti);
pdf_concatmatrix(&M, &M1);
pdf_dev_concat(&M);
/* Clip */
- if (p->flags & INFO_DO_CLIP) {
-#if 0
- pdf_dev_newpath();
- pdf_dev_moveto(r.llx, r.lly);
- pdf_dev_lineto(r.urx, r.lly);
- pdf_dev_lineto(r.urx, r.ury);
- pdf_dev_lineto(r.llx, r.ury);
- pdf_dev_closepath();
- pdf_dev_clip();
- pdf_dev_newpath();
-#else
+ if (ti->flags & INFO_DO_CLIP) {
pdf_dev_rectclip(r.llx, r.lly, r.urx - r.llx, r.ury - r.lly);
-#endif
}
res_name = pdf_ximage_get_resname(id);
- len = sprintf(work_buffer, " /%s Do", res_name);
- pdf_doc_add_page_content(work_buffer, len); /* op: Do */
+ {
+ char *buf;
+
+ buf = NEW(strlen(res_name)+6, char);
+ len = sprintf(buf, " /%s Do", res_name);
+ dev_out(p, buf, len); /* op: Do */
+ RELEASE(buf);
+ }
pdf_dev_grestore();
@@ -1861,19 +1848,19 @@ pdf_dev_put_image (int id,
if (dvi_is_tracking_boxes()) {
pdf_tmatrix P;
- int i;
- pdf_rect rect;
- pdf_coord corner[4];
+ int i;
+ pdf_rect rect;
+ pdf_coord corner[4];
pdf_dev_set_rect(&rect, 65536 * ref_x, 65536 * ref_y,
- 65536 * (r.urx - r.llx), 65536 * (r.ury - r.lly), 0);
+ 65536 * (r.urx - r.llx), 65536 * (r.ury - r.lly), 0);
corner[0].x = rect.llx; corner[0].y = rect.lly;
corner[1].x = rect.llx; corner[1].y = rect.ury;
corner[2].x = rect.urx; corner[2].y = rect.ury;
corner[3].x = rect.urx; corner[3].y = rect.lly;
- pdf_copymatrix(&P, &(p->matrix));
+ pdf_copymatrix(&P, &(ti->matrix));
for (i = 0; i < 4; ++i) {
corner[i].x -= rect.llx;
corner[i].y -= rect.lly;
@@ -1888,13 +1875,13 @@ pdf_dev_put_image (int id,
rect.ury = corner[0].y;
for (i = 0; i < 4; ++i) {
if (corner[i].x < rect.llx)
- rect.llx = corner[i].x;
+ rect.llx = corner[i].x;
if (corner[i].x > rect.urx)
- rect.urx = corner[i].x;
+ rect.urx = corner[i].x;
if (corner[i].y < rect.lly)
- rect.lly = corner[i].y;
+ rect.lly = corner[i].y;
if (corner[i].y > rect.ury)
- rect.ury = corner[i].y;
+ rect.ury = corner[i].y;
}
pdf_doc_expand_box(&rect);
@@ -1903,7 +1890,6 @@ pdf_dev_put_image (int id,
return 0;
}
-
void
transform_info_clear (transform_info *info)
{
@@ -1926,7 +1912,8 @@ transform_info_clear (transform_info *info)
void
pdf_dev_begin_actualtext (uint16_t *unicodes, int count)
{
- int len, i, pdf_doc_enc = 1;
+ pdf_dev *p = current_device();
+ int len, i, pdf_doc_enc = 1;
/* check whether we can use PDFDocEncoding for this string
(we punt on the 0x80..0xA0 range that does not directly correspond to unicode) */
@@ -1937,41 +1924,144 @@ pdf_dev_begin_actualtext (uint16_t *unicodes, int count)
}
}
- graphics_mode();
+ pdf_dev_graphics_mode(p);
- len = sprintf(work_buffer, "\n/Span<</ActualText(");
- if (!pdf_doc_enc) {
- len += sprintf(work_buffer + len, "\xFE\xFF");
- }
- pdf_doc_add_page_content(work_buffer, len);
+ dev_out(p, "\n/Span << /ActualText (", 23);
+ if (!pdf_doc_enc)
+ dev_out(p, "\xFE\xFF", 2);
while (count-- > 0) {
unsigned char s[2] = { *unicodes >> 8, *unicodes & 0xff };
+ char buf[32];
i = pdf_doc_enc; /* if using PDFDocEncoding, we only care about the low 8 bits,
so start with the second byte of our pair */
len = 0;
for (; i < 2; i++) {
unsigned char c = s[i];
if (c == '(' || c == ')' || c == '\\') {
- len += sprintf(work_buffer + len, "\\%c", c);
+ len += sprintf(buf + len, "\\%c", c);
} else if (c < ' ') {
- len += sprintf(work_buffer + len, "\\%03o", c);
+ len += sprintf(buf + len, "\\%03o", c);
} else {
- len += sprintf(work_buffer + len, "%c", c);
+ len += sprintf(buf + len, "%c", c);
}
}
- pdf_doc_add_page_content(work_buffer, len);
+ dev_out(p, buf, len);
++unicodes;
}
- len = sprintf(work_buffer, ")>>BDC");
- pdf_doc_add_page_content(work_buffer, len);
+ dev_out(p, ") >> BDC", 8);
}
void
pdf_dev_end_actualtext (void)
{
- graphics_mode();
+ pdf_dev *p = current_device();
+
+ pdf_dev_graphics_mode(p);
+
+ dev_out(p, " EMC", 4);
+}
+
+/* Compatibility functions.... For other files still using old interface */
+void
+graphics_mode (void)
+{
+ pdf_dev *p = current_device();
+
+ pdf_dev_graphics_mode(p);
+}
+
+double
+dev_unit_dviunit (void)
+{
+ pdf_dev *p = current_device();
+ return pdf_dev_unit_dviunit(p);
+}
+
+int
+pdf_sprint_matrix (char *buf, const pdf_tmatrix *M)
+{
+ pdf_dev *p = current_device();
+ return (int) pdf_dev_sprint_matrix(p, buf, M);
+}
+
+int
+pdf_sprint_rect (char *buf, const pdf_rect *rect)
+{
+ pdf_dev *p = current_device();
+ return (int) pdf_dev_sprint_rect(p, buf, rect);
+}
+
+int
+pdf_sprint_coord (char *buf, const pdf_coord *c)
+{
+ pdf_dev *p = current_device();
+ return (int) pdf_dev_sprint_coord(p, buf, c);
+}
+
+int
+pdf_sprint_length (char *buf, double value)
+{
+ pdf_dev *p = current_device();
+ return (int) pdf_dev_sprint_length(p, buf, value);
+}
+
+int
+pdf_sprint_number (char *buf, double value)
+{
+ pdf_dev *p = current_device();
+ return (int) pdf_dev_sprint_number(p, buf, value);
+}
+
+/* Access text state parameters. */
+int
+pdf_dev_get_font_wmode (int font_id)
+{
+ pdf_dev *p = current_device();
+ struct dev_font *font;
+
+ font = GET_FONT(p, font_id);
+ if (font) {
+ return font->wmode;
+ }
+
+ return 0;
+}
+
+/* Saved text position compensation */
+void
+pdf_dev_get_coord (double *xpos, double *ypos)
+{
+ pdf_dev *p = current_device();
+
+ if (p->num_dev_coords > 0) {
+ *xpos = p->dev_coords[p->num_dev_coords-1].x;
+ *ypos = p->dev_coords[p->num_dev_coords-1].y;
+ } else {
+ *xpos = *ypos = 0.0;
+ }
+}
+
+void
+pdf_dev_push_coord (double xpos, double ypos)
+{
+ pdf_dev *p = current_device();
+
+ if (p->num_dev_coords >= p->max_dev_coords) {
+ p->max_dev_coords += 4;
+ p->dev_coords = RENEW(p->dev_coords, p->max_dev_coords, pdf_coord);
+ }
+ p->dev_coords[p->num_dev_coords].x = xpos;
+ p->dev_coords[p->num_dev_coords].y = ypos;
+ p->num_dev_coords++;
+}
+
+void
+pdf_dev_pop_coord (void)
+{
+ pdf_dev *p = current_device();
- pdf_doc_add_page_content(" EMC", 4);
+ if (p->num_dev_coords > 0)
+ p->num_dev_coords--;
}
diff --git a/Build/source/texk/dvipdfm-x/pdfdev.h b/Build/source/texk/dvipdfm-x/pdfdev.h
index 09124e2785f..f896be7850b 100644
--- a/Build/source/texk/dvipdfm-x/pdfdev.h
+++ b/Build/source/texk/dvipdfm-x/pdfdev.h
@@ -1,6 +1,6 @@
/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
- Copyright (C) 2002-2019 by Jin-Hwan Cho and Shunsaku Hirata,
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
the dvipdfmx project team.
Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
@@ -27,6 +27,8 @@
#include "pdfobj.h"
#include "pdfcolor.h"
+typedef struct pdf_dev pdf_dev;
+
typedef int spt_t;
typedef struct pdf_tmatrix
@@ -89,39 +91,6 @@ extern void pdf_close_device (void);
/* returns 1.0/unit_conv */
extern double dev_unit_dviunit (void);
-#if 0
-/* DVI interpreter knows text positioning in relative motion.
- * However, pdf_dev_set_string() recieves text string with placement
- * in absolute position in user space, and it convert absolute
- * positioning back to relative positioning. It is quite wasteful.
- *
- * TeX using DVI register stack operation to do CR and then use down
- * command for LF. DVI interpreter knows hint for current leading
- * and others (raised or lowered), but they are mostly lost in
- * pdf_dev_set_string().
- */
-
-typedef struct
-{
- int argc;
-
- struct {
- int is_kern; /* kern or string */
-
- spt_t kern; /* negative kern means space */
-
- int offset; /* offset to sbuf */
- int length; /* length of string */
- } args[];
-
- unsigned char sbuf[PDF_STRING_LEN_MAX];
-
-} pdf_text_string;
-
-/* Something for handling raise, leading, etc. here. */
-
-#endif
-
/* Draw texts and rules:
*
* xpos, ypos, width, and height are all fixed-point numbers
@@ -134,15 +103,12 @@ typedef struct
* 2 - input string is in 16-bit encoding.
*/
extern void pdf_dev_set_string (spt_t xpos, spt_t ypos,
- const void *instr_ptr, int instr_len,
- spt_t text_width,
- int font_id, int ctype);
-extern void pdf_dev_set_rule (spt_t xpos, spt_t ypos,
- spt_t width, spt_t height);
+ const void *instr_ptr, int instr_len,
+ spt_t text_width, int font_id, int ctype);
+extern void pdf_dev_set_rule (spt_t xpos, spt_t ypos, spt_t width, spt_t height);
/* Place XObject */
-extern int pdf_dev_put_image (int xobj_id,
- transform_info *p, double ref_x, double ref_y);
+extern int pdf_dev_put_image (int xobj_id, transform_info *p, double ref_x, double ref_y);
/* The design_size and ptsize required by PK font support...
*/
@@ -151,18 +117,9 @@ extern int pdf_dev_locate_font (const char *font_name, spt_t ptsize);
/* The following two routines are NOT WORKING.
* Dvipdfmx doesn't manage gstate well..
*/
-#if 0
-/* pdf_dev_translate() or pdf_dev_concat() should be used. */
-extern void pdf_dev_set_origin (double orig_x, double orig_y);
-#endif
-/* Always returns 1.0, please rename this. */
-extern double pdf_dev_scale (void);
+#define pdf_dev_scale() (1.0)
/* Access text state parameters. */
-#if 0
-extern int pdf_dev_currentfont (void); /* returns font_id */
-extern double pdf_dev_get_font_ptsize (int font_id);
-#endif
extern int pdf_dev_get_font_wmode (int font_id); /* ps: special support want this (pTeX). */
/* Text composition (direction) mode
@@ -214,11 +171,11 @@ extern void pdf_dev_eop (void);
*/
extern void graphics_mode (void);
-extern void pdf_dev_get_coord(double *xpos, double *ypos);
-extern void pdf_dev_push_coord(double xpos, double ypos);
-extern void pdf_dev_pop_coord(void);
+extern void pdf_dev_get_coord (double *xpos, double *ypos);
+extern void pdf_dev_push_coord (double xpos, double ypos);
+extern void pdf_dev_pop_coord (void);
extern void pdf_dev_begin_actualtext (uint16_t *unicodes, int len);
-extern void pdf_dev_end_actualtext (void);
+extern void pdf_dev_end_actualtext (void);
#endif /* _PDFDEV_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pdfdoc.c b/Build/source/texk/dvipdfm-x/pdfdoc.c
index 98f8625cfd4..3da9f320c50 100644
--- a/Build/source/texk/dvipdfm-x/pdfdoc.c
+++ b/Build/source/texk/dvipdfm-x/pdfdoc.c
@@ -66,19 +66,6 @@
#define PDFDOC_ARTICLE_ALLOC_SIZE 16
#define PDFDOC_BEAD_ALLOC_SIZE 16
-static char manual_thumb_enabled = 0;
-static char *thumb_basename = NULL;
-
-void
-pdf_doc_enable_manual_thumbnails (void)
-{
-#if HAVE_LIBPNG
- manual_thumb_enabled = 1;
-#else
- WARN("Manual thumbnail is not supported without the libpng library.");
-#endif
-}
-
static pdf_obj *
read_thumbnail (const char *thumb_filename)
{
@@ -234,10 +221,12 @@ typedef struct pdf_doc
struct {
int outline_open_depth;
double annot_grow;
- } opt;
+ int enable_manual_thumb;
+ } options;
struct form_list_node *pending_forms;
+ char *thumb_basename;
} pdf_doc;
static pdf_doc pdoc;
@@ -1257,7 +1246,7 @@ pdf_doc_init_bookmarks (pdf_doc *p, int bm_open_depth)
pdf_olitem *item;
#define MAX_OUTLINE_DEPTH 256u
- p->opt.outline_open_depth =
+ p->options.outline_open_depth =
((bm_open_depth >= 0) ?
bm_open_depth : MAX_OUTLINE_DEPTH - bm_open_depth);
@@ -1470,7 +1459,7 @@ pdf_doc_bookmarks_add (pdf_obj *dict, int is_open)
item = item->next;
}
-#define BMOPEN(b,p) (((b) < 0) ? (((p)->outlines.current_depth > (p)->opt.outline_open_depth) ? 0 : 1) : (b))
+#define BMOPEN(b,p) (((b) < 0) ? (((p)->outlines.current_depth > (p)->options.outline_open_depth) ? 0 : 1) : (b))
#if 0
item->dict = pdf_link_obj(dict);
@@ -2381,13 +2370,13 @@ pdf_doc_finish_page (pdf_doc *p)
currentpage->resources = NULL;
}
- if (manual_thumb_enabled) {
+ if (p->options.enable_manual_thumb) {
char *thumb_filename;
pdf_obj *thumb_ref;
- thumb_filename = NEW(strlen(thumb_basename)+7, char);
+ thumb_filename = NEW(strlen(p->thumb_basename)+7, char);
sprintf(thumb_filename, "%s.%ld",
- thumb_basename, (p->pages.num_entries % 99999) + 1L);
+ p->thumb_basename, (p->pages.num_entries % 99999) + 1L);
thumb_ref = read_thumbnail(thumb_filename);
RELEASE(thumb_filename);
if (thumb_ref)
@@ -2494,22 +2483,29 @@ pdf_doc_add_page_content (const char *buffer, unsigned length)
void
pdf_open_document (const char *filename,
- const char *creator, const unsigned char *id1, const unsigned char *id2,
+ const char *creator,
+ const unsigned char *id1, const unsigned char *id2,
struct pdf_setting settings)
{
pdf_doc *p = &pdoc;
- if (settings.enable_encrypt)
- pdf_init_encryption(settings.encrypt, id1);
-
- pdf_out_init(filename, settings.enable_encrypt,
+ pdf_out_init(filename, id1, id2,
+ settings.ver_major, settings.ver_minor, settings.object.compression_level,
+ settings.enable_encrypt,
settings.object.enable_objstm, settings.object.enable_predictor);
pdf_files_init();
pdf_doc_init_catalog(p);
- p->opt.annot_grow = settings.annot_grow_amount;
- p->opt.outline_open_depth = settings.outline_open_depth;
+ /* After Catalog is created... */
+ if (settings.enable_encrypt) {
+ pdf_out_set_encrypt(settings.encrypt.key_size, settings.encrypt.permission,
+ settings.encrypt.oplain, settings.encrypt.uplain,
+ 1, 1);
+ }
+
+ p->options.annot_grow = settings.annot_grow_amount;
+ p->options.outline_open_depth = settings.outline_open_depth;
pdf_init_resources();
pdf_init_colors();
@@ -2531,30 +2527,18 @@ pdf_open_document (const char *filename,
pdf_doc_set_bgcolor(NULL);
- if (settings.enable_encrypt) {
- pdf_obj *encrypt = pdf_encrypt_obj();
- pdf_set_encrypt(encrypt);
- pdf_release_obj(encrypt);
- }
- if (id1 && id2) {
- pdf_obj *id_obj = pdf_new_array();
-
- pdf_add_array(id_obj, pdf_new_string(id1, 16));
- pdf_add_array(id_obj, pdf_new_string(id2, 16));
- pdf_set_id(id_obj);
- }
-
+ p->options.enable_manual_thumb = settings.enable_manual_thumb;
/* Create a default name for thumbnail image files */
- if (manual_thumb_enabled) {
+ if (p->options.enable_manual_thumb) {
if (strlen(filename) > 4 &&
!strncmp(".pdf", filename + strlen(filename) - 4, 4)) {
size_t len = strlen(filename) - strlen(".pdf");
- thumb_basename = NEW(len+1, char);
- strncpy(thumb_basename, filename, len);
- thumb_basename[len] = 0;
+ p->thumb_basename = NEW(len+1, char);
+ strncpy(p->thumb_basename, filename, len);
+ p->thumb_basename[len] = 0;
} else {
- thumb_basename = NEW(strlen(filename)+1, char);
- strcpy(thumb_basename, filename);
+ p->thumb_basename = NEW(strlen(filename)+1, char);
+ strcpy(p->thumb_basename, filename);
}
}
@@ -2598,8 +2582,8 @@ pdf_close_document (void)
pdf_files_close();
pdf_out_flush();
- if (thumb_basename)
- RELEASE(thumb_basename);
+ if (p->thumb_basename)
+ RELEASE(p->thumb_basename);
return;
}
@@ -2817,7 +2801,7 @@ void
pdf_doc_break_annot (void)
{
pdf_doc *p = &pdoc;
- double g = p->opt.annot_grow;
+ double g = p->options.annot_grow;
if (breaking_state.dirty) {
pdf_obj *annot_dict, *annot_copy;
diff --git a/Build/source/texk/dvipdfm-x/pdfdoc.h b/Build/source/texk/dvipdfm-x/pdfdoc.h
index 855563d2d1c..2fbb0f8ae87 100644
--- a/Build/source/texk/dvipdfm-x/pdfdoc.h
+++ b/Build/source/texk/dvipdfm-x/pdfdoc.h
@@ -55,14 +55,17 @@ struct pdf_enc_setting {
struct pdf_obj_setting {
int enable_objstm;
int enable_predictor;
+ int compression_level;
};
struct pdf_setting
{
+ int ver_major, ver_minor;
double media_width, media_height;
double annot_grow_amount;
int outline_open_depth;
int check_gotos;
+ int enable_manual_thumb;
int enable_encrypt;
struct pdf_enc_setting encrypt;
struct pdf_dev_setting device;
@@ -71,7 +74,8 @@ struct pdf_setting
extern void pdf_open_document (const char *filename,
const char *creator,
- const unsigned char *id1, const unsigned char *id2,
+ const unsigned char *id1,
+ const unsigned char *id2,
struct pdf_setting settings);
extern void pdf_close_document(void);
diff --git a/Build/source/texk/dvipdfm-x/pdfencrypt.c b/Build/source/texk/dvipdfm-x/pdfencrypt.c
index a1c02561da4..524181b084f 100644
--- a/Build/source/texk/dvipdfm-x/pdfencrypt.c
+++ b/Build/source/texk/dvipdfm-x/pdfencrypt.c
@@ -1,6 +1,6 @@
/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
- Copyright (C) 2002-2018 by Jin-Hwan Cho and Shunsaku Hirata,
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
the dvipdfmx project team.
This program is free software; you can redistribute it and/or modify
@@ -45,20 +45,13 @@
* TODO: Convert password to PDFDocEncoding. SASLPrep stringpref for AESV3.
*/
-static void pdf_enc_set_passwd (unsigned int bits, unsigned int perm,
- const char *oplain, const char *uplain);
-/* PDF-2.0 is not published yet. */
#define USE_ADOBE_EXTENSION 1
-#ifdef USE_ADOBE_EXTENSION
-#include "pdfdoc.h"
-#endif
-
#include "dvipdfmx.h"
#include "pdfencrypt.h"
-static struct pdf_sec {
+struct pdf_sec {
unsigned char key[32];
int key_size;
@@ -78,7 +71,10 @@ static struct pdf_sec {
uint64_t objnum;
uint16_t gennum;
} label;
-} sec_data;
+};
+
+static void pdf_enc_set_password (pdf_sec *p_sec, unsigned int bits, unsigned int perm,
+ const char *oplain, const char *uplain);
static const unsigned char padding_bytes[32] = {
0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41,
@@ -87,29 +83,38 @@ static const unsigned char padding_bytes[32] = {
0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a
};
-int
-pdf_init_encryption (struct pdf_enc_setting settings, const unsigned char *trailer_id)
+pdf_sec *
+pdf_enc_init (const unsigned char *id,
+ int keybits, uint32_t permission,
+ const char *opasswd, const char *upasswd,
+ int use_aes, int encrypt_metadata)
{
- time_t current_time;
- struct pdf_sec *p = &sec_data;
+ time_t current_time;
+ pdf_sec *p_sec;
- if (trailer_id) {
- memcpy(p->ID, trailer_id, 16);
- } else {
- memset(p->ID, 0, 16);
- }
+ p_sec = NEW(1, pdf_sec);
+ memset(p_sec, 0, sizeof(pdf_sec));
current_time = dpx_util_get_unique_time_if_given();
if (current_time == INVALID_EPOCH_VALUE)
current_time = time(NULL);
srand(current_time); /* For AES IV */
- p->setting.use_aes = settings.use_aes;
- p->setting.encrypt_metadata = settings.encrypt_metadata;
- p->setting.need_adobe_extension = 0;
+ p_sec->setting.use_aes = use_aes;
+ p_sec->setting.encrypt_metadata = encrypt_metadata;
+ p_sec->setting.need_adobe_extension = 0;
+
+ memcpy(p_sec->ID, id, 16);
+ pdf_enc_set_password(p_sec, keybits, permission, opasswd, upasswd);
- pdf_enc_set_passwd(settings.key_size, settings.permission,
- settings.oplain, settings.uplain);
+ return p_sec;
+}
- return 0;
+void
+pdf_enc_close (pdf_sec **p_sec)
+{
+ if (p_sec && *p_sec) {
+ RELEASE(*p_sec);
+ *p_sec = NULL;
+ }
}
static void
@@ -124,10 +129,10 @@ passwd_padding (const char *src, unsigned char *dst)
}
static void
-compute_owner_password (struct pdf_sec *p,
+compute_owner_password (pdf_sec *p_sec,
const char *opasswd, const char *upasswd)
{
- int i, j;
+ int i, j;
unsigned char padded[32];
MD5_CONTEXT md5;
ARC4_CONTEXT arc4;
@@ -138,39 +143,39 @@ compute_owner_password (struct pdf_sec *p,
MD5_init (&md5);
MD5_write(&md5, padded, 32);
MD5_final(hash, &md5);
- if (p->R >= 3) {
+ if (p_sec->R >= 3) {
for (i = 0; i < 50; i++) {
/*
* NOTE: We truncate each MD5 hash as in the following step.
* Otherwise Adobe Reader won't decrypt the PDF file.
*/
MD5_init (&md5);
- MD5_write(&md5, hash, p->key_size);
+ MD5_write(&md5, hash, p_sec->key_size);
MD5_final(hash, &md5);
}
}
- ARC4_set_key(&arc4, p->key_size, hash);
+ ARC4_set_key(&arc4, p_sec->key_size, hash);
passwd_padding(upasswd, padded);
{
unsigned char tmp1[32], tmp2[32];
unsigned char key[16];
ARC4(&arc4, 32, padded, tmp1);
- if (p->R >= 3) {
+ if (p_sec->R >= 3) {
for (i = 1; i <= 19; i++) {
memcpy(tmp2, tmp1, 32);
- for (j = 0; j < p->key_size; j++)
+ for (j = 0; j < p_sec->key_size; j++)
key[j] = hash[j] ^ i;
- ARC4_set_key(&arc4, p->key_size, key);
+ ARC4_set_key(&arc4, p_sec->key_size, key);
ARC4(&arc4, 32, tmp2, tmp1);
}
}
- memcpy(p->O, tmp1, 32);
+ memcpy(p_sec->O, tmp1, 32);
}
}
static void
-compute_encryption_key (struct pdf_sec *p, const char *passwd)
+compute_encryption_key (pdf_sec *p_sec, const char *passwd)
{
int i;
unsigned char hash[32], padded[32];
@@ -179,53 +184,53 @@ compute_encryption_key (struct pdf_sec *p, const char *passwd)
passwd_padding(passwd, padded);
MD5_init (&md5);
MD5_write(&md5, padded, 32);
- MD5_write(&md5, p->O, 32);
+ MD5_write(&md5, p_sec->O, 32);
{
unsigned char tmp[4];
- tmp[0] = (unsigned char)(p->P) & 0xFF;
- tmp[1] = (unsigned char)(p->P >> 8) & 0xFF;
- tmp[2] = (unsigned char)(p->P >> 16) & 0xFF;
- tmp[3] = (unsigned char)(p->P >> 24) & 0xFF;
+ tmp[0] = (unsigned char)(p_sec->P) & 0xFF;
+ tmp[1] = (unsigned char)(p_sec->P >> 8) & 0xFF;
+ tmp[2] = (unsigned char)(p_sec->P >> 16) & 0xFF;
+ tmp[3] = (unsigned char)(p_sec->P >> 24) & 0xFF;
MD5_write(&md5, tmp, 4);
}
- MD5_write(&md5, p->ID, 16);
+ MD5_write(&md5, p_sec->ID, 16);
#if 0
/* Not Supported Yet */
- if (!p->setting.encrypt_metadata) {
+ if (!p_sec->setting.encrypt_metadata) {
unsigned char tmp[4] = {0xff, 0xff, 0xff, 0xff};
MD5_write(&md5, tmp, 4);
}
#endif
MD5_final(hash, &md5);
- if (p->R >= 3) {
+ if (p_sec->R >= 3) {
for (i = 0; i < 50; i++) {
/*
* NOTE: We truncate each MD5 hash as in the following step.
* Otherwise Adobe Reader won't decrypt the PDF file.
*/
MD5_init (&md5);
- MD5_write(&md5, hash, p->key_size);
+ MD5_write(&md5, hash, p_sec->key_size);
MD5_final(hash, &md5);
}
}
- memcpy(p->key, hash, p->key_size);
+ memcpy(p_sec->key, hash, p_sec->key_size);
}
static void
-compute_user_password (struct pdf_sec *p, const char *uplain)
+compute_user_password (pdf_sec *p_sec, const char *uplain)
{
int i, j;
ARC4_CONTEXT arc4;
MD5_CONTEXT md5;
unsigned char upasswd[32];
- compute_encryption_key(p, uplain);
+ compute_encryption_key(p_sec, uplain);
- switch (p->R) {
+ switch (p_sec->R) {
case 2:
- ARC4_set_key(&arc4, p->key_size, p->key);
+ ARC4_set_key(&arc4, p_sec->key_size, p_sec->key);
ARC4(&arc4, 32, padding_bytes, upasswd);
break;
case 3: case 4:
@@ -236,19 +241,19 @@ compute_user_password (struct pdf_sec *p, const char *uplain)
MD5_init (&md5);
MD5_write(&md5, padding_bytes, 32);
- MD5_write(&md5, p->ID, 16);
+ MD5_write(&md5, p_sec->ID, 16);
MD5_final(hash, &md5);
- ARC4_set_key(&arc4, p->key_size, p->key);
+ ARC4_set_key(&arc4, p_sec->key_size, p_sec->key);
ARC4(&arc4, 16, hash, tmp1);
- for (i = 1; i <= 19; i++) {
+ for (i = 1; i <= 19; i++) {
unsigned char key[16];
memcpy(tmp2, tmp1, 16);
- for (j = 0; j < p->key_size; j++)
- key[j] = p->key[j] ^ i;
- ARC4_set_key(&arc4, p->key_size, key);
+ for (j = 0; j < p_sec->key_size; j++)
+ key[j] = p_sec->key[j] ^ i;
+ ARC4_set_key(&arc4, p_sec->key_size, key);
ARC4(&arc4, 16, tmp2, tmp1);
}
memcpy(upasswd, tmp1, 32);
@@ -258,7 +263,7 @@ compute_user_password (struct pdf_sec *p, const char *uplain)
ERROR("Invalid revision number.");
}
- memcpy(p->U, upasswd, 32);
+ memcpy(p_sec->U, upasswd, 32);
}
/* Algorithm 2.B from ISO 32000-1 chapter 7 */
@@ -352,7 +357,7 @@ compute_hash_V5 (unsigned char *hash,
}
static void
-compute_owner_password_V5 (struct pdf_sec *p, const char *oplain)
+compute_owner_password_V5 (pdf_sec *p_sec, const char *oplain)
{
unsigned char vsalt[8], ksalt[8], hash[32];
unsigned char *OE, iv[AES_BLOCKSIZE];
@@ -364,20 +369,20 @@ compute_owner_password_V5 (struct pdf_sec *p, const char *oplain)
ksalt[i] = rand() % 256;
}
- compute_hash_V5(hash, oplain, vsalt, p->U, p->R);
- memcpy(p->O, hash, 32);
- memcpy(p->O + 32, vsalt, 8);
- memcpy(p->O + 40, ksalt, 8);
+ compute_hash_V5(hash, oplain, vsalt, p_sec->U, p_sec->R);
+ memcpy(p_sec->O, hash, 32);
+ memcpy(p_sec->O + 32, vsalt, 8);
+ memcpy(p_sec->O + 40, ksalt, 8);
- compute_hash_V5(hash, oplain, ksalt, p->U, p->R);
+ compute_hash_V5(hash, oplain, ksalt, p_sec->U, p_sec->R);
memset(iv, 0, AES_BLOCKSIZE);
- AES_cbc_encrypt(hash, 32, iv, 0, p->key, p->key_size, &OE, &OE_len);
- memcpy(p->OE, OE, 32);
+ AES_cbc_encrypt(hash, 32, iv, 0, p_sec->key, p_sec->key_size, &OE, &OE_len);
+ memcpy(p_sec->OE, OE, 32);
RELEASE(OE);
}
static void
-compute_user_password_V5 (struct pdf_sec *p, const char *uplain)
+compute_user_password_V5 (pdf_sec *p_sec, const char *uplain)
{
unsigned char vsalt[8], ksalt[8], hash[32];
unsigned char *UE, iv[AES_BLOCKSIZE];
@@ -389,36 +394,36 @@ compute_user_password_V5 (struct pdf_sec *p, const char *uplain)
ksalt[i] = rand() % 256;
}
- compute_hash_V5(hash, uplain, vsalt, NULL, p->R);
- memcpy(p->U, hash, 32);
- memcpy(p->U + 32, vsalt, 8);
- memcpy(p->U + 40, ksalt, 8);
+ compute_hash_V5(hash, uplain, vsalt, NULL, p_sec->R);
+ memcpy(p_sec->U, hash, 32);
+ memcpy(p_sec->U + 32, vsalt, 8);
+ memcpy(p_sec->U + 40, ksalt, 8);
- compute_hash_V5(hash, uplain, ksalt, NULL, p->R);
+ compute_hash_V5(hash, uplain, ksalt, NULL, p_sec->R);
memset(iv, 0, AES_BLOCKSIZE);
- AES_cbc_encrypt(hash, 32, iv, 0, p->key, p->key_size, &UE, &UE_len);
- memcpy(p->UE, UE, 32);
+ AES_cbc_encrypt(hash, 32, iv, 0, p_sec->key, p_sec->key_size, &UE, &UE_len);
+ memcpy(p_sec->UE, UE, 32);
RELEASE(UE);
}
static void
-check_version (struct pdf_sec *p, int version)
+check_version (pdf_sec *p_sec, int version)
{
- if (p->V > 2 && version < 14) {
+ if (p_sec->V > 2 && version < 14) {
WARN("Current encryption setting requires PDF version >= 1.4.");
- p->V = 1;
- p->key_size = 5;
- } else if (p->V == 4 && version < 15) {
+ p_sec->V = 1;
+ p_sec->key_size = 5;
+ } else if (p_sec->V == 4 && version < 15) {
WARN("Current encryption setting requires PDF version >= 1.5.");
- p->V = 2;
- } else if (p->V ==5 && version < 17) {
+ p_sec->V = 2;
+ } else if (p_sec->V ==5 && version < 17) {
WARN("Current encryption setting requires PDF version >= 1.7" \
" (plus Adobe Extension Level 3).");
- p->V = 4;
- p->key_size = 16;
+ p_sec->V = 4;
+ p_sec->key_size = 16;
}
- if (p->V == 5 && version < 20) {
- p->setting.need_adobe_extension = 1;
+ if (p_sec->V == 5 && version < 20) {
+ p_sec->setting.need_adobe_extension = 1;
}
}
@@ -493,54 +498,55 @@ preproc_password (const char *passwd, char *outbuf, int V)
}
static void
-pdf_enc_set_passwd (unsigned int bits, unsigned int perm,
- const char *oplain, const char *uplain)
+pdf_enc_set_password (pdf_sec *p_sec, unsigned int bits, unsigned int perm,
+ const char *oplain, const char *uplain)
{
- struct pdf_sec *p = &sec_data;
- char opasswd[128], upasswd[128];
- int version;
- char empty_passwd[1] = "\0";
+ char opasswd[128], upasswd[128];
+ int version;
+ char empty_passwd[1] = "\0";
version = pdf_get_version();
- p->key_size = (int) (bits / 8);
- if (p->key_size == 5) /* 40bit */
- p->V = 1;
- else if (p->key_size <= 16) {
- p->V = p->setting.use_aes ? 4 : 2;
- } else if (p->key_size == 32) {
- p->V = 5;
+ p_sec->key_size = (int) (bits / 8);
+ if (p_sec->key_size == 5) { /* 40bit */
+ p_sec->V = 1;
+ } else if (p_sec->key_size < 16) {
+ p_sec->V = 2;
+ } else if (p_sec->key_size == 16) {
+ p_sec->V = p_sec->setting.use_aes ? 4 : 2;
+ } else if (p_sec->key_size == 32) {
+ p_sec->V = 5;
} else {
WARN("Key length %d unsupported.", bits);
- p->key_size = 5;
- p->V = 2;
+ p_sec->key_size = 5;
+ p_sec->V = 2;
}
- check_version(p, version);
+ check_version(p_sec, version);
- p->P = (int32_t) (perm | 0xC0U);
+ p_sec->P = (int32_t) (perm | 0xC0U);
/* Bit position 10 shall be always set to 1 for PDF >= 2.0. */
if (version >= 20)
- p->P |= (1 << 9);
- switch (p->V) {
+ p_sec->P |= (1 << 9);
+ switch (p_sec->V) {
case 1:
- p->R = (p->P < 0x100L) ? 2 : 3;
+ p_sec->R = (p_sec->P < 0x100L) ? 2 : 3;
break;
case 2: case 3:
- p->R = 3;
+ p_sec->R = 3;
break;
case 4:
- p->R = 4;
+ p_sec->R = 4;
break;
case 5:
#if USE_ADOBE_EXTENSION
- p->R = 6;
+ p_sec->R = 6;
#else
WARN("Encryption V 5 unsupported.");
- p->R = 4; p->V = 4;
+ p_sec->R = 4; p_sec->V = 4;
#endif
break;
default:
- p->R = 3;
+ p_sec->R = 3;
break;
}
@@ -548,54 +554,54 @@ pdf_enc_set_passwd (unsigned int bits, unsigned int perm,
memset(upasswd, 0, 128);
/* Password must be preprocessed. */
if (oplain) {
- if (preproc_password(oplain, opasswd, p->V) < 0)
+ if (preproc_password(oplain, opasswd, p_sec->V) < 0)
WARN("Invaid UTF-8 string for password.");
} else {
- preproc_password(empty_passwd, opasswd, p->V);
+ preproc_password(empty_passwd, opasswd, p_sec->V);
}
if (uplain) {
- if (preproc_password(uplain, upasswd, p->V) < 0)
+ if (preproc_password(uplain, upasswd, p_sec->V) < 0)
WARN("Invalid UTF-8 string for passowrd.");
} else {
- preproc_password(empty_passwd, upasswd, p->V);
+ preproc_password(empty_passwd, upasswd, p_sec->V);
}
- if (p->R >= 3)
- p->P |= 0xFFFFF000U;
+ if (p_sec->R >= 3)
+ p_sec->P |= 0xFFFFF000U;
- if (p->V < 5) {
- compute_owner_password(p, opasswd, upasswd);
- compute_user_password (p, upasswd);
- } else if (p->V == 5) {
+ if (p_sec->V < 5) {
+ compute_owner_password(p_sec, opasswd, upasswd);
+ compute_user_password (p_sec, upasswd);
+ } else if (p_sec->V == 5) {
int i;
for (i = 0; i < 32; i++)
- p->key[i] = rand() % 256;
- p->key_size = 32;
+ p_sec->key[i] = rand() % 256;
+ p_sec->key_size = 32;
/* Order is important here */
- compute_user_password_V5 (p, upasswd);
- compute_owner_password_V5(p, opasswd); /* uses p->U */
+ compute_user_password_V5 (p_sec, upasswd);
+ compute_owner_password_V5(p_sec, opasswd); /* uses p_sec->U */
}
}
static void
-calculate_key (struct pdf_sec *p, unsigned char *key)
+calculate_key (pdf_sec *p_sec, unsigned char *key)
{
- int len = p->key_size + 5;
+ int len = p_sec->key_size + 5;
unsigned char tmp[25];
MD5_CONTEXT md5;
- memcpy(tmp, p->key, p->key_size);
- tmp[p->key_size ] = (unsigned char) p->label.objnum & 0xFF;
- tmp[p->key_size+1] = (unsigned char)(p->label.objnum >> 8) & 0xFF;
- tmp[p->key_size+2] = (unsigned char)(p->label.objnum >> 16) & 0xFF;
- tmp[p->key_size+3] = (unsigned char)(p->label.gennum) & 0xFF;
- tmp[p->key_size+4] = (unsigned char)(p->label.gennum >> 8) & 0xFF;
- if (p->V >= 4) {
- tmp[p->key_size + 5] = 0x73;
- tmp[p->key_size + 6] = 0x41;
- tmp[p->key_size + 7] = 0x6c;
- tmp[p->key_size + 8] = 0x54;
+ memcpy(tmp, p_sec->key, p_sec->key_size);
+ tmp[p_sec->key_size ] = (unsigned char) p_sec->label.objnum & 0xFF;
+ tmp[p_sec->key_size+1] = (unsigned char)(p_sec->label.objnum >> 8) & 0xFF;
+ tmp[p_sec->key_size+2] = (unsigned char)(p_sec->label.objnum >> 16) & 0xFF;
+ tmp[p_sec->key_size+3] = (unsigned char)(p_sec->label.gennum) & 0xFF;
+ tmp[p_sec->key_size+4] = (unsigned char)(p_sec->label.gennum >> 8) & 0xFF;
+ if (p_sec->V >= 4) {
+ tmp[p_sec->key_size + 5] = 0x73;
+ tmp[p_sec->key_size + 6] = 0x41;
+ tmp[p_sec->key_size + 7] = 0x6c;
+ tmp[p_sec->key_size + 8] = 0x54;
len += 4;
}
MD5_init (&md5);
@@ -604,49 +610,52 @@ calculate_key (struct pdf_sec *p, unsigned char *key)
}
void
-pdf_encrypt_data (const unsigned char *plain, size_t plain_len,
+pdf_encrypt_data (pdf_sec *p_sec,
+ const unsigned char *plain, size_t plain_len,
unsigned char **cipher, size_t *cipher_len)
{
- struct pdf_sec *p = &sec_data;
- unsigned char key[32];
+ unsigned char key[32];
+
+ ASSERT(p_sec);
- switch (p->V) {
+ switch (p_sec->V) {
case 1: case 2:
- calculate_key(p, key);
+ calculate_key(p_sec, key);
{
ARC4_CONTEXT arc4;
*cipher_len = plain_len;
*cipher = NEW(*cipher_len, unsigned char);
- ARC4_set_key(&arc4, MIN(16, p->key_size + 5), key);
+ ARC4_set_key(&arc4, MIN(16, p_sec->key_size + 5), key);
ARC4(&arc4, plain_len, plain, *cipher);
}
break;
case 4:
- calculate_key(p, key);
- AES_cbc_encrypt(key, MIN(16, p->key_size + 5), NULL, 1,
+ calculate_key(p_sec, key);
+ AES_cbc_encrypt(key, MIN(16, p_sec->key_size + 5), NULL, 1,
plain, plain_len, cipher, cipher_len);
break;
case 5:
- AES_cbc_encrypt(p->key, p->key_size, NULL, 1,
+ AES_cbc_encrypt(p_sec->key, p_sec->key_size, NULL, 1,
plain, plain_len, cipher, cipher_len);
break;
default:
- ERROR("pdfencrypt: Unexpected V value: %d", p->V);
+ ERROR("pdfencrypt: Unexpected V value: %d", p_sec->V);
break;
}
}
pdf_obj *
-pdf_encrypt_obj (void)
+pdf_enc_get_encrypt_dict (pdf_sec *p_sec)
{
- struct pdf_sec *p = &sec_data;
pdf_obj *doc_encrypt;
+ ASSERT(p_sec);
+
doc_encrypt = pdf_new_dict();
pdf_add_dict(doc_encrypt, pdf_new_name("Filter"), pdf_new_name("Standard"));
- pdf_add_dict(doc_encrypt, pdf_new_name("V"), pdf_new_number(p->V));
+ pdf_add_dict(doc_encrypt, pdf_new_name("V"), pdf_new_number(p_sec->V));
#if 0
/* PDF reference describes it as:
*
@@ -654,54 +663,54 @@ pdf_encrypt_obj (void)
*
* but Acrobat *requires* this even for V 5!
*/
- if (p->V > 1 && p->V < 4)
+ if (p_sec->V > 1 && p_sec->V < 4)
#endif
pdf_add_dict(doc_encrypt,
- pdf_new_name("Length"), pdf_new_number(p->key_size * 8));
- if (p->V >= 4) {
+ pdf_new_name("Length"), pdf_new_number(p_sec->key_size * 8));
+ if (p_sec->V >= 4) {
pdf_obj *CF, *StdCF;
CF = pdf_new_dict();
StdCF = pdf_new_dict();
pdf_add_dict(StdCF, pdf_new_name("CFM"),
- pdf_new_name( (p->V == 4) ? "AESV2" : "AESV3" ));
+ pdf_new_name( (p_sec->V == 4) ? "AESV2" : "AESV3" ));
pdf_add_dict(StdCF, pdf_new_name("AuthEvent"), pdf_new_name("DocOpen"));
- pdf_add_dict(StdCF, pdf_new_name("Length"), pdf_new_number(p->key_size));
+ pdf_add_dict(StdCF, pdf_new_name("Length"), pdf_new_number(p_sec->key_size));
pdf_add_dict(CF, pdf_new_name("StdCF"), StdCF);
pdf_add_dict(doc_encrypt, pdf_new_name("CF"), CF);
pdf_add_dict(doc_encrypt, pdf_new_name("StmF"), pdf_new_name("StdCF"));
pdf_add_dict(doc_encrypt, pdf_new_name("StrF"), pdf_new_name("StdCF"));
#if 0
/* NOT SUPPORTED YET */
- if (!p->setting.encrypt_metadata)
+ if (!p_sec->setting.encrypt_metadata)
pdf_add_dict(doc_encrypt,
pdf_new_name("EncryptMetadata"), pdf_new_boolean(false));
#endif
}
- pdf_add_dict(doc_encrypt, pdf_new_name("R"), pdf_new_number(p->R));
- if (p->V < 5) {
- pdf_add_dict(doc_encrypt, pdf_new_name("O"), pdf_new_string(p->O, 32));
- pdf_add_dict(doc_encrypt, pdf_new_name("U"), pdf_new_string(p->U, 32));
- } else if (p->V == 5) {
- pdf_add_dict(doc_encrypt, pdf_new_name("O"), pdf_new_string(p->O, 48));
- pdf_add_dict(doc_encrypt, pdf_new_name("U"), pdf_new_string(p->U, 48));
+ pdf_add_dict(doc_encrypt, pdf_new_name("R"), pdf_new_number(p_sec->R));
+ if (p_sec->V < 5) {
+ pdf_add_dict(doc_encrypt, pdf_new_name("O"), pdf_new_string(p_sec->O, 32));
+ pdf_add_dict(doc_encrypt, pdf_new_name("U"), pdf_new_string(p_sec->U, 32));
+ } else if (p_sec->V == 5) {
+ pdf_add_dict(doc_encrypt, pdf_new_name("O"), pdf_new_string(p_sec->O, 48));
+ pdf_add_dict(doc_encrypt, pdf_new_name("U"), pdf_new_string(p_sec->U, 48));
}
- pdf_add_dict(doc_encrypt, pdf_new_name("P"), pdf_new_number(p->P));
+ pdf_add_dict(doc_encrypt, pdf_new_name("P"), pdf_new_number(p_sec->P));
- if (p->V == 5) {
+ if (p_sec->V == 5) {
unsigned char perms[16], *cipher = NULL;
size_t cipher_len = 0;
- pdf_add_dict(doc_encrypt, pdf_new_name("OE"), pdf_new_string(p->OE, 32));
- pdf_add_dict(doc_encrypt, pdf_new_name("UE"), pdf_new_string(p->UE, 32));
- perms[0] = p->P & 0xff;
- perms[1] = (p->P >> 8) & 0xff;
- perms[2] = (p->P >> 16) & 0xff;
- perms[3] = (p->P >> 24) & 0xff;
+ pdf_add_dict(doc_encrypt, pdf_new_name("OE"), pdf_new_string(p_sec->OE, 32));
+ pdf_add_dict(doc_encrypt, pdf_new_name("UE"), pdf_new_string(p_sec->UE, 32));
+ perms[0] = p_sec->P & 0xff;
+ perms[1] = (p_sec->P >> 8) & 0xff;
+ perms[2] = (p_sec->P >> 16) & 0xff;
+ perms[3] = (p_sec->P >> 24) & 0xff;
perms[4] = 0xff;
perms[5] = 0xff;
perms[6] = 0xff;
perms[7] = 0xff;
- perms[8] = p->setting.encrypt_metadata ? 'T' : 'F';
+ perms[8] = p_sec->setting.encrypt_metadata ? 'T' : 'F';
perms[9] = 'a';
perms[10] = 'd';
perms[11] = 'b';
@@ -709,39 +718,47 @@ pdf_encrypt_obj (void)
perms[13] = 0;
perms[14] = 0;
perms[15] = 0;
- AES_ecb_encrypt(p->key, p->key_size, perms, 16, &cipher, &cipher_len);
+ AES_ecb_encrypt(p_sec->key, p_sec->key_size, perms, 16, &cipher, &cipher_len);
pdf_add_dict(doc_encrypt,
pdf_new_name("Perms"), pdf_new_string(cipher, cipher_len));
RELEASE(cipher);
}
+
+ return doc_encrypt;
+}
+
+pdf_obj *
+pdf_enc_get_extension_dict (pdf_sec *p_sec)
+{
+ pdf_obj *ext = NULL, *adbe;
+
+ ASSERT(p_sec);
#ifdef USE_ADOBE_EXTENSION
- if (p->R > 5 && p->setting.need_adobe_extension != 0) {
- pdf_obj *catalog = pdf_doc_catalog();
- pdf_obj *ext = pdf_new_dict();
- pdf_obj *adbe = pdf_new_dict();
+ if (p_sec->setting.need_adobe_extension) {
+ ext = pdf_new_dict();
+ adbe = pdf_new_dict();
pdf_add_dict(adbe, pdf_new_name("BaseVersion"), pdf_new_name("1.7"));
pdf_add_dict(adbe, pdf_new_name("ExtensionLevel"),
- pdf_new_number(p->R == 5 ? 3 : 8));
+ pdf_new_number(p_sec->R == 5 ? 3 : 8));
pdf_add_dict(ext, pdf_new_name("ADBE"), adbe);
- pdf_add_dict(catalog, pdf_new_name("Extensions"), ext);
}
#endif
- return doc_encrypt;
+ return ext;
}
-void pdf_enc_set_label (unsigned label)
+void pdf_enc_set_label (pdf_sec *p_sec, unsigned label)
{
- struct pdf_sec *p = &sec_data;
+ ASSERT(p_sec);
- p->label.objnum = label;
+ p_sec->label.objnum = label;
}
-void pdf_enc_set_generation (unsigned generation)
+void pdf_enc_set_generation (pdf_sec *p_sec, unsigned generation)
{
- struct pdf_sec *p = &sec_data;
+ ASSERT(p_sec);
- p->label.gennum = generation;
+ p_sec->label.gennum = generation;
}
diff --git a/Build/source/texk/dvipdfm-x/pdfencrypt.h b/Build/source/texk/dvipdfm-x/pdfencrypt.h
index 98e4b48e31b..885cdc6d0b6 100644
--- a/Build/source/texk/dvipdfm-x/pdfencrypt.h
+++ b/Build/source/texk/dvipdfm-x/pdfencrypt.h
@@ -2,7 +2,7 @@
This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
- Copyright (C) 2007-2018 by Jin-Hwan Cho and Shunsaku Hirata,
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
the dvipdfmx project team.
This program is free software; you can redistribute it and/or modify
@@ -28,11 +28,18 @@
#define MAX_PWD_LEN 127
-extern int pdf_init_encryption (struct pdf_enc_setting, const unsigned char *trailer_id);
-extern void pdf_enc_set_label (unsigned label);
-extern void pdf_enc_set_generation (unsigned generation);
-extern void pdf_encrypt_data (const unsigned char *plain, size_t plain_len,
- unsigned char **cipher, size_t *cipher_len);
-extern pdf_obj *pdf_encrypt_obj (void);
+typedef struct pdf_sec pdf_sec;
+extern pdf_sec *pdf_enc_init (const unsigned char *id,
+ int keybits, uint32_t permission,
+ const char *opasswd, const char *upasswd,
+ int use_aes, int encrypt_metadata);
+extern void pdf_enc_close (pdf_sec **p_sec);
+
+extern void pdf_enc_set_label (pdf_sec *p_sec, unsigned label);
+extern void pdf_enc_set_generation (pdf_sec *p_sec, unsigned generation);
+extern void pdf_encrypt_data (pdf_sec *p_sec, const unsigned char *plain, size_t plain_len,
+ unsigned char **cipher, size_t *cipher_len);
+extern pdf_obj *pdf_enc_get_encrypt_dict (pdf_sec *p_sec);
+extern pdf_obj *pdf_enc_get_extension_dict (pdf_sec *p_sec);
#endif /* _PDFENCRYPT_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pdfobj.c b/Build/source/texk/dvipdfm-x/pdfobj.c
index 7cae7295356..9be1744ba2d 100644
--- a/Build/source/texk/dvipdfm-x/pdfobj.c
+++ b/Build/source/texk/dvipdfm-x/pdfobj.c
@@ -1,6 +1,6 @@
/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
- Copyright (C) 2007-2020 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>
@@ -35,6 +35,7 @@
#include "mfileio.h"
#include "dpxconf.h"
#include "dpxutil.h"
+
#include "pdflimits.h"
#include "pdfencrypt.h"
#include "pdfparse.h"
@@ -60,13 +61,12 @@
/* Any of these types can be represented as follows */
struct pdf_obj
{
- int type;
+ int type;
- unsigned int label; /* Only used for indirect objects
- all other "label" to zero */
- unsigned short generation; /* Only used if "label" is used */
- unsigned refcount; /* Number of links to this object */
- int flags;
+ uint32_t label; /* Only used for indirect objects all other "label" to zero */
+ uint16_t generation; /* Only used if "label" is used */
+ int refcount; /* Number of links to this object */
+ int32_t flags;
void *data;
#if defined(PDFOBJ_DEBUG)
@@ -81,7 +81,7 @@ static int cur_obj_id = 0;
struct pdf_boolean
{
- char value;
+ char value;
};
struct pdf_number
@@ -92,7 +92,7 @@ struct pdf_number
struct pdf_string
{
unsigned char *string;
- unsigned short length;
+ size_t length;
};
struct pdf_name
@@ -102,8 +102,8 @@ struct pdf_name
struct pdf_array
{
- unsigned int max;
- unsigned int size;
+ size_t max;
+ size_t size;
struct pdf_obj **values;
};
@@ -138,18 +138,18 @@ struct pdf_stream
struct pdf_obj *dict;
unsigned char *stream;
int *objstm_data; /* used for object streams */
- unsigned int stream_length;
- unsigned int max_length;
+ size_t stream_length;
+ size_t max_length;
int32_t _flags;
struct decode_parms decodeparms;
};
struct pdf_indirect
{
- pdf_file *pf;
- pdf_obj *obj; /* used when PF == NULL */
- unsigned label;
- unsigned short generation;
+ pdf_file *pf;
+ pdf_obj *obj; /* used when PF == NULL */
+ uint32_t label;
+ uint16_t generation;
};
typedef void pdf_null;
@@ -162,101 +162,182 @@ typedef struct pdf_dict pdf_dict;
typedef struct pdf_stream pdf_stream;
typedef struct pdf_indirect pdf_indirect;
-static FILE *pdf_output_file = NULL;
-
-static int pdf_output_file_position = 0;
-static int pdf_output_line_position = 0;
-static int compression_saved = 0;
-
-#define FORMAT_BUF_SIZE 4096
-static char format_buffer[FORMAT_BUF_SIZE];
-
typedef struct xref_entry
{
- unsigned char type; /* object storage type */
- unsigned int field2; /* offset in file or object stream */
- unsigned short field3; /* generation or index */
- pdf_obj *direct; /* used for imported objects */
- pdf_obj *indirect; /* used for imported objects */
+ uint8_t type; /* object storage type */
+ uint32_t field2; /* offset in file or object stream */
+ uint16_t field3; /* generation or index */
+ pdf_obj *direct; /* used for imported objects */
+ pdf_obj *indirect; /* used for imported objects */
} xref_entry;
-static xref_entry *output_xref;
-
-static unsigned int pdf_max_ind_objects;
-static unsigned int next_label;
-
-static unsigned int startxref;
-
struct pdf_file
{
- FILE *file;
- pdf_obj *trailer;
- xref_entry *xref_table;
- pdf_obj *catalog;
- int num_obj;
- int file_size;
- int version;
+ FILE *file;
+ pdf_obj *trailer;
+ xref_entry *xref_table;
+ pdf_obj *catalog;
+ int num_obj;
+ int file_size;
+ int version;
};
-static pdf_obj *output_stream;
+static int error_out = 0;
#define OBJSTM_MAX_OBJS 200
/* the limit is only 100 for linearized PDF */
-static int enc_mode;
-static int doc_enc_mode;
+struct pdf_out {
+ struct {
+ int enc_mode; /* boolean */
+ } state;
+
+ unsigned char id1[16];
+ unsigned char id2[16];
+
+ struct {
+ int major;
+ int minor;
+ } version;
+
+ struct {
+ struct {
+ int level;
+ int use_predictor;
+ } compression;
+
+ int enable_encrypt;
+ int use_objstm;
+ } options;
+
+ struct {
+ FILE *file;
+ size_t file_position;
+ int line_position;
+ size_t compression_saved;
+#if defined(LIBDPX)
+ size_t file_stats;
+#endif /* LIBDPX */
+ } output;
-static pdf_obj *trailer_dict;
-static pdf_obj *xref_stream;
+ struct {
+ uint32_t next_label;
+ uint32_t max_ind_objects;
+ } obj;
-/* Internal static routines */
+ pdf_sec *sec_data;
-static int check_for_pdf_version (FILE *file);
+ pdf_obj *trailer;
+ uint32_t startxref;
+ xref_entry * xref_table;
-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);
+ pdf_obj *xref_stream;
+ pdf_obj *output_stream;
+ pdf_obj *current_objstm;
+};
-static void set_objstm_data (pdf_obj *objstm, int *data);
-static int *get_objstm_data (pdf_obj *objstm);
-static void release_objstm (pdf_obj *objstm);
+/* Underway to reform PDF related code... For a moment place pdf_out
+ * object as a static variable. */
+static pdf_out pout;
-static void pdf_out_char (FILE *file, char c);
-static void pdf_out (FILE *file, const void *buffer, int length);
+static pdf_out *
+current_output (void)
+{
+ return &pout;
+}
-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);
+static void
+init_pdf_out_struct (pdf_out *p)
+{
+ ASSERT(p);
-static void release_boolean (pdf_obj *data);
-static void write_boolean (pdf_boolean *data, FILE *file);
+ p->state.enc_mode = 0;
-static void write_null (FILE *file);
+ memset(p->id1, 0, 16);
+ memset(p->id2, 0, 16);
-static void release_number (pdf_number *number);
-static void write_number (pdf_number *number, FILE *file);
+ p->version.major = 1;
+ p->version.minor = PDF_VERSION_DEFAULT;
-static void write_string (pdf_string *str, FILE *file);
-static void release_string (pdf_string *str);
+ p->options.compression.level = 9;
+ p->options.compression.use_predictor = 1;
+ p->options.enable_encrypt = 0;
+ p->options.use_objstm = 1;
-static void write_name (pdf_name *name, FILE *file);
-static void release_name (pdf_name *name);
+ p->output.file = NULL;
+ p->output.file_position = 0;
+ p->output.line_position = 0;
+ p->output.compression_saved = 0;
+#if defined(LIBDPX)
+ p->output.file_stats = 0;
+#endif /* LIBDPX */
-static void write_array (pdf_array *array, FILE *file);
-static void release_array (pdf_array *array);
+ p->obj.next_label = 1;
+ p->obj.max_ind_objects = 0;
-static void write_dict (pdf_dict *dict, FILE *file);
-static void release_dict (pdf_dict *dict);
+ p->sec_data = NULL;
+ p->trailer = NULL;
+ p->startxref = 0;
+ p->xref_table = NULL;
-static void write_stream (pdf_stream *stream, FILE *file);
-static void release_stream (pdf_stream *stream);
+ p->xref_stream = NULL;
+ p->output_stream = NULL;
+ p->current_objstm = NULL;
+}
-static char compression_level = 9;
-static char compression_use_predictor = 1;
+static void
+clean_pdf_out_struct (pdf_out *p)
+{
+ memset(p, 0, sizeof(pdf_out));
+}
-void
-pdf_set_compression (int level)
+/* Internal static routines */
+
+static int check_for_pdf_version (FILE *file);
+
+static void pdf_flush_obj (pdf_out *p, pdf_obj *object);
+static void pdf_label_obj (pdf_out *p, pdf_obj *object);
+static void pdf_write_obj (pdf_out *p, pdf_obj *object);
+
+static void set_objstm_data (pdf_obj *objstm, int *data);
+static int *get_objstm_data (pdf_obj *objstm);
+static void release_objstm (pdf_obj *objstm);
+
+static void pdf_out_char (pdf_out *p, char c);
+static void pdf_out_str (pdf_out *p, const void *buffer, size_t length);
+
+static pdf_obj *pdf_new_ref (pdf_out *p, pdf_obj *object);
+static void release_indirect (pdf_indirect *data);
+static void write_indirect (pdf_out *p, pdf_indirect *indirect);
+
+static void release_boolean (pdf_obj *data);
+static void write_boolean (pdf_out *p, pdf_boolean *data);
+
+static void write_null (pdf_out *p);
+
+static void release_number (pdf_number *number);
+static void write_number (pdf_out *p, pdf_number *number);
+
+static void write_string (pdf_out *p, pdf_string *str);
+static void release_string (pdf_string *str);
+
+static void write_name (pdf_out *p, pdf_name *name);
+static void release_name (pdf_name *name);
+
+static void write_array (pdf_out *p, pdf_array *array);
+static void release_array (pdf_array *array);
+
+static void write_dict (pdf_out *p, pdf_dict *dict);
+static void release_dict (pdf_dict *dict);
+
+static void write_stream (pdf_out *p, pdf_stream *stream);
+static void release_stream (pdf_stream *stream);
+
+static void
+pdf_out_set_compression (pdf_out *p, int level)
{
+ ASSERT(p);
+
#ifndef HAVE_ZLIB
ERROR("You don't have compression compiled in. Possibly libz wasn't found by configure.");
#else
@@ -265,7 +346,7 @@ pdf_set_compression (int level)
WARN("Unable to set compression level -- your zlib doesn't have compress2().");
#endif
if (level >= 0 && level <= 9)
- compression_level = level;
+ p->options.compression.level = level;
else {
ERROR("set_compression: invalid compression level: %d", level);
}
@@ -277,156 +358,233 @@ pdf_set_compression (int level)
FILE *
pdf_get_output_file (void)
{
- return pdf_output_file;
+ pdf_out *p = current_output();
+ return p->output.file;
}
-static int pdf_version = PDF_VERSION_DEFAULT;
-
-void
-pdf_set_version (int version)
+static void
+pdf_out_set_version (pdf_out *p, int ver_major, int ver_minor)
{
+ int version;
+
+ ASSERT(p);
+
+ version = ver_major * 10 + ver_minor;
/* Don't forget to update CIDFont_stdcc_def[] in cid.c too! */
if (version >= PDF_VERSION_MIN && version <= PDF_VERSION_MAX) {
- pdf_version = version;
+ p->version.major = ver_major;
+ p->version.minor = ver_minor;
+ } else {
+ WARN("Unsupported PDF version %d.%d ... Ignoring.", ver_major, ver_minor);
}
}
int
pdf_get_version (void)
{
- return pdf_version;
+ pdf_out *p = current_output();
+ return (p->version.major * 10 + p->version.minor);
}
int
pdf_get_version_major (void)
{
- return pdf_version/10;
+ pdf_out *p = current_output();
+ return p->version.major;
}
int
pdf_get_version_minor (void)
{
- return pdf_version%10;
+ pdf_out *p = current_output();
+ return p->version.minor;
}
int
pdf_check_version (int major, int minor)
{
- return (pdf_version >= major*10+minor) ? 0 : -1;
-}
+ pdf_out *p = current_output();
+ if (p->version.major > major)
+ return 0;
+ else if (p->version.major < major)
+ return -1;
+ else {
+ return (p->version.minor >= minor) ? 0 : -1;
+ }
-static pdf_obj *current_objstm = NULL;
-static int do_objstm;
+ return -1;
+}
static void
-add_xref_entry (unsigned label, unsigned char type, unsigned int field2, unsigned short field3)
+add_xref_entry (pdf_out *p,
+ uint32_t label, uint8_t type, uint32_t field2, uint16_t field3)
{
- if (label >= pdf_max_ind_objects) {
- pdf_max_ind_objects = (label/IND_OBJECTS_ALLOC_SIZE+1)*IND_OBJECTS_ALLOC_SIZE;
- output_xref = RENEW(output_xref, pdf_max_ind_objects, xref_entry);
+ ASSERT(p);
+
+ if (label >= p->obj.max_ind_objects) {
+ p->obj.max_ind_objects = (label/IND_OBJECTS_ALLOC_SIZE+1)*IND_OBJECTS_ALLOC_SIZE;
+ p->xref_table = RENEW(p->xref_table, p->obj.max_ind_objects, xref_entry);
}
- output_xref[label].type = type;
- output_xref[label].field2 = field2;
- output_xref[label].field3 = field3;
- output_xref[label].direct = NULL;
- output_xref[label].indirect = NULL;
+ p->xref_table[label].type = type;
+ p->xref_table[label].field2 = field2;
+ p->xref_table[label].field3 = field3;
+ p->xref_table[label].direct = NULL;
+ p->xref_table[label].indirect = NULL;
}
#define BINARY_MARKER "%\344\360\355\370\n"
-void
+pdf_out *
pdf_out_init (const char *filename,
- int do_encryption, int enable_objstm, int enable_predictor)
+ const unsigned char *id1,
+ const unsigned char *id2,
+ int ver_major, int ver_minor, int compression_level,
+ int enable_encrypt,
+ int enable_objstm,
+ int enable_predictor)
{
- char v;
+ pdf_out *p = current_output();
+ char v;
+
+ init_pdf_out_struct(p);
+
+ pdf_out_set_version(p, ver_major, ver_minor);
+ pdf_out_set_compression(p, compression_level);
- output_xref = NULL;
- pdf_max_ind_objects = 0;
- add_xref_entry(0, 0, 0, 0xffff);
- next_label = 1;
+ add_xref_entry(p, 0, 0, 0, 0xffff);
- if (pdf_version >= 15) {
+ /* This must be set before pdf_set_root() is called */
+ p->options.enable_encrypt = enable_encrypt;
+ if (pdf_check_version(1, 5) == 0) {
if (enable_objstm) {
- xref_stream = pdf_new_stream(STREAM_COMPRESS);
- xref_stream->flags |= OBJ_NO_ENCRYPT;
- trailer_dict = pdf_stream_dict(xref_stream);
- pdf_add_dict(trailer_dict, pdf_new_name("Type"), pdf_new_name("XRef"));
- do_objstm = 1;
+ p->xref_stream = pdf_new_stream(STREAM_COMPRESS);
+ p->xref_stream->flags |= OBJ_NO_ENCRYPT;
+ p->trailer = pdf_stream_dict(p->xref_stream);
+ pdf_add_dict(p->trailer, pdf_new_name("Type"), pdf_new_name("XRef"));
+ p->options.use_objstm = 1;
} else {
- trailer_dict = pdf_new_dict();
- do_objstm = 0;
+ p->xref_stream = NULL;
+ p->trailer = pdf_new_dict();
+ p->options.use_objstm = 0;
}
} else {
- xref_stream = NULL;
- trailer_dict = pdf_new_dict();
- do_objstm = 0;
+ p->xref_stream = NULL;
+ p->trailer = pdf_new_dict();
+ p->options.use_objstm = 0;
}
- output_stream = NULL;
+ p->output_stream = NULL;
if (filename == NULL) { /* no filename: writing to stdout */
#ifdef WIN32
setmode(fileno(stdout), _O_BINARY);
#endif
- pdf_output_file = stdout;
+ p->output.file = stdout;
} else {
- pdf_output_file = MFOPEN(filename, FOPEN_WBIN_MODE);
- if (!pdf_output_file) {
+ p->output.file = MFOPEN(filename, FOPEN_WBIN_MODE);
+ if (!p->output.file) {
if (strlen(filename) < 128)
ERROR("Unable to open \"%s\".", filename);
else
ERROR("Unable to open file.");
}
}
- pdf_out(pdf_output_file, "%PDF-", strlen("%PDF-"));
- v = '0' + (pdf_version / 10);
- pdf_out(pdf_output_file, &v, 1);
- pdf_out(pdf_output_file, ".", 1);
- v = '0' + (pdf_version % 10);
- pdf_out(pdf_output_file, &v, 1);
- pdf_out(pdf_output_file, "\n", 1);
- pdf_out(pdf_output_file, BINARY_MARKER, strlen(BINARY_MARKER));
+ pdf_out_str(p, "%PDF-", strlen("%PDF-"));
+ v = '0' + p->version.major;
+ pdf_out_str(p, &v, 1);
+ pdf_out_str(p, ".", 1);
+ v = '0' + p->version.minor;
+ pdf_out_str(p, &v, 1);
+ pdf_out_str(p, "\n", 1);
+ pdf_out_str(p, BINARY_MARKER, strlen(BINARY_MARKER));
+
+ /* Set trailer ID and setup security handler */
+ {
+ pdf_obj *id_array;
+
+ memcpy(p->id1, id1, 16);
+ memcpy(p->id2, id2, 16);
+ id_array = pdf_new_array();
+ pdf_add_array(id_array, pdf_new_string(p->id1, 16));
+ pdf_add_array(id_array, pdf_new_string(p->id2, 16));
+ pdf_add_dict(p->trailer, pdf_new_name("ID"), id_array);
+ }
+ p->state.enc_mode = 0;
+ p->options.compression.use_predictor = enable_predictor;
- enc_mode = 0;
- doc_enc_mode = do_encryption;
- compression_use_predictor = enable_predictor;
+ return p;
+}
+
+void
+pdf_out_set_encrypt (int keybits, int32_t permission,
+ const char *opasswd, const char *upasswd,
+ int use_aes, int encrypt_metadata)
+{
+ pdf_out *p = current_output();
+
+ pdf_obj *encrypt, *extension, *catalog;
+
+ p->sec_data = pdf_enc_init(p->id1, keybits, permission,
+ opasswd, upasswd, use_aes, encrypt_metadata);
+ if (!p->sec_data) {
+ p->options.enable_encrypt = 0;
+ return;
+ }
+
+ encrypt = pdf_enc_get_encrypt_dict(p->sec_data);
+ pdf_add_dict(p->trailer,
+ pdf_new_name("Encrypt"), pdf_ref_obj(encrypt));
+ encrypt->flags |= OBJ_NO_ENCRYPT;
+ encrypt->flags |= OBJ_NO_OBJSTM;
+ pdf_release_obj(encrypt);
+
+ extension = pdf_enc_get_extension_dict(p->sec_data);
+ if (extension) {
+ catalog = pdf_doc_catalog();
+ pdf_add_dict(catalog, pdf_new_name("Extensions"), extension);
+ }
}
static void
-dump_xref_table (void)
+dump_xref_table (pdf_out *p)
{
- int length;
- unsigned int i;
+ int i, length;
+ char buf[32];
- pdf_out(pdf_output_file, "xref\n", 5);
+ ASSERT(p);
- length = sprintf(format_buffer, "%d %u\n", 0, next_label);
- pdf_out(pdf_output_file, format_buffer, length);
+ pdf_out_str(p, "xref\n", 5);
+
+ length = sprintf(buf, "%d %u\n", 0, p->obj.next_label);
+ pdf_out_str(p, buf, length);
/*
* Every space counts. The space after the 'f' and 'n' is * *essential*.
* The PDF spec says the lines must be 20 characters long including the
* end of line character.
*/
- for (i = 0; i < next_label; i++) {
- unsigned char type = output_xref[i].type;
+ for (i = 0; i < p->obj.next_label; i++) {
+ uint8_t type = p->xref_table[i].type;
if (type > 1)
ERROR("object type %hu not allowed in xref table", type);
- length = sprintf(format_buffer, "%010u %05hu %c \n",
- output_xref[i].field2, output_xref[i].field3,
- type ? 'n' : 'f');
- pdf_out(pdf_output_file, format_buffer, length);
+ length = sprintf(buf, "%010u %05hu %c \n",
+ p->xref_table[i].field2, p->xref_table[i].field3,
+ type ? 'n' : 'f');
+ pdf_out_str(p, buf, length);
}
}
static void
-dump_trailer_dict (void)
+dump_trailer (pdf_out *p)
{
- pdf_out(pdf_output_file, "trailer\n", 8);
- enc_mode = 0;
- write_dict(trailer_dict->data, pdf_output_file);
- pdf_release_obj(trailer_dict);
- pdf_out_char(pdf_output_file, '\n');
+ ASSERT(p);
+
+ pdf_out_str(p, "trailer\n", 8);
+ p->state.enc_mode = 0;
+ write_dict(p, p->trailer->data);
+ pdf_release_obj(p->trailer);
+ p->trailer = NULL;
+ pdf_out_char(p, '\n');
}
/*
@@ -434,16 +592,17 @@ dump_trailer_dict (void)
* contributed by Matthias Franz (March 21, 2007)
*/
static void
-dump_xref_stream (void)
+dump_xref_stream (pdf_out *p)
{
- unsigned int pos, i;
- unsigned poslen;
+ uint32_t pos, i;
+ uint32_t poslen;
unsigned char buf[7] = {0, 0, 0, 0, 0};
+ pdf_obj *w;
- pdf_obj *w;
+ ASSERT(p);
/* determine the necessary size of the offset field */
- pos = startxref; /* maximal offset value */
+ pos = p->startxref; /* maximal offset value */
poslen = 1;
while (pos >>= 8)
poslen++;
@@ -452,48 +611,52 @@ dump_xref_stream (void)
pdf_add_array(w, pdf_new_number(1)); /* type */
pdf_add_array(w, pdf_new_number(poslen)); /* offset (big-endian) */
pdf_add_array(w, pdf_new_number(2)); /* generation */
- pdf_add_dict(trailer_dict, pdf_new_name("W"), w);
+ pdf_add_dict(p->trailer, pdf_new_name("W"), w);
/* We need the xref entry for the xref stream right now */
- add_xref_entry(next_label-1, 1, startxref, 0);
+ add_xref_entry(p, p->obj.next_label - 1, 1, p->startxref, 0);
- for (i = 0; i < next_label; i++) {
- unsigned j;
- unsigned short f3;
- buf[0] = output_xref[i].type;
- pos = output_xref[i].field2;
+ for (i = 0; i < p->obj.next_label; i++) {
+ size_t j;
+ uint16_t f3;
+ buf[0] = p->xref_table[i].type;
+ pos = p->xref_table[i].field2;
for (j = poslen; j--; ) {
buf[1+j] = (unsigned char) pos;
pos >>= 8;
}
- f3 = output_xref[i].field3;
+ f3 = p->xref_table[i].field3;
buf[poslen+1] = (unsigned char) (f3 >> 8);
buf[poslen+2] = (unsigned char) (f3);
- pdf_add_stream(xref_stream, &buf, poslen+3);
+ pdf_add_stream(p->xref_stream, &buf, poslen+3);
}
- pdf_release_obj(xref_stream);
+ pdf_release_obj(p->xref_stream);
+ p->xref_stream = NULL;
}
#if defined(LIBDPX)
-static long pdf_output_file_stats = 0;
long
pdf_output_stats (void)
{
- return pdf_output_file_stats;
+ pdf_out *p = current_output();
+ return p->output.file_stats;
}
#endif /* LIBDPX */
void
pdf_out_flush (void)
{
- if (pdf_output_file) {
- int length;
+ pdf_out *p = current_output();
+ char buf[16];
+
+ if (p->output.file) {
+ int length;
/* Flush current object stream */
- if (current_objstm) {
- release_objstm(current_objstm);
- current_objstm =NULL;
+ if (p->current_objstm) {
+ release_objstm(p->current_objstm);
+ p->current_objstm =NULL;
}
/*
@@ -501,53 +664,56 @@ pdf_out_flush (void)
* for the xref stream dictionary (= trailer).
* Labelling it in pdf_out_init (with 1) does not work (why?).
*/
- if (xref_stream)
- pdf_label_obj(xref_stream);
+ if (p->xref_stream)
+ pdf_label_obj(p, p->xref_stream);
/* Record where this xref is for trailer */
- startxref = pdf_output_file_position;
+ p->startxref = p->output.file_position;
- pdf_add_dict(trailer_dict, pdf_new_name("Size"),
- pdf_new_number(next_label));
+ pdf_add_dict(p->trailer,
+ pdf_new_name("Size"), pdf_new_number(p->obj.next_label));
- if (xref_stream)
- dump_xref_stream();
+ if (p->xref_stream)
+ dump_xref_stream(p);
else {
- dump_xref_table();
- dump_trailer_dict();
+ dump_xref_table(p);
+ dump_trailer(p);
}
/* Done with xref table */
- RELEASE(output_xref);
+ RELEASE(p->xref_table);
+ p->xref_table = NULL;
- pdf_out(pdf_output_file, "startxref\n", 10);
- length = sprintf(format_buffer, "%u\n", startxref);
- pdf_out(pdf_output_file, format_buffer, length);
- pdf_out(pdf_output_file, "%%EOF\n", 6);
+ pdf_out_str(p, "startxref\n", 10);
+ length = sprintf(buf, "%u\n", p->startxref);
+ pdf_out_str(p, buf, length);
+ pdf_out_str(p, "%%EOF\n", 6);
#if !defined(LIBDPX)
MESG("\n");
#endif /* !LIBDPX */
if (dpx_conf.verbose_level > 0) {
- if (compression_level > 0) {
- MESG("Compression saved %ld bytes%s\n", compression_saved,
- pdf_version < 15 ? ". Try \"-V 1.5\" for better compression" : "");
+ if (p->options.compression.level > 0) {
+ MESG("Compression saved %ld bytes%s\n", p->output.compression_saved);
}
}
#if !defined(LIBDPX)
- MESG("%ld bytes written", pdf_output_file_position);
+ MESG("%ld bytes written", p->output.file_position);
#else
- pdf_output_file_stats = pdf_output_file_position;
+ p->output.file_stats = p->output.file_position;
#endif /* !LIBDPX */
- MFCLOSE(pdf_output_file);
- pdf_output_file_position = 0;
- pdf_output_line_position = 0;
- pdf_output_file = NULL;
+ MFCLOSE(p->output.file);
+ p->output.file = NULL;
+ p->output.file_position = 0;
+ p->output.line_position = 0;
}
+ if (p->sec_data)
+ pdf_enc_close(&p->sec_data);
#if defined(PDFOBJ_DEBUG)
{
int i;
+ error_out = 1;
MESG("\ndebug>> %d PDF objects created.", cur_obj_id);
for (i = 0; i < cur_obj_id; i++) {
pdf_obj *obj = bucket[i];
@@ -555,110 +721,113 @@ pdf_out_flush (void)
if (obj->label > 0) {
WARN("Object obj_id=<%lu, %u> unreleased...", obj->label, obj->generation);
WARN("Reference count=%d", obj->refcount);
+ pdf_write_obj(p, obj);
+ MESG("\n");
} else {
- WARN("Unreleased object found: %d", i);
- pdf_write_obj(obj, stderr);
+ WARN("Unreleased object found: (unlabeled) id=%d", i);
+ pdf_write_obj(p, obj);
MESG("\n");
}
}
}
}
#endif
+ clean_pdf_out_struct(p);
}
void
pdf_error_cleanup (void)
{
+ pdf_out *p = current_output();
/*
* This routine is the cleanup required for an abnormal exit.
* For now, simply close the file.
*/
- if (pdf_output_file)
- MFCLOSE(pdf_output_file);
- pdf_output_file = NULL;
+ if (p->output.file)
+ MFCLOSE(p->output.file);
+ p->output.file = NULL;
}
void
pdf_set_root (pdf_obj *object)
{
- if (pdf_add_dict(trailer_dict, pdf_new_name("Root"), pdf_ref_obj(object))) {
+ pdf_out *p = current_output();
+
+ if (pdf_lookup_dict(p->trailer, "Root"))
ERROR("Root object already set!");
- }
+ pdf_add_dict(p->trailer, pdf_new_name("Root"), pdf_ref_obj(object));
/* Adobe Readers don't like a document catalog inside an encrypted
* object stream, although the PDF v1.5 spec seems to allow this.
* Note that we don't set OBJ_NO_ENCRYPT since the name dictionary in
* a document catalog may contain strings, which should be encrypted.
*/
- if (doc_enc_mode)
+ if (p->options.enable_encrypt)
object->flags |= OBJ_NO_OBJSTM;
}
void
pdf_set_info (pdf_obj *object)
{
- if (pdf_add_dict(trailer_dict, pdf_new_name("Info"), pdf_ref_obj(object))) {
+ pdf_out *p = current_output();
+
+ if (pdf_lookup_dict(p->trailer, "Info"))
ERROR ("Info object already set!");
- }
+ pdf_add_dict(p->trailer, pdf_new_name("Info"), pdf_ref_obj(object));
}
-void
-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;
-}
-static
-void pdf_out_char (FILE *file, char c)
+static void
+pdf_out_char (pdf_out *p, char c)
{
- if (output_stream && file == pdf_output_file)
- pdf_add_stream(output_stream, &c, 1);
- else {
- fputc(c, file);
- /* Keep tallys for xref table *only* if writing a pdf file. */
- if (file == pdf_output_file) {
- pdf_output_file_position += 1;
+ ASSERT(p);
+
+ if (error_out) {
+ fputc(c, stderr);
+ } else {
+ if (p->output_stream)
+ pdf_add_stream(p->output_stream, &c, 1);
+ else {
+ fputc(c, p->output.file);
+ p->output.file_position += 1;
if (c == '\n')
- pdf_output_line_position = 0;
+ p->output.line_position = 0;
else
- pdf_output_line_position += 1;
+ p->output.line_position += 1;
}
}
}
static char xchar[] = "0123456789abcdef";
-#define pdf_out_xchar(f,c) do {\
- pdf_out_char((f), xchar[((c) >> 4) & 0x0f]);\
- pdf_out_char((f), xchar[(c) & 0x0f]);\
-} while (0)
+static void
+pdf_out_xchar (pdf_out *p, char c)
+{
+ ASSERT(p);
-static
-void pdf_out (FILE *file, const void *buffer, int length)
+ pdf_out_char(p, xchar[(c >> 4) & 0x0f]);
+ pdf_out_char(p, xchar[c & 0x0f]);
+}
+
+static void
+pdf_out_str (pdf_out *p, const void *buffer, size_t length)
{
- if (output_stream && file == pdf_output_file)
- pdf_add_stream(output_stream, buffer, length);
+ ASSERT(p);
+
+ if (error_out)
+ fwrite(buffer, 1, length, stderr);
else {
- fwrite(buffer, 1, length, file);
- /* Keep tallys for xref table *only* if writing a pdf file */
- if (file == pdf_output_file) {
- pdf_output_file_position += length;
- pdf_output_line_position += length;
+ if (p->output_stream)
+ pdf_add_stream(p->output_stream, buffer, length);
+ else {
+ fwrite(buffer, 1, length, p->output.file);
+ p->output.file_position += length;
+ p->output.line_position += length;
/* "foo\nbar\n "... */
if (length > 0 &&
- ((const char *)buffer)[length-1] == '\n')
- pdf_output_line_position = 0;
+ ((const char *)buffer)[length-1] == '\n')
+ p->output.line_position = 0;
}
}
}
@@ -674,12 +843,14 @@ int pdf_need_white (int type1, int type2)
}
static
-void pdf_out_white (FILE *file)
+void pdf_out_white (pdf_out *p)
{
- if (file == pdf_output_file && pdf_output_line_position >= 80) {
- pdf_out_char(file, '\n');
+ ASSERT(p);
+
+ if (p->output.line_position >= 80) {
+ pdf_out_char(p, '\n');
} else {
- pdf_out_char(file, ' ');
+ pdf_out_char(p, ' ');
}
}
@@ -724,8 +895,10 @@ pdf_obj_typeof (pdf_obj *object)
}
static void
-pdf_label_obj (pdf_obj *object)
+pdf_label_obj (pdf_out *p, pdf_obj *object)
{
+ ASSERT(p);
+
if (INVALIDOBJ(object))
ERROR("pdf_label_obj(): passed invalid object.");
@@ -733,7 +906,7 @@ pdf_label_obj (pdf_obj *object)
* Don't change label on an already labeled object. Ignore such calls.
*/
if (object->label == 0) {
- object->label = next_label++;
+ object->label = p->obj.next_label++;
object->generation = 0;
}
}
@@ -772,19 +945,23 @@ pdf_link_obj (pdf_obj *object)
pdf_obj *
pdf_ref_obj (pdf_obj *object)
{
+ pdf_out *p = current_output();
+
if (INVALIDOBJ(object))
ERROR("pdf_ref_obj(): passed invalid object.");
if (object->refcount == 0) {
MESG("\nTrying to refer already released object!!!\n");
- pdf_write_obj(object, stderr);
+ error_out = 1;
+ pdf_write_obj(p, object);
ERROR("Cannot continue...");
+ error_out = 0;
}
if (PDF_OBJ_INDIRECTTYPE(object)) {
return pdf_link_obj(object);
} else {
- return pdf_new_ref(object);
+ return pdf_new_ref(p, object);
}
}
@@ -795,14 +972,17 @@ release_indirect (pdf_indirect *data)
}
static void
-write_indirect (pdf_indirect *indirect, FILE *file)
+write_indirect (pdf_out *p, pdf_indirect *indirect)
{
- int length;
+ int length;
+ char buf[64];
+ ASSERT(p);
ASSERT(!indirect->pf);
- length = sprintf(format_buffer, "%u %hu R", indirect->label, indirect->generation);
- pdf_out(file, format_buffer, length);
+ length = sprintf(buf, "%u %hu R",
+ indirect->label, indirect->generation);
+ pdf_out_str(p, buf, length);
}
/* The undefined object is used as a placeholder in pdfnames.c
@@ -831,9 +1011,9 @@ pdf_new_null (void)
}
static void
-write_null (FILE *file)
+write_null (pdf_out *p)
{
- pdf_out(file, "null", 4);
+ pdf_out_str(p, "null", 4);
}
pdf_obj *
@@ -857,12 +1037,12 @@ release_boolean (pdf_obj *data)
}
static void
-write_boolean (pdf_boolean *data, FILE *file)
+write_boolean (pdf_out *p, pdf_boolean *data)
{
if (data->value) {
- pdf_out(file, "true", 4);
+ pdf_out_str(p, "true", 4);
} else {
- pdf_out(file, "false", 5);
+ pdf_out_str(p, "false", 5);
}
}
@@ -899,13 +1079,14 @@ release_number (pdf_number *data)
}
static void
-write_number (pdf_number *number, FILE *file)
+write_number (pdf_out *p, pdf_number *number)
{
- int count;
+ int count;
+ char buf[512];
- count = pdf_sprint_number(format_buffer, number->value);
+ count = pdf_sprint_number(buf, number->value);
- pdf_out(file, format_buffer, count);
+ pdf_out_str(p, buf, count);
}
@@ -938,20 +1119,20 @@ 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;
data->length = length;
- if (str && length > 0) {
+ if (length) {
data->string = NEW(length+1, unsigned char);
memcpy(data->string, str, length);
/* Shouldn't assume NULL terminated. */
data->string[length] = '\0';
- } else {
+ } else
data->string = NULL;
- data->length = 0;
- }
return result;
}
@@ -977,7 +1158,7 @@ pdf_string_length (pdf_obj *object)
data = object->data;
- return (unsigned) (data->length);
+ return (unsigned) data->length;
}
/*
@@ -987,8 +1168,8 @@ pdf_string_length (pdf_obj *object)
int
pdfobj_escape_str (char *buffer, int bufsize, const unsigned char *s, int len)
{
- int result = 0;
- int i;
+ size_t result = 0;
+ size_t i;
for (i = 0; i < len; i++) {
unsigned char ch;
@@ -1031,21 +1212,22 @@ pdfobj_escape_str (char *buffer, int bufsize, const unsigned char *s, int len)
}
}
- return result;
+ return (int) result;
}
static void
-write_string (pdf_string *str, FILE *file)
+write_string (pdf_out *p, pdf_string *str)
{
- unsigned char *s = NULL;
- char wbuf[FORMAT_BUF_SIZE]; /* Shouldn't use format_buffer[]. */
- int nescc = 0, i, count;
- size_t len = 0;
+ unsigned char *s = NULL;
+ size_t i, nescc = 0;
+ size_t len = 0;
- if (enc_mode) {
- pdf_encrypt_data(str->string, str->length, &s, &len);
+ ASSERT(p);
+
+ if (p->state.enc_mode) {
+ pdf_encrypt_data(p->sec_data, str->string, str->length, &s, &len);
} else {
- s = str->string;
+ s = str->string;
len = str->length;
}
@@ -1061,13 +1243,22 @@ write_string (pdf_string *str, FILE *file)
* ASCII hex string.
*/
if (nescc > len / 3) {
- pdf_out_char(file, '<');
+ pdf_out_char(p, '<');
for (i = 0; i < len; i++) {
- pdf_out_xchar(file, s[i]);
+ pdf_out_xchar(p, s[i]);
}
- pdf_out_char(file, '>');
+ pdf_out_char(p, '>');
} else {
- pdf_out_char(file, '(');
+ char *buf;
+ size_t size, count;
+
+ /* At most len/3 is to be escaped here. (see above)
+ * Thus 4*len/3 + 2*len/3 + 2 is enough for buffer size.
+ */
+ size = len * 2 + 3;
+ buf = NEW(size, char);
+
+ pdf_out_char(p, '(');
/*
* This section of code probably isn't speed critical. Escaping the
* characters in the string one at a time may seem slow, but it's
@@ -1077,12 +1268,14 @@ write_string (pdf_string *str, FILE *file)
* handled as quickly as possible since there are so many of them.
*/
for (i = 0; i < len; i++) {
- count = pdfobj_escape_str(wbuf, FORMAT_BUF_SIZE, &(s[i]), 1);
- pdf_out(file, wbuf, count);
+ count = pdfobj_escape_str(buf, size, &(s[i]), 1);
+ pdf_out_str(p, buf, count);
}
- pdf_out_char(file, ')');
+ pdf_out_char(p, ')');
+ RELEASE(buf);
}
- if (enc_mode && s)
+
+ if (p->state.enc_mode && s)
RELEASE(s);
}
@@ -1123,7 +1316,7 @@ pdf_obj *
pdf_new_name (const char *name)
{
pdf_obj *result;
- unsigned length;
+ size_t length;
pdf_name *data;
result = pdf_new_obj(PDF_NAME);
@@ -1142,10 +1335,12 @@ pdf_new_name (const char *name)
}
static void
-write_name (pdf_name *name, FILE *file)
+write_name (pdf_out *p, pdf_name *name)
{
- char *s;
- int i, length;
+ char *s;
+ size_t i, length;
+
+ ASSERT(p);
s = name->name;
length = name->name ? strlen(name->name) : 0;
@@ -1169,14 +1364,14 @@ write_name (pdf_name *name, FILE *file)
(c) == '{' || (c) == '}' || \
(c) == '%')
#endif
- pdf_out_char(file, '/');
+ pdf_out_char(p, '/');
for (i = 0; i < length; i++) {
if (s[i] < '!' || s[i] > '~' || s[i] == '#' || is_delim(s[i])) {
/* ^ "space" is here. */
- pdf_out_char (file, '#');
- pdf_out_xchar(file, s[i]);
+ pdf_out_char (p, '#');
+ pdf_out_xchar(p, s[i]);
} else {
- pdf_out_char (file, s[i]);
+ pdf_out_char (p, s[i]);
}
}
}
@@ -1225,25 +1420,27 @@ pdf_new_array (void)
}
static void
-write_array (pdf_array *array, FILE *file)
+write_array (pdf_out *p, pdf_array *array)
{
- pdf_out_char(file, '[');
+ ASSERT(p);
+
+ pdf_out_char(p, '[');
if (array->size > 0) {
- unsigned int i;
- int type1 = PDF_UNDEFINED, type2;
+ size_t i;
+ int type1 = PDF_UNDEFINED, type2;
for (i = 0; i < array->size; i++) {
if (array->values[i]) {
- type2 = array->values[i]->type;
- if (type1 != PDF_UNDEFINED && pdf_need_white(type1, type2))
- pdf_out_white(file);
- type1 = type2;
- pdf_write_obj(array->values[i], file);
+ type2 = array->values[i]->type;
+ if (type1 != PDF_UNDEFINED && pdf_need_white(type1, type2))
+ pdf_out_white(p);
+ type1 = type2;
+ pdf_write_obj(p, array->values[i]);
} else
- WARN("PDF array element #ld undefined.", i);
+ WARN("PDF array element #ld undefined.", i);
}
}
- pdf_out_char(file, ']');
+ pdf_out_char(p, ']');
}
pdf_obj *
@@ -1264,7 +1461,7 @@ pdf_get_array (pdf_obj *array, int idx)
return result;
}
-unsigned int
+unsigned
pdf_array_length (pdf_obj *array)
{
pdf_array *data;
@@ -1273,13 +1470,13 @@ pdf_array_length (pdf_obj *array)
data = (pdf_array *) array->data;
- return (unsigned int) data->size;
+ return (unsigned) data->size;
}
static void
release_array (pdf_array *data)
{
- unsigned int i;
+ size_t i;
if (data->values) {
for (i = 0; i < data->size; i++) {
@@ -1316,7 +1513,7 @@ pdf_add_array (pdf_obj *array, pdf_obj *object)
#if 0
void
-pdf_put_array (pdf_obj *array, unsigned idx, pdf_obj *object)
+pdf_put_array (pdf_obj *array, int idx, pdf_obj *object)
{
pdf_array *data;
int i;
@@ -1357,7 +1554,7 @@ pdf_shift_array (pdf_obj *array)
data = array->data;
if (data->size > 0) {
- int i;
+ size_t i;
result = data->values[0];
for (i = 1; i < data->size; i++)
@@ -1409,25 +1606,25 @@ pdf_pop_array (pdf_obj *array)
#endif
static void
-write_dict (pdf_dict *dict, FILE *file)
+write_dict (pdf_out *p, pdf_dict *dict)
{
#if 0
- pdf_out (file, "<<\n", 3); /* dropping \n saves few kb. */
+ pdf_out_str (p, "<<\n", 3); /* dropping \n saves few kb. */
#else
- pdf_out (file, "<<", 2);
+ pdf_out_str(p, "<<", 2);
#endif
while (dict->key != NULL) {
- pdf_write_obj(dict->key, file);
+ pdf_write_obj(p, dict->key);
if (pdf_need_white(PDF_NAME, (dict->value)->type)) {
- pdf_out_white(file);
+ pdf_out_white(p);
}
- pdf_write_obj(dict->value, file);
+ pdf_write_obj(p, dict->value);
#if 0
pdf_out_char (file, '\n'); /* removing this saves few kb. */
#endif
dict = dict->next;
}
- pdf_out (file, ">>", 2);
+ pdf_out_str(p, ">>", 2);
}
pdf_obj *
@@ -1826,7 +2023,9 @@ filter_PNG15_apply_filter (unsigned char *raster,
return dst;
}
-/* This modifies "raster" itself! */
+/* TIFF predictor filter support
+ * This modifies "raster" itself!
+ */
static void
apply_filter_TIFF2_1_2_4 (unsigned char *raster,
int32_t width, int32_t height,
@@ -1880,7 +2079,8 @@ apply_filter_TIFF2_1_2_4 (unsigned char *raster,
}
}
if (outbits > 0) {
- raster[k] = (outbuf << (8 - outbits)); k++;
+ raster[k] = (outbuf << (8 - outbits));
+ k++;
}
}
RELEASE(prev);
@@ -1966,17 +2166,19 @@ filter_create_predictor_dict (int predictor, int32_t columns,
}
static void
-write_stream (pdf_stream *stream, FILE *file)
+write_stream (pdf_out *p, pdf_stream *stream)
{
unsigned char *filtered;
- unsigned int filtered_length;
+ size_t filtered_length;
#ifdef HAVE_ZLIB
uLong buffer_length;
#else
- unsigned int buffer_length;
+ size_t buffer_length;
#endif
unsigned char *buffer;
+ ASSERT(p);
+
/*
* Always work from a copy of the stream. All filters read from
* "filtered" and leave their result in "filtered".
@@ -2001,11 +2203,11 @@ write_stream (pdf_stream *stream, FILE *file)
/* Apply compression filter if requested */
if (stream->stream_length > 0 &&
(stream->_flags & STREAM_COMPRESS) &&
- compression_level > 0) {
+ p->options.compression.level > 0) {
pdf_obj *filters;
/* First apply predictor filter if requested. */
- if ( compression_use_predictor &&
+ if ( p->options.compression.use_predictor &&
(stream->_flags & STREAM_USE_PREDICTOR) &&
!pdf_lookup_dict(stream->dict, "DecodeParms")) {
int bits_per_pixel = stream->decodeparms.colors *
@@ -2071,18 +2273,19 @@ write_stream (pdf_stream *stream, FILE *file)
}
#ifdef HAVE_ZLIB_COMPRESS2
if (compress2(buffer, &buffer_length, filtered,
- filtered_length, compression_level)) {
+ filtered_length, p->options.compression.level)) {
ERROR("Zlib error");
}
#else
if (compress(buffer, &buffer_length, filtered,
- filtered_length)) {
+ filtered_length)) {
ERROR ("Zlib error");
}
#endif /* HAVE_ZLIB_COMPRESS2 */
RELEASE(filtered);
- compression_saved += filtered_length - buffer_length
- - (filters ? strlen("/FlateDecode "): strlen("/Filter/FlateDecode\n"));
+ p->output.compression_saved +=
+ filtered_length - buffer_length
+ - (filters ? strlen("/FlateDecode "): strlen("/Filter/FlateDecode\n"));
filtered = buffer;
filtered_length = buffer_length;
@@ -2090,10 +2293,10 @@ write_stream (pdf_stream *stream, FILE *file)
#endif /* HAVE_ZLIB */
/* AES will change the size of data! */
- if (enc_mode) {
+ if (p->state.enc_mode) {
unsigned char *cipher = NULL;
size_t cipher_len = 0;
- pdf_encrypt_data(filtered, filtered_length, &cipher, &cipher_len);
+ pdf_encrypt_data(p->sec_data, filtered, filtered_length, &cipher, &cipher_len);
RELEASE(filtered);
filtered = cipher;
filtered_length = cipher_len;
@@ -2115,12 +2318,12 @@ write_stream (pdf_stream *stream, FILE *file)
pdf_add_dict(stream->dict,
pdf_new_name("Length"), pdf_new_number(filtered_length));
- pdf_write_obj(stream->dict, file);
+ pdf_write_obj(p, stream->dict);
- pdf_out(file, "\nstream\n", 8);
+ pdf_out_str(p, "\nstream\n", 8);
if (filtered_length > 0)
- pdf_out(file, filtered, filtered_length);
+ pdf_out_str(p, filtered, filtered_length);
RELEASE(filtered);
/*
@@ -2130,8 +2333,8 @@ write_stream (pdf_stream *stream, FILE *file)
* filters, this could be a problem.
*/
- pdf_out(file, "\n", 1);
- pdf_out(file, "endstream", 9);
+ pdf_out_str(p, "\n", 1);
+ pdf_out_str(p, "endstream", 9);
}
static void
@@ -2497,7 +2700,7 @@ filter_stream_decode_FlateDecode (const void *data, size_t len, struct decode_pa
WARN("Ignoring zlib error: status=%d, message=\"%s\"", status, z.msg);
break;
} else if (status != Z_OK) {
- WARN("inflate() failed (status=%d, message=\"%s\").", status, z.msg);
+ WARN("inflate() failed. Broken PDF file?");
inflateEnd(&z);
pdf_release_obj(tmp);
return NULL;
@@ -2861,76 +3064,83 @@ pdf_stream_get_flags (pdf_obj *stream)
#endif
static void
-pdf_write_obj (pdf_obj *object, FILE *file)
+pdf_write_obj (pdf_out *p, pdf_obj *object)
{
+ ASSERT(p);
+
if (object == NULL) {
- write_null(file);
+ write_null(p);
return;
}
if (INVALIDOBJ(object) || PDF_OBJ_UNDEFINED(object))
ERROR("pdf_write_obj: Invalid object, type = %d\n", object->type);
- if (file == stderr)
+ if (error_out)
fprintf(stderr, "{%d}", object->refcount);
switch (object->type) {
case PDF_BOOLEAN:
- write_boolean(object->data, file);
+ write_boolean(p, object->data);
break;
case PDF_NUMBER:
- write_number (object->data, file);
+ write_number (p, object->data);
break;
case PDF_STRING:
- write_string (object->data, file);
+ write_string (p, object->data);
break;
case PDF_NAME:
- write_name(object->data, file);
+ write_name(p, object->data);
break;
case PDF_ARRAY:
- write_array(object->data, file);
+ write_array(p, object->data);
break;
case PDF_DICT:
- write_dict (object->data, file);
+ write_dict (p, object->data);
break;
case PDF_STREAM:
- write_stream(object->data, file);
+ write_stream(p, object->data);
break;
case PDF_NULL:
- write_null(file);
+ write_null(p);
break;
case PDF_INDIRECT:
- write_indirect(object->data, file);
+ write_indirect(p, object->data);
break;
}
}
/* Write the object to the file */
static void
-pdf_flush_obj (pdf_obj *object, FILE *file)
+pdf_flush_obj (pdf_out *p, pdf_obj *object)
{
- int length;
+ size_t length;
+ char buf[64];
/*
* Record file position
*/
- add_xref_entry(object->label, 1,
- pdf_output_file_position, object->generation);
- length = sprintf(format_buffer, "%u %hu obj\n", object->label, object->generation);
- enc_mode = doc_enc_mode && !(object->flags & OBJ_NO_ENCRYPT);
- pdf_enc_set_label(object->label);
- pdf_enc_set_generation(object->generation);
- pdf_out(file, format_buffer, length);
- pdf_write_obj(object, file);
- pdf_out(file, "\nendobj\n", 8);
+ add_xref_entry(p, object->label, 1,
+ p->output.file_position, object->generation);
+ length = sprintf(buf, "%u %hu obj\n", object->label, object->generation);
+ p->state.enc_mode =
+ (p->options.enable_encrypt && !(object->flags & OBJ_NO_ENCRYPT)) ? 1 : 0;
+ if (p->state.enc_mode) {
+ pdf_enc_set_label(p->sec_data, object->label);
+ pdf_enc_set_generation(p->sec_data, object->generation);
+ }
+ pdf_out_str(p, buf, length);
+ pdf_write_obj(p, object);
+ pdf_out_str(p, "\nendobj\n", 8);
}
static int
-pdf_add_objstm (pdf_obj *objstm, pdf_obj *object)
+pdf_add_objstm (pdf_out *p, pdf_obj *objstm, pdf_obj *object)
{
int *data, pos;
TYPECHECK(objstm, PDF_STREAM);
+ ASSERT(p);
data = get_objstm_data(objstm);
pos = ++data[0];
@@ -2938,14 +3148,14 @@ pdf_add_objstm (pdf_obj *objstm, pdf_obj *object)
data[2*pos] = object->label;
data[2*pos+1] = pdf_stream_length(objstm);
- add_xref_entry(object->label, 2, objstm->label, pos-1);
+ add_xref_entry(p, object->label, 2, objstm->label, pos-1);
/* redirect output into objstm */
- output_stream = objstm;
- enc_mode = 0;
- pdf_write_obj(object, pdf_output_file);
- pdf_out_char(pdf_output_file, '\n');
- output_stream = NULL;
+ p->output_stream = objstm;
+ p->state.enc_mode = 0;
+ pdf_write_obj(p, object);
+ pdf_out_char(p, '\n');
+ p->output_stream = NULL;
return pos;
}
@@ -2958,7 +3168,7 @@ release_objstm (pdf_obj *objstm)
pdf_obj *dict;
pdf_stream *stream;
unsigned char *old_buf;
- unsigned int old_length;
+ size_t old_length;
stream = (pdf_stream *) objstm->data;
/* Precede stream data by offset table */
@@ -2971,8 +3181,9 @@ release_objstm (pdf_obj *objstm)
{
int i = 2*pos, *val = data+2;
while (i--) {
- int length = sprintf(format_buffer, "%d ", *(val++));
- pdf_add_stream(objstm, format_buffer, length);
+ char buf[32];
+ size_t length = sprintf(buf, "%d ", *(val++));
+ pdf_add_stream(objstm, buf, length);
}
}
@@ -2989,13 +3200,17 @@ release_objstm (pdf_obj *objstm)
void
pdf_release_obj (pdf_obj *object)
{
+ pdf_out *p = current_output();
+
if (object == NULL)
return;
if (INVALIDOBJ(object) || object->refcount <= 0) {
MESG("\npdf_release_obj: object=%p, type=%d, refcount=%d\n",
- object, object->type, object->refcount);
- pdf_write_obj(object, stderr);
+ object, object->type, object->refcount);
+ error_out = 1;
+ pdf_write_obj(p, object);
ERROR("pdf_release_obj: Called with invalid object.");
+ error_out = 0;
}
object->refcount -= 1;
if (object->refcount == 0) {
@@ -3006,23 +3221,23 @@ pdf_release_obj (pdf_obj *object)
* Nothing is using this object so it's okay to remove it.
* Nonzero "label" means object needs to be written before it's destroyed.
*/
- if (object->label && pdf_output_file != NULL) {
- if (!do_objstm || object->flags & OBJ_NO_OBJSTM
- || (doc_enc_mode && object->flags & OBJ_NO_ENCRYPT)
- || object->generation)
- pdf_flush_obj(object, pdf_output_file);
+ if (object->label && p->output.file != NULL) {
+ if (!p->options.use_objstm || object->flags & OBJ_NO_OBJSTM ||
+ (p->options.enable_encrypt && (object->flags & OBJ_NO_ENCRYPT)) ||
+ object->generation)
+ pdf_flush_obj(p, object);
else {
- if (!current_objstm) {
- int *data = NEW(2*OBJSTM_MAX_OBJS+2, int);
- data[0] = data[1] = 0;
- current_objstm = pdf_new_stream(STREAM_COMPRESS);
- set_objstm_data(current_objstm, data);
- pdf_label_obj(current_objstm);
- }
- if (pdf_add_objstm(current_objstm, object) == OBJSTM_MAX_OBJS) {
- release_objstm(current_objstm);
- current_objstm = NULL;
- }
+ if (!p->current_objstm) {
+ int *data = NEW(2*OBJSTM_MAX_OBJS+2, int);
+ data[0] = data[1] = 0;
+ p->current_objstm = pdf_new_stream(STREAM_COMPRESS);
+ set_objstm_data(p->current_objstm, data);
+ pdf_label_obj(p, p->current_objstm);
+ }
+ if (pdf_add_objstm(p, p->current_objstm, object) == OBJSTM_MAX_OBJS) {
+ release_objstm(p->current_objstm);
+ p->current_objstm = NULL;
+ }
}
}
switch (object->type) {
@@ -3060,6 +3275,9 @@ pdf_release_obj (pdf_obj *object)
}
}
+/* Reading external PDF files
+ *
+ */
static int
backup_line (FILE *pdf_input_file)
{
@@ -3086,11 +3304,11 @@ backup_line (FILE *pdf_input_file)
static int
find_xref (FILE *pdf_input_file)
{
- int xref_pos = 0;
- int len, tries = 10;
+ size_t len, xref_pos = 0;
+ int tries = 10;
do {
- int currentpos;
+ size_t currentpos;
if (!backup_line(pdf_input_file)) {
tries = 0;
@@ -3162,10 +3380,11 @@ parse_trailer (pdf_file *pf)
* :-(
*/
static int
-next_object_offset (pdf_file *pf, unsigned int obj_num)
+next_object_offset (pdf_file *pf, uint32_t obj_num)
{
- int next = pf->file_size; /* Worst case */
- int i, curr;
+ uint32_t next = pf->file_size; /* Worst case */
+ size_t i;
+ uint32_t curr;
curr = pf->xref_table[obj_num].field2;
/* Check all other type 1 objects to find next one */
@@ -3184,7 +3403,7 @@ next_object_offset (pdf_file *pf, unsigned int obj_num)
((pf)->xref_table[(n)].type == 2 && !(g))))
pdf_obj *
-pdf_new_indirect (pdf_file *pf, unsigned obj_num, unsigned short obj_gen)
+pdf_new_indirect (pdf_file *pf, uint32_t obj_num, uint16_t obj_gen)
{
pdf_obj *result;
pdf_indirect *indirect;
@@ -3202,13 +3421,12 @@ pdf_new_indirect (pdf_file *pf, unsigned obj_num, unsigned short obj_gen)
}
static pdf_obj *
-pdf_read_object (unsigned int obj_num, unsigned short obj_gen,
- pdf_file *pf, int offset, int limit)
+pdf_read_object (uint32_t obj_num, uint16_t obj_gen, pdf_file *pf, size_t offset, size_t limit)
{
- int length;
- char *buffer;
+ pdf_obj *result = NULL;
+ size_t length;
+ char *buffer;
const char *p, *endptr;
- pdf_obj *result;
length = limit - offset;
@@ -3227,7 +3445,7 @@ pdf_read_object (unsigned int obj_num, unsigned short obj_gen,
{
const char *q = p; /* <== p */
char *sp;
- unsigned int n, g;
+ uint32_t n, g;
skip_white(&q, endptr);
sp = parse_unsigned(&q, endptr);
@@ -3279,16 +3497,16 @@ pdf_read_object (unsigned int obj_num, unsigned short obj_gen,
}
static pdf_obj *
-read_objstm (pdf_file *pf, unsigned int num)
+read_objstm (pdf_file *pf, uint32_t num)
{
- unsigned int offset = pf->xref_table[num].field2;
- unsigned short gen = pf->xref_table[num].field3;
- int limit = next_object_offset(pf, num), n, first, *header = NULL;
- char *data = NULL, *q;
+ size_t offset = pf->xref_table[num].field2;
+ uint16_t gen = pf->xref_table[num].field3;
+ size_t limit = next_object_offset(pf, num);
+ int n, first, *header = NULL;
+ char *data = NULL, *q;
const char *p, *endptr;
- int i;
-
- pdf_obj *objstm, *dict, *type, *n_obj, *first_obj;
+ int i;
+ pdf_obj *objstm, *dict, *type, *n_obj, *first_obj;
objstm = pdf_read_object(num, gen, pf, offset, limit);
@@ -3365,7 +3583,7 @@ read_objstm (pdf_file *pf, unsigned int num)
* several cross-reference sections.
*/
static pdf_obj *
-pdf_get_object (pdf_file *pf, unsigned int obj_num, unsigned short obj_gen)
+pdf_get_object (pdf_file *pf, uint32_t obj_num, uint16_t obj_gen)
{
pdf_obj *result;
@@ -3381,27 +3599,27 @@ pdf_get_object (pdf_file *pf, unsigned int obj_num, unsigned short obj_gen)
if (pf->xref_table[obj_num].type == 1) {
/* type == 1 */
- unsigned int offset;
- int limit;
+ uint32_t offset;
+ size_t limit;
offset = pf->xref_table[obj_num].field2;
limit = next_object_offset(pf, obj_num);
result = pdf_read_object(obj_num, obj_gen, pf, offset, limit);
} else {
/* type == 2 */
- unsigned int objstm_num = pf->xref_table[obj_num].field2;
- unsigned short index = pf->xref_table[obj_num].field3;
- pdf_obj *objstm;
- int *data, n, first, length;
+ uint32_t objstm_num = pf->xref_table[obj_num].field2;
+ uint16_t index = pf->xref_table[obj_num].field3;
+ pdf_obj *objstm;
+ int *data, n, first, length;
const char *p, *q;
if (objstm_num >= pf->num_obj ||
- pf->xref_table[objstm_num].type != 1 ||
- !((objstm = pf->xref_table[objstm_num].direct) ||
- (objstm = read_objstm(pf, objstm_num))))
+ pf->xref_table[objstm_num].type != 1 ||
+ !((objstm = pf->xref_table[objstm_num].direct) ||
+ (objstm = read_objstm(pf, objstm_num))))
goto error;
- data = get_objstm_data(objstm);
- n = *(data++);
+ data = get_objstm_data(objstm);
+ n = *(data++);
first = *(data++);
if (index >= n || data[2*index] != obj_num)
@@ -3431,12 +3649,14 @@ pdf_get_object (pdf_file *pf, unsigned int obj_num, unsigned short obj_gen)
#define OBJ_GEN(o) (((pdf_indirect *)((o)->data))->generation)
static pdf_obj *
-pdf_new_ref (pdf_obj *object)
+pdf_new_ref (pdf_out *p, pdf_obj *object)
{
pdf_obj *result;
+ ASSERT(p);
+
if (object->label == 0) {
- pdf_label_obj(object);
+ pdf_label_obj(p, object);
}
result = pdf_new_indirect(NULL, object->label, object->generation);
OBJ_OBJ(result) = object;
@@ -3456,8 +3676,8 @@ pdf_deref_obj (pdf_obj *obj)
while (PDF_OBJ_INDIRECTTYPE(obj) && --count) {
pdf_file *pf = OBJ_FILE(obj);
if (pf) {
- unsigned int obj_num = OBJ_NUM(obj);
- unsigned short obj_gen = OBJ_GEN(obj);
+ uint32_t obj_num = OBJ_NUM(obj);
+ uint16_t obj_gen = OBJ_GEN(obj);
pdf_release_obj(obj);
obj = pdf_get_object(pf, obj_num, obj_gen);
} else {
@@ -3481,9 +3701,9 @@ pdf_deref_obj (pdf_obj *obj)
}
static void
-extend_xref (pdf_file *pf, int new_size)
+extend_xref (pdf_file *pf, size_t new_size)
{
- unsigned int i;
+ size_t i;
pf->xref_table = RENEW(pf->xref_table, new_size, xref_entry);
for (i = pf->num_obj; i < new_size; i++) {
@@ -3498,12 +3718,12 @@ extend_xref (pdf_file *pf, int new_size)
/* Returns < 0 for error, 1 for success, and 0 when xref stream found. */
static int
-parse_xref_table (pdf_file *pf, int xref_pos)
+parse_xref_table (pdf_file *pf, size_t xref_pos)
{
FILE *pdf_input_file = pf->file;
const char *p, *endptr;
char buf[256]; /* See, PDF ref. v.1.7, p.91 for "255+1" here. */
- int len;
+ size_t len;
/*
* This routine reads one xref segment. It may be called multiple times
@@ -3535,10 +3755,10 @@ parse_xref_table (pdf_file *pf, int xref_pos)
/* Next line in file has first item and size of table */
for (;;) {
- char flag;
- unsigned int current_pos;
- int i;
- uint32_t first, size, offset, obj_gen;
+ char flag;
+ size_t current_pos, size, offset;
+ int i;
+ uint32_t first, obj_gen;
current_pos = tell_position(pdf_input_file);
len = mfreadln(buf, 255, pdf_input_file);
@@ -3702,10 +3922,10 @@ parse_xref_table (pdf_file *pf, int xref_pos)
return 1;
}
-static unsigned int
-parse_xrefstm_field (const char **p, int length, unsigned int def)
+static uint32_t
+parse_xrefstm_field (const char **p, size_t length, uint32_t def)
{
- unsigned int val = 0;
+ uint32_t val = 0;
if (!length)
return def;
@@ -3720,9 +3940,9 @@ parse_xrefstm_field (const char **p, int length, unsigned int def)
static int
parse_xrefstm_subsec (pdf_file *pf,
- const char **p, int *length,
- int *W, int wsum,
- int first, int size) {
+ const char **p, size_t *length,
+ int *W, int wsum, int first, int size)
+{
xref_entry *e;
if ((*length -= wsum*size) < 0)
@@ -3733,9 +3953,9 @@ parse_xrefstm_subsec (pdf_file *pf,
e = pf->xref_table + first;
while (size--) {
- unsigned char type;
- unsigned int field2;
- unsigned short field3;
+ uint8_t type;
+ uint32_t field2;
+ uint16_t field3;
type = (unsigned char) parse_xrefstm_field(p, W[0], 1);
if (type > 2)
@@ -3746,8 +3966,8 @@ parse_xrefstm_subsec (pdf_file *pf,
return -1;
#endif
- field2 = (unsigned int) parse_xrefstm_field(p, W[1], 0);
- field3 = (unsigned short) parse_xrefstm_field(p, W[2], 0);
+ field2 = (uint32_t) parse_xrefstm_field(p, W[1], 0);
+ field3 = (uint16_t) parse_xrefstm_field(p, W[2], 0);
if (!e->field2) {
e->type = type;
@@ -3761,12 +3981,12 @@ parse_xrefstm_subsec (pdf_file *pf,
}
static int
-parse_xref_stream (pdf_file *pf, int xref_pos, pdf_obj **trailer)
+parse_xref_stream (pdf_file *pf, size_t xref_pos, pdf_obj **trailer)
{
- pdf_obj *xrefstm, *size_obj, *W_obj, *index_obj;
- unsigned int size;
- int length;
- int W[3], i, wsum = 0;
+ pdf_obj *xrefstm, *size_obj, *W_obj, *index_obj;
+ uint32_t size;
+ size_t length;
+ int W[3], i, wsum = 0;
const char *p;
xrefstm = pdf_read_object(0, 0, pf, xref_pos, pf->file_size);
@@ -3786,7 +4006,7 @@ parse_xref_stream (pdf_file *pf, int xref_pos, pdf_obj **trailer)
size_obj = pdf_lookup_dict(*trailer, "Size");
if (!PDF_OBJ_NUMBERTYPE(size_obj))
goto error;
- size = (unsigned int) pdf_number_value(size_obj);
+ size = (uint32_t) pdf_number_value(size_obj);
length = pdf_stream_length(xrefstm);
@@ -3805,7 +4025,7 @@ parse_xref_stream (pdf_file *pf, int xref_pos, pdf_obj **trailer)
index_obj = pdf_lookup_dict(*trailer, "Index");
if (index_obj) {
- unsigned int index_len;
+ size_t index_len;
if (!PDF_OBJ_ARRAYTYPE(index_obj) ||
((index_len = pdf_array_length(index_obj)) % 2 ))
goto error;
@@ -3845,7 +4065,7 @@ static pdf_obj *
read_xref (pdf_file *pf)
{
pdf_obj *trailer = NULL, *main_trailer = NULL;
- int xref_pos;
+ size_t xref_pos;
if (!(xref_pos = find_xref(pf->file)))
goto error;
@@ -3859,37 +4079,37 @@ read_xref (pdf_file *pf)
pdf_obj *xrefstm;
if (!(trailer = parse_trailer(pf)))
- goto error;
+ goto error;
if (!main_trailer)
- main_trailer = pdf_link_obj(trailer);
+ main_trailer = pdf_link_obj(trailer);
if ((xrefstm = pdf_lookup_dict(trailer, "XRefStm"))) {
- pdf_obj *new_trailer = NULL;
- if (PDF_OBJ_NUMBERTYPE(xrefstm) &&
- parse_xref_stream(pf, (int) pdf_number_value(xrefstm),
+ pdf_obj *new_trailer = NULL;
+ if (PDF_OBJ_NUMBERTYPE(xrefstm) &&
+ parse_xref_stream(pf, (int) pdf_number_value(xrefstm),
&new_trailer))
- pdf_release_obj(new_trailer);
- else
- WARN("Skipping hybrid reference section.");
- /* Many PDF 1.5 xref streams use DecodeParms, which we cannot
- parse. This way we can use at least xref tables in hybrid
- documents. Or should we better stop parsing the file?
- */
+ pdf_release_obj(new_trailer);
+ else
+ WARN("Skipping hybrid reference section.");
+ /* Many PDF 1.5 xref streams use DecodeParms, which we cannot
+ * parse. This way we can use at least xref tables in hybrid
+ * documents. Or should we better stop parsing the file?
+ */
}
} else if (!res && parse_xref_stream(pf, xref_pos, &trailer)) {
/* cross-reference stream */
if (!main_trailer)
- main_trailer = pdf_link_obj(trailer);
+ main_trailer = pdf_link_obj(trailer);
} else
goto error;
if ((prev = pdf_lookup_dict(trailer, "Prev"))) {
if (PDF_OBJ_NUMBERTYPE(prev))
- xref_pos = (int) pdf_number_value(prev);
+ xref_pos = (size_t) pdf_number_value(prev);
else
- goto error;
+ goto error;
} else
xref_pos = 0;
@@ -3938,7 +4158,7 @@ pdf_file_new (FILE *file)
static void
pdf_file_free (pdf_file *pf)
{
- unsigned int i;
+ size_t i;
if (!pf) {
return;
@@ -3995,6 +4215,7 @@ pdf_file_get_catalog (pdf_file *pf)
pdf_file *
pdf_open (const char *ident, FILE *file)
{
+ pdf_out *p = current_output();
pdf_file *pf = NULL;
ASSERT(pdf_files);
@@ -4008,15 +4229,21 @@ pdf_open (const char *ident, FILE *file)
pdf_obj *new_version;
int version = check_for_pdf_version(file);
- if (version < 10)
- WARN("Unrecognized PDF version specified for input PDF file: %d.%d",
- pdf_version/10, pdf_version%10);
- else if (version > pdf_version) {
- WARN("Trying to include PDF file with version (%d.%d), which is " \
- "newer than current output PDF setting (%d.%d).",
- version/10, version%10, pdf_version/10, pdf_version%10);
- }
+ if (!dpx_conf.is_xbb) {
+ int ver_major, ver_minor;
+ ver_major = version / 10;
+ ver_minor = version % 10;
+
+ if (version < 10)
+ WARN("Unrecognized PDF version specified for input PDF file: %d.%d",
+ ver_major, ver_minor);
+ else if (pdf_check_version(ver_major, ver_minor) < 0) {
+ WARN("Trying to include PDF file with version (%d.%d), which is " \
+ "newer than current output PDF setting (%d.%d).",
+ ver_major, ver_minor, p->version.major, p->version.minor);
+ }
+ }
pf = pdf_file_new(file);
pf->version = version;
@@ -4096,7 +4323,7 @@ check_for_pdf (FILE *file)
if (version < 0) /* not a PDF file */
return 0;
- if (version <= pdf_version)
+ if (version <= pdf_get_version())
return 1;
return 1;
@@ -4122,10 +4349,11 @@ import_dict (pdf_obj *key, pdf_obj *value, void *pdata)
static pdf_obj *
pdf_import_indirect (pdf_obj *object)
{
+ pdf_out *p = current_output();
pdf_file *pf = OBJ_FILE(object);
- unsigned int obj_num = OBJ_NUM(object);
- unsigned short obj_gen = OBJ_GEN(object);
- pdf_obj *ref;
+ uint32_t obj_num = OBJ_NUM(object);
+ uint16_t obj_gen = OBJ_GEN(object);
+ pdf_obj *ref;
ASSERT(pf);
@@ -4154,7 +4382,7 @@ pdf_import_indirect (pdf_obj *object)
* are completely read.
*/
reserved = pdf_new_null(); /* for reservation of label */
- pf->xref_table[obj_num].indirect = ref = pdf_new_ref(reserved);
+ pf->xref_table[obj_num].indirect = ref = pdf_new_ref(p, reserved);
imported = pdf_import_object(obj);
if (imported) {
if (imported->label) {
@@ -4187,7 +4415,7 @@ pdf_import_object (pdf_obj *object)
{
pdf_obj *imported;
pdf_obj *tmp;
- int i;
+ size_t i;
switch (pdf_obj_typeof(object)) {
@@ -4233,8 +4461,8 @@ pdf_import_object (pdf_obj *object)
for (i = 0; i < pdf_array_length(object); i++) {
tmp = pdf_import_object(pdf_get_array(object, i));
if (!tmp) {
- pdf_release_obj(imported);
- return NULL;
+ pdf_release_obj(imported);
+ return NULL;
}
pdf_add_array(imported, tmp);
}
diff --git a/Build/source/texk/dvipdfm-x/pdfobj.h b/Build/source/texk/dvipdfm-x/pdfobj.h
index 04ba12e711c..7b41bb411b4 100644
--- a/Build/source/texk/dvipdfm-x/pdfobj.h
+++ b/Build/source/texk/dvipdfm-x/pdfobj.h
@@ -1,6 +1,6 @@
/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
- Copyright (C) 2007-2020 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>
@@ -25,6 +25,7 @@
#include <stdio.h>
+typedef struct pdf_out pdf_out;
/* Here is the complete list of PDF object types */
@@ -54,13 +55,19 @@ typedef struct pdf_file pdf_file;
extern void pdf_error_cleanup (void);
extern FILE *pdf_get_output_file (void);
-
-extern void pdf_out_init (const char *filename,
- int enable_encrypt, int enable_objstm,
- int enable_predictor);
+extern pdf_out *pdf_out_init (const char *filename,
+ const unsigned char *id1, const unsigned char *id2,
+ int ver_major, int ver_minor,
+ int compression_level,
+ int enable_encrypt,
+ int enable_objstm,
+ int enable_predictor);
+extern void pdf_out_set_encrypt (int keybits, int32_t permission,
+ const char *opasswd, const char *upasswd,
+ int use_aes, int encrypt_metadata);
extern void pdf_out_flush (void);
-extern void pdf_set_version (int version);
-extern int pdf_get_version (void);
+
+extern int pdf_get_version (void);
extern int pdf_get_version_major (void);
extern int pdf_get_version_minor (void);
@@ -152,6 +159,7 @@ extern pdf_obj *pdf_new_stream (int flags);
extern void pdf_add_stream (pdf_obj *stream,
const void *stream_data_ptr,
int stream_data_len);
+
extern int pdf_concat_stream (pdf_obj *dst, pdf_obj *src);
extern pdf_obj *pdf_stream_dict (pdf_obj *stream);
extern int pdf_stream_length (pdf_obj *stream);
@@ -164,24 +172,21 @@ extern void pdf_stream_set_predictor (pdf_obj *stream,
int predictor, int32_t columns,
int bpc, int colors);
-/* Compare labels of two indirect reference object. */
+/* Compare label of two indirect reference object. */
extern int pdf_compare_reference (pdf_obj *ref1, pdf_obj *ref2);
/* Compare objects. */
extern int pdf_compare_object (pdf_obj *obj1, pdf_obj *obj2);
+
/* The following routines are not appropriate for pdfobj.
*/
-extern void pdf_set_compression (int level);
-
extern void pdf_set_info (pdf_obj *obj);
extern void pdf_set_root (pdf_obj *obj);
-extern void pdf_set_id (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 int check_for_pdf (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);
@@ -193,7 +198,7 @@ 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 label, unsigned short generation);
+extern pdf_obj *pdf_new_indirect (pdf_file *pf, uint32_t label, uint16_t generation);
extern int pdf_check_version (int major, int minor);
diff --git a/Build/source/texk/dvipdfm-x/pdfparse.c b/Build/source/texk/dvipdfm-x/pdfparse.c
index 050eb988230..58ea9a0bc4e 100644
--- a/Build/source/texk/dvipdfm-x/pdfparse.c
+++ b/Build/source/texk/dvipdfm-x/pdfparse.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>
@@ -70,8 +70,6 @@ static struct {
static int xtoi (char ch);
-static const char *save = NULL;
-
void
dump (const char *start, const char *end)
{
@@ -86,14 +84,6 @@ dump (const char *start, const char *end)
MESG("<--\n");
}
-#define SAVE(s,e) do {\
- save = (s);\
- } while (0)
-#define DUMP_RESTORE(s,e) do {\
- dump(save, end);\
- (s) = save;\
- } while (0)
-
void
pdfparse_skip_line (const char **start, const char *end)
{
@@ -646,28 +636,12 @@ parse_pdf_string (const char **pp, const char *endptr)
return NULL;
}
-#ifndef PDF_PARSE_STRICT
-pdf_obj *
-parse_pdf_tainted_dict (const char **pp, const char *endptr)
-{
- pdf_obj *result;
-
- parser_state.tainted = 1;
- result = parse_pdf_dict(pp, endptr, NULL);
- parser_state.tainted = 0;
-
- return result;
-}
-#else /* PDF_PARSE_STRICT */
-pdf_obj *
-parse_pdf_tainted_dict (const char **pp, const char *endptr)
-{
- return parse_pdf_dict(pp, endptr, NULL);
-}
-#endif /* !PDF_PARSE_STRICT */
-
-pdf_obj *
-parse_pdf_dict (const char **pp, const char *endptr, pdf_file *pf)
+static pdf_obj *
+parse_pdf_dict_extended (const char **pp, const char *endptr, pdf_file *pf,
+ pdf_obj* (*unknown_handler) (const char **pp,
+ const char *endptr,
+ void *user_data),
+ void *user_data)
{
pdf_obj *result = NULL;
const char *p;
@@ -699,7 +673,7 @@ parse_pdf_dict (const char **pp, const char *endptr, pdf_file *pf)
skip_white(&p, endptr);
- value = parse_pdf_object(&p, endptr, pf);
+ value = parse_pdf_object_extended(&p, endptr, pf, unknown_handler, user_data);
if (!value) {
pdf_release_obj(key);
pdf_release_obj(value);
@@ -723,8 +697,12 @@ parse_pdf_dict (const char **pp, const char *endptr, pdf_file *pf)
return result;
}
-pdf_obj *
-parse_pdf_array (const char **pp, const char *endptr, pdf_file *pf)
+static pdf_obj *
+parse_pdf_array_extended (const char **pp, const char *endptr, pdf_file *pf,
+ pdf_obj* (*unknown_handler) (const char **pp,
+ const char *endptr,
+ void *user_data),
+ void *user_data)
{
pdf_obj *result;
const char *p;
@@ -745,7 +723,7 @@ parse_pdf_array (const char **pp, const char *endptr, pdf_file *pf)
while (p < endptr && p[0] != ']') {
pdf_obj *elem;
- elem = parse_pdf_object(&p, endptr, pf);
+ elem = parse_pdf_object_extended(&p, endptr, pf, unknown_handler, user_data);
if (!elem) {
pdf_release_obj(result);
WARN("Could not find a valid object in array object.");
@@ -865,39 +843,6 @@ parse_pdf_stream (const char **pp, const char *endptr, pdf_obj *dict)
return result;
}
-#ifndef PDF_PARSE_STRICT
-
-/* PLEASE REMOVE THIS */
-#include "specials.h"
-
-/* This is not PDF indirect reference. */
-static pdf_obj *
-parse_pdf_reference (const char **start, const char *end)
-{
- pdf_obj *result = NULL;
- char *name;
-
- SAVE(*start, end);
-
- skip_white(start, end);
- name = parse_opt_ident(start, end);
- if (name) {
- result = spc_lookup_reference(name);
- if (!result) {
- WARN("Could not find the named reference (@%s).", name);
- DUMP_RESTORE(*start, end);
- }
- RELEASE(name);
- } else {
- WARN("Could not find a reference name.");
- DUMP_RESTORE(*start, end);
- result = NULL;
- }
-
- return result;
-}
-#endif /* !PDF_PARSE_STRICT */
-
static pdf_obj *
try_pdf_reference (const char *start, const char *end, const char **endptr, pdf_file *pf)
{
@@ -945,7 +890,11 @@ try_pdf_reference (const char *start, const char *end, const char **endptr, pdf_
}
pdf_obj *
-parse_pdf_object (const char **pp, const char *endptr, pdf_file *pf)
+parse_pdf_object_extended (const char **pp, const char *endptr, pdf_file *pf,
+ pdf_obj* (*unknown_handler) (const char **pp,
+ const char *endptr,
+ void *user_data),
+ void *user_data)
/* If pf is NULL, then indirect references are not allowed */
{
pdf_obj *result = NULL;
@@ -966,7 +915,7 @@ parse_pdf_object (const char **pp, const char *endptr, pdf_file *pf)
} else {
pdf_obj *dict;
- result = parse_pdf_dict(pp, endptr, pf);
+ result = parse_pdf_dict_extended(pp, endptr, pf, unknown_handler, user_data);
skip_white(pp, endptr);
if ( result &&
*pp <= endptr - 15 &&
@@ -982,7 +931,7 @@ parse_pdf_object (const char **pp, const char *endptr, pdf_file *pf)
result = parse_pdf_string(pp, endptr);
break;
case '[':
- result = parse_pdf_array(pp, endptr, pf);
+ result = parse_pdf_array_extended(pp, endptr, pf, unknown_handler, user_data);
break;
case '/':
result = parse_pdf_name(pp, endptr);
@@ -1010,18 +959,51 @@ parse_pdf_object (const char **pp, const char *endptr, pdf_file *pf)
}
break;
- case '@':
-
-#ifndef PDF_PARSE_STRICT
- result = parse_pdf_reference(pp, endptr);
-#endif /* !PDF_PARSE_STRICT */
- break;
-
default:
- WARN("Unknown PDF object type.");
- result = NULL;
+ if (unknown_handler) {
+ result = unknown_handler(pp, endptr, user_data);
+ } else {
+ WARN("Unknown PDF object type.");
+ result = NULL;
+ }
+ break;
}
return result;
}
+pdf_obj *
+parse_pdf_dict (const char **pp, const char *endptr, pdf_file *pf)
+{
+ return parse_pdf_dict_extended(pp, endptr, pf, NULL, NULL);
+}
+
+pdf_obj *
+parse_pdf_array (const char **pp, const char *endptr, pdf_file *pf)
+{
+ return parse_pdf_array_extended(pp, endptr, pf, NULL, NULL);
+}
+
+pdf_obj *
+parse_pdf_object (const char **pp, const char *endptr, pdf_file *pf)
+{
+ return parse_pdf_object_extended(pp, endptr, pf, NULL, NULL);
+}
+
+
+pdf_obj *
+parse_pdf_tainted_dict (const char **pp, const char *endptr,
+ pdf_obj* (*unknown_handler) (const char **pp,
+ const char *endptr,
+ void *user_data),
+ void *user_data)
+{
+ pdf_obj *result;
+
+ parser_state.tainted = 1;
+ result = parse_pdf_dict_extended(pp, endptr, NULL, unknown_handler, user_data);
+ parser_state.tainted = 0;
+
+ return result;
+}
+
diff --git a/Build/source/texk/dvipdfm-x/pdfparse.h b/Build/source/texk/dvipdfm-x/pdfparse.h
index f55469864c0..52ec95d99fc 100644
--- a/Build/source/texk/dvipdfm-x/pdfparse.h
+++ b/Build/source/texk/dvipdfm-x/pdfparse.h
@@ -1,6 +1,6 @@
/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
- Copyright (C) 2002-2016 by Jin-Hwan Cho and Shunsaku Hirata,
+ Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata,
the dvipdfmx project team.
Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
@@ -48,6 +48,15 @@ extern pdf_obj *parse_pdf_dict (const char **pp, const char *endptr, pdf_file
extern pdf_obj *parse_pdf_array (const char **pp, const char *endptr, pdf_file *pf);
extern pdf_obj *parse_pdf_object (const char **pp, const char *endptr, pdf_file *pf);
-extern pdf_obj *parse_pdf_tainted_dict (const char **pp, const char *endptr);
+extern pdf_obj *parse_pdf_object_extended (const char **pp, const char *endptr, pdf_file *pf,
+ pdf_obj* (*unknown_handler) (const char **pp,
+ const char *endptr,
+ void *user_data),
+ void *user_data);
+extern pdf_obj *parse_pdf_tainted_dict (const char **pp, const char *endptr,
+ pdf_obj* (*unknown_handler) (const char **pp,
+ const char *endptr,
+ void *user_data),
+ void *user_data);
#endif /* _PDFPARSE_H_ */
diff --git a/Build/source/texk/dvipdfm-x/pdfximage.c b/Build/source/texk/dvipdfm-x/pdfximage.c
index e83d29f47fa..50190a2d439 100644
--- a/Build/source/texk/dvipdfm-x/pdfximage.c
+++ b/Build/source/texk/dvipdfm-x/pdfximage.c
@@ -38,7 +38,6 @@
#include "pdfdev.h"
#include "pdfdraw.h"
#include "pdfnames.h"
-#include "specials.h"
#include "epdf.h"
#include "mpost.h"
diff --git a/Build/source/texk/dvipdfm-x/spc_pdfm.c b/Build/source/texk/dvipdfm-x/spc_pdfm.c
index 7d068ba4718..fdb2ac13d68 100644
--- a/Build/source/texk/dvipdfm-x/spc_pdfm.c
+++ b/Build/source/texk/dvipdfm-x/spc_pdfm.c
@@ -59,12 +59,6 @@
#define SPC_PDFM_SUPPORT_ANNOT_TRANS 1
-/* PLEASE REMOVE THIS */
-struct resource_map {
- int type;
- int res_id;
-};
-
struct tounicode {
int cmap_id;
int unescape_backslash;
@@ -86,6 +80,27 @@ static struct spc_pdf_ _pdf_stat = {
NULL
};
+static pdf_obj *
+parse_pdf_reference (const char **start, const char *end, void *user_data)
+{
+ pdf_obj *result = NULL;
+ char *name;
+
+ skip_white(start, end);
+ name = parse_opt_ident(start, end);
+ if (name) {
+ result = spc_lookup_reference(name);
+ if (!result) {
+ WARN("Could not find the named reference (@%s).", name);
+ }
+ RELEASE(name);
+ } else {
+ WARN("Could not find a reference name.");
+ result = NULL;
+ }
+
+ return result;
+}
static int
spc_handler_pdfm__init (void *dp)
@@ -340,7 +355,7 @@ spc_handler_pdfm_put (struct spc_env *spe, struct spc_arg *ap)
}
skip_white(&ap->curptr, ap->endptr);
- obj2 = parse_pdf_object(&ap->curptr, ap->endptr, NULL);
+ obj2 = parse_pdf_object_extended(&ap->curptr, ap->endptr, NULL, parse_pdf_reference, spe);
if (!obj2) {
spc_warn(spe, "Missing (an) object(s) to put into \"%s\"!", ident);
RELEASE(ident);
@@ -386,7 +401,7 @@ spc_handler_pdfm_put (struct spc_env *spe, struct spc_arg *ap)
/* dvipdfm */
pdf_add_array(obj1, pdf_link_obj(obj2));
while (ap->curptr < ap->endptr) {
- pdf_obj *obj3 = parse_pdf_object(&ap->curptr, ap->endptr, NULL);
+ pdf_obj *obj3 = parse_pdf_object_extended(&ap->curptr, ap->endptr, NULL, parse_pdf_reference, spe);
if (!obj3)
break;
pdf_add_array(obj1, obj3);
@@ -577,17 +592,30 @@ parse_pdf_dict_with_tounicode (const char **pp, const char *endptr, struct touni
pdf_obj *dict;
/* disable this test for XDV files, as we do UTF8 reencoding with no cmap */
- if ((dpx_conf.compat_mode != dpx_mode_xdv_mode) && cd->cmap_id < 0)
- return parse_pdf_dict(pp, endptr, NULL);
-
- /* :( */
- if (cd && cd->unescape_backslash)
- dict = parse_pdf_tainted_dict(pp, endptr);
- else {
- dict = parse_pdf_dict(pp, endptr, NULL);
+ if ((dpx_conf.compat_mode != dpx_mode_xdv_mode) && cd->cmap_id < 0) {
+ dict = parse_pdf_object_extended(pp, endptr, NULL, parse_pdf_reference, NULL);
+ if (dict && !PDF_OBJ_DICTTYPE(dict)) {
+ WARN("Dictionary type object expected but non-dictionary type found.");
+ pdf_release_obj(dict);
+ dict = NULL;
+ }
+ } else {
+ /* :( */
+ if (cd && cd->unescape_backslash) {
+ dict = parse_pdf_tainted_dict(pp, endptr, parse_pdf_reference, NULL);
+ } else {
+ dict = parse_pdf_object_extended(pp, endptr, NULL, parse_pdf_reference, NULL);
+ }
+ if (dict) {
+ if (!PDF_OBJ_DICTTYPE(dict)) {
+ WARN("Dictionary type object expected but non-dictionary type found.");
+ pdf_release_obj(dict);
+ dict = NULL;
+ } else {
+ pdf_foreach_dict(dict, modstrings, cd);
+ }
+ }
}
- if (dict)
- pdf_foreach_dict(dict, modstrings, cd);
return dict;
}
@@ -1246,7 +1274,7 @@ spc_handler_pdfm_image (struct spc_env *spe, struct spc_arg *args)
skip_white(&args->curptr, args->endptr);
if (args->curptr < args->endptr) {
- options.dict = parse_pdf_object(&args->curptr, args->endptr, NULL);
+ options.dict = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
}
xobj_id = pdf_ximage_load_image(ident, pdf_string_value(fspec), options);
@@ -1297,7 +1325,7 @@ spc_handler_pdfm_dest (struct spc_env *spe, struct spc_arg *args)
WARN("Failed to convert input string to UTF16...");
#endif
- array = parse_pdf_object(&args->curptr, args->endptr, NULL);
+ array = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
if (!array) {
spc_warn(spe, "No destination specified for pdf:dest.");
pdf_release_obj(name);
@@ -1334,7 +1362,7 @@ spc_handler_pdfm_names (struct spc_env *spe, struct spc_arg *args)
return -1;
}
- tmp = parse_pdf_object(&args->curptr, args->endptr, NULL);
+ tmp = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
if (!tmp) {
spc_warn(spe, "PDF object expected but not found.");
pdf_release_obj(category);
@@ -1369,7 +1397,7 @@ spc_handler_pdfm_names (struct spc_env *spe, struct spc_arg *args)
pdf_release_obj(tmp);
} else if (PDF_OBJ_STRINGTYPE(tmp)) {
key = tmp;
- value = parse_pdf_object(&args->curptr, args->endptr, NULL);
+ value = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
if (!value) {
pdf_release_obj(category);
pdf_release_obj(key);
@@ -1474,7 +1502,7 @@ spc_handler_pdfm_object (struct spc_env *spe, struct spc_arg *args)
return -1;
}
- object = parse_pdf_object(&args->curptr, args->endptr, NULL);
+ object = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
if (!object) {
spc_warn(spe, "Could not find an object definition for \"%s\".", ident);
RELEASE(ident);
@@ -1692,12 +1720,18 @@ spc_handler_pdfm_stream_with_type (struct spc_env *spe, struct spc_arg *args, in
stream_dict = pdf_stream_dict(fstream);
- tmp = parse_pdf_dict(&args->curptr, args->endptr, NULL);
+ tmp = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
if (!tmp) {
spc_warn(spe, "Parsing dictionary failed.");
pdf_release_obj(fstream);
RELEASE(ident);
return -1;
+ } else if (!PDF_OBJ_DICTTYPE(tmp)) {
+ spc_warn(spe, "Expecting dictionary type object but non-dictionary type found.");
+ pdf_release_obj(fstream);
+ pdf_release_obj(tmp);
+ RELEASE(ident);
+ return -1;
}
if (pdf_lookup_dict(tmp, "Length")) {
pdf_remove_dict(tmp, "Length");
@@ -1829,7 +1863,7 @@ spc_handler_pdfm_eform (struct spc_env *spe, struct spc_arg *args)
skip_white(&args->curptr, args->endptr);
if (args->curptr < args->endptr) {
- attrib = parse_pdf_dict(&args->curptr, args->endptr, NULL);
+ attrib = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
if (attrib && !PDF_OBJ_DICTTYPE(attrib)) {
pdf_release_obj(attrib);
attrib = NULL;
@@ -2131,7 +2165,7 @@ spc_handler_pdfm_pageresources (struct spc_env *spe, struct spc_arg *args)
struct spc_pdf_ *sd = &_pdf_stat;
pdf_obj *dict;
- dict = parse_pdf_object(&args->curptr, args->endptr, NULL);
+ dict = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
if (!dict) {
spc_warn(spe, "Dictionary object expected but not found.");
return -1;
@@ -2147,19 +2181,19 @@ spc_handler_pdfm_pageresources (struct spc_env *spe, struct spc_arg *args)
static int
spc_handler_pdfm_bxgstate (struct spc_env *spe, struct spc_arg *args)
{
- pdf_obj *object;
+ pdf_obj *obj;
skip_white(&args->curptr, args->endptr);
- object = parse_pdf_object(&args->curptr, args->endptr, NULL);
- if (!object) {
+ obj = parse_pdf_object_extended(&args->curptr, args->endptr, NULL, parse_pdf_reference, spe);
+ if (!obj) {
spc_warn(spe, "Could not find an object definition.");
return -1;
- } else if (!PDF_OBJ_DICTTYPE(object)) {
+ } else if (!PDF_OBJ_DICTTYPE(obj)) {
spc_warn(spe, "Parsed object for ExtGState not a dictionary object!");
- pdf_release_obj(object);
+ pdf_release_obj(obj);
return -1;
}
- pdf_dev_xgstate_push(object);
+ pdf_dev_xgstate_push(obj);
skip_white(&args->curptr, args->endptr);
diff --git a/Build/source/texk/dvipdfm-x/xbb.c b/Build/source/texk/dvipdfm-x/xbb.c
index fbea47f173c..36e7e895349 100644
--- a/Build/source/texk/dvipdfm-x/xbb.c
+++ b/Build/source/texk/dvipdfm-x/xbb.c
@@ -304,7 +304,7 @@ int extractbb (int argc, char *argv[])
pdf_files_init();
- pdf_set_version(PDF_VERSION_MAX);
+ dpx_conf.is_xbb = 1;
opterr = 0;