summaryrefslogtreecommitdiff
path: root/dviware/quicspool/src/tfm2ofont.c
diff options
context:
space:
mode:
Diffstat (limited to 'dviware/quicspool/src/tfm2ofont.c')
-rw-r--r--dviware/quicspool/src/tfm2ofont.c231
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);
+}