[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/libraries/tcpdf/fonts/ttf2ufm/ttf2ufm-src/ -> t1asm.c (source)

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


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1