w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

t1asm.c
Go to the documentation of this file.
1 /* t1asm
2  *
3  * This program `assembles' Adobe Type-1 font programs in pseudo-PostScript
4  * form into either PFB or PFA format. The human readable/editable input is
5  * charstring- and eexec-encrypted as specified in the `Adobe Type 1 Font
6  * Format' version 1.1 (the `black book'). There is a companion program,
7  * t1disasm, which `disassembles' PFB and PFA files into a pseudo-PostScript
8  * file.
9  *
10  * Copyright (c) 1992 by I. Lee Hetherington, all rights reserved.
11  *
12  * Permission is hereby granted to use, modify, and distribute this program
13  * for any purpose provided this copyright notice and the one below remain
14  * intact.
15  *
16  * I. Lee Hetherington (ilh@lcs.mit.edu)
17  *
18  * Revision 1.2 92/05/22 11:54:45 ilh
19  * Fixed bug where integers larger than 32000 could not be encoded in
20  * charstrings. Now integer range is correct for four-byte
21  * twos-complement integers: -(1<<31) <= i <= (1<<31)-1. Bug detected by
22  * Piet Tutelaers (rcpt@urc.tue.nl).
23  *
24  * Revision 1.1 92/05/22 11:48:46 ilh
25  * initial version
26  *
27  * Ported to Microsoft C/C++ Compiler and MS-DOS operating system by
28  * Kai-Uwe Herbing (herbing@netmbx.netmbx.de) on June 12, 1992. Code
29  * specific to the MS-DOS version is encapsulated with #ifdef _MSDOS
30  * ... #endif, where _MSDOS is an identifier, which is automatically
31  * defined, if you compile with the Microsoft C/C++ Compiler.
32  *
33  */
34 
35 #ifndef lint
36 static char copyright[] =
37  "@(#) Copyright (c) 1992 by I. Lee Hetherington, all rights reserved.";
38 #ifdef _MSDOS
39 static char portnotice[] =
40  "@(#) Ported to MS-DOS by Kai-Uwe Herbing (herbing@netmbx.netmbx.de).";
41 #endif
42 #endif
43 
44 /* Note: this is ANSI C. */
45 
46 #ifdef WIN32
47  #include <fcntl.h>
48  #include <io.h>
49 #endif
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #include <ctype.h>
54 #include <limits.h>
55 
56 #ifdef WINDOWS
57 # ifdef STANDALONE
58 # define WINDOWS_FUNCTIONS
59 # include "winport.h"
60 # endif
61 #endif
62 
63 /* int32 must be at least 32-bit and uint16 must be at least 16-bit */
64 #if INT_MAX >= 0x7FFFFFFFUL
65 typedef int int32;
66 #else
67 typedef long int32;
68 #endif
69 #if USHRT_MAX >= 0xFFFFUL
70 typedef unsigned short uint16;
71 #else
72 typedef unsigned int uint16;
73 #endif
74 
75 #define LINESIZE 256
76 
77 #define MAXBLOCKLEN ((1L<<17)-6)
78 #define MINBLOCKLEN ((1L<<8)-6)
79 
80 #define MARKER 128
81 #define ASCII 1
82 #define BINARY 2
83 #define DONE 3
84 
85 typedef unsigned char byte;
86 
87 /* must be visible from outside */
90 
91 /* flags */
92 static int pfb = 0;
93 static int active = 0;
94 static int start_charstring = 0;
95 static int in_eexec = 0;
96 
97 static char line[LINESIZE];
98 
99 /* lenIV and charstring start command */
100 static int lenIV = 4;
101 static char cs_start[10];
102 
103 /* for charstring buffering */
104 static byte charstring_buf[65535];
105 static byte *charstring_bp;
106 
107 /* for PFB block buffering */
108 static byte blockbuf[MAXBLOCKLEN];
110 static int32 blockpos = -1;
111 static int blocktyp = ASCII;
112 
113 /* decryption stuff */
114 static uint16 er, cr;
115 static uint16 c1 = 52845, c2 = 22719;
116 
117 /* table of charstring commands */
118 static struct command {
119  char *name;
120  int one, two;
121 } command_table[] = {
122  { "callothersubr", 12, 16 },
123  { "callsubr", 10, -1 },
124  { "closepath", 9, -1 },
125  { "div", 12, 12 },
126  { "dotsection", 12, 0 },
127  { "endchar", 14, -1 },
128  { "hlineto", 6, -1 },
129  { "hmoveto", 22, -1 },
130  { "hsbw", 13, -1 },
131  { "hstem", 1, -1 },
132  { "hstem3", 12, 2 },
133  { "hvcurveto", 31, -1 },
134  { "pop", 12, 17 },
135  { "return", 11, -1 },
136  { "rlineto", 5, -1 },
137  { "rmoveto", 21, -1 },
138  { "rrcurveto", 8, -1 },
139  { "sbw", 12, 7 },
140  { "seac", 12, 6 },
141  { "setcurrentpoint", 12, 33 },
142  { "vhcurveto", 30, -1 },
143  { "vlineto", 7, -1 },
144  { "vmoveto", 4, -1 },
145  { "vstem", 3, -1 },
146  { "vstem3", 12, 1 },
147 }; /* alphabetical */
148 
149 /* Two separate encryption functions because eexec and charstring encryption
150  must proceed in parallel. */
151 
152 static byte eencrypt(byte plain)
153 {
154  byte cipher;
155 
156  cipher = (byte) (plain ^ (er >> 8));
157  er = (uint16) ((cipher + er) * c1 + c2);
158  return cipher;
159 }
160 
161 static byte cencrypt(byte plain)
162 {
163  byte cipher;
164 
165  cipher = (byte) (plain ^ (cr >> 8));
166  cr = (uint16) ((cipher + cr) * c1 + c2);
167  return cipher;
168 }
169 
170 /* This function flushes a buffered PFB block. */
171 
172 static void output_block()
173 {
174  int32 i;
175 
176  /* output four-byte block length */
177  fputc((int) (blockpos & 0xff), ofp);
178  fputc((int) ((blockpos >> 8) & 0xff), ofp);
179  fputc((int) ((blockpos >> 16) & 0xff), ofp);
180  fputc((int) ((blockpos >> 24) & 0xff), ofp);
181 
182  /* output block data */
183  for (i = 0; i < blockpos; i++)
184  fputc(blockbuf[i], ofp);
185 
186  /* mark block buffer empty and uninitialized */
187  blockpos = -1;
188 }
189 
190 /* This function outputs a single byte. If output is in PFB format then output
191  is buffered through blockbuf[]. If output is in PFA format, then output
192  will be hexadecimal if in_eexec is set, ASCII otherwise. */
193 
194 static void output_byte(byte b)
195 {
196  static char *hexchar = "0123456789ABCDEF";
197  static int hexcol = 0;
198 
199  if (pfb) {
200  /* PFB */
201  if (blockpos < 0) {
202  fputc(MARKER, ofp);
203  fputc(blocktyp, ofp);
204  blockpos = 0;
205  }
206  blockbuf[blockpos++] = b;
207  if (blockpos == blocklen)
208  output_block();
209  } else {
210  /* PFA */
211  if (in_eexec) {
212  /* trim hexadecimal lines to 64 columns */
213  if (hexcol >= 64) {
214  fputc('\n', ofp);
215  hexcol = 0;
216  }
217  fputc(hexchar[(b >> 4) & 0xf], ofp);
218  fputc(hexchar[b & 0xf], ofp);
219  hexcol += 2;
220  } else {
221  fputc(b, ofp);
222  }
223  }
224 }
225 
226 /* This function outputs a byte through possible eexec encryption. */
227 
228 static void eexec_byte(byte b)
229 {
230  if (in_eexec)
232  else
233  output_byte(b);
234 }
235 
236 /* This function outputs a null-terminated string through possible eexec
237  encryption. */
238 
239 static void eexec_string(char *string)
240 {
241  while (*string)
242  eexec_byte((byte) *string++);
243 }
244 
245 /* This function gets ready for the eexec-encrypted data. If output is in
246  PFB format then flush current ASCII block and get ready for binary block.
247  We start encryption with four random (zero) bytes. */
248 
249 static void eexec_start()
250 {
252  if (pfb) {
253  output_block();
254  blocktyp = BINARY;
255  }
256 
257  in_eexec = 1;
258  er = 55665;
259  eexec_byte(0);
260  eexec_byte(0);
261  eexec_byte(0);
262  eexec_byte(0);
263 }
264 
265 /* This function wraps-up the eexec-encrypted data.
266  If output is in PFB format then this entails flushing binary block and
267  starting an ASCII block. */
268 
269 static void eexec_end()
270 {
271  int i, j;
272 
273  if (pfb) {
274  output_block();
275  blocktyp = ASCII;
276  } else {
277  fputc('\n', ofp);
278  }
279  in_eexec = 0;
280  for (i = 0; i < 8; i++) {
281  for (j = 0; j < 64; j++)
282  eexec_byte('0');
283  eexec_byte('\n');
284  }
285 #if 0
286  eexec_string("cleartomark\n");
287 #endif
288 }
289 
290 /* This function writes ASCII trailer.
291  If output is in PFB format then this entails flushing binary block and
292  starting an ASCII block. */
293 
294 static void file_end()
295 {
296  if (pfb) {
297  output_block();
298  fputc(MARKER, ofp);
299  fputc(DONE, ofp);
300  }
301 }
302 /* This function returns an input line of characters. A line is terminated by
303  length (including terminating null) greater than LINESIZE, a newline \n, or
304  when active (looking for charstrings) by '{'. When terminated by a newline
305  the newline is put into line[]. When terminated by '{', the '{' is not put
306  into line[], and the flag start_charstring is set to 1. */
307 
308 static void t1asm_getline()
309 {
310  int c;
311  char *p = line;
312  int comment = 0;
313 
314  start_charstring = 0;
315  while (p < line + LINESIZE) {
316  c = fgetc(ifp);
317  if (c == EOF)
318  break;
319  if (c == '%')
320  comment = 1;
321  if (active && !comment && c == '{') {
322  start_charstring = 1;
323  break;
324  }
325  *p++ = (char) c;
326  if (c == '\n')
327  break;
328  }
329  *p = '\0';
330 }
331 
332 /* This function is used by the binary search, bsearch(), for command names in
333  the command table. */
334 
335 static int command_compare(const void *key, const void *item)
336 {
337  return strcmp((char *) key, ((struct command *) item)->name);
338 }
339 
340 /* This function returns 1 if the string is an integer and 0 otherwise. */
341 
342 static int is_integer(char *string)
343 {
344  if (isdigit(string[0]) || string[0] == '-' || string[0] == '+') {
345  while (*++string && isdigit(*string))
346  ; /* deliberately empty */
347  if (!*string)
348  return 1;
349  }
350  return 0;
351 }
352 
353 /* This function initializes charstring encryption. Note that this is called
354  at the beginning of every charstring. */
355 
356 static void charstring_start()
357 {
358  int i;
359 
361  cr = 4330;
362  for (i = 0; i < lenIV; i++)
363  *charstring_bp++ = cencrypt((byte) 0);
364 }
365 
366 /* This function encrypts and buffers a single byte of charstring data. */
367 
368 static void charstring_byte(int v)
369 {
370  byte b = (byte) (v & 0xff);
371 
372  if (charstring_bp - charstring_buf > sizeof(charstring_buf)) {
373  fprintf(stderr, "error: charstring_buf full (%zd bytes)\n",
374  sizeof(charstring_buf));
375  exit(1);
376  }
377  *charstring_bp++ = cencrypt(b);
378 }
379 
380 /* This function outputs buffered, encrypted charstring data through possible
381  eexec encryption. */
382 
383 static void charstring_end()
384 {
385  byte *bp;
386 
389  sprintf(line, "%s ", cs_start);
391  for (bp = charstring_buf; bp < charstring_bp; bp++)
392  eexec_byte(*bp);
393 }
394 
395 /* This function generates the charstring representation of an integer. */
396 
397 static void charstring_int(int num)
398 {
399  int x;
400 
401  if (num >= -107 && num <= 107) {
402  charstring_byte(num + 139);
403  } else if (num >= 108 && num <= 1131) {
404  x = num - 108;
405  charstring_byte(x / 256 + 247);
406  charstring_byte(x % 256);
407  } else if (num >= -1131 && num <= -108) {
408  x = abs(num) - 108;
409  charstring_byte(x / 256 + 251);
410  charstring_byte(x % 256);
411  } else if (num >= (-2147483647-1) && num <= 2147483647) {
412  charstring_byte(255);
413  charstring_byte(num >> 24);
414  charstring_byte(num >> 16);
415  charstring_byte(num >> 8);
417  } else {
418  fprintf(stderr,
419  "error: cannot format the integer %d, too large\n", num);
420  exit(1);
421  }
422 }
423 
424 /* This function parses an entire charstring into integers and commands,
425  outputting bytes through the charstring buffer. */
426 
427 static void parse_charstring()
428 {
429  struct command *cp;
430 
432  while (fscanf(ifp, "%s", line) == 1) {
433  if (line[0] == '%') {
434  /* eat comment to end of line */
435  while (fgetc(ifp) != '\n' && !feof(ifp))
436  ; /* deliberately empty */
437  continue;
438  }
439  if (line[0] == '}')
440  break;
441  if (is_integer(line)) {
443  } else {
444  cp = (struct command *)
445  bsearch((void *) line, (void *) command_table,
446  sizeof(command_table) / sizeof(struct command),
447  sizeof(struct command),
449  if (cp) {
450  charstring_byte(cp->one);
451  if (cp->two >= 0)
452  charstring_byte(cp->two);
453  } else {
454  fprintf(stderr, "error: cannot use `%s' in charstring\n",line);
455  exit(1);
456  }
457  }
458  }
459  charstring_end();
460 }
461 
462 static void usage()
463 {
464  fprintf(stderr,
465  "usage: t1asm [-b] [-l block-length] [input [output]]\n");
466  fprintf(stderr,
467  "\n-b means output in PFB format, otherwise PFA format.\n");
468  fprintf(stderr,
469  "The block length applies to the length of blocks in the\n");
470  fprintf(stderr,
471  "PFB output file; the default is to use the largest possible.\n");
472  exit(1);
473 }
474 
475 static void print_banner()
476 {
477  static char rcs_revision[] = ""; /* removed RCS */
478  static char revision[20];
479 
480  if (sscanf(rcs_revision, "$Revision: %19s", revision) != 1)
481  revision[0] = '\0';
482  fprintf(stderr, "This is t1asm %s.\n", revision);
483 }
484 
485 #ifdef STANDALONE
486 int main(int argc, char **argv)
487 {
488  char *p, *q, *r;
489  int c;
490 
491  extern char *optarg;
492  extern int optind;
493 
494  ifp = stdin;
495  ofp = stdout;
496 
497  print_banner();
498 
499  /* interpret command line arguments using getopt */
500  while ((c = getopt(argc, argv, "bl:")) != -1)
501  switch (c) {
502  case 'b':
503  pfb = 1;
504  break;
505  case 'l':
506  blocklen = atoi(optarg);
507  if (blocklen < MINBLOCKLEN) {
509  fprintf(stderr,
510  "warning: using minimum block length of %d\n",
511  blocklen);
512  } else if (blocklen > MAXBLOCKLEN) {
514  fprintf(stderr,
515  "warning: using maximum block length of %d\n",
516  blocklen);
517  }
518  break;
519  default:
520  usage();
521  break;
522  }
523  if (argc - optind > 2)
524  usage();
525 
526  /* possibly open input & output files */
527  if (argc - optind >= 1) {
528  ifp = fopen(argv[optind], "r");
529  if (!ifp) {
530  fprintf(stderr, "error: cannot open %s for reading\n", argv[1]);
531  exit(1);
532  }
533  }
534  if (argc - optind >= 2) {
535  ofp = fopen(argv[optind + 1], "wb");
536  if (!ofp) {
537  fprintf(stderr, "error: cannot open %s for writing\n", argv[2]);
538  exit(1);
539  }
540  }
541 
542 #else
544 {
545  char *p, *q, *r;
546 
547  pfb = pfbflag;
548 #endif
549 
550  #ifdef WINDOWS
551  /* If we are processing a PFB (binary) output */
552  /* file, we must set its file mode to binary. */
553  if(pfb)
554  _setmode(_fileno(ofp), _O_BINARY);
555  #endif
556 
557  /* Finally, we loop until no more input. Some special things to look for
558  are the `currentfile eexec' line, the beginning of the `/Subrs'
559  definition, the definition of `/lenIV', and the definition of the
560  charstring start command which has `...string currentfile...' in it. */
561 
562  while (!feof(ifp) && !ferror(ifp)) {
563  t1asm_getline();
564  if (strcmp(line, "currentfile eexec\n") == 0) {
565  eexec_start();
566  continue;
567  } else if (strstr(line, "/Subrs") && isspace(line[6])) {
568  active = 1;
569  } else if ((p = strstr(line, "/lenIV"))) {
570  sscanf(p, "%*s %d", &lenIV);
571  } else if ((p = strstr(line, "string currentfile"))) {
572  /* locate the name of the charstring start command */
573  *p = '\0'; /* damage line[] */
574  q = strrchr(line, '/');
575  if (q) {
576  r = cs_start;
577  ++q;
578  while (!isspace(*q) && *q != '{')
579  *r++ = *q++;
580  *r = '\0';
581  }
582  *p = 's'; /* repair line[] */
583  }
584  /* output line data */
586  if ((p = strstr(line, "currentfile closefile"))) {
587  eexec_end();
588  }
589  if (start_charstring) {
590  if (!cs_start[0]) {
591  fprintf(stderr, "error: couldn't find charstring start command\n");
592  exit(1);
593  }
595  }
596  }
597  file_end();
598 
599  fclose(ifp);
600  fclose(ofp);
601 
602  return 0;
603 }
void *__cdecl bsearch(void const *_Key, void const *_Base, size_t _NumOfElements, size_t _SizeOfElements, _CoreCrtNonSecureSearchSortCompareFunction _CompareFunction)
bp
Definition: action.c:1035
cp
Definition: action.c:1035
q
Definition: afm2pl.c:2287
#define name
static int item
Definition: brushtopbm.c:66
#define b
Definition: jpegint.h:372
#define strrchr
Definition: detex.c:67
int v
Definition: dviconv.c:10
#define fopen
Definition: xxstdio.h:21
#define fgetc
Definition: xxstdio.h:26
int strcmp()
Definition: coll.cpp:143
int sscanf()
static char rcs_revision[]
Definition: dvihp.c:33
void revision(void)
Definition: fmtutil.c:158
#define c(n)
Definition: gpos-common.c:150
char comment[255+1]
Definition: hbf2gf.c:350
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
sizeof(AF_ModuleRec)
void exit()
#define EOF
Definition: afmparse.c:59
int getopt(int nargc, char *const nargv[], const char *ostr)
Definition: getopt.c:53
int optind
Definition: getopt.c:39
char * optarg
Definition: getopt.c:42
int atoi(const char *)
int num
Definition: disdvi.c:621
char * strstr()
#define fclose
Definition: debug.h:100
#define fprintf
Definition: mendex.h:64
#define sprintf
Definition: snprintf.c:44
#define isdigit(c)
Definition: snprintf.c:177
unsigned short uint16
Definition: tiff.h:62
long int32
Definition: tiff.h:67
#define _O_BINARY
Definition: lfs.c:127
float x
Definition: cordic.py:15
#define abs(a)
Definition: pbmplus.h:225
int r
Definition: ppmqvga.c:68
#define isspace(ch)
Definition: utype.h:87
int two
Definition: type1asm.c:88
int one
Definition: type1asm.c:88
char * name
Definition: type1asm.c:87
Definition: bdf.c:133
static int hexcol
Definition: t1ascii.c:141
#define FILE
Definition: t1stdio.h:34
#define feof(f)
Definition: t1stdio.h:109
#define ferror(f)
Definition: t1stdio.h:110
int j
Definition: t4ht.c:1589
#define key
Definition: tex2xindy.c:753
#define LINESIZE
Definition: t1asm.c:75
unsigned short uint16
Definition: t1asm.c:70
unsigned char byte
Definition: t1asm.c:85
static struct command command_table[]
static int is_integer(char *string)
Definition: t1asm.c:342
static int32 blocklen
Definition: t1asm.c:109
#define MARKER
Definition: t1asm.c:80
static void eexec_byte(byte b)
Definition: t1asm.c:228
static void charstring_int(int num)
Definition: t1asm.c:397
static int in_eexec
Definition: t1asm.c:95
int runt1asm(int pfbflag)
Definition: t1asm.c:543
static uint16 cr
Definition: t1asm.c:114
static void charstring_end()
Definition: t1asm.c:383
static void output_block()
Definition: t1asm.c:172
static void eexec_string(char *string)
Definition: t1asm.c:239
static void eexec_end()
Definition: t1asm.c:269
static byte cencrypt(byte plain)
Definition: t1asm.c:161
int int32
Definition: t1asm.c:65
static void parse_charstring()
Definition: t1asm.c:427
#define ASCII
Definition: t1asm.c:81
FILE * ofp
Definition: t1asm.c:89
FILE * ifp
Definition: t1asm.c:88
static void usage()
Definition: t1asm.c:462
static byte charstring_buf[65535]
Definition: t1asm.c:104
static void output_byte(byte b)
Definition: t1asm.c:194
static int start_charstring
Definition: t1asm.c:94
static byte eencrypt(byte plain)
Definition: t1asm.c:152
static int blocktyp
Definition: t1asm.c:111
static int pfb
Definition: t1asm.c:92
static void print_banner()
Definition: t1asm.c:475
static void charstring_byte(int v)
Definition: t1asm.c:368
static uint16 er
Definition: t1asm.c:114
static byte * charstring_bp
Definition: t1asm.c:105
static uint16 c1
Definition: t1asm.c:115
static int32 blockpos
Definition: t1asm.c:110
static void file_end()
Definition: t1asm.c:294
static void charstring_start()
Definition: t1asm.c:356
static int active
Definition: t1asm.c:93
#define MINBLOCKLEN
Definition: t1asm.c:78
static char cs_start[10]
Definition: t1asm.c:101
static char copyright[]
Definition: t1asm.c:36
static byte blockbuf[((1L<< 17) -6)]
Definition: t1asm.c:108
#define DONE
Definition: t1asm.c:83
static void eexec_start()
Definition: t1asm.c:249
static void t1asm_getline()
Definition: t1asm.c:308
static int command_compare(const void *key, const void *item)
Definition: t1asm.c:335
static char line[256]
Definition: t1asm.c:97
#define BINARY
Definition: t1asm.c:82
static uint16 c2
Definition: t1asm.c:115
static int lenIV
Definition: t1asm.c:100
#define MAXBLOCKLEN
Definition: t1asm.c:77
int pfbflag
Definition: ttf2pt1.c:117
int main(int argc, char *argv[])
Definition: t1asm.c:625
#define argv
Definition: xmain.c:270
#define argc
Definition: xmain.c:269