[pdftex] Patch for pdftex for subsetted font printing problem

Tom Kacvinsky tjk at ams.org
Fri Jun 15 22:10:56 CEST 2001


Hi all,

Attached is a patch for pdftex 3.14159-14h-released-20010417 that fixes the
following problem:

  PDF files generated by pdftex in which Type 1 fonts are subsetted do
  not print correctly from Acrobat (Reader) 5.0.

Having been down this road before (sending a patch in for pdftex whilst
Thanh is away), I feel compelled to state that this patch is for those who
want to use it, and I am not asking for it to be the definitive, official
fix for this problem.

With that said, the patch just simply fills in the gaps in the Subrs array
with subroutines do nothing.  This does not yield the smallest possible
subsetted font. To do that, one needs to renumber all of the subroutines,
and make sure the charstrings which call these renumbered subroutines use
the new numbers, etc...

The limited tests I have run indicate the patch does work and does not
introduce any new bugs.  Comments and more testing would be appreciated.

Regards,

Tom
-------------- next part --------------
*** /tmp/T0U3aimV	Fri Jun 15 20:59:40 2001
--- writet1.c	Fri Jun 15 20:54:25 2001
***************
*** 199,205 ****
  
  static unsigned short t1_dr, t1_er;
  static unsigned short t1_c1 = 52845, t1_c2 = 22719;
! static unsigned short t1_cslen, t1_lenIV;
  static char t1_line[T1_BUF_SIZE], t1_buf[T1_BUF_SIZE], *t1_line_ptr;
  static char enc_line[ENC_BUF_SIZE];
  
--- 199,206 ----
  
  static unsigned short t1_dr, t1_er;
  static unsigned short t1_c1 = 52845, t1_c2 = 22719;
! 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,218 ****
--- 214,226 ----
  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[2][2] = { {"RD", "NP"}, {"-|", "|"} };
+ 
+ /* Which begin/end token set do we use for the font? */
+ static int  cs_token_choice = 0;
+ 
  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;
***************
*** 417,422 ****
--- 425,437 ----
      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);
***************
*** 485,490 ****
--- 500,512 ----
              break;
          if (t1_cs && t1_cslen == 0 && (t1_line_ptr - t1_line > 4) && 
             (t1_suffix(" RD ") || t1_suffix(" -| "))) {
+            
+             /* Modify this as necessary, for other begin/end token pairs. */
+             if (t1_suffix(" RD "))
+               cs_token_choice = 0;
+             else if (t1_suffix(" -| "))
+               cs_token_choice = 1;
+               
              p = t1_line_ptr - 5;
              while (*p != ' ')
                  p--;
***************
*** 1447,1462 ****
  static void t1_flush_cs(boolean is_subr)
  {
      char *p;
      cs_entry *tab, *end_tab, *ptr;
      char *start_line, *line_end;
      int count, size_pos;
      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;
      }
      else {
          start_line = cs_dict_start;
--- 1469,1486 ----
  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;
          count = subr_max + 1;
+         end_tab = subr_tab + count;
      }
      else {
          start_line = cs_dict_start;
***************
*** 1475,1481 ****
--- 1499,1521 ----
      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,1491 ****
--- 1526,1544 ----
              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);


More information about the pdftex mailing list