diff options
Diffstat (limited to 'dviware/quicspool/src/tfm2ofont.c')
-rw-r--r-- | dviware/quicspool/src/tfm2ofont.c | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/dviware/quicspool/src/tfm2ofont.c b/dviware/quicspool/src/tfm2ofont.c new file mode 100644 index 0000000000..d40d38098e --- /dev/null +++ b/dviware/quicspool/src/tfm2ofont.c @@ -0,0 +1,231 @@ +#ifndef lint +static char *rcs = "$Header: tfm2ofont.c,v 1.1 88/01/15 13:05:54 simpson Rel $"; +#endif +/* +$Log: tfm2ofont.c,v $ + * Revision 1.1 88/01/15 13:05:54 simpson + * initial release + * + * Revision 0.1 87/12/11 18:31:26 simpson + * beta test + * +*/ +#include <stdio.h> +#include <ctype.h> +#include <local/standard.h> +#include "constants.h" + +extern char RegularOrder[], SpecialOrder[]; /* Order we want to output */ + +char OutputFile[81]; +char TfmName[81]; /* Only used in error routine */ +char *WhoAmI; /* Argv[0] */ +char *Usage = "Usage: %s [-s] file...\n"; +Boolean Special = FALSE; /* Designates whether font is special */ +int ExitStatus = SUCCEED; + +main(argc, argv) +int argc; +char *argv[]; +{ + extern int optind; + extern char *optarg; + int c; + FILE *infile, *outfile; + void seteoffunction(), tfmeofsoexit(), convert(); + char *strcpy(), *strcat(), *strncat(); + + WhoAmI = argv[0]; + while ((c = getopt(argc, argv, "s")) != EOF) + switch (c) { + case 's': + Special = TRUE; + break; + case '?': + fprintf(stderr, Usage, WhoAmI); + exit(FAIL); + } + seteoffunction(tfmeofsoexit); + for (; optind < argc; optind++) { + if (strlen(argv[optind]) < 5 || !EQ(".tfm", &argv[optind][strlen( + argv[optind])-4])) { + fprintf(stderr, "%s: invalid input file name %s\n", WhoAmI, + argv[optind]); + ExitStatus = FAIL; + continue; + } + if (!(infile = fopen(argv[optind], "r"))) { + fprintf(stderr, "%s: cannot open input file %s\n", WhoAmI, + argv[optind]); + ExitStatus = FAIL; + continue; + } + (void)strcpy(TfmName, argv[optind]); + (void)strcpy(OutputFile, "ft"); + (void)strncat(OutputFile, argv[optind], strlen(argv[optind])-4); + (void)strcat(OutputFile, ".c"); + if (!(outfile = fopen(OutputFile, "w"))) { + fprintf(stderr, "%s: cannot open output file %s\n", WhoAmI, + OutputFile); + ExitStatus = FAIL; + continue; + } + convert(infile, outfile, argv[optind]); + (void)fclose(infile), (void)fclose(outfile); + } + exit(ExitStatus); +} + +/* The main routine which converts a tfm file to an otroff width table file. + */ +void convert(infile, outfile, inname) +FILE *infile, *outfile; +char *inname; +{ + long aheight, i, j, widthindex, heightanddepth, zero, height, + depth, charpos; + long widths[256][2]; /* Width of char in FIX/designsize & kern */ + unsigned long uinteger(), lh, bc, ec, nw, nh, designsize; + long integer(), getaheight(); + + fprintf(outfile, "char font[256-32] = {\n"); + if ((aheight = getaheight(infile)) == MAX_INTEGER) { + fprintf(stderr, "%s: no letter 'a' in file %s\n", WhoAmI, inname); + fprintf(stderr, "\tsetting height to zero\n"); + aheight = 0; + } + rewind(infile); + bzero((char *)widths, sizeof(widths)); + (void)uinteger(infile, 2); /* lf */ + lh = uinteger(infile, 2); + bc = uinteger(infile, 2); + ec = uinteger(infile, 2); + nw = uinteger(infile, 2); + nh = uinteger(infile, 2); + (void)uinteger(infile, 2); /* nd */ + (void)uinteger(infile, 2); /* ni */ + (void)uinteger(infile, 2); /* nl */ + (void)uinteger(infile, 2); /* nk */ + (void)uinteger(infile, 2); /* ne */ + (void)uinteger(infile, 2); /* np */ + (void)uinteger(infile, 4); /* Skip checksum */ + designsize = uinteger(infile, 4) / FIX; + for (i = bc; i <= ec; i++) { + (void)fseek(infile, 24L + 4 * lh + (i - bc) * 4, 0); + widthindex = uinteger(infile, 1); + heightanddepth = uinteger(infile, 1); + if (widthindex == 0) + continue; + (void)fseek(infile, 24L + 4 * lh + (ec - bc + 1) * 4 + widthindex + * 4, 0); + widths[i][0] = integer(infile, 4); + (void)fseek(infile, 24L + 4 * lh + (ec - bc + 1) * 4 + nw * 4 + + (heightanddepth >> 4) * 4, 0); + height = uinteger(infile, 4); + (void)fseek(infile, 24L + 4 * lh + (ec - bc + 1) * 4 + nw * 4 + + nh * 4 + (heightanddepth & 0xF) * 4, 0); + depth = uinteger(infile, 4); + if (!Special && isalnum(i) || Special && (0101 <= i && i <= 0130 + || 0141 <= i && i <= 0170 || i == 014 || i == 050)) { + if (height > aheight) /* Letters taller than 'a' get 0200 */ + widths[i][1] |= 0200; /* turned on. */ + if (depth > 0) /* Letters below baseline get 0100 */ + widths[i][1] |= 0100; /* turned on. */ + } + } + for (i = 040, zero = 0; i < 256; i++) { + if (i == 0177 && !Special) { /* 1/16em is always 6 units */ + if (zero) { + zero = 0; + putc('\n', outfile); + } + fprintf(outfile, "6,\n"); + continue; + } + if (i == 0226 && !Special) { /* 1/12em is always 3 units */ + if (zero) { + zero = 0; + putc('\n', outfile); + } + fprintf(outfile, "3,\n"); + continue; + } + if (i == ' ' && !Special) { /* Space is always 12 units */ + if (zero) { + zero = 0; + putc('\n', outfile); + } + fprintf(outfile, "12,\n"); + continue; + } + charpos = (Special ? SpecialOrder[i - 32] : RegularOrder[i - 32]); + if (charpos == 0 || widths[charpos][0] == 0) { + fprintf(outfile, "0,"); + zero++; + if (!((i+1)%8)) { + putc('\n', outfile); + zero = 0; + } + } else { + if (zero) { + zero = 0; + putc('\n', outfile); + } + j = ROUND((widths[charpos][0] / (double)FIX * designsize) / PPI + * 254.6457); + /* Don't ask where the 254.6457 came from. I haven't the faintest + * notion why troff uses this constant, but it works, and that + * is fine enough with me. Otroff can't handle widths over + * 63 (2^6). If you give it something greater, it take the + * lower six bits. This screws up the TRW logo which is 79 but + * there is nothing we can do. + */ + fprintf(outfile, "%d", j > 63 ? 63 : j); + if (widths[charpos][1]) + fprintf(outfile, "+0%o,\n", widths[charpos][1]); + else + fprintf(outfile, ",\n"); + } + } + fprintf(outfile, "};\n"); +} + +/* Returns the height of the letter 'a' in the font passed as a parameter. + * The height is returned in FIXes/designsize. If the letter 'a' is not + * found, MAX_INTEGER is returned. + */ +long getaheight(in) +FILE *in; +{ + unsigned long lh, bc, ec, nw, uinteger(); + + (void)fseek(in, 0L, 0); + (void)uinteger(in, 2); /* lf */ + lh = uinteger(in, 2); + bc = uinteger(in, 2); + ec = uinteger(in, 2); + nw = uinteger(in, 2); + (void)uinteger(in, 2); /* nh */ + (void)uinteger(in, 2); /* nd */ + (void)uinteger(in, 2); /* ni */ + (void)uinteger(in, 2); /* nl */ + (void)uinteger(in, 2); /* nk */ + (void)uinteger(in, 2); /* ne */ + (void)uinteger(in, 2); /* np */ + if (bc > 'a' || ec < 'a') + return MAX_INTEGER; + (void)uinteger(in, 4); /* Skip checksum */ + (void)uinteger(in, 4); /* Width */ + (void)fseek(in, 24L + lh*4 + ('a'-bc)*4, 0); + if (uinteger(in, 1) == 0) + return MAX_INTEGER; + (void)fseek(in, 24L + lh*4 + (ec-bc+1)*4 + nw*4 + (uinteger(in,1) >> 4)*4, + 0); + return uinteger(in, 4); +} + +void tfmeofsoexit() +{ + fprintf(stderr, "%s: unexpected end of tfm file %s\n", WhoAmI, TfmName); + exit(FAIL); +} |