[pdftex] writet1, part n for large n
Tom Kacvinsky
tjk at ams.org
Tue Jun 26 14:36:56 CEST 2001
OK,
Some testing by Hans Hagen and Tom Kiffe pointed out a bug in the
patch I had submitted. So here is a new one that fixes the problem.
This time, I am sure the patch works right... :)
Hans' test files points out another bug in Acrobat 5.0. The problem is
when one uses pdftex to include another PDF file. The font resources
are scanned over, and sometimes a Type 1 font is written into the PDF
file with an encoding array that looks like this:
/Enoding 256 array
0 1 255 {1 index /.notdef exch put} for
readonly def
Acrobat 5.0 does not like this. I will try to come up with a fix this
weekend.
Tom
-------------- next part --------------
--- writet1.c 2001/06/15 22:54:57 1.1
+++ writet1.c 2001/06/22 14:40:39 1.7
@@ -199,7 +199,8 @@
static unsigned short t1_dr, t1_er;
static unsigned short t1_c1 = 52845, t1_c2 = 22719;
-static unsigned short t1_cslen, t1_lenIV;
+static unsigned short t1_cslen;
+static short t1_lenIV;
static char t1_line[T1_BUF_SIZE], t1_buf[T1_BUF_SIZE], *t1_line_ptr;
static char enc_line[ENC_BUF_SIZE];
@@ -213,6 +214,19 @@
static char *subr_array_start, *subr_array_end;
static int subr_max, subr_size, subr_size_pos;
+/* This array contains the begin/end tokens commonly used in the */
+/* /Subrs array of a Type 1 font. */
+static char *cs_token_pairs[4][2] = {
+ {"RD", "NP"},
+ {"-|", "|"},
+ {"RD", "noaccess put"},
+ {"-|", "noaccess put"}
+};
+
+/* Which begin/end token set do we use for the font? */
+static int cs_token_choice = -1;
+static boolean cs_tokens_found = false;
+
static boolean t1_pfa, t1_cs, t1_scan, t1_eexec_encrypt, t1_synthetic;
static int t1_in_eexec; /* 0 before eexec-encrypted, 1 during, 2 after */
static long t1_block_length;
@@ -222,6 +236,7 @@
#define str_prefix(s1, s2) (strncmp(s1, s2, strlen(s2)) == 0)
#define t1_prefix(s) str_prefix(t1_line, s)
+#define t1_buf_prefix(s) str_prefix(t1_buf, s)
#define t1_charstrings() strstr(t1_line, "/CharStrings")
#define t1_subrs() t1_prefix("/Subrs")
#define t1_end_eexec() t1_suffix("mark currentfile closefile")
@@ -417,6 +432,13 @@
return cipher;
}
+static byte cencrypt(byte plain, unsigned short *cr)
+{
+ byte cipher = (plain^(*cr >> 8));
+ *cr = (cipher + *cr)*t1_c1 + t1_c2;
+ return cipher;
+}
+
static char *eol(char *s)
{
char *p = strend(s);
@@ -456,6 +478,19 @@
return s1 >= t1_line - 1;
}
+static boolean t1_buf_suffix(char *s, char *r)
+{
+ char *s1 = r - 1,
+ *s2 = strend(s) - 1;
+ if (*s1 == 10)
+ s1--;
+ while (s1 >= t1_buf && s2 >= s) {
+ if (*s1-- != *s2--)
+ return false;
+ }
+ return s1 >= t1_buf - 1;
+}
+
static void t1_getline(void)
{
int c, l, eexec_scan;
@@ -1055,10 +1090,22 @@
else
ptr->name = xstrdup(t1_buf + 1);
}
- memcpy(t1_buf, cs_start - 4, (unsigned)(t1_cslen + 4)); /* copy " RD " + cs data to t1_buf */
- for (p = cs_start + t1_cslen, q = t1_buf + t1_cslen + 4; *p != 10; *q++ = *p++);
+ /* copy " RD " + cs data to t1_buf */
+ memcpy(t1_buf, cs_start - 4, (unsigned)(t1_cslen + 4));
/* copy the end of cs data to t1_buf */
- *q++ = 10;
+ for (p = cs_start + t1_cslen, q = t1_buf + t1_cslen + 4; *p != 10; *q++ = *p++);
+ *q++ = 10;
+ /* get the begin/end token pairs. Modify this as necessary for other token pairs. */
+ if (is_subr && !cs_tokens_found) {
+ if (t1_buf_prefix(" RD") && t1_buf_suffix("NP", q))
+ { cs_token_choice = 0; cs_tokens_found = true; }
+ else if (t1_buf_prefix(" -|") && t1_buf_suffix("|", q))
+ { cs_token_choice = 1; cs_tokens_found = true; }
+ else if (t1_buf_prefix(" RD") && t1_buf_suffix("noaccess put", q))
+ { cs_token_choice = 2; cs_tokens_found = true; }
+ else if (t1_buf_prefix(" -|") && t1_buf_suffix("noaccess put", q))
+ { cs_token_choice = 3; cs_tokens_found = true; }
+ }
ptr->len = q - t1_buf;
ptr->cslen = t1_cslen;
ptr->data = xtalloc(ptr->len, byte);
@@ -1447,16 +1494,18 @@
static void t1_flush_cs(boolean is_subr)
{
char *p;
+ byte *r, return_cs[T1_BUF_SIZE];
cs_entry *tab, *end_tab, *ptr;
char *start_line, *line_end;
int count, size_pos;
+ unsigned short cr, cs_len;
if (is_subr) {
start_line = subr_array_start;
line_end = subr_array_end;
size_pos = subr_size_pos;
tab = subr_tab;
- end_tab = subr_tab + subr_size;
count = subr_max + 1;
+ end_tab = subr_tab + count;
}
else {
start_line = cs_dict_start;
@@ -1475,7 +1524,23 @@
strcat(t1_line_ptr, p);
t1_line_ptr = eol(t1_line);
t1_putline();
+
+ if (is_subr) {
+ cr = 4330;
+ cs_len = 0;
+ if (t1_lenIV >= 0) {
+ for (cs_len = 0, r = return_cs; cs_len < t1_lenIV; cs_len++, r++)
+ *r = cencrypt(0x00, &cr);
+ *r = cencrypt(CS_RETURN, &cr);
+ }
+ else {
+ *return_cs = CS_RETURN;
+ }
+ cs_len++;
+ }
+
for (ptr = tab; ptr < end_tab; ptr++) {
+
if (ptr->used) {
if (is_subr)
sprintf(t1_line, "dup %u %u", ptr - tab, ptr->cslen);
@@ -1486,6 +1551,19 @@
t1_line_ptr = p + ptr->len;
t1_putline();
}
+ else {
+ if (is_subr) {
+ sprintf(t1_line, "dup %u %u %s ", ptr - tab, cs_len,
+ cs_token_pairs[cs_token_choice][0]);
+ p = strend(t1_line);
+ memcpy(p, return_cs, cs_len);
+ t1_line_ptr = p + cs_len;
+ t1_putline();
+ sprintf(t1_line, " %s", cs_token_pairs[cs_token_choice][1]);
+ t1_line_ptr = eol(t1_line);
+ t1_putline();
+ }
+ }
xfree(ptr->data);
if (ptr->name != 0 && ptr->name != notdef)
xfree(ptr->name);
@@ -1493,6 +1571,10 @@
sprintf(t1_line, "%s", line_end);
t1_line_ptr = eol(t1_line);
t1_putline();
+ if (is_subr) {
+ cs_token_choice = -1;
+ cs_tokens_found = false;
+ }
xfree(tab);
xfree(start_line);
xfree(line_end);
@@ -1563,8 +1645,11 @@
}
cs_dict_end = xstrdup(t1_line);
t1_mark_glyphs();
- if (subr_tab != 0)
+ if (subr_tab != 0) {
+ if (cs_token_choice == -1)
+ pdftex_fail("This Type 1 font uses mismatched subroutine begin/end token pairs.");
t1_subr_flush();
+ }
for (cs_count = 0, ptr = cs_tab; ptr < cs_ptr; ptr++)
if (ptr->used)
cs_count++;
More information about the pdftex
mailing list