summaryrefslogtreecommitdiff
path: root/Build/source/utils/t1utils/t1utils-src/t1disasm.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/t1utils/t1utils-src/t1disasm.c')
-rw-r--r--Build/source/utils/t1utils/t1utils-src/t1disasm.c760
1 files changed, 0 insertions, 760 deletions
diff --git a/Build/source/utils/t1utils/t1utils-src/t1disasm.c b/Build/source/utils/t1utils/t1utils-src/t1disasm.c
deleted file mode 100644
index 4382f6839b7..00000000000
--- a/Build/source/utils/t1utils/t1utils-src/t1disasm.c
+++ /dev/null
@@ -1,760 +0,0 @@
-/* t1disasm
- *
- * This program `disassembles' Adobe Type-1 font programs in either PFB or PFA
- * format. It produces a human readable/editable pseudo-PostScript file by
- * performing eexec and charstring decryption as specified in the `Adobe Type 1
- * Font Format' version 1.1 (the `black book'). There is a companion program,
- * t1asm, which `assembles' such a pseudo-PostScript file into either PFB or
- * PFA format.
- *
- * Copyright (c) 1992 by I. Lee Hetherington, all rights reserved.
- * Copyright (c) 1998-2017 Eddie Kohler
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, subject to the
- * conditions listed in the Click LICENSE file, which is available in full at
- * http://github.com/kohler/click/blob/master/LICENSE. The conditions
- * include: you must preserve this copyright notice, and you cannot mention
- * the copyright holders in advertising related to the Software without
- * their permission. The Software is provided WITHOUT ANY WARRANTY, EXPRESS
- * OR IMPLIED. This notice is a summary of the Click LICENSE file; the
- * license in that file is binding.
- *
- * New change log in `NEWS'. Old change log:
- *
- * Revision 1.4 92/07/10 10:55:08 ilh
- * Added support for additional PostScript after the closefile command
- * (ie., some fonts have {restore}if' after the cleartomark). Also,
- * removed hardwired charstring start command (-| or RD) in favor of
- * automatically determining it.
- *
- * Revision 1.3 92/06/23 10:57:53 ilh
- * MSDOS porting by Kai-Uwe Herbing (herbing@netmbx.netmbx.de)
- * incoporated.
- *
- * Revision 1.2 92/05/22 12:05:33 ilh
- * Fixed bug where we were counting on sprintf to return its first
- * argument---not true in ANSI C. This bug was detected by Piet
- * Tutelaers (rcpt@urc.tue.nl). Also, fixed (signed) integer overflow
- * error when testing high-order bit of integer for possible
- * sign-extension by making comparison between unsigned integers.
- *
- * Revision 1.1 92/05/22 12:04:07 ilh
- * initial version
- *
- * Ported to Microsoft C/C++ Compiler and MS-DOS operating system by
- * Kai-Uwe Herbing (herbing@netmbx.netmbx.de) on June 12, 1992. Code
- * specific to the MS-DOS version is encapsulated with #ifdef _MSDOS
- * ... #endif, where _MSDOS is an identifier, which is automatically
- * defined, if you compile with the Microsoft C/C++ Compiler.
- *
- */
-
-/* Note: this is ANSI C. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-#if defined(_MSDOS) || defined(_WIN32)
-# include <fcntl.h>
-# include <io.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <assert.h>
-#include <lcdf/clp.h>
-#include "t1lib.h"
-#include "t1asmhelp.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef unsigned char byte;
-
-static FILE *ofp;
-static int unknown = 0;
-
-/* decryption stuff */
-static const uint32_t c1 = 52845;
-static const uint32_t c2 = 22719;
-static uint16_t cr_default = 4330;
-static uint16_t er_default = 55665;
-
-static int error_count = 0;
-
-
-/* Subroutine to output strings. */
-
-static void
-output(const char *string)
-{
- fprintf(ofp, "%s", string);
-}
-
-/* Subroutine to neatly format output of charstring tokens. If token = "\n",
- then a newline is output. If at start of line (start == 1), prefix token
- with tab, otherwise a space. */
-
-static void
-output_token(const char *token)
-{
- static int start = 1;
- if (strcmp(token, "\n") == 0) {
- fprintf(ofp, "\n");
- start = 1;
- } else {
- fprintf(ofp, "%s%s", start ? "\t" : " ", token);
- start = 0;
- }
-}
-
-/* Subroutine to decrypt and ASCII-ify tokens in charstring data. The
- charstring decryption machinery is fired up, skipping the first lenIV
- bytes, and the decrypted tokens are expanded into human-readable form. */
-
-static void
-decrypt_charstring(unsigned char *line, int len)
-{
- int i;
- int32_t val;
- char buf[20];
-
- /* decrypt charstring */
- if (lenIV >= 0) {
- /* only decrypt if lenIV >= 0 -- negative lenIV means unencrypted
- charstring. Thanks to Tom Kacvinsky <tjk@ams.org> */
- uint16_t cr = cr_default;
- byte plain;
- for (i = 0; i < len; i++) {
- byte cipher = line[i];
- plain = (byte)(cipher ^ (cr >> 8));
- cr = (uint16_t)((cipher + cr) * c1 + c2);
- line[i] = plain;
- }
- line += lenIV;
- len -= lenIV;
- }
-
- /* handle each charstring command */
- for (i = 0; i < len; i++) {
- byte b = line[i];
-
- if (b >= 32) {
- if (b >= 32 && b <= 246)
- val = b - 139;
- else if (b >= 247 && b <= 250) {
- i++;
- val = (b - 247)*256 + 108 + line[i];
- } else if (b >= 251 && b <= 254) {
- i++;
- val = -(b - 251)*256 - 108 - line[i];
- } else {
- uint32_t uval;
- uval = (uint32_t) line[i+1] << 24;
- uval |= (uint32_t) line[i+2] << 16;
- uval |= (uint32_t) line[i+3] << 8;
- uval |= (uint32_t) line[i+4] << 0;
- /* in case an int32 is larger than four bytes---sign extend */
-#if INT_MAX > 0x7FFFFFFFUL
- if (uval & 0x80000000U)
- uval |= ~0x7FFFFFFFU;
-#endif
- val = (int32_t) uval;
- i += 4;
- }
- sprintf(buf, "%d", val);
- output_token(buf);
-
- } else {
- switch (b) {
- case 0: output_token("error"); break; /* special */
- case 1: output_token("hstem"); break;
- case 3: output_token("vstem"); break;
- case 4: output_token("vmoveto"); break;
- case 5: output_token("rlineto"); break;
- case 6: output_token("hlineto"); break;
- case 7: output_token("vlineto"); break;
- case 8: output_token("rrcurveto"); break;
- case 9: output_token("closepath"); break; /* Type 1 ONLY */
- case 10: output_token("callsubr"); break;
- case 11: output_token("return"); break;
- case 13: output_token("hsbw"); break; /* Type 1 ONLY */
- case 14: output_token("endchar"); break;
- case 16: output_token("blend"); break; /* Type 2 */
- case 18: output_token("hstemhm"); break; /* Type 2 */
- case 19: output_token("hintmask"); break; /* Type 2 */
- case 20: output_token("cntrmask"); break; /* Type 2 */
- case 21: output_token("rmoveto"); break;
- case 22: output_token("hmoveto"); break;
- case 23: output_token("vstemhm"); break; /* Type 2 */
- case 24: output_token("rcurveline"); break; /* Type 2 */
- case 25: output_token("rlinecurve"); break; /* Type 2 */
- case 26: output_token("vvcurveto"); break; /* Type 2 */
- case 27: output_token("hhcurveto"); break; /* Type 2 */
- case 28: { /* Type 2 */
- /* short integer */
- val = (line[i+1] & 0xff) << 8;
- val |= (line[i+2] & 0xff);
- i += 2;
- if (val & 0x8000)
- val |= ~0x7FFF;
- sprintf(buf, "%d", val);
- output_token(buf);
- }
- case 29: output_token("callgsubr"); break; /* Type 2 */
- case 30: output_token("vhcurveto"); break;
- case 31: output_token("hvcurveto"); break;
- case 12:
- i++;
- b = line[i];
- switch (b) {
- case 0: output_token("dotsection"); break; /* Type 1 ONLY */
- case 1: output_token("vstem3"); break; /* Type 1 ONLY */
- case 2: output_token("hstem3"); break; /* Type 1 ONLY */
- case 3: output_token("and"); break; /* Type 2 */
- case 4: output_token("or"); break; /* Type 2 */
- case 5: output_token("not"); break; /* Type 2 */
- case 6: output_token("seac"); break; /* Type 1 ONLY */
- case 7: output_token("sbw"); break; /* Type 1 ONLY */
- case 8: output_token("store"); break; /* Type 2 */
- case 9: output_token("abs"); break; /* Type 2 */
- case 10: output_token("add"); break; /* Type 2 */
- case 11: output_token("sub"); break; /* Type 2 */
- case 12: output_token("div"); break;
- case 13: output_token("load"); break; /* Type 2 */
- case 14: output_token("neg"); break; /* Type 2 */
- case 15: output_token("eq"); break; /* Type 2 */
- case 16: output_token("callothersubr"); break; /* Type 1 ONLY */
- case 17: output_token("pop"); break; /* Type 1 ONLY */
- case 18: output_token("drop"); break; /* Type 2 */
- case 20: output_token("put"); break; /* Type 2 */
- case 21: output_token("get"); break; /* Type 2 */
- case 22: output_token("ifelse"); break; /* Type 2 */
- case 23: output_token("random"); break; /* Type 2 */
- case 24: output_token("mul"); break; /* Type 2 */
- case 26: output_token("sqrt"); break; /* Type 2 */
- case 27: output_token("dup"); break; /* Type 2 */
- case 28: output_token("exch"); break; /* Type 2 */
- case 29: output_token("index"); break; /* Type 2 */
- case 30: output_token("roll"); break; /* Type 2 */
- case 33: output_token("setcurrentpoint"); break;/* Type 1 ONLY */
- case 34: output_token("hflex"); break; /* Type 2 */
- case 35: output_token("flex"); break; /* Type 2 */
- case 36: output_token("hflex1"); break; /* Type 2 */
- case 37: output_token("flex1"); break; /* Type 2 */
- default:
- sprintf(buf, "escape_%d", b);
- unknown++;
- output_token(buf);
- break;
- }
- break;
- default:
- sprintf(buf, "UNKNOWN_%d", b);
- unknown++;
- output_token(buf);
- break;
- }
- output_token("\n");
- }
- }
- if (i > len) {
- output("\terror\n");
- error("disassembly error: charstring too short");
- }
-}
-
-
-/* Disassembly font_reader functions */
-
-static int in_eexec = 0;
-static unsigned char *save = 0;
-static int save_len = 0;
-static int save_cap = 0;
-
-static void
-append_save(const unsigned char *line, int len)
-{
- if (line == save) {
- assert(len <= save_cap);
- save_len = len;
- return;
- }
- if (save_len + len >= save_cap) {
- unsigned char *new_save;
- if (!save_cap) save_cap = 1024;
- while (save_len + len >= save_cap) save_cap *= 2;
- new_save = (unsigned char *)malloc(save_cap);
- if (!new_save)
- fatal_error("out of memory");
- memcpy(new_save, save, save_len);
- free(save);
- save = new_save;
- }
- memcpy(save + save_len, line, len);
- save_len += len;
-}
-
-
-static unsigned char*
-check_eexec_charstrings_begin(unsigned char* line, int line_len)
-{
- unsigned char* line_end = line + line_len;
- line = memmem(line, line_len, "/CharStrings ", 13);
- if (!line)
- return 0;
- line += 13;
- while (line < line_end && isspace(*line))
- ++line;
- if (line == line_end || !isdigit(*line))
- return 0;
- while (line < line_end && isdigit(*line))
- ++line;
- if (line == line_end || !isspace(*line))
- return 0;
- while (line < line_end && isspace(*line))
- ++line;
- if (line_end - line < 14 || memcmp(line, "dict dup begin", 14) != 0)
- return 0;
- line += 14;
- while (line < line_end && isspace(*line))
- ++line;
- if (line == line_end || *line != '/')
- return 0;
- return line;
-}
-
-
-/* returns 1 if next \n should be deleted */
-
-static int
-eexec_line(unsigned char *line, int line_len)
-{
- int cs_start_len = strlen(cs_start);
- int pos;
- int first_space;
- int digits;
- int cut_newline = 0;
-
- /* append this data to the end of `save' if necessary */
- if (save_len) {
- append_save(line, line_len);
- line = save;
- line_len = save_len;
- save_len = 0;
- }
-
- if (!line_len)
- return 0;
-
- /* Look for charstring start */
-
- /* skip first word */
- for (pos = 0; pos < line_len && isspace(line[pos]); pos++)
- ;
- while (pos < line_len && !isspace(line[pos]))
- pos++;
- if (pos >= line_len)
- goto not_charstring;
-
- /* skip spaces */
- first_space = pos;
- while (pos < line_len && isspace(line[pos]))
- pos++;
- if (pos >= line_len || !isdigit(line[pos]))
- goto not_charstring;
-
- /* skip number */
- digits = pos;
- while (pos < line_len && isdigit(line[pos]))
- pos++;
-
- /* check for subr (another number) */
- if (pos < line_len - 1 && isspace(line[pos]) && isdigit(line[pos+1])) {
- first_space = pos;
- digits = pos + 1;
- for (pos = digits; pos < line_len && isdigit(line[pos]); pos++)
- ;
- }
-
- /* check for charstring start */
- if (pos + 2 + cs_start_len < line_len
- && pos > digits
- && line[pos] == ' '
- && strncmp((const char *)(line + pos + 1), cs_start, cs_start_len) == 0
- && line[pos + 1 + cs_start_len] == ' ') {
- /* check if charstring is long enough */
- int cs_len = atoi((const char *)(line + digits));
- if (pos + 2 + cs_start_len + cs_len < line_len) {
- /* long enough! */
- if (line[line_len - 1] == '\r') {
- line[line_len - 1] = '\n';
- cut_newline = 1;
- }
- fprintf(ofp, "%.*s {\n", first_space, line);
- decrypt_charstring(line + pos + 2 + cs_start_len, cs_len);
- pos += 2 + cs_start_len + cs_len;
- fprintf(ofp, "\t}%.*s", line_len - pos, line + pos);
- return cut_newline;
- } else {
- /* not long enough! */
- append_save(line, line_len);
- return 0;
- }
- }
-
- /* otherwise, just output the line */
- not_charstring:
- /* 6.Oct.2003 - Werner Lemberg reports a stupid Omega font that behaves
- badly: a charstring definition follows "/Charstrings ... begin", ON THE
- SAME LINE. */
- {
- unsigned char* csbegin = check_eexec_charstrings_begin(line, line_len);
- if (csbegin) {
- int len = csbegin - line;
- fprintf(ofp, "%.*s\n", len, line);
- return eexec_line(csbegin, line_len - len);
- }
- }
-
- if (line[line_len - 1] == '\r') {
- line[line_len - 1] = '\n';
- cut_newline = 1;
- }
- set_lenIV((char*) line, line_len);
- set_cs_start((char*) line, line_len);
- fprintf(ofp, "%.*s", line_len, line);
-
- /* look for `currentfile closefile' to see if we should stop decrypting */
- if (memmem(line, line_len, "currentfile closefile", 21) != 0)
- in_eexec = -1;
-
- return cut_newline;
-}
-
-static int
-all_zeroes(const char *string)
-{
- if (*string != '0')
- return 0;
- while (*string == '0')
- string++;
- return *string == '\0' || *string == '\n';
-}
-
-static void
-disasm_output_ascii(char *line, int len)
-{
- int was_in_eexec = in_eexec;
- (void) len; /* avoid warning */
- in_eexec = 0;
-
- /* if we came from a binary section, we need to process that too */
- if (was_in_eexec > 0) {
- unsigned char zero = 0;
- eexec_line(&zero, 0);
- }
-
- /* if we just came from the "ASCII part" of an eexec section, we need to
- process the saved lines */
- if (was_in_eexec < 0) {
- int i = 0;
- int save_char = 0; /* note: save[] is unsigned char * */
-
- while (i < save_len) {
- /* grab a line */
- int start = i;
- while (i < save_len && save[i] != '\r' && save[i] != '\n')
- i++;
- if (i < save_len) {
- if (i < save_len - 1 && save[i] == '\r' && save[i+1] == '\n')
- save_char = -1;
- else
- save_char = save[i+1];
- save[i] = '\n';
- save[i+1] = 0;
- } else
- save[i] = 0;
-
- /* output it */
- disasm_output_ascii((char *)(save + start), -1);
-
- /* repair damage */
- if (i < save_len) {
- if (save_char >= 0) {
- save[i+1] = save_char;
- i++;
- } else
- i += 2;
- }
- }
- save_len = 0;
- }
-
- if (!all_zeroes(line))
- output(line);
-}
-
-/* collect until '\n' or end of binary section */
-
-static void
-disasm_output_binary(unsigned char *data, int len)
-{
- static int ignore_newline;
- static uint16_t er;
-
- byte plain;
- int i;
-
- /* in the ASCII portion of a binary section, just save this data */
- if (in_eexec < 0) {
- append_save(data, len);
- return;
- }
-
- /* eexec initialization */
- if (in_eexec == 0) {
- er = er_default;
- ignore_newline = 0;
- in_eexec = 0;
- }
- if (in_eexec < 4) {
- for (i = 0; i < len && in_eexec < 4; i++, in_eexec++) {
- byte cipher = data[i];
- plain = (byte)(cipher ^ (er >> 8));
- er = (uint16_t)((cipher + er) * c1 + c2);
- data[i] = plain;
- }
- data += i;
- len -= i;
- }
-
- /* now make lines: collect until '\n' or '\r' and pass them off to
- eexec_line. */
- i = 0;
- while (in_eexec > 0) {
- int start = i;
-
- for (; i < len; i++) {
- byte cipher = data[i];
- plain = (byte)(cipher ^ (er >> 8));
- er = (uint16_t)((cipher + er) * c1 + c2);
- data[i] = plain;
- if (plain == '\r' || plain == '\n')
- break;
- }
-
- if (ignore_newline && start < i && data[start] == '\n') {
- ignore_newline = 0;
- continue;
- }
-
- if (i >= len) {
- if (start < len)
- append_save(data + start, i - start);
- break;
- }
-
- i++;
- ignore_newline = eexec_line(data + start, i - start);
- }
-
- /* if in_eexec < 0, we have some plaintext lines sitting around in a binary
- section of the PFB. save them for later */
- if (in_eexec < 0 && i < len)
- append_save(data + i, len - i);
-}
-
-static void
-disasm_output_end(void)
-{
- /* take care of leftover saved data */
- static char crap[1] = "";
- disasm_output_ascii(crap, 0);
-}
-
-
-/*****
- * Command line
- **/
-
-#define OUTPUT_OPT 301
-#define VERSION_OPT 302
-#define HELP_OPT 303
-
-static Clp_Option options[] = {
- { "help", 0, HELP_OPT, 0, 0 },
- { "output", 'o', OUTPUT_OPT, Clp_ValString, 0 },
- { "version", 0, VERSION_OPT, 0, 0 },
-};
-static const char *program_name;
-
-void
-fatal_error(const char *message, ...)
-{
- va_list val;
- va_start(val, message);
- fprintf(stderr, "%s: ", program_name);
- vfprintf(stderr, message, val);
- fputc('\n', stderr);
- va_end(val);
- exit(1);
-}
-
-void
-error(const char *message, ...)
-{
- va_list val;
- va_start(val, message);
- fprintf(stderr, "%s: ", program_name);
- vfprintf(stderr, message, val);
- fputc('\n', stderr);
- error_count++;
- va_end(val);
-}
-
-static void
-short_usage(void)
-{
- fprintf(stderr, "Usage: %s [INPUT [OUTPUT]]\n\
-Try `%s --help' for more information.\n",
- program_name, program_name);
-}
-
-static void
-usage(void)
-{
- printf("\
-`T1disasm' translates a PostScript Type 1 font in PFB or PFA format into a\n\
-human-readable, human-editable form. The result is written to the standard\n\
-output unless an OUTPUT file is given.\n\
-\n\
-Usage: %s [OPTION]... [INPUT [OUTPUT]]\n\
-\n\
-Options:\n\
- -o, --output=FILE Write output to FILE.\n\
- -h, --help Print this message and exit.\n\
- --version Print version number and warranty and exit.\n\
-\n\
-Report bugs to <ekohler@gmail.com>.\n", program_name);
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-
-int
-main(int argc, char *argv[])
-{
- struct font_reader fr;
- int c;
- FILE *ifp = 0;
- const char *ifp_filename = "<stdin>";
-
- Clp_Parser *clp =
- Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options);
- program_name = Clp_ProgramName(clp);
-
- /* interpret command line arguments using CLP */
- while (1) {
- int opt = Clp_Next(clp);
- switch (opt) {
-
- output_file:
- case OUTPUT_OPT:
- if (ofp)
- fatal_error("output file already specified");
- if (strcmp(clp->vstr, "-") == 0)
- ofp = stdout;
- else {
- ofp = fopen(clp->vstr, "w");
- if (!ofp) fatal_error("%s: %s", clp->vstr, strerror(errno));
- }
- break;
-
- case HELP_OPT:
- usage();
- exit(0);
- break;
-
- case VERSION_OPT:
- printf("t1disasm (LCDF t1utils) %s\n", VERSION);
- printf("Copyright (C) 1992-2017 I. Lee Hetherington, Eddie Kohler et al.\n\
-This is free software; see the source for copying conditions.\n\
-There is NO warranty, not even for merchantability or fitness for a\n\
-particular purpose.\n");
- exit(0);
- break;
-
- case Clp_NotOption:
- if (ifp && ofp)
- fatal_error("too many arguments");
- else if (ifp)
- goto output_file;
- if (strcmp(clp->vstr, "-") == 0)
- ifp = stdin;
- else {
- ifp_filename = clp->vstr;
- ifp = fopen(clp->vstr, "rb");
- if (!ifp) fatal_error("%s: %s", clp->vstr, strerror(errno));
- }
- break;
-
- case Clp_Done:
- goto done;
-
- case Clp_BadOption:
- short_usage();
- exit(1);
- break;
-
- }
- }
-
- done:
- if (!ifp) ifp = stdin;
- if (!ofp) ofp = stdout;
-
-#if defined(_MSDOS) || defined(_WIN32)
- /* As we might be processing a PFB (binary) input file, we must set its file
- mode to binary. */
- _setmode(_fileno(ifp), _O_BINARY);
- _setmode(_fileno(ofp), _O_BINARY);
-#endif
-
- /* prepare font reader */
- fr.output_ascii = disasm_output_ascii;
- fr.output_binary = disasm_output_binary;
- fr.output_end = disasm_output_end;
-
- /* peek at first byte to see if it is the PFB marker 0x80 */
- c = getc(ifp);
- ungetc(c, ifp);
-
- /* do the file */
- if (c == PFB_MARKER)
- process_pfb(ifp, ifp_filename, &fr);
- else if (c == '%')
- process_pfa(ifp, ifp_filename, &fr);
- else
- fatal_error("%s does not start with font marker (`%%' or 0x80)", ifp_filename);
-
- fclose(ifp);
- fclose(ofp);
-
- if (unknown)
- error((unknown > 1
- ? "encountered %d unknown charstring commands"
- : "encountered %d unknown charstring command"),
- unknown);
-
- return (error_count ? 1 : 0);
-}