summaryrefslogtreecommitdiff
path: root/dviware/quicspool
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/quicspool
Initial commit
Diffstat (limited to 'dviware/quicspool')
-rw-r--r--dviware/quicspool/diffs/eqn22
-rw-r--r--dviware/quicspool/diffs/pic23
-rw-r--r--dviware/quicspool/libglob/glob.c223
-rw-r--r--dviware/quicspool/libglob/glob.h18
-rw-r--r--dviware/quicspool/libglob/makefile29
-rw-r--r--dviware/quicspool/libglob/makefile.trw29
-rw-r--r--dviware/quicspool/libprofile/boolean.c79
-rw-r--r--dviware/quicspool/libprofile/free.c62
-rw-r--r--dviware/quicspool/libprofile/has.c63
-rw-r--r--dviware/quicspool/libprofile/makefile29
-rw-r--r--dviware/quicspool/libprofile/makefile.trw29
-rw-r--r--dviware/quicspool/libprofile/profile.h63
-rw-r--r--dviware/quicspool/libprofile/read.c834
-rw-r--r--dviware/quicspool/libprofile/space.c60
-rw-r--r--dviware/quicspool/libprofile/write.c206
-rw-r--r--dviware/quicspool/libqmsquery/lexsed17
-rw-r--r--dviware/quicspool/libqmsquery/makefile136
-rw-r--r--dviware/quicspool/libqmsquery/makefile.trw136
-rw-r--r--dviware/quicspool/libqmsquery/qms.h186
-rw-r--r--dviware/quicspool/libqmsquery/qmsfnt.y94
-rw-r--r--dviware/quicspool/libqmsquery/qmsfntlex.l43
-rw-r--r--dviware/quicspool/libqmsquery/qmsmap.y108
-rw-r--r--dviware/quicspool/libqmsquery/qmsmaplex.l28
-rw-r--r--dviware/quicspool/libqmsquery/qmsopc.y133
-rw-r--r--dviware/quicspool/libqmsquery/qmsopclex.l28
-rw-r--r--dviware/quicspool/libqmsquery/qmsovl.y80
-rw-r--r--dviware/quicspool/libqmsquery/qmsovllex.l29
-rw-r--r--dviware/quicspool/libqmsquery/qmspag.y162
-rw-r--r--dviware/quicspool/libqmsquery/qmspaglex.l50
-rw-r--r--dviware/quicspool/libqmsquery/qmspfp.y75
-rw-r--r--dviware/quicspool/libqmsquery/qmspfplex.l32
-rw-r--r--dviware/quicspool/libqmsquery/qmsquery.c152
-rw-r--r--dviware/quicspool/libqmsquery/qmsram.y79
-rw-r--r--dviware/quicspool/libqmsquery/qmsramlex.l29
-rw-r--r--dviware/quicspool/libqmsquery/qmsver.y68
-rw-r--r--dviware/quicspool/libqmsquery/qmsverlex.l41
-rw-r--r--dviware/quicspool/libqmsquery/yaccsed12
-rw-r--r--dviware/quicspool/libtrw/getopt.c61
-rw-r--r--dviware/quicspool/libtrw/makefile23
-rw-r--r--dviware/quicspool/libtrw/makefile.trw23
-rw-r--r--dviware/quicspool/libtrw/shift.c39
-rw-r--r--dviware/quicspool/makefile175
-rw-r--r--dviware/quicspool/makefile.trw178
-rw-r--r--dviware/quicspool/man/cat.l226
-rw-r--r--dviware/quicspool/man/cati.l216
-rw-r--r--dviware/quicspool/man/dumpdesc.l_backup30
-rw-r--r--dviware/quicspool/man/getopt.l145
-rw-r--r--dviware/quicspool/man/glob.l180
-rw-r--r--dviware/quicspool/man/makefile46
-rw-r--r--dviware/quicspool/man/makefile.trw48
-rw-r--r--dviware/quicspool/man/pktoch.l_backup47
-rw-r--r--dviware/quicspool/man/profile.l285
-rw-r--r--dviware/quicspool/man/profile5.l237
-rw-r--r--dviware/quicspool/man/qmsquery.l258
-rw-r--r--dviware/quicspool/man/quicspool.l_backup321
-rw-r--r--dviware/quicspool/man/shift.l37
-rw-r--r--dviware/quicspool/man/standard.l266
-rw-r--r--dviware/quicspool/man/tfm2difont.l_backup79
-rw-r--r--dviware/quicspool/man/tfm2ofont.l_backup48
-rw-r--r--dviware/quicspool/mffiles/logodesign.mf170
-rw-r--r--dviware/quicspool/readme.nr593
-rw-r--r--dviware/quicspool/src/cat.c560
-rw-r--r--dviware/quicspool/src/cati.c709
-rw-r--r--dviware/quicspool/src/cleanup.c86
-rw-r--r--dviware/quicspool/src/constants.h_backup26
-rw-r--r--dviware/quicspool/src/dev.h49
-rw-r--r--dviware/quicspool/src/df.c_backup1164
-rw-r--r--dviware/quicspool/src/ditroff.backup49
-rw-r--r--dviware/quicspool/src/dumpdesc.c177
-rw-r--r--dviware/quicspool/src/dvi.h72
-rw-r--r--dviware/quicspool/src/eqnchar104
-rw-r--r--dviware/quicspool/src/fontinfo.h44
-rw-r--r--dviware/quicspool/src/fontnode.h27
-rw-r--r--dviware/quicspool/src/getc.c172
-rw-r--r--dviware/quicspool/src/gf.c419
-rw-r--r--dviware/quicspool/src/glpq32
-rw-r--r--dviware/quicspool/src/glpr104
-rw-r--r--dviware/quicspool/src/if.c221
-rw-r--r--dviware/quicspool/src/io.c104
-rw-r--r--dviware/quicspool/src/list.c101
-rw-r--r--dviware/quicspool/src/makefile152
-rw-r--r--dviware/quicspool/src/makefile.trw190
-rw-r--r--dviware/quicspool/src/misc.c183
-rw-r--r--dviware/quicspool/src/mount.nr13
-rw-r--r--dviware/quicspool/src/nf.c_backup1329
-rw-r--r--dviware/quicspool/src/of.c271
-rw-r--r--dviware/quicspool/src/pk.c475
-rw-r--r--dviware/quicspool/src/pk.h23
-rw-r--r--dviware/quicspool/src/pktoch.c100
-rw-r--r--dviware/quicspool/src/profile.c40
-rw-r--r--dviware/quicspool/src/qms.c66
-rw-r--r--dviware/quicspool/src/qtroff.backup60
-rw-r--r--dviware/quicspool/src/quic.l60
-rw-r--r--dviware/quicspool/src/rf.c163
-rw-r--r--dviware/quicspool/src/spline.c75
-rw-r--r--dviware/quicspool/src/stack.c75
-rw-r--r--dviware/quicspool/src/string.c177
-rw-r--r--dviware/quicspool/src/table.c89
-rw-r--r--dviware/quicspool/src/tf.c_backup953
-rw-r--r--dviware/quicspool/src/tfm2difont.c489
-rw-r--r--dviware/quicspool/src/tfm2ofont.c231
-rw-r--r--dviware/quicspool/src/xxx.y411
-rw-r--r--dviware/quicspool/src/xxxlex.l52
-rw-r--r--dviware/quicspool/standard/makefile28
-rw-r--r--dviware/quicspool/standard/makefile.trw28
-rw-r--r--dviware/quicspool/standard/standard.h14
-rw-r--r--dviware/quicspool/standard/standconst.h75
-rw-r--r--dviware/quicspool/standard/standenviron.h49
-rw-r--r--dviware/quicspool/standard/standmacro.h21
-rw-r--r--dviware/quicspool/standard/standtype.h118
-rw-r--r--dviware/quicspool/wbfonts/b.mf83
-rw-r--r--dviware/quicspool/wbfonts/b.tfmbin0 -> 1260 bytes
-rw-r--r--dviware/quicspool/wbfonts/cw.mf83
-rw-r--r--dviware/quicspool/wbfonts/cw.tfmbin0 -> 799 bytes
-rw-r--r--dviware/quicspool/wbfonts/desc43
-rw-r--r--dviware/quicspool/wbfonts/i.mf83
-rw-r--r--dviware/quicspool/wbfonts/i.tfmbin0 -> 1348 bytes
-rw-r--r--dviware/quicspool/wbfonts/makefile40
-rw-r--r--dviware/quicspool/wbfonts/makefile.trw40
-rw-r--r--dviware/quicspool/wbfonts/makefonts30
-rw-r--r--dviware/quicspool/wbfonts/r.mf83
-rw-r--r--dviware/quicspool/wbfonts/r.tfmbin0 -> 1220 bytes
-rw-r--r--dviware/quicspool/wbfonts/s.mf83
-rw-r--r--dviware/quicspool/wbfonts/s.tfmbin0 -> 1028 bytes
-rw-r--r--dviware/quicspool/wbfonts/tcomlig.mf21
-rw-r--r--dviware/quicspool/wbfonts/tgreekl.mf418
-rw-r--r--dviware/quicspool/wbfonts/tgreeku.mf611
-rw-r--r--dviware/quicspool/wbfonts/titalig.mf206
-rw-r--r--dviware/quicspool/wbfonts/titalms.mf40
-rw-r--r--dviware/quicspool/wbfonts/titalp.mf114
-rw-r--r--dviware/quicspool/wbfonts/tmathit.mf1015
-rw-r--r--dviware/quicspool/wbfonts/tpunct.mf241
-rw-r--r--dviware/quicspool/wbfonts/troman.mf341
-rw-r--r--dviware/quicspool/wbfonts/tromlig.mf171
-rw-r--r--dviware/quicspool/wbfonts/tromms.mf42
-rw-r--r--dviware/quicspool/wbfonts/ttextit.mf336
-rw-r--r--dviware/quicspool/wwfonts/b.mf83
-rw-r--r--dviware/quicspool/wwfonts/b.tfmbin0 -> 1260 bytes
-rw-r--r--dviware/quicspool/wwfonts/cw.mf83
-rw-r--r--dviware/quicspool/wwfonts/cw.tfmbin0 -> 799 bytes
-rw-r--r--dviware/quicspool/wwfonts/desc43
-rw-r--r--dviware/quicspool/wwfonts/i.mf83
-rw-r--r--dviware/quicspool/wwfonts/i.tfmbin0 -> 1348 bytes
-rw-r--r--dviware/quicspool/wwfonts/makefile40
-rw-r--r--dviware/quicspool/wwfonts/makefile.trw40
-rw-r--r--dviware/quicspool/wwfonts/makefonts30
-rw-r--r--dviware/quicspool/wwfonts/r.mf83
-rw-r--r--dviware/quicspool/wwfonts/r.tfmbin0 -> 1220 bytes
-rw-r--r--dviware/quicspool/wwfonts/s.mf83
-rw-r--r--dviware/quicspool/wwfonts/s.tfmbin0 -> 1028 bytes
-rw-r--r--dviware/quicspool/wwfonts/tcomlig.mf21
-rw-r--r--dviware/quicspool/wwfonts/tgreekl.mf418
-rw-r--r--dviware/quicspool/wwfonts/tgreeku.mf611
-rw-r--r--dviware/quicspool/wwfonts/titalig.mf206
-rw-r--r--dviware/quicspool/wwfonts/titalms.mf40
-rw-r--r--dviware/quicspool/wwfonts/titalp.mf114
-rw-r--r--dviware/quicspool/wwfonts/tmathit.mf1015
-rw-r--r--dviware/quicspool/wwfonts/tpunct.mf241
-rw-r--r--dviware/quicspool/wwfonts/troman.mf341
-rw-r--r--dviware/quicspool/wwfonts/tromlig.mf171
-rw-r--r--dviware/quicspool/wwfonts/tromms.mf42
-rw-r--r--dviware/quicspool/wwfonts/ttextit.mf336
162 files changed, 25696 insertions, 0 deletions
diff --git a/dviware/quicspool/diffs/eqn b/dviware/quicspool/diffs/eqn
new file mode 100644
index 0000000000..d593b99460
--- /dev/null
+++ b/dviware/quicspool/diffs/eqn
@@ -0,0 +1,22 @@
+*** io.c.orig Thu Nov 12 09:51:32 1987
+--- io.c Thu Nov 12 10:39:36 1987
+***************
+*** 167,172
+ case 'T':
+ if (strcmp(&svargv[1][2], "202") == 0)
+ {res = 972; minsize = 5; ttype = DEV202; }
+ else if (strcmp(&svargv[1][2], "aps") == 0)
+ {res = 723; minsize = 5; ttype = DEVAPS; }
+ else if (strcmp(&svargv[1][2], "cat") == 0)
+
+--- 167,176 -----
+ case 'T':
+ if (strcmp(&svargv[1][2], "202") == 0)
+ {res = 972; minsize = 5; ttype = DEV202; }
++ else if (strcmp(&svargv[1][2], "qms") == 0)
++ /* Use the Xerox 9700 type for the qms */
++ /* since it has the same resolution */
++ {res = 300; minsize = 4; ttype = DEVX97; }
+ else if (strcmp(&svargv[1][2], "aps") == 0)
+ {res = 723; minsize = 5; ttype = DEVAPS; }
+ else if (strcmp(&svargv[1][2], "cat") == 0)
diff --git a/dviware/quicspool/diffs/pic b/dviware/quicspool/diffs/pic
new file mode 100644
index 0000000000..f2b2a8b2ef
--- /dev/null
+++ b/dviware/quicspool/diffs/pic
@@ -0,0 +1,23 @@
+*** main.c.orig Thu Nov 12 10:42:49 1987
+--- main.c Thu Nov 12 10:44:26 1987
+***************
+*** 81,86
+ res = 723;
+ devtype = DEVAPS;
+ DX = DY = 1;
+ } else if (strcmp(&argv[1][2], "202") == 0) {
+ res = 972;
+ devtype = DEV202;
+
+--- 81,91 -----
+ res = 723;
+ devtype = DEVAPS;
+ DX = DY = 1;
++ } else if (strcmp(&argv[1][2], "qms") == 0) {
++ res = 300;
++ /* X9700 has the same resolution so use it */
++ devtype = DEVX97;
++ DX = DY = 1;
+ } else if (strcmp(&argv[1][2], "202") == 0) {
+ res = 972;
+ devtype = DEV202;
diff --git a/dviware/quicspool/libglob/glob.c b/dviware/quicspool/libglob/glob.c
new file mode 100644
index 0000000000..a407361557
--- /dev/null
+++ b/dviware/quicspool/libglob/glob.c
@@ -0,0 +1,223 @@
+static char *rcs= "$Header: glob.c,v 1.1 88/01/15 12:15:45 simpson Rel $";
+/*
+$Log: glob.c,v $
+ * Revision 1.1 88/01/15 12:15:45 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:18:05 simpson
+ * beta test
+ *
+*/
+#include "glob.h"
+
+#define SLOP 5
+#define MAX_SET 0177
+
+/* control codes for regular expression evaluation */
+#define PATTERN_ANY '?'
+#define PATTERN_CHARACTER 'X'
+#define PATTERN_END '$'
+#define PATTERN_SET '['
+#define PATTERN_SET_MEMBER 'M'
+#define PATTERN_SET_RANGE '-'
+#define PATTERN_STAR '*'
+
+/*
+ * Examples (=> denotes `compiles into')
+ *
+ * a => Xa
+ * ? => ?
+ * [x0-9] => [^EMx-09 (^E is control-E)
+ * * => *
+ * END => $
+ *
+ * a?[x0-9]* => Xa?[^EMx-09*$
+ */
+
+glob_compile (pattern, buffer)
+char *pattern;
+char *buffer; /* compiled pattern */
+{
+ char *x; /* pointer into compiled pattern */
+ int c;
+ int result;
+
+ if (pattern == 0 || pattern[0] == 0)
+ return(GLOB_PATTERN_EMPTY);
+
+ x = buffer;
+ while (x < &buffer[GLOB_MAX_PATTERN - SLOP]) {
+ c = *pattern++;
+ if (c == 0) {
+ *x++ = PATTERN_END;
+ return(GLOB_OK);
+ }
+
+ switch (c) {
+ case '?':
+ *x++ = PATTERN_ANY;
+ continue;
+
+ case '[':
+ if ((result = compile_set(pattern, x, &buffer[GLOB_MAX_PATTERN - SLOP])) < 0)
+ return(result);
+ pattern += result + 1;
+ x += x[1] + 2;
+ continue;
+
+ case '*':
+ *x++ = PATTERN_STAR;
+ continue;
+
+ default:
+ *x++ = PATTERN_CHARACTER;
+ *x++ = c;
+ continue;
+ }
+ }
+ return(GLOB_PATTERN_TOO_BIG);
+}
+
+int glob_execute (pattern, s)
+char *pattern; /* compiled pattern */
+char *s; /* string to be matched against */
+{
+ char *current;
+ int result;
+
+ for (;;)
+ switch (*pattern++) {
+ case PATTERN_ANY:
+ if (*s++)
+ continue;
+ return(0);
+
+ case PATTERN_CHARACTER:
+ if (*pattern++ == *s++)
+ continue;
+ return(0);
+
+ case PATTERN_END:
+ return(*s == 0);
+
+ case PATTERN_SET:
+ if ((result = in_set(pattern, *s++)) == 1) {
+ pattern += *pattern + 1;
+ continue;
+ }
+ return(result);
+
+ case PATTERN_STAR:
+ current = s;
+ while (*s++)
+ continue;
+ do {
+ s--;
+ if (result = glob_execute(pattern, s))
+ return(result);
+ } while (s > current);
+ return(0);
+
+ default:
+ return(GLOB_EXECUTION_ERROR);
+ }
+}
+
+int glob_match (pattern, s)
+char *pattern;
+char *s;
+{
+ int result;
+ char buffer[GLOB_MAX_PATTERN];
+
+ if ((result = glob_compile(pattern, buffer)) < 0)
+ return(result);
+ else
+ return(glob_execute(buffer, s));
+}
+
+/* returns 1 if character c is member of set and 0 otherwise */
+static int in_set (set, c)
+char *set; /* compiled set pattern */
+char c;
+{
+ int n;
+
+ if (c == 0)
+ return(0);
+ n = *set++;
+ while (n > 0)
+ switch (*set++) {
+ case PATTERN_SET_MEMBER:
+ if (*set++ == c)
+ return(1);
+ n -= 2;
+ continue;
+
+ case PATTERN_SET_RANGE:
+ if (*set++ <= c && c <= *set++)
+ return(1);
+ n -= 3;
+ continue;
+
+ default:
+ return(GLOB_EXECUTION_ERROR);
+ }
+ return(0);
+}
+
+#define IS_RANGE(s) (s[1] && s[2] && s[1] == '-' && s[2] != ']')
+
+/* compiles a set returning the number of pattern characters consumed */
+static int compile_set (pattern, x, limit)
+char *pattern;
+char *x;
+char *limit;
+{
+ char *slot; /* size of set goes here */
+ int size; /* number of bytes in compiled set */
+ char *start = pattern;
+
+ if (*pattern == 0)
+ return(GLOB_BRACKET_MISSING);
+
+ *x++ = PATTERN_SET;
+ slot = x++;
+ size = 0;
+
+ if (IS_RANGE(pattern)) {
+ if (pattern[0] > pattern[2]) /* pattern[1] == '-' */
+ return(GLOB_RANGE_INVERTED);
+ *x++ = PATTERN_SET_RANGE;
+ *x++ = pattern[0];
+ *x++ = pattern[2];
+ pattern += 3;
+ size += 3;
+ } else {
+ *x++ = PATTERN_SET_MEMBER;
+ *x++ = *pattern++;
+ size += 2;
+ }
+
+ while (*pattern != ']' && x < limit) {
+ if (*pattern == 0)
+ return(GLOB_BRACKET_MISSING);
+ if (IS_RANGE(pattern)) {
+ if (pattern[0] > pattern[2]) /* pattern[1] == '-' */
+ return(GLOB_RANGE_INVERTED);
+ *x++ = PATTERN_SET_RANGE;
+ *x++ = pattern[0];
+ *x++ = pattern[2];
+ pattern += 3;
+ size += 3;
+ } else {
+ *x++ = PATTERN_SET_MEMBER;
+ *x++ = *pattern++;
+ size += 2;
+ }
+ }
+ if (size > MAX_SET)
+ return(GLOB_SET_TOO_BIG);
+ *slot = size;
+ return(pattern - start);
+}
diff --git a/dviware/quicspool/libglob/glob.h b/dviware/quicspool/libglob/glob.h
new file mode 100644
index 0000000000..51f26c4156
--- /dev/null
+++ b/dviware/quicspool/libglob/glob.h
@@ -0,0 +1,18 @@
+/* $Header: glob.h,v 1.1 88/01/15 12:15:48 simpson Rel $ */
+/*
+$Log: glob.h,v $
+ * Revision 1.1 88/01/15 12:15:48 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:18:07 simpson
+ * beta test
+ *
+*/
+#define GLOB_MAX_PATTERN 1024
+#define GLOB_OK 0
+#define GLOB_PATTERN_TOO_BIG -1
+#define GLOB_PATTERN_EMPTY -2
+#define GLOB_BRACKET_MISSING -3
+#define GLOB_RANGE_INVERTED -4
+#define GLOB_SET_TOO_BIG -5
+#define GLOB_EXECUTION_ERROR -6
diff --git a/dviware/quicspool/libglob/makefile b/dviware/quicspool/libglob/makefile
new file mode 100644
index 0000000000..e7e8bfbb86
--- /dev/null
+++ b/dviware/quicspool/libglob/makefile
@@ -0,0 +1,29 @@
+# $Header: Makefile,v 1.1 88/01/15 12:15:41 simpson Rel $
+# $Log: Makefile,v $
+#Revision 1.1 88/01/15 12:15:41 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 17:18:04 simpson
+#beta test
+#
+INCLUDE=/usr/include/local
+LIB=/usr/local/lib
+
+all: libglob.a
+
+# This system include file is need right away
+configure:
+ install -c -m 644 glob.h $(INCLUDE)
+
+libglob.a: glob.o
+ ar cr libglob.a glob.o
+ ranlib libglob.a
+
+install:
+ install -c -m 644 glob.h $(INCLUDE)
+ install -m 644 libglob.a $(LIB)
+
+clean:
+ -rm -f *.o libglob.a
+
+glob.o: glob.h
diff --git a/dviware/quicspool/libglob/makefile.trw b/dviware/quicspool/libglob/makefile.trw
new file mode 100644
index 0000000000..6be780c472
--- /dev/null
+++ b/dviware/quicspool/libglob/makefile.trw
@@ -0,0 +1,29 @@
+# $Header: Makefile.TRW,v 1.1 88/01/15 12:15:43 simpson Rel $
+# $Log: Makefile.TRW,v $
+#Revision 1.1 88/01/15 12:15:43 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 17:18:05 simpson
+#beta test
+#
+INCLUDE=/usr/include/local
+LIB=/usr/local/lib
+
+all: libglob.a
+
+# This system include file is need right away
+configure:
+ install -c -m 644 glob.h $(INCLUDE)
+
+libglob.a: glob.o
+ ar cr libglob.a glob.o
+ ranlib libglob.a
+
+install:
+ install -c -m 644 glob.h $(INCLUDE)
+ install -m 644 libglob.a $(LIB)
+
+clean:
+ -rm -f *.o libglob.a
+
+glob.o: glob.h
diff --git a/dviware/quicspool/libprofile/boolean.c b/dviware/quicspool/libprofile/boolean.c
new file mode 100644
index 0000000000..a26df19a38
--- /dev/null
+++ b/dviware/quicspool/libprofile/boolean.c
@@ -0,0 +1,79 @@
+static char *rcs = "$Header: boolean.c,v 1.1 88/01/15 12:16:56 simpson Rel $";
+/*
+$Log: boolean.c,v $
+ * Revision 1.1 88/01/15 12:16:56 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:02:10 simpson
+ * beta test
+ *
+*/
+#include <ctype.h>
+#include "profile.h"
+
+static char *Yes[] = {
+ "yes",
+ "on",
+ "true",
+ "enable",
+ "available",
+ "present",
+ 0
+};
+
+static char *No[] = {
+ "no",
+ "off",
+ "false",
+ "disable",
+ "unavailable",
+ "absent",
+ 0
+};
+
+int profile_boolean (v)
+PROFILE_VALUE *v;
+{
+ char x[16];
+ int i;
+
+ if (v == 0)
+ return(0);
+
+ switch (v->class) {
+ case PROFILE_OTHER:
+ case PROFILE_STRING:
+ strncpy(x, v->value.s, sizeof(x)-1);
+ x[sizeof(x)-1] = 0;
+ downshift(x);
+ for (i = 0; Yes[i]; i++)
+ if (strcmp(x, Yes[i]) == 0)
+ return(1);
+ else if (strcmp(x, No[i]) == 0)
+ return(0);
+ return(-1); /* unknown string */
+
+ case PROFILE_HEX:
+ case PROFILE_INTEGER:
+ case PROFILE_OCTAL:
+ return(v->value.i != 0);
+
+ case PROFILE_CHARACTER:
+ return(v->value.c != 0);
+
+ case PROFILE_FLOAT:
+ return(v->value.f != 0.0);
+
+ default:
+ return(-1); /* unknown class */
+ }
+}
+
+/* downshift a string in place */
+static downshift (s)
+char *s;
+{
+ for (; *s; s++)
+ if (isupper(*s))
+ *s = tolower(*s);
+}
diff --git a/dviware/quicspool/libprofile/free.c b/dviware/quicspool/libprofile/free.c
new file mode 100644
index 0000000000..1832e0c88f
--- /dev/null
+++ b/dviware/quicspool/libprofile/free.c
@@ -0,0 +1,62 @@
+static char *rcs = "$Header: free.c,v 1.1 88/01/15 12:16:58 simpson Rel $";
+/*
+$Log: free.c,v $
+ * Revision 1.1 88/01/15 12:16:58 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:02:11 simpson
+ * beta test
+ *
+*/
+#include "profile.h"
+
+profile_free_profile (s)
+PROFILE_STANZA *s;
+{
+ PROFILE_STANZA *x;
+
+ for (x = s; x != (PROFILE_STANZA *)0 && x != s; x = x->next)
+ profile_free_stanza(x);
+}
+
+profile_free_stanza (s)
+PROFILE_STANZA *s;
+{
+ free_markers(s->marker);
+ free_bindings(s->binding);
+ free(s);
+}
+
+static free_markers (m)
+PROFILE_MARKER *m;
+{
+ PROFILE_MARKER *x;
+
+ for (; m; m = x) {
+ x = m->next;
+ free(m);
+ }
+}
+
+static free_bindings (b)
+PROFILE_BINDING *b;
+{
+ PROFILE_BINDING *x;
+
+ for (; b; b = x) {
+ x = b->next;
+ free_values(b->value);
+ free(b);
+ }
+}
+
+static free_values (v)
+PROFILE_VALUE *v;
+{
+ PROFILE_VALUE *x;
+
+ for (; v; v = x) {
+ x = v->next;
+ free(v);
+ }
+}
diff --git a/dviware/quicspool/libprofile/has.c b/dviware/quicspool/libprofile/has.c
new file mode 100644
index 0000000000..a215cd3674
--- /dev/null
+++ b/dviware/quicspool/libprofile/has.c
@@ -0,0 +1,63 @@
+static char *rcs = "$Header: has.c,v 1.1 88/01/15 12:17:00 simpson Rel $";
+/*
+$Log: has.c,v $
+ * Revision 1.1 88/01/15 12:17:00 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:02:12 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include "profile.h"
+
+PROFILE_MARKER *profile_has_marker (s, m)
+PROFILE_STANZA *s;
+char *m;
+{
+ PROFILE_MARKER *x;
+ int result;
+
+ for (x = s->marker; x; x = x->next)
+ if(glob_match(x->text, m) > 0)
+ return(x);
+ return((PROFILE_MARKER *)0);
+}
+
+/*
+ * read down a linked list of stanzas looking
+ * for a stanza that has the requested markers
+ */
+PROFILE_STANZA *profile_has_stanza(s, marker)
+PROFILE_STANZA *s;
+char *marker[]; /* terminated by a null pointer */
+{
+ int i;
+ PROFILE_STANZA *x;
+
+ if (s == NULL)
+ return(s);
+ x = s;
+ do {
+ for (i = 0; marker[i] != NULL; i++)
+ if (profile_has_marker(x, marker[i]) == NULL)
+ break;
+ if (marker[i] == NULL)
+ return(x);
+ x = x->next;
+ } while (x != s && x != NULL);
+
+ return((PROFILE_STANZA *)NULL);
+}
+
+PROFILE_BINDING *profile_has_binding (s, b)
+PROFILE_STANZA *s;
+char *b;
+{
+ PROFILE_BINDING *x;
+
+ for (x = s->binding; x; x = x->next)
+ if (glob_match(x->name, b) > 0)
+ return(x);
+ return((PROFILE_BINDING *)0);
+}
diff --git a/dviware/quicspool/libprofile/makefile b/dviware/quicspool/libprofile/makefile
new file mode 100644
index 0000000000..369b5bc101
--- /dev/null
+++ b/dviware/quicspool/libprofile/makefile
@@ -0,0 +1,29 @@
+# $Header: Makefile,v 1.1 88/01/15 12:16:52 simpson Rel $
+# $Log: Makefile,v $
+#Revision 1.1 88/01/15 12:16:52 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 17:20:06 simpson
+#beta test
+#
+INCLUDE=/usr/include/local
+LIB=/usr/local/lib
+
+all: libprofile.a
+
+# This system include file is needed right away
+configure:
+ install -c -m 644 profile.h $(INCLUDE)
+
+libprofile.a: boolean.o free.o has.o read.o space.o write.o
+ ar cr libprofile.a boolean.o free.o has.o read.o space.o write.o
+ ranlib libprofile.a
+
+install:
+ install -c -m 644 profile.h $(INCLUDE)
+ install -m 644 libprofile.a $(LIB)
+
+clean:
+ -rm *.o libprofile.a
+
+boolean.o free.o has.o read.o space.o write.o: profile.h
diff --git a/dviware/quicspool/libprofile/makefile.trw b/dviware/quicspool/libprofile/makefile.trw
new file mode 100644
index 0000000000..ce136b7693
--- /dev/null
+++ b/dviware/quicspool/libprofile/makefile.trw
@@ -0,0 +1,29 @@
+# $Header: Makefile.TRW,v 1.1 88/01/15 12:16:54 simpson Rel $
+# $Log: Makefile.TRW,v $
+#Revision 1.1 88/01/15 12:16:54 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 17:20:07 simpson
+#beta test
+#
+INCLUDE=/usr/include/local
+LIB=/usr/local/lib
+
+all: libprofile.a
+
+# This system include file is needed right away
+configure:
+ install -c -m 644 profile.h $(INCLUDE)
+
+libprofile.a: boolean.o free.o has.o read.o space.o write.o
+ ar cr libprofile.a boolean.o free.o has.o read.o space.o write.o
+ ranlib libprofile.a
+
+install:
+ install -c -m 644 profile.h $(INCLUDE)
+ install -m 644 libprofile.a $(LIB)
+
+clean:
+ -rm *.o libprofile.a
+
+boolean.o free.o has.o read.o space.o write.o: profile.h
diff --git a/dviware/quicspool/libprofile/profile.h b/dviware/quicspool/libprofile/profile.h
new file mode 100644
index 0000000000..7e30a81e22
--- /dev/null
+++ b/dviware/quicspool/libprofile/profile.h
@@ -0,0 +1,63 @@
+/* $Header: profile.h,v 1.1 88/01/15 12:17:02 simpson Rel $ */
+/*
+$Log: profile.h,v $
+ * Revision 1.1 88/01/15 12:17:02 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:02:13 simpson
+ * beta test
+ *
+*/
+typedef struct PROFILE_VALUE {
+ char class;
+ union {
+ long int i;
+ double f;
+ char c;
+ char *s;
+ } value;
+ struct PROFILE_VALUE *previous;
+ struct PROFILE_VALUE *next;
+} PROFILE_VALUE;
+
+typedef struct PROFILE_BINDING {
+ char *name;
+ PROFILE_VALUE *value;
+ struct PROFILE_BINDING *previous;
+ struct PROFILE_BINDING *next;
+} PROFILE_BINDING;
+
+typedef struct PROFILE_MARKER {
+ char *text;
+ struct PROFILE_MARKER *previous;
+ struct PROFILE_MARKER *next;
+} PROFILE_MARKER;
+
+typedef struct PROFILE_STANZA {
+ PROFILE_MARKER *marker;
+ PROFILE_BINDING *binding;
+ struct PROFILE_STANZA *previous;
+ struct PROFILE_STANZA *next;
+} PROFILE_STANZA;
+
+/* classes */
+#define PROFILE_INTEGER 01
+#define PROFILE_FLOAT 02
+#define PROFILE_STRING 03
+#define PROFILE_CHARACTER 04
+#define PROFILE_OTHER 05
+#define PROFILE_OCTAL 06
+#define PROFILE_HEX 07
+
+/* no single lexical element may exceed this size in characters */
+#define PROFILE_MAX_TEXT 255
+
+PROFILE_STANZA *profile_read_stanza();
+PROFILE_STANZA *profile_read_profile();
+PROFILE_MARKER *profile_has_marker();
+PROFILE_STANZA *profile_has_stanza();
+PROFILE_BINDING *profile_has_binding();
+PROFILE_STANZA *profile_stanza_space();
+PROFILE_MARKER *profile_marker_space();
+PROFILE_BINDING *profile_binding_space();
+PROFILE_VALUE *profile_value_space();
diff --git a/dviware/quicspool/libprofile/read.c b/dviware/quicspool/libprofile/read.c
new file mode 100644
index 0000000000..3ab17765bf
--- /dev/null
+++ b/dviware/quicspool/libprofile/read.c
@@ -0,0 +1,834 @@
+static char *rcs = "$Header: read.c,v 1.1 88/01/15 12:17:05 simpson Rel $";
+/*
+$Log: read.c,v $
+ * Revision 1.1 88/01/15 12:17:05 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:02:13 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <ctype.h>
+#include "profile.h"
+
+#define isoctal(d) ('0' <= d && d <= '7')
+#define ishex(x) (isdigit(x) || ('a' <= x && x <= 'f') || ('A' <= x && x <= 'F'))
+#define isprime(c) (c == '\'')
+#define isbackslash(c) (c == '\\')
+#define iscaret(c) (c == '^')
+
+extern char *strcpy();
+extern PROFILE_STANZA *profile_stanza_space();
+extern PROFILE_MARKER *profile_marker_space();
+extern PROFILE_BINDING *profile_binding_space();
+extern PROFILE_VALUE *profile_value_space();
+
+static PROFILE_BINDING *get_binding();
+static PROFILE_BINDING *get_bindings();
+static PROFILE_MARKER *get_marker();
+static PROFILE_MARKER *get_markers();
+static PROFILE_VALUE *get_value();
+static PROFILE_VALUE *get_values();
+static char parse_character();
+static PROFILE_VALUE *parse_value();
+
+PROFILE_STANZA *profile_read_stanza (f)
+FILE *f;
+{
+ PROFILE_STANZA *stanza;
+
+ stanza = profile_stanza_space();
+ if (stanza == NULL)
+ return(NULL);
+ stanza->marker = get_markers(f);
+ if (get_open_bindings(f))
+ stanza->binding = get_bindings(f);
+ else {
+ profile_free_stanza(stanza);
+ return(NULL);
+ }
+ if (get_close_bindings(f))
+ return(stanza);
+ else {
+ profile_free_stanza(stanza);
+ return(NULL);
+ }
+}
+
+/* Returns the list of markers at the head of a stanza. */
+static PROFILE_MARKER *get_markers (f)
+FILE *f;
+{
+ PROFILE_MARKER *head, *tail, *m;
+
+ head = tail = NULL;
+ while (m = get_marker(f))
+ if (tail) {
+ tail->next = m;
+ m->previous = tail;
+ tail = m;
+ } else
+ head = tail = m;
+ return(head);
+}
+
+/* Returns the next marker from the head of the stanza. */
+static PROFILE_MARKER *get_marker (f)
+FILE *f;
+{
+ int n;
+ PROFILE_MARKER *m;
+ char scratch[PROFILE_MAX_TEXT+1];
+
+ for (;;)
+ if (n = get_name_text(f, scratch)) {
+ if ((m = profile_marker_space(n)) == NULL)
+ return(NULL);
+ strcpy(m->text, scratch);
+ return(m);
+ } else if (get_end_of_line(f))
+ continue;
+ else
+ return(NULL);
+}
+
+/* Returns the list of bindings in the body of the stanza. */
+static PROFILE_BINDING *get_bindings (f)
+FILE *f;
+{
+ PROFILE_BINDING *head, *tail, *b;
+
+ head = tail = NULL;
+ while (b = get_binding(f))
+ if (tail) {
+ tail->next = b;
+ b->previous = tail;
+ tail = b;
+ } else
+ head = tail = b;
+ return(head);
+}
+
+/* Returns the next binding in the body of the stanza. */
+static PROFILE_BINDING *get_binding (f)
+FILE *f;
+{
+ int n;
+ PROFILE_BINDING *b;
+ char scratch[PROFILE_MAX_TEXT+1];
+
+ for (;;)
+ if (n = get_name_text(f, scratch)) {
+ if ((b = profile_binding_space(n)) == NULL)
+ return(NULL);
+ strcpy(b->name, scratch);
+ break;
+ } else if (get_end_of_line(f))
+ continue;
+ else
+ return(NULL);
+ b->value = get_values(f);
+ return(b);
+}
+
+/* Returns the list of values following the name of the binding. */
+static PROFILE_VALUE *get_values (f)
+FILE *f;
+{
+ PROFILE_VALUE *head, *tail, *v;
+
+ head = tail = NULL;
+ while (v = get_value(f))
+ if (tail) {
+ tail->next = v;
+ v->previous = tail;
+ tail = v;
+ } else
+ head = tail = v;
+ return(head);
+}
+
+/* Returns the next value in the binding. */
+static PROFILE_VALUE *get_value (f)
+FILE *f;
+{
+ char text[PROFILE_MAX_TEXT+1];
+ int n;
+
+ for (;;)
+ if (n = get_value_text(f, text))
+ return(parse_value(text, n));
+ else if (get_end_of_line(f))
+ return(NULL);
+ else
+ return(NULL);
+}
+
+/*
+ * Reads the text of the next value (if any) in the binding. Returns
+ * the length of the literal text in characters.
+ */
+static int get_value_text (f, text)
+FILE *f;
+char *text;
+{
+ register int c;
+ char *s = text;
+
+ while ((c = getc(f)) != EOF)
+ switch (c) {
+ case '\b': case '\f':
+ case '\r': case '\t': case ' ':
+ /* white space terminates any text gathered so far */
+ if (s > text) {
+ *s = '\0';
+ return(s - text);
+ }
+ continue;
+
+ case '\n':
+ /* newline terminates a binding */
+ ungetc(c, f);
+ *s = '\0';
+ return(s - text);
+
+ case '#':
+ /* gobble up the comment */
+ while ((c = getc(f)) != EOF && c != '\n')
+ continue;
+ if (c == '\n')
+ ungetc(c, f);
+ *s = '\0';
+ return(s - text);
+
+ case '{': case '}':
+ ungetc(c, f);
+ *s = '\0';
+ return(s - text);
+
+ case '"': /* string quotes */
+ ungetc(c, f);
+ if (s > text) {
+ *s = '\0';
+ return(s - text);
+ } else
+ return(get_string(f, s));
+
+ case '\'': /* character quotes */
+ ungetc(c, f);
+ if (s > text) {
+ *s = '\0';
+ return(s - text);
+ } else
+ return(get_character(f, s));
+
+ case '\\': /* newline escape */
+ c = getc(f);
+ if (c == '\n') {
+ if (s > text) {
+ *s = '\0';
+ return(s - text);
+ }
+ continue; /* just like a blank */
+ }
+ ungetc(c, f);
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = '\\';
+ continue;
+
+ default:
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ continue;
+ }
+ *s = '\0';
+ return(s - text);
+}
+
+/* Digests the raw value text returning a new value structure. */
+static PROFILE_VALUE *parse_value (s, length)
+char *s; /* literal text */
+int length; /* in characters */
+{
+ PROFILE_VALUE *v;
+
+ if (is_integer(s)) {
+ if ((v = profile_value_space(0)) == NULL)
+ return(NULL);
+ v->class = PROFILE_INTEGER;
+ sscanf(s, "%D", &v->value.i);
+ } else if (is_octal(s)) {
+ if ((v = profile_value_space(0)) == NULL)
+ return(NULL);
+ v->class = PROFILE_OCTAL;
+ /* skip the `0o' prefix */
+ sscanf(s+2, "%O", &v->value.i);
+ } else if (is_hex(s)) {
+ if ((v = profile_value_space(0)) == NULL)
+ return(NULL);
+ v->class = PROFILE_HEX;
+ /* skip the `0x' prefix */
+ sscanf(s+2, "%X", &v->value.i);
+ } else if (is_string(s)) {
+ /* be careful when dealing with the empty string "" */
+ if ((v = profile_value_space(length > 2 ? length - 2 : 1)) == NULL)
+ return(NULL);
+ v->class = PROFILE_STRING;
+ /* erase the terminating double quote */
+ s[length - 1] = '\0';
+ /* skip past the initial quote */
+ parse_string(s + 1, v->value.s);
+ } else if (is_character(s)) {
+ if ((v = profile_value_space(0)) == NULL)
+ return(NULL);
+ v->class = PROFILE_CHARACTER;
+ /* erase the end single quote */
+ s[length - 1] = '\0';
+ v->value.c = parse_character(s + 1);
+ } else if (is_float(s)) {
+ if ((v = profile_value_space(0)) == NULL)
+ return(NULL);
+ v->class = PROFILE_FLOAT;
+ sscanf(s, "%E", &v->value.f);
+ } else {
+ if ((v = profile_value_space(length)) == NULL)
+ return(NULL);
+ v->class = PROFILE_OTHER;
+ strcpy(v->value.s, s);
+ }
+ return(v);
+}
+
+/* Converts a string literal to the internal representation. */
+static parse_string (source, result)
+char *source;
+char *result;
+{
+ for (; *source; source++)
+ if (*source == '\\')
+ switch (*++source) {
+ case 'b': /* backspace */
+ *result++ = '\b';
+ continue;
+ case 'f': /* formfeed */
+ *result++ = '\f';
+ continue;
+ case 'n': /* newline */
+ *result++ = '\n';
+ continue;
+ case 'r': /* carriage return */
+ *result++ = '\r';
+ continue;
+ case 't': /* horizontal tab */
+ *result++ = '\t';
+ continue;
+ case '\'': /* single quote */
+ *result++ = '\'';
+ continue;
+ case '"': /* double quote */
+ *result++ = '"';
+ continue;
+ case '\\': /* backslash */
+ *result++ = '\\';
+ continue;
+ case '^': /* caret */
+ *result++ = '^';
+ continue;
+ case '0': case '1': /* octal constant */
+ case '2': case '3':
+ case '4': case '5':
+ case '6': case '7':
+ source += parse_octal(source, result) - 2;
+ result++;
+ continue;
+ default:
+ *result++ = *source; /* ignore backslash */
+ }
+ else if (*source == '^') { /* control escape */
+ char c = *++source;
+ *result++ = ('@' <= c && c <= '_') ? c - '@' :
+ (c == '?') ? '\177' : c;
+ continue;
+ } else
+ *result++ = *source;
+ *result = '\0';
+}
+
+/* Converts a character literal to the internal representation. */
+static char parse_character (source)
+char *source;
+{
+ char c;
+
+ if (*source == '\\')
+ switch (*++source) {
+ case 'b': /* backspace */
+ return('\b');
+ case 'f': /* formfeed */
+ return('\f');
+ case 'n': /* newline */
+ return('\n');
+ case 'r': /* carriage return */
+ return('\r');
+ case 't': /* horizontal tab */
+ return('\t');
+ case '\'': /* single quote */
+ return('\'');
+ case '\\': /* backslash */
+ return('\\');
+ case '^':
+ return('^');
+ case '0': case '1': /* octal constant */
+ case '2': case '3':
+ case '4': case '5':
+ case '6': case '7':
+ parse_octal(source, &c);
+ return(c);
+ default:
+ return(*source); /* ignore backslash */
+ }
+ else if (*source == '^') { /* control escape */
+ c = *++source;
+ return(('@' <= c && c <= '_') ? c - '@' : (c == '?') ? '\177' : c);
+ } else
+ return(*source);
+}
+
+/* Converts an octal escape `\ddd' to its byte representation. */
+static int parse_octal (source, result)
+char *source;
+char *result;
+{
+ int count;
+ char byte = '\0';
+ char digit;
+
+ for (count = 1; count <= 3; count++) {
+ digit = *source++;
+ if ('0' <= digit && digit <= '7')
+ byte = (byte * 8) + (digit - '0');
+ else
+ break;
+ }
+ *result = byte;
+ return(count);
+}
+
+/*
+ * Reads the literal text for markers and binding names. Returns the
+ * length in characters of the literal text.
+ */
+static int get_name_text (f, text)
+FILE *f;
+char *text;
+{
+ register int c;
+ char *s = text;
+
+ while ((c = getc(f)) != EOF)
+ switch (c) {
+ case '\b': case '\f':
+ case '\r': case '\t': case ' ':
+ /* white space terminates text gathered so far */
+ if (s > text) {
+ *s = '\0';
+ return(s - text);
+ }
+ continue;
+
+ case '\n':
+ ungetc(c, f);
+ *s = '\0';
+ return(s - text);
+
+ case '#':
+ /* gobble up the comment */
+ while ((c = getc(f)) != EOF && c != '\n')
+ continue;
+ if (c == '\n')
+ ungetc(c, f);
+ *s = '\0';
+ return(s - text);
+
+ case '{': case '}':
+ ungetc(c, f);
+ *s = '\0';
+ return(s - text);
+
+ case '[':
+ /* sets may contain embedded white space */
+ if (s + 1 < &text[PROFILE_MAX_TEXT]) {
+ *s++ = '[';
+ if ((c = getc(f)) != EOF)
+ *s++ = c;
+ }
+ while ((c = getc(f)) != EOF) {
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ if (c == ']')
+ break;
+ }
+ continue;
+
+ case '\\':
+ c = getc(f);
+ if (c == '\n') {
+ if (s > text) {
+ *s = '\0';
+ return(s - text);
+ }
+ continue; /* just like a blank */
+ }
+ ungetc(c, f);
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = '\\';
+ continue;
+
+ default:
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ continue;
+ }
+ *s = '\0';
+ return(s - text);
+}
+
+/* Returns non-zero on end of line and zero otherwise. */
+static int get_end_of_line (f)
+FILE *f;
+{
+ int c;
+
+ if ((c = getc(f)) == '\n')
+ return(1);
+ ungetc(c, f);
+ return(0);
+}
+
+/* Returns non-zero on seeing `{' and zero otherwise. */
+static int get_open_bindings (f)
+FILE *f;
+{
+ int c;
+
+ if ((c = getc(f)) == '{')
+ return(1);
+ ungetc(c, f);
+ return(0);
+}
+
+/* Returns non-zero on seeing `}' and zero otherwise. */
+static int get_close_bindings (f)
+FILE *f;
+{
+ int c;
+
+ if ((c = getc(f)) == '}')
+ return(1);
+ ungetc(c, f);
+ return(0);
+}
+
+/* Reads a string literal returning the length of the literal text in characters */
+static int get_string (f, text)
+FILE *f;
+char *text;
+{
+ register int c;
+ char *s = text;
+
+ /* the first double quote is guaranteed */
+ *s++ = getc(f);
+ while ((c = getc(f)) != EOF)
+ switch (c) {
+ case '\\':
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ c = getc(f);
+ if (c == EOF)
+ return(s - text);
+ else if (c == '\n') {
+ ungetc(c, f);
+ return(s - text);
+ } else if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ continue;
+
+ case '"':
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ *s = '\0';
+ return(s - text);
+
+ case '\n':
+ ungetc(c, f);
+ *s = '\0';
+ return(s - text);
+
+ default:
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ continue;
+ }
+ *s = '\0';
+ return(s - text);
+}
+
+/* Reads a character literal returning the length of the literal text in characters. */
+static int get_character (f, text)
+FILE *f;
+char *text;
+{
+ register int c;
+ char *s = text;
+
+ /* the first single quote is guaranteed */
+ *s++ = getc(f);
+ while ((c = getc(f)) != EOF)
+ switch (c) {
+ case '\\':
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ c = getc(f);
+ if (c == EOF)
+ return(s - text);
+ else if (c == '\n') {
+ ungetc(c, f);
+ return(s - text);
+ } else if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ continue;
+ case '\'':
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ *s = '\0';
+ return(s - text);
+ case '\n':
+ ungetc(c, f);
+ *s = '\0';
+ return(s - text);
+ default:
+ if (s < &text[PROFILE_MAX_TEXT])
+ *s++ = c;
+ continue;
+ }
+ *s = '\0';
+ return(s - text);
+}
+
+/* all regular expressions below are in lex notation */
+
+/* returns non-zero iff -?[0-9]+ matches */
+static int is_integer (s)
+char *s;
+{
+ char *x;
+
+ /* -? */
+ if (*s == '-')
+ s++;
+ /* [0-9]+ */
+ for (x = s; isdigit(*s); s++)
+ continue;
+ return(s > x && !*s);
+}
+
+/* returns non-zero iff 0[oO][0-7]+ matches */
+static int is_octal (s)
+char *s;
+{
+ char *x;
+
+ /* 0 */
+ if (*s == '0')
+ s++;
+ else
+ return(0);
+ /* [oO] */
+ if (*s == 'o' || *s == 'O')
+ s++;
+ else
+ return(0);
+ /* [0-7]+ */
+ for (x = s; isoctal(*s); s++)
+ continue;
+ return(s > x && !*s);
+}
+
+/* returns non-zero iff 0[xX][0-9a-fA-F]+ matches */
+static int is_hex (s)
+char *s;
+{
+ char *x;
+
+ /* 0 */
+ if (*s == '0')
+ s++;
+ else
+ return(0);
+ /* [xX] */
+ if (*s == 'x' || *s == 'X')
+ s++;
+ else
+ return(0);
+ /* [0-9a-fA-F]+ */
+ for (x = s; ishex(*s); s++)
+ continue;
+ return(s > x && !*s);
+}
+
+/* returns non-zero iff [eE][-+]?[0-9]+ matches */
+static int is_exponent (s)
+char *s;
+{
+ char *x;
+
+ /* [eE] */
+ if (*s == 'e' || *s == 'E')
+ s++;
+ else
+ return(0);
+ /* [-+]? */
+ if (*s == '-' || *s == '+')
+ s++;
+ /* [0-9]+ */
+ for (x = s; isdigit(*s); s++)
+ continue;
+ return(s > x && !*s);
+}
+
+static int is_float (s)
+char *s;
+{
+ return(is_integer_part_float(s) ||
+ is_fractional_part_float(s) ||
+ is_power_float(s));
+}
+
+/* returns non-zero iff -?[0-9]+"."[0-9]*({exponent})? matches */
+static int is_integer_part_float (s)
+char *s;
+{
+ char *x;
+
+ /* -? */
+ if (*s == '-')
+ s++;
+ /* [0-9]+"." */
+ for (x = s; isdigit(*s); s++)
+ continue;
+ if (x == s || *s != '.')
+ return(0);
+ /* [0-9]* */
+ for (s++; isdigit(*s); s++)
+ continue;
+ /* ({exponent})? */
+ return(*s ? is_exponent(s) : 1);
+}
+
+/* returns non-zero iff -?"."[0-9]+({exponent})? matches */
+static int is_fractional_part_float (s)
+char *s;
+{
+ char *x;
+
+ /* -? */
+ if (*s == '-')
+ s++;
+ /* "." */
+ if (*s == '.')
+ s++;
+ else
+ return(0);
+ /* [0-9]+({exponent})? */
+ for (x = s; isdigit(*s); s++)
+ continue;
+ return(s > x ? !*s || is_exponent(s) : 0);
+}
+
+/* returns non-zero iff -?[0-9]+{exponent} matches */
+static int is_power_float (s)
+char *s;
+{
+ char *x;
+
+ /* -? */
+ if (*s == '-')
+ s++;
+ /* [0-9]+{exponent} */
+ for (x = s; isdigit(*s); s++)
+ continue;
+ return(s > x ? is_exponent(s) : 0);
+}
+
+/* returns non-zero iff '[^^\]' | '\^.' | '\\\\' | '\\'' | '\[0-7]{1-3}' matches */
+static int is_character (s)
+char *s;
+{
+ char *x;
+
+ if (isprime(*s))
+ s++;
+ else
+ return(0);
+ if (isbackslash(*s)) {
+ s++;
+ if ((isbackslash(s[0]) || isprime(s[0]) || !isdigit(s[0])) &&
+ isprime(s[1]) && !s[2])
+ return(1);
+ for (x = s; isoctal(*s); s++)
+ continue;
+ return(x < s && s < (x+4) && isprime(s[0]) && !s[1]);
+ } else if (iscaret(*s))
+ s++;
+ return(isprint(s[0]) && isprime(s[1]) && !s[2]);
+}
+
+/* returns non-zero iff s is a string constant */
+static int is_string (s)
+char *s;
+{
+ char *x;
+
+ if (*s != '"')
+ return(0);
+ for (s++; *s; s++) {
+ if (*s == '"')
+ return(!*++s); /* quote must be followed by null */
+ if (isbackslash(*s) || iscaret(*s)) {
+ if (*++s)
+ continue; /* legal escape */
+ return(0); /* null follows \ or ^ */
+ }
+ }
+ return(0);
+}
+
+/*
+ * read an entire profile, making a bidirectional
+ * circularly linked list
+ * returns pointer to the first stanza or NULL on error
+ */
+PROFILE_STANZA *profile_read_profile(f)
+FILE *f;
+{
+ PROFILE_STANZA *head = NULL;
+ PROFILE_STANZA *tail = NULL;
+ PROFILE_STANZA *x = NULL;
+
+ while ((x = profile_read_stanza(f)) != NULL) {
+ if (head == NULL)
+ head = tail = x;
+ else {
+ tail->next = x;
+ x->previous = tail;
+ tail = x;
+ }
+ }
+ if (head != NULL) {
+ tail->next = head;
+ head->previous = tail;
+ }
+ return(head);
+}
diff --git a/dviware/quicspool/libprofile/space.c b/dviware/quicspool/libprofile/space.c
new file mode 100644
index 0000000000..8bca164ae2
--- /dev/null
+++ b/dviware/quicspool/libprofile/space.c
@@ -0,0 +1,60 @@
+static char *rcs = "$Header: space.c,v 1.1 88/01/15 12:17:10 simpson Rel $";
+/*
+$Log: space.c,v $
+ * Revision 1.1 88/01/15 12:17:10 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:02:15 simpson
+ * beta test
+ *
+*/
+#include "profile.h"
+
+extern char *calloc();
+
+PROFILE_STANZA *profile_stanza_space ()
+{
+ return((PROFILE_STANZA *)calloc(1, sizeof(PROFILE_STANZA)));
+}
+
+PROFILE_MARKER *profile_marker_space (n)
+int n;
+{
+ char *space;
+ PROFILE_MARKER *m = (PROFILE_MARKER *)0;
+
+ if (space = calloc(1, sizeof(PROFILE_MARKER) + n + 1)) {
+ m = (PROFILE_MARKER *)space;
+ m->text = space + sizeof(PROFILE_MARKER);
+ }
+ return(m);
+}
+
+PROFILE_BINDING *profile_binding_space (n)
+int n; /* length of binding name in characters */
+{
+ char *space;
+ PROFILE_BINDING *b = (PROFILE_BINDING *)0;
+
+ if (space = calloc(1, sizeof(PROFILE_BINDING) + n + 1)) {
+ b = (PROFILE_BINDING *)space;
+ b->name = space + sizeof(PROFILE_BINDING);
+ }
+ return(b);
+}
+
+PROFILE_VALUE *profile_value_space (n)
+int n;
+{
+ char *space;
+ PROFILE_VALUE *v = (PROFILE_VALUE *)0;
+
+ if (n > 0) {
+ if (space = calloc(1, sizeof(PROFILE_VALUE) + n + 1)) {
+ v = (PROFILE_VALUE *)space;
+ v->value.s = space + sizeof(PROFILE_VALUE);
+ }
+ } else
+ v = (PROFILE_VALUE *)calloc(1, sizeof(PROFILE_VALUE));
+ return(v);
+}
diff --git a/dviware/quicspool/libprofile/write.c b/dviware/quicspool/libprofile/write.c
new file mode 100644
index 0000000000..af25db2c50
--- /dev/null
+++ b/dviware/quicspool/libprofile/write.c
@@ -0,0 +1,206 @@
+static char *rcs = "$Header: write.c,v 1.1 88/01/15 12:17:13 simpson Rel $";
+/*
+$Log: write.c,v $
+ * Revision 1.1 88/01/15 12:17:13 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:02:16 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <ctype.h>
+#include "profile.h"
+
+profile_write_stanza (f, s)
+FILE *f;
+PROFILE_STANZA *s;
+{
+ write_markers(f, s->marker);
+ fprintf(f, "{\n");
+ write_bindings(f, s->binding);
+ fprintf(f, "}\n");
+}
+
+static write_markers (f, m)
+FILE *f;
+PROFILE_MARKER *m;
+{
+ for (; m; m = m->next)
+ fprintf(f, "%s\n", m->text);
+}
+
+static write_bindings (f, b)
+FILE *f;
+PROFILE_BINDING *b;
+{
+ while (b) {
+ fprintf(f, "\t%s", b->name);
+ write_values(f, b->value);
+ fputc('\n', f);
+ b = b->next;
+ }
+}
+
+static write_values (f, v)
+FILE *f;
+PROFILE_VALUE *v;
+{
+ char scratch[PROFILE_MAX_TEXT+1];
+
+ for (; v; v = v->next)
+ switch (v->class) {
+ case PROFILE_INTEGER:
+ fprintf(f, " %D", v->value.i);
+ continue;
+ case PROFILE_FLOAT:
+ fprintf(f, " %G", v->value.f);
+ continue;
+ case PROFILE_STRING:
+ unparse_string(v->value.s, scratch);
+ fprintf(f, " \"%s\"", scratch);
+ continue;
+ case PROFILE_CHARACTER:
+ unparse_character(v->value.c, scratch);
+ fprintf(f, " '%s'", scratch);
+ continue;
+ case PROFILE_OCTAL:
+ fprintf(f, " 0o%O", v->value.i);
+ continue;
+ case PROFILE_HEX:
+ fprintf(f, " 0x%X", v->value.i);
+ continue;
+ case PROFILE_OTHER:
+ fprintf(f, " %s", v->value.s);
+ continue;
+ }
+}
+
+static int unparse_string (from, to)
+char *from;
+char *to;
+{
+ char *x = to;
+
+ for (; *from; from++)
+ switch (*from) {
+ case '\b': /* backspace */
+ *x++ = '\\';
+ *x++ = 'b';
+ continue;
+ case '\f': /* formfeed */
+ *x++ = '\\';
+ *x++ = 'f';
+ continue;
+ case '\n': /* newline */
+ *x++ = '\\';
+ *x++ = 'n';
+ continue;
+ case '\r':
+ *x++ = '\\';
+ *x++ = 'r';
+ continue;
+ case '\t': /* horizontal tab */
+ *x++ = '\\';
+ *x++ = 't';
+ continue;
+ case '\\': /* backslash */
+ *x++ = '\\';
+ *x++ = '\\';
+ continue;
+ case '"': /* double quote */
+ *x++ = '\\';
+ *x++ = '"';
+ continue;
+ case '^':
+ *x++ = '\\';
+ *x++ = '^';
+ continue;
+ default:
+ if (isascii(*from))
+ if (iscntrl(*from)) {
+ sprintf(x, "^%c", *from == '\177' ? '?' : *from + '@');
+ x += 2;
+ } else
+ *x++ = *from;
+ else {
+ sprintf(x, "\\%03o", *from);
+ x += 4;
+ }
+ continue;
+ }
+ *x = '\0';
+ return(x - to);
+}
+
+static int unparse_character (from, to)
+char from;
+char *to;
+{
+ char *x = to;
+
+ switch (from) {
+ case '\b': /* backspace */
+ *x++ = '\\';
+ *x++ = 'b';
+ break;
+ case '\f': /* formfeed */
+ *x++ = '\\';
+ *x++ = 'f';
+ break;
+ case '\n': /* newline */
+ *x++ = '\\';
+ *x++ = 'n';
+ break;
+ case '\r':
+ *x++ = '\\';
+ *x++ = 'r';
+ break;
+ case '\t': /* horizontal tab */
+ *x++ = '\\';
+ *x++ = 't';
+ break;
+ case '\\': /* backslash */
+ *x++ = '\\';
+ *x++ = '\\';
+ break;
+ case '\'': /* single quote */
+ *x++ = '\\';
+ *x++ = '\'';
+ break;
+ case '^':
+ *x++ = '\\';
+ *x++ = '^';
+ break;
+ default:
+ if (isascii(from))
+ if (iscntrl(from)) {
+ sprintf(x, "^%c", from == '\177' ? '?' : from + '@');
+ x += 2;
+ } else
+ *x++ = from;
+ else {
+ sprintf(x, "\\%03o", from);
+ x += 4;
+ }
+ break;
+ }
+ *x = '\0';
+ return(x - to);
+}
+
+/*
+ * write out a linked list of stanzas
+ */
+profile_write_profile(f, s)
+FILE *f;
+PROFILE_STANZA *s;
+{
+ PROFILE_STANZA *x;
+
+ for (x = s; x != NULL; x = x->next) {
+ profile_write_stanza(f, x);
+ if (x->next == s)
+ break;
+ }
+}
diff --git a/dviware/quicspool/libqmsquery/lexsed b/dviware/quicspool/libqmsquery/lexsed
new file mode 100644
index 0000000000..f480aae584
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/lexsed
@@ -0,0 +1,17 @@
+s/^yylex()/static &/
+s/^FILE \*yyin/static &/
+s/^int yyvstop\[\]/static &/
+s/^struct.*yycrank\[\] =/static &/
+s/^struct.*yysvec\[\] =/static &/
+s/^struct yywork \*yytop/static &/
+s/^struct yysvf \*yybgin/static &/
+s/^char yymatch\[\]/static &/
+s/^char yyextra\[\]/static &/
+s/^int yylineno/static &/
+s/^char \*yysptr/static &/
+s/^int yyprevious/static &/
+s/^yylook()/static &/
+s/^yyback(p, m)/static &/
+s/^yyinput(){/static &/
+s/^yyoutput(c)/static &/
+s/^yyunput(c)/static &/
diff --git a/dviware/quicspool/libqmsquery/makefile b/dviware/quicspool/libqmsquery/makefile
new file mode 100644
index 0000000000..2e628be509
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/makefile
@@ -0,0 +1,136 @@
+# $Header: Makefile,v 1.1 88/01/15 12:18:46 simpson Rel $
+# $Log: Makefile,v $
+#Revision 1.1 88/01/15 12:18:46 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 17:22:31 simpson
+#beta test
+#
+INCLUDE=/usr/include/local
+LIB=/usr/local/lib
+
+all: libqmsquery.a
+
+# This system include file is need right away
+configure:
+ install -c -m 644 qms.h $(INCLUDE)
+
+libqmsquery.a: qmsquery.o qmsmap.o qmspag.o qmsovl.o qmspfp.o qmsopc.o \
+ qmsram.o qmsfnt.o qmsver.o
+ ar rc $@ qmsquery.o qmsmap.o qmspag.o qmsovl.o qmspfp.o qmsopc.o \
+ qmsram.o qmsfnt.o qmsver.o
+ ranlib $@
+
+qmsquery.o: qms.h
+
+qmsmap.o: qms.h qmsmaplex.c
+
+qmsmap.c: qmsmap.y
+ $(YACC) $(YFLAGS) qmsmap.y
+ sed -f yaccsed < y.tab.c > qmsmap.c
+ rm y.tab.c
+
+qmsmaplex.c: qmsmaplex.l
+ $(LEX) $(LFLAGS) qmsmaplex.l
+ sed -f lexsed < lex.yy.c > qmsmaplex.c
+ rm lex.yy.c
+
+qmspag.o: qms.h qmspaglex.c
+
+qmspag.c: qmspag.y
+ $(YACC) $(YFLAGS) qmspag.y
+ sed -f yaccsed < y.tab.c > qmspag.c
+ rm y.tab.c
+
+qmspaglex.c: qmspaglex.l
+ $(LEX) $(LFLAGS) qmspaglex.l
+ sed -f lexsed < lex.yy.c > qmspaglex.c
+ rm lex.yy.c
+
+qmsovl.o: qms.h qmsovllex.c
+
+qmsovl.c: qmsovl.y
+ $(YACC) $(YFLAGS) qmsovl.y
+ sed -f yaccsed < y.tab.c > qmsovl.c
+ rm y.tab.c
+
+qmsovllex.c: qmsovllex.l
+ $(LEX) $(LFLAGS) qmsovllex.l
+ sed -f lexsed < lex.yy.c > qmsovllex.c
+ rm lex.yy.c
+
+qmspfp.o: qms.h qmspfplex.c
+
+qmspfp.c: qmspfp.y
+ $(YACC) $(YFLAGS) qmspfp.y
+ sed -f yaccsed < y.tab.c > qmspfp.c
+ rm y.tab.c
+
+qmspfplex.c: qmspfplex.l
+ $(LEX) $(LFLAGS) qmspfplex.l
+ sed -f lexsed < lex.yy.c > qmspfplex.c
+ rm lex.yy.c
+
+qmsopc.o: qms.h qmsopclex.c
+
+qmsopc.c: qmsopc.y
+ $(YACC) $(YFLAGS) qmsopc.y
+ sed -f yaccsed < y.tab.c > qmsopc.c
+ rm y.tab.c
+
+qmsopclex.c: qmsopclex.l
+ $(LEX) $(LFLAGS) qmsopclex.l
+ sed -f lexsed < lex.yy.c > qmsopclex.c
+ rm lex.yy.c
+
+qmsram.o: qms.h qmsramlex.c
+
+qmsram.c: qmsram.y
+ $(YACC) $(YFLAGS) qmsram.y
+ sed -f yaccsed < y.tab.c > qmsram.c
+ rm y.tab.c
+
+qmsramlex.c: qmsramlex.l
+ $(LEX) $(LFLAGS) qmsramlex.l
+ sed -f lexsed < lex.yy.c > qmsramlex.c
+ rm lex.yy.c
+
+qmsfnt.o: qms.h qmsfntlex.c
+
+qmsfnt.c: qmsfnt.y
+ $(YACC) $(YFLAGS) qmsfnt.y
+ sed -f yaccsed < y.tab.c > qmsfnt.c
+ rm y.tab.c
+
+qmsfntlex.c: qmsfntlex.l
+ $(LEX) $(LFLAGS) qmsfntlex.l
+ sed -f lexsed < lex.yy.c > qmsfntlex.c
+ rm lex.yy.c
+
+qmsver.o: qms.h qmsverlex.c
+
+qmsver.c: qmsver.y
+ $(YACC) $(YFLAGS) qmsver.y
+ sed -f yaccsed < y.tab.c > qmsver.c
+ rm y.tab.c
+
+qmsverlex.c: qmsverlex.l
+ $(LEX) $(LFLAGS) qmsverlex.l
+ sed -f lexsed < lex.yy.c > qmsverlex.c
+ rm lex.yy.c
+
+install:
+ install -c -m 644 qms.h $(INCLUDE)
+ install -m 644 libqmsquery.a $(LIB)
+
+clean:
+ -rm -f *.o y.tab.c lex.yy.c libqmsquery.a \
+ qmsmap.c qmsmaplex.c \
+ qmspag.c qmspaglex.c \
+ qmsovl.c qmsovllex.c \
+ qmspfp.c qmspfplex.c \
+ qmsopc.c qmsopclex.c \
+ qmsram.c qmsramlex.c \
+ qmsfnt.c qmsfntlex.c \
+ qmsver.c qmsverlex.c
+
diff --git a/dviware/quicspool/libqmsquery/makefile.trw b/dviware/quicspool/libqmsquery/makefile.trw
new file mode 100644
index 0000000000..f0ea4485a8
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/makefile.trw
@@ -0,0 +1,136 @@
+# $Header: Makefile.TRW,v 1.1 88/01/15 12:18:50 simpson Rel $
+# $Log: Makefile.TRW,v $
+#Revision 1.1 88/01/15 12:18:50 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 17:22:32 simpson
+#beta test
+#
+INCLUDE=/usr/include/local
+LIB=/usr/local/lib
+
+all: libqmsquery.a
+
+# This system include file is need right away
+configure:
+ install -c -m 644 qms.h $(INCLUDE)
+
+libqmsquery.a: qmsquery.o qmsmap.o qmspag.o qmsovl.o qmspfp.o qmsopc.o \
+ qmsram.o qmsfnt.o qmsver.o
+ ar rc $@ qmsquery.o qmsmap.o qmspag.o qmsovl.o qmspfp.o qmsopc.o \
+ qmsram.o qmsfnt.o qmsver.o
+ ranlib $@
+
+qmsquery.o: qms.h
+
+qmsmap.o: qms.h qmsmaplex.c
+
+qmsmap.c: qmsmap.y
+ $(YACC) $(YFLAGS) qmsmap.y
+ sed -f yaccsed < y.tab.c > qmsmap.c
+ rm y.tab.c
+
+qmsmaplex.c: qmsmaplex.l
+ $(LEX) $(LFLAGS) qmsmaplex.l
+ sed -f lexsed < lex.yy.c > qmsmaplex.c
+ rm lex.yy.c
+
+qmspag.o: qms.h qmspaglex.c
+
+qmspag.c: qmspag.y
+ $(YACC) $(YFLAGS) qmspag.y
+ sed -f yaccsed < y.tab.c > qmspag.c
+ rm y.tab.c
+
+qmspaglex.c: qmspaglex.l
+ $(LEX) $(LFLAGS) qmspaglex.l
+ sed -f lexsed < lex.yy.c > qmspaglex.c
+ rm lex.yy.c
+
+qmsovl.o: qms.h qmsovllex.c
+
+qmsovl.c: qmsovl.y
+ $(YACC) $(YFLAGS) qmsovl.y
+ sed -f yaccsed < y.tab.c > qmsovl.c
+ rm y.tab.c
+
+qmsovllex.c: qmsovllex.l
+ $(LEX) $(LFLAGS) qmsovllex.l
+ sed -f lexsed < lex.yy.c > qmsovllex.c
+ rm lex.yy.c
+
+qmspfp.o: qms.h qmspfplex.c
+
+qmspfp.c: qmspfp.y
+ $(YACC) $(YFLAGS) qmspfp.y
+ sed -f yaccsed < y.tab.c > qmspfp.c
+ rm y.tab.c
+
+qmspfplex.c: qmspfplex.l
+ $(LEX) $(LFLAGS) qmspfplex.l
+ sed -f lexsed < lex.yy.c > qmspfplex.c
+ rm lex.yy.c
+
+qmsopc.o: qms.h qmsopclex.c
+
+qmsopc.c: qmsopc.y
+ $(YACC) $(YFLAGS) qmsopc.y
+ sed -f yaccsed < y.tab.c > qmsopc.c
+ rm y.tab.c
+
+qmsopclex.c: qmsopclex.l
+ $(LEX) $(LFLAGS) qmsopclex.l
+ sed -f lexsed < lex.yy.c > qmsopclex.c
+ rm lex.yy.c
+
+qmsram.o: qms.h qmsramlex.c
+
+qmsram.c: qmsram.y
+ $(YACC) $(YFLAGS) qmsram.y
+ sed -f yaccsed < y.tab.c > qmsram.c
+ rm y.tab.c
+
+qmsramlex.c: qmsramlex.l
+ $(LEX) $(LFLAGS) qmsramlex.l
+ sed -f lexsed < lex.yy.c > qmsramlex.c
+ rm lex.yy.c
+
+qmsfnt.o: qms.h qmsfntlex.c
+
+qmsfnt.c: qmsfnt.y
+ $(YACC) $(YFLAGS) qmsfnt.y
+ sed -f yaccsed < y.tab.c > qmsfnt.c
+ rm y.tab.c
+
+qmsfntlex.c: qmsfntlex.l
+ $(LEX) $(LFLAGS) qmsfntlex.l
+ sed -f lexsed < lex.yy.c > qmsfntlex.c
+ rm lex.yy.c
+
+qmsver.o: qms.h qmsverlex.c
+
+qmsver.c: qmsver.y
+ $(YACC) $(YFLAGS) qmsver.y
+ sed -f yaccsed < y.tab.c > qmsver.c
+ rm y.tab.c
+
+qmsverlex.c: qmsverlex.l
+ $(LEX) $(LFLAGS) qmsverlex.l
+ sed -f lexsed < lex.yy.c > qmsverlex.c
+ rm lex.yy.c
+
+install:
+ install -c -m 644 qms.h $(INCLUDE)
+ install -m 644 libqmsquery.a $(LIB)
+
+clean:
+ -rm -f *.o y.tab.c lex.yy.c libqmsquery.a \
+ qmsmap.c qmsmaplex.c \
+ qmspag.c qmspaglex.c \
+ qmsovl.c qmsovllex.c \
+ qmspfp.c qmspfplex.c \
+ qmsopc.c qmsopclex.c \
+ qmsram.c qmsramlex.c \
+ qmsfnt.c qmsfntlex.c \
+ qmsver.c qmsverlex.c
+
diff --git a/dviware/quicspool/libqmsquery/qms.h b/dviware/quicspool/libqmsquery/qms.h
new file mode 100644
index 0000000000..7f28db646f
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qms.h
@@ -0,0 +1,186 @@
+/* $Header: qms.h,v 1.1 88/01/15 12:18:55 simpson Rel $ */
+/*
+$Log: qms.h,v $
+ * Revision 1.1 88/01/15 12:18:55 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:11:57 simpson
+ * beta test
+ *
+*/
+#define QUICON "\r^PY^-\r" /* QUIC Conversion On */
+#define QUICOFF "\r^-^PN^-\r" /* QUIC Conversion Off */
+#define PORTRAIT "^IOP" /* Portrait mode */
+#define LANDSCAPE "^IOL" /* Landscape mode */
+#define COMMAND "^N" /* Change command character */
+#define SYNTAX "^ISYNTAX" /* Set syntax of numeric parameters */
+#define FREEFORM "^F" /* Begin free-form input */
+#define FREEOFF "^O" /* End free-form input */
+#define IGNOREDATA "^X" /* Ignore subsequent input */
+#define ENDIGNORE "^A" /* Stop ignoring data */
+#define INITIALIZE "^IF" /* Select tray, offset page length */
+#define STATUS "^ISTATUS" /* Print status page */
+#define SPECIAL "^$" /* Enter special characters */
+#define INITJUST "^IJ" /* Default top page margin */
+#define INITBOTTOM "^IB" /* Default bottom page margin */
+#define INITTAB "^IT" /* Default left page margin */
+#define JUSTIFY "^J" /* Vertical positioning */
+#define JUSTIFYMARGIN "^JM" /* Vertical positioning from margin */
+#define JUSTIFYRELATIVE "^JR" /* Relative vertical positioning */
+#define JUSTIFYDOTS "^JD" /* Relative vertical in dots */
+#define TAB "^T" /* Horizontal positioning */
+#define TABRELATIVE "^TR" /* Relative horizontal positioning */
+#define TABDOTS "^TD" /* Relative horizontal in dots */
+#define INITMARGVERT "^IMV" /* Default vertical margins */
+#define INITMARGHORZ "^IMH" /* Default horizontal margins */
+#define DEFFONT "^IS" /* Default font select */
+#define FONT "^S" /* Select font */
+#define CHARSPACING "^IC" /* Character spacing */
+#define LINESPACING "^IL" /* Line spacing */
+#define DOWNLOAD "^DF" /* Download font */
+#define ADOWNLOAD "^DFA" /* Advanced download font */
+#define QUICCHAR "^M" /* Quic characters */
+#define VERTQUIC "^V" /* Vertical Quic characters */
+#define LEFTVERTQUIC "^E" /* Left vertical Quic characters */
+#define INVERTQUIC "^U" /* Upside down Quic characters */
+#define DESCENDER "^DL" /* Lower case descenders on */
+#define HALFTONE "^KH" /* Half tone */
+#define HALFTONESELECT "^KL" /* Select a half tone */
+#define REVERSE "^R" /* Reverse image */
+#define LINE "^LS" /* Line drawing */
+#define DASHEDLINE "^LD" /* Dashed lines */
+#define HORLINEPLOT "^LP" /* Horizontal line plotting */
+#define VERTLINEPLOT "^LQ" /* Vertical line plotting */
+#define ARC "^LA" /* Arc drawing */
+#define DECIMALARC "^LAD" /* Decimal arc drawing */
+#define BOX "^LB" /* Box drawing */
+#define FORM "^LF" /* Form drawing */
+#define HORFORM "^LE" /* Horizontal form drawing */
+#define PLOT "^P" /* Plotting */
+#define PATTVEC "^PV" /* Pattern vector */
+#define PLOTEXPAND "^IP" /* Plot expansion */
+#define PENWIDTH "^PW" /* Pen width */
+#define PENUP "^U" /* Pen up */
+#define PENDOWN "^D" /* Pen down */
+#define PENERASE "^E" /* Pen erase */
+#define VECTORON "^IGV" /* Vector graphics on */
+#define VECTOROFF "^IGE" /* Vector graphics off */
+#define BARCHART "^BAR" /* Bar chart drawing */
+#define PIECHART "^LAP" /* Pie chart drawing */
+#define AREAFILL "^LAF" /* Area fill */
+#define REPEAT "^DR" /* Repeat command */
+#define AUTOINCDEC "^Y" /* Automatic increment/decrement */
+#define INFO "^INFO" /* Get information from printer */
+#define COPIES "^DC" /* Number of page copies */
+#define STOREOVERLAY "^DOS" /* Store an overlay sequence */
+#define RECALLOVERLAY "^DOR" /* Recall an overlay sequence */
+#define CLEAROVERLAY "^DOC" /* Clear an overlay sequence */
+#define AUTOOVERLAY "^DAOS" /* Define an automatic overlay */
+#define CLEARAOVERLAY "^DAOC" /* Clear an automatic overlay */
+#define HORBARCODE "^B" /* Horizontal barcodes */
+#define VERTBARCODE "^C" /* Vertical barcodes */
+#define DIABLO "^IWD" /* Enable diablo simulation */
+#define QUME "^IWQ" /* Enable QUME simulation */
+#define EXITSIMULATE "^IWE" /* Exit simulation mode */
+#define PCONFIG "^ICFG" /* Printer configuration */
+#define TEXTPROC "^ISTF" /* Text processing command */
+#define EIGHTBITON "^(" /* Turn on eight bit format */
+#define EIGHTBITOFF "^)" /* Turn off eight bit format */
+
+#define ENDPASS "^-" /* End pass */
+#define NEWLINE "^*" /* End pass, new line */
+#define FORMFEED "^," /* End pass, form feed */
+#define ENDCMD "^G" /* Command terminator */
+#define HEIGHT "^H" /* Quic character height */
+#define WIDTH "^W" /* Quic character width */
+
+/* Structure returned when requesting MAP info */
+struct qmsmap {
+ int count; /* Byte count */
+ int checksum;
+ char *data; /* "count" bytes of data terminated by NULL */
+ struct qmsmap *next;
+};
+
+/* Structure returned when requesting PAG info */
+struct qmspag {
+ char PO; /* Orientation. 'P' or 'L' */
+ float TM; /* Top margin */
+ float BM; /* Bottom margin */
+ float LM; /* Left margin */
+ float RM; /* Right margin */
+ float LPI; /* Lines per inch */
+ float CPI; /* Characters per inch. 0 == Proportional */
+ short PT; /* Paper Tray. 0 == Top tray. 1 == Bottom Tray */
+ short PS; /* Page Size. 0 == Short. 1 == Long. 2 == European A-4 */
+ char SO; /* Stacker Offset. 'Y' or 'N' */
+ short CC; /* Copy Count */
+};
+
+/* Structure returned when requesting OVL info */
+struct qmsovl {
+ enum { regular, automatic } ovltype;
+ /* The number and size are only valid for regular overlays */
+ int ovlnumber; /* Overlay number */
+ int ovlsize; /* Overlay size in bytes */
+ struct qmsovl *next;
+};
+
+/* Structure returned when requesting PFP info */
+struct qmspfp {
+ char *module; /* Name of installed module */
+ struct qmspfp *next;
+};
+
+/* Structure returned when requesting OPC info */
+struct qmsopc {
+ struct optnode *OC1, *OC2, *OC3, *OC4, *OC5;
+};
+
+struct optnode {
+ short option; /* Number of option */
+ struct optnode *next;
+};
+
+/* Structure returned when requesting RAM info */
+struct qmsram {
+ short TR; /* Total Ram memory in printer */
+ short AR; /* Current Available Ram memory */
+ short FR; /* Font Ram memory used */
+ short OR; /* Overlay Ram memory used */
+};
+
+/* Structure returned when requesting FNTB info */
+struct qmsfnt {
+ struct fontnode *rom; /* List of rom fonts */
+ struct fontnode *ram; /* List of ram fonts */
+};
+
+struct fontnode {
+ char orientation; /* 'P' or 'L' */
+ short number; /* Font number */
+ long bytes; /* Number of bytes in printer */
+ char version;
+ char class; /* '1' or '2' */
+ struct fontnode *next;
+};
+
+/* Structure returned when requesting version information */
+struct qmsver {
+ float version; /* Version of QUIC */
+ float firmware; /* Version of the firmware */
+ struct date { /* Date of the firmware */
+ short month;
+ short day;
+ short year; /* Without the 1900 */
+ } date;
+};
+
+struct qmsmap *qmsmap();
+struct qmspag *qmspag();
+struct qmsovl *qmsovl();
+struct qmspfp *qmspfp();
+struct qmsopc *qmsopc();
+struct qmsram *qmsram();
+struct qmsfnt *qmsfnt();
+struct qmsver *qmsver();
diff --git a/dviware/quicspool/libqmsquery/qmsfnt.y b/dviware/quicspool/libqmsquery/qmsfnt.y
new file mode 100644
index 0000000000..b670c24d08
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qmsfnt.y
@@ -0,0 +1,94 @@
+%{
+#ifndef lint
+static char *rcs = "$Header: qmsfnt.y,v 1.1 88/01/15 12:18:57 simpson Rel $";
+#endif
+/*
+$Log: qmsfnt.y,v $
+ * Revision 1.1 88/01/15 12:18:57 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:11:59 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <setjmp.h>
+#include <local/standard.h>
+#include "qms.h"
+
+extern FILE *_Ifp, *_Ofp;
+extern Boolean _FirstChar;
+static jmp_buf Env;
+char *malloc();
+static struct qmsfnt Fnt;
+static struct fontnode *P;
+%}
+%token FRO FDL INTEGER CHAR NONE ENDLINE
+%%
+fntlines : fntlines fntline | /* epsilon */ ;
+
+fntline :
+ fonttype NONE ENDLINE
+ {
+ if ($1 == FRO)
+ Fnt.rom = NULL;
+ else
+ Fnt.ram = NULL;
+ }
+ |
+ fonttype orientation INTEGER 'S' INTEGER 'V' anychar 'C' anychar ENDLINE
+ {
+ P = (struct fontnode *)malloc((unsigned)sizeof(struct fontnode));
+ if ($1 == FRO) {
+ P->next = Fnt.rom, Fnt.rom = P;
+ } else {
+ P->next = Fnt.ram, Fnt.ram = P;
+ }
+ P->orientation = $2;
+ P->number = $3;
+ P->bytes = $5;
+ P->version = $7;
+ P->class = $9;
+ }
+ ;
+
+fonttype : FRO | FDL ;
+
+orientation : 'P' | 'L' ;
+
+anychar :
+ 'P' | 'L' | 'S' | 'V' | 'C' | CHAR
+ |
+ INTEGER
+ {
+ $$ = '0' + $1;
+ }
+ ;
+%%
+#include "qmsfntlex.c"
+
+struct qmsfnt *qmsfnt()
+{
+ _FirstChar = TRUE;
+ Fnt.rom = Fnt.ram = NULL;
+ fputs(QUICON, _Ofp);
+ fprintf(_Ofp, "%s00000", SYNTAX);
+ fprintf(_Ofp, "%sFNTB%s", INFO, ENDCMD);
+ fputs(QUICOFF, _Ofp);
+ (void)fflush(_Ofp);
+ if (setjmp(Env)) {
+ while (timedgetc(_Ifp) != EOF) /* Discard remaining input */
+ ;
+ return NULL;
+ }
+ if (yyparse() != 0)
+ return NULL;
+ yysptr = yysbuf; /* Resets lex lookahead buffer */
+ return &Fnt;
+}
+
+static yyerror(s)
+char *s;
+{
+ longjmp(Env, TRUE);
+}
diff --git a/dviware/quicspool/libqmsquery/qmsfntlex.l b/dviware/quicspool/libqmsquery/qmsfntlex.l
new file mode 100644
index 0000000000..ea94910f97
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qmsfntlex.l
@@ -0,0 +1,43 @@
+/* $Header: qmsfntlex.l,v 1.1 88/01/15 12:19:00 simpson Rel $ */
+%{
+/*
+$Log: qmsfntlex.l,v $
+ * Revision 1.1 88/01/15 12:19:00 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 21:34:44 simpson
+ * beta test
+ *
+*/
+#undef input
+#define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):timedgetc(_Ifp)) \
+ ==10?(yylineno++, yytchar):yytchar)==EOF?0:yytchar)
+%}
+integer [0-9]+
+%%
+FRO: {
+ yylval = FRO;
+ return FRO;
+ }
+FDL: {
+ yylval = FDL;
+ return FDL;
+ }
+{integer} {
+ yylval = atoi(yytext);
+ return INTEGER;
+ }
+P |
+L |
+S |
+V |
+C {
+ yylval = yytext[0];
+ return yytext[0];
+ }
+. {
+ yylval = yytext[0];
+ return CHAR;
+ }
+NONE return NONE;
+\r\n return ENDLINE;
diff --git a/dviware/quicspool/libqmsquery/qmsmap.y b/dviware/quicspool/libqmsquery/qmsmap.y
new file mode 100644
index 0000000000..e535e91bd9
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qmsmap.y
@@ -0,0 +1,108 @@
+%{
+#ifndef lint
+static char *rcs = "$Header: qmsmap.y,v 1.1 88/01/15 12:19:03 simpson Rel $";
+#endif
+/*
+$Log: qmsmap.y,v $
+ * Revision 1.1 88/01/15 12:19:03 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:12:01 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <setjmp.h>
+#include <local/standard.h>
+#include "qms.h"
+
+extern FILE *_Ifp, *_Ofp;
+extern Boolean _FirstChar;
+static jmp_buf Env;
+char *malloc();
+static struct qmsmap *MapList, *P;
+static int ByteCount, CheckSum;
+char S[77];
+%}
+%union {
+ char s[77];
+}
+%token <s> MAP MAPEND BYTECOUNT DATA ENDLINE
+%%
+mapdata :
+ MAP ENDLINE
+ datalines
+ MAPEND ENDLINE
+ ;
+
+datalines :
+ datalines
+ dataline
+ {
+ if (MapList == NULL) {
+ MapList = (struct qmsmap *)malloc((unsigned)
+ sizeof(struct qmsmap));
+ MapList->count = ByteCount;
+ MapList->checksum = CheckSum;
+ (void)strcpy(MapList->data = malloc((unsigned)(strlen(S)
+ + 1)), S);
+ MapList->next = NULL;
+ } else {
+ for (P = MapList; P->next; P = P->next)
+ ;
+ P->next = (struct qmsmap *)malloc((unsigned)
+ sizeof(struct qmsmap));
+ P = P->next;
+ P->count = ByteCount;
+ P->checksum = CheckSum;
+ (void)strcpy(P->data = malloc((unsigned)(strlen(S) + 1)), S);
+ P->next = NULL;
+ }
+ }
+ |
+ /* epsilon */
+ ;
+
+dataline :
+ BYTECOUNT
+ {
+ (void)sscanf(&$1[1], "%X", &ByteCount);
+ }
+ DATA
+ {
+ (void)sscanf(&$3[strlen($3) - 4], "%X", &CheckSum);
+ $3[strlen($3) - 4] = '\0';
+ (void)strcpy(S, $3);
+ }
+ ENDLINE
+ ;
+%%
+#include "qmsmaplex.c"
+
+struct qmsmap *qmsmap(north, south, west, east)
+double north, south, west, east;
+{
+ _FirstChar = TRUE;
+ MapList = NULL;
+ fputs(QUICON, _Ofp);
+ fprintf(_Ofp, "%s00000", SYNTAX);
+ fprintf(_Ofp, "%sMAP%05d%05d%05d%05d%s", INFO, (int)(north * 1000),
+ (int)(south * 1000), (int)(west * 1000), (int)(east * 1000), ENDCMD);
+ fputs(QUICOFF, _Ofp);
+ (void)fflush(_Ofp);
+ if (setjmp(Env)) {
+ while (timedgetc(_Ifp) != EOF) /* Discard remaining input */
+ ;
+ return NULL;
+ }
+ if (yyparse() != 0)
+ return NULL;
+ yysptr = yysbuf; /* Resets lex lookahead buffer */
+ return MapList;
+}
+
+static yyerror(s)
+char *s;
+{
+ longjmp(Env, TRUE);
+}
diff --git a/dviware/quicspool/libqmsquery/qmsmaplex.l b/dviware/quicspool/libqmsquery/qmsmaplex.l
new file mode 100644
index 0000000000..3ef469a91f
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qmsmaplex.l
@@ -0,0 +1,28 @@
+/* $Header: qmsmaplex.l,v 1.1 88/01/15 12:19:06 simpson Rel $ */
+%{
+/*
+$Log: qmsmaplex.l,v $
+ * Revision 1.1 88/01/15 12:19:06 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 21:34:45 simpson
+ * beta test
+ *
+*/
+#undef input
+#define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):timedgetc(_Ifp)) \
+ ==10?(yylineno++, yytchar):yytchar)==EOF?0:yytchar)
+%}
+hex [0-9A-F]
+%%
+MAP: return MAP;
+MAPEND return MAPEND;
+^Q{hex}{hex}{hex}{hex} {
+ (void)strcpy(yylval.s, yytext);
+ return BYTECOUNT;
+ }
+{hex}+ {
+ (void)strcpy(yylval.s, yytext);
+ return DATA;
+ }
+\r\n return ENDLINE;
diff --git a/dviware/quicspool/libqmsquery/qmsopc.y b/dviware/quicspool/libqmsquery/qmsopc.y
new file mode 100644
index 0000000000..c72ebe9800
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qmsopc.y
@@ -0,0 +1,133 @@
+%{
+#ifndef lint
+static char *rcs = "$Header: qmsopc.y,v 1.1 88/01/15 12:19:09 simpson Rel $";
+#endif
+/*
+$Log: qmsopc.y,v $
+ * Revision 1.1 88/01/15 12:19:09 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:12:03 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <setjmp.h>
+#include <local/standard.h>
+#include "qms.h"
+
+extern FILE *_Ifp, *_Ofp;
+extern Boolean _FirstChar;
+static jmp_buf Env;
+char *malloc();
+static struct qmsopc Opc;
+static struct optnode *P;
+%}
+%token NONE ENDLINE
+%token <i> OC INTEGER
+%type <p> numlist
+%union {
+ int i;
+ struct optnode *p;
+}
+%%
+opclines : opclines opcline | opcline ;
+
+opcline :
+ OC NONE ENDLINE
+ {
+ switch ($1) {
+ case 1:
+ Opc.OC1 = NULL;
+ break;
+ case 2:
+ Opc.OC2 = NULL;
+ break;
+ case 3:
+ Opc.OC3 = NULL;
+ break;
+ case 4:
+ Opc.OC4 = NULL;
+ break;
+ case 5:
+ Opc.OC5 = NULL;
+ break;
+ }
+ }
+ |
+ OC numlist ENDLINE
+ {
+ switch ($1) {
+ case 1:
+ Opc.OC1 = $2;
+ break;
+ case 2:
+ Opc.OC2 = $2;
+ break;
+ case 3:
+ Opc.OC3 = $2;
+ break;
+ case 4:
+ Opc.OC4 = $2;
+ break;
+ case 5:
+ Opc.OC5 = $2;
+ break;
+ }
+ }
+ ;
+
+numlist :
+ numlist INTEGER optcomma
+ {
+ if ($1 == NULL) {
+ $1 = (struct optnode *)malloc((unsigned)
+ sizeof(struct optnode));
+ $1->option = $2;
+ $1->next = NULL;
+ } else {
+ for (P = $1; P->next; P = P->next)
+ ;
+ P->next = (struct optnode *)malloc((unsigned)
+ sizeof(struct optnode));
+ P = P->next;
+ P->option = $2;
+ P->next = NULL;
+ }
+ $$ = $1;
+ }
+ |
+ {
+ /* epsilon */
+ $$ = NULL;
+ }
+ ;
+
+optcomma : ',' | /* epsilon */ ;
+%%
+#include "qmsopclex.c"
+
+struct qmsopc *qmsopc()
+{
+ _FirstChar = TRUE;
+ fputs(QUICON, _Ofp);
+ fprintf(_Ofp, "%s00000", SYNTAX);
+ fprintf(_Ofp, "%sOPC%s", INFO, ENDCMD);
+ fputs(QUICOFF, _Ofp);
+ (void)fflush(_Ofp);
+ if (setjmp(Env)) {
+ while (timedgetc(_Ifp) != EOF) /* Discard remaining input */
+ ;
+ return NULL;
+ }
+ if (yyparse() != 0)
+ return NULL;
+ yysptr = yysbuf; /* Resets lex lookahead buffer */
+ return &Opc;
+}
+
+static yyerror(s)
+char *s;
+{
+ longjmp(Env, TRUE);
+}
diff --git a/dviware/quicspool/libqmsquery/qmsopclex.l b/dviware/quicspool/libqmsquery/qmsopclex.l
new file mode 100644
index 0000000000..e35f4b137c
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qmsopclex.l
@@ -0,0 +1,28 @@
+/* $Header: qmsopclex.l,v 1.1 88/01/15 12:19:11 simpson Rel $
+%{
+/*
+$Log: qmsopclex.l,v $
+ * Revision 1.1 88/01/15 12:19:11 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 21:34:46 simpson
+ * beta test
+ *
+*/
+#undef input
+#define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):timedgetc(_Ifp)) \
+ ==10?(yylineno++, yytchar):yytchar)==EOF?0:yytchar)
+%}
+integer [0-9]+
+%%
+OC[1-5]: {
+ yylval.i = yytext[2] - '0';
+ return OC;
+ }
+{integer} {
+ yylval.i = atoi(yytext);
+ return INTEGER;
+ }
+\, return yytext[0];
+NONE return NONE;
+\r\n return ENDLINE;
diff --git a/dviware/quicspool/libqmsquery/qmsovl.y b/dviware/quicspool/libqmsquery/qmsovl.y
new file mode 100644
index 0000000000..6c96de10d3
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qmsovl.y
@@ -0,0 +1,80 @@
+%{
+#ifndef lint
+static char *rcs = "$Header: qmsovl.y,v 1.1 88/01/15 12:19:13 simpson Rel $";
+#endif
+/*
+$Log: qmsovl.y,v $
+ * Revision 1.1 88/01/15 12:19:13 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:12:05 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <setjmp.h>
+#include <local/standard.h>
+#include "qms.h"
+
+extern FILE *_Ifp, *_Ofp;
+extern Boolean _FirstChar;
+static jmp_buf Env;
+char *malloc();
+static struct qmsovl *OvlList, *P;
+%}
+%token OVL INTEGER SPACE AUTOPAGE NONE ENDLINE
+%%
+ovllines : ovllines ovlline | ovlline ;
+
+ovlline : OVL overlay ENDLINE ;
+
+overlay :
+ NONE
+ {
+ OvlList = NULL;
+ }
+ |
+ INTEGER SPACE
+ {
+ P = (struct qmsovl *)malloc((unsigned)sizeof(struct qmsovl));
+ P->next = OvlList, OvlList = P;
+ P->ovltype = regular;
+ P->ovlnumber = $1;
+ P->ovlsize = $2;
+ }
+ |
+ AUTOPAGE
+ {
+ P = (struct qmsovl *)malloc((unsigned)sizeof(struct qmsovl));
+ P->next = OvlList, OvlList = P;
+ P->ovltype = automatic;
+ }
+ ;
+%%
+#include "qmsovllex.c"
+
+struct qmsovl *qmsovl()
+{
+ _FirstChar = TRUE;
+ OvlList = NULL;
+ fputs(QUICON, _Ofp);
+ fprintf(_Ofp, "%s00000", SYNTAX);
+ fprintf(_Ofp, "%sOVL%s", INFO, ENDCMD);
+ fputs(QUICOFF, _Ofp);
+ (void)fflush(_Ofp);
+ if (setjmp(Env)) {
+ while (timedgetc(_Ifp) != EOF) /* Discard remaining input */
+ ;
+ return NULL;
+ }
+ if (yyparse() != 0)
+ return NULL;
+ yysptr = yysbuf; /* Resets lex lookahead buffer */
+ return OvlList;
+}
+
+static yyerror(s)
+char *s;
+{
+ longjmp(Env, TRUE);
+}
diff --git a/dviware/quicspool/libqmsquery/qmsovllex.l b/dviware/quicspool/libqmsquery/qmsovllex.l
new file mode 100644
index 0000000000..ab485be5de
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qmsovllex.l
@@ -0,0 +1,29 @@
+/* $Header: qmsovllex.l,v 1.1 88/01/15 12:19:16 simpson Rel $
+%{
+/*
+$Log: qmsovllex.l,v $
+ * Revision 1.1 88/01/15 12:19:16 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 21:34:47 simpson
+ * beta test
+ *
+*/
+#undef input
+#define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):timedgetc(_Ifp)) \
+ ==10?(yylineno++, yytchar):yytchar)==EOF?0:yytchar)
+%}
+integer [0-9]+
+%%
+OVL: return OVL;
+S{integer} {
+ yylval = atoi(&yytext[1]);
+ return SPACE;
+ }
+{integer} {
+ yylval = atoi(yytext);
+ return INTEGER;
+ }
+"Automatic Page" return AUTOPAGE;
+NONE return NONE;
+\r\n return ENDLINE;
diff --git a/dviware/quicspool/libqmsquery/qmspag.y b/dviware/quicspool/libqmsquery/qmspag.y
new file mode 100644
index 0000000000..ce3e25235a
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qmspag.y
@@ -0,0 +1,162 @@
+%{
+#ifndef lint
+static char *rcs = "$Header: qmspag.y,v 1.1 88/01/15 12:19:19 simpson Rel $";
+#endif
+/*
+$Log: qmspag.y,v $
+ * Revision 1.1 88/01/15 12:19:19 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:12:07 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <setjmp.h>
+#include <local/standard.h>
+#include "qms.h"
+
+extern FILE *_Ifp, *_Ofp;
+extern Boolean _FirstChar;
+static jmp_buf Env;
+static struct qmspag Result;
+%}
+%union {
+ float r;
+ int i;
+}
+%token PAG POT TMT BMT LMT RMT LPIT CPIT PROP PTT PST SOT CCT ENDLINE
+%token <r> REAL
+%token <i> INTEGER
+%type <i> orientation yesorno 'P' 'L' 'Y' 'N'
+%%
+paglines : paglines pagline | pagline ;
+
+pagline : PAG settings ENDLINE ;
+
+settings : settings setting optcomma | /* epsilon */ ;
+
+setting :
+ POT '=' orientation
+ {
+ Result.PO = $3;
+ }
+ |
+ TMT '=' INTEGER
+ {
+ Result.TM = $3;
+ }
+ |
+ TMT '=' REAL
+ {
+ Result.TM = $3;
+ }
+ |
+ BMT '=' INTEGER
+ {
+ Result.BM = $3;
+ }
+ |
+ BMT '=' REAL
+ {
+ Result.BM = $3;
+ }
+ |
+ LMT '=' INTEGER
+ {
+ Result.LM = $3;
+ }
+ |
+ LMT '=' REAL
+ {
+ Result.LM = $3;
+ }
+ |
+ RMT '=' INTEGER
+ {
+ Result.RM = $3;
+ }
+ |
+ RMT '=' REAL
+ {
+ Result.RM = $3;
+ }
+ |
+ LPIT '=' INTEGER
+ {
+ Result.LPI = $3;
+ }
+ |
+ LPIT '=' REAL
+ {
+ Result.LPI = $3;
+ }
+ |
+ CPIT '=' INTEGER
+ {
+ Result.CPI = $3;
+ }
+ |
+ CPIT '=' REAL
+ {
+ Result.CPI = $3;
+ }
+ |
+ CPIT '=' PROP
+ {
+ Result.CPI = 0;
+ }
+ |
+ PTT '=' INTEGER
+ {
+ Result.PT = $3;
+ }
+ |
+ PST '=' INTEGER
+ {
+ Result.PS = $3;
+ }
+ |
+ SOT '=' yesorno
+ {
+ Result.SO = $3;
+ }
+ |
+ CCT '=' INTEGER
+ {
+ Result.CC = $3;
+ }
+ ;
+
+orientation : 'P' | 'L' ;
+
+yesorno : 'Y' | 'N' ;
+
+optcomma : ',' | /* epsilon */ ;
+%%
+#include "qmspaglex.c"
+
+struct qmspag *qmspag()
+{
+ _FirstChar = TRUE;
+ fputs(QUICON, _Ofp);
+ fprintf(_Ofp, "%s00000", SYNTAX);
+ fprintf(_Ofp, "%sPAG%s", INFO, ENDCMD);
+ fputs(QUICOFF, _Ofp);
+ (void)fflush(_Ofp);
+ if (setjmp(Env)) {
+ while (timedgetc(_Ifp) != EOF) /* Discard remaining input */
+ ;
+ return NULL;
+ }
+ if (yyparse() != 0)
+ return NULL;
+ yysptr = yysbuf; /* Resets lex lookahead buffer */
+ return &Result;
+}
+
+static yyerror(s)
+char *s;
+{
+ longjmp(Env, TRUE);
+}
diff --git a/dviware/quicspool/libqmsquery/qmspaglex.l b/dviware/quicspool/libqmsquery/qmspaglex.l
new file mode 100644
index 0000000000..bb4c903b02
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qmspaglex.l
@@ -0,0 +1,50 @@
+/* $Header: qmspaglex.l,v 1.1 88/01/15 12:19:22 simpson Rel $
+%{
+/*
+$Log: qmspaglex.l,v $
+ * Revision 1.1 88/01/15 12:19:22 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 21:34:48 simpson
+ * beta test
+ *
+*/
+#undef input
+#define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):timedgetc(_Ifp)) \
+ ==10?(yylineno++, yytchar):yytchar)==EOF?0:yytchar)
+double atof();
+%}
+real ([0-9]*\.[0-9]+)|([0-9]+\.[0-9]*)
+integer [0-9]+
+%%
+PAG: return PAG;
+PO return POT;
+TM return TMT;
+BM return BMT;
+LM return LMT;
+RM return RMT;
+LPI return LPIT;
+CPI return CPIT;
+PROP return PROP;
+PT return PTT;
+PS return PST;
+SO return SOT;
+CC return CCT;
+= |
+\, |
+P |
+L |
+Y |
+N {
+ yylval.i = yytext[0];
+ return yytext[0];
+ }
+{real} {
+ yylval.r = atof(yytext);
+ return REAL;
+ }
+{integer} {
+ yylval.i = atoi(yytext);
+ return INTEGER;
+ }
+\r\n return ENDLINE;
diff --git a/dviware/quicspool/libqmsquery/qmspfp.y b/dviware/quicspool/libqmsquery/qmspfp.y
new file mode 100644
index 0000000000..7deba078e2
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qmspfp.y
@@ -0,0 +1,75 @@
+%{
+#ifndef lint
+static char *rcs = "$Header: qmspfp.y,v 1.1 88/01/15 12:19:26 simpson Rel $";
+#endif
+/*
+$Log: qmspfp.y,v $
+ * Revision 1.1 88/01/15 12:19:26 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:12:09 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <setjmp.h>
+#include <local/standard.h>
+#include "qms.h"
+
+extern FILE *_Ifp, *_Ofp;
+extern Boolean _FirstChar;
+static jmp_buf Env;
+char *malloc();
+static struct qmspfp *PfpList, *P;
+%}
+%token PFP NONE ENDLINE
+%token <s> STRING
+%union {
+ char s[81];
+}
+%%
+pfplines : pfplines pfpline | pfpline ;
+
+pfpline : PFP module ENDLINE ;
+
+module :
+ NONE
+ {
+ PfpList = NULL;
+ }
+ |
+ STRING
+ {
+ P = (struct qmspfp *)malloc((unsigned)sizeof(struct qmspfp));
+ P->next = PfpList, PfpList = P;
+ (void)strcpy(P->module = malloc((unsigned)(strlen($1) + 1)), $1);
+ }
+ ;
+%%
+#include "qmspfplex.c"
+
+struct qmspfp *qmspfp()
+{
+ _FirstChar = TRUE;
+ PfpList = NULL;
+ fputs(QUICON, _Ofp);
+ fprintf(_Ofp, "%s00000", SYNTAX);
+ fprintf(_Ofp, "%sPFP%s", INFO, ENDCMD);
+ fputs(QUICOFF, _Ofp);
+ (void)fflush(_Ofp);
+ if (setjmp(Env)) {
+ while (timedgetc(_Ifp) != EOF) /* Discard remaining input */
+ ;
+ return NULL;
+ }
+ if (yyparse() != 0)
+ return NULL;
+ yysptr = yysbuf; /* Resets lex lookahead buffer */
+ return PfpList;
+}
+
+static yyerror(s)
+char *s;
+{
+ longjmp(Env, TRUE);
+}
diff --git a/dviware/quicspool/libqmsquery/qmspfplex.l b/dviware/quicspool/libqmsquery/qmspfplex.l
new file mode 100644
index 0000000000..7b3899a692
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qmspfplex.l
@@ -0,0 +1,32 @@
+/* $Header: qmspfplex.l,v 1.1 88/01/15 12:19:28 simpson Rel $
+%{
+/*
+$Log: qmspfplex.l,v $
+ * Revision 1.1 88/01/15 12:19:28 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 21:34:49 simpson
+ * beta test
+ *
+*/
+#undef input
+#define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):timedgetc(_Ifp)) \
+ ==10?(yylineno++, yytchar):yytchar)==EOF?0:yytchar)
+#ifdef TRW
+#include <local/standard.h>
+#else
+#define EQN(s, t, n) (!strncmp(s, t, n))
+#endif
+%}
+%%
+[^\r\n]+ {
+ if (EQN("PFP:", yytext, 4))
+ REJECT;
+ if (EQN("NONE", yytext, 4))
+ REJECT;
+ (void)strcpy(yylval.s, yytext);
+ return STRING;
+ }
+PFP: return PFP;
+NONE return NONE;
+\r\n return ENDLINE;
diff --git a/dviware/quicspool/libqmsquery/qmsquery.c b/dviware/quicspool/libqmsquery/qmsquery.c
new file mode 100644
index 0000000000..be3730eb66
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qmsquery.c
@@ -0,0 +1,152 @@
+#ifndef lint
+static char *rcs = "$Header: qmsquery.c,v 1.1 88/01/15 12:19:30 simpson Rel $";
+#endif
+#include <stdio.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <local/standard.h>
+#include "qms.h"
+
+FILE *_Ifp, *_Ofp; /* Input and output file pointer */
+Boolean _FirstChar;
+static int (*OldAlarm)(); /* Saves the old SIGALRM value */
+static jmp_buf Env;
+
+int qmsopen(writefd, readfd)
+int writefd, readfd;
+{
+ int timeout();
+
+ if (!(_Ofp = fdopen(writefd, "w")))
+ return FALSE;
+ if (!(_Ifp = fdopen(readfd, "r")))
+ return FALSE;
+ setbuffer(_Ifp, (char *)NULL, 0); /* Turn off buffering on input */
+ OldAlarm = signal(SIGALRM, timeout);
+ return TRUE;
+}
+
+int qmsclose()
+{
+ (void)signal(SIGALRM, OldAlarm);
+ (void)fclose(_Ofp), (void)fclose(_Ifp);
+ return TRUE;
+}
+
+int timedgetc(f)
+FILE *f;
+{
+ int c;
+
+ /* The amount of time to wait until we have decided it is EOF is
+ * hard to select. The printer does not always send the status
+ * information out of the debugger port upon immediately receiving the
+ * ^INFO command. It will accept the ^INFO command, put it in its
+ * buffer, and send the status information when it finally interprets
+ * the ^INFO command. I have seen it take as long as 11 seconds
+ * between the time the ^INFO command was sent and the time the status
+ * information is sent out the debugger port. We don't want to wait 11
+ * or 15 seconds each time we wish to read data. We observe that each
+ * ^INFO command returns at least one character and that when the ^INFO
+ * command is finally interpreted, all the information is sent out to
+ * the debugger port very quickly. Consequently, we can wait a long
+ * time before reading the first character, but after reading the
+ * subsequent characters we wait a short time.
+ */
+ if (_FirstChar)
+ (void)alarm(300); /* Wait 5 minutes maximum */
+ else
+ (void)alarm(3);
+ if (setjmp(Env)) {
+ (void)alarm(0);
+ return EOF;
+ }
+ c = getc(f);
+ (void)alarm(0);
+ _FirstChar = FALSE;
+ return c;
+}
+
+static timeout()
+{
+ longjmp(Env, TRUE);
+}
+
+void qmsmapfree(mapinfo)
+struct qmsmap *mapinfo;
+{
+ struct qmsmap *p;
+
+ for (; mapinfo; mapinfo = p) {
+ if (mapinfo->data)
+ free(mapinfo->data);
+ p = mapinfo->next;
+ free((char *)mapinfo);
+ }
+}
+
+void qmsovlfree(ovlinfo)
+struct qmsovl *ovlinfo;
+{
+ struct qmsovl *p;
+
+ for (; ovlinfo; ovlinfo = p) {
+ p = ovlinfo->next;
+ free((char *)ovlinfo);
+ }
+}
+
+void qmspfpfree(pfpinfo)
+struct qmspfp *pfpinfo;
+{
+ struct qmspfp *p;
+
+ for (; pfpinfo; pfpinfo = p) {
+ if (pfpinfo->module)
+ free(pfpinfo->module);
+ p = pfpinfo->next;
+ free((char *)pfpinfo);
+ }
+}
+
+void qmsopcfree(opcinfo)
+struct qmsopc *opcinfo;
+{
+ struct optnode *p1, *p2;
+
+ for (p1 = opcinfo->OC1; p1; p1 = p2) {
+ p2 = p1->next;
+ free((char *)p1);
+ }
+ for (p1 = opcinfo->OC2; p1; p1 = p2) {
+ p2 = p1->next;
+ free((char *)p1);
+ }
+ for (p1 = opcinfo->OC3; p1; p1 = p2) {
+ p2 = p1->next;
+ free((char *)p1);
+ }
+ for (p1 = opcinfo->OC4; p1; p1 = p2) {
+ p2 = p1->next;
+ free((char *)p1);
+ }
+ for (p1 = opcinfo->OC5; p1; p1 = p2) {
+ p2 = p1->next;
+ free((char *)p1);
+ }
+}
+
+void qmsfntfree(fntinfo)
+struct qmsfnt *fntinfo;
+{
+ struct fontnode *p1, *p2;
+
+ for (p1 = fntinfo->rom; p1; p1 = p2) {
+ p2 = p1->next;
+ free((char *)p1);
+ }
+ for (p1 = fntinfo->ram; p1; p1 = p2) {
+ p2 = p1->next;
+ free((char *)p1);
+ }
+}
diff --git a/dviware/quicspool/libqmsquery/qmsram.y b/dviware/quicspool/libqmsquery/qmsram.y
new file mode 100644
index 0000000000..a7cccbae27
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qmsram.y
@@ -0,0 +1,79 @@
+%{
+#ifndef lint
+static char *rcs = "$Header: qmsram.y,v 1.1 88/01/15 12:19:35 simpson Rel $";
+#endif
+/*
+$Log: qmsram.y,v $
+ * Revision 1.1 88/01/15 12:19:35 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:12:12 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <setjmp.h>
+#include <local/standard.h>
+#include "qms.h"
+
+extern FILE *_Ifp, *_Ofp;
+extern Boolean _FirstChar;
+static jmp_buf Env;
+static struct qmsram Result;
+%}
+%token RAM TRT ART FRT ORT INTEGER ENDLINE
+%%
+ramline : RAM valuelist ENDLINE ;
+
+valuelist : valuelist value optcomma | /* epsilon */ ;
+
+value :
+ TRT '=' INTEGER
+ {
+ Result.TR = $3;
+ }
+ |
+ ART '=' INTEGER
+ {
+ Result.AR = $3;
+ }
+ |
+ FRT '=' INTEGER
+ {
+ Result.FR = $3;
+ }
+ |
+ ORT '=' INTEGER
+ {
+ Result.OR = $3;
+ }
+ ;
+
+optcomma : ',' | /* epsilon */ ;
+%%
+#include "qmsramlex.c"
+
+struct qmsram *qmsram()
+{
+ _FirstChar = TRUE;
+ fputs(QUICON, _Ofp);
+ fprintf(_Ofp, "%s00000", SYNTAX);
+ fprintf(_Ofp, "%sRAM%s", INFO, ENDCMD);
+ fputs(QUICOFF, _Ofp);
+ (void)fflush(_Ofp);
+ if (setjmp(Env)) {
+ while (timedgetc(_Ifp) != EOF) /* Discard remaining input */
+ ;
+ return NULL;
+ }
+ if (yyparse() != 0)
+ return NULL;
+ yysptr = yysbuf; /* Resets lex lookahead buffer */
+ return &Result;
+}
+
+static yyerror(s)
+char *s;
+{
+ longjmp(Env, TRUE);
+}
diff --git a/dviware/quicspool/libqmsquery/qmsramlex.l b/dviware/quicspool/libqmsquery/qmsramlex.l
new file mode 100644
index 0000000000..69bf6e9ad2
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qmsramlex.l
@@ -0,0 +1,29 @@
+/* $Header: qmsramlex.l,v 1.1 88/01/15 12:19:37 simpson Rel $ */
+%{
+/*
+$Log: qmsramlex.l,v $
+ * Revision 1.1 88/01/15 12:19:37 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 21:34:49 simpson
+ * beta test
+ *
+*/
+#undef input
+#define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):timedgetc(_Ifp)) \
+ ==10?(yylineno++, yytchar):yytchar)==EOF?0:yytchar)
+%}
+integer [0-9]+
+%%
+RAM: return RAM;
+TR return TRT;
+AR return ART;
+FR return FRT;
+OR return ORT;
+{integer} {
+ yylval = atoi(yytext);
+ return INTEGER;
+ }
+= |
+\, return yytext[0];
+\r\n return ENDLINE;
diff --git a/dviware/quicspool/libqmsquery/qmsver.y b/dviware/quicspool/libqmsquery/qmsver.y
new file mode 100644
index 0000000000..a12a33edb7
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qmsver.y
@@ -0,0 +1,68 @@
+%{
+#ifndef lint
+static char *rcs = "$Header: qmsver.y,v 1.1 88/01/15 12:19:41 simpson Rel $";
+#endif
+/*
+$Log: qmsver.y,v $
+ * Revision 1.1 88/01/15 12:19:41 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:12:14 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <setjmp.h>
+#include <local/standard.h>
+#include "qms.h"
+
+extern FILE *_Ifp, *_Ofp;
+extern Boolean _FirstChar;
+static jmp_buf Env;
+static struct qmsver Result;
+%}
+%token DATE FIRMWARE VERSION ENDLINE QUIC
+%token <i> INTEGER
+%token <r> REAL
+%union {
+ int i;
+ float r;
+}
+%%
+version : VERSION '=' QUIC ':' REAL FIRMWARE ':' REAL DATE INTEGER '/'
+ INTEGER '/' INTEGER ENDLINE
+ {
+ Result.version = $5;
+ Result.firmware = $8;
+ Result.date.month = $10;
+ Result.date.day = $12;
+ Result.date.year = $14;
+ }
+ ;
+%%
+#include "qmsverlex.c"
+
+struct qmsver *qmsver()
+{
+ _FirstChar = TRUE;
+ fputs(QUICON, _Ofp);
+ fprintf(_Ofp, "%s00000", SYNTAX);
+ fprintf(_Ofp, "%sVER%s", INFO, ENDCMD);
+ fputs(QUICOFF, _Ofp);
+ (void)fflush(_Ofp);
+ if (setjmp(Env)) {
+ while (timedgetc(_Ifp) != EOF) /* Discard remaining input */
+ ;
+ return NULL;
+ }
+ if (yyparse() != 0)
+ return NULL;
+ yysptr = yysbuf; /* Resets lex lookahead buffer */
+ return &Result;
+}
+
+static yyerror(s)
+char *s;
+{
+ longjmp(Env, TRUE);
+}
diff --git a/dviware/quicspool/libqmsquery/qmsverlex.l b/dviware/quicspool/libqmsquery/qmsverlex.l
new file mode 100644
index 0000000000..be5dba8982
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/qmsverlex.l
@@ -0,0 +1,41 @@
+/* $Header: qmsverlex.l,v 1.1 88/01/15 12:19:49 simpson Rel $ */
+%{
+/*
+$Log: qmsverlex.l,v $
+ * Revision 1.1 88/01/15 12:19:49 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 21:34:50 simpson
+ * beta test
+ *
+*/
+#ifdef TRW
+#include <local/standard.h>
+#else
+#define EQN(s, t, n) (!strncmp(s, t, n))
+#endif
+#undef input
+#define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):timedgetc(_Ifp)) \
+ ==10?(yylineno++, yytchar):yytchar)==EOF?0:yytchar)
+double atof();
+%}
+real ([0-9]*\.[0-9]+)|([0-9]+\.[0-9]*)
+integer [0-9]+
+%%
+QUIC return QUIC;
+Date return DATE;
+Firmware return FIRMWARE;
+Version return VERSION;
+= |
+: |
+\/ return yytext[0];
+{integer} {
+ yylval.i = atoi(yytext);
+ return INTEGER;
+ }
+{real} {
+ yylval.r = atof(yytext);
+ return REAL;
+ }
+\r\n return ENDLINE;
+[ \t]+ ;
diff --git a/dviware/quicspool/libqmsquery/yaccsed b/dviware/quicspool/libqmsquery/yaccsed
new file mode 100644
index 0000000000..16c307ed6c
--- /dev/null
+++ b/dviware/quicspool/libqmsquery/yaccsed
@@ -0,0 +1,12 @@
+s/^short yyexca\[\]/static &/
+s/^short yyact\[\]/static &/
+s/^short yypact\[\]/static &/
+s/^short yypgo\[\]/static &/
+s/^short yyr1\[\]/static &/
+s/^short yyr2\[\]/static &/
+s/^short yychk\[\]/static &/
+s/^short yydef\[\]/static &/
+s/^int yychar/static &/
+s/^int yynerrs/static &/
+s/^short yyerrflag/static &/
+s/^yyparse()/static &/
diff --git a/dviware/quicspool/libtrw/getopt.c b/dviware/quicspool/libtrw/getopt.c
new file mode 100644
index 0000000000..b81dc931c3
--- /dev/null
+++ b/dviware/quicspool/libtrw/getopt.c
@@ -0,0 +1,61 @@
+static char *rcs = "$Header: getopt.c,v 1.1 88/01/15 12:56:30 simpson Rel $";
+/*
+$Log: getopt.c,v $
+ * Revision 1.1 88/01/15 12:56:30 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:14:09 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+
+/*
+ * get option letter from argument vector
+ */
+int opterr = 1, /* useless, never set or used */
+ optind = 1, /* index into parent argv vector */
+ optopt; /* character checked for validity */
+char *optarg; /* argument associated with option */
+
+#define BADCH (int)'?'
+#define EMSG ""
+#define tell(s) fputs(*nargv,stderr);fputs(s,stderr); \
+ fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);
+
+getopt(nargc,nargv,ostr)
+int nargc;
+char **nargv,
+ *ostr;
+{
+ static char *place = EMSG; /* option letter processing */
+ register char *oli; /* option letter list index */
+ char *index();
+
+ if(!*place) { /* update scanning pointer */
+ if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) return(EOF);
+ if (*place == '-') { /* found "--" */
+ ++optind;
+ return(EOF);
+ }
+ } /* option letter okay? */
+ if ((optopt = (int)*place++) == (int)':' || !(oli = index(ostr,optopt))) {
+ if(!*place) ++optind;
+ tell(": illegal option -- ");
+ }
+ if (*++oli != ':') { /* don't need argument */
+ optarg = NULL;
+ if (!*place) ++optind;
+ }
+ else { /* need an argument */
+ if (*place) optarg = place; /* no white space */
+ else if (nargc <= ++optind) { /* no arg */
+ place = EMSG;
+ tell(": option requires an argument -- ");
+ }
+ else optarg = nargv[optind]; /* white space */
+ place = EMSG;
+ ++optind;
+ }
+ return(optopt); /* dump back option letter */
+}
diff --git a/dviware/quicspool/libtrw/makefile b/dviware/quicspool/libtrw/makefile
new file mode 100644
index 0000000000..9ae6b43e4c
--- /dev/null
+++ b/dviware/quicspool/libtrw/makefile
@@ -0,0 +1,23 @@
+# $Header: Makefile,v 1.1 88/01/15 12:56:26 simpson Rel $
+# $Log: Makefile,v $
+#Revision 1.1 88/01/15 12:56:26 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 17:24:03 simpson
+#beta test
+#
+LIB=/usr/local/lib
+
+all: libtrw.a
+
+configure:
+
+libtrw.a: shift.o getopt.o
+ ar cr libtrw.a shift.o getopt.o
+ ranlib libtrw.a
+
+clean:
+ -rm -f *.o libtrw.a
+
+install: all
+ install -m 644 libtrw.a $(LIB)
diff --git a/dviware/quicspool/libtrw/makefile.trw b/dviware/quicspool/libtrw/makefile.trw
new file mode 100644
index 0000000000..2d6cf74f34
--- /dev/null
+++ b/dviware/quicspool/libtrw/makefile.trw
@@ -0,0 +1,23 @@
+# $Header: Makefile.TRW,v 1.1 88/01/15 12:56:29 simpson Rel $
+# $Log: Makefile.TRW,v $
+#Revision 1.1 88/01/15 12:56:29 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 17:24:04 simpson
+#beta test
+#
+LIB=/usr/local/lib
+
+all: libtrw.a
+
+configure:
+
+libtrw.a: shift.o getopt.o
+ ar cr libtrw.a shift.o getopt.o
+ ranlib libtrw.a
+
+clean:
+ -rm -f *.o libtrw.a
+
+install: all
+ install -m 644 libtrw.a $(LIB)
diff --git a/dviware/quicspool/libtrw/shift.c b/dviware/quicspool/libtrw/shift.c
new file mode 100644
index 0000000000..71372f55d0
--- /dev/null
+++ b/dviware/quicspool/libtrw/shift.c
@@ -0,0 +1,39 @@
+static char *rcs = "$Header: shift.c,v 1.1 88/01/15 12:56:32 simpson Rel $";
+/*
+$Log: shift.c,v $
+ * Revision 1.1 88/01/15 12:56:32 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:14:10 simpson
+ * beta test
+ *
+*/
+#include <ctype.h>
+
+/*
+ * Downshifts a string in place.
+ */
+char *string_downshift(s)
+char *s;
+{
+
+ register char *x = s;
+ for (; *x; x++)
+ if (isupper(*x))
+ *x = tolower(*x);
+ return(s);
+}
+
+/*
+ * Upshifts a string in place.
+ */
+char *string_upshift(s)
+char *s;
+{
+
+ register char *x = s;
+ for (; *x; x++)
+ if (islower(*x))
+ *x = toupper(*x);
+ return(s);
+}
diff --git a/dviware/quicspool/makefile b/dviware/quicspool/makefile
new file mode 100644
index 0000000000..583154074d
--- /dev/null
+++ b/dviware/quicspool/makefile
@@ -0,0 +1,175 @@
+# $Header: Makefile,v 1.1 88/01/15 12:13:57 simpson Rel $
+# $Log: Makefile,v $
+#Revision 1.1 88/01/15 12:13:57 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 16:49:12 simpson
+#beta test
+#
+CFLAGS=-O
+LDFLAGS=-s
+# Location to put system include files
+INCLUDE=/usr/include/local
+# Location to put lpr filters
+FILTER=/usr/local/lib/lpr
+# Location to put libraries
+LIB=/usr/local/lib
+# Location of TeX fonts (write-write and write-black)
+WBTEXFONT=/usr/lib/tex/imagenfonts
+WWTEXFONT=/usr/lib/tex/qmsfonts
+# Location to put troff font width tables
+OTROFFFONT=/usr/lib/font
+# Location to put ditroff font width tables
+DITROFFFONT=/usr/lib/font/devqms
+# Location to put executable programs
+BINARIES=/usr/local/bin
+# User to switch to if from a remote host
+DOCILEUSER=games
+
+all:
+ for i in standard libtrw libglob libprofile libqmsquery man src \
+ wbfonts wwfonts; do \
+ cd $$i; \
+ make \
+ 'LOADLIBES=$(LOADLIBES)' \
+ 'FFLAGS=$(FFLAGS)' \
+ 'EFLAGS=$(EFLAGS)' \
+ 'FC=$(FC)' \
+ 'RFLAGS=$(RFLAGS)' \
+ 'RC=$(RC)' \
+ 'CFLAGS=$(CFLAGS)' \
+ 'PFLAGS=$(PFLAGS)' \
+ 'PC=$(PC)' \
+ 'AS=$(AS)' \
+ 'CC=$(CC)' \
+ 'LFLAGS=$(LFLAGS)' \
+ 'LEX=$(LEX)' \
+ 'YFLAGS=$(YFLAGS)' \
+ 'YACCE=$(YACCE)' \
+ 'YACCR=$(YACCR)' \
+ 'YACC=$(YACC)' \
+ 'LDFLAGS=$(LDFLAGS)' \
+ 'INCLUDE=$(INCLUDE)' \
+ 'FILTER=$(FILTER)' \
+ 'LIB=$(LIB)' \
+ 'WWTEXFONT=$(WWTEXFONT)' \
+ 'WBTEXFONT=$(WBTEXFONT)' \
+ 'OTROFFFONT=$(OTROFFFONT)' \
+ 'DITROFFFONT=$(DITROFFFONT)' \
+ 'BINARIES=$(BINARIES)' \
+ 'DOCILEUSER=$(DOCILEUSER)' \
+ all; \
+ cd ..; \
+ done
+
+configure:
+ -mkdir $(INCLUDE) $(FILTER) $(LIB) $(WWTEXFONT) $(WBTEXFONT) \
+ $(OTROFFFONT) $(DITROFFFONT) $(DITROFFFONT)/wbfonts \
+ $(DITROFFFONT)/wwfonts $(BINARIES)
+ for i in standard libtrw libglob libprofile libqmsquery man src \
+ wbfonts wwfonts; do \
+ cd $$i; \
+ make \
+ 'LOADLIBES=$(LOADLIBES)' \
+ 'FFLAGS=$(FFLAGS)' \
+ 'EFLAGS=$(EFLAGS)' \
+ 'FC=$(FC)' \
+ 'RFLAGS=$(RFLAGS)' \
+ 'RC=$(RC)' \
+ 'CFLAGS=$(CFLAGS)' \
+ 'PFLAGS=$(PFLAGS)' \
+ 'PC=$(PC)' \
+ 'AS=$(AS)' \
+ 'CC=$(CC)' \
+ 'LFLAGS=$(LFLAGS)' \
+ 'LEX=$(LEX)' \
+ 'YFLAGS=$(YFLAGS)' \
+ 'YACCE=$(YACCE)' \
+ 'YACCR=$(YACCR)' \
+ 'YACC=$(YACC)' \
+ 'LDFLAGS=$(LDFLAGS)' \
+ 'INCLUDE=$(INCLUDE)' \
+ 'FILTER=$(FILTER)' \
+ 'LIB=$(LIB)' \
+ 'WWTEXFONT=$(WWTEXFONT)' \
+ 'WBTEXFONT=$(WBTEXFONT)' \
+ 'OTROFFFONT=$(OTROFFFONT)' \
+ 'DITROFFFONT=$(DITROFFFONT)' \
+ 'BINARIES=$(BINARIES)' \
+ 'DOCILEUSER=$(DOCILEUSER)' \
+ configure; \
+ cd ..; \
+ done
+
+install: all
+ for i in standard libtrw libglob libprofile libqmsquery man src \
+ wbfonts wwfonts; do \
+ cd $$i; \
+ make \
+ 'LOADLIBES=$(LOADLIBES)' \
+ 'FFLAGS=$(FFLAGS)' \
+ 'EFLAGS=$(EFLAGS)' \
+ 'FC=$(FC)' \
+ 'RFLAGS=$(RFLAGS)' \
+ 'RC=$(RC)' \
+ 'CFLAGS=$(CFLAGS)' \
+ 'PFLAGS=$(PFLAGS)' \
+ 'PC=$(PC)' \
+ 'AS=$(AS)' \
+ 'CC=$(CC)' \
+ 'LFLAGS=$(LFLAGS)' \
+ 'LEX=$(LEX)' \
+ 'YFLAGS=$(YFLAGS)' \
+ 'YACCE=$(YACCE)' \
+ 'YACCR=$(YACCR)' \
+ 'YACC=$(YACC)' \
+ 'LDFLAGS=$(LDFLAGS)' \
+ 'INCLUDE=$(INCLUDE)' \
+ 'FILTER=$(FILTER)' \
+ 'LIB=$(LIB)' \
+ 'WWTEXFONT=$(WWTEXFONT)' \
+ 'WBTEXFONT=$(WBTEXFONT)' \
+ 'OTROFFFONT=$(OTROFFFONT)' \
+ 'DITROFFFONT=$(DITROFFFONT)' \
+ 'BINARIES=$(BINARIES)' \
+ 'DOCILEUSER=$(DOCILEUSER)' \
+ install; \
+ cd ..; \
+ done
+
+clean:
+ for i in standard libtrw libglob libprofile libqmsquery man src \
+ wbfonts wwfonts; do \
+ cd $$i; \
+ make \
+ 'LOADLIBES=$(LOADLIBES)' \
+ 'FFLAGS=$(FFLAGS)' \
+ 'EFLAGS=$(EFLAGS)' \
+ 'FC=$(FC)' \
+ 'RFLAGS=$(RFLAGS)' \
+ 'RC=$(RC)' \
+ 'CFLAGS=$(CFLAGS)' \
+ 'PFLAGS=$(PFLAGS)' \
+ 'PC=$(PC)' \
+ 'AS=$(AS)' \
+ 'CC=$(CC)' \
+ 'LFLAGS=$(LFLAGS)' \
+ 'LEX=$(LEX)' \
+ 'YFLAGS=$(YFLAGS)' \
+ 'YACCE=$(YACCE)' \
+ 'YACCR=$(YACCR)' \
+ 'YACC=$(YACC)' \
+ 'LDFLAGS=$(LDFLAGS)' \
+ 'INCLUDE=$(INCLUDE)' \
+ 'FILTER=$(FILTER)' \
+ 'LIB=$(LIB)' \
+ 'WWTEXFONT=$(WWTEXFONT)' \
+ 'WBTEXFONT=$(WBTEXFONT)' \
+ 'OTROFFFONT=$(OTROFFFONT)' \
+ 'DITROFFFONT=$(DITROFFFONT)' \
+ 'BINARIES=$(BINARIES)' \
+ 'DOCILEUSER=$(DOCILEUSER)' \
+ clean; \
+ cd ..; \
+ done
+
diff --git a/dviware/quicspool/makefile.trw b/dviware/quicspool/makefile.trw
new file mode 100644
index 0000000000..51327e7319
--- /dev/null
+++ b/dviware/quicspool/makefile.trw
@@ -0,0 +1,178 @@
+# $Header: Makefile.TRW,v 1.1 88/01/15 12:14:02 simpson Rel $
+# $Log: Makefile.TRW,v $
+#Revision 1.1 88/01/15 12:14:02 simpson
+#initial release
+#
+#Revision 0.2 87/12/18 11:42:08 simpson
+#removed reference to /usr/lib/font/otroff
+#
+#Revision 0.1 87/12/11 16:49:14 simpson
+#beta test
+#
+CFLAGS=-O -I/usr/src/usr.lib/lpr -DTRW
+LDFLAGS=-s
+# Location to put system include files
+INCLUDE=/usr/include/local
+# Location to put lpr filters
+FILTER=/usr/local/lib/lpr
+# Location to put libraries
+LIB=/usr/local/lib
+# Location of TeX fonts (write-write and write-black)
+WBTEXFONT=/usr/lib/tex/imagenfonts
+WWTEXFONT=/usr/lib/tex/qmsfonts
+# Location to put troff font width tables
+OTROFFFONT=/usr/lib/font
+# Location to put ditroff font width tables
+DITROFFFONT=/usr/lib/font/devqms
+# Location to put executable programs
+BINARIES=/usr/local/bin
+# User to switch to if from a remote host
+DOCILEUSER=games
+
+all:
+ for i in standard libtrw libglob libprofile libqmsquery man src \
+ wbfonts wwfonts; do \
+ cd $$i; \
+ make -f Makefile.TRW \
+ 'LOADLIBES=$(LOADLIBES)' \
+ 'FFLAGS=$(FFLAGS)' \
+ 'EFLAGS=$(EFLAGS)' \
+ 'FC=$(FC)' \
+ 'RFLAGS=$(RFLAGS)' \
+ 'RC=$(RC)' \
+ 'CFLAGS=$(CFLAGS)' \
+ 'PFLAGS=$(PFLAGS)' \
+ 'PC=$(PC)' \
+ 'AS=$(AS)' \
+ 'CC=$(CC)' \
+ 'LFLAGS=$(LFLAGS)' \
+ 'LEX=$(LEX)' \
+ 'YFLAGS=$(YFLAGS)' \
+ 'YACCE=$(YACCE)' \
+ 'YACCR=$(YACCR)' \
+ 'YACC=$(YACC)' \
+ 'LDFLAGS=$(LDFLAGS)' \
+ 'INCLUDE=$(INCLUDE)' \
+ 'FILTER=$(FILTER)' \
+ 'LIB=$(LIB)' \
+ 'WWTEXFONT=$(WWTEXFONT)' \
+ 'WBTEXFONT=$(WBTEXFONT)' \
+ 'OTROFFFONT=$(OTROFFFONT)' \
+ 'DITROFFFONT=$(DITROFFFONT)' \
+ 'BINARIES=$(BINARIES)' \
+ 'DOCILEUSER=$(DOCILEUSER)' \
+ all; \
+ cd ..; \
+ done
+
+configure:
+ -mkdir $(INCLUDE) $(FILTER) $(LIB) $(WWTEXFONT) $(WBTEXFONT) \
+ $(OTROFFFONT) $(DITROFFFONT) $(DITROFFFONT)/wbfonts \
+ $(DITROFFFONT)/wwfonts $(BINARIES)
+ for i in standard libtrw libglob libprofile libqmsquery man src \
+ wbfonts wwfonts; do \
+ cd $$i; \
+ make -f Makefile.TRW \
+ 'LOADLIBES=$(LOADLIBES)' \
+ 'FFLAGS=$(FFLAGS)' \
+ 'EFLAGS=$(EFLAGS)' \
+ 'FC=$(FC)' \
+ 'RFLAGS=$(RFLAGS)' \
+ 'RC=$(RC)' \
+ 'CFLAGS=$(CFLAGS)' \
+ 'PFLAGS=$(PFLAGS)' \
+ 'PC=$(PC)' \
+ 'AS=$(AS)' \
+ 'CC=$(CC)' \
+ 'LFLAGS=$(LFLAGS)' \
+ 'LEX=$(LEX)' \
+ 'YFLAGS=$(YFLAGS)' \
+ 'YACCE=$(YACCE)' \
+ 'YACCR=$(YACCR)' \
+ 'YACC=$(YACC)' \
+ 'LDFLAGS=$(LDFLAGS)' \
+ 'INCLUDE=$(INCLUDE)' \
+ 'FILTER=$(FILTER)' \
+ 'LIB=$(LIB)' \
+ 'WWTEXFONT=$(WWTEXFONT)' \
+ 'WBTEXFONT=$(WBTEXFONT)' \
+ 'OTROFFFONT=$(OTROFFFONT)' \
+ 'DITROFFFONT=$(DITROFFFONT)' \
+ 'BINARIES=$(BINARIES)' \
+ 'DOCILEUSER=$(DOCILEUSER)' \
+ configure; \
+ cd ..; \
+ done
+
+install: all
+ for i in standard libtrw libglob libprofile libqmsquery man src \
+ wbfonts wwfonts; do \
+ cd $$i; \
+ make -f Makefile.TRW \
+ 'LOADLIBES=$(LOADLIBES)' \
+ 'FFLAGS=$(FFLAGS)' \
+ 'EFLAGS=$(EFLAGS)' \
+ 'FC=$(FC)' \
+ 'RFLAGS=$(RFLAGS)' \
+ 'RC=$(RC)' \
+ 'CFLAGS=$(CFLAGS)' \
+ 'PFLAGS=$(PFLAGS)' \
+ 'PC=$(PC)' \
+ 'AS=$(AS)' \
+ 'CC=$(CC)' \
+ 'LFLAGS=$(LFLAGS)' \
+ 'LEX=$(LEX)' \
+ 'YFLAGS=$(YFLAGS)' \
+ 'YACCE=$(YACCE)' \
+ 'YACCR=$(YACCR)' \
+ 'YACC=$(YACC)' \
+ 'LDFLAGS=$(LDFLAGS)' \
+ 'INCLUDE=$(INCLUDE)' \
+ 'FILTER=$(FILTER)' \
+ 'LIB=$(LIB)' \
+ 'WWTEXFONT=$(WWTEXFONT)' \
+ 'WBTEXFONT=$(WBTEXFONT)' \
+ 'OTROFFFONT=$(OTROFFFONT)' \
+ 'DITROFFFONT=$(DITROFFFONT)' \
+ 'BINARIES=$(BINARIES)' \
+ 'DOCILEUSER=$(DOCILEUSER)' \
+ install; \
+ cd ..; \
+ done
+
+clean:
+ for i in standard libtrw libglob libprofile libqmsquery man src \
+ wbfonts wwfonts; do \
+ cd $$i; \
+ make -f Makefile.TRW \
+ 'LOADLIBES=$(LOADLIBES)' \
+ 'FFLAGS=$(FFLAGS)' \
+ 'EFLAGS=$(EFLAGS)' \
+ 'FC=$(FC)' \
+ 'RFLAGS=$(RFLAGS)' \
+ 'RC=$(RC)' \
+ 'CFLAGS=$(CFLAGS)' \
+ 'PFLAGS=$(PFLAGS)' \
+ 'PC=$(PC)' \
+ 'AS=$(AS)' \
+ 'CC=$(CC)' \
+ 'LFLAGS=$(LFLAGS)' \
+ 'LEX=$(LEX)' \
+ 'YFLAGS=$(YFLAGS)' \
+ 'YACCE=$(YACCE)' \
+ 'YACCR=$(YACCR)' \
+ 'YACC=$(YACC)' \
+ 'LDFLAGS=$(LDFLAGS)' \
+ 'INCLUDE=$(INCLUDE)' \
+ 'FILTER=$(FILTER)' \
+ 'LIB=$(LIB)' \
+ 'WWTEXFONT=$(WWTEXFONT)' \
+ 'WBTEXFONT=$(WBTEXFONT)' \
+ 'OTROFFFONT=$(OTROFFFONT)' \
+ 'DITROFFFONT=$(DITROFFFONT)' \
+ 'BINARIES=$(BINARIES)' \
+ 'DOCILEUSER=$(DOCILEUSER)' \
+ clean; \
+ cd ..; \
+ done
+
diff --git a/dviware/quicspool/man/cat.l b/dviware/quicspool/man/cat.l
new file mode 100644
index 0000000000..cac7d3a814
--- /dev/null
+++ b/dviware/quicspool/man/cat.l
@@ -0,0 +1,226 @@
+.\" $Header: cat.l,v 1.1 88/01/15 12:58:13 simpson Rel $
+.\" $Log: cat.l,v $
+.\" Revision 1.1 88/01/15 12:58:13 simpson
+.\" initial release
+.\"
+.\" Revision 0.1 87/12/11 17:56:49 simpson
+.\" beta test
+.\"
+.TH CAT 5 TRW
+.UC 4
+.SH NAME
+cat \- GSI CAT-4/8 phototypesetter code
+.SH DESCRIPTION
+The Graphic Systems Industries CAT phototypesetter is driven by sending it a
+sequence of one-byte codes
+which specify characters, fonts, sizes, and other control information.
+.PP
+The CAT's basic unit of length is 1/432 of an inch (6 units to a
+typesetter's ``point'').
+The quantum of horizontal motion is one unit.
+The quantum of vertical motion is three units (1/144 of an inch, 1/2 point).
+.PP
+The top two bits of the code classify it as one of three major
+types:
+an
+.I escape
+code (top bit 1),
+a
+.I flash
+code (top bits 00),
+or a control code (top bits 01).
+A code of all zeros is ignored; a code of all ones is illegal.
+.PP
+A flash code specifies flashing one of 63 characters, as given by the
+remaining six bits.
+Since this is not enough to specify all possible characters, or even
+all characters in a single font \- there are 108 per font \-
+various control codes (described later) select a font and either
+the
+.I lower
+or
+.I upper
+half of the font.
+The lower half is the first 63 characters of the font;
+the upper half is the remaining 45.
+A flash code of 46 or higher in the upper half is illegal.
+.PP
+An escape code specifies horizontal motion.
+The size of the motion, in horizontal quanta, is the one's-complement
+of the low seven bits of the code.
+The direction of the motion is set by control codes.
+Hitting the right or left margin limit switch is illegal and will
+cause the machine to stop.
+The machine starts out, after initialization, hard against the left
+margin limit switch; an initial escape of 16 units
+.I must
+be given before starting work, and the position after this motion
+should be the limit of all future leftward motions.
+From this point, the distance to the right margin limit switch
+is about 7.5 inches.
+.PP
+A code with the top three bits 011 is a
+.I lead
+code,
+specifying vertical motion.
+The remaining five bits are the one's-complement of the size of
+the motion, in vertical quanta.
+The direction of motion is set by control codes.
+The amount of vertical motion is, in principle, limited only by
+running off the paper in the upward direction and by the limited
+capacity of the output cartridge in the downward direction.
+.PP
+A code with the top four bits 0101 is a size-change code, which
+specifies movement of the lens turret and the doubler lens to
+change point size.
+These codes are as follows:
+.PP
+.RS
+.nf
+.ta 2c
+Size Code
+
+6 0101\|1000
+7 0101\|0000
+8 0101\|0001
+9 0101\|0111
+10 0101\|0010
+11 0101\|0011
+12 0101\|0100
+14 0101\|0101
+16 0101\|1001
+18 0101\|0110
+20 0101\|1010
+22 0101\|1011
+24 0101\|1100
+28 0101\|1101
+36 0101\|1110
+.DT
+.fi
+.RE
+.PP
+Size changes involving the doubler lens alter the horizontal position.
+Changes from single to double sizes should be followed by a forward
+escape of 55 quanta; changes from double to single sizes should be
+followed by a reverse escape of 55 quanta.
+The single sizes are 6, 7, 8, 9, 10, 11, 12, 14, and 18;
+the double sizes are 16, 20, 22, 24, 28, and 36.
+.PP
+The control codes with the top four bits 0100 specify miscellaneous
+control codes, not all of which have valid meanings.
+They are:
+.PP
+.RS
+.ta 6c
+.nf
+initialize 0100\|0000
+stop 0100\|1001
+upper rail 0100\|0010
+lower rail 0100\|0001
+upper magazine 0100\|0011
+lower magazine 0100\|0100
+tilt up 0100\|1110
+tilt down 0100\|1111
+upper font half 0100\|0110
+lower font half 0100\|0101
+escape forward 0100\|0111
+escape backward 0100\|1000
+lead forward 0100\|1010
+lead backward 0100\|1100
+.fi
+.DT
+.RE
+.PP
+The
+.I initialize
+code causes leftward motion to the left margin limit
+switch,
+and sets the following modes:
+escape forward, lead forward, lower font half,
+lower rail, lower mag, tilt down.
+Note that the left margin limit switch does not define a precise
+position, and hence reinitializing the machine
+will destroy precise left-margin alignment.
+.PP
+The
+.I stop
+code stops the machine, which must be manually
+restarted (normally after changing output cartridges);
+this code should be used only at the end of a run.
+.PP
+Fonts are selected by the combination of
+.IR rail ,
+.IR magazine ,
+and
+.IR tilt .
+The tilt codes do not exist on the 4-font CAT; this is the only user-visible
+difference between the 4-font and 8-font machines.
+The correspondence between rail/magazine/tilt and font number is as follows:
+.PP
+.RS
+.nf
+.ta 2c 5c 7c 9c
+rail magazine tilt 4 font 8 font
+
+lower lower up 1 1
+lower lower down 1 2
+upper lower up 2 3
+upper lower down 2 4
+lower upper up 3 5
+lower upper down 3 6
+upper upper up 4 7
+upper upper down 4 8
+.DT
+.fi
+.RE
+.PP
+Several additional commands were introduced locally to ease
+the simulation of the CAT on a variety of raster plotters.
+Each is several bytes long.
+The first byte is the
+.I extension
+control code 0100\|1011.
+The remaining bytes specify the command and its argument
+(if any, treated as an unsigned integer).
+The commands are:
+.PP
+.RS
+.nf
+.ta 6c
+big lead 0000\|0001
+big escape 0000\|0010
+formfeed 0000\|0011
+.fi
+.DT
+.RE
+.PP
+The
+.I "big lead"
+code specifies vertical motion whose magnitude is
+64 * the following byte.
+The
+.I "big escape"
+code specifies horizontal motion whose magnitude is
+128 * the following byte.
+The
+.I formfeed
+code specifies an advance to the next page resetting the current
+row and column to <0,0>.
+.PP
+A complete CAT file should begin with an
+.I initialize
+code followed
+by an
+.IR escape -16
+code,
+and should end with 14 inches of trailer and a
+.I stop
+code.
+.SH AUTHORS
+Henry Spencer, University of Toronto
+.br
+Michael Gorlick, TRW
+.SH BUGS
+The documentation and the hardware disagree on the initial tilt setting;
+the above describes the hardware.
+
diff --git a/dviware/quicspool/man/cati.l b/dviware/quicspool/man/cati.l
new file mode 100644
index 0000000000..602a55cc4a
--- /dev/null
+++ b/dviware/quicspool/man/cati.l
@@ -0,0 +1,216 @@
+.\" $Header: cati.l,v 1.1 88/01/15 12:58:16 simpson Rel $
+.\" $Log: cati.l,v $
+.\" Revision 1.1 88/01/15 12:58:16 simpson
+.\" initial release
+.\"
+.\" Revision 0.1 87/12/11 17:56:50 simpson
+.\" beta test
+.\"
+.TH CATI 1 TRW
+.UC 4
+.SH NAME
+cati \- GSI CAT-4/8 phototypesetter interpreter
+.SH SYNOPSIS
+.B cati
+[
+.B -l
+] [
+.B -v
+] [ file ... ]
+.SH DESCRIPTION
+.I Cati
+writes a commentary on standard output
+interpreting each command as it would act on the phototypesetter.
+The options are:
+.TP
+.B -l
+print a one line summary of the leading and nothing else.
+.TP
+.B -v
+turn on verbose mode where each individual lead or escape command is printed.
+The default is terse mode where only a one line summary
+of an ubroken series of lead or escape commands is printed.
+.PP
+If
+.I file
+is omitted
+.I cati
+reads from standard input.
+.PP
+The output notation is:
+.TP
+.RI > " E F B T"
+> (<) denotes forward (backward) escape.
+.I E
+is the accumulated escape of an unbroken series of escape commands.
+.IR F " (" B )
+is the total forward (backward) escape to date.
+.I T
+is the magnitude of all escape (in either direction) to date.
+All numerical values are in CAT horizontal units.
+.TP
+.RI + " L F B T"
++ (-) denotes forward (backward) leading.
+.I L
+is the accumulated leading of an unbroken series of lead commands.
+.IR F " (" B )
+is the total forward (backward) leading to date.
+.I T
+is the magnitude of all leading (in either direction) to date.
+All numerical values are in CAT vertical units.
+.TP
+Initialize
+an
+.I initialize
+control code.
+.TP
+.RI "Lower rail (font " N )
+a
+.I "lower rail"
+control code.
+.I N
+is the font selected by the mode change.
+.TP
+.RI "Upper rail (font " N )
+an
+.I "upper rail"
+control code.
+.I N
+is the font selected by the mode change.
+.TP
+.RI "Upper magazine (font " N )
+an
+.I "upper magazine"
+control code.
+.I N
+is the font selected by the mode change.
+.TP
+.RI "Lower magazine (font " N )
+a
+.I "lower magazine"
+control code.
+.I N
+is the font selected by the mode change.
+.TP
+Font half lower
+a
+.I "lower font half"
+control code.
+.TP
+Font half upper
+an
+.I "upper font half"
+control code.
+.TP
+.RI "> mode" " F B T"
+an
+.I "escape mode"
+control code.
+> (<) denotes forward (backward) escape mode.
+.IR "F " ( B )
+is the total amount of forward (backward) escape to date.
+.I T
+is the magnitude of all escape to date.
+All numerical values are in CAT horizontal units.
+.TP
+STOP
+a
+.I stop
+control code.
+.TP
+.RI "+ mode" " F B T"
+a
+.I "lead mode"
+control code.
++ (-) denotes forward (backward) lead mode.
+.IR "F " ( B )
+is the total amount of forward (backward) leading to date.
+.I T
+is the magnitude of all leading to date.
+All numerical values are in CAT vertical units.
+.TP
+.RI "Tilt up (font " N )
+a
+.I "tilt up"
+control code.
+.I N
+is the font selected by the mode change.
+.TP
+.RI "Tilt down (font " N )
+a
+.I "tilt down"
+control code.
+.I N
+is the font selected by the mode change.
+.TP
+.RI Size " N"
+a
+.I "point size change control"
+code.
+.I N
+is the selected point size.
+If the size change is a single to double transition the parenthetical
+remark `(double)' will follow
+.IR N .
+If the size change is a double to single transition the parenthetical
+remark `(single)' will follow
+.IR N .
+.TP
+Flash \fIF \fR(font \fIN IH \fRsize \fIS \fR<\fIR\fR,\fIC\fR>)
+a
+.I flash
+code.
+.I F
+is the flashed character.
+.I Cati
+assumes that regular filmstrips are mounted are mounted on font positions
+1-6 and 8 and that the Bell Special Mathematical font is mounted on position
+7.
+These assumptions are compatible with the default mountings
+.IR troff (1)
+assumes for the CAT-4.
+.I N
+is the font position 1-8.
+.I I
+is the filmstrip index of the character and
+.I H
+is the current font half
+where L or U denote the lower and upper font halfs respectively.
+.I S
+is the current point size.
+.I R
+and
+.I C
+are the current row and column expressed in CAT vertical and
+horizontal units respectively.
+.TP
+Formfeed
+a
+.I formfeed
+control code.
+.PP
+In verbose mode each escape or leading command in the code stream
+is printed.
+The output notation is:
+.TP
+.RI "> " E
+> (<) denotes forward (backward) escape.
+.I E
+is the magnitude of the escape in CAT horizontal units.
+.TP
+.RI "+ " L
++ (-) denotes forward (backware) leading.
+.I L
+is the magintude of the leading in CAT vertical units.
+.TP
+.RI ">> " E
+>> (<<) denotes big forward (backward) escape.
+.I E
+is the magnitude of the escape in CAT horizontal units.
+.TP
+.RI "++ " L
+++ (--) denotes big forward (backward) leading.
+.I L
+is the magnitude of the leading in CAT vertical units.
+.SH SEE ALSO
+troff(1), cat(5)
diff --git a/dviware/quicspool/man/dumpdesc.l_backup b/dviware/quicspool/man/dumpdesc.l_backup
new file mode 100644
index 0000000000..10e517ce46
--- /dev/null
+++ b/dviware/quicspool/man/dumpdesc.l_backup
@@ -0,0 +1,30 @@
+.\" $Header: dumpdesc.l.backup,v 1.1 88/01/15 12:58:18 simpson Rel $
+.\" $Log: dumpdesc.l.backup,v $
+.\" Revision 1.1 88/01/15 12:58:18 simpson
+.\" initial release
+.\"
+.\" Revision 0.1 87/12/11 17:56:51 simpson
+.\" beta test
+.\"
+.TH DUMPDESC 1 TRW
+.UC
+.SH NAME
+dumpdesc \- symbolically dump out the contents of a ditroff DESC file
+.SH ORIGIN
+TRW
+.SH SYNOPSIS
+dumpDESC
+.I DESCfile
+.SH DESCRIPTION
+.IR Dumpdesc (1)
+symbolically dumps out the contents of a DESC.out file created by
+.I makedev.
+The first argument should be the name of the \fIbinary\fP DESC file (usually
+DESC.out).
+.SH FILES
+.ta \w'--FONTDIR--'
+--FONTDIR-- directory containing DESC.out file
+.SH AUTHOR
+Scott Simpson
+.SH SEE ALSO
+font(5)
diff --git a/dviware/quicspool/man/getopt.l b/dviware/quicspool/man/getopt.l
new file mode 100644
index 0000000000..c1a50de8b0
--- /dev/null
+++ b/dviware/quicspool/man/getopt.l
@@ -0,0 +1,145 @@
+.\" $Header: getopt.l,v 1.1 88/01/15 12:58:20 simpson Rel $
+.\" $Log: getopt.l,v $
+.\" Revision 1.1 88/01/15 12:58:20 simpson
+.\" initial release
+.\"
+.\" Revision 0.1 87/12/11 17:56:51 simpson
+.\" beta test
+.\"
+.TH GETOPT 3
+.SH NAME
+getopt \- get option letter from argument vector
+.SH SYNOPSIS
+.B int getopt (argc, argv, optstring)
+.br
+.B int argc;
+.br
+.B char \(**\(**argv;
+.br
+.B char \(**optstring;
+.PP
+.B extern char \(**optarg;
+.br
+.B extern int optind;
+.PP
+cc ... -ltrw
+.SH DESCRIPTION
+.I Getopt\^
+returns the next option letter in
+.I argv\^
+that matches
+a letter in
+.IR optstring .
+.I Optstring\^
+is a string of recognized option letters;
+if a letter is followed by a colon, the option
+is expected to have an argument that may or
+may not be separated from it by white space.
+.I Optarg\^
+is set to point to the start of the option argument
+on return from
+.IR getopt .
+.PP
+.I Getopt\^
+places in
+.I optind\^
+the
+.I argv\^
+index of the next argument to be processed.
+Because
+.I optind\^
+is external, it is normally initialized to zero
+automatically before the first call to
+.IR getopt .
+.PP
+When all options have been processed
+(i.e., up to the first non-option argument),
+.I getopt\^
+returns
+.SM
+.BR EOF .
+The special option
+.B \-\-
+may be used to delimit the end of the options;
+.SM
+.B EOF
+will be returned, and
+.B \-\-
+will be skipped.
+.SH DIAGNOSTICS
+.I Getopt\^
+prints an error message on
+.I stderr\^
+and returns a
+question mark
+.RB ( ? )
+when it encounters an option letter not included in
+.IR optstring .
+.SH WARNING
+The above routine uses \fB<stdio.h>\fP, which causes
+it to increase the size of programs,
+not otherwise using standard I/O, more
+than might be expected.
+.SH EXAMPLE
+The following code fragment shows how one might process the arguments
+for a command that can take the mutually exclusive options
+.B a
+and
+.BR b ,
+and the options
+.B f
+and
+.BR o ,
+both of which require arguments:
+.PP
+.RS
+.nf
+.ss 18
+main (argc, argv)
+int argc;
+char \(**\(**argv;
+{
+ int c;
+ extern int optind;
+ extern char \(**optarg;
+ \&\f3.\fP
+ \&\f3.\fP
+ \&\f3.\fP
+ while ((c = getopt (argc, argv, "abf:o:")) != \s-1EOF\s+1)
+ switch (c) {
+ case \(fma\(fm:
+ if (bflg)
+ errflg++;
+ else
+ aflg++;
+ break;
+ case \(fmb\(fm:
+ if (aflg)
+ errflg++;
+ else
+ bproc( );
+ break;
+ case \(fmf\(fm:
+ ifile = optarg;
+ break;
+ case \(fmo\(fm:
+ ofile = optarg;
+ bufsiza = 512;
+ break;
+ case \(fm?\(fm:
+ errflg++;
+ }
+ if (errflg) {
+ fprintf (stderr, "usage: . . . ");
+ exit (2);
+ }
+ for ( ; optind < argc; optind++) {
+ if (access (argv[optind], 4)) {
+ \&\f3.\fP
+ \&\f3.\fP
+ \&\f3.\fP
+}
+.ss 12
+.fi
+.RE
+.\" @(#)getopt.3c 5.2 of 5/18/82
diff --git a/dviware/quicspool/man/glob.l b/dviware/quicspool/man/glob.l
new file mode 100644
index 0000000000..667ab942cc
--- /dev/null
+++ b/dviware/quicspool/man/glob.l
@@ -0,0 +1,180 @@
+.\" $Header: glob.l,v 1.1 88/01/15 12:58:23 simpson Rel $
+.\" $Log: glob.l,v $
+.\" Revision 1.1 88/01/15 12:58:23 simpson
+.\" initial release
+.\"
+.\" Revision 0.1 87/12/11 17:56:52 simpson
+.\" beta test
+.\"
+.TH GLOB 3 TRW
+.UC
+.SH NAME
+glob \- shell style pattern matching
+.SH SYNOPSIS
+.nf
+.B #include <local/glob.h>
+
+.B int glob_compile(pattern, buffer)
+.B char *pattern;
+.B char *buffer;
+
+.B int glob_execute(buffer, s)
+.B char *buffer;
+.B char *s;
+
+.B int glob_match (pattern, s)
+.B char *pattern;
+.B char *s;
+.fi
+
+.B cc
+[ flags ] files
+.B -lglob
+[ libraries ]
+.fi
+.SH DESCRIPTION
+.I Glob
+is a pattern matching facility similar to that of
+.IR sh (1)
+and
+.IR csh (1).
+.PP
+A pattern specifies a set of strings of characters.
+A member of this set of strings is said to be matched by the pattern.
+.TP
+(1)
+Any character except a special character matches itself.
+The special characters are [ * and ?.
+.TP
+(2)
+A ? matches any character.
+.TP
+(3)
+A nonempty string
+.I s
+bracketed
+.RI [ s ]
+matches any character in
+.IR s .
+In
+.I s
+] may only appear as the first letter.
+A substring
+.IR a \- b ,
+with
+.I a
+and
+.I b
+in ascending ASCII order,
+stands for the inclusive range of ASCII characters.
+.TP
+(4)
+A * matches 0 or more characters.
+.PP
+.I Glob_compile
+compiles a
+.I pattern
+into an internal form suitable for matching,
+placing the result in the character array
+.IR buffer .
+.I Buffer
+must be a character array of size
+.BR GLOB_MAX_PATTERN .
+.I Glob_compile
+returns 0 if the
+.I pattern
+was compiled successfully;
+otherwise a negative error code is returned.
+.PP
+.I Glob_execute
+checks the argument string
+.I s
+against the compiled
+.IR pattern .
+.I Glob_execute
+returns 1 if the string
+.I s
+matches the compiled pattern in
+.IR buffer ,
+0 if the string
+.I s
+failed to match the compiled pattern in
+.IR buffer ,
+and a negative error code if the compiled pattern was invalid.
+.PP
+The strings passed to both
+.I glob_compile
+and
+.I glob_execute
+may have trailing or embedded newline characters;
+they are terminated by nulls.
+.PP
+.I Glob_match
+compiles
+.I pattern
+and matches it against the argument string
+.IR s .
+It returns 1 if the string
+.I s
+matches the pattern;
+0 if the string
+.I s
+fails to match the pattern
+and a negative error code if the pattern was invalid.
+.SH AUTHOR
+Michael Gorlick, TRW
+.SH SEE ALSO
+regex(3)
+.SH DIAGNOSTICS
+The following diagnostic codes are provided:
+.TP
+GLOB_OK
+returned by
+.I glob_compile
+indicating the pattern compiled successfully;
+.TP
+GLOB_PATTERN_TOO_BIG
+returned by
+.I glob_compile
+or
+.I glob_match
+indicating the compiled pattern overflowed the buffer;
+.TP
+GLOB_PATTERN_EMPTY
+returned by
+.I glob_compile
+or
+.I glob_match
+indicating the pattern is the empty string;
+.TP
+GLOB_BRACKET_MISSING
+returned by
+.I glob_compile
+or
+.I glob_match
+indicating that a set expression
+.RI [ s ]
+is missing the terminating bracket ];
+.TP
+GLOB_RANGE_INVERTED
+returned by
+.I glob_compile
+or
+.I glob_match
+indicating a range expression in a set
+is inverted, for example [z-a];
+.TP
+GLOB_SET_TOO_BIG
+returned by
+.I glob_compile
+or
+.I glob_match
+indicating a compiled set requires more than 127 bytes
+(a single character consumes 2 bytes and a range consumes 3 bytes);
+.TP
+GLOB_EXECUTION_ERROR
+returned by
+.I glob_execute
+or
+.I glob_match
+indicating an internal error.
diff --git a/dviware/quicspool/man/makefile b/dviware/quicspool/man/makefile
new file mode 100644
index 0000000000..1b3cc4acb0
--- /dev/null
+++ b/dviware/quicspool/man/makefile
@@ -0,0 +1,46 @@
+# $Header: Makefile,v 1.1 88/01/15 12:58:09 simpson Rel $
+# $Log: Makefile,v $
+#Revision 1.1 88/01/15 12:58:09 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 17:56:47 simpson
+#beta test
+#
+WBTEXFONT=/usr/lib/tex/imagenfonts
+WWTEXFONT=/usr/lib/tex/qmsfonts
+DITROFFFONT=/usr/lib/font/devqms
+OTROFFFONT=/usr/lib/font
+FILTER=/usr/local/lib/lpr
+
+all:
+
+configure:
+ sed s:--WBTEX--:$(WBTEXFONT): < quicspool.l.backup | \
+ sed s:--WWTEX--:$(WWTEXFONT): | sed s:--OFONT--:$(OTROFFFONT): | \
+ sed s:--DIFONT--:$(DITROFFFONT): | sed s:--FILTER--:$(FILTER): \
+ > quicspool.l
+ sed s:--FONTDIR--:$(DITROFFFONT): < dumpdesc.l.backup > dumpdesc.l
+ sed s:--WBTEX--:$(WBTEXFONT): < pktoch.l.backup | \
+ sed s:--WWTEX--:$(WWTEXFONT): | sed s:--OFONT--:$(OTROFFFONT): | \
+ sed s:--DIFONT--:$(DITROFFFONT): > pktoch.l
+ sed s:--FONTDIR--:$(OTROFFFONT): < tfm2ofont.l.backup > tfm2ofont.l
+ sed s:--FONTDIR--:$(DITROFFFONT): < tfm2difont.l.backup > tfm2difont.l
+
+clean:
+ -rm dumpdesc.l pktoch.l tfm2ofont.l tfm2difont.l quicspool.l
+
+install:
+ install -c cat.l /usr/man/manl
+ install -c cati.l /usr/man/manl
+ install -c dumpdesc.l /usr/man/manl
+ install -c getopt.l /usr/man/manl
+ install -c glob.l /usr/man/manl
+ install -c pktoch.l /usr/man/manl
+ install -c profile.l /usr/man/manl
+ install -c profile5.l /usr/man/manl
+ install -c qmsquery.l /usr/man/manl
+ install -c quicspool.l /usr/man/manl
+ install -c shift.l /usr/man/manl
+ install -c standard.l /usr/man/manl
+ install -c tfm2ofont.l /usr/man/manl
+ install -c tfm2difont.l /usr/man/manl
diff --git a/dviware/quicspool/man/makefile.trw b/dviware/quicspool/man/makefile.trw
new file mode 100644
index 0000000000..d73250e7c9
--- /dev/null
+++ b/dviware/quicspool/man/makefile.trw
@@ -0,0 +1,48 @@
+# $Header: Makefile.TRW,v 1.1 88/01/15 12:58:12 simpson Rel $
+# $Log: Makefile.TRW,v $
+#Revision 1.1 88/01/15 12:58:12 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 17:56:48 simpson
+#beta test
+#
+WBTEXFONT=/usr/lib/tex/imagenfonts
+WWTEXFONT=/usr/lib/tex/qmsfonts
+DITROFFFONT=/usr/lib/font/devqms
+OTROFFFONT=/usr/lib/font
+FILTER=/usr/local/lib/lpr
+
+all:
+
+configure:
+ sed s:--WBTEX--:$(WBTEXFONT): < quicspool.l.backup | \
+ sed s:--WWTEX--:$(WWTEXFONT): | sed s:--OFONT--:$(OTROFFFONT): | \
+ sed s:--DIFONT--:$(DITROFFFONT): | sed s:--FILTER--:$(FILTER): \
+ > quicspool.l
+ sed s:--FONTDIR--:$(DITROFFFONT): < dumpdesc.l.backup > dumpdesc.l
+ sed s:--WBTEX--:$(WBTEXFONT): < pktoch.l.backup | \
+ sed s:--WWTEX--:$(WWTEXFONT): | sed s:--OFONT--:$(OTROFFFONT): | \
+ sed s:--DIFONT--:$(DITROFFFONT): > pktoch.l
+ sed s:--FONTDIR--:$(OTROFFFONT): < tfm2ofont.l.backup > tfm2ofont.l
+ sed s:--FONTDIR--:$(DITROFFFONT): < tfm2difont.l.backup > tfm2difont.l
+
+clean:
+ -rm dumpdesc.l pktoch.l tfm2ofont.l tfm2difont.l quicspool.l
+
+install:
+ install -c cat.l /usr/man/manl/cat.5
+ install -c cati.l /usr/man/manl/cati.1
+ install -c dumpdesc.l /usr/man/manl/dumpdesc.1
+ install -c getopt.l /usr/man/manl/getopt.3
+ install -c glob.l /usr/man/manl/glob.3
+ install -c pktoch.l /usr/man/manl/pktoch.1
+ install -c profile.l /usr/man/manl/profile.3
+ install -c profile5.l /usr/man/manl/profile.5
+ install -c qmsquery.l /usr/man/manl/qmsquery.3
+ install -c quicspool.l /usr/man/manl/quicspool.7
+ install -c shift.l /usr/man/manl/shift.3
+ install -c standard.l /usr/man/manl/standard.5
+ install -c tfm2ofont.l /usr/man/manl/tfm2ofont.1
+ install -c tfm2difont.l /usr/man/manl/tfm2ofont.1
+ install -c lpr.l /usr/man/man1/lpr.1
+ install -c pac.l /usr/man/man8/pac.8
diff --git a/dviware/quicspool/man/pktoch.l_backup b/dviware/quicspool/man/pktoch.l_backup
new file mode 100644
index 0000000000..b76bec1a18
--- /dev/null
+++ b/dviware/quicspool/man/pktoch.l_backup
@@ -0,0 +1,47 @@
+.\" $Header: pktoch.l.backup,v 1.1 88/01/15 12:58:29 simpson Rel $
+.\" $Log: pktoch.l.backup,v $
+.\" Revision 1.1 88/01/15 12:58:29 simpson
+.\" initial release
+.\"
+.\" Revision 0.1 87/12/11 17:56:55 simpson
+.\" beta test
+.\"
+.if t .ds TX T\h'-.1667m'\v'.22m'E\h'-.125m'\v'-.22m'X
+.if n .ds TX TeX
+.if t .ds LX L\v'-.22m'a\v'.22m'T\h'-.1667m'\v'.22m'E\h'-.125m'\v'-.22m'X
+.if n .ds LX LaTeX
+.TH PKTOCH 1 TRW
+.UC
+.SH NAME
+pktoch \- print out the contents of a packed format (pk) pixel file
+.SH ORIGIN
+TRW
+.SH SYNOPSIS
+pktoch pkfile chfile
+.SH DESCRIPTION
+.IR Pktoch (1)
+prints out the bit map of a packed format (pk) format pixel file on the second
+argument.
+The output bit map is a readable ascii file containing a dump of the
+information in the packed font file.
+A dump of each character bit map is given so you can see the bitmap of the
+characters. Ones in the bitmaps are represented by *s and zeros are
+represented by periods.
+Other information, such as the
+.I x
+and
+.I y
+offset are also given.
+The format of a pk file is beyond the scope of this manual page.
+.SH FILES
+.nf
+.ta \w'--WBTEX-- 'u
+--WBTEX-- \*(TX write-black engine font directory
+--WWTEX-- \*(TX write-write engine font directory
+--DIFONT--/w?fonts raster font directories
+.SH AUTHOR
+Scott Simpson
+.SH SEE ALSO
+pxtoch(1), tex(1)
+.SH BUGS
+The opposite conversion program is not yet written.
diff --git a/dviware/quicspool/man/profile.l b/dviware/quicspool/man/profile.l
new file mode 100644
index 0000000000..9b02878686
--- /dev/null
+++ b/dviware/quicspool/man/profile.l
@@ -0,0 +1,285 @@
+.\" $Header: profile.l,v 1.1 88/01/15 12:58:31 simpson Rel $
+.\" $Log: profile.l,v $
+.\" Revision 1.1 88/01/15 12:58:31 simpson
+.\" initial release
+.\"
+.\" Revision 0.1 87/12/11 17:56:56 simpson
+.\" beta test
+.\"
+.TH PROFILE 3 TRW
+.UC 4
+.SH NAME
+profile \- read/write configuration files
+.SH SYNOPSIS
+.nf
+.B #include <stdio.h>
+.B #include <local/profile.h>
+
+.B PROFILE_STANZA *profile_read_stanza(f)
+.B FILE *f;
+
+.B PROFILE_STANZA *profile_read_profile(f)
+.B FILE *f;
+
+.B profile_write_stanza(f, s)
+.B FILE *f;
+.B PROFILE_STANZA *s;
+
+.B profile_write_profile(f, s)
+.B FILE *f;
+.B PROFILE_STANZA *s;
+
+.B profile_free_stanza(s)
+.B PROFILE_STANZA *s;
+
+.B PROFILE_MARKER *profile_has_marker(s, m)
+.B PROFILE_STANZA *s;
+.B char *m;
+
+.B PROFILE_STANZA *profile_has_stanza(s, marker)
+.B PROFILE_STANZA *s;
+.B char *marker[];
+
+.B PROFILE_BINDING *profile_has_binding(s, b)
+.B PROFILE_STANZA *s;
+.B char *b;
+
+.B PROFILE_STANZA *profile_stanza_space()
+
+.B PROFILE_MARKER *profile_marker_space(n)
+.B int n;
+
+.B PROFILE_BINDING *profile_binding_space(n)
+.B int n;
+
+.B PROFILE_VALUE *profile_value_space(n)
+.B int n;
+.fi
+.SH DESCRIPTION
+.I Profile_read_stanza
+reads a single stanza from a configuration file returning
+a pointer to the stanza if successful and NULL on error or end of file.
+A stanza is defined as:
+.nf
+.ta 1i +\w'typedef 'u
+
+ typedef struct PROFILE_STANZA {
+ PROFILE_MARKER *marker;
+ PROFILE_BINDING *binding;
+ struct PROFILE_STANZA *previous;
+ struct PROFILE_STANZA *next;
+ } PROFILE_STANZA;
+.fi
+.PP
+.I Marker
+and
+.I binding
+point to linked lists of markers and bindings respectively.
+If
+.I marker
+is
+.B NULL
+the stanza has no markers.
+If
+.I binding
+is
+.B NULL
+the stanza has no bindings.
+.I Previous
+and
+.I next
+are ignored and may be used to doubly link successive stanzas together.
+.DT
+.PP
+A marker is defined as:
+.nf
+.ta 1i +\w'typedef 'u
+
+ typedef struct PROFILE_MARKER {
+ char *text;
+ struct PROFILE_MARKER *previous;
+ struct PROFILE_MARKER *next;
+ } PROFILE_MARKER;
+.fi
+.DT
+.PP
+.I Text
+is a string containing the literal text of the marker
+and is always nonempty.
+.IR Previous " (" next )
+is a pointer to the previous (next) marker in the sequence.
+In the first (last) marker
+.IR previous " (" next )
+is
+.BR NULL .
+.PP
+A binding is defined as:
+.nf
+.ta 1i +\w'typedef 'u
+
+ typedef struct PROFILE_BINDING {
+ char *name;
+ PROFILE_VALUE *value;
+ struct PROFILE_BINDING *previous;
+ struct PROFILE_BINDING *next;
+ } PROFILE_BINDING;
+.fi
+.DT
+.PP
+.I Name
+is the literal text of the name of the binding and is always nonempty.
+.I Value
+is a pointer to the list of values associated with the name.
+If
+.I value
+is
+.B NULL
+then the binding consists solely of a name with no associated value.
+.IR Previous " (" next )
+points to the previous (next) binding in the sequence.
+In the first (last) binding
+.IR previous " (" next )
+is
+.BR NULL .
+.PP
+A value is defined as:
+.nf
+.ta 1i +\w'typedef 'u +\w'union { 'u
+
+ typedef struct PROFILE_VALUE {
+ char class;
+ union {
+ long int i;
+ double f;
+ char c;
+ char *s;
+ } value;
+ struct PROFILE_VALUE *previous;
+ struct PROFILE_VALUE *next;
+ } PROFILE_VALUE;
+.fi
+.DT
+.PP
+.I Class
+is always one of:
+.TP
+PROFILE_CHARACTER
+the value is a character constant contained in
+.IR c .
+.TP
+PROFILE_HEX
+the value is a hex constant contained in
+.IR i .
+.TP
+PROFILE_INTEGER
+the value is an integer constant contained in
+.IR i .
+.TP
+PROFILE_FLOAT
+the value is a real constant contained in
+.IR f .
+.TP
+PROFILE_OCTAL
+the value is an octal constant contained in
+.IR i .
+.TP
+PROFILE_STRING
+the value is a string constant contained in
+.IR s .
+.TP
+PROFILE_OTHER
+the value is not recognizably
+character,
+hex,
+integer,
+float,
+octal
+or string.
+The literal text is contained in
+.IR s .
+.PP
+.IR Previous " (" next )
+points to the previous (next) value in the sequence.
+In the first (last) value
+.IR previous " (" next )
+is
+.BR NULL .
+.PP
+.I Profile_read_profile
+reads an entire configuration file and builds a bi-directional,
+circularly linked list of stanzas using the
+.I previous
+and
+.I next
+pointers.
+The value returned is a pointer to the first stanza in the list.
+.PP
+.I Profile_write_stanza
+writes a stanza in a canonical form suitable for input by
+.IR profile_read_stanza .
+Markers are output one to a line.
+Each binding is indented by a single tab.
+Names and values are separated, one from the other,
+by a single blank.
+.PP
+.I Profile_write_profile
+writes all the stanzas in a linked list by applying
+.I profile_write_stanza
+to each stanza in the list.
+The list need not be doubly linked.
+.PP
+.I Profile_free_stanza
+frees all storage associated with a stanza.
+.PP
+.I Profile_has_marker
+searches the marker list of a stanza for a match to the given marker,
+.IR m .
+A pointer to the marker is returned on success and
+.B NULL
+on failure.
+.PP
+.I Profile_has_stanza
+searches a linked list of stanzas for a stanza that has all the
+markers in
+.I marker.
+.I Marker
+must be terminated by a null entry.
+.PP
+.I Profile_has_binding
+searches the binding list of a stanza
+for a binding with a match to the given name.
+A pointer to the binding is returned on success and
+.B NULL
+on failure.
+.PP
+The following routines are useful for constructing stanzas on the fly.
+.I Profile_stanza_space
+allocates storage for a stanza.
+.I Profile_marker_space
+allocates storage for a marker including sufficient space for
+.I n
+characters of text plus a terminating null byte.
+.I Profile_binding_space
+allocates storage for a binding including sufficient space for
+.I n
+characters of name text plus a terminating null byte.
+.I Profile_value_space
+allocates storage for a value.
+If
+.I n
+is positive and non-zero the component
+.IR value . s
+is initialized as a
+.IR n +1
+character array.
+All of the above routines return a pointer on success and
+.B NULL
+on failure.
+All storage is zero filled.
+The routine
+.IR free (3)
+may be safely used to release storage allocated by these routines.
+.SH AUTHOR
+Michael Gorlick, TRW
+.SH SEE ALSO
+malloc(3), profile(5)
diff --git a/dviware/quicspool/man/profile5.l b/dviware/quicspool/man/profile5.l
new file mode 100644
index 0000000000..29657c9cb4
--- /dev/null
+++ b/dviware/quicspool/man/profile5.l
@@ -0,0 +1,237 @@
+.\" $Header: profile5.l,v 1.1 88/01/15 12:58:34 simpson Rel $
+.\" $Log: profile5.l,v $
+.\" Revision 1.1 88/01/15 12:58:34 simpson
+.\" initial release
+.\"
+.\" Revision 0.1 87/12/11 17:56:57 simpson
+.\" beta test
+.\"
+.TH PROFILE 5 TRW
+.UC 4
+.SH NAME
+profile \- configuration file format
+.SH SYNOPSIS
+.B #include <local/profile.h>
+.SH DESCRIPTION
+.I Profile
+is a general purpose configuration file facility.
+.PP
+Each profile is an ASCII file containing a sequence of one or more
+.IR stanzas .
+Each stanza in turn consists of a sequence of
+.I markers
+followed by a sequence of
+.IR bindings .
+The characters `{' (left brace) and `}' (right brace)
+delimit the beginning and end respectively of the stanza bindings.
+Each binding consists of a name
+followed by an optional sequence of values.
+.SH MARKERS
+Markers are arbitrary patterns in the style of
+.IR glob (3)
+delimited by white space.
+The list of markers may be empty.
+There is no limit to the number of markers.
+Examples of markers are:
+.nf
+
+ queue
+ /usr/lib
+ 1776
+ a_long_marker
+ file[0-9]*.?
+.fi
+.SH BINDINGS
+Bindings are the association of names with values.
+There is one binding to a line each consisting of a name followed
+by an optional sequence of values.
+Names and values are separated,
+one from the other,
+by blanks or tabs.
+Here a newline preceded by a backslash is equivalent to a blank.
+The list of bindings may be empty.
+There is no limit to the number of bindings.
+By convention each binding is indented by a single tab.
+.SH NAMES
+Names are arbitrary patterns in the style of
+.IR glob (3)
+delimited by white space.
+.SH VALUES
+Values are
+integer,
+real,
+octal,
+hex,
+character,
+or
+string
+constants.
+Arbitrary text,
+not recognizably one of the aforementioned types,
+is classified as
+.I other
+and is a legitimate value.
+.TP
+integer
+A sequence of digits optionally preceded by a minus sign.
+Every integer constant is taken to be long.
+.TP
+floating
+A floating constant consists of an optional minus sign,
+an integer part
+a decimal point,
+a fraction part,
+an
+.B e
+or
+.BR E ,
+and an optionally signed integer exponent.
+The integer and fraction parts both consist of a sequence of digits.
+Either the integer part or the fraction part (not both)
+may be missing;
+either the decimal point or the
+.B e
+and the exponent (not both) may be missing.
+Every floating constant is taken to be double-precision.
+.TP
+hex
+A sequence of hexidecimal digits preceded by
+.B 0x
+or
+.BR 0X .
+The hexidecimal digits are 0-9, a-e and A-F.
+Every hex constant is taken to be long.
+.TP
+octal
+A sequence of octal digits preceded by
+.B 0o
+or
+.B 0O
+(digit zero followed by a letter o).
+The octal digits are 0-7.
+Every octal constant is taken to be long.
+.TP
+character
+A character constant is a character enclosed in single quotes.
+Certain non-graphic characters,
+the single quote ',
+the caret ^ and
+the backslash \\,
+may be represented according to the following table of escape sequences:
+.ta 1i +\w'carriage return 'u
+.nf
+
+ newline \\n
+ horizontal tab \\t
+ backspace \\b
+ carriage return \\r
+ form feed \\f
+ escape \\e
+ backslash \\\\
+ single quote \\'
+ caret \\^
+ control-@ ^@
+ control-A ^A
+ ... ...
+ control-Z ^Z
+ control-[ ^[
+ control-\\ ^\\
+ control-^ ^^
+ control-_ ^_
+ delete ^?
+ bit pattern \\\fIddd\fR
+
+.fi
+.DT
+The escape \\\fIddd\fR
+consists of the backslash followed by 1, 2, or 3 octal digits
+which are taken to specify the value of the desired character.
+If the character following a backslash (caret) is not one of those
+specified, the backslash (caret) is ignored.
+.TP
+string
+A string is a sequence of characters surrounded by double quotes, as in
+\fB"..."\fR.
+In a string,
+the double quote character \fB"\fR must be preceded by a \\;
+in addition,
+the same escapes as described for character constants may be used.
+.PP
+Examples of values are:
+.nf
+
+ 7
+ -1.293e3
+ 0x10a5
+ 0o1273
+ 'x'
+ "a string"
+ an_other_value
+.fi
+.SH COMMENTS
+Comments may appear anywhere within a profile.
+They are introduced by the character `#' and are terminated by
+the succeeding newline.
+.SH EXAMPLES
+The empty stanza.
+.nf
+
+{
+}
+.fi
+.PP
+A stanza in the configuration file of a fictitious network server.
+.nf
+.ta \w'queue 'u +\w'cost_per_packet 'u +\w'0o125 0x1af 'u
+
+queue net*
+{
+ priority 7 # integer
+ expect "who is it" # string
+ send '?' # character
+ flags[0-9] 0o125 0x1af # octal and hex
+ cost_per_packet 0.28 # floating
+ device /dev/net # other
+ homebrew # a name with no associated value
+}
+.fi
+.DT
+.PP
+A password file entry recast as a stanza.
+.nf
+.ta \w'brown 'u +\w'password 'u
+
+brown
+{
+ password /bObOZtyGclMV
+ userid 225
+ groupid 30
+ home /home/brown
+ shell /bin/csh
+}
+.fi
+.DT
+.PP
+A termcap entry recast as a stanza.
+.nf
+.ta \w'adm3a 'u +\w'mm 'u
+
+adm3a
+{
+ fullname "lsi adm3a"
+ am
+ bs
+ cm "\\e=%+ %+ "
+ cl "1^Z"
+ co 80
+ li 24
+ ho '^^'
+ ma "^K^P"
+ nd '^L'
+ up '^K'
+}
+.fi
+.SH AUTHOR
+Michael Gorlick, TRW
+.SH SEE ALSO
+glob(3), profile(3)
diff --git a/dviware/quicspool/man/qmsquery.l b/dviware/quicspool/man/qmsquery.l
new file mode 100644
index 0000000000..e5b833ef72
--- /dev/null
+++ b/dviware/quicspool/man/qmsquery.l
@@ -0,0 +1,258 @@
+.\" $Header: qmsquery.l,v 1.1 88/01/15 12:58:36 simpson Rel $
+.\" $Log: qmsquery.l,v $
+.\" Revision 1.1 88/01/15 12:58:36 simpson
+.\" initial release
+.\"
+.\" Revision 0.1 87/12/11 17:56:58 simpson
+.\" beta test
+.\"
+.TH QMSQUERY 3 TRW
+.UC
+.SH NAME
+qmsquery \- routines to query the status of a QMS printer
+.SH SYNOPSIS
+.nf
+#include <local/qms.h>
+.sp
+qmsopen(writefd, readfd)
+int writefd, readfd;
+.sp
+struct qmsmap *qmsmap(north, south, west, east)
+double north, south, west, east;
+.sp
+struct qmspag *qmspag()
+.sp
+struct qmsovl *qmsovl()
+.sp
+struct qmspfp *qmspfp()
+.sp
+struct qmsopc *qmsopc()
+.sp
+struct qmsram *qmsram()
+.sp
+struct qmsfnt *qmsfnt()
+.sp
+struct qmsver *qmsver()
+.sp
+qmsclose()
+.sp
+void qmsmapfree(mapinfo)
+struct qmsmap *mapinfo;
+.sp
+void qmsovlfree(ovlinfo)
+struct qmsovl *ovlinfo;
+.sp
+void qmspfpfree(pfpinfo)
+struct qmspfp *pfpinfo;
+.sp
+void qmsopcfree(opcinfo)
+struct qmsopc *opcinfo;
+.sp
+void qmsfntfree(fntinfo)
+struct qmsfnt *fntinfo;
+.fi
+.SH DESCRIPTION
+These routines query the QMS printer for internal information. The QMS
+printer must be connected through two sets of serial lines.
+The QMS laser printers read data through one serial line (the daughter
+board port)
+and send status
+information through their debugger port on another serial line.
+Qmsopen and qmsclose return 1 on success, 0 on error.
+The *free routines free the space containing the structures returned
+by the rest of the routines.
+NULL is used by qmsmap, qmspag, qmsovl, qmspfp, qmsopc, qmsram, qmsfnt and
+qmsver to designate an empty list or an error.
+All of the
+routines except qmsopen, qmsclose and the *free routines
+will displace the current position in the QMS printer
+so you have to reposition the virtual QMS cursor with the tab and justify
+commands after using these routines.
+All of the coordinates are given in inches and
+the routines will change the
+QMS input syntax to inches if it is not already.
+Since the routines are written in
+.IR lex (1)
+and
+.IR yacc (1),
+the
+.I -ll
+library must be loaded when using the routines.
+A variety of structures stored in the header file
+.I qms.h
+are used to return information.
+.nf
+.sp
+/* Structure returned when requesting MAP info */
+struct qmsmap {
+ int count; /* Byte count */
+ int checksum;
+ char *data; /* "count" bytes of data terminated by NULL */
+ struct qmsmap *next;
+};
+
+/* Structure returned when requesting PAG info */
+struct qmspag {
+ char PO; /* Orientation. 'P' or 'L' */
+ float TM; /* Top margin */
+ float BM; /* Bottom margin */
+ float LM; /* Left margin */
+ float RM; /* Right margin */
+ float LPI; /* Lines per inch */
+ float CPI; /* Characters per inch. 0 == Proportional */
+ short PT; /* Paper Tray. 0 == Top tray. 1 == Bottom Tray */
+ short PS; /* Page Size. 0 == Short. 1 == Long. 2 == European A-4 */
+ char SO; /* Stacker Offset. 'Y' or 'N' */
+ short CC; /* Copy Count */
+};
+
+/* Structure returned when requesting OVL info */
+struct qmsovl {
+ enum { regular, automatic } ovltype;
+ /* The number and size are only valid for regular overlays */
+ int ovlnumber; /* Overlay number */
+ int ovlsize; /* Overlay size in bytes */
+ struct qmsovl *next;
+};
+
+/* Structure returned when requesting PFP info */
+struct qmspfp {
+ char *module; /* Name of installed module */
+ struct qmspfp *next;
+};
+
+/* Structure returned when requesting OPC info */
+struct qmsopc {
+ struct optnode *OC1, *OC2, *OC3, *OC4, *OC5;
+};
+
+struct optnode {
+ short option; /* Number of option */
+ struct optnode *next;
+};
+
+/* Structure returned when requesting RAM info */
+struct qmsram {
+ short TR; /* Total Ram memory in printer */
+ short AR; /* Current Available Ram memory */
+ short FR; /* Font Ram memory used */
+ short OR; /* Overlay Ram memory used */
+};
+
+/* Structure returned when requesting FNTB info */
+struct qmsfnt {
+ struct fontnode *rom; /* List of rom fonts */
+ struct fontnode *ram; /* List of ram fonts */
+};
+
+struct fontnode {
+ char orientation; /* 'P' or 'L' */
+ short number; /* Font number */
+ long bytes; /* Number of bytes in printer */
+ char version;
+ char class; /* '1' or '2' */
+ struct fontnode *next;
+};
+
+/* Structure returned when requesting version information */
+struct qmsver {
+ float version; /* Version of QUIC */
+ float firmware; /* Version of the firmware */
+ struct date { /* Date of the firmware */
+ short month;
+ short day;
+ short year; /* Without the 1900 */
+ } date;
+};
+.sp
+.fi
+Please refer to the above structures for the discussion of the following
+routines.
+.TP
+qmsopen(writefd, readfd)
+This routine does some internal housekeeping before you can use any of
+the other routines.
+It should be called exactly once before all the other
+routines.
+Writefd is an open file descriptor on the line to the QMS printer
+(the daughter board port).
+Readfd is an open file descriptor on the line to the QMS printer debugger
+port. It is used for reading status information from the QMS printer.
+These routines do not fiddle with the tty bits. Do this elsewhere.
+.TP
+qmsmap(north, south, west, east)
+This function returns a hex dump of a portion of the QMS page memory.
+The coordinates of the dump should be given in inches from the top and left
+of the page. The linked list returned is allocated by
+.IR malloc (3)
+and sorted in the order the data comes from the QMS printer.
+That is, the first node of data is the first line of data returned by the
+QMS printer.
+.TP
+qmspag()
+This function returns information about page formatting specifications.
+The value returned is static and overwritten by each call.
+.TP
+qmsovl()
+This function returns information on currently defined overlays.
+The linked list returned is allocated by
+.IR malloc (3).
+If an automatic overlay is loaded then one and only one of the nodes in
+the list will have ovltype automatic.
+The variables ovlnumber and ovlsize are not used for an automatic overlay.
+The return value ovlinfo is NULL if no overlays are loaded.
+.TP
+qmspfp()
+This function returns a linked list of the currently installed PFP modules.
+The linked list is allocated by
+.IR malloc (3).
+If no PFP modules are installed, pfpinfo is NULL.
+.TP
+qmsopc()
+This function returns information on the currently set option classes.
+The return structure contains a set of five linked lists allocated by
+.I malloc (3)
+but the structure qmsopc is static and its values are overwritten after each
+call.
+If no options are set for one of the five option classes then the
+appropriate list is
+NULL.
+.TP
+qmsram()
+This function returns information about ram usage in the printer.
+The value returned is static and overwritten after each call.
+The ram values are given in blocks. QMS ram memory consists of 16 bit words
+in 1024 byte blocks.
+.TP
+qmsfnt()
+This function returns two lists containing the rom and ram fonts loaded.
+The qmsfnt structure is static but the two lists are allocated by
+.IR malloc (3).
+If no rom or ram fonts are loaded the appropriate list is NULL.
+.TP
+qmsver()
+This function returns information about the firmware.
+The version information returned is stored in a static area that is
+overwritten with each call.
+.TP
+qmsclose()
+This function closes the tty lines used by the above routines. It should
+be called when you are done using the routines.
+.PP
+The *free routines return the space allocated by
+.IR malloc (3)
+for further use.
+Free space routines only exist for the routines above which use
+.IR malloc (3)
+to allocate space. Static areas are not freed by the free routines.
+.SH FILES
+.nf
+.ta \w'/dev/tty* 'u
+/dev/tty* Usually the two serial lines to the printer
+.fi
+.SH AUTHOR
+Scott Simpson, TRW
+.SH SEE ALSO
+lex(1), yacc(1), malloc(3)
+.br
+QUIC Programming Manual
diff --git a/dviware/quicspool/man/quicspool.l_backup b/dviware/quicspool/man/quicspool.l_backup
new file mode 100644
index 0000000000..495f42d4c1
--- /dev/null
+++ b/dviware/quicspool/man/quicspool.l_backup
@@ -0,0 +1,321 @@
+.\" $Header: quicspool.l.backup,v 1.2 88/02/03 08:55:18 simpson Exp $
+.\" $Log: quicspool.l.backup,v $
+.\" Revision 1.2 88/02/03 08:55:18 simpson
+.\" added tpic support
+.\"
+.\" Revision 1.1 88/01/15 12:58:40 simpson
+.\" initial release
+.\"
+.\" Revision 0.1 87/12/11 17:56:59 simpson
+.\" beta test
+.\"
+.de BD
+.nf
+.in +3m
+.sp
+..
+.de ED
+.fi
+.in -3m
+.sp
+..
+.if t .ds TX T\h'-.1667m'\v'.22m'E\h'-.125m'\v'-.22m'X
+.if n .ds TX TeX
+.if t .ds LX L\v'-.22m'a\v'.22m'T\h'-.1667m'\v'.22m'E\h'-.125m'\v'-.22m'X
+.if n .ds LX LaTeX
+.TH QUICSPOOL 7 TRW
+.UC
+.SH NAME
+quicspool \- idiosyncracies of the QMS filters for the Berkeley
+spooling system
+.SH ORIGIN
+TRW
+.SH DESCRIPTION
+.I Quicspool
+is a set of filters for driving QMS or Talaris laser printers under the
+Berkeley spooling system.
+The filters have some features that are not documented in the
+manual pages. These features are described here.
+.PP
+Raw input files should be sent to
+.IR lpr (1)
+with the
+.B -l
+option.
+The raw option turns off translation of line feeds into
+carriage-return/line-feed combinations.
+Since the data sent to the printer is scanned by
+.IR lex (1),
+the ASCII null character should not be sent.
+.PP
+The \*(TX and device-independent troff (ditroff)
+printer filters recognize certain commands that are not part of standard
+\*(TX and ditroff.
+\*(TX recognizes
+the ``\especial'' command when it is
+given the keyword
+``overlay''
+followed by a file in parentheses.
+This file could possibly have
+been generated by a graphics package and should be a sequence of QUIC
+commands to dump out to the printer at that point in the \*(TX
+document.
+For example, the \*(TX command
+.BD
+\especial{overlay(\estring~/quicfile)}
+.ED
+would cause the filter to look for the file
+``quicfile''
+in the user's home directory and output it to the printer at that
+point.
+The ``\estring'' control sequence is necessary or \*(TX expands ~ into
+.BD
+\epenalty \e@M \e
+.ED
+which is not what you want.
+Ditroff also recognizes the ``overlay'' keyword but it has a different syntax.
+If you insert the command
+.BD
+\e!x X overlay(~/quicfile)
+.ED
+in your ditroff document, the contents of
+``quicfile''
+are dumped to the printer at that point.
+.PP
+Tilde escapes are recognized just as in the C shell; that is, names may
+be given after the tilde. Spaces are ignored in the string
+except within the keyword
+``overlay''
+or within the file name where they would serve as delimiters.
+Relative pathnames are not recommended since the filters run in the
+spooling directory of the printer.
+To preserve protections, the filters switch to the uid of the user
+after they begin execution.
+.PP
+The \*(TX driver also provides support for
+.IR tpic ,
+a graphics drawing package for \*(TX that is equivalent to the
+.IR pic (1)
+program for AT&Ts device-independent troff.
+Tpic was written by Tim Morgan at UC Irvine (morgan@ics.uci.edu).
+.PP
+The \*(TX user can use his or her own fonts, possibly created by
+METAFONT, by giving a full pathname to \*(TX's font definition command or
+putting the appropriate fonts in the path of the
+TEXFONTS environment variable. Normally, \*(TX uses this path to
+search for \*(TX Font Metric (tfm) files for font width information.
+This path is also searched by the \*(TX filter for packed font raster files
+(pk format).
+A font file can be converted from the generic font format created by
+METAFONT to the pk format with the program
+.IR gftopk (1).
+Since the filter process is not an ancestor of the user's login
+shell, its execution environment
+is that of root. Consequently, the filter searches the ``.profile'' file
+(if you are using the Bourne or Korn shell) or the ``.cshrc'' and ``.login''
+files (if you are using the C shell) for the TEXFONTS environment
+variable.
+The filter looks for a line of the form
+.BD
+TEXFONTS=...
+.ED
+or
+.BD
+setenv TEXFONTS ...
+.ED
+in the appropriate file and uses the string represented by the
+ellipses as the path for TEXFONTS.
+The filter recognizes continuation lines in the file but the path
+should not be surrounded by quotes since it does not do shell
+interpretation. Tilde escapes and the prefix $HOME are recognized in
+a shell pathname. There should be a single space before and after
+the word ``TEXFONTS'' when you are using the C shell.
+If the user is from a remote host, then obviously the environment
+variable scheme will not work so no files are searched. Also, fonts
+that are not loaded from the system font directory are deleted at the
+completion of every job. This way, users will not accidently use someone
+else's previously loaded font.
+.PP
+There are two queues for each printer\-one for portrait mode and one for
+landscape mode. The landscape queue normally has the same name as the portrait
+queue but the landscape queue's name is suffixed with an `l'.
+Suppose you have a portrait queue called
+``grumpy''
+and a corresponding landscape queue
+``grumpyl''.
+If you queue a file to the grumpy queue and a file is already printing in the
+grumpyl queue, then when you do an
+.IR lpq (1)
+you will get a message
+.BD
+waiting for grumpy to become ready (offline ?)
+.ED
+stating that the grumpy job cannot begin until the grumpyl job is completed.
+You can list the grumpyl queue using the
+.B -P
+flag of lpq.
+.SH \*(TX FONTS
+It is important when using \*(TX to make sure that the size of the PK font
+you are requesting exists.
+If the size does not exist, then the closest size is selected. This
+can cause some strange output when a document is printed if you
+use a font that doesn't exist.
+Fonts normally have a name that looks something like
+.BD
+font\fId\fP.\fIm\fPpk
+.ED
+where ``font\fId\fP'' is the name of the font you give to \*(TX,
+.I d
+is the design size of the font (i.e., the size the font looks best
+at) and
+.I m
+is the magnification.
+Normally fonts are designed with a particular size in mind.
+For example, although cmr10.200pk and cmr5.400pk are both ten points
+high on a 200 dots per inch device, the cmr5 font is a magnified five
+point font that looks crummy at twice its regular size.
+The version designed for ten points has its characters thinned out
+and looks better at the size it was intended for.
+Some fonts look good at any magnification and these fonts normally
+have the
+.I d
+missing from the file name.
+.PP
+The equation 5\fIm\fP/1.5, where
+.I m
+is as above,
+gives the appropriate scale factor if you wish to declare a particular font
+to \*(TX.
+For example, if the
+largest cmr10 font is cmr10.746pk (i.e., \emagstep5), then you
+can declare
+this font in \*(TX by
+.BD
+\efont\ebigfont=cmr10 scaled 2487
+.ED
+If you wish to declare a font using \*(TX's ``at \fIsize\fP'',
+you would use the equation \fIdm\fP/300.
+For example, you could also declare the cmr10 font by
+.BD
+\efont\ebigfont=cmr10 at 24.866pt
+.ED
+.SH GENERIC QUEUEING
+Lpr queues to a specific printer.
+If you wish to queue to any idle printer, you can use the
+.I glpr
+script.
+When your site has multiple printers, this script will look for an idle QMS
+printer if there is one, and queue to it.
+If it cannot find an idle printer, it will attempt to queue to a printer that
+is not stopped or disabled.
+If you wish to queue in landscape mode,
+give the
+.B -L
+option to the script.
+There is also a
+.I glpq
+script that prints out the jobs in each queue.
+.SH TROFF SCRIPTS
+There are two versions of troff on the market: C/A/T troff for the GSI CAT-4
+phototypesetter
+and AT&T's ditroff,
+which supports a variety
+of devices.
+The quicspool software supports the QMS printer for both versions of troff.
+The naming convention for your
+troff varies depending on whether you have purchased
+ditroff or not.
+If you have a stock BSD system and you have not purchased
+ditroff, then the C/A/T troff will be named ``troff\|''. If you have purchased
+ditroff, then the C/A/T troff will be named ``otroff\|''
+and ditroff will be named ``troff\|''.
+The C/A/T troff corresponds to the
+.B -t
+option of lpr and ditroff corresponds to the
+.B -n
+option.
+Unfortunately, you can not simply pipe output from either troff directly
+into lpr and get correct output.
+Instead, use the script
+.I qtroff
+if you wish to use the C/A/T troff and
+.I ditroff
+if you wish to use the device-independent troff.
+You needn't pipe the output from these scripts into lpr.
+The scripts queue the output automatically.
+.PP
+Since both troff and lpr have some conflicting options, the scripts need
+to resolve who to pass the flags to on the command line.
+The flags are passed as follows:
+.sp
+.in +1i
+.ta +1i
+to otroff \fIo\fP,\fIn\fP,\fIm\fP,\fIR\fP,\fIi\fP,\fIq\fP,\fIf\fP,\fIb\fP,\fIa\fP,\fIp\fP,\fIF\fP
+.br
+to ditroff \fIo\fP,\fIn\fP,\fIm\fP,\fIR\fP,\fIi\fP,\fIq\fP,\fIz\fP,\fIa\fP,\fIT\fP
+.br
+to lpr \fIP\fP,\fI#\fP,\fIC\fP,\fIJ\fP,\fI1\fP,\fI2\fP,\fI3\fP,\fI4\fP,\fIw\fP,\fIl\fP,\fIt\fP,\fId\fP,\fIg\fP,\fIv\fP,\fIc\fP,\fIr\fP,\fIM\fP,\fIh\fP,\fIs\fP,\fIL\fP
+.in -1i
+.sp
+Notice that
+.B -m
+option of lpr
+and the
+.B -r
+option of troff
+are not available.
+If you wish to pass these two options on to lpr or troff,
+you can use the capital
+letters
+.B -M
+and
+.BR -R ,
+respectively.
+Since these scripts call
+.I glpr
+you can give the option
+.B -L
+to get landscape mode output.
+.PP
+If you are running
+.IR eqn (1)
+or
+.IR pic (1)
+and you are running ditroff, you will need to give the
+.B -Tqms
+flag to eqn and/or pic.
+.IR Tbl (1)
+does not need such a flag.
+If your system administrator has not installed the appropriate changes to
+your ditroff version of eqn and pic, try using the
+.B -TX9700
+flag instead.
+If you have ditroff and you wish to pipe the output from eqn to
+.I qtroff
+instead of
+.IR ditroff ,
+you will need to give the
+.B -Tcat
+option to eqn to generate output for the C/A/T phototypesetter.
+.PP
+The bell system logo (\e(bs) has been replaced by the TRW logo (\(bs)
+in both versions of troff.
+.SH FILES
+.nf
+.ta \w'--WBTEX-- 'u
+--WBTEX-- \*(TX write-black engine font directory
+--WWTEX-- \*(TX write-white engine font directory
+--OFONT-- old troff font directory
+--DIFONT-- device independent troff font directory
+--FILTER-- filter directory
+.fi
+.SH AUTHOR
+Scott Simpson
+.SH SEE ALSO
+csh(1), eqn(1), gftopk(1),
+ksh(1), lex(1), lpq(1), lpr(1), lprm(1), mf(1), pic(1), sh(1), tbl(1),
+tex(1), troff(1), lpc(8)
+.SH BUGS
+Shading of ellipses in
+.I tpic
+does not work.
diff --git a/dviware/quicspool/man/shift.l b/dviware/quicspool/man/shift.l
new file mode 100644
index 0000000000..0de48b7805
--- /dev/null
+++ b/dviware/quicspool/man/shift.l
@@ -0,0 +1,37 @@
+.\" $Header: shift.l,v 1.1 88/01/15 12:58:43 simpson Rel $
+.\" $Log: shift.l,v $
+.\" Revision 1.1 88/01/15 12:58:43 simpson
+.\" initial release
+.\"
+.\" Revision 0.1 87/12/11 17:57:00 simpson
+.\" beta test
+.\"
+.TH SHIFT 3 TRW
+.UC
+.SH NAME
+string_downshift, string_upshift \- shift case of strings
+.SH SYNOPSIS
+.nf
+.B char *string_downshift(s)
+.B char *s;
+
+.B char *string_upshift(s)
+.B char *s;
+
+.B cc ... -ltrw
+.fi
+.SH DESCRIPTION
+.I String_downshift
+shifts
+.I s
+in place to lowercase.
+.I String_upshift
+shifts
+.I s
+in place to uppercase.
+Both routines return
+.I s.
+.SH AUTHOR
+Michael Gorlick, TRW
+.SH SEE ALSO
+ctype(3), string(3)
diff --git a/dviware/quicspool/man/standard.l b/dviware/quicspool/man/standard.l
new file mode 100644
index 0000000000..5146c71c44
--- /dev/null
+++ b/dviware/quicspool/man/standard.l
@@ -0,0 +1,266 @@
+.\" $Header: standard.l,v 1.1 88/01/15 12:58:46 simpson Rel $
+.\" $Log: standard.l,v $
+.\" Revision 1.1 88/01/15 12:58:46 simpson
+.\" initial release
+.\"
+.\" Revision 0.1 87/12/11 17:57:01 simpson
+.\" beta test
+.\"
+.TH STANDARD 5 TRW
+.UC
+.SH NAME
+standard \- standard include file for portability
+.SH ORIGIN
+TRW
+.SH SYNOPSIS
+#include <local/standard.h>
+.SH DESCRIPTION
+.I Standard
+is a set of defines, macro definitions and typedefs that provide
+portable constructs
+and machine specific information
+for different machine architectures and C compilers.
+Basically, the include file is divided up into four sections:
+machine
+environment
+information,
+standard type definitions,
+useful constants and useful macros.
+.PP
+The environment of the computer a program is executing on is described by
+the following defines:
+.TP
+HAS_UNSIGNED_SHORT
+If defined, unsigned shorts are supported.
+.TP
+CHAR_IS_SIGNED
+If defined, chars are signed.
+.TP
+HAS_UNSIGNED_CHAR
+If defined, unsigned chars are supported.
+.TP
+HAS_UNSIGNED_LONG
+If defined, unsigned longs are supported.
+.TP
+HAS_VOID
+If defined, the void function type is supported.
+.TP
+BITS_PER_CHAR
+Defined as the number of bits in a char.
+.TP
+BITS_PER_SHORT
+Defined as the number of bits in a short.
+.TP
+BITS_PER_INT
+Defined as the number of bits in an int.
+.TP
+BITS_PER_LONG
+Defined as the number of bits in a long.
+.TP
+BITS_PER_POINTER
+Defined as the number of bits in a pointer.
+.PP
+There are a set of machine independent type definitions and macros.
+.TP
+Tiny
+A signed character type.
+.TP
+TINY(\fIx\fP)
+An extraction macro for a signed character. The value of the macro is an
+integer that will be sign extended if the most significant bit of the
+character is one.
+.TP
+UnsignedTiny
+An unsigned character type.
+.TP
+UNSIGNED_TINY(\fIx\fP)
+An extraction macro for an unsigned character. The value of the macro is an
+integer that will not be signed extended even if the most significant bit
+of the character is one.
+.TP
+Short
+Simply a short type. All compilers have a short type but this is included
+for lexical consistency.
+.TP
+UnsignedShort
+An unsigned short type.
+.TP
+UNSIGNED_SHORT(\fIx\fP)
+An extraction macro for an unsigned short.
+The value of the macro is an integer that will not be sign extended even if
+the most significant bit of the short is one.
+.TP
+Integer
+The int type. Included for lexical consistency.
+.TP
+UnsignedInteger
+The unsigned integer type.
+.TP
+Long
+The long type.
+.TP
+UnsignedLong
+An unsigned long type.
+.TP
+UNSIGNED_LONG(\fIx\fP)
+An extraction macro for an unsigned long integer.
+Not all compilers support unsigned longs so we may have to simulate them.
+.TP
+TinyBoolean
+A tiny boolean value. Boolean types take on only the values TRUE and FALSE.
+.TP
+Boolean
+A regular boolean value.
+.TP
+Character
+The char type. Included for lexical consistency.
+.TP
+TinyBits
+A type used only for bit set, clear and test operations.
+.TP
+Bits
+The regular size bit type.
+.TP
+LongBits
+The long size bit type.
+.TP
+Void
+The void type. If the void type is not supported then it is defined as
+an int.
+.TP
+Import
+The storage class used when importing variables from separate files.
+It is defined to be the keyword
+.I extern.
+.TP
+Export
+The storage class used when exporting variables from separate files.
+In C, you needn't
+declare that a variable is available to other files if it is declared
+outside a function so this is defined as a no-op.
+.TP
+Local
+The static storage class.
+.PP
+A number of useful constants are also defined.
+.TP
+TRUE and FALSE
+The values 1 and 0 respectively.
+.TP
+SUCCEED and FAIL
+The values 0 and 1 respectively. These are normally used as exit statuses.
+.TP
+ON
+A long with all the bits set.
+.TP
+OFF
+A long with no bits set.
+.TP
+STANDARD_IN
+Defined as 0.
+.TP
+STANDARD_OUT
+Defined as 1.
+.TP
+STANDARD_ERROR
+Defined as 2.
+.TP
+MAX_TINY
+The maximum value a Tiny type can hold.
+.TP
+MIN_TINY
+The minimum value a Tiny type can hold.
+.TP
+MAX_UNSIGNED_TINY
+The maximum value an UnsignedTiny type can hold.
+.TP
+MIN_UNSIGNED_TINY
+The minimum value an UnsignedTiny type can hold.
+.TP
+MAX_SHORT
+The maximum value a Short type can hold.
+.TP
+MIN_SHORT
+The minimum value a Short type can hold.
+.TP
+MAX_UNSIGNED_SHORT
+The maximum value an UnsignedShort type can hold.
+.TP
+MIN_UNSIGNED_SHORT
+The minimum value an UnsignedShort type can hold.
+.TP
+MAX_INTEGER
+The maximum value an Integer type can hold.
+.TP
+MIN_INTEGER
+The minimum value an Integer type can hold.
+.TP
+MAX_UNSIGNED_INTEGER
+The maximum value an UnsignedInteger type can hold.
+.TP
+MIN_UNSIGNED_INTEGER
+The minimum value an UnsignedInteger type can hold.
+.TP
+MAX_LONG
+The maximum value a Long type can hold.
+.TP
+MIN_LONG
+The minimum value a Long type can hold.
+.TP
+MAX_UNSIGNED_LONG
+The maximum value an UnsignedLong type can hold.
+.TP
+MIN_UNSIGNED_LONG
+The minimum value an UnsignedLong type can hold.
+.TP
+BITS_PER_BYTE
+The number of bits in a byte.
+.PP
+A number of useful macro are also defined.
+.TP
+MAX(\fIx\fP, \fIy\fP)
+Returns the maximum value of
+.I x
+and
+.I y.
+.TP
+MIN(\fIx\fP, \fIy\fP)
+Returns the minimum value of
+.I x
+and
+.I y.
+.TP
+ABS(\fIx\fP)
+Returns the absolute value of its parameter. This works for integers and
+reals.
+.TP
+ROUND(\fIx\fP)
+Returns
+its parameter rounded to the nearest integer value.
+.TP
+CEILING(\fIx\fP)
+Returns the ceiling of its parameter.
+.TP
+FLOOR(\fIx\fP)
+Returns the floor of its parameter.
+.TP
+EQ(\fIs\fP, \fIt\fP)
+Returns true if the two strings passed to it as parameters are equal.
+.TP
+EQN(\fIs\fP, \fIt\fP, \fIn\fP)
+Returns true if the two strings passed to it as parameters are equal in
+the first
+.I n
+characters (as in
+.IR strcmp ).
+.SH FILES
+.nf
+.ta \w'/usr/include/local/standenviron.h 'u
+/usr/include/local/standard.h
+/usr/include/local/standenviron.h
+/usr/include/local/standtype.h
+/usr/include/local/standconst.h
+/usr/include/local/standmacro.h
+.fi
+.SH AUTHOR
+Michael Gorlick
diff --git a/dviware/quicspool/man/tfm2difont.l_backup b/dviware/quicspool/man/tfm2difont.l_backup
new file mode 100644
index 0000000000..b4b9a15df3
--- /dev/null
+++ b/dviware/quicspool/man/tfm2difont.l_backup
@@ -0,0 +1,79 @@
+.\" $Header: tfm2difont.l.backup,v 1.1 88/01/15 12:58:48 simpson Rel $
+.\" $Log: tfm2difont.l.backup,v $
+.\" Revision 1.1 88/01/15 12:58:48 simpson
+.\" initial release
+.\"
+.\" Revision 0.1 87/12/11 17:57:02 simpson
+.\" beta test
+.\"
+.if t .ds TX T\h'-.1667m'\v'.22m'E\h'-.125m'\v'-.22m'X
+.if n .ds TX TeX
+.TH TFM2DIFONT 1 TRW
+.UC
+.SH NAME
+tfm2difont \- convert tfm files to ditroff compatible width tables
+.SH ORIGIN
+TRW
+.SH SYNOPSIS
+tfm2difont
+.B [ -s ]
+.B [ -w
+.I width
+.B ]
+.B [ -l
+.I ligature
+.B ]
+\&...
+file...
+.SH DESCRIPTION
+.IR Tfm2difont (1)
+converts tfm files to ditroff compatible width tables which can subsequently
+be run through
+.I makedev
+and used with ditroff.
+A file is created with the same name as the tfm file with the `.tfm' extension
+removed.
+The `name' and `internalname' are set to the same name as the font.
+.PP
+The
+.B -s
+flag causes the font(s) to be considered special.
+The
+.B -w
+flag allows you to set
+.I spacewidth.
+Normally, a non-special font is assumed to have the ligatures
+.BR ff ,
+.BR fi ,
+.BR fl ,
+.B ffi
+and
+.BR ffl .
+The
+.B -l
+flag causes a named ligature to be removed.
+Any number of
+.B -l
+flags may be given.
+Ligatures are ignored if the font is special since special fonts don't have
+ligatures.
+Because the `a' character is used for kerning information in non-special
+fonts, it must exist in a non-special font.
+.PP
+The created width table contains the size of the characters at 10 points
+.RI ( unitwidth
+in the DESC file).
+.IR Troff (1)
+scales the width of characters depending on the size currently in use.
+So, if a 5 point font is being used, the width is halved.
+Because of this, you cannot create a separate font with reshaped characters
+for five points with
+METAFONT.
+\*(TX allows you to do this though.
+.SH FILES
+.ta \w'--FONTDIR-- '
+--FONTDIR-- device-independent troff font directory
+.SH AUTHOR
+Scott Simpson
+.SH SEE ALSO
+mf(1), tex(1), font(5)
diff --git a/dviware/quicspool/man/tfm2ofont.l_backup b/dviware/quicspool/man/tfm2ofont.l_backup
new file mode 100644
index 0000000000..37b930f742
--- /dev/null
+++ b/dviware/quicspool/man/tfm2ofont.l_backup
@@ -0,0 +1,48 @@
+.\" $Header: tfm2ofont.l.backup,v 1.1 88/01/15 12:58:52 simpson Rel $
+.\" $Log: tfm2ofont.l.backup,v $
+.\" Revision 1.1 88/01/15 12:58:52 simpson
+.\" initial release
+.\"
+.\" Revision 0.1 87/12/11 17:57:03 simpson
+.\" beta test
+.\"
+.if t .ds TX T\h'-.1667m'\v'.22m'E\h'-.125m'\v'-.22m'X
+.if n .ds TX TeX
+.TH TFM2OFONT 1 TRW
+.UC
+.SH NAME
+tfm2ofont \- convert tfm files to old troff compatible width tables
+.SH ORIGIN
+TRW
+.SH SYNOPSIS
+tfm2ofont
+.B [ -s ]
+file...
+.SH DESCRIPTION
+.IR Tfm2ofont (1)
+converts tfm files to old
+troff compatible width tables (C program files) which can subsequently
+be compiled
+and used with troff.
+A file is created with the same name as the tfm file with the `.tfm' extension
+removed, `ft' prepended and `.c' appended.
+.PP
+The
+.B -s
+flag causes the font(s) to be considered special.
+.PP
+.IR Otroff (1)
+scales the width of characters depending on the size currently in use.
+So, if a 5 point font is being used, the width is halved.
+Because of this, you cannot create a separate font with reshaped characters
+for five points with
+METAFONT.
+\*(TX allows you to do this though.
+.SH FILES
+.ta \w'--FONTDIR-- '
+--FONTDIR-- old troff font directory
+.SH AUTHOR
+Scott Simpson
+.SH SEE ALSO
+mf(1), tex(1), troff(1)
+
diff --git a/dviware/quicspool/mffiles/logodesign.mf b/dviware/quicspool/mffiles/logodesign.mf
new file mode 100644
index 0000000000..7ee3264afc
--- /dev/null
+++ b/dviware/quicspool/mffiles/logodesign.mf
@@ -0,0 +1,170 @@
+% $Header: logodesign.mf,v 1.1 88/01/15 12:59:36 simpson Rel $
+% $Log: logodesign.mf,v $
+% Revision 1.1 88/01/15 12:59:36 simpson
+% initial release
+%
+% Revision 0.2 88/01/13 12:16:31 simpson
+% removed trademark notice
+%
+% Revision 0.1 87/12/11 19:16:34 simpson
+% beta test
+%
+% RCS $Header: logodesign.mf,v 1.1 88/01/15 12:59:36 simpson Rel $
+% Makes the TRW logo! Whoopee!
+def LOGO =
+z0=(0,3.91a);
+
+y1=y0-1a;
+fixpt(z1,z0,250);
+
+y2=y1;
+over(z2,z1,3.46a);
+
+y3=y0;
+z3-z2=z0-z1;
+
+
+y4=0; fixpt(z4,z0,250); % the imaginary intersection of left of top and base
+
+y5=0; over(z5,z4,1.19a);
+
+y6=0; over(z6,z4,2.45a);
+
+y7=2.16a;
+fixpt(z7,z6,70);
+
+y8=y7; z8-z5 = z7-z6;
+
+
+fill z0--z1--z2--z3..cycle; % Top of the T
+fill z5--z6--z7--z8..cycle; % Bottom of the T
+
+% The R requires some erasures. Tricky.
+
+y10=0;
+over(z10,z4,3.8a);
+
+y11=y10;
+over(z11,z4,5.01a);
+
+y12=2.16a;
+fixpt(z12,z11,70);
+
+y13=y12;
+z13-z10=z12-z11;
+
+fill z10--z11--z12--z13..cycle; % Bottom parallelogram of the R
+
+pair bigcenter; % Center of major (2.51 diam) circle;
+bigcenter=((7.60-.26)*a-(2.51a/2),(3.91a-(2.51a/2)));
+
+pair littlecenter; % Center of the minor (1.08 rad) circle;
+littlecenter=((7.60-.26)*a-1.08a, (3.91-1.08)*a);
+
+y14=3.91a; fixpt(z14,z10,70);
+y15=y14-1a; fixpt(z15,z10,70);
+y16=y14; x16 = xpart bigcenter;
+y17=y15; x17 = x16;
+
+fill z14--z15--z17--z16..cycle; % Top left of the R, sort of.
+
+pair rvert; % the imaginary vertex of the R
+ypart rvert=2.36a;
+fixpt(rvert,z11,70);
+
+y18=0; fixpt(z18,rvert,(250+45.5));
+y19=0; x19=x18+1.29a;
+x20=x18+.56a;
+y21=2.15a; fixpt(z21,rvert,(250+45.5));
+path bigsemicircle;
+bigsemicircle = (halfcircle scaled (2.51a) rotated (-90)) shifted bigcenter;
+path crossline;
+ crossline = (x18+0.56a, 0)..(x18+.56a, 3a);
+z100 = (x18+0.56a, 3*a*xpart (crossline intersectiontimes bigsemicircle) );
+y101 = 2.16a; x101=x100;
+y102 = y101; fixpt(z102, rvert, (250+45.5));
+
+fill z18--z19--z100--z101--z102..cycle; % Bottom right of the R.
+fill bigsemicircle--cycle; % Top right of the R, without the extras.
+fill (quartercircle scaled (1.08a*2) shifted littlecenter)--cycle;
+
+x103=(7.60-(.26+1.24))*a; y103 = y15; % Fill in something to carve out
+y104=y103; x104 = x103-.31a;
+x105=x104; y105 = y104-.31a;
+y106=2.16a; x106= x103-(.9/2)*a;
+y107=y106; x107=x103;
+
+fill z103--z104--z105--z106--z107--cycle; % Now we have to take away the circs
+
+path bigecirc, smallecirc; % The quarter circles to unfill
+pair bigecent, smallecent; % different centers
+
+bigecent = (x106,(2.16a+(.9/2)*a));
+smallecent = (x104, y105);
+
+bigecirc = (((quartercircle rotated -90)scaled .9a) shifted bigecent) --
+bigecent--cycle;
+smallecirc = ((quartercircle scaled (.31a*2)) shifted smallecent) -- smallecent
+ --cycle;
+
+unfill bigecirc; unfill smallecirc; % We can but hope.
+
+
+% The W is a *little* easier
+
+z22=(7.6a,3.91a);
+z23=(7.6a,2.91a);
+z24=((7.6+1.19)*a, 2.91a);
+z25-z24=z22-z23;
+
+fill z22--z23--z24--z25..cycle; % Top left rect of W
+
+z26=(7.6a,0);
+x27=x26;y27=2.16a;
+x28=x24;y28=y27;
+x29=x28;y29=y28-.33a;
+y30=y28; fixpt(z30,z29,70);
+
+pair wvert; % The bottom vertex of the w, imaginary in the hole
+wvert=(9.93a,(2.16+.41)*a);
+
+y31=y30; fixpt(z31,wvert,(270-21.75));
+y32=0; fixpt(z32,wvert,(270-21.75));
+
+fill z32--z31--z27--z26..cycle; % Bottom left of W (omit 28...30)
+
+pair uright; % The upper right. Determines where the bottom ends up
+uright=(12.82a, 3.91a);
+
+x33=xpart wvert; y33=0;
+y34=0; fixpt(z34,uright,(270-22.25));
+y35=2.16a; fixpt(z35,uright,(270-22.25));
+x36=x33; y36=y35;
+y37=y36; x37=x22+3.35a;
+x38=x37; y38=y37-.33a;
+y39=y37; fixpt(z39,z38,70);
+
+%show z33,z34,z35,z39,z38,z37,z36;
+fill z33--z34--z35--z36..cycle; % Bottom right of W (omit 39--38--37)
+
+z40=uright;
+y41=y40; fixpt(z41,z38,70);
+y42=2.91a; fixpt(z42,z38,70);
+y43=y42; fixpt(z43,uright,(270-22.5));
+
+fill z40--z41--z42--z43..cycle; % Upper right trapezoid of W
+
+z44=(x38,y40);
+y45=y44; fixpt(z45,z29,70);
+y46=y43; fixpt(z46,z29,70);
+z47=(x44,y46);
+
+fill z44--z45--z46--z47..cycle; % Top middle trapezoid of W
+
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
+penlabels(21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40);
+penlabels(41,42,43,44,45,46,47);
+penlabels(100,101,102,103,104,105,106,107);
+
+enddef;
+
diff --git a/dviware/quicspool/readme.nr b/dviware/quicspool/readme.nr
new file mode 100644
index 0000000000..f4c5b65fad
--- /dev/null
+++ b/dviware/quicspool/readme.nr
@@ -0,0 +1,593 @@
+.\" $Header: README.nr,v 1.1 88/01/15 12:14:04 simpson Rel $
+.\" $Log: README.nr,v $
+.\" Revision 1.1 88/01/15 12:14:04 simpson
+.\" initial release
+.\"
+.\" Revision 0.2 88/01/13 14:31:43 simpson
+.\" removed reference to pre-made PK files
+.\"
+.\" Revision 0.1 88/01/07 08:27:30 simpson
+.\" beta test
+.\"
+.\" This document uses the -ms macros
+.if t .ds Tx T\h'-.1667m'\v'.22m'E\h'-.125m'\v'-.22m'X
+.if n .ds Tx TeX
+.if t .ds LX L\v'-.22m'a\v'.22m'T\h'-.1667m'\v'.22m'E\h'-.125m'\v'-.22m'X
+.if n .ds LX LaTeX
+.TL
+QMS and Talaris Laser Printer Software for
+the 4.2 BSD Spooling System
+.AU
+Scott Simpson
+.AI
+TRW Space & Defense Sector
+One Space Park, R2/2133
+Redondo Beach, CA 90278
+(213) 812-5338
+{decvax,ucbvax,ihnp4}!trwrb!simpson
+trwrb!simpson@trwind.trw.com
+.AB
+.PP
+This is the installation guide for the 4.2 BSD QMS and Talaris
+laser printer software. It is a long document, so before you
+install anything get a cup of coffee (or a beer),
+put your feet on the desk, and relax. This will be
+a fun, hallucinogenic ride through installation land.
+.AE
+.SH
+The Name Of The Game
+.PP
+Many of you may not know the difference between a Talaris
+printer and a QMS printer. Well, the difference is\-nothing. Well,
+almost nothing. Talaris puts new ROM fonts in their printer when they
+sell it to you but they just buy the printers from QMS and put their
+name on them. QMS in turn buys their printer engines from Xerox,
+Canon and Ricoh and puts their controllers on them. The end result is that
+consumers like you and I pay through the wazoo for everything. Such
+is the way of the world.
+.SH
+In The Beginning...
+.PP
+Around 1985 I had
+written a QMS \*(Tx and troff driver for our QMS laser printers since at
+the time there were none available (or none that I knew of). I made
+this driver compatible with an otroff (the C/A/T troff, not ditroff)
+driver called ``qcat'' from Mt. Xinu. This driver maintained a state
+table on disk which stored information about the fonts currently
+residing in the printer. Some type of state information needed to be
+stored since it was not possible to query the QMS printer to ask it
+what fonts it had downloaded or how much memory those fonts consumed.
+This seemed like a logical solution.
+.PP
+I didn't like the code so
+I rewrote it. Before I rewrote the troff driver, I had given my \*(Tx
+driver to the University of Washington to distribute on the Unix \*(Tx
+tape. After I had completed my troff driver, a number of people
+discovered my TRW telephone number and asked if they could have a copy
+of it (the driver, not my telephone number). I freely gave away the
+software to interested parties.
+.SH
+Problems In Paradise
+.PP
+I immediately ran into some problems. The otroff driver used
+proprietary fonts so when someone asked for the code, they needed to
+already have ``qcat'' and the fonts. Freely distributable fonts were needed.
+.PP
+I also discovered some annoying problems with the \*(Tx and
+troff drivers. First, the state table presents a consistency problem.
+If the printer is powered down or if fonts are downloaded without
+going through the driver software or the state table is inadvertently
+trashed, the table and the printer have different ideas about what
+fonts are loaded and they proceed to print funny documents often with
+many greek characters. (The character 0 is Gamma in \*(Tx fonts and the
+QMS printer prints character 0 when it can't find a letter in a
+certain font.) This is very entertaining unless you are trying to get
+work done. Users don't have a sense of humor.
+.PP
+Another more serious problem reared its ugly head. The \*(Tx
+driver supported the ``\especial'' command of \*(Tx. So, you could say
+``\especial{overlay(/staff1/simpson/barchart)}'' and output the file
+barchart to the QMS printer at that point. The file ``barchart'' would be
+a QMS QUIC file possibly generated by a graphics program. Nice graphs
+and other wonderful pictures could be inserted into \*(Tx documents this
+way. There is one problem: the driver often ran as root. So, the
+mischevious user could say ``\especial{overlay(/usr/lib/uucp/L.sys)}'' and
+merrily print out the contents of the UUCP password file. This is not
+good. A simple solution would be to change the uid of the driver to
+the person running the driver. This works, but now you must make the
+state table writable by everyone so the driver can write it. This is
+also not good. A last solution would be to run as root, open the
+state table, leave it open and then change the uid. This works, is
+secure and was not implemented. Sorry. (The new drivers do this and
+don't suffer security problems.)
+.PP
+During the next couple of years a few nice advances in
+technology occurred. The very compact pk format font file was
+designed. This font format stores the bit rasters as run lengths
+rather than bit maps. It created a 78% reduction in font file disk
+space over the pxl format (which stores characters as bit maps) on our
+system. Also, QMS added the ability to query the controller and ask
+it pertinent information about the status of the printer. Information
+is provided about available font ram and the currently downloaded
+fonts. This is very useful. I congratulate QMS on doing something
+right. Unfortunately, the way they implemented it was brain damaged.
+There are two ports on the QMS controller. Ours are both serial lines
+although one used to be a parallel interface. RS232 lines can
+talk both ways but the QMS dedicates one line for writing to the QMS
+printer and the other line (known as the debugger port) for reading
+status information. It works but you have to dedicate two ports to
+each printer instead of one. Not too painful. Lastly, they added the
+ability to download font data in binary format instead of as ASCII hex
+characters. This allows you to send half the amount of data down to
+the printer when downloading fonts compared to the ASCII hex format.
+Since much of the printer time is spent downloading fonts, this is
+actually quite useful.
+.PP
+In summary, the old driver is woefully out of date. If you have
+it, burn it in effigy.
+.SH
+My Solution
+.PP
+My solution incorporates what I feel is the best solution so
+far. I decided to write a set of filters to fit snugly in the 4.2BSD
+spooling system.
+My new otroff, ditroff and \*(Tx drivers query the QMS printers
+for font download and ram available information so the information is
+always correct, even if you re-power up the printer. Also, my driver
+uses the new compact ``pk'' font format and converts fonts from ``pk'' format
+to QMS format on the fly. Eight bit download format is used.
+.PP
+QMS font numbers are assigned ranges. The font numbers
+1-10000 are available for \*(Tx fonts and the range 10001-20000 are for
+troff fonts (both otroff and ditroff share the same fonts).
+Consequently, you can not have more than 10000 \*(Tx or
+10000 troff fonts. If you run over this limit you are warped. Font
+numbers are assigned in the following manner: Each time the driver
+runs, it reads all the names in the font directory and assigns them
+numbers consecutively in the order they are found in the font
+directory. This takes surprisingly little time. If you add or delete
+files from the system font directory you will have to reset the printer since
+the numbers of the fonts in the printer and the mapping the drivers
+compute may not mesh.
+.SH
+Installation
+.PP
+There are a number of steps to follow to install the software.
+Follow them closely. Don't be scared about the length. I explain things
+in gory detail.
+.IP 1.
+You must have a running METAFONT and \fIgftopk\fR(1)
+to create the troff fonts.
+Copy the METAFONT file ``logodesign.mf'' in the directory
+``mffiles'' to your METAFONT macro directory.
+Next, run the ``makefonts'' scripts in the directories ``wwfonts''
+and ``wbfonts''.
+This assumes you have set up the mode ``qms'' for the Xerox and Ricoh
+engines and the mode ``imagen'' for the Canon engine.
+Our ``local.mf'' contains the lines
+.ID
+.ft CW
+mode_def imagen = % imagen mode: for the Imagen 8/300 (Canon engine)
+ proofing:=0; % no, we're not making proofs
+ fontmaking:=1; % yes, we are making a font
+ tracingtitles:=0;% no, don't show titles in the log
+ pixels_per_inch:=300;
+ blacker:=0; % Canon engine is black enough
+ fillin:=.2; % and it tends to fill in diagonals
+ o_correction:=.6;
+ enddef;
+
+mode_def qms = % qms mode: for the QMS (Xerox engine)
+ proofing:=0; % no, we're not making proofs
+ fontmaking:=1; % yes, we are making a font
+ tracingtitles:=0;% no, don't show titles in the log
+ pixels_per_inch:=300;
+ blacker:=.8; % Values from Charles Karney, TUGboat, April 1987
+ fillin:=.2;
+ o_correction:=.4;
+ enddef;
+.DE
+.ft R
+``Local.mf'' is loaded when you create METAFONT.
+If you don't understand the concept of modes or how ``local.mf'' plays
+a part in all this, see The METAFONTbook.
+Running these two scripts will probably take a couple of days. Literally.
+.IP 2.
+Decide if you have device-independent troff. This is easy.
+Did you send a lot of money to AT&T and get a tape in the mail? If you
+did, you must unfortunately make some changes to the eqn and pic preprocessors
+that came in the distribution.
+These two processors take a
+.B -T
+option which designates which device to generate
+output for.
+We need to add the QMS printer as a valid device.
+In the directory ``diffs'' are two context diffs suitable for input to
+Larry Wall's infamous
+.I patch
+program.
+The eqn patch modifies the file ``io.c'' in the distribution.
+The pic patch modifies the file ``main.c'' in the distribution. Modify
+your eqn and pic now.
+.IP 3.
+If you have multiple printers, let's first set up one printer at a time.
+You can come back to this step to install more printers when you are done
+if need be.
+Select two tty ports to use to talk to your printer.
+That's right. Each printer needs
+.I two
+serial tty lines.
+If your printer has a parallel port, get
+it converted.
+A parallel port will probably work but I have not tested it. You are on
+your own if you don't convert to serial.
+Two types of flow control are used\-one type for each
+port. The daughter board port uses hardware flow control. The
+printer lowers DTR when the buffer is full and raises it when it is
+ready to accept data. Since the computer is a DTE and the printer is
+a DTE, a null modem must be used to connect the computer and the
+printer.
+The tty bits for the daughter board port are
+specified in the ``/etc/printcap'' file and are
+set by lpr. The tty bits are also read by my software to set the
+debugger port bits.
+.IP
+Hardware flow control (DTR) is used for the daughter board port so
+^S/^Q can be sent and not interpreted as flow control. Unfortunately,
+the debugger port will not work with hardware flow control and ^S/^Q
+must be used.
+Simply run a regular RS-232 line through from the debugger port to the
+computer.
+.IP
+All machines don't work as simply as this. In fact, none of the machines
+I have tested the software on work as simply as this!
+Here are descriptions of what to do different for different machines.
+If your machine is not listed here, the software has not been tested on your
+machine and you need to figure it out. When you do, let me know so I can
+share your experience with other users of the same equipment.
+.RS
+.IP PYRAMID
+The Pyramid does not use a
+normal null modem. To create a null modem for the Pyramid, switch
+pins 2 and 3, 4 and 8, and connect pin 20 on one side to pins 5 and 6
+on the other side.
+Connect lines 1, 7 and 22 straight through.
+I don't know why this works and even the people at
+RTOC (Pyramid's Remote Technical Operations Center) could not explain
+it to me.
+.IP SUN
+I hooked the two lines up to the serial ports on the Sun CPU board.
+These ports are driven by the ``zs0'' driver in the kernel configuration
+file.
+The ``flags'' variable to the zs0 driver determines whether a modem
+can detect a carrier drop.
+If bit 0 of the flags variable is on, software carrier will be turned on
+the first port.
+If bit 1 of the flags variable is on, software carrier will be turned on
+the second port.
+We want to use hardware carrier on both ports so set the flags variable
+to 0x0 and reconfigure and reinstall the kernel if necessary.
+.IP
+A Sun null modem can be made by switching lines 2 and 3 and running line
+7 straight through. See the excellent Sun documentation.
+.IP "OTHER COMPUTERS"
+Here are some hints for other computers.
+First, check the documentation!
+This sounds completely obvious but it is amazing how many people don't do
+it.
+If the documentation does not describe how to make a null modem for hardware
+carrier, try using a normal null modem.
+On normal machines, a NULL modem is made by switching pins 2
+and 3, 6 and 20, and looping 4 back to 5.
+Lines 1, 7, 8 and 22 are connected straight through.
+.IP
+Often fast machines have front ends whose tty bits need to be configured.
+For example,
+the Pyramid has a couple of ioctl calls
+specific to it that must be used to really get flow control to work.
+In the file ``of.c'' in the ``src'' directory
+you will see a section demarcated ``#ifdef pyr''
+that really gets the flow control to work on the Pyramid since the
+Pyramid has a pseudo front-end called an ITP which has special ioctl
+calls.
+You may have to change this to get this to work on your
+machine\-or maybe not. You can usually check the include file
+``/usr/include/sys/ioctl.h'' to see if your computer has such a special
+call.
+.RE
+.IP 4.
+Each printer has two queues\-one for portrait mode and one for landscape
+mode.
+The landscape queue retains the same name as the portrait queue but the
+landscape queue is suffixed with an `l'.
+For example, suppose you want to name
+your printer queue ``grumpy''. You will create two queues: ``grumpy'' and
+``grumpyl'' for portrait and landscape mode respectively.
+If you queue to the two different queues simultaneously, you obviously
+don't want both jobs printing at the same time!
+Pyramid has modified their ``lpd'' daemon to check if another job has
+the printer. Sun hasn't.
+If your ``lpd'' does not check whether two jobs are
+using the same printer simultaneously, my software will check for it.
+In the ``src'' directory in the file ``of.c'' you will see two sections
+delimited by ``#if defined(sun)'' that lock out other print jobs.
+Define it in both places
+if your lpd does not lock out other processes.
+.IP 5.
+You'll now have to set up the correct interface options on your
+printer. The interface options for the printer are the class 1 options
+and unfortunately cannot be set by software. If you have a QMS 1200, QMS
+1500 or
+QMS 2400,
+set the interface options
+2 and 30 in class 1 using the panel.
+Do not set any other options within this class.
+This is eight bit, no parity with hardware flow control.
+If you have a QMS 800, set
+bit 2 on SWS 1 on, all others on SWS 1 off.
+Setting options is
+described in the User Guide and Daughter Board manuals. The options in
+the other classes will be set by software and are specified in the
+configuration file (see step 10). You will also need to set the dip
+switches on the QMS Daughter Board to the appropriate speed.
+We use our printers at 9600 baud. I couldn't get 19200 to work. You
+can try.
+Set bits 7 and 8 on, all others off, on switch S1 on the daughter board
+for 9600 baud.
+See the QMS RS-232 Daughter Board Operating Manual.
+.IP 6.
+Set the owner of the two tty lines to root and the group owner to
+daemon. Set the permissions to 660.
+Turn off getty on the two tty lines by editing the ``/etc/ttys'' file.
+If you have a 4.2 BSD ``/etc/ttys'' file, set the first column to 0 to
+disable getty and the second column to the appropriate baud rate.
+Do a ``kill -HUP 1'' so init rereads the ``/etc/ttys'' file.
+.IP 7.
+There are a set of include files written here at TRW which declare
+machine specific C preprocessor #defines and macros.
+Use of these symbolic
+names within programs makes them more portable, since you
+need only change the ``standard'' include files and the programs will port.
+The include files are only currently set up for a small variety of machines.
+You may have to add the appropriate values for your machine.
+.IP
+In the directory ``standard'', look at the files ``standenviron.h'' and
+``standconst.h.'' If your machine type is not in there, add it and send
+me a message telling me what your additions are. Please try to use the
+pre-defined C preprocessor variables as I did. This makes things more
+portable.
+.IP 8.
+The top level Makefile makes and installs everything. You will need to set
+up some paths in it. I strongly suggest that you use the paths distributed.
+Here is what the variables are:
+.RS
+.IP INCLUDE
+This distribution includes a set of libraries that you receive in addition
+to the printer filters. The printer filters use these libraries so you
+must install them. The libraries need some header files and the header
+files are put in this directory. You must
+.I "leave this variable as is."
+.IP FILTER
+This is where all the lpr filters are put. You can change this to anything
+you want, but ``/usr/local/lib/lpr'' seems the most logical.
+.IP LIB
+This is where the bonus libraries are put. The glob and profile library
+are quite useful. The trw and qmsquery libraries aren't.
+.IP "WBTEXFONT and WWTEXFONT"
+This is where the write-black and write-white \*(Tx pk fonts are stored.
+There are two kinds of laser printers in this great big world of ours:
+write-black and write-white engines.
+Write-black printers write the black part with the laser and write-white
+write everything but the black part with the laser.
+To get the best looking output, you should use different fonts for each
+type of printer. The QMS
+800 is a write-black printer. The QMS 1200, QMS 1500 and
+QMS 2400 are write-white printers. At our site, we only have QMS 1200, QMS
+1500 and
+QMS 2400 printers so we don't have any write-black printers. If we did,
+I would put the \*(Tx
+fonts in ``/usr/lib/tex/imagenfonts'' since the imagen 240
+laser printer is write-black.
+Also, you specify ``\emode:=imagen;'' to METAFONT when you want to get
+fonts for a write-black printer.
+We store our write-white fonts in ``/usr/lib/tex/qmsfonts'' since you
+say ``\emode:=qms;'' to get write-white fonts from METAFONT. Our \*(Tx
+tfm files are stored in ``/usr/lib/tex/tfm'' since both write-black and
+write-white printers can use the same tfm files. \*(Tx doesn't care about
+what type of printer you have so it only reads the files in the ``tfm''
+directory. My driver only cares about the rasters and can get the widths
+from the pk file so it only reads the files in the ``imagenfonts'' and
+``qmsfonts'' directories. Whether you have a write-black/write-white
+printer or not, set both paths to an appropriate value.
+.IP OTROFFFONT
+This is the directory where the width tables for otroff are stored.
+This is always ``/usr/lib/font'' on every system I have ever seen.
+The rasters for old troff are discussed under DITROFFFONT.
+.IP DITROFFFONT
+This is the location of the ditroff width tables and the grandfather
+directory of the font raster files.
+Please leave it as ``/usr/lib/font/devqms''. Ditroff likes to look
+there.
+In this directory will be created two more directories: ``wbfonts'' and
+``wwfonts.'' You guessed it. These are the write-black and write-white
+troff font directories. Both otroff and ditroff share the same fonts
+so they don't have to download fonts very often if they run right after each
+other. If you have ditroff, most people never use otroff again so this is
+not usually a problem anyway, but otroff is there if you need it.
+.IP BINARIES
+Along with the filters comes a few programs that manipulate fonts and such.
+This is the location to store those programs.
+.IP DOCILEUSER
+The \*(Tx and ditroff drivers can output a file directly to the printer
+during execution so that graphics can be included into text.
+This can present a security problem since they run as root. To avoid this,
+the drivers open the tty lines to the printer and then change uid to the
+user they are processing the file for. This solves our permission problems.
+Remote users don't have a uid on this machine so they switch to the uid
+given here. Games seems docile enough.
+.RE
+.IP
+You must also change the values in a couple of scripts. In the scripts
+.I glpr
+and
+.I glpq
+in the ``src'' directory
+change the ``printers'' variable to the name of your QMS printer queues.
+The landscape versions of the queues need not be given.
+If you don't have ditroff, you need to change the last line
+of the ``qtroff.backup'' script from ``otroff'' to ``troff''.
+.IP 9.
+If you have ditroff, there is a program called ``makedev'' distributed with
+it. This program takes a human readable DESC file and creates the ``DESC.out''
+binary file that ditroff reads. Put this in your path now if you have it.
+Some systems have an ``/etc/makedev'' so you will want to put this program
+in your path before the system makedev.
+If you are using the C shell, you may have to type ``rehash''.
+.IP 10.
+Type ``make configure install'' as root in the home directory.
+Stand back. This installs
+everything. (At TRW, we use the ``Makefile.TRW'' makefile, since we have
+added extensive accounting for badge numbers, cost centers, charge numbers
+and session ids. We had to modify our kernel to handle all these bizarre
+elements so you should never have a need to use this Makefile.)
+.IP 11.
+A configuration file is used by the software for each printer
+queue. It is in \fIprofile\fP(5) format and should reside in the spooling
+directory of the printer (usually /usr/spool/*)
+in the file ``configuration''.
+If you have not made two directories for each printer, do so now.
+Make a portrait and landscape directory with owner root, group daemon
+and mode 775.
+You will need a
+configuration file in each spooling directory.
+Our configuration file looks like
+.ID
+.ft CW
+{
+ readline /dev/ttyi54
+ portraitfont 1204
+ portraitpitch 12
+ landscapefont 1217
+ landscapepitch 14
+ model QMS1200
+ queuename grumpy
+ class1 2 30
+ class2 2 11
+ class3 2
+ class4
+}
+.DE
+.ft R
+The stanza does not need a marker. The ``readline'' value is the tty
+number of the line the software should read from (the tty line hooked
+to the debugger port). The ``portraitfont'' and ``landscapefont'' are the
+ROM fonts to use in portrait and landscape mode when acting as a line
+printer. The pitch values are the number of characters per inch in
+these fonts. It can be a real number or an integer. This needs to be
+set or a backspace-underline sequence won't work. The model is the
+model of the QMS printer. It should be ``QMS800'', ``QMS1200'', ``QMS1500'',
+or ``QMS2400''.
+Since the QMS 800 and QMS 1500 lasers scan
+the page in a direction perpendicular to
+the QMS 1200 and QMS 2400, they download fonts differently and the
+software needs to know which way to download fonts. The ``queuename'' is
+the name of the queue this configuration file is for.
+The class values are
+printer configuration options to turn on. These values are
+automatically set by software so if they are not correct then they
+will be changed and you will get messages on your error file when the
+first job you print runs. As previously mentioned, the class1 options
+are ignored because they cannot be set with software. Set
+the class 1 options as in
+step 4 above.
+.IP 12.
+Set up your ``/etc/printcap''. You will need separate queue entries for
+landscape and portrait mode. Our printcap looks like
+.ft CW
+.ID
+grumpy|lp|QMS laser printer model number 2400:\e
+ :br#9600:fc#0177737:fs#040:xs#0460:xc#040000:\e
+ :mx#0:pl#66:pw#80:px#2550:py#3300:\e
+ :lp=/dev/ttyi62:\e
+ :if=/usr/local/lib/lpr/if:\e
+ :of=/usr/local/lib/lpr/of:\e
+ :gf=/usr/local/lib/lpr/gf:\e
+ :rf=/usr/local/lib/lpr/rf:\e
+ :df=/usr/local/lib/lpr/df:\e
+ :nf=/usr/local/lib/lpr/nf:\e
+ :tf=/usr/local/lib/lpr/tf:\e
+ :sd=/usr/spool/grumpy:\e
+ :af=/usr/adm/grumpyacct:
+grumpyl|QMS laser printer model number 2400 landscape:\e
+ :pl#66:pw#132:px#3300:py#2550:\e
+ :af=/usr/adm/grumpylacct:\e
+ :sd=/usr/spool/grumpyl:\e
+ :tc=grumpy:
+.DE
+.ft R
+Note the skillful use of the ``tc'' termcap entry. Accounting is fully
+implemented. Just add an ``af'' entry and accounting files will
+automatically get written (provided the accounting file is writable by
+daemon). Make sure the tty bit entries ``fs'', ``fc'', ``xs'' and ``xc''
+are set correctly and that the baud rate entry, ``br'', matches the baud
+rate that you have set on the daughter board. If you also name your
+printers after the seven dwarfs do not get more than seven printers.
+.PP
+You're done.
+The biggest problem I anticipate you having is that you cannot get flow
+control to work. There is hope. If you define the flag ``-DASCIILOAD''
+to the CFLAGS variable in the top level Makefile and re-install, the drivers
+will use only ASCII characters when downloading a font. You can then
+turn on software flow control at a small performance cost. You will also
+need to change the class 1 option from 2 and 30 to only 6 if you have a QMS
+1200, 1500
+or 2400, or turn on bit 6 on switch SWS 1 if you have a QMS 800.
+You will also need to change the ``fc'', ``fs'', ``xs'' and ``xc'' entries
+in /etc/printcap to #0177776, #001, #040460 and #00, respectively.
+.PP
+If you wish to add characters to ditroff, you will need to select an unused
+font character position and insert the METAFONT source for the new character.
+You will also need to change the file ``tfm2difont.c'' in the ``src'' directory
+and add the new character to the table contained within it.
+You can create a table of character positions using the ``testfont.tex''
+file on the \*(TX distribution tape.
+Don't fill in the space character and
+don't add characters to octal 000 or 177 in a normal (i.e., not special)
+font because these positions are occupied by the ditroff \e| and \e^
+characters.
+That is, they won't show up on the table printout because they have width
+but no bitmap!
+.PP
+Some of the additional goodies you get with the code are useful.
+There is a version of ``eqnchar'' in the ``src'' directory that is
+suitable for both otroff and ditroff.
+You will probably want to replace your system ``eqnchar.''
+Look at the libraries. You might find some
+quite useful (especially the profile library). Also, there are five
+programs in the src directory that are made and installed in the BINARIES
+directory:
+``pktoch'', ``cati'',
+``tfm2difont'',
+``tfm2ofont'' and ``dumpdesc''. Pktoch prints out a symbolic dump of a
+PK file
+just like pxtoch. Tfm2difont converts a METAFONT TFM file to a ditroff
+width table file. It is used in the Makefile in the font
+directories.
+Tfm2ofont converts a METAFONT TFM file to a C file which can be compiled and
+used as a width table for old troff.
+Dumpdesc symbolically prints out a dump of the ``DESC.out'' file.
+It's pretty worthless except for debugging.
+Cati symbolically prints out the output of old troff, just like ``dvitype''
+does for DVI files. It's pretty worthless too.
+.PP
+Any error messages output by the programs are pretty self-explanatory.
+Some of you may have trouble installing this software. Since
+it has not been tested on a lot of systems, I expect this. If you have
+trouble, please mail a message to the UUCP or ARPA address at the beginning of
+this file. You can call me, but \fBI PREFER MAIL\fP.
+Also, my phone number is subject to change at whim so you may have to do
+some hunting.
+If you find any bugs
+or things you really don't like, please tell me about them.
+Good
+luck.
diff --git a/dviware/quicspool/src/cat.c b/dviware/quicspool/src/cat.c
new file mode 100644
index 0000000000..bd3e52b8aa
--- /dev/null
+++ b/dviware/quicspool/src/cat.c
@@ -0,0 +1,560 @@
+#ifndef lint
+static char *rcs = "$Header: cat.c,v 1.1 88/01/15 13:03:09 simpson Rel $";
+#endif
+/*
+$Log: cat.c,v $
+ * Revision 1.1 88/01/15 13:03:09 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:30:40 simpson
+ * beta test
+ *
+*/
+
+/* This file contains structure for mapping between ASCII and the weird
+ * CAT otroff font positions. The CAT only contains 102 characters per
+ * font mapped into strange positions.
+ */
+
+/* This table maps from CAT otroff order of a non-special font to the position
+ * of the character in the real font.
+ */
+char RegularToAscii[128] = {
+0, /* Not used */
+'h', /* h */
+'t', /* t */
+'n', /* n */
+'m', /* m */
+'l', /* l */
+'i', /* i */
+'z', /* z */
+'s', /* s */
+'d', /* d */
+'b', /* b */
+'x', /* x */
+'f', /* f */
+'j', /* j */
+'u', /* u */
+'k', /* k */
+0, /* Not used */
+'p', /* p */
+006, /* \(em */
+';', /* ; */
+0, /* Not used */
+'a', /* a */
+005, /* \(ru */
+'c', /* c */
+'`', /* ` */
+'e', /* e */
+'\'', /* ' */
+'o', /* o */
+021, /* \(14 */
+'r', /* r */
+022, /* \(12 */
+'v', /* v */
+'-', /* - or \(hy */
+'w', /* w */
+'q', /* q */
+'/', /* / */
+'.', /* . */
+'g', /* g */
+023, /* \(34 */
+',', /* , */
+'&', /* & */
+'y', /* y */
+0, /* Not used */
+'%', /* % */
+0, /* Not used */
+'Q', /* Q */
+'T', /* T */
+'O', /* O */
+'H', /* H */
+'N', /* N */
+'M', /* M */
+'L', /* L */
+'R', /* R */
+'G', /* G */
+'I', /* I */
+'P', /* P */
+'C', /* C */
+'V', /* V */
+'E', /* E */
+'Z', /* Z */
+'D', /* D */
+'B', /* B */
+'S', /* S */
+'Y', /* Y */
+0, /* Not used */
+'F', /* F */
+'X', /* X */
+'A', /* A */
+'W', /* W */
+'J', /* J */
+'U', /* U */
+'K', /* K */
+'0', /* 0 */
+'1', /* 1 */
+'2', /* 2 */
+'3', /* 3 */
+'4', /* 4 */
+'5', /* 5 */
+'6', /* 6 */
+'7', /* 7 */
+'8', /* 8 */
+'9', /* 9 */
+'*', /* * */
+004, /* \- or \(-- */
+001, /* \(fi */
+002, /* \(fl */
+003, /* \(ff */
+020, /* \(ct */
+012, /* \(fL or \(Fl */
+011, /* \fI or \(Fi */
+'(', /* ( */
+')', /* ) */
+'[', /* [ */
+']', /* ] */
+013, /* \(de */
+014, /* \(dg */
+'=', /* = */
+017, /* \(rg */
+':', /* : */
+'+', /* + */
+0, /* Not used */
+'!', /* ! */
+007, /* \(bu */
+'?', /* ? */
+015, /* \(fm */
+'|', /* | */
+0, /* Not used */
+016, /* \(co */
+010, /* \(sq */
+'$', /* $ */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+};
+
+/* This table maps from CAT otroff order in a special font to the position
+ * of the character in the real font.
+ */
+char SpecialToAscii[128] = {
+0, /* Not used */
+'w', /* \(*q */
+'h', /* \(*h */
+'m', /* \(*n */
+'l', /* \(*m */
+'k', /* \(*l */
+'i', /* \(*i */
+'f', /* \(*z */
+'r', /* \(*s */
+'d', /* \(*d */
+'b', /* \(*b */
+'n', /* \(*c */
+'g', /* \(*y */
+'u', /* \(*f */
+'t', /* \(*u */
+'j', /* \(*k */
+0, /* Not used */
+'p', /* \(*p */
+'@', /* @ */
+'7', /* \(da */
+0, /* Not used */
+'a', /* \(*a */
+'|', /* \(or */
+'v', /* \(*x */
+'"', /* " */
+'e', /* \(*e */
+'=', /* = */
+'o', /* \(*o */
+'4', /* \(<- */
+'q', /* \(*r */
+'6', /* \(ua */
+'s', /* \(*t */
+'_', /* _ */
+'\\', /* \e */
+'W', /* \(*Q */
+007, /* \(bs */
+001, /* \(if */
+'c', /* \(*g */
+002, /* \(fl */
+003, /* \(pt */
+004, /* \(rh */
+'x', /* \(*w */
+0, /* Not used */
+'(', /* \(gr */
+0, /* Not used */
+'U', /* \(*F */
+'H', /* \(*H */
+'X', /* \(*W */
+005, /* \(cu */
+006, /* \(rn */
+014, /* \(ts */
+'K', /* \(*L */
+'-', /* \(mi */
+'C', /* \(*G */
+015, /* \(is */
+'P', /* \(*P */
+032, /* \(sb */
+033, /* \(sp */
+'2', /* \(ap */
+'y', /* \(pd */
+'D', /* \(*D */
+013, /* \(sr */
+'R', /* \(*S */
+'1', /* \(~= */
+0, /* Not used */
+'>', /* > */
+'N', /* \(*C */
+'<', /* < */
+016, /* \(sl */
+034, /* \(ca */
+'T', /* \(*U */
+035, /* \(no */
+023, /* \(rc */
+024, /* \(lt */
+017, /* \(bv */
+030, /* \(lk */
+025, /* \(lb */
+026, /* \(rt */
+031, /* \(rk */
+027, /* \(rb */
+021, /* \(rf */
+020, /* \(lf */
+022, /* \(lc */
+'*', /* \(mu */
+'/', /* \(di */
+010, /* \(+- */
+011, /* \(<= */
+012, /* \(>= */
+'0', /* \(== */
+'3', /* \(!= */
+'{', /* { */
+'}', /* } */
+'\'', /* ' */
+'`', /* \` */
+'^', /* ^ */
+'#', /* # */
+036, /* \(lh */
+037, /* \(mo */
+'~', /* ~ */
+'z', /* \(es */
+0, /* Not used */
+'Y', /* \(dd */
+'Z', /* \(br */
+'9', /* \(** */
+'[', /* \(ib */
+']', /* \(ci */
+0, /* Not used */
+'+', /* \(pl */
+'5', /* \(-> */
+'8', /* \(sc */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0, /* Not used */
+0 /* Not used */
+};
+
+/* This tables maps from the order in the otroff width output table to
+ * the font position of that character. A zero value designates not used.
+ */
+char RegularOrder[256-32] = {
+' ',
+'!',
+0, /* " */
+0, /* # */
+'$',
+'%',
+'&',
+'\'',
+'(',
+')',
+'*',
+'+',
+',',
+'-', /* hyphen */
+'.',
+'/',
+'0',
+'1',
+'2',
+'3',
+'4',
+'5',
+'6',
+'7',
+'8',
+'9',
+':',
+';',
+0, /* < */
+'=',
+0, /* > */
+'?',
+0, /* @ */
+'A',
+'B',
+'C',
+'D',
+'E',
+'F',
+'G',
+'H',
+'I',
+'J',
+'K',
+'L',
+'M',
+'N',
+'O',
+'P',
+'Q',
+'R',
+'S',
+'T',
+'U',
+'V',
+'W',
+'X',
+'Y',
+'Z',
+'[',
+0, /* \ */
+']',
+0, /* ^ */
+0, /* _ */
+'`',
+'a',
+'b',
+'c',
+'d',
+'e',
+'f',
+'g',
+'h',
+'i',
+'j',
+'k',
+'l',
+'m',
+'n',
+'o',
+'p',
+'q',
+'r',
+'s',
+'t',
+'u',
+'v',
+'w',
+'x',
+'y',
+'z',
+0, /* { */
+'|',
+0, /* } */
+0, /* ~ */
+0, /* narrow space */
+055, /* hyphen */
+007, /* bullet */
+010, /* square */
+006, /* 3/4 em */
+005, /* rule */
+021, /* 1/4 */
+022, /* 1/2 */
+023, /* 3/4 */
+004, /* minus */
+001, /* fi */
+002, /* fl */
+003, /* ff */
+011, /* ffi */
+012, /* ffl */
+013, /* degree */
+014, /* dagger */
+0, /* section */
+015, /* foot mark */
+0, /* ' */
+0, /* ` */
+0, /* _ */
+0,
+0, /* half narrow space */
+0,
+0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,
+0,0,0,0,0,
+017, /* registered */
+016, /* copyright */
+0,
+020 /* cent */
+};
+
+/* Just like RegularOrder, but for the special font */
+char SpecialOrder[256-32] = {
+0,0,
+'"',
+'#',
+0,0,0,0,
+0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,
+0,0,0,0,
+'<',
+0,
+'>',
+0,
+'@',
+0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,
+0,0,0,0,
+'\\',
+0,
+'^',
+'_',
+0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,
+0,0,0,
+'{',
+0,
+'}',
+'~',
+0,
+0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,
+070, /* section */
+0,
+'\'',
+'`',
+'_',
+016, /* slash (longer) */
+0,
+0,
+0141, /* alpha */
+0142, /* beta */
+0143, /* gamma */
+0144, /* delta */
+0145, /* epsilon */
+0146, /* zeta */
+0147, /* eta */
+0150, /* theta */
+0151, /* iota */
+0152, /* kappa */
+0153, /* lambda */
+0154, /* mu */
+0155, /* nu */
+0156, /* xi */
+0157, /* omicron */
+0160, /* pi */
+0161, /* rho */
+0162, /* sigma */
+0163, /* tau */
+0164, /* upsilon */
+0165, /* phi */
+0166, /* chi */
+0167, /* psi */
+0170, /* omega */
+0103, /* Gamma */
+0104, /* Delta */
+0110, /* Theta */
+0113, /* Lambda */
+0116, /* Xi */
+0120, /* Pi */
+0122, /* Sigma */
+0,
+0124, /* Upsilon */
+0125, /* Phi */
+0127, /* Psi */
+0130, /* Omega */
+013, /* square root */
+014, /* terminal sigma */
+006, /* root extender */
+012, /* >= */
+011, /* <= */
+060, /* identically equal */
+055, /* minus */
+061, /* approximately = */
+062, /* approximates */
+063, /* not equal */
+065, /* right arrow */
+064, /* left arrow */
+066, /* up arrow */
+067, /* down arrow */
+'=',
+052, /* multiply */
+057, /* divide */
+010, /* plus minus */
+005, /* cup (union) */
+034, /* cap (intersection) */
+032, /* subset of */
+033, /* superset of */
+0133, /* improper subset */
+002, /* improper superset */
+001, /* infinity */
+0171, /* partial derivative */
+050, /* gradient */
+035, /* not */
+015, /* integral sign */
+003, /* proportional to */
+0172, /* empty set */
+037, /* member of */
+'+',
+0,
+0,
+0, /* box vertical rule */
+0,
+0131, /* double dagger */
+004, /* right hand */
+036, /* left hand */
+071, /* math * */
+007, /* bell system sign */
+'|', /* or */
+0135, /* circle */
+024, /* left top (of big curly) */
+025, /* left bottom */
+026, /* right top */
+027, /* right bottom */
+022, /* left center of big curly bracket */
+023, /* right center of big curly bracket */
+017, /* bold vertical */
+020, /* left floor */
+021, /* right floor */
+022, /* left ceiling */
+023 /* right ceiling */
+};
+
+
diff --git a/dviware/quicspool/src/cati.c b/dviware/quicspool/src/cati.c
new file mode 100644
index 0000000000..e34ad05ad3
--- /dev/null
+++ b/dviware/quicspool/src/cati.c
@@ -0,0 +1,709 @@
+#ifndef lint
+static char *rcs = "$Header: cati.c,v 1.1 88/01/15 13:03:12 simpson Rel $";
+#endif
+/*
+$Log: cati.c,v $
+ * Revision 1.1 88/01/15 13:03:12 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:30:41 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+/* mask for high order 4 bits of byte */
+#define CAT_HIGH_NIBBLE 0xf0
+#define CAT_MAX_BYTE 0xff
+
+#define CAT_ESCAPE_CODE 0x80
+#define CAT_ESCAPE_MASK 0x7f
+#define CAT_MAX_ESCAPE 0x7f
+/* nonzero if escape command and zero otherwise */
+#define CAT_IS_ESCAPE(x) (((x) & (CAT_HIGH_NIBBLE << 3)) == CAT_ESCAPE_CODE)
+/* magnitude of escape */
+#define CAT_ESCAPE(x) (~(x) & CAT_ESCAPE_MASK)
+#define CAT_ENCODE_ESCAPE(n) (CAT_ESCAPE_CODE | (~(n) & CAT_ESCAPE_MASK))
+
+#define CAT_LEAD_CODE 0x60
+#define CAT_LEAD_MASK 0x1f
+#define CAT_MAX_LEAD 0x1f
+/* nonzero if leading command and zero otherwise */
+#define CAT_IS_LEADING(x) (((x) & (CAT_HIGH_NIBBLE << 1)) == CAT_LEAD_CODE)
+/* magnitude of leading */
+#define CAT_LEAD(x) (~(x) & CAT_MAX_LEAD)
+#define CAT_ENCODE_LEAD(n) (CAT_LEAD_CODE | (~(n) & CAT_LEAD_MASK))
+
+#define CAT_SIZE_CHANGE_CODE 0x50
+/* nonzero if point size change command and zero otherwise */
+#define CAT_IS_SIZE_CHANGE(x) (((x) & CAT_HIGH_NIBBLE) == CAT_SIZE_CHANGE_CODE)
+
+/* translates from the weird CAT point size change codes into something sane */
+#define CAT_SIZE_CHANGE(x) \
+ ((x) == 0x50 ? 7 : \
+ (x) == 0x51 ? 8 : \
+ (x) == 0x52 ? 10 : \
+ (x) == 0x53 ? 11 : \
+ (x) == 0x54 ? 12 : \
+ (x) == 0x55 ? 14 : \
+ (x) == 0x56 ? 18 : \
+ (x) == 0x57 ? 9 : \
+ (x) == 0x58 ? 6 : \
+ (x) == 0x59 ? 16 : \
+ (x) == 0x5a ? 20 : \
+ (x) == 0x5b ? 22 : \
+ (x) == 0x5c ? 24 : \
+ (x) == 0x5d ? 28 : \
+ (x) == 0x5e ? 36 : 0)
+
+/* translates from sane point sizes into the weird CAT encodings */
+#define CAT_ENCODE_SIZE(x) \
+ ((x) == 6 ? 0x58 : \
+ (x) == 7 ? 0x50 : \
+ (x) == 8 ? 0x51 : \
+ (x) == 9 ? 0x57 : \
+ (x) == 10 ? 0x52 : \
+ (x) == 11 ? 0x53 : \
+ (x) == 12 ? 0x54 : \
+ (x) == 14 ? 0x55 : \
+ (x) == 16 ? 0x59 : \
+ (x) == 18 ? 0x56 : \
+ (x) == 20 ? 0x5a : \
+ (x) == 22 ? 0x5b : \
+ (x) == 24 ? 0x5c : \
+ (x) == 28 ? 0x5d : \
+ (x) == 36 ? 0x5e : 0)
+
+#define CAT_FLASH_CODE 0x00
+#define CAT_FLASH_MASK 0x3f
+#define CAT_MAX_FLASH 0x3f
+/* nonzero if printable character and zero otherwise */
+#define CAT_IS_FLASH(x) (((x) & (CAT_HIGH_NIBBLE << 2)) == CAT_FLASH_CODE)
+#define CAT_FLASH(x) ((x) & CAT_MAX_FLASH)
+#define CAT_ENCODE_FLASH(n) (CAT_FLASH_CODE | ((n) & CAT_FLASH_MASK))
+
+#define CAT_CONTROL_CODE 0x40
+/* nonzero if control command and zero otherwise */
+#define CAT_IS_CONTROL(x) (((x) & CAT_HIGH_NIBBLE) == CAT_CONTROL_CODE)
+
+/* CAT-8 control commands */
+#define CAT_INITIALIZE 0x40
+#define CAT_LOWER_RAIL 0x41
+#define CAT_UPPER_RAIL 0x42
+#define CAT_UPPER_MAGAZINE 0x43
+#define CAT_LOWER_MAGAZINE 0x44
+#define CAT_LOWER_FONT 0x45
+#define CAT_UPPER_FONT 0x46
+#define CAT_ESCAPE_FORWARD 0x47
+#define CAT_ESCAPE_BACKWARD 0x48
+#define CAT_STOP 0x49
+#define CAT_LEAD_FORWARD 0x4a
+#define CAT_LEAD_BACKWARD 0x4c
+#define CAT_TILT_UP 0x4e
+#define CAT_TILT_DOWN 0x4f
+#define CAT_NOOP 0x00
+/* trapdoor for CAT extensions */
+#define CAT_EXTENSION 0x4b
+
+/* CAT_BIG_LEAD means take the next byte * 64 to obtain leading */
+#define CAT_BIG_LEAD 0x01
+#define CAT_BIG_LEAD_MULTIPLIER 64
+#define CAT_MIN_BIG_LEAD (CAT_BIG_LEAD_MULTIPLIER * 0x01)
+#define CAT_MAX_BIG_LEAD (CAT_BIG_LEAD_MULTIPLIER * 0xff)
+
+/* CAT_BIG_ESCAPE means take the next byte * 128 to obtain escape */
+#define CAT_BIG_ESCAPE 0x02
+#define CAT_BIG_ESCAPE_MULTIPLIER 128
+#define CAT_MIN_BIG_ESCAPE (CAT_BIG_ESCAPE_MULTIPLIER * 0x01)
+#define CAT_MAX_BIG_ESCAPE (CAT_BIG_ESCAPE_MULTIPLIER * 0xff)
+
+/*
+ * CAT_FORMFEED means advance to next page resetting current row
+ * and column to <0,0>.
+ */
+#define CAT_FORMFEED 0x03
+
+/*
+ * Returns nonzero if a single point size and zero otherwise.
+ * The parameter is the `sane' point size and NOT the weird CAT encoding.
+ */
+#define CAT_IS_SINGLE(p) ((6 <= (p) && (p) <= 14) || (p) == 18)
+
+/*
+ * Returns nonzero is a double point size and zero otherwise.
+ * The parmeter is the `sane' point size and NOT the weird CAT encoding.
+ */
+#define CAT_IS_DOUBLE(p) ((p) == 16 || (p) >= 20)
+
+/*
+ * Returns nonzero if the old to new point size transition is a
+ * single to double transition and zero otherwise.
+ * The parameters are the `sane' point sizes NOT the weird CAT encodings.
+ */
+#define CAT_IS_SINGLE_TO_DOUBLE(old, new) \
+ (CAT_IS_SINGLE(old) && CAT_IS_DOUBLE(new))
+
+/*
+ * Returns nonzero if the old to new point size transition is a
+ * double to single transition and zero otherwise.
+ * The parameters are the `sane' point sizes NOT the weird CAT encodings.
+ */
+#define CAT_IS_DOUBLE_TO_SINGLE(old, new) \
+ (CAT_IS_DOUBLE(old) && CAT_IS_SINGLE(new))
+
+typedef struct CAT {
+ char escape_where; /* BACKWARD or FORWARD */
+ char lead_where; /* BACKWARD or FORWARD */
+ char font; /* bit 0 => tilt, bit 1 => rail, bit 2 => magazine */
+ char font_half; /* LOWER or UPPER */
+ char point_size; /* current point size */
+} CAT;
+
+#define CAT_FORWARD 0
+#define CAT_BACKWARD 1
+#define CAT_UPPER 0
+#define CAT_LOWER 1
+
+/* vertical resolution per inch */
+#define CAT_VERTICAL_UNITS 144.0
+/* horizontal resolution per inch */
+#define CAT_HORIZONTAL_UNITS 432.0
+
+/* compensatory escape for single/double point size transitions */
+#define CAT_LENSE_COMPENSATION 55
+
+#define CAT_TILT 01
+#define CAT_RAIL 02
+#define CAT_MAGAZINE 04
+
+/* default troff and scribe font mountings for CAT-8 */
+#define CAT_ROMAN_FONT 0
+#define CAT_ITALIC_FONT 2
+#define CAT_BOLD_FONT 4
+#define CAT_SPECIAL_FONT 6
+
+/* the maximum number of characters on a filmstrip */
+#define CAT_MAX_FONT_INDEX 108
+
+
+FILE *freopen();
+
+typedef struct STATE {
+ CAT cat;
+ long escape; /* temporary escape accumulator */
+ long forward_escape; /* total forward escape to date */
+ long backward_escape; /* total backward escape to date */
+ long lead; /* temporary lead accumulator */
+ long forward_lead; /* total forward lead to date */
+ long backward_lead; /* total backward lead to date */
+ long row; /* current row */
+ long column; /* current column */
+} STATE;
+
+char *regular[128];
+char *special[128];
+char *Whoami;
+
+main (argc, argv)
+int argc;
+char *argv[];
+{
+ int lead_only_flag = 0;
+ int verbose_flag = 0;
+ STATE s;
+ int i;
+
+ Whoami = argv[0];
+ for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++)
+ switch (argv[0][1]) {
+ case 'l':
+ lead_only_flag++;
+ continue;
+
+ case 'v':
+ verbose_flag++;
+ continue;
+
+ default:
+ fprintf(stderr, "%s: unknown option %s\n", Whoami, argv[0]);
+ exit(1);
+ }
+
+ if (argc > 0)
+ if (freopen(argv[0], "r", stdin) == NULL) {
+ fprintf(stderr, "%s: cannot open %s\n", Whoami, argv[0]);
+ exit(1);
+ }
+
+ s.escape = s.forward_escape = s.backward_escape = 0;
+ s.lead = s.forward_lead = s.backward_lead = 0;
+ s.row = s.column = 0;
+ while ((i = getchar()) != EOF)
+ interpret(i, &s, !lead_only_flag, verbose_flag);
+ printf("Total lead %d\n", s.forward_lead + s.backward_lead);
+ exit(0);
+}
+
+interpret (c, s, noisy, verbose)
+int c;
+STATE *s;
+int noisy;
+int verbose;
+{
+ int point_size;
+ int index; /* temporary for computing filmstrip index */
+ int lead;
+ int escape;
+
+ if (c == 0) {
+ if (noisy)
+ printf("No-op\n");
+ return; /* ascii null is a no-op for the CAT */
+ }
+
+ if (CAT_IS_ESCAPE(c)) {
+ s->escape += CAT_ESCAPE(c);
+ if (noisy & verbose)
+ printf("%c %d\n", s->cat.escape_where == CAT_FORWARD ? '>' : '<', CAT_ESCAPE(c));
+ return;
+ }
+
+ if (s->escape) {
+ if (s->cat.escape_where == CAT_FORWARD) {
+ s->forward_escape += s->escape;
+ s->column += s->escape;
+ if (noisy)
+ printf("> %d %d %d %d\n",
+ s->escape,
+ s->forward_escape,
+ s->backward_escape,
+ s->forward_escape + s->backward_escape);
+ } else {
+ s->backward_escape += s->escape;
+ s->column -= s->escape;
+ if (noisy)
+ printf("< %d %d %d %d\n",
+ s->escape,
+ s->forward_escape,
+ s->backward_escape,
+ s->forward_escape + s->backward_escape);
+ }
+ s->escape = 0;
+ }
+
+ if (CAT_IS_LEADING(c)) {
+ s->lead += CAT_LEAD(c);
+ if (noisy & verbose)
+ printf("%c %d\n", s->cat.lead_where == CAT_FORWARD ? '+' : '-', CAT_LEAD(c));
+ return;
+ }
+
+ if (s->lead) {
+ if (s->cat.lead_where == CAT_FORWARD) {
+ s->forward_lead += s->lead;
+ s->row += s->lead;
+ if (noisy)
+ printf("+ %d %d %d %d\n",
+ s->lead,
+ s->forward_lead,
+ s->backward_lead,
+ s->forward_lead + s->backward_lead);
+ } else {
+ s->backward_lead += s->lead;
+ s->row -= s->lead;
+ if (noisy)
+ printf("- %d %d %d %d\n",
+ s->lead,
+ s->forward_lead,
+ s->backward_lead,
+ s->forward_lead + s->backward_lead);
+ }
+ s->lead = 0;
+ }
+
+ if (CAT_IS_SIZE_CHANGE(c)) {
+ point_size = CAT_SIZE_CHANGE(c);
+ if (noisy) {
+ printf("Size %d", point_size);
+ if (CAT_IS_SINGLE_TO_DOUBLE(s->cat.point_size, point_size))
+ printf(" (double)");
+ else if (CAT_IS_DOUBLE_TO_SINGLE(s->cat.point_size, point_size))
+ printf(" (single)");
+ putchar('\n');
+ }
+ s->cat.point_size = point_size;
+ return;
+ }
+
+ if (CAT_IS_FLASH(c)) {
+ c = CAT_FLASH(c);
+ if (noisy) {
+ index = c + (s->cat.font_half == CAT_LOWER ? 0 : 63);
+ if (index > CAT_MAX_FONT_INDEX) {
+ printf("Flash !!ILLEGAL!! (%d)\n", index);
+ return;
+ }
+ printf("Flash %s (font %d %d%c size %d <%d,%d>)\n",
+ s->cat.font == CAT_SPECIAL_FONT ? special[index] : regular[index],
+ s->cat.font + 1,
+ c,
+ s->cat.font_half == CAT_LOWER ? 'L' : 'U',
+ s->cat.point_size,
+ s->row,
+ s->column);
+ }
+ return;
+ }
+
+ switch (c) {
+
+ case CAT_INITIALIZE:
+ s->cat.escape_where = s->cat.lead_where = CAT_FORWARD;
+ s->cat.font = 0; /* tilt up, lower rail and lower magazine */
+ s->cat.font_half = CAT_LOWER;
+ s->column = 0;
+ if (noisy)
+ printf("Initialize\n");
+ return;
+
+ case CAT_LOWER_RAIL:
+ s->cat.font &= ~CAT_RAIL;
+ if (noisy)
+ printf("Lower rail (font %d)\n", s->cat.font + 1);
+ return;
+
+ case CAT_UPPER_RAIL:
+ s->cat.font |= CAT_RAIL;
+ if (noisy)
+ printf("Upper rail (font %d)\n", s->cat.font + 1);
+ return;
+
+ case CAT_UPPER_MAGAZINE:
+ s->cat.font |= CAT_MAGAZINE;
+ if (noisy)
+ printf("Upper magazine (font %d)\n", s->cat.font + 1);
+ return;
+
+ case CAT_LOWER_MAGAZINE:
+ s->cat.font &= ~CAT_MAGAZINE;
+ if (noisy)
+ printf("Lower magazine (font %d)\n", s->cat.font + 1);
+ return;
+
+ case CAT_LOWER_FONT:
+ s->cat.font_half = CAT_LOWER;
+ if (noisy)
+ printf("Font half lower\n");
+ return;
+
+ case CAT_UPPER_FONT:
+ s->cat.font_half = CAT_UPPER;
+ if (noisy)
+ printf("Font half upper\n");
+ return;
+
+ case CAT_ESCAPE_FORWARD:
+ s->cat.escape_where = CAT_FORWARD;
+ if (noisy)
+ printf("> mode, %d %d %d\n",
+ s->forward_escape,
+ s->backward_escape,
+ s->forward_escape + s->backward_escape);
+ return;
+
+ case CAT_ESCAPE_BACKWARD:
+ s->cat.escape_where = CAT_BACKWARD;
+ if (noisy)
+ printf("< mode %d %d %d\n",
+ s->forward_escape,
+ s->backward_escape,
+ s->forward_escape + s->backward_escape);
+ return;
+
+ case CAT_STOP:
+ if (noisy)
+ printf("STOP\n");
+ return;
+
+ case CAT_LEAD_FORWARD:
+ s->cat.lead_where = CAT_FORWARD;
+ if (noisy)
+ printf("+ mode %d %d %d\n",
+ s->forward_lead,
+ s->backward_lead,
+ s->forward_lead + s->backward_lead);
+ return;
+
+ case CAT_LEAD_BACKWARD:
+ s->cat.lead_where = CAT_BACKWARD;
+ if (noisy)
+ printf("- mode %d %d %d\n",
+ s->forward_lead,
+ s->backward_lead,
+ s->forward_lead + s->backward_lead);
+ return;
+
+ case CAT_EXTENSION:
+ switch (getchar()) {
+ case CAT_BIG_LEAD:
+ lead = getchar() * CAT_BIG_LEAD_MULTIPLIER;
+ if (noisy & verbose)
+ printf("%s %d\n", s->cat.lead_where == CAT_FORWARD ? "++" : "--", lead);
+ s->lead += lead;
+ return;
+
+ case CAT_BIG_ESCAPE:
+ escape = getchar() * CAT_BIG_ESCAPE_MULTIPLIER;
+ if (noisy & verbose)
+ printf("%s %d\n", s->cat.escape_where == CAT_FORWARD ? ">>" : "<<", escape);
+ s->escape += escape;
+ return;
+
+ case CAT_FORMFEED:
+ s->row = s->column = 0;
+ if (noisy)
+ printf("Formfeed\n");
+ return;
+
+ default:
+ if (noisy)
+ printf("Undefined extension\n");
+ return;
+ }
+
+ case CAT_TILT_UP:
+ s->cat.font &= ~CAT_TILT;
+ if (noisy)
+ printf("Tilt up (font %d)\n", s->cat.font + 1);
+ return;
+
+ case CAT_TILT_DOWN:
+ s->cat.font |= CAT_TILT;
+ if (noisy)
+ printf("Tilt down (font %d)\n", s->cat.font + 1);
+ return;
+ }
+}
+
+char *regular[128] = {
+ "", /* garbage slot */
+ "h", /* h */
+ "t", /* t */
+ "n", /* n */
+ "m", /* m */
+ "l", /* l */
+ "i", /* i */
+ "z", /* z */
+ "s", /* s */
+ "d", /* d */
+ "b", /* b */
+ "x", /* x */
+ "f", /* f */
+ "j", /* j */
+ "u", /* u */
+ "k", /* k */
+ "-blank-", /* blank */
+ "p", /* p */
+ "-", /* _ 3/4 em dash */
+ ";", /* ; */
+ "-blank-", /* blank */
+ "a", /* a */
+ "_", /* rule */
+ "c", /* c */
+ "`", /* ` open */
+ "e", /* e */
+ "'", /* ' close */
+ "o", /* o */
+ "-1/4-", /* 1/4 */
+ "r", /* r */
+ "-1/2-", /* 1/2 */
+ "v", /* v */
+ "-", /* - hyphen */
+ "w", /* w */
+ "q", /* q */
+ "/", /* / */
+ ".", /* . */
+ "g", /* g */
+ "-3/4-", /* 3/4 */
+ ",", /* , */
+ "&", /* & */
+ "y", /* y */
+ "-blank-", /* blank */
+ "%", /* % */
+ "-blank-", /* blank */
+ "Q", /* Q */
+ "T", /* T */
+ "O", /* O */
+ "H", /* H */
+ "N", /* N */
+ "M", /* M */
+ "L", /* L */
+ "R", /* R */
+ "G", /* G */
+ "I", /* I */
+ "P", /* P */
+ "C", /* C */
+ "V", /* V */
+ "E", /* E */
+ "Z", /* Z */
+ "D", /* D */
+ "B", /* B */
+ "S", /* S */
+ "Y", /* Y */
+ "F", /* F */
+ "X", /* X */
+ "A", /* A */
+ "W", /* W */
+ "J", /* J */
+ "U", /* U */
+ "K", /* K */
+ "0", /* 0 */
+ "1", /* 1 */
+ "2", /* 2 */
+ "3", /* 3 */
+ "4", /* 4 */
+ "5", /* 5 */
+ "6", /* 6 */
+ "7", /* 7 */
+ "8", /* 8 */
+ "9", /* 9 */
+ "*", /* * */
+ "-", /* minus */
+ "-fi-", /* fi */
+ "-fl-", /* fl */
+ "-ff-", /* ff */
+ "-cent mark-", /* cent mark */
+ "-ffl-", /* ffl */
+ "-ffi-", /* ffi */
+ "(", /* ( */
+ ")", /* ) */
+ "[", /* [ */
+ "]", /* ] */
+ "-degree-", /* degree */
+ "-dagger-", /* dagger */
+ "=", /* = */
+ "-registered-", /* registered */
+ ":", /* : */
+ "+", /* + */
+ "-blank-", /* blank */
+ "!", /* ! */
+ "-bullet-", /* bullet */
+ "?", /* ? */
+ "'", /* foot mark */
+ "|", /* | */
+ "-blank-", /* blank */
+ "-copyright-", /* copyright */
+ "-square-", /* square */
+ "$" /* $ */
+};
+
+char *special[128] = {
+ "", /* garbage slot */
+ "-psi-", /* psi */
+ "-theta-", /* theta */
+ "-nu-", /* nu */
+ "-mu-", /* mu */
+ "-lambda-", /* lambda */
+ "-iota-", /* iota */
+ "-zeta-", /* zeta */
+ "-sigma-", /* sigma */
+ "-delta-", /* delta */
+ "-beta-", /* beta */
+ "-xi-", /* xi */
+ "-eta-", /* eta */
+ "-phi", /* phi */
+ "-upsilon-", /* upsilon */
+ "-kappa-", /* kappa */
+ "-blank-", /* blank */
+ "-pi-", /* pi */
+ "@", /* at sign @ */
+ "-down arrow-", /* down arrow */
+ "-blank-", /* blank */
+ "-alpha-", /* alpha */
+ "|", /* or */
+ "-chi-", /* chi */
+ "\"", /* " */
+ "-epsilon-", /* epsilon */
+ "=", /* equals */
+ "-omicron-", /* omicron */
+ "-left arrow-", /* left arrow */
+ "-rho-", /* rho */
+ "-up arrow-", /* up arrow */
+ "-tau-", /* tau */
+ "_", /* underrule */
+ "\\", /* \ */
+ "-Psi-", /* Psi */
+ "-bell system sign-", /* bell system sign */
+ "-infinity-", /* infinity */
+ "-gamma-", /* gamma */
+ "-improper subset-", /* improper superset */
+ "-proportional to-", /* proportional to */
+ "-right hand-", /* right hand */
+ "-omega-", /* omega */
+ "-blank-", /* blank */
+ "-gradient-", /* gradient */
+ "-blank-", /* blank */
+ "-Phi-", /* Phi */
+ "-Theta-", /* Theta */
+ "-Omega-", /* Omega */
+ "-union-", /* cup (union) */
+ "-root en-", /* root en */
+ "-terminal sigma-", /* terminal sigma */
+ "-Lambda-", /* Lambda */
+ "-", /* some horizontal line */
+ "-Gamma-", /* Gamma */
+ "-integral sign-", /* integral sign */
+ "-Pi-", /* Pi */
+ "-subset of-", /* subset of */
+ "-superset of-", /* superset of */
+ "-approximates-", /* approximates */
+ "-partial derivative-", /* partial derivative */
+ "-Delta-", /* Delta */
+ "-square root-", /* square root */
+ "-Sigma-", /* Sigma */
+ "-approximates-", /* approximates */
+ ">", /* > */
+ "-Xi-", /* Xi */
+ "<", /* < */
+ "/", /* slash (longer) */
+ "-cap-", /* cap (intersection) */
+ "-Upsilon-", /* Upsilon */
+ "-not-", /* not */
+ "-right ceiling-", /* right ceiling */
+ "-left curly top-", /* left top of big curly bracket */
+ "-bold vertical-", /* bold vertical */
+ "-left curly center-", /* left center of big curly bracket */
+ "-left curly bottom-", /* left bottom of big curly bracket */
+ "-right curly top-", /* right top of big curly bracket */
+ "-right curly center-", /* right center of big curly bracket */
+ "-right floor-", /* right floor */
+ "-right floor-", /* right floor */
+ "-left floor-", /* left floor */
+ "-left ceiling-", /* left ceiling */
+ "-multiply-", /* multiply */
+ "-divide-", /* divide */
+ "-plus/minus-", /* plus-minus */
+ "-less than or equal-", /* <= */
+ "-greater than or equal-", /* >= */
+ "-identical-", /* identically equal */
+ "-not equal-", /* not equal */
+ "{", /* { */
+ "}", /* } */
+ "'", /* ' acute accent */
+ "`", /* ` grave accent */
+ "^", /* ^ */
+ "#", /* sharp */
+ "-left hand-", /* left hand */
+ "-member of-", /* member of */
+ "~", /* ~ */
+ "-empty set-", /* empty set */
+ "-blank-", /* blank */
+ "-double dagger-", /* double dagger */
+ "-box vertical rule-", /* box rule */
+ "*", /* telephone asterisk? */
+ "-improper subset-", /* improper subset */
+ "-circle-", /* circle */
+ "-blank-", /* blank */
+ "+", /* equation plus sign */
+ "-right arrow-", /* right arrow */
+ "-section mark-" /* section mark */
+};
diff --git a/dviware/quicspool/src/cleanup.c b/dviware/quicspool/src/cleanup.c
new file mode 100644
index 0000000000..571d902e27
--- /dev/null
+++ b/dviware/quicspool/src/cleanup.c
@@ -0,0 +1,86 @@
+#ifndef lint
+static char *rcs = "$Header: cleanup.c,v 1.1 88/01/15 13:03:17 simpson Rel $";
+#endif
+/*
+$Log: cleanup.c,v $
+ * Revision 1.1 88/01/15 13:03:17 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:30:43 simpson
+ * beta test
+ *
+*/
+
+/* Cleanup and error routines */
+
+#include <stdio.h>
+#include <local/profile.h>
+#include <local/qms.h>
+#include "constants.h"
+#include "fontnode.h"
+
+
+Boolean Accounting = FALSE;
+FILE *Accting;
+int NumPages = 0;
+char *User;
+char *Host;
+
+/* This routine is called on exit. It does some housekeeping before
+ * exiting.
+ */
+void cleanup(head, exitstatus)
+struct FontNode *head;
+int exitstatus;
+{
+ struct FontNode *p;
+ void sanestate();
+ int portfont = 1204;
+ PROFILE_VALUE *v, *getbindingvalue();
+
+ for (p = head; p; p = p->next) /* Delete user fonts */
+ if (p->qmsnumber > 30000 && (p->flags & LOADED))
+ printf("%s%d%c%s", DOWNLOAD, p->qmsnumber, p->flags & PORT ?
+ 'P' : 'L', ENDCMD);
+ if ((v = getbindingvalue("portraitfont")) && v->class == PROFILE_INTEGER)
+ portfont = v->value.i;
+ sanestate(portfont);
+ fputs(QUICOFF, stdout);
+ if (Accounting) {
+#ifdef TRW
+ FILE *f;
+ char badge[51], costcenter[51], chargenumber[51], sessionid[51];
+ char s[51], *strcpy();
+
+ if (!(f = fopen(ACCTFILE, "r")))
+ goto getout;
+ while (fgets(s, 51, f))
+ if (strlen(s) > 0) {
+ if (s[strlen(s) - 1] == '\n')
+ s[strlen(s) - 1] = '\0';
+ switch (s[0]) {
+ case 'b':
+ (void)strcpy(badge, &s[1]);
+ break;
+ case 'e':
+ (void)strcpy(costcenter, &s[1]);
+ break;
+ case 'u':
+ (void)strcpy(chargenumber, &s[1]);
+ break;
+ case 's':
+ (void)strcpy(sessionid, &s[1]);
+ break;
+ }
+ }
+ fprintf(Accting, "%s %s %s %s %d %s@%s\n", badge, costcenter,
+ chargenumber, sessionid, NumPages, User, Host);
+ (void)fclose(f);
+#else
+ fprintf(Accting, "%d %s@%s\n", NumPages, User, Host);
+#endif
+ (void)fclose(Accting);
+ }
+getout:
+ exit(exitstatus);
+}
diff --git a/dviware/quicspool/src/constants.h_backup b/dviware/quicspool/src/constants.h_backup
new file mode 100644
index 0000000000..46c855f596
--- /dev/null
+++ b/dviware/quicspool/src/constants.h_backup
@@ -0,0 +1,26 @@
+/* $Header: constants.h.backup,v 1.1 88/01/15 13:03:20 simpson Rel $ */
+/*
+$Log: constants.h.backup,v $
+Revision 1.1 88/01/15 13:03:20 simpson
+initial release
+
+Revision 0.1 87/12/11 18:30:44 simpson
+beta test
+
+*/
+
+#define FIX 1048576 /* 2^20 FIXes = 1 point */
+#define SPOINT 65536 /* 2^16 scaled points (sps) = 1 pt */
+#define RSU 10000000 /* 10000000 RSUs = 1 meter */
+#define PPI 72.27 /* Points per inch */
+#define RESOLUTION 300 /* Pixels per inch */
+#define DVIID 2
+#define DOCILEUSER "--USER--" /* Name of uid to switch to if user is from */
+ /* a remote host */
+#define PI 3.14159265358979
+#define HORCATRES 432 /* Horizontal resolution of C/A/T typesetter */
+#define VERCATRES 144 /* Vertical resolution of C/A/T typesetter */
+
+#ifdef TRW
+#define ACCTFILE ".acctinfo"
+#endif
diff --git a/dviware/quicspool/src/dev.h b/dviware/quicspool/src/dev.h
new file mode 100644
index 0000000000..423d45a3f3
--- /dev/null
+++ b/dviware/quicspool/src/dev.h
@@ -0,0 +1,49 @@
+/* $Header: dev.h,v 1.1 88/01/15 13:03:23 simpson Rel $ */
+/*
+$Log: dev.h,v $
+ * Revision 1.1 88/01/15 13:03:23 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:30:45 simpson
+ * beta test
+ *
+*/
+/* @(#)dev.h 1.1 */
+/*
+ dev.h: characteristics of a typesetter
+*/
+
+struct dev {
+ short filesize; /* number of bytes in file, */
+ /* excluding dev part */
+ short res; /* basic resolution in goobies/inch */
+ short hor; /* goobies horizontally */
+ short vert;
+ short unitwidth; /* size at which widths are given, in effect */
+ short nfonts; /* number of fonts physically available */
+ short nsizes; /* number of sizes it has */
+ short sizescale; /* scaling for fractional point sizes */
+ short paperwidth; /* max line length in units */
+ short paperlength; /* max paper length in units */
+ short nchtab; /* number of funny names in chtab */
+ short lchname; /* length of chname table */
+ short spare1; /* in case of expansion */
+ short spare2;
+};
+
+struct font { /* characteristics of a font */
+ char nwfont; /* number of width entries for this font */
+ char specfont; /* 1 == special font */
+ char ligfont; /* 1 == ligatures exist on this font */
+ char spare1; /* unused for now */
+ char namefont[10]; /* name of this font (e.g., "R" */
+ char intname[10]; /* internal name (=number) on device, in ascii */
+};
+
+/* ligatures, ORed into ligfont */
+
+#define LFF 01
+#define LFI 02
+#define LFL 04
+#define LFFI 010
+#define LFFL 020
diff --git a/dviware/quicspool/src/df.c_backup b/dviware/quicspool/src/df.c_backup
new file mode 100644
index 0000000000..1ef9a3ea8a
--- /dev/null
+++ b/dviware/quicspool/src/df.c_backup
@@ -0,0 +1,1164 @@
+/* TeX driver */
+/*
+$Log: df.c.backup,v $
+Revision 1.2 88/02/03 08:52:23 simpson
+added tpic support
+
+Revision 1.1 88/01/15 13:03:27 simpson
+initial release
+
+Revision 0.2 87/12/18 11:39:36 simpson
+added void for lint
+
+Revision 0.1 87/12/11 18:30:46 simpson
+beta test
+
+*/
+#ifndef lint
+static char *rcs = "$Header: df.c.backup,v 1.2 88/02/03 08:52:23 simpson Exp $";
+#endif
+#include <stdio.h>
+#include <signal.h>
+#include <assert.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/dir.h>
+#include <local/profile.h>
+#include <local/qms.h>
+#include "dvi.h"
+#include "constants.h"
+#include "fontinfo.h"
+#include "fontnode.h"
+
+/* Cast for accessing LocalInfo */
+#define LI(p) ((struct LocalInfo *)p->localinfo)
+
+struct Stack {
+ long h, v, w, x, y, z;
+};
+
+struct DviNode {
+ long dvinumber;
+ struct DviNode *next;
+};
+
+struct LocalInfo {
+ long widths[256]; /* RSUs. Font but ! file mag in account */
+ short mapsize[2][256];/* Width & height of each char bitmap */
+ int qmsheight; /* Height to give QMS printer */
+ int qmsbaseline; /* Baseline height to give QMS printer */
+ struct DviNode *dvifontnumbers; /* List of #s DVI file uses */
+ char pathname[81]; /* Full pathname in file system */
+};
+
+double ConvInches; /* RSU->inches. File mag not taken into account */
+char *Whoami; /* argv[0] */
+char Orientation = 'P'; /* P=Portrait, L=Landscape */
+char *Model; /* Model of printer being used */
+char PKName[101]; /* Only used by pkeofsocleanup() */
+char *Xxxstring; /* String found in XXX? command */
+char *Pxxxstring; /* And a pointer used by lexical analyzer */
+char PKDir[101]; /* Location of PK font files */
+int Magnification; /* Magnification file was TeXed at (x1000) */
+int MaxBlocks; /* # of free blocks w/out ram or rom fonts, ovls */
+int CurRamBlocks; /* # of blocks used by ram fonts */
+int CurRomBlocks; /* # of blocks used by rom fonts */
+int DownLoadFNum; /* Number of font currently being downloaded */
+int UserFontCount = 30001; /* User fonts start getting #s from here */
+int Origin[2]; /* Origin of a postprocessor graph in pixels */
+long Numerator, Denominator; /* From .dvi preamble */
+FILE *ReadLine; /* Debugger port tty */
+struct sigvec SigStruct;
+struct FontNode *FontList; /* List containing all fnts & their attributes */
+extern char *Host, *User;
+extern FILE *Accting;
+extern Boolean Accounting;
+extern int NumPages;
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ extern char *optarg;
+ extern int optind;
+ void qmsfntfree(), cleanup(), dvieofsoexit(), readpreamble(),
+ seteoffunction(), dvieofsocleanup(), process();
+ Boolean found, loadnametable(), setnewid();
+ int c;
+ int *intptr, *tempintptr;
+ int simplyexit(), callcleanup();
+ int romlist[41]; /* List of rom font #s */
+ char *strcpy();
+#ifdef DEBUG
+ char *malloc(), orien;
+ int i, fontno, size;
+ struct fontnode *fn;
+ FILE *f;
+#endif
+ PROFILE_VALUE *v, *getbindingvalue();
+ struct qmsram *raminfo;
+ struct qmsfnt *fntinfo;
+ struct FontNode *createfontlist();
+ struct fontnode *p;
+
+ Whoami = argv[0];
+ while ((c = getopt(argc, argv, "x:y:n:h:w:l:i:")) != EOF)
+ switch (c) {
+ case 'x':
+ if (atoi(optarg) > 2550)
+ Orientation = 'L';
+ break;
+ case 'h':
+ Host = optarg;
+ break;
+ case 'n':
+ User = optarg;
+ break;
+ case 'y':
+ case 'w':
+ case 'l':
+ case 'i':
+ break;
+ default:
+ exit(2);
+ }
+ SigStruct.sv_handler = simplyexit;
+ SigStruct.sv_mask = 0;
+ SigStruct.sv_onstack = 0;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ if (optind < argc) {
+ Accounting = TRUE;
+ if (!(Accting = fopen(argv[optind], "a"))) {
+ fprintf(stderr, "%s: cannot open accounting file %s\n", Whoami,
+ argv[optind]);
+ Accounting = FALSE;
+ }
+ }
+ if (!(v = getbindingvalue("model")) || v->class != PROFILE_STRING &&
+ v->class != PROFILE_OTHER) {
+ fprintf(stderr,
+ "%s: model binding missing or invalid in configuration file\n",
+ Whoami);
+ exit(2);
+ }
+ Model = v->value.s;
+ fputs(QUICON, stdout);
+ printf("%s^Z%s%s", CLEAROVERLAY, CLEARAOVERLAY, ENDCMD);
+ fputs(QUICOFF, stdout);
+ (void)fflush(stdout);
+ if (!(v = getbindingvalue("readline")) || v->class != PROFILE_STRING &&
+ v->class != PROFILE_OTHER) {
+ fprintf(stderr,
+ "%s: readline binding missing or invalid in configuration file\n",
+ Whoami);
+ exit(2);
+ }
+ if (!(ReadLine = fopen(v->value.s, "r"))) {
+ fprintf(stderr, "%s: could not open %s for reading\n", Whoami,
+ v->value.s);
+ exit(2);
+ }
+#ifdef DEBUG
+ raminfo = (struct qmsram *)malloc((unsigned)sizeof(struct qmsram));
+ raminfo->TR = 401;
+ raminfo->AR = 387;
+ raminfo->FR = 13;
+ raminfo->OR = 0;
+#else
+ qmsopen(fileno(stdout), fileno(ReadLine));
+ if (!(raminfo = qmsram())) {
+ fprintf(stderr, "%s: could not get printer ram info\n", Whoami);
+ exit(2);
+ }
+#endif
+ MaxBlocks = raminfo->AR + raminfo->FR;
+ /* Save 5 blocks for filling with tpic */
+ MaxBlocks -= 5;
+#ifdef DEBUG
+ fntinfo = (struct qmsfnt *)malloc((unsigned)sizeof(struct qmsfnt));
+ fntinfo->ram = fntinfo->rom = NULL;
+ for (i = 0; i < 13; i++) {
+ switch (i) {
+ case 0:
+ fontno = 521;
+ orien = 'L';
+ break;
+ case 1:
+ fontno = 522;
+ orien = 'L';
+ break;
+ case 2:
+ fontno = 523;
+ orien = 'L';
+ break;
+ case 3:
+ fontno = 524;
+ orien = 'L';
+ break;
+ case 4:
+ fontno = 1100;
+ orien = 'P';
+ break;
+ case 5:
+ fontno = 1103;
+ orien = 'P';
+ break;
+ case 6:
+ fontno = 1200;
+ orien = 'P';
+ break;
+ case 7:
+ fontno = 1204;
+ orien = 'P';
+ break;
+ case 8:
+ fontno = 1217;
+ orien = 'L';
+ case 9:
+ fontno = 7009;
+ orien = 'P';
+ break;
+ case 10:
+ fontno = 7010;
+ orien = 'P';
+ break;
+ case 11:
+ fontno = 7036;
+ orien = 'P';
+ break;
+ case 12:
+ fontno = 7037;
+ orien = 'P';
+ break;
+ }
+ fn = (struct fontnode *)malloc((unsigned)sizeof(struct fontnode));
+ fn->next = fntinfo->rom, fntinfo->rom = fn;
+ fn->orientation = orien;
+ fn->number = fontno;
+ fn->bytes = 1024; /* Rom fonts occupy one block */
+ fn->version = '0';
+ fn->class = '1';
+ }
+ /* For testing, ramfonts contains the already loaded fonts. It should
+ * consist of lines containing two numbers and a letter, the first being
+ * the font number, the second being the font size, and the third letter
+ * is an orientation. The orientation should be the character immediately
+ * after the size of the font.
+ */
+ if (f = fopen("ramfonts", "r")) { /* File is optional for testing */
+ while (fscanf(f, "%d%d%c", &fontno, &size, &orien) == 3)
+ {
+ fn = (struct fontnode *)malloc((unsigned)sizeof(struct fontnode));
+ fn->next = fntinfo->ram, fntinfo->ram = fn;
+ fn->orientation = orien;
+ fn->number = fontno;
+ fn->bytes = size;
+ fn->version = '0';
+ fn->class = '1';
+ raminfo->AR -= CEILING(size / 1024.0);
+ raminfo->FR += CEILING(size / 1024.0);
+ }
+ fclose(f);
+ }
+#else
+ if (!(fntinfo = qmsfnt())) {
+ fprintf(stderr, "%s: could not get printer font info\n", Whoami);
+ exit(2);
+ }
+#endif
+ for (CurRomBlocks = 0, p = fntinfo->rom; p; p = p->next)
+ CurRomBlocks += CEILING(p->bytes / (double)1024);
+ CurRamBlocks = raminfo->FR - CurRomBlocks;
+ /* Make an array of rom font #s */
+ for (p = fntinfo->rom, intptr = romlist; p; p = p->next) {
+ for (tempintptr = romlist, found = FALSE; tempintptr < intptr;
+ tempintptr++)
+ if (*tempintptr == p->number)
+ found = TRUE;
+ if (!found)
+ *intptr++ = p->number;
+ }
+ *intptr = 0;
+ if (EQ(Model, "QMS800"))
+ (void)strcpy(PKDir, "--PKDIR1--");
+ else
+ (void)strcpy(PKDir, "--PKDIR2--");
+ if (!loadnametable(PKDir, romlist, 1)) {
+ fprintf(stderr, "%s: could not open font directory %s\n", Whoami,
+ PKDir);
+ exit(2);
+ }
+ FontList = createfontlist(fntinfo);
+ qmsfntfree(fntinfo);
+ if (!setnewid(Host, User)) {
+ fprintf(stderr, "%s: could not change user id to %s\n", Whoami,
+ User);
+ exit(2); /* This is fatal, bud. */
+ }
+ seteoffunction(dvieofsoexit);
+ readpreamble();
+ SigStruct.sv_handler = callcleanup;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ fputs(QUICON, stdout);
+ if (Orientation == 'P')
+ fputs(PORTRAIT, stdout);
+ else
+ fputs(LANDSCAPE, stdout);
+ printf("%s%c%c", TEXTPROC, '0', '0');
+ printf("%s00000%05d", INITMARGVERT, Orientation == 'P' ? 11 * 1000 :
+ (int)(8.5 * 1000));
+ printf("%s00000%05d", INITMARGHORZ, Orientation == 'P' ? (int)(8.5 *
+ 1000) : 11 * 1000);
+ printf("%s0000", CHARSPACING);
+ fputs(FREEOFF, stdout);
+ seteoffunction(dvieofsocleanup);
+ process();
+ cleanup(FontList, SUCCEED);
+}
+
+/* Reads the info in the DVI preamble */
+void readpreamble()
+{
+ int i, k;
+ long integer();
+ unsigned long uinteger();
+
+ if (cgetchar() != PRE) {
+ fprintf(stderr, "%s: input file is not a DVI file\n", Whoami);
+ exit(2);
+ }
+ if (cgetchar() != DVIID) {
+ fprintf(stderr, "%s: wrong version of DVI file \n", Whoami);
+ exit(2);
+ }
+ Numerator = uinteger(stdin, 4);
+ Denominator = uinteger(stdin, 4);
+ Magnification = integer(stdin, 4);
+ k = cgetchar(); /* Ignore comment */
+ for (i = 0; i < k; i++)
+ (void)cgetchar();
+ ConvInches = 1 / 100000.0 / 2.54;
+ /* RSU 1m 100cm 1inch n inches */
+ /* x --------- x ----- x ------ = */
+ /* 10^7 RSUs 1m 2.54cm */
+}
+
+/* Main routine that interprets the DVI file */
+void process()
+{
+ unsigned long uinteger(), ulk, uli;
+ struct FontNode *curfontnode = NULL, *getdvifontnode(), *tempcurfontnode;
+ struct Stack *tempstack;
+ Boolean download(), makeroom(), fontselected = FALSE;
+ int ch, ldirectory, lfontname, i;
+ long dvifontnum, dvichecksum, scalefactor, designsize, curfontnum,
+ integer(), a, b;
+ char directory[256], fontname[256], *push(), *pop(), *malloc();
+ void fonttolist(), adjust(), endoflist();
+ long h, v, w, x, y, z; /* In RSUs. Mag not taken in account */
+ long realhpxl, realvpxl; /* Real h & v in printer in pixels */
+ long virthpxl, virtvpxl; /* Virtual h & v current point in */
+ /* pixels. Mag is taken in account */
+
+ for (ch = cgetchar(); ch != BOP; ch = cgetchar())
+ switch (ch) {
+ case NOP:
+ break;
+ case FNTDEF1:
+ case FNTDEF2:
+ case FNTDEF3:
+ case FNTDEF4:
+ dvifontnum = integer(stdin, ch - FNTDEF1 + 1);
+ dvichecksum = integer(stdin, 4);
+ scalefactor = integer(stdin, 4);
+ designsize = integer(stdin, 4);
+ ldirectory = cgetchar();
+ lfontname = cgetchar();
+ for (i = 0; i < ldirectory; i++)
+ directory[i] = cgetchar();
+ directory[i] = '\0';
+ for (i = 0; i < lfontname; i++)
+ fontname[i] = cgetchar();
+ fontname[i] = '\0';
+ fonttolist(dvifontnum, dvichecksum, scalefactor, designsize,
+ directory, fontname);
+ break;
+ default:
+#ifndef lint
+ assert(FALSE);
+#else
+ ;
+#endif
+ cleanup(FontList, 2);
+ }
+ while (ch == BOP) {
+ for (i = 0; i < 10; i++)
+ (void)integer(stdin, 4);
+ (void)uinteger(stdin, 4); /* Pointer to previous page */
+ virthpxl = virtvpxl = realhpxl = realvpxl = h = v = w = x = y = z = 0;
+ for (ch = cgetchar(); ch != EOP; ch = cgetchar()) {
+ virthpxl = ROUND(h*ConvInches*RESOLUTION*(Magnification/1000.0));
+ virtvpxl = ROUND(v*ConvInches*RESOLUTION*(Magnification/1000.0));
+ if (SETCHAR0 <= ch && ch < 128) {
+ /* The following statement will only be true if the first
+ * font in the dvi file was not found at any magnification.
+ * In this case, skip this character since we don't know
+ * how to increment the virtual or real pixel locations!
+ * The true coordinates will probably be reset when TeX
+ * pops the stack at the beginning of a line.
+ */
+ if (!curfontnode || !curfontnode->localinfo)
+ continue;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ if (!(curfontnode->flags & LOADED)) {
+ if (!makeroom(FontList, MaxBlocks, &CurRamBlocks,
+ CurRomBlocks, curfontnode->blocksize)) {
+ fprintf(stderr,
+ "%s: could not free %d blocks for font %s\n", Whoami,
+ curfontnode->blocksize, LI(curfontnode)->pathname);
+ goto trytocontinue1;
+ }
+ if (!download(curfontnode))
+ goto trytocontinue1;
+ realhpxl = realvpxl = 0;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ }
+ if (!fontselected) {
+ printf("%s%d%s", DEFFONT, curfontnode->qmsnumber, ENDCMD);
+ fontselected = TRUE;
+ }
+ /* SliTeX fonts have width but no bitmap. Unfortunately the
+ * QMS will not print (or download) a character with width and
+ * no bitmap so we must not print characters that are not in
+ * the font. If you do, you will get the lowest character in
+ * the font.
+ */
+trytocontinue1: if (LI(curfontnode)->mapsize[0][ch] != 0 &&
+ LI(curfontnode)->mapsize[1][ch] != 0) {
+ if (ch == '^' || ch <= 32 || ch >= 127)
+ printf("%s%02X", SPECIAL, ch);
+ else
+ (void)putchar(ch);
+ realhpxl += ROUND(LI(curfontnode)->widths[ch] *
+ (Magnification / 1000.0) * ConvInches * RESOLUTION);
+ }
+ h += LI(curfontnode)->widths[ch];
+ } else if (FNTNUM0 <= ch && ch < FNT1) {
+ curfontnum = ch - FNTNUM0;
+ if (!(tempcurfontnode = getdvifontnode(FontList,
+ curfontnum, Orientation)))
+ continue; /* Font file was not found during FNTDEF */
+ curfontnode = tempcurfontnode;
+ endoflist(&FontList, curfontnode);
+ fontselected = FALSE;
+ putchar('\r'); /* Ends the pass */
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ } else switch (ch) {
+ case SET1:
+ case SET2:
+ case SET3:
+ case SET4:
+ ch = uinteger(stdin, ch - SET1 + 1);
+ assert(0 <= ch && ch <= 255);
+ if (!curfontnode || !curfontnode->localinfo)
+ continue;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ if (!(curfontnode->flags & LOADED)) {
+ if (!makeroom(FontList, MaxBlocks, &CurRamBlocks,
+ CurRomBlocks, curfontnode->blocksize)) {
+ fprintf(stderr,
+ "%s: could not free %d blocks for font %s\n",
+ Whoami, curfontnode->blocksize,
+ LI(curfontnode)->pathname);
+ goto trytocontinue2;
+ }
+ if (!download(curfontnode))
+ goto trytocontinue2;
+ realhpxl = realvpxl = 0;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ }
+ if (!fontselected) {
+ printf("%s%d%s", DEFFONT, curfontnode->qmsnumber,
+ ENDCMD);
+ fontselected = TRUE;
+ }
+trytocontinue2: if (LI(curfontnode)->mapsize[0][ch] != 0 &&
+ LI(curfontnode)->mapsize[1][ch] != 0) {
+ if (ch == '^' || ch <= 32 || ch >= 127)
+ printf("%s%02X", SPECIAL, ch);
+ else
+ (void)putchar(ch);
+ realhpxl += ROUND(LI(curfontnode)->widths[ch] *
+ (Magnification / 1000.0) * ConvInches * RESOLUTION);
+ }
+ h += LI(curfontnode)->widths[ch];
+ break;
+ case SETRULE:
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ a = integer(stdin, 4);
+ b = integer(stdin, 4);
+ if (a > 0 && b > 0) {
+ printf("%s-%05d", JUSTIFYRELATIVE, ROUND(a /
+ (double)SPOINT / PPI * (double)Magnification));
+ printf("%s%05d%05d", LINE,
+ ROUND(b/(double)SPOINT/PPI*(double)Magnification),
+ ROUND(a/(double)SPOINT/PPI*(double)Magnification));
+ printf("%s+%05d", JUSTIFYRELATIVE, ROUND(a /
+ (double)SPOINT / PPI * (double)Magnification));
+ realhpxl += ROUND(b / (double)SPOINT / PPI *
+ RESOLUTION * (Magnification / 1000.0));
+ }
+ h += ROUND(b * (Numerator / (double)Denominator));
+ break;
+ case PUT1:
+ case PUT2:
+ case PUT3:
+ case PUT4:
+ ch = uinteger(stdin, ch - PUT1 + 1);
+ assert(0 <= ch && ch <= 255);
+ if (!curfontnode || !curfontnode->localinfo)
+ continue;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ if (!(curfontnode->flags & LOADED)) {
+ if (!makeroom(FontList, MaxBlocks, &CurRamBlocks,
+ CurRomBlocks, curfontnode->blocksize)) {
+ fprintf(stderr,
+ "%s: could not free %d blocks for font %s\n",
+ Whoami, curfontnode->blocksize,
+ LI(curfontnode)->pathname);
+ goto trytocontinue3;
+ }
+ if (!download(curfontnode))
+ goto trytocontinue3;
+ realhpxl = realvpxl = 0;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ }
+ if (!fontselected) {
+ printf("%s%d%s", DEFFONT, curfontnode->qmsnumber,
+ ENDCMD);
+ fontselected = TRUE;
+ }
+trytocontinue3: if (LI(curfontnode)->mapsize[0][ch] != 0 &&
+ LI(curfontnode)->mapsize[1][ch] != 0) {
+ if (ch == '^' || ch <= 32 || ch >= 127)
+ printf("%s%02X", SPECIAL, ch);
+ else
+ (void)putchar(ch);
+ realhpxl += ROUND(LI(curfontnode)->widths[ch] *
+ (Magnification / 1000.0) * ConvInches * RESOLUTION);
+ }
+ break;
+ case PUTRULE:
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ a = integer(stdin, 4);
+ b = integer(stdin, 4);
+ if (a > 0 && b > 0) {
+ printf("%s-%05d", JUSTIFYRELATIVE, ROUND(a /
+ (double)SPOINT / PPI * (double)Magnification));
+ printf("%s%05d%05d", LINE,
+ ROUND(b/(double)SPOINT/PPI*(double)Magnification),
+ ROUND(a/(double)SPOINT/PPI*(double)Magnification));
+ printf("%s+%05d", JUSTIFYRELATIVE, ROUND(a /
+ (double)SPOINT / PPI * (double)Magnification));
+ realhpxl += ROUND(b / (double)SPOINT / PPI *
+ RESOLUTION * (Magnification / 1000.0));
+ }
+ break;
+ case NOP:
+ break;
+ case PUSH:
+ tempstack = (struct Stack *)malloc((unsigned)sizeof(
+ struct Stack));
+ tempstack->h = h, tempstack->v = v, tempstack->w = w,
+ tempstack->x = x, tempstack->y = y, tempstack->z = z;
+ (void)push((char *)tempstack);
+ break;
+ case POP:
+ tempstack = (struct Stack *)pop();
+ assert(tempstack);
+ h = tempstack->h, v = tempstack->v, w = tempstack->w,
+ x = tempstack->x, y = tempstack->y, z = tempstack->z;
+ free((char *)tempstack);
+ break;
+ case RIGHT1:
+ case RIGHT2:
+ case RIGHT3:
+ case RIGHT4:
+ h += integer(stdin, ch - RIGHT1 + 1) * (Numerator /
+ (double)Denominator);
+ break;
+ case W0:
+horw: h += w;
+ break;
+ case W1:
+ case W2:
+ case W3:
+ case W4:
+ w = integer(stdin, ch - W1 + 1) * (Numerator /
+ (double)Denominator);
+ goto horw;
+ case X0:
+horx: h += x;
+ break;
+ case X1:
+ case X2:
+ case X3:
+ case X4:
+ x = integer(stdin, ch - X1 + 1) * (Numerator /
+ (double)Denominator);
+ goto horx;
+ case DOWN1:
+ case DOWN2:
+ case DOWN3:
+ case DOWN4:
+ v += integer(stdin, ch - DOWN1 + 1) * (Numerator /
+ (double)Denominator);
+ break;
+ case Y0:
+very: v += y;
+ break;
+ case Y1:
+ case Y2:
+ case Y3:
+ case Y4:
+ y = integer(stdin, ch - Y1 + 1) * (Numerator /
+ (double)Denominator);
+ goto very;
+ case Z0:
+verz: v += z;
+ break;
+ case Z1:
+ case Z2:
+ case Z3:
+ case Z4:
+ z = integer(stdin, ch - Z1 + 1) * (Numerator /
+ (double)Denominator);
+ goto verz;
+ case FNT1:
+ case FNT2:
+ case FNT3:
+ case FNT4:
+ curfontnum = uinteger(stdin, ch - FNT1 + 1);
+ if (!(tempcurfontnode = getdvifontnode(FontList,
+ curfontnum, Orientation)))
+ continue;
+ curfontnode = tempcurfontnode;
+ endoflist(&FontList, curfontnode);
+ fontselected = FALSE;
+ putchar('\r'); /* Ends the pass */
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ break;
+ case XXX1:
+ case XXX2:
+ case XXX3:
+ case XXX4:
+ ulk = uinteger(stdin, ch - XXX1 + 1);
+ Pxxxstring = Xxxstring = malloc((unsigned)(ulk + 1));
+ for (uli = 0; uli < ulk; uli++)
+ Xxxstring[uli] = cgetchar();
+ Xxxstring[uli] = '\0';
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ Origin[0] = virthpxl + RESOLUTION, Origin[1] = virtvpxl +
+ RESOLUTION;
+ (void)yyparse();
+ free(Xxxstring);
+ fputs(QUICON, stdout);
+ if (Orientation == 'P')
+ fputs(PORTRAIT, stdout);
+ else
+ fputs(LANDSCAPE, stdout);
+ printf("%s%c%c", TEXTPROC, '0', '0');
+ printf("%s00000%05d", INITMARGVERT, Orientation == 'P' ?
+ 11 * 1000 : (int)(8.5 * 1000));
+ printf("%s00000%05d", INITMARGHORZ, Orientation == 'P' ?
+ (int)(8.5 * 1000) : 11 * 1000);
+ printf("%s0000", CHARSPACING);
+ realhpxl = realvpxl = 0;
+ break;
+ case FNTDEF1:
+ case FNTDEF2:
+ case FNTDEF3:
+ case FNTDEF4:
+ dvifontnum = integer(stdin, ch - FNTDEF1 + 1);
+ dvichecksum = integer(stdin, 4);
+ scalefactor = integer(stdin, 4);
+ designsize = integer(stdin, 4);
+ ldirectory = cgetchar();
+ lfontname = cgetchar();
+ for (i = 0; i < ldirectory; i++)
+ directory[i] = cgetchar();
+ directory[i] = '\0';
+ for (i = 0; i < lfontname; i++)
+ fontname[i] = cgetchar();
+ fontname[i] = '\0';
+ fonttolist(dvifontnum, dvichecksum, scalefactor,
+ designsize, directory, fontname);
+ break;
+ default: /* Bad DVI command */
+#ifndef lint
+ assert(FALSE);
+#else
+ ;
+#endif
+ cleanup(FontList, 2);
+ }
+ }
+ NumPages++;
+ printf("%s", FORMFEED);
+ for (ch = cgetchar(); ch != BOP && ch != POST; ch = cgetchar())
+ switch (ch) {
+ case NOP:
+ break;
+ case FNTDEF1:
+ case FNTDEF2:
+ case FNTDEF3:
+ case FNTDEF4:
+ dvifontnum = integer(stdin, ch - FNTDEF1 + 1);
+ dvichecksum = integer(stdin, 4);
+ scalefactor = integer(stdin, 4);
+ designsize = integer(stdin, 4);
+ ldirectory = cgetchar();
+ lfontname = cgetchar();
+ for (i = 0; i < ldirectory; i++)
+ directory[i] = cgetchar();
+ directory[i] = '\0';
+ for (i = 0; i < lfontname; i++)
+ fontname[i] = cgetchar();
+ fontname[i] = '\0';
+ fonttolist(dvifontnum, dvichecksum, scalefactor,
+ designsize, directory, fontname);
+ break;
+ default:
+#ifndef lint
+ assert(FALSE);
+#else
+ ;
+#endif
+ cleanup(FontList, 2);
+ }
+ }
+ while (getchar() != EOF)
+ ;
+}
+
+
+/* Returns the full pathname of the pk file found or NULL if not found.
+ * The algorithm is as follows:
+ * Create a new path, say TEXFONTS*, which is equal to $TEXFONTS:PKDir
+ * if there is a directory name in the DVI file {
+ * look in that directory for the font at any magnification
+ * if found {
+ * select this font
+ * return it
+ * }
+ * }
+ * look in TEXFONTS* directories consecutively for font with closest
+ * magnification
+ * if no font matches, return NULL
+ */
+char *findpkfont(directory, fontname, designsize, scalefactor)
+char *directory;
+char *fontname;
+long designsize, scalefactor;
+{
+ int closestnumber = MAX_INTEGER;
+ int desiredmagnification = ROUND(RESOLUTION *
+ ((double)scalefactor / designsize) * (Magnification /
+ 1000.0));
+ int dirdsize, dirmag;
+ Boolean extractinfo();
+ static char returnvalue[101];
+ char dirfname[81], dirsfname[81], hostname[81], component[81];
+ char fontpaths[201], *strcpy(), *nextcomponent();
+ char *p, *comp, *fgetenv(), *expandtilde(), *expandhome();
+ DIR *dirp;
+ struct direct *direntry;
+
+ returnvalue[0] = '\0';
+ (void)gethostname(hostname, 80);
+ if (!EQ(hostname, Host) || !(p = fgetenv("TEXFONTS", User)))
+ (void)strcpy(fontpaths, PKDir);
+ else
+ (void)sprintf(fontpaths, "%s:%s", p, PKDir);
+ if (directory && strlen(directory) > 0) {
+ if (dirp = opendir(directory)) {
+ for (direntry = readdir(dirp); direntry; direntry =
+ readdir(dirp)) {
+ if (direntry->d_namlen < 5 || !extractinfo(direntry->d_name,
+ dirfname, dirsfname, &dirdsize, &dirmag) || !EQ(dirfname,
+ fontname))
+ continue;
+ if (ABS(dirmag - desiredmagnification) < closestnumber) {
+ closestnumber = ABS(dirmag - desiredmagnification);
+ (void)sprintf(returnvalue, "%s%s", directory,
+ direntry->d_name);
+ }
+ }
+ closedir(dirp);
+ if (strlen(returnvalue) > 0)
+ return returnvalue;
+ }
+ }
+ for (p = &fontpaths[0]; comp = nextcomponent(&p); ) {
+ (void)strcpy(component, comp);
+ (void)expandtilde(component);
+ (void)expandhome(component);
+ if (dirp = opendir(component)) {
+ for (direntry = readdir(dirp); direntry; direntry = readdir(dirp))
+ {
+ if (direntry->d_namlen < 5 || !extractinfo(direntry->d_name,
+ dirfname, dirsfname, &dirdsize, &dirmag) || !EQ(dirfname,
+ fontname))
+ continue;
+ if (ABS(dirmag - desiredmagnification) < closestnumber) {
+ closestnumber = ABS(dirmag - desiredmagnification);
+ (void)sprintf(returnvalue, "%s/%s", component,
+ direntry->d_name);
+ }
+ }
+ closedir(dirp);
+ }
+ }
+ if (strlen(returnvalue) > 0)
+ return returnvalue;
+ return NULL;
+}
+
+/* Adjusts the real current position to the virtual current position */
+void adjust(realh, realv, virth, virtv, h, v)
+long *realh, *realv;
+long virth, virtv;
+long h, v;
+{
+ if (*realh != virth + RESOLUTION) {
+ printf("%s%05d%s", TAB, ROUND(h * ConvInches * Magnification) + 1000,
+ ENDCMD); /* Add 1000 since the origin is (1in,1in) */
+ *realh = virth + RESOLUTION;
+ }
+ if (*realv != virtv + RESOLUTION) {
+ printf("%s%05d%s", JUSTIFYMARGIN, ROUND(v * ConvInches *
+ Magnification) + 1000, ENDCMD);
+ *realv = virtv + RESOLUTION;
+ }
+}
+
+/* Adds a new font to the font list. The width info, mapsize, qmsheight,
+ * qmsbaseline, pathname, blocksize and dvifontnumber in the FontNode
+ * structure and LocalInfo structure are filled in also. If the font is
+ * loaded on startup, the blocksize is left as is; otherwise, the blocksize
+ * is estimated.
+ */
+void fonttolist(fontnumber, dvichecksum, scalefactor, designsize, directory,
+fontname)
+long fontnumber;
+long dvichecksum;
+long scalefactor, designsize;
+char *directory, *fontname;
+{
+ struct DviNode *d;
+ struct FontInfo *fi, *getfontinfo();
+ struct FontNode *fn, *getfontnode();
+ char *fullfontpath, *findpkfont(), *tail();
+ void cleanup(), pkeofsocleanup(), seteoffunction(),
+ dvieofsocleanup();
+ int qmsfontnum, i;
+ Boolean found;
+
+ if (!(fullfontpath = findpkfont(directory, fontname, designsize,
+ scalefactor))) {
+ fprintf(stderr, "%s: could not find font %s anywhere\n", Whoami,
+ fontname);
+ return; /* Try to continue */
+ }
+ if (EQN(PKDir, fullfontpath, strlen(PKDir)) && fullfontpath[strlen(PKDir)]
+ == '/' && EQ(&fullfontpath[strlen(PKDir)+1], tail(fullfontpath)))
+ qmsfontnum = getnumfromtable(tail(fullfontpath));
+ else /*tail(fullfontpath) ! necessarily == fontname if exact size !found*/
+ qmsfontnum = UserFontCount++;
+ assert(qmsfontnum > 0);
+ if (!(fn = getfontnode(FontList, qmsfontnum, Orientation))) {
+ bzero((char *)(fn = (struct FontNode *)malloc((unsigned)sizeof(struct
+ FontNode))), sizeof(struct FontNode));
+ fn->next = FontList, FontList = fn;
+ }
+ if (!fn->localinfo)
+ bzero(fn->localinfo = malloc((unsigned)sizeof(struct LocalInfo)),
+ sizeof(struct LocalInfo));
+ fn->flags |= RAM;
+ if (Orientation == 'P')
+ fn->flags |= PORT;
+ fn->qmsnumber = qmsfontnum;
+ (void)strcpy(LI(fn)->pathname, fullfontpath);
+ for (d = LI(fn)->dvifontnumbers, found = FALSE; d && !found; d = d->next)
+ if (d->dvinumber == fontnumber)
+ found = TRUE;
+ if (!found) {
+ d = (struct DviNode *)malloc(sizeof(struct DviNode));
+ d->next = LI(fn)->dvifontnumbers, LI(fn)->dvifontnumbers = d;
+ d->dvinumber = fontnumber;
+ }
+ (void)strcpy(PKName, fullfontpath);
+ seteoffunction(pkeofsocleanup);
+ if (!(fi = getfontinfo(fullfontpath, (EQ(Model, "QMS800") ||
+ EQ(Model, "QMS1500")) && Orientation == 'P' || (!EQ(Model, "QMS800") &&
+ !EQ(Model, "QMS1500")) && Orientation == 'L' ? 'X' : 'Y'))) {
+ fprintf(stderr, "%s: cannot open or invalid font file %s\n", Whoami,
+ fullfontpath);
+ fn->flags |= LOADED; /* Try to continue */
+ fn->blocksize = 0;
+ return;
+ }
+ seteoffunction(dvieofsocleanup);
+ LI(fn)->qmsheight = fi->qmsheight;
+ LI(fn)->qmsbaseline = fi->qmsbaseline;
+ if (!(fn->flags & PRELOADED))
+ fn->blocksize = fi->blocksize;
+ for (i = 0; i < 256; i++) {
+ LI(fn)->widths[i] = ROUND(fi->chararray[i].tfm * ((fi->ds /
+ (double)FIX) / FIX) * (2.54 / PPI * 100000) * ((fi->hppp /
+ (double)SPOINT * PPI / RESOLUTION) / (Magnification / 1000.0)));
+ LI(fn)->mapsize[0][i] = fi->chararray[i].w;
+ LI(fn)->mapsize[1][i] = fi->chararray[i].h;
+ }
+/* fi->chararray[i].tfm is in units of FIXes/designsize. fi->hppp is in units
+ * of scaled points times pixels/point. Convert the width into RSUs with only
+ * font magnification taken into account by the following formulas:
+ *
+ * tfm designsize
+ * x ---------- = width in points
+ * FIX
+ *
+ * width 1inch 2.54cm 1m 10^7RSUs
+ * in x -------- x ------ x ----- x -------- = width in RSUs
+ * points 72.27pts 1inch 100cm 1m
+ *
+ * hppp PPI
+ * ------ x = Resolution designed for (the number before "pk" in the
+ * SPOINT file name)
+ *
+ * Multiplying the width in RSUs by the number before the "pk" in the file
+ * name yields the width in RSUs with font and file magnification taken into
+ * account. Dividing by the file magnification yields the width with only
+ * the font magnification taken into account.
+ */
+ if (dvichecksum != 0 && fi->cs != 0)
+ if (dvichecksum != fi->cs)
+ fprintf(stderr,
+ "%s: DVI checksum (O%lo) != PK checksum (O%lo) in %s\n",
+ Whoami, dvichecksum, fi->cs, LI(fn)->pathname);
+}
+
+/* Downloads a font */
+Boolean download(fn)
+struct FontNode *fn;
+{
+ struct CharInfo *ci;
+ char *tail(), *strcpy();
+ void resetpkfile(), seteoffunction(),
+ downloadpkeofsocleanup(), dvieofsocleanup();
+ int downloadinterrupt(), callcleanup();
+ int downloadtype, result, i, truebyteswide, bytestooutput,
+ row, bytes;
+
+ if (!fn || fn->flags & LOADED || !(fn->flags & RAM) || (fn->flags & PORT ?
+ 'P' : 'L') != Orientation)
+ return FALSE;
+ resetpkfile();
+ downloadtype = ((EQ(Model, "QMS800") || EQ(Model, "QMS1500")) &&
+ Orientation == 'P' || (!EQ(Model, "QMS800") && !EQ(Model, "QMS1500"))
+ && Orientation == 'L' ? 'X' : 'Y');
+ DownLoadFNum = fn->qmsnumber;
+ (void)sigblock(SIGINT); /* Temporarily block interrupts */
+ SigStruct.sv_handler = downloadinterrupt;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ (void)strcpy(PKName, LI(fn)->pathname);
+ seteoffunction(downloadpkeofsocleanup);
+ /* #defining ASCIILOAD causes ASCII characters to be used for the download
+ * sequence. Twice as many characters must be sent but it is useful for
+ * looking at the output when debugging. Also, you can actually see the
+ * bitmaps in the output. ASCII loading must be used when you can't get
+ * hardware flow control to work. Far out.
+ */
+#ifdef ASCIILOAD
+ fputs(FREEFORM, stdout);
+#else
+ fputs(EIGHTBITON, stdout);
+#endif
+ printf("%s%05d%c0%-4.4s%03d%03dT", DOWNLOAD, fn->qmsnumber, Orientation,
+ tail(LI(fn)->pathname), LI(fn)->qmsheight, LI(fn)->qmsbaseline);
+ (void)sigsetmask(sigblock(0) & ~SIGINT); /* Unblock interrupts */
+ while ((result = getnextcharinfo(LI(fn)->pathname, downloadtype, &ci)) !=
+ 1)
+ switch (result) {
+ case 2:
+ fprintf(stderr, "%s: could not open %s\n", Whoami,
+ LI(fn)->pathname);
+ return FALSE;
+ case 3:
+ fprintf(stderr, "%s: %s is not a PK file\n", Whoami,
+ LI(fn)->pathname);
+ return FALSE;
+ case 4:
+ fprintf(stderr, "%s: %s PK version is incorrect\n", Whoami,
+ LI(fn)->pathname);
+ return FALSE;
+ case 0: /* Ok. Got a bitmap */
+ if (ci->h == 0 || ci->w == 0)
+ continue;
+ putchar(',');
+ printf("%02X%03d", ci->cc, ROUND(LI(fn)->widths[ci->cc] *
+ (Magnification / 1000.0) * ConvInches * RESOLUTION));
+ if (downloadtype == 'X') {
+ printf("%03d%03d", ci->h, ci->w);
+ printf("%c%03d", LI(fn)->qmsbaseline - ci->voff >= 0 ? '+'
+ : '-', ABS(LI(fn)->qmsbaseline - ci->voff));
+ printf("%c%03d", -ci->hoff >= 0 ? '+' : '-', ABS(-ci->hoff));
+ } else {
+ printf("%03d%03d", ci->w, ci->h);
+ printf("%c%03d", -ci->hoff >= 0 ? '+' : '-', ABS(ci->hoff));
+ printf("%c%03d", (LI(fn)->qmsheight - LI(fn)->qmsbaseline) -
+ (ci->h - ci->voff) >= 0 ? '+' : '-', ABS((LI(fn)->qmsheight
+ - LI(fn)->qmsbaseline) - (ci->h - ci->voff)));
+ i = ci->w, ci->w = ci->h, ci->h = i; /* Swaparoo! */
+ }
+ truebyteswide = ci->w + 7 >> 3; /* >> divides by 8 */
+ bytestooutput = (ci->w + 15 >> 4) * 2; /* >> divides by 16 */
+#ifdef ASCIILOAD
+ for (row = 0; row < ci->h; row++) {
+#else
+ for (row = 0; row < ci->h; row++)
+#endif
+ for (bytes = 0; bytes < bytestooutput; bytes++) {
+ if (bytes == truebyteswide - 1)
+ *(ci->bitmap + row * truebyteswide + bytes) &=
+ 0xFF<<7-(ci->w+7)%8;
+ if (bytes < truebyteswide) {
+ i = *(ci->bitmap + row * truebyteswide + bytes) &
+ 0xFF;
+#ifdef ASCIILOAD
+ printf("%c%c", "0123456789ABCDEF"[i >> 4],
+ "0123456789ABCDEF"[i & 0xF]);
+#else
+ if (i == '^')
+ printf("^^");
+ else
+ (void)putchar(i);
+#endif
+ } else
+#ifdef ASCIILOAD
+ printf("00");
+#else
+ (void)putchar(0);
+#endif
+ }
+#ifdef ASCIILOAD
+ putchar('\n');
+ }
+#endif
+ break;
+ } /* End switch */
+#ifdef ASCIILOAD
+ printf("%s%s", ENDCMD, FREEOFF);
+#else
+ printf("%s%s", ENDCMD, EIGHTBITOFF);
+#endif
+ putchar('\r'); /* Ends the pass */
+ (void)sigblock(SIGINT);
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ SigStruct.sv_handler = callcleanup;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ seteoffunction(dvieofsocleanup);
+ CurRamBlocks += fn->blocksize;
+ fn->flags |= LOADED;
+ (void)sigsetmask(sigblock(0) & ~SIGINT);
+ return TRUE;
+}
+
+/* Returns a pointer to a font on the font list using the DVI number; NULL
+ * if not found.
+ */
+struct FontNode *getdvifontnode(head, dvinumber, orientation)
+struct FontNode *head;
+long dvinumber;
+int orientation;
+{
+ struct FontNode *p;
+ struct DviNode *d;
+
+ for (p = head; p; p = p->next)
+ if (p->flags & RAM && (p->flags & PORT ? 'P' : 'L') == orientation
+ && p->localinfo && LI(p)->dvifontnumbers)
+ for (d = LI(p)->dvifontnumbers; d; d = d->next)
+ if (d->dvinumber == dvinumber)
+ return p;
+ return NULL;
+}
+
+/* The following are routines called when a SIGINT is received or EOF is
+ * unexpectedly encountered when reading a file.
+ */
+simplyexit()
+{
+ exit(SUCCEED);
+}
+
+callcleanup()
+{
+ void cleanup();
+
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, SUCCEED); /* Interrupting a program is not an error */
+}
+
+void dvieofsoexit()
+{
+ fprintf(stderr, "%s: unexpected EOF when reading DVI file\n", Whoami);
+ exit(2);
+}
+
+void dvieofsocleanup()
+{
+ fprintf(stderr, "%s: unexpected EOF when reading DVI file\n", Whoami);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+}
+
+void pkeofsocleanup()
+{
+ fprintf(stderr, "%s: unexpected EOF in PK file %s\n", Whoami, PKName);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+}
+
+void downloadpkeofsocleanup()
+{
+ fputs(ENDCMD, stdout);
+#ifdef ASCIILOAD
+ fputs(FREEOFF, stdout);
+#else
+ fputs(EIGHTBITOFF, stdout);
+#endif
+ printf("%s%05d%c%s", DOWNLOAD, DownLoadFNum, Orientation, ENDCMD);
+ pkeofsocleanup();
+}
+
+downloadinterrupt()
+{
+ fputs(ENDCMD, stdout);
+#ifdef ASCIILOAD
+ fputs(FREEOFF, stdout);
+#else
+ fputs(EIGHTBITOFF, stdout);
+#endif
+ printf("%s%05d%c%s", DOWNLOAD, DownLoadFNum, Orientation, ENDCMD);
+ callcleanup();
+}
+
+
+/* Lex and Yacc routines to parse \special command string */
+#include "xxx.c"
diff --git a/dviware/quicspool/src/ditroff.backup b/dviware/quicspool/src/ditroff.backup
new file mode 100644
index 0000000000..ef044e2d99
--- /dev/null
+++ b/dviware/quicspool/src/ditroff.backup
@@ -0,0 +1,49 @@
+#! /bin/sh
+# $Header: ditroff.backup,v 1.1 88/01/15 13:03:40 simpson Rel $
+# $Log: ditroff.backup,v $
+#Revision 1.1 88/01/15 13:03:40 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 18:30:49 simpson
+#beta test
+#
+# We must give the -T flag to ditroff so it knows to look in
+# --DIFONT--. We also must parse the ditroff and lpr flags.
+troffflags=-Tqms
+lprflags=-n
+while [ $# -gt 0 ];do
+ case $1 in
+# Begin of ditroff flags
+ -o* | -n* | -m* | -i | -q | -z | -a | -T*)
+ troffflags="$troffflags $1"
+ shift
+ ;;
+# Begin of lpr flags
+ -P* | -\#* | -w* | -l | -t | -d | -g | -v | -c | -r | -h | -s | -L)
+ lprflags="$lprflags $1"
+ shift
+ ;;
+ -C | -J | -1 | -2 | -3 | -4)
+ lprflags="$lprflags $1 $2"
+ shift; shift
+ ;;
+# Troff extension flags
+ -R*)
+ troffflags="$troffflags `echo $1|sed s/-R/-r/`"
+ shift
+ ;;
+ -M)
+ lprflags="$lprflags -m"
+ shift
+ ;;
+# Any remaining flags go to troff
+ -*)
+ troffflags="$troffflags $1"
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+troff $troffflags $* | glpr $lprflags
diff --git a/dviware/quicspool/src/dumpdesc.c b/dviware/quicspool/src/dumpdesc.c
new file mode 100644
index 0000000000..4b249de919
--- /dev/null
+++ b/dviware/quicspool/src/dumpdesc.c
@@ -0,0 +1,177 @@
+#ifndef lint
+static char *rcs = "$Header: dumpdesc.c,v 1.1 88/01/15 13:03:43 simpson Rel $";
+#endif
+/*
+$Log: dumpdesc.c,v $
+ * Revision 1.1 88/01/15 13:03:43 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:30:50 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <local/standard.h>
+#include "dev.h"
+
+char EOFName[81];
+char *WhoAmI;
+char *Usage = "Usage: %s DESCfile\n";
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ extern int optind;
+ extern char *optarg;
+ int c;
+ FILE *f;
+ void dumpdescfile(), desceofsoexit(), seteoffunction();
+ char *strcpy();
+
+ WhoAmI = argv[0];
+ while ((c = getopt(argc, argv, "")) != EOF)
+ switch (c) {
+ case '?':
+badusage: fprintf(stderr, Usage, WhoAmI);
+ exit(FAIL);
+ }
+ if (optind != argc - 1)
+ goto badusage;
+ if (!(f = fopen(argv[optind], "r"))) {
+ perror(argv[optind]);
+ exit(FAIL);
+ }
+ seteoffunction(desceofsoexit);
+ (void)strcpy(EOFName, argv[optind]);
+ dumpdescfile(f);
+ (void)fclose(f);
+ exit(SUCCEED);
+}
+
+/* Symbolically dumps a DESC.out file. The parameter should be an open
+ * DESC.out file.
+ */
+void dumpdescfile(f)
+FILE *f;
+{
+ unsigned char spacewidth, widthindex;
+ struct dev devheader;
+ struct font fontheader;
+ int count, c;
+ short size, index;
+ long funnycharoffset; /* Static file offset - Before */
+ /* funnycharindextable. */
+ long fontstructoffset; /* Floating offset - Beginning of each */
+ /* font structure. */
+
+ rewind(f);
+ (void)cfread((char *)&devheader, sizeof(struct dev), 1, f);
+ printf("filesize: (%d+%d)=%d\n", sizeof(struct dev), devheader.filesize,
+ sizeof(struct dev) + devheader.filesize);
+ printf("res: %d\tmotion (hor,ver): (%d,%d)\n", devheader.res,
+ devheader.hor, devheader.vert);
+ printf("unitwidth: %d\tsizescale: %d\n", devheader.unitwidth,
+ devheader.sizescale);
+ printf("nfonts: %d\tnsizes: %d\n", devheader.nfonts, devheader.nsizes);
+ printf("paper (width,length): (%d,%d)\n", devheader.paperwidth,
+ devheader.paperlength);
+ /* Read the sizes table */
+ printf("point sizes available:\n");
+ (void)cfread((char *)&size, sizeof(short), 1, f);
+ for (count = 0; size; count++) {
+ if ((count + 1) % 20 == 0)
+ putchar('\n');
+ printf("%d, ", size);
+ (void)cfread((char *)&size, sizeof(short), 1, f);
+ }
+ if (count > 0)
+ putchar('\n');
+ /* Read the funnycharstrings */
+ printf("special character names:\n");
+ funnycharoffset = ftell(f);
+ for (count = 0; count < devheader.nchtab; count++) {
+ if ((count + 1) % 20 == 0)
+ putchar('\n');
+ (void)fseek(f, funnycharoffset + count * sizeof(short), 0);
+ (void)cfread((char *)&index, sizeof(short), 1, f);
+ (void)fseek(f, funnycharoffset + devheader.nchtab * sizeof(short) +
+ index, 0);
+ while ((c = cgetc(f)) != '\0')
+ putchar(c);
+ putchar(',');
+ }
+ if (count > 0)
+ putchar('\n');
+ (void)fseek(f, funnycharoffset + devheader.nchtab * sizeof(short) +
+ devheader.lchname, 0);
+ /* Read each individual font information */
+ fontstructoffset = ftell(f);
+ while (fread((char *)&fontheader, sizeof(struct font), 1, f) == 1) {
+ printf("\n%s font %s (internal %s)\n",
+ fontheader.specfont == 1 ? "Special" : "Regular",
+ fontheader.namefont, fontheader.intname);
+ if (fontheader.ligfont > 0) {
+ printf("ligatures: ");
+ if (fontheader.ligfont & LFI)
+ printf("fi, ");
+ if (fontheader.ligfont & LFL)
+ printf("fl, ");
+ if (fontheader.ligfont & LFF)
+ printf("ff, ");
+ if (fontheader.ligfont & LFFI)
+ printf("ffi, ");
+ if (fontheader.ligfont & LFFL)
+ printf("ffl, ");
+ printf("\n");
+ }
+ spacewidth = cgetc(f);
+ if (spacewidth > (unsigned)0)
+ printf("spacewidth: %u\n", spacewidth);
+ for (count = 0; count < 96 + devheader.nchtab; count++) {
+ /* Seek to fontindextable */
+ (void)fseek(f, fontstructoffset + sizeof(struct font) + 3 *
+ fontheader.nwfont + count, 0);
+ widthindex = cgetc(f);
+ if (widthindex == 0)
+ continue;
+ if (count < 96)
+ if (count + 32 == 0177) /* Delete */
+ printf("0177\t");
+ else
+ printf("%c\t", count + 32);
+ else {
+ /* Print out special character sequence. */
+ (void)fseek(f, funnycharoffset + (count - 96) * sizeof(short),
+ 0);
+ (void)cfread((char *)&index, sizeof(short), 1, f);
+ (void)fseek(f, funnycharoffset + devheader.nchtab *
+ sizeof(short) + index, 0);
+ while ((c = cgetc(f)) != '\0')
+ putchar(c);
+ putchar('\t');
+ }
+ /* Print out width, kerning and code info */
+ (void)fseek(f, fontstructoffset + sizeof(struct font) + widthindex,
+ 0);
+ printf("width %d\t", cgetc(f));
+ (void)fseek(f, fontstructoffset + sizeof(struct font) +
+ fontheader.nwfont + widthindex, 0);
+ printf("kerning %d\t", cgetc(f));
+ (void)fseek(f, fontstructoffset + sizeof(struct font) +
+ fontheader.nwfont * 2 + widthindex, 0);
+ printf("code %d\n", cgetc(f));
+ }
+ /* Go to next font structure */
+ (void)fseek(f, fontstructoffset + sizeof(struct font) + 3 *
+ fontheader.nwfont + 96 + devheader.nchtab, 0);
+ fontstructoffset = ftell(f);
+ }
+}
+
+void desceofsoexit()
+{
+ fprintf(stderr, "%s: unexpected eof in DESC.out file %s\n", WhoAmI,
+ EOFName);
+ exit(FAIL);
+}
diff --git a/dviware/quicspool/src/dvi.h b/dviware/quicspool/src/dvi.h
new file mode 100644
index 0000000000..899c6db066
--- /dev/null
+++ b/dviware/quicspool/src/dvi.h
@@ -0,0 +1,72 @@
+/* $Header: dvi.h,v 1.1 88/01/15 13:03:49 simpson Rel $ */
+/*
+$Log: dvi.h,v $
+ * Revision 1.1 88/01/15 13:03:49 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:30:51 simpson
+ * beta test
+ *
+*/
+#define SETCHAR0 0
+#define SET1 128
+#define SET2 129
+#define SET3 130
+#define SET4 131
+#define SETRULE 132
+#define PUT1 133
+#define PUT2 134
+#define PUT3 135
+#define PUT4 136
+#define PUTRULE 137
+#define NOP 138
+#define BOP 139
+#define EOP 140
+#define PUSH 141
+#define POP 142
+#define RIGHT1 143
+#define RIGHT2 144
+#define RIGHT3 145
+#define RIGHT4 146
+#define W0 147
+#define W1 148
+#define W2 149
+#define W3 150
+#define W4 151
+#define X0 152
+#define X1 153
+#define X2 154
+#define X3 155
+#define X4 156
+#define DOWN1 157
+#define DOWN2 158
+#define DOWN3 159
+#define DOWN4 160
+#define Y0 161
+#define Y1 162
+#define Y2 163
+#define Y3 164
+#define Y4 165
+#define Z0 166
+#define Z1 167
+#define Z2 168
+#define Z3 169
+#define Z4 170
+#define FNTNUM0 171
+#define FNT1 235
+#define FNT2 236
+#define FNT3 237
+#define FNT4 238
+#define XXX1 239
+#define XXX2 240
+#define XXX3 241
+#define XXX4 242
+#define FNTDEF1 243
+#define FNTDEF2 244
+#define FNTDEF3 245
+#define FNTDEF4 246
+#define PRE 247
+#define POST 248
+#define POSTPOST 249
+
+#define TRAILER 223 /* Trailing bytes at end of file */
diff --git a/dviware/quicspool/src/eqnchar b/dviware/quicspool/src/eqnchar
new file mode 100644
index 0000000000..2e401c34ae
--- /dev/null
+++ b/dviware/quicspool/src/eqnchar
@@ -0,0 +1,104 @@
+.\" $Header: eqnchar,v 1.1 88/01/15 13:03:55 simpson Rel $
+.\" $Log: eqnchar,v $
+.\" Revision 1.1 88/01/15 13:03:55 simpson
+.\" initial release
+.\"
+.\" Revision 0.1 87/12/11 18:30:52 simpson
+.\" beta test
+.\"
+.EQ
+tdefine ciplus % "\o'\(pl\(ci'" %
+ndefine ciplus % O+ %
+tdefine citimes % "\o'\(mu\(ci'" %
+ndefine citimes % Ox %
+tdefine =wig % "\(eq\h'-\w'\(eq'u-\w'\s-1\(ap'u/2u'\v'-.4m'\s-1\z\(ap\(ap\s+1\v'.4m'\h'\w'\(eq'u-\w'\s-1\(ap'u/2u'" %
+ndefine =wig % ="~" %
+tdefine bigstar % "\o'\(pl\(mu'" %
+ndefine bigstar % X|- %
+tdefine =dot % "\z\(eq\v'-.6m'\h'.2m'\s+2.\s-2\v'.6m'\h'.1m'" %
+ndefine =dot % = dot %
+tdefine orsign % "\s-2\v'-.15m'\z\e\e\h'-.15m'\z\(sl\(sl\v'.15m'\s+2" %
+ndefine orsign % \e/ %
+tdefine andsign % "\s-2\v'-.15m'\z\(sl\(sl\h'-.15m'\z\e\e\v'.15m'\s+2" %
+ndefine andsign % /\e %
+tdefine =del % "\v'.3m'\z\(eq\v'-.6m'\s-1\(*D\s+1\v'.3m'" %
+ndefine =del % = to DELTA %
+tdefine oppA % "\s-2\v'-.15m'\z\e\e\h'-.15m'\z\(sl\(sl\v'-.15m'\h'-.75m'\z-\z-\h'.2m'\z-\z-\v'.3m'\h'.4m'\s+2" %
+ndefine oppA % V- %
+tdefine oppE %"\s-3\v'.2m'\z\(em\v'-.5m'\z\(em\v'-.5m'\z\(em\v'.50m'\h'1m'\z\(br\z\(br\v'.25m'\s+3" %
+ndefine oppE % E/ %
+tdefine incl % "\s-1\z\(or\v'-.5m'\z\(em\v'1.05m'\z\(em\v'.2m'\(em\v'-.75m'\s+1" %
+ndefine incl % C_ %
+tdefine nomem % "\o'\(mo\(sl'" %
+ndefine nomem % C-/ %
+tdefine angstrom % "\fR\zA\v'-.15m'\(de\v'.15m'\fP\h'.2m'" %
+ndefine angstrom % A to o %
+tdefine star %{ roman "\v'.4m'\s+3*\s-3\v'-.4m'"}%
+ndefine star % * %
+tdefine || % \(or\(or %
+tdefine <wig % "\z<\v'.5m'\(ap\v'-.5m'" %
+ndefine <wig %{ < from "~" }%
+tdefine >wig % "\z>\v'.5m'\(ap\v'-.5m'" %
+ndefine >wig %{ > from "~" }%
+tdefine langle % "\s-3\b'\(sl\e'\s0" %
+ndefine langle %<%
+tdefine rangle % "\s-3\b'\e\(sl'\s0" %
+ndefine rangle %>%
+tdefine hbar % "\zh\v'-.6m'\h'.05m'\(ru\v'.6m'" %
+ndefine hbar % h\u-\d %
+ndefine ppd % _| %
+tdefine ppd % "\h'.25m'\v'-.2m'\s-2\z\(or\s+2\h'-.25m'\v'.2m'\(ru" %
+tdefine <-> % "\o'\(<-\(->'" %
+ndefine <-> % "<-->" %
+tdefine <=> % { roman "\s-2\z<\h'.3m'\z=\h'.45m'=\h'-.56m'>\s+2" } %
+ndefine <=> % "<=>" %
+tdefine |< % "\o'<\(or'" %
+ndefine |< % <| %
+tdefine |> % "\o'>\(or'" %
+ndefine |> % |> %
+tdefine ang % "\v'-.15m'\z\s-2\(sl\s+2\v'.15m'\(ru" %
+ndefine ang % /_ %
+tdefine rang % "\h'-.05m'\v'-.2m'\s-2\z\(or\s+2\h'.05m'\v'.2m'\(ru" %
+ndefine rang % L %
+tdefine 3dot % "\v'-.8m'\z.\v'.5m'\z.\v'.5m'.\v'-.2m'" %
+ndefine 3dot % .\u.\u.\d\d %
+tdefine thf % ".\v'-.5m'.\v'.5m'." %
+ndefine thf % ..\u.\d %
+tdefine quarter % roman \(14 %
+ndefine quarter % 1/4 %
+tdefine 3quarter % roman \(34 %
+ndefine 3quarter % 3/4 %
+tdefine degree % { roman \(de } %
+ndefine degree % nothing sup o %
+tdefine square % roman \(sq %
+ndefine square % [] %
+tdefine circle % \(ci %
+ndefine circle % O %
+tdefine blot % "\fB\(sq\fP" %
+ndefine blot % HIX %
+tdefine bullet % roman \(bu %
+ndefine bullet % oxe %
+tdefine -wig % "\(~=" %
+ndefine -wig % - to "~" %
+tdefine wig % \(ap %
+ndefine wig % "~" %
+tdefine prop % \(pt %
+ndefine prop % oc %
+tdefine empty % \(es %
+ndefine empty % O/ %
+tdefine member % \(mo %
+ndefine member % C- %
+tdefine cup % \(cu %
+ndefine cup % U %
+tdefine scrL % "\v'-.2m'\z\fI)\fP\fR(\fP\v'.2m'" %
+ndefine scrL % (/ %
+tdefine ==> % "\z>\v'.6m'\(eq\v'-.6m'\h'.05m'" %
+ndefine ==> % >\d=\u %
+tdefine ==< % "\z<\v'.6m'\(eq\v'-.6m'\h'.05m'" %
+ndefine ==< % <\d=\u %
+define cap % \(ca %
+define subset % \(sb %
+define supset % \(sp %
+define !subset % \(ib %
+define !supset % \(ip %
+.EN
diff --git a/dviware/quicspool/src/fontinfo.h b/dviware/quicspool/src/fontinfo.h
new file mode 100644
index 0000000000..151d4ff298
--- /dev/null
+++ b/dviware/quicspool/src/fontinfo.h
@@ -0,0 +1,44 @@
+/* $Header: fontinfo.h,v 1.1 88/01/15 13:03:58 simpson Rel $ */
+/*
+$Log: fontinfo.h,v $
+ * Revision 1.1 88/01/15 13:03:58 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:30:53 simpson
+ * beta test
+ *
+*/
+
+/* Information on a whole font */
+struct FontInfo {
+ int blocksize; /* Estimated blocks >= real blocks */
+ int qmsheight; /* Height to give QMS printer */
+ int qmsbaseline; /* Baseline height to give QMS printer */
+ int numchars; /* Number of characters in font */
+ /* The following are just as in the PK documentation */
+ char comment[256];
+ long ds; /* Design size in FIXes */
+ long cs; /* Checksum */
+ long hppp, vppp; /* Pixel sps per point */
+ struct charinfo {
+ long tfm; /* Width of character in FIXes/designsize */
+ long dx, dy; /* Escapements in pixels sps */
+ long w, h; /* Width, height in pixels */
+ long hoff, voff; /* horizontal, vertical offset in pixels */
+ } chararray[256];
+};
+
+/* Information on a single character in a font */
+struct CharInfo {
+ long cc; /* Character found */
+ long tfm; /* Width of character in FIXes/designsize */
+ enum {pshort, pexshort, plong} preambletype;
+ long dxordm, dy; /* Escapements */
+ long w, h; /* Width and height of bitmap */
+ long hoff, voff; /* Offsets */
+ char *bitmap; /* Raster bitmap. If type 'X' orientation
+ * then it is (w+7)/8 bytes wide, h tall.
+ * If type 'Y' orientation then it is (h+7)/8
+ * bytes wide, w tall.
+ */
+};
diff --git a/dviware/quicspool/src/fontnode.h b/dviware/quicspool/src/fontnode.h
new file mode 100644
index 0000000000..ab026ec5d7
--- /dev/null
+++ b/dviware/quicspool/src/fontnode.h
@@ -0,0 +1,27 @@
+/* $Header: fontnode.h,v 1.1 88/01/15 13:04:00 simpson Rel $ */
+/*
+$Log: fontnode.h,v $
+ * Revision 1.1 88/01/15 13:04:00 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:30:54 simpson
+ * beta test
+ *
+*/
+#include <local/standard.h>
+/* The following are flag masks */
+#define PORT 1 /* Portrait mode */
+#define RAM 2 /* This is a ram font */
+#define LOADED 4 /* Font is currently loaded in memory */
+#define PRELOADED 8 /* Font was in ram memory on startup */
+
+/* All fonts may have the following information stored about them, regardless
+ * of whether we are using troff, TeX, etc.
+ */
+struct FontNode {
+ Bits flags;
+ int blocksize; /* in printer */
+ int qmsnumber;
+ char *localinfo; /* Info local to typesetting program */
+ struct FontNode *next; /* Store fonts as singly linked list */
+};
diff --git a/dviware/quicspool/src/getc.c b/dviware/quicspool/src/getc.c
new file mode 100644
index 0000000000..cf935e18bb
--- /dev/null
+++ b/dviware/quicspool/src/getc.c
@@ -0,0 +1,172 @@
+#ifndef lint
+static char *rcs = "$Header: getc.c,v 1.1 88/01/15 13:04:03 simpson Rel $";
+#endif
+/*
+$Log: getc.c,v $
+ * Revision 1.1 88/01/15 13:04:03 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:30:55 simpson
+ * beta test
+ *
+*/
+
+/* Secure getc(3) routines. These routines provide a set of standard I/O
+ * functions for reading data from files. The routines are essentially
+ * identical to their standard I/O equivalents except that these routines
+ * check for EOF. If EOF is encountered, a function determined by the user is
+ * called. This is useful if you are reading from a file, such as a TeX DVI
+ * file or troff file, and you want to check to see if the file ends
+ * prematurely without putting checks in every time you call getc(), gets(),
+ * etc. When reading a DVI file for example, you know when a file should end
+ * by the context, so if it does end prematurely, you can call an error
+ * routine. The following functions are provided:
+ *
+ * void seteoffunction(f)
+ * void (*f)();
+ *
+ * Sets the function to call if EOF is reached when reading with any of the
+ * routines. The function is assumed not to return although returning is
+ * allowed.
+ *
+ * int cgetc(f)
+ * FILE *f;
+ *
+ * Just like getc(3) but it checks for EOF. If EOF is encountered, the
+ * function set in seteoffunction() is called. (It is really more like
+ * fgetc(3) since it is not a macro).
+ *
+ * int cgetchar()
+ *
+ * Equivalent to cgetc(stdin). It's not a macro since we would need an
+ * include file.
+ *
+ * int cgetw(f)
+ * FILE *f;
+ *
+ * Just like getw(3) but is checks for EOF. If EOF is encountered, the
+ * function set in seteoffunction() is called.
+ *
+ * char *cgets(s)
+ * char *s;
+ *
+ * Just like gets(3) except it checks for EOF. This is a little lie.
+ * Actually it only calls the function set in seteoffunction if it
+ * encounters EOF on the first character read. The rationale behind this is
+ * that you probably want the last line of a file even if it doesn't end with
+ * a newline.
+ *
+ * char *cfgets(s, n, stream)
+ * char *s;
+ * int n;
+ * FILE *stream;
+ *
+ * Just like fgets(3) except it checks for EOF. Again, it only calls the
+ * eof function if the first character read returns EOF.
+ *
+ * int cfread(ptr, size, nitems, stream)
+ * char *ptr;
+ * int size;
+ * int nitems;
+ * FILE *stream;
+ *
+ * Just like fread(3) except it checks for EOF. The size read must be the
+ * size expected.
+ */
+
+#include <stdio.h>
+#include <local/standard.h>
+
+static void (*EOFFunction)();
+
+void seteoffunction(f)
+void (*f)();
+{
+ EOFFunction = f;
+}
+
+int cgetc(f)
+FILE *f;
+{
+ int c;
+
+ if ((c = getc(f)) == EOF) {
+ if (EOFFunction)
+ (*EOFFunction)();
+ }
+ else
+ return c;
+ return EOF; /* Only if EOFFunction returns or is NULL */
+}
+
+int cgetchar()
+{
+ return cgetc(stdin);
+}
+
+int cgetw(f)
+FILE *f;
+{
+ int w;
+
+ w = getw(f);
+ if (feof(f)) {
+ if (EOFFunction)
+ (*EOFFunction)();
+ } else
+ return w;
+ return EOF; /* Only if EOFFunction returns or is NULL */
+}
+
+char *cgets(s)
+char *s;
+{
+ int c;
+ char *p = s;
+
+ for (c = getchar(); c != '\n' && c != EOF; c = getchar())
+ *p++ = c;
+ if (c == EOF && p == s) {
+ if (EOFFunction)
+ (*EOFFunction)();
+ } else {
+ *p = '\0';
+ return s;
+ }
+ return NULL; /* Only if EOFFunction returns or is NULL */
+}
+
+char *cfgets(s, n, stream)
+char *s;
+int n;
+FILE *stream;
+{
+ int c = '\0';
+ char *p = s, *strcat();
+
+ while (p - s < n - 1 && (c = getc(stream)) != '\n' && c != EOF)
+ *p++ = c;
+ if (c == EOF && p == s) {
+ if (EOFFunction)
+ (*EOFFunction)();
+ }
+ else {
+ *p = '\0';
+ if (c == '\n')
+ (void)strcat(s, "\n");
+ return s;
+ }
+ return NULL; /* Only if EOFFunction returns or is NULL */
+}
+
+int cfread(ptr, size, nitems, stream)
+char *ptr;
+int size;
+int nitems;
+FILE *stream;
+{
+ if (fread(ptr, size, nitems, stream) != nitems)
+ if (EOFFunction)
+ (*EOFFunction)();
+ return nitems;
+}
diff --git a/dviware/quicspool/src/gf.c b/dviware/quicspool/src/gf.c
new file mode 100644
index 0000000000..33ccb06eaf
--- /dev/null
+++ b/dviware/quicspool/src/gf.c
@@ -0,0 +1,419 @@
+#ifndef lint
+static char *rcs = "$Header: gf.c,v 1.1 88/01/15 13:04:05 simpson Rel $";
+#endif
+/*
+$Log: gf.c,v $
+ * Revision 1.1 88/01/15 13:04:05 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:30:56 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <signal.h>
+#include <math.h>
+#include <local/standard.h>
+#include <local/qms.h>
+#include <local/profile.h>
+#include "constants.h"
+#include "fontnode.h"
+
+enum linetypes { dotted, solid, longdashed, shortdashed, dotdashed };
+char *Whoami; /* argv[0] */
+int X, Y;
+int PortraitFont = 1204;
+int LandscapeFont = 1217;
+int curx, cury, lowx, lowy, highx, highy;
+double scalefactor;
+enum linetypes linetype = solid;
+extern char *User;
+extern char *Host;
+extern Boolean Accounting;
+extern int NumPages;
+extern FILE *Accting;
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ extern int optind;
+ extern char *optarg;
+ PROFILE_VALUE *v, *getbindingvalue();
+ struct sigvec SigStruct;
+ int c, callcleanup();
+ int xi, yi, x0, y0, x1, y1, r;
+ char s[256];
+ void sanestate(), openpl(), move(), line(), label(), erase(),
+ point(), cont(), space(), arc(), circle(), linemod(),
+ closepl(), getstring();
+ void cleanup();
+
+ Whoami = argv[0];
+ while ((c = getopt(argc, argv, "x:y:n:h:w:l:")) != EOF)
+ switch (c) {
+ case 'x':
+ X = atoi(optarg);
+ break;
+ case 'y':
+ Y = atoi(optarg);
+ break;
+ case 'l':
+ case 'w':
+ break;
+ case 'n':
+ User = optarg;
+ break;
+ case 'h':
+ Host = optarg;
+ break;
+ case '?':
+ exit(2);
+ }
+ if (optind < argc) {
+ Accounting = TRUE;
+ if (!(Accting = fopen(argv[optind], "a"))) {
+ fprintf(stderr,"%s: cannot open accounting file %s\r\n", Whoami,
+ argv[optind]);
+ Accounting = FALSE;
+ }
+ }
+ if (X > 2550) {
+ if ((v = getbindingvalue("landscapefont")) && v->class ==
+ PROFILE_INTEGER)
+ LandscapeFont = v->value.i;
+ } else if ((v = getbindingvalue("portraitfont")) && v->class ==
+ PROFILE_INTEGER)
+ PortraitFont = v->value.i;
+ SigStruct.sv_handler = callcleanup;
+ SigStruct.sv_mask = 0;
+ SigStruct.sv_onstack = 0;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ openpl();
+ while ((c = getchar()) != EOF)
+ switch (c) {
+ case 'm':
+ xi = getsi(stdin);
+ yi = getsi(stdin);
+ move(xi,yi);
+ break;
+ case 'l':
+ x0 = getsi(stdin);
+ y0 = getsi(stdin);
+ x1 = getsi(stdin);
+ y1 = getsi(stdin);
+ line(x0,y0,x1,y1);
+ break;
+ case 't':
+ getstring(s,stdin);
+ label(s);
+ break;
+ case 'e':
+ erase();
+ break;
+ case 'p':
+ xi = getsi(stdin);
+ yi = getsi(stdin);
+ point(xi,yi);
+ break;
+ case 'n':
+ xi = getsi(stdin);
+ yi = getsi(stdin);
+ cont(xi,yi);
+ break;
+ case 's':
+ x0 = getsi(stdin);
+ y0 = getsi(stdin);
+ x1 = getsi(stdin);
+ y1 = getsi(stdin);
+ space(x0,y0,x1,y1);
+ break;
+ case 'a':
+ xi = getsi(stdin);
+ yi = getsi(stdin);
+ x0 = getsi(stdin);
+ y0 = getsi(stdin);
+ x1 = getsi(stdin);
+ y1 = getsi(stdin);
+ arc(xi,yi,x0,y0,x1,y1);
+ break;
+ case 'c':
+ xi = getsi(stdin);
+ yi = getsi(stdin);
+ r = getsi(stdin);
+ circle(xi,yi,r);
+ break;
+ case 'f':
+ getstring(s,stdin);
+ linemod(s);
+ break;
+ }
+ (void)sigblock(SIGINT);
+ closepl();
+ fputs(QUICON, stdout);
+ cleanup((struct FontNode *)NULL, SUCCEED);
+}
+
+callcleanup()
+{
+ void cleanup();
+
+ closepl();
+ fputs(QUICON, stdout);
+ cleanup((struct FontNode *)NULL, SUCCEED);
+}
+
+void openpl()
+{
+ fputs(QUICON, stdout);
+ if (X > 2550)
+ fputs(LANDSCAPE, stdout);
+ else
+ fputs(PORTRAIT, stdout);
+ printf("%s00000", SYNTAX);
+ printf("%s00000%05d", INITMARGVERT, X > 2550 ? (int)(8.5 * 1000) : 11 *
+ 1000);
+ printf("%s00000%05d", INITMARGHORZ, X > 2550 ? 11 * 1000 : (int)(8.5 *
+ 1000));
+ printf("%s%d%s", DEFFONT, X > 2550 ? LandscapeFont : PortraitFont,
+ ENDCMD);
+ fputs(FREEOFF, stdout);
+ fputs(VECTORON, stdout);
+}
+
+void move(x, y)
+int x, y;
+{
+ curx = x;
+ cury = y;
+}
+
+void line(x1, y1, x2, y2)
+int x1, y1, x2, y2;
+{
+ fputs(VECTORON, stdout);
+ fputs("^V", stdout);
+ switch (linetype) {
+ case dotted:
+ printf("2");
+ break;
+ case shortdashed:
+ printf("4");
+ break;
+ case longdashed:
+ printf("6");
+ break;
+ case dotdashed:
+ printf("7");
+ break;
+ default:
+ printf("0");
+ break;
+ } /* end switch */
+ printf("^U%05d:%05d", (int)((x1 - lowx) * scalefactor / 300.0 * 1000.0),
+ (int)(((X > 2550 ? 8.5 : 11) - ((y1 - lowy) * scalefactor /
+ 300.0)) * 1000.0));
+ printf("^D%05d:%05d", (int)((x2 - lowx) * scalefactor / 300.0 * 1000.0),
+ (int)(((X > 2550 ? 8.5 : 11) - ((y2 - lowy) * scalefactor /
+ 300.0)) * 1000.0));
+ fputs(VECTOROFF, stdout);
+ curx = x2, cury = y2;
+}
+
+void label(s)
+char *s;
+{
+ double scale;
+ char *ptr;
+
+ /* Each character is assumed to be 54 units wide without scaling.
+ Since the QMS fonts are proportional make sure that they are typeset
+ in the right place. The minimum width can be 45 dots (a 'W' in
+ font 1204) so adjust "scale" in case scalefactor would make
+ the width smaller than this.
+ 54*x = 45 x = 45/54 = 0.833333
+ */
+ scale = scalefactor;
+ if (scale < 0.833333)
+ scale = 0.833333;
+ for (ptr = s; *ptr != '\0' && *ptr != '\n'; ptr++) {
+ printf("\r^IV%05d", (int)(((X > 2550 ? 8.5 : 11) - (cury -
+ lowy) * scalefactor / 300.0) * 1000.0));
+ printf("%s-00170", JUSTIFYRELATIVE);
+ printf("^IH%05d", (int)((curx - lowx) * scalefactor / 300.0 *
+ 1000.0));
+ if (ptr - s > 0)
+ printf("%s+%05d", TABRELATIVE, (int)(54 * (ptr - s) * scale /
+ 300.0 * 1000.0));
+ (void)putchar(*ptr);
+ }
+}
+
+void erase()
+{
+ NumPages++;
+ putchar('\r');
+ fputs(FORMFEED, stdout);
+}
+
+void point(x, y)
+{
+ printf("^IH%05d", (int)((((curx - lowx) * scalefactor - 5.0) / 300.0)
+ * 1000.0));
+ printf("^IV%05d", (int)(((X > 2550 ? 8.5 : 11) - ((cury - lowy)
+ * scalefactor - 5.0) / 300.0) * 1000.0));
+ printf("%s0003300033", LINE);
+ curx = x;
+ cury = y;
+}
+
+void cont(x, y)
+int x, y;
+{
+ fputs(VECTORON, stdout);
+ fputs("^V", stdout);
+ switch (linetype) {
+ case dotted:
+ printf("2");
+ break;
+ case shortdashed:
+ printf("4");
+ break;
+ case longdashed:
+ printf("6");
+ break;
+ case dotdashed:
+ printf("7");
+ break;
+ default:
+ printf("0");
+ break;
+ } /* end switch */
+ printf("^U%05d:%05d", (int)((curx - lowx) * scalefactor / 300.0 *
+ 1000.0), (int)(((X > 2550 ? 8.5 : 11) - ((cury - lowy) *
+ scalefactor / 300.0)) * 1000.0));
+ printf("^D%05d:%05d", (int)((x - lowx) * scalefactor / 300.0 *
+ 1000.0), (int)(((X > 2550 ? 8.5 : 11.0) - ((y - lowy) *
+ scalefactor / 300.0)) * 1000.0));
+ fputs(VECTOROFF, stdout);
+ curx = x, cury = y;
+}
+
+void space(x0, y0, x1, y1)
+int x0, y0, x1, y1;
+{
+ double xscale, yscale;
+
+ lowx = x0;
+ highx = x1;
+ lowy = y0;
+ highy = y1;
+ /* Pick smallest scale factor (x or y) and use it. Don't scale different
+ * x and y directions or the image will become distorted.
+ */
+ xscale = (double)X / (highx - lowx);
+ yscale = (double)Y / (highy - lowy);
+ if (xscale > yscale)
+ scalefactor = yscale > 1.0 ? 1.0 : yscale;
+ else
+ scalefactor = xscale > 1.0 ? 1.0 : xscale;
+}
+
+void arc(x, y, x0, y0, x1, y1)
+{
+ double dx, dy, startangle, endangle;
+
+ fputs(DECIMALARC, stdout);
+ printf("+%05d+%05d", (int)((x - lowx) * scalefactor / 300.0 * 1000.0),
+ (int)(((X > 2550 ? 8.5 : 11.0) - ((y - lowy) * scalefactor / 300.0)) *
+ 1000.0));
+ printf("%05d", (int)(sqrt(pow((double)x0 - x, 2.0) + /* radius */
+ pow((double)y0 - y, 2.0)) * scalefactor / 300.0 * 1000.0));
+ dx = x0 - x;
+ dy = y0 - y;
+ if (dx == 0.0)
+ startangle = dy > 0.0 ? 90.0 : -90.0;
+ else
+ startangle = atan2(dy, dx) / PI * 180.0;
+ if (startangle < 0.0)
+ startangle += 360.0;
+ startangle = 1000.0 - (startangle / 360.0 * 1000.0);
+ if (startangle == 1000.0) /* QMS only takes 3 digits */
+ startangle = 999.0;
+ dx = x1 - x;
+ dy = y1 - y;
+ if (dx == 0.0)
+ endangle = dy > 0.0 ? 90.0 : -90.0;
+ else
+ endangle = atan2(dy, dx) / PI * 180.0;
+ if (endangle < 0.0)
+ endangle += 360.0;
+ endangle = 1000.0 - (endangle / 360.0 * 1000.0);
+ if (endangle == 1000.0)
+ endangle = 999.0;
+ /* Since the QMS draws clockwise, reverse points */
+ printf("%03d%03d", (int)endangle, (int)startangle);
+ fputs("04", stdout);
+ fputs(ENDCMD, stdout);
+}
+
+void circle(x, y, r)
+int x, y, r;
+{
+ arc(x, y, x + r, y, x - r, y);
+ arc(x, y, x - r, y, x + r, y);
+}
+
+void linemod(s)
+char *s;
+{
+ int stringlen;
+ char *index();
+
+ if (index(s, '\n'))
+ stringlen = s - index(s, '\n');
+ else
+ stringlen = 100;
+ if (EQN(s, "dotted", stringlen))
+ linetype = dotted;
+ else if (EQN(s, "dotdashed", stringlen))
+ linetype = dotdashed;
+ else if (EQN(s, "longdashed", stringlen))
+ linetype = longdashed;
+ else if (EQN(s, "shortdashed", stringlen))
+ linetype = shortdashed;
+ else
+ linetype = solid;
+}
+
+void closepl()
+{
+ NumPages++;
+ (void)putchar('\r');
+ fputs(FORMFEED, stdout);
+ fputs(QUICOFF, stdout);
+}
+
+/* Get an integer stored in 2 ascii bytes */
+int getsi(fin)
+FILE *fin;
+{
+ short a, b;
+
+ if ((b = getc(fin)) == EOF)
+ return(EOF);
+ if ((a = getc(fin)) == EOF)
+ return(EOF);
+ a <<= 8;
+ return a | b;
+}
+
+void getstring(s, fin)
+char *s;
+FILE *fin;
+{
+ for (; *s = getc(fin); s++)
+ if (*s == '\n')
+ break;
+ *s = '\0';
+}
diff --git a/dviware/quicspool/src/glpq b/dviware/quicspool/src/glpq
new file mode 100644
index 0000000000..9d3c9638c0
--- /dev/null
+++ b/dviware/quicspool/src/glpq
@@ -0,0 +1,32 @@
+#! /bin/csh
+# $Header: glpq,v 1.1 88/01/15 13:04:09 simpson Rel $
+# $Log: glpq,v $
+#Revision 1.1 88/01/15 13:04:09 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 18:30:57 simpson
+#beta test
+#
+set printers=(sneezy dopey grumpy)
+set lpqflags
+while ($#argv > 0)
+ switch ($1)
+ # if the -P option or a job number is given, only use one printer
+ case -P*:
+ lpq $lpqflags $*
+ exit
+ case [0-9]*:
+ lpq $lpqflags $*
+ exit
+ default:
+ set lpqflags=($lpqflags $1)
+ shift
+ breaksw
+ endsw
+end
+foreach i ($printers)
+ echo ${i}:
+ lpq -P$i $lpqflags
+ echo ${i}l:
+ lpq -P${i}l $lpqflags
+end
diff --git a/dviware/quicspool/src/glpr b/dviware/quicspool/src/glpr
new file mode 100644
index 0000000000..99a8718b0f
--- /dev/null
+++ b/dviware/quicspool/src/glpr
@@ -0,0 +1,104 @@
+#! /bin/csh
+# $Header: glpr,v 1.1 88/01/15 13:04:11 simpson Rel $
+# $Log: glpr,v $
+#Revision 1.1 88/01/15 13:04:11 simpson
+#initial release
+#
+#Revision 0.2 87/12/21 12:29:52 simpson
+#changed spelling of queuing
+#
+#Revision 0.1 87/12/11 18:30:58 simpson
+#beta test
+#
+# The algorithm is as follows:
+# If given -P flag, use that printer
+# Decide which printer to use by (minutes after hr modulo # of printers)
+# Assign states to printer
+# If printer is idle, use it
+# Look for idle printer
+# If found
+# use it
+# Look for busy printer
+# If found
+# use it
+# Look for stopped printer
+# If found
+# use it
+# Else all printers are disabled
+# Printers can be in 4 states: 1==disabled, 2==stopped, 3==busy, 4==idle
+set printers=(sneezy dopey grumpy)
+set landscape
+set lprflags
+while ($#argv > 0)
+ switch ($1)
+ case -P*:
+ lpr $lprflags $*
+ exit
+ case -L:
+ set landscape=l
+ shift
+ breaksw
+ default:
+ set lprflags=($lprflags $1)
+ shift
+ breaksw
+ endsw
+end
+@ index = `date|sed 's/.* [0-9][0-9]:\([0-9][0-9]\).*/\1/'` % $#printers + 1
+set i = 1
+set states=($printers)
+while ($i <= $#printers)
+ /etc/lpc status $printers[$i]$landscape|fgrep 'queuing is disabled'>\
+ /dev/null
+ if ($status == 0) then
+ set states[$i] = 1
+ @ i++
+ continue
+ endif
+ /etc/lpc status $printers[$i]$landscape|fgrep 'printing is disabled'>\
+ /dev/null
+ if ($status == 0) then
+ set states[$i] = 2
+ @ i++
+ continue
+ endif
+ lpq -P$printers[$i]|fgrep 'no entries'>/dev/null
+ set portraitstatus=$status
+ lpq -P$printers[$i]l|fgrep 'no entries'>/dev/null
+ if ($portraitstatus == 0 & $status == 0) then
+ set states[$i] = 4
+ else
+ set states[$i] = 3
+ endif
+ @ i++
+end
+if ($states[$index] == 4) then
+ lpr -P$printers[$index]$landscape $lprflags
+ exit
+endif
+set i = 1
+while ($i <= $#printers)
+ if ($states[$i] == 4) then
+ lpr -P$printers[$i]$landscape $lprflags
+ exit
+ endif
+ @ i++
+end
+set i = 1
+while ($i <= $#printers)
+ if ($states[$i] == 3) then
+ lpr -P$printers[$i]$landscape $lprflags
+ exit
+ endif
+ @ i++
+end
+set i = 1
+while ($i <= $#printers)
+ if ($states[$i] == 2) then
+ lpr -P$printers[$i]$landscape $lprflags
+ exit
+ endif
+ @ i++
+end
+# If we get here, all printers are disabled! Try anything!
+lpr -P$printers[$index]$landscape $lprflags
diff --git a/dviware/quicspool/src/if.c b/dviware/quicspool/src/if.c
new file mode 100644
index 0000000000..3353371ff7
--- /dev/null
+++ b/dviware/quicspool/src/if.c
@@ -0,0 +1,221 @@
+#ifndef lint
+static char *rcs = "$Header: if.c,v 1.1 88/01/15 13:04:16 simpson Rel $";
+#endif
+/*
+$Log: if.c,v $
+ * Revision 1.1 88/01/15 13:04:16 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:30:58 simpson
+ * beta test
+ *
+*/
+/* "if" filter
+ * This doesn't filter the input at all if the -c option is given. If the
+ * -c option is not given, then it converts \n into \r\n if it is not in
+ * QUIC mode. It performs accounting if an accounting file is given. It
+ * makes educated guesses as to the number of pages printed. Here is the
+ * page count algorithm:
+ * if -c option given then {
+ * if input string equals "^,"
+ * increment page count
+ * else if input character is formfeed and not free format
+ * increment page count
+ * } else
+ * if not in QUIC mode {
+ * if input character is \n and line count is greater than the
+ * length of the page
+ * increment page count
+ * } else
+ * if input string equals "^,"
+ * increment page count
+ * else if input character is formfeed and not free format
+ * increment page count
+ */
+#include <stdio.h>
+#include <signal.h>
+#include <local/qms.h>
+#include <local/standard.h>
+#include <local/profile.h>
+#include "fontnode.h"
+
+char *WhoAmI; /* argv[0] */
+char *Model;
+Boolean EnteredQuic = FALSE;
+Boolean QuicMode = FALSE;
+Boolean FreeForm = FALSE;
+Boolean Raw = FALSE;
+int LineNum = 1;
+int CharCount = 1;
+int Length;
+int Width;
+int Indent = 0;
+int PortraitFont = 1204;
+int LandscapeFont = 1217;
+struct sigvec SigStruct;
+extern char *User;
+extern char *Host;
+extern Boolean Accounting;
+extern int NumPages;
+extern FILE *Accting;
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ extern int optind;
+ extern char *optarg;
+ PROFILE_VALUE *v, *getbindingvalue();
+ int c, callcleanup();
+ void sanestate();
+ void cleanup();
+
+ WhoAmI = argv[0];
+ while ((c = getopt(argc, argv, "cw:l:i:n:h:")) != EOF)
+ switch (c) {
+ case 'c':
+ Raw = TRUE;
+ break;
+ case 'l':
+ Length = atoi(optarg);
+ break;
+ case 'w':
+ Width = atoi(optarg);
+ break;
+ case 'i':
+ Indent = atoi(optarg);
+ break;
+ case 'n':
+ User = optarg;
+ break;
+ case 'h':
+ Host = optarg;
+ break;
+ case '?': /* This should not happen */
+ exit(2);
+ }
+ if (optind < argc) {
+ Accounting = TRUE;
+ if (!(Accting = fopen(argv[optind], "a"))) {
+ fprintf(stderr, "%s: cannot open accounting file %s\n", WhoAmI,
+ argv[optind]);
+ Accounting = FALSE;
+ }
+ }
+ if (!(v = getbindingvalue("model")) || v->class != PROFILE_STRING &&
+ v->class != PROFILE_OTHER) {
+ fprintf(stderr,
+ "%s: model binding missing or invalid in configuration file\n",
+ WhoAmI);
+ exit(2);
+ }
+ Model = v->value.s;
+ if (Width > 80) {
+ if ((v = getbindingvalue("landscapefont")) && v->class ==
+ PROFILE_INTEGER)
+ LandscapeFont = v->value.i;
+ } else
+ if ((v = getbindingvalue("portraitfont")) && v->class ==
+ PROFILE_INTEGER)
+ PortraitFont = v->value.i;
+ SigStruct.sv_handler = callcleanup;
+ SigStruct.sv_mask = 0;
+ SigStruct.sv_onstack = 0;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ fputs(QUICON, stdout);
+ fputs(Width > 80 ? LANDSCAPE : PORTRAIT, stdout);
+ printf("%s00000", SYNTAX);
+ if (Raw) {
+ printf("%s00000%05d", INITMARGVERT, Width > 80 ? (int)(8.5 * 1000) :
+ 11 * 1000);
+ printf("%s00000%05d", INITMARGHORZ, Width > 80 ? 11 * 1000 : (int)(8.5
+ * 1000));
+ } else {
+ /* Different print engines can print in different parts of the page.
+ * For example, the Canon engine (QMS 800) cannot print in the top
+ * 1/4 inch of the page. The QMS 1500 uses a Ricoh engine. The
+ * 1200 and 2400 use a Xerox engine. We have to account for each
+ * by having different spacing.
+ */
+ if (EQ(Model, "QMS800"))
+ if (Width > 80) {
+ printf("%s%05d%05d", INITMARGVERT, (int)(.4 * 1000),
+ (int)(8.5 * 1000));
+ printf("%s%05d%05d", INITMARGHORZ, (int)(.325 * 1000),
+ 11 * 1000);
+ printf("%s%04d", LINESPACING, (int)(8.2 * 100));
+ } else {
+ printf("%s%05d%05d", INITMARGVERT, (int)(.3 * 1000),
+ 11 * 1000);
+ printf("%s%05d%05d", INITMARGHORZ, (int)(.325 * 1000),
+ (int)(8.5 * 1000));
+ printf("%s%04d", LINESPACING, (int)(6.1 * 100));
+ }
+ else if (EQ(Model, "QMS1500"))
+ if (Width > 80) {
+ printf("%s%05d%05d", INITMARGVERT, (int)(.1 * 1000),
+ (int)(8.2 * 1000));
+ printf("%s%05d%05d", INITMARGHORZ, (int)(.325 * 1000),
+ 11 * 1000);
+ printf("%s%04d", LINESPACING, (int)(8.2 * 100));
+ } else {
+ printf("%s%05d%05d", INITMARGVERT, (int)(.1 * 1000),
+ (int)(10.85 * 1000));
+ printf("%s%05d%05d", INITMARGHORZ, (int)(.325 * 1000),
+ (int)(8.5 * 1000));
+ printf("%s%04d", LINESPACING, (int)(6.1 * 100));
+ }
+ else /* Models 1200 and 2400 */
+ if (Width > 80) {
+ printf("%s%05d%05d", INITMARGVERT, (int)(.32 * 1000),
+ (int)(8.5 * 1000));
+ printf("%s%05d%05d", INITMARGHORZ, (int)(.325 * 1000),
+ 11 * 1000);
+ printf("%s%04d", LINESPACING, (int)(7.95 * 100));
+ } else {
+ printf("%s%05d%05d", INITMARGVERT, (int)(.22 * 1000),
+ 11 * 1000);
+ printf("%s%05d%05d", INITMARGHORZ, (int)(.325 * 1000),
+ (int)(8.5 * 1000));
+ printf("%s%04d", LINESPACING, (int)(6.02 * 100));
+ }
+ if (Width > 80) {
+ if ((v = getbindingvalue("landscapepitch")) && (v->class ==
+ PROFILE_INTEGER || v->class == PROFILE_FLOAT))
+ if (v->class == PROFILE_INTEGER)
+ printf("%s%04d", CHARSPACING, v->value.i * 100);
+ else
+ printf("%s%04d", CHARSPACING, (int)(v->value.f * 100));
+ } else
+ if ((v = getbindingvalue("portraitpitch")) && (v->class ==
+ PROFILE_INTEGER || v->class == PROFILE_FLOAT))
+ if (v->class == PROFILE_INTEGER)
+ printf("%s%04d", CHARSPACING, v->value.i * 100);
+ else
+ printf("%s%04d", CHARSPACING, (int)(v->value.f * 100));
+ }
+ printf("%s%d%s", DEFFONT, Width > 80 ? LandscapeFont : PortraitFont,
+ ENDCMD);
+ fputs(FREEOFF, stdout);
+ fputs(QUICOFF, stdout);
+ while (yylex())
+ ;
+ (void)sigblock(SIGINT);
+ if (Raw || EnteredQuic || LineNum != 1 || CharCount != 1) {
+ (void)putchar('\f');
+ NumPages++;
+ }
+ fputs(QUICON, stdout);
+ cleanup((struct FontNode *)NULL, SUCCEED);
+}
+
+int callcleanup()
+{
+ void cleanup();
+
+ fputs(QUICON, stdout);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup((struct FontNode *)NULL, SUCCEED);
+}
+
+#include "quic.c"
diff --git a/dviware/quicspool/src/io.c b/dviware/quicspool/src/io.c
new file mode 100644
index 0000000000..b1043cda50
--- /dev/null
+++ b/dviware/quicspool/src/io.c
@@ -0,0 +1,104 @@
+#ifndef lint
+static char *rcs = "$Header: io.c,v 1.1 88/01/15 13:04:20 simpson Rel $";
+#endif
+/*
+$Log: io.c,v $
+ * Revision 1.1 88/01/15 13:04:20 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:30:59 simpson
+ * beta test
+ *
+*/
+/* General I/O routines */
+
+#include <stdio.h>
+#include <local/standard.h>
+#include <ctype.h>
+
+/* Reads n bytes from file f into an unsigned long. The cgetc() routine is used
+ * so an appropriate error routine will need to be selected. */
+unsigned long uinteger(f, bytes)
+FILE *f;
+int bytes;
+{
+ int i;
+ long n = 0;
+
+ for (i = 0; i < bytes; i++)
+ n = n << 8 | cgetc(f);
+ return n;
+}
+
+/* Reads n bytes from file f into a long. The cgetc() routine is used so
+ * an appropriate error routine will need to be selected. */
+long integer(f, bytes)
+FILE *f;
+int bytes;
+{
+ int i;
+ long n = 0;
+
+ for (i = 0; i < bytes; i++) {
+ n = n << 8 | cgetc(f);
+ if (i == 0 && n & 0x80)
+ n = n | ~0x7f;
+ }
+ return n;
+}
+
+/* Gets the next character from the input that is not a space character.
+ * It calls cgetc() on EOF so the EOF function should be set appropriately.
+ */
+int getnonblank(f)
+FILE *f;
+{
+ int c;
+
+ while (isspace(c = cgetc(f)))
+ ;
+ return c;
+}
+
+/* Gets the next integer from the input and returns its value. It calls
+ * cgetc() on EOF so the EOF function should be set appropriately.
+ */
+int getinteger(f)
+FILE *f;
+{
+ int c, i = 0;
+ Boolean negative = FALSE;
+
+ while (isspace(c = cgetc(f)))
+ ;
+ if (c == '-') {
+ negative = TRUE;
+ c = cgetc(f);
+ }
+ while ('0' <= c && c <= '9') {
+ i = i * 10 + c - '0';
+ c = cgetc(f);
+ }
+ (void)ungetc(c, f);
+ if (negative)
+ i = -i;
+ return i;
+}
+
+/* Reads the next blank delineated string from the file. It calls cgetc()
+ * so an EOF function should be set appropriately. The return value is static
+ * and is overwritten with each call.
+ */
+char *getstring(f)
+FILE *f;
+{
+ static char buf[81];
+ int c;
+
+ c = getnonblank(f);
+ buf[0] = c, buf[1] = '\0';
+ while (!isspace(c = cgetc(f)))
+ buf[strlen(buf)+1] = '\0', buf[strlen(buf)] = c;
+ (void)ungetc(c, f);
+ return buf;
+}
diff --git a/dviware/quicspool/src/list.c b/dviware/quicspool/src/list.c
new file mode 100644
index 0000000000..f71598f48c
--- /dev/null
+++ b/dviware/quicspool/src/list.c
@@ -0,0 +1,101 @@
+#ifndef lint
+static char *rcs = "$Header: list.c,v 1.1 88/01/15 13:04:23 simpson Rel $";
+#endif
+/*
+$Log: list.c,v $
+ * Revision 1.1 88/01/15 13:04:23 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:31:00 simpson
+ * beta test
+ *
+*/
+
+/* Routines for processing and returning information on font lists */
+
+#include <stdio.h>
+#include <local/qms.h>
+#include "fontnode.h"
+
+
+/* Returns a pointer to a font on the font list; NULL if not found */
+struct FontNode *getfontnode(head, fontnumber, orientation)
+struct FontNode *head;
+int fontnumber;
+int orientation;
+{
+ struct FontNode *p;
+
+ for (p = head; p; p = p->next)
+ if (p->qmsnumber == fontnumber && (p->flags & PORT ? 'P' : 'L') ==
+ orientation)
+ return p;
+ return NULL;
+}
+
+/* Puts the node passed as an argument on the end of the list. Fonts are
+ * deleted from the beginning of the list when making room in font memory
+ * so put the current font on the end of the list.
+ */
+void endoflist(head, thenode)
+struct FontNode **head;
+struct FontNode *thenode;
+{
+ struct FontNode *prev = NULL, *p;
+
+ if (!head || !thenode)
+ return;
+ /* First delete it from the FontList */
+ for (p = *head; p; prev = p, p = p->next)
+ if (p == thenode)
+ if (p == *head)
+ *head = (*head)->next;
+ else
+ prev->next = p->next;
+ thenode->next = NULL;
+ /* Tack it on the end */
+ if (!*head)
+ *head = thenode;
+ else {
+ for (p = *head; p->next; p = p->next)
+ ;
+ p->next = thenode;
+ }
+}
+
+/* Takes a list of fonts that are already loaded in the printer (i.e., the
+ * two lists returned by qmsfnt()) and returns a single list of FontNode's.
+ * We manipulate singly linked lists of FontNode's in each driver, not the
+ * lists returned by qmsfnt().
+ */
+struct FontNode *createfontlist(fntinfo)
+struct qmsfnt *fntinfo;
+{
+ struct fontnode *p;
+ struct FontNode *list = NULL, *new;
+ char *malloc();
+
+ if (!fntinfo)
+ return NULL;
+ for (p = fntinfo->rom; p; p = p->next) {
+ bzero((char *)(new = (struct FontNode *)malloc(
+ (unsigned)sizeof(struct FontNode))), sizeof(struct FontNode));
+ new->next = list, list = new; /* Put on front of list */
+ list->flags = LOADED | PRELOADED;
+ if (p->orientation == 'P')
+ list->flags |= PORT;
+ list->qmsnumber = p->number;
+ list->blocksize = CEILING(p->bytes / 1024.0);
+ }
+ for (p = fntinfo->ram; p; p = p->next) {
+ bzero((char *)(new = (struct FontNode *)malloc(
+ (unsigned)sizeof(struct FontNode))), sizeof(struct FontNode));
+ new->next = list, list = new;
+ list->flags = RAM | LOADED | PRELOADED;
+ if (p->orientation == 'P')
+ list->flags |= PORT;
+ list->qmsnumber = p->number;
+ list->blocksize = CEILING(p->bytes / 1024);
+ }
+ return list;
+}
diff --git a/dviware/quicspool/src/makefile b/dviware/quicspool/src/makefile
new file mode 100644
index 0000000000..6a2bde4be0
--- /dev/null
+++ b/dviware/quicspool/src/makefile
@@ -0,0 +1,152 @@
+# $Header: Makefile,v 1.2 88/02/03 08:52:35 simpson Exp $
+# $Log: Makefile,v $
+#Revision 1.2 88/02/03 08:52:35 simpson
+#added tpic support
+#
+#Revision 1.1 88/01/15 13:03:01 simpson
+#initial release
+#
+#Revision 0.2 87/12/18 11:25:41 simpson
+#added spline file
+#
+#Revision 0.1 87/12/11 18:30:37 simpson
+#beta test
+#
+CFLAGS=-O
+LDFLAGS=-s
+FILTER=/usr/local/lib/lpr
+OTROFFFONT=/usr/lib/font
+DITROFFFONT=/usr/lib/font/devqms
+WWTEXFONT=/usr/lib/tex/qmsfonts
+WBTEXFONT=/usr/lib/tex/imagenfonts
+BINARIES=/usr/local/bin
+DOCILEUSER=games
+
+all: of if rf gf df nf tf pktoch tfm2difont tfm2ofont dumpdesc cati
+
+configure:
+ sed s:--PKDIR1--:$(WBTEXFONT): < df.c.backup | \
+ sed s:--PKDIR2--:$(WWTEXFONT): > df.c
+ sed s:--FONTDIR--:$(DITROFFFONT): < tf.c.backup > tf.c
+ sed s:--FONTDIR--:$(DITROFFFONT): < nf.c.backup > nf.c
+ sed s:--USER--:$(DOCILEUSER): < constants.h.backup > constants.h
+ sed s:--OFONT--:$(OTROFFFONT): < qtroff.backup | \
+ sed s:--FILTER--:$(FILTER): > qtroff
+ sed s:--DIFONT--:$(DITROFFFONT): < ditroff.backup > ditroff
+
+of: of.o profile.o misc.o string.o
+ $(CC) -o $@ $(LDFLAGS) of.o profile.o misc.o string.o \
+ ../libtrw/libtrw.a ../libprofile/libprofile.a ../libglob/libglob.a \
+ ../libqmsquery/libqmsquery.a -ll -ltermcap
+
+if: if.o profile.o qms.o cleanup.o
+ $(CC) -o $@ $(LDFLAGS) if.o profile.o qms.o cleanup.o \
+ ../libtrw/libtrw.a ../libprofile/libprofile.a ../libglob/libglob.a \
+ ../libqmsquery/libqmsquery.a -ll -ltermcap
+
+rf: rf.o profile.o qms.o cleanup.o
+ $(CC) -o $@ $(LDFLAGS) rf.o profile.o qms.o cleanup.o \
+ ../libtrw/libtrw.a ../libqmsquery/libqmsquery.a \
+ ../libprofile/libprofile.a ../libglob/libglob.a -ll -ltermcap
+
+gf: gf.o profile.o qms.o cleanup.o
+ $(CC) -o $@ $(LDFLAGS) gf.o profile.o qms.o cleanup.o \
+ ../libtrw/libtrw.a ../libqmsquery/libqmsquery.a \
+ ../libprofile/libprofile.a ../libglob/libglob.a -ll -ltermcap -lm
+
+df: df.o cleanup.o getc.o io.o list.o misc.o pk.o profile.o qms.o spline.o \
+ stack.o string.o table.o
+ $(CC) -o $@ $(LDFLAGS) df.o cleanup.o getc.o io.o list.o misc.o \
+ pk.o profile.o qms.o spline.o stack.o string.o table.o \
+ ../libtrw/libtrw.a ../libqmsquery/libqmsquery.a -ll \
+ ../libprofile/libprofile.a ../libglob/libglob.a -ltermcap -lm
+
+nf: nf.o cleanup.o getc.o io.o list.o misc.o pk.o profile.o qms.o spline.o \
+ stack.o string.o table.o
+ $(CC) -o $@ $(LDFLAGS) nf.o cleanup.o getc.o io.o list.o misc.o pk.o \
+ profile.o qms.o spline.o stack.o string.o table.o ../libtrw/libtrw.a \
+ ../libqmsquery/libqmsquery.a ../libprofile/libprofile.a \
+ ../libglob/libglob.a -ll -ltermcap -lm
+
+tf: tf.o cat.o cleanup.o getc.o io.o list.o misc.o pk.o profile.o qms.o \
+ stack.o string.o table.o
+ $(CC) -o $@ $(LDFLAGS) tf.o cat.o cleanup.o getc.o io.o list.o misc.o \
+ pk.o profile.o qms.o stack.o string.o table.o ../libtrw/libtrw.a \
+ ../libqmsquery/libqmsquery.a ../libprofile/libprofile.a \
+ ../libglob/libglob.a -ll -ltermcap
+
+pktoch: pktoch.o misc.o pk.o io.o getc.o string.o
+ $(CC) $(LDFLAGS) -o $@ pktoch.o misc.o pk.o io.o getc.o string.o \
+ ../libtrw/libtrw.a -ltermcap
+
+tfm2difont: tfm2difont.o getc.o io.o
+ $(CC) $(LDFLAGS) -o $@ tfm2difont.o getc.o io.o ../libtrw/libtrw.a
+
+tfm2ofont: tfm2ofont.o cat.o getc.o io.o
+ $(CC) $(LDFLAGS) -o $@ tfm2ofont.o cat.o getc.o io.o ../libtrw/libtrw.a
+
+dumpdesc: dumpdesc.o getc.o io.o
+ $(CC) $(LDFLAGS) -o $@ dumpdesc.o getc.o io.o ../libtrw/libtrw.a
+
+cati: cati.o
+ $(CC) $(LDFLAGS) -o $@ cati.o
+
+install:
+ install -m 755 if $(FILTER)
+ install -m 755 of $(FILTER)
+ install -m 755 rf $(FILTER)
+ install -m 755 gf $(FILTER)
+ install -m 755 tf $(FILTER)
+ install -o root -g daemon -m 4750 nf $(FILTER)
+ install -o root -g daemon -m 4750 df $(FILTER)
+ install -c -m 644 mount.nr $(FILTER)
+ install -m 755 tfm2ofont $(BINARIES)
+ install -m 755 tfm2difont $(BINARIES)
+ install -m 755 dumpdesc $(BINARIES)
+ install -m 755 pktoch $(BINARIES)
+ install -m 755 cati $(BINARIES)
+ install -c -m 755 qtroff $(BINARIES)
+ install -c -m 755 ditroff $(BINARIES)
+ install -c -m 755 glpr $(BINARIES)
+ install -c -m 755 glpq $(BINARIES)
+
+clean:
+ -rm -f of if rf gf df nf tf pktoch tfm2difont tfm2ofont dumpdesc cati \
+ *.o lex.yy.c y.tab.c quic.c xxx.c xxxlex.c \
+ df.c tf.c nf.c constants.h qtroff ditroff
+
+lint:
+ lint of.c profile.c misc.c string.c
+ lint if.c profile.c qms.c cleanup.c
+ lint rf.c profile.c qms.c cleanup.c
+ lint gf.c profile.c qms.c cleanup.c
+ lint df.c cleanup.c getc.c io.c list.c misc.c pk.c profile.c qms.c \
+ stack.c string.c table.c
+ lint nf.c cleanup.c getc.c io.c list.c misc.c pk.c profile.c qms.c \
+ spline.c stack.c string.c table.c
+ lint tf.c cat.c cleanup.c getc.c io.c list.c misc.c pk.c profile.c \
+ qms.c stack.c string.c table.c
+ lint pktoch.c misc.c pk.c io.c getc.c string.c
+ lint tfm2ofont.c cat.c getc.c io.c
+ lint tfm2difont.c io.c getc.c
+ lint dumpdesc.c io.c getc.c
+ lint cati.c
+
+if.o: fontnode.h quic.c
+rf.o: fontnode.h
+gf.c: constants.h fontnode.h
+df.o: dvi.h constants.h fontinfo.h fontnode.h xxx.c
+nf.o: constants.h dev.h fontinfo.h fontnode.h xxx.c
+tf.o: constants.h fontinfo.h fontnode.h
+pktoch.o: fontinfo.h
+tfm2difont.o: constants.h dev.h
+tfm2ofont.o: constants.h
+dumpdesc.o: dev.h
+cleanup.o: constants.h fontnode.h
+list.o: fontnode.h
+misc.o: constants.h
+pk.o: constants.h fontinfo.h pk.h
+qms.o: fontnode.h
+quic.c: quic.l
+xxx.c: xxxlex.c xxx.y
+xxxlex.c: xxxlex.l
diff --git a/dviware/quicspool/src/makefile.trw b/dviware/quicspool/src/makefile.trw
new file mode 100644
index 0000000000..ac2648aa29
--- /dev/null
+++ b/dviware/quicspool/src/makefile.trw
@@ -0,0 +1,190 @@
+# $Header: Makefile.TRW,v 1.2 88/02/03 08:52:38 simpson Exp $
+# $Log: Makefile.TRW,v $
+# Revision 1.2 88/02/03 08:52:38 simpson
+# added tpic support
+#
+# Revision 1.1 88/01/15 13:03:05 simpson
+# initial release
+#
+# Revision 0.2 87/12/18 11:34:39 simpson
+# added spline file for pic
+#
+# Revision 0.1 87/12/11 19:13:28 simpson
+# beta test
+#
+CFLAGS=-O -I/usr/src/usr.lib/lpr -DTRW
+LDFLAGS=-s
+FILTER=/usr/local/lib/lpr
+OTROFFFONT=/usr/lib/font
+DITROFFFONT=/usr/lib/font/devqms
+WWTEXFONT=/usr/lib/tex/qmsfonts
+WBTEXFONT=/usr/lib/tex/imagenfonts
+BINARIES=/usr/local/bin
+DOCILEUSER=games
+
+all: of if rf gf df nf tf pktoch tfm2difont tfm2ofont dumpdesc cati lpr lpd \
+ lpq pac
+
+configure:
+ sed s:--PKDIR1--:$(WBTEXFONT): < df.c.backup | \
+ sed s:--PKDIR2--:$(WWTEXFONT): > df.c
+ sed s:--FONTDIR--:$(DITROFFFONT): < tf.c.backup > tf.c
+ sed s:--FONTDIR--:$(DITROFFFONT): < nf.c.backup > nf.c
+ sed s:--USER--:$(DOCILEUSER): < constants.h.backup > constants.h
+ sed s:--OFONT--:$(OTROFFFONT): < qtroff.backup | \
+ sed s:--FILTER--:$(FILTER): > qtroff
+ sed s:--DIFONT--:$(DITROFFFONT): < ditroff.backup > ditroff
+
+of: of.o profile.o misc.o string.o
+ $(CC) -o $@ $(LDFLAGS) of.o profile.o misc.o string.o \
+ ../libtrw/libtrw.a ../libprofile/libprofile.a ../libglob/libglob.a \
+ ../libqmsquery/libqmsquery.a -ll -ltermcap
+
+if: if.o profile.o qms.o cleanup.o
+ $(CC) -o $@ $(LDFLAGS) if.o profile.o qms.o cleanup.o \
+ ../libtrw/libtrw.a ../libprofile/libprofile.a ../libglob/libglob.a \
+ ../libqmsquery/libqmsquery.a -ll -ltermcap
+
+rf: rf.o profile.o qms.o cleanup.o
+ $(CC) -o $@ $(LDFLAGS) rf.o profile.o qms.o cleanup.o \
+ ../libtrw/libtrw.a ../libqmsquery/libqmsquery.a \
+ ../libprofile/libprofile.a ../libglob/libglob.a -ll -ltermcap
+
+gf: gf.o profile.o qms.o cleanup.o
+ $(CC) -o $@ $(LDFLAGS) gf.o profile.o qms.o cleanup.o \
+ ../libtrw/libtrw.a ../libqmsquery/libqmsquery.a \
+ ../libprofile/libprofile.a ../libglob/libglob.a -ll -ltermcap -lm
+
+df: df.o cleanup.o getc.o io.o list.o misc.o pk.o profile.o qms.o spline.o \
+ stack.o string.o table.o
+ $(CC) -o $@ $(LDFLAGS) df.o cleanup.o getc.o io.o list.o misc.o \
+ pk.o profile.o qms.o spline.o stack.o string.o table.o \
+ ../libtrw/libtrw.a ../libqmsquery/libqmsquery.a -ll \
+ ../libprofile/libprofile.a ../libglob/libglob.a -ltermcap -lm
+
+nf: nf.o cleanup.o getc.o io.o list.o misc.o pk.o profile.o qms.o spline.o \
+ stack.o string.o table.o
+ $(CC) -o $@ $(LDFLAGS) nf.o cleanup.o getc.o io.o list.o misc.o pk.o \
+ profile.o qms.o spline.o stack.o string.o table.o ../libtrw/libtrw.a \
+ ../libqmsquery/libqmsquery.a ../libprofile/libprofile.a \
+ ../libglob/libglob.a -ll -ltermcap -lm
+
+tf: tf.o cat.o cleanup.o getc.o io.o list.o misc.o pk.o profile.o qms.o \
+ stack.o string.o table.o
+ $(CC) -o $@ $(LDFLAGS) tf.o cat.o cleanup.o getc.o io.o list.o misc.o \
+ pk.o profile.o qms.o stack.o string.o table.o ../libtrw/libtrw.a \
+ ../libqmsquery/libqmsquery.a ../libprofile/libprofile.a \
+ ../libglob/libglob.a -ll -ltermcap
+
+pktoch: pktoch.o misc.o pk.o io.o getc.o string.o
+ $(CC) $(LDFLAGS) -o $@ pktoch.o misc.o pk.o io.o getc.o string.o \
+ ../libtrw/libtrw.a -ltermcap
+
+tfm2difont: tfm2difont.o getc.o io.o
+ $(CC) $(LDFLAGS) -o $@ tfm2difont.o getc.o io.o ../libtrw/libtrw.a
+
+tfm2ofont: tfm2ofont.o cat.o getc.o io.o
+ $(CC) $(LDFLAGS) -o $@ tfm2ofont.o cat.o getc.o io.o ../libtrw/libtrw.a
+
+dumpdesc: dumpdesc.o getc.o io.o
+ $(CC) $(LDFLAGS) -o $@ dumpdesc.o getc.o io.o ../libtrw/libtrw.a
+
+cati: cati.o
+ $(CC) $(LDFLAGS) -o $@ cati.o
+
+lpr: lpr.o startdaemon.o printcap.o
+ $(CC) -o $@ $(LDFLAGS) lpr.o startdaemon.o printcap.o -lledger
+
+lpd: lpd.o printjob.o recvjob.o displayq.o rmjob.o startdaemon.o lpdchar.o \
+ common.o printcap.o
+ $(CC) -o $@ $(LDFLAGS) lpd.o printjob.o recvjob.o displayq.o rmjob.o \
+ startdaemon.o lpdchar.o common.o printcap.o -lledger
+
+lpq: lpq.o displayq.o common.o printcap.o
+ $(CC) -o $@ $(LDFLAGS) lpq.o displayq.o common.o printcap.o -ltermcap
+
+pac: pac.o printcap.o
+ $(CC) -o $@ $(LDFLAGS) pac.o printcap.o -ltrw -lledger -lprofile \
+ -lglob
+
+install:
+ install -m 755 if $(FILTER)
+ install -m 755 of $(FILTER)
+ install -m 755 rf $(FILTER)
+ install -m 755 gf $(FILTER)
+ install -m 755 tf $(FILTER)
+ install -o root -g daemon -m 4750 nf $(FILTER)
+ install -o root -g daemon -m 4750 df $(FILTER)
+ install -o root -g daemon -m 6711 lpr /usr/ucb/lpr
+ install -o root -g daemon -m 6711 lpd /usr/lib/lpd
+ install -o root -g daemon -m 6711 lpq /usr/ucb/lpq
+ install -m 755 pac /etc
+ install -c -m 644 mount.nr $(FILTER)
+ install -m 755 tfm2ofont $(BINARIES)
+ install -m 755 tfm2difont $(BINARIES)
+ install -m 755 dumpdesc $(BINARIES)
+ install -m 755 pktoch $(BINARIES)
+ install -m 755 cati $(BINARIES)
+ install -c -m 755 qtroff $(BINARIES)
+ install -c -m 755 ditroff $(BINARIES)
+ install -c -m 755 glpr $(BINARIES)
+ install -c -m 755 glpq $(BINARIES)
+
+clean:
+ -rm -f of if rf gf df nf tf pktoch tfm2difont tfm2ofont dumpdesc cati \
+ lpr lpd lpq pac *.o lex.yy.c y.tab.c quic.c xxx.c xxxlex.c \
+ df.c tf.c nf.c constants.h qtroff ditroff
+
+lint:
+ lint of.c profile.c misc.c string.c
+ lint if.c profile.c qms.c cleanup.c
+ lint rf.c profile.c qms.c cleanup.c
+ lint gf.c profile.c qms.c cleanup.c
+ lint df.c cleanup.c getc.c io.c list.c misc.c pk.c profile.c qms.c \
+ stack.c string.c table.c
+ lint nf.c cleanup.c getc.c io.c list.c misc.c pk.c profile.c qms.c \
+ spline.c stack.c string.c table.c
+ lint tf.c cat.c cleanup.c getc.c io.c list.c misc.c pk.c profile.c \
+ qms.c stack.c string.c table.c
+ lint pktoch.c misc.c pk.c io.c getc.c string.c
+ lint tfm2ofont.c cat.c getc.c io.c
+ lint tfm2difont.c io.c getc.c
+ lint dumpdesc.c io.c getc.c
+ lint cati.c
+
+if.o: fontnode.h quic.c
+rf.o: fontnode.h
+gf.c: constants.h fontnode.h
+df.o: dvi.h constants.h fontinfo.h fontnode.h xxx.c
+nf.o: constants.h dev.h fontinfo.h fontnode.h xxx.c
+tf.o: constants.h fontinfo.h fontnode.h
+pktoch.o: fontinfo.h
+tfm2difont.o: constants.h dev.h
+tfm2ofont.o: constants.h
+dumpdesc.o: dev.h
+lpd.o lpr.o startdaemon.o printjob.o displayq.o rmjob.o recvjob.ocommon.o \
+pac.o: /usr/src/usr.lib/lpr/lp.h /usr/src/usr.lib/lpr/lp.local.h
+cleanup.o: constants.h fontnode.h
+list.o: fontnode.h
+misc.o: constants.h
+pk.o: constants.h fontinfo.h pk.h
+qms.o: fontnode.h
+quic.c: quic.l
+startdaemon.o: /usr/src/usr.lib/lpr/startdaemon.c
+ $(CC) -c $(CFLAGS) /usr/src/usr.lib/lpr/startdaemon.c
+printcap.o: /usr/src/usr.lib/lpr/printcap.c
+ $(CC) -c $(CFLAGS) /usr/src/usr.lib/lpr/printcap.c
+lpd.o: /usr/src/usr.lib/lpr/lpd.c
+ $(CC) -c $(CFLAGS) /usr/src/usr.lib/lpr/lpd.c
+lpq.o: /usr/src/usr.lib/lpr/lpq.c
+ $(CC) -c $(CFLAGS) /usr/src/usr.lib/lpr/lpq.c
+recvjob.o: /usr/src/usr.lib/lpr/recvjob.c
+ $(CC) -c $(CFLAGS) /usr/src/usr.lib/lpr/recvjob.c
+rmjob.o: /usr/src/usr.lib/lpr/rmjob.c
+ $(CC) -c $(CFLAGS) /usr/src/usr.lib/lpr/rmjob.c
+lpdchar.o: /usr/src/usr.lib/lpr/lpdchar.c
+ $(CC) -c $(CFLAGS) /usr/src/usr.lib/lpr/lpdchar.c
+common.o: /usr/src/usr.lib/lpr/common.c
+ $(CC) -c $(CFLAGS) /usr/src/usr.lib/lpr/common.c
+xxx.c: xxxlex.c xxx.y
+xxxlex.c: xxxlex.l
diff --git a/dviware/quicspool/src/misc.c b/dviware/quicspool/src/misc.c
new file mode 100644
index 0000000000..1a6e60ed51
--- /dev/null
+++ b/dviware/quicspool/src/misc.c
@@ -0,0 +1,183 @@
+#ifndef lint
+static char *rcs = "$Header: misc.c,v 1.1 88/01/15 13:04:30 simpson Rel $";
+#endif
+/*
+$Log: misc.c,v $
+ * Revision 1.1 88/01/15 13:04:30 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:31:03 simpson
+ * beta test
+ *
+*/
+
+/* Miscellaneous routines */
+
+#include <stdio.h>
+#include <pwd.h>
+#include <local/standard.h>
+#include <ctype.h>
+#include "constants.h"
+
+/* Same as the tgetent of termcap(3x) but it works for the printcap
+ * database. Use the rest of the termcap(3x) routines after you use
+ * this one.
+ */
+int pgetent(bp, name)
+char *bp;
+char *name;
+{
+ void setenv();
+
+ setenv("TERMCAP", "/etc/printcap");
+ return tgetent(bp, name);
+}
+
+/* Changes the uid of the running process to that of `user'. If the `host' is
+ * not equal to the current hostname, then a docile uid is switched to. TRUE
+ * is returned if the person selected in the password file exists and the uid
+ * is switched, FALSE otherwise.
+ */
+Boolean setnewid(host, user)
+char *host, *user;
+{
+ char username[51];
+ char hostname[51];
+ char *strcpy();
+ struct passwd *passwd;
+
+ (void)strcpy(username, user);
+ (void)gethostname(hostname, 51);
+ if (!EQ(hostname, host))
+ (void)strcpy(username, DOCILEUSER);
+ if (!(passwd = getpwnam(username)))
+ return FALSE;
+ seteuid(passwd->pw_uid);
+ setegid(passwd->pw_gid);
+ return TRUE;
+}
+
+/* Gets the value of an environment variable just like getenv(3) but
+ * instead it reads the value of the environment variable from the user's
+ * .profile, .login or .cshrc file depending on what shell they are using.
+ * This is useful for processes that are not forked by the user but still
+ * wish to know the value of a user's environment variable. The .cshrc
+ * file is searched before the .login file. The returned value is static
+ * and the result is written over after each call as in getenv(3). NULL is
+ * returned if the user does not exist, the file is not readable or the
+ * environment variable does not exist. The string searched for should
+ * begin with "<variable name>=" in .profile or "setenv <variable name> "
+ * in the .cshrc or .login file. Continuation lines are handled too. If
+ * the user name that is passed is NULL then the current effective user id
+ * will used.
+ */
+char *fgetenv(variable, user)
+char *variable;
+char *user;
+{
+ struct passwd *passwd;
+ static char envvariable[201];
+ char s[201], line[201], *strcpy(), *strcat();
+ FILE *f;
+ Boolean continueline;
+ Boolean bourne;
+ Boolean dotcshrc = TRUE;
+
+ if (!user) {
+ if (!(passwd = getpwuid(geteuid())))
+ return NULL;
+ } else
+ if (!(passwd = getpwnam(user)))
+ return NULL;
+ if (!passwd->pw_shell || strlen(passwd->pw_shell) == 0 ||
+ passwd->pw_shell && (EQ(passwd->pw_shell, "/bin/sh") ||
+ EQ(passwd->pw_shell, "/bin/ksh"))) {
+ (void)sprintf(s, "%s/.profile", passwd->pw_dir);
+ bourne = TRUE;
+ } else {
+ (void)sprintf(s, "%s/.cshrc", passwd->pw_dir);
+ bourne = FALSE;
+ }
+onceagain:
+ continueline = FALSE;
+ if (!(f = fopen(s, "r")))
+ if (bourne)
+ return NULL;
+ else
+ goto trynextfile;
+ while (fgets(line, 201, f)) {
+ if (line[strlen(line) - 1] == '\n')
+ line[strlen(line) - 1] = '\0';
+ if (bourne)
+ (void)sprintf(s, "%s=", variable);
+ else
+ (void)sprintf(s, "setenv %s ", variable);
+ /* Delete trailing blanks */
+ while (strlen(line) > 0 && isspace(line[strlen(line) - 1]))
+ line[strlen(line) - 1] = '\0';
+ if (continueline)
+ /* Check for \ on end of line */
+ if (line[strlen(line) - 1] == '\\') {
+ line[strlen(line) - 1] = '\0';
+ continueline = TRUE;
+ (void)strcat(envvariable, line);
+ } else {
+ (void)strcat(envvariable, line);
+ (void)fclose(f);
+ return envvariable;
+ }
+ else if (EQN(line, s, strlen(s))) {
+ if (line[strlen(line) - 1] == '\\') {
+ line[strlen(line) - 1] = '\0';
+ (void)strcpy(envvariable, &line[strlen(s)]);
+ continueline = TRUE;
+ } else {
+ continueline = FALSE;
+ (void)strcpy(envvariable, &line[strlen(s)]);
+ (void)fclose(f);
+ return envvariable;
+ }
+ } else
+ continue;
+ }
+ if (continueline) {
+ (void)fclose(f);
+ return envvariable;
+ }
+ (void)fclose(f);
+trynextfile:
+ if (!bourne && dotcshrc) {
+ (void)sprintf(s, "%s/.login", passwd->pw_dir);
+ dotcshrc = FALSE;
+ goto onceagain;
+ }
+ return NULL;
+}
+
+void printbitmap(drawer, acter_set, egral, erceptor)
+FILE *drawer;
+char *acter_set;
+int egral;
+int erceptor;
+{
+ unsigned char red_human_bodies; /* Heeeeere's Johnny... */
+ int erpret; /* -- Jack Nicholson */
+ short cakes = (egral + 7) / 8;
+ long john, silver;
+
+ for (erpret = 0; erpret < erceptor; erpret++) {
+ for (john = 0; john < cakes; john++)
+ if (john < cakes - 1)
+ for (red_human_bodies = 0x80, silver = 0; silver < 8;
+ silver++, red_human_bodies >>= 1)
+ fprintf(drawer, "%c", *(acter_set + cakes * erpret +
+ john) & red_human_bodies ? '*' : '.');
+ else
+ for (red_human_bodies = 0x80, silver = 0; silver < (egral + 7)
+ % 8 + 1; silver++, red_human_bodies >>= 1)
+ fprintf(drawer, "%c", *(acter_set + cakes * erpret +
+ john) & red_human_bodies ? '*' : '.');
+ fprintf(drawer, "\n");
+ }
+}
+
diff --git a/dviware/quicspool/src/mount.nr b/dviware/quicspool/src/mount.nr
new file mode 100644
index 0000000000..5c9e59f159
--- /dev/null
+++ b/dviware/quicspool/src/mount.nr
@@ -0,0 +1,13 @@
+.\" $Header: mount.nr,v 1.1 88/01/15 13:04:34 simpson Rel $
+.\" $Log: mount.nr,v $
+.\" Revision 1.1 88/01/15 13:04:34 simpson
+.\" initial release
+.\"
+.\" Revision 0.1 87/12/11 18:31:04 simpson
+.\" beta test
+.\"
+.\" Mount the fonts on the positions or the width tables are not read
+.fp 1 R
+.fp 2 I
+.fp 3 B
+.fp 4 S
diff --git a/dviware/quicspool/src/nf.c_backup b/dviware/quicspool/src/nf.c_backup
new file mode 100644
index 0000000000..544b2cf126
--- /dev/null
+++ b/dviware/quicspool/src/nf.c_backup
@@ -0,0 +1,1329 @@
+/* Ditroff driver */
+#ifndef lint
+static char *rcs = "$Header: nf.c.backup,v 1.2 88/02/03 08:52:15 simpson Exp $";
+#endif
+/*
+$Log: nf.c.backup,v $
+Revision 1.2 88/02/03 08:52:15 simpson
+added tpic support
+
+Revision 1.1 88/01/15 13:04:37 simpson
+initial release
+
+Revision 0.3 88/01/06 08:46:06 simpson
+corrected determination of charexists
+
+Revision 0.2 87/12/18 11:37:32 simpson
+added spline and ellipse support
+
+Revision 0.1 87/12/11 18:31:04 simpson
+beta test
+
+*/
+#include <stdio.h>
+#include <signal.h>
+#include <math.h>
+#include <assert.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/dir.h>
+#include <local/standard.h>
+#include <local/qms.h>
+#include <local/profile.h>
+#include "fontnode.h"
+#include "fontinfo.h"
+#include "constants.h"
+#include "dev.h"
+
+#define FONTDIR "--FONTDIR--"
+#define DEVNAME "qms" /* Name given to -T option*/
+/* Cast for accessing LocalInfo */
+#define LI(p) ((struct LocalInfo *)p->localinfo)
+#define UNITWIDTH 10 /* Same as in DESC file */
+
+typedef struct {
+ double x, y;
+} COORDINATE;
+
+struct FontState {
+ int pointsize;
+ int font;
+};
+
+struct Stack {
+ struct FontState fontstate;
+ int h, v;
+};
+
+struct LocalInfo {
+ char name[21]; /* Name of font */
+ int pointsize;
+ int qmsheight; /* Height to give QMS printer */
+ int qmsbaseline; /* Baseline height to give QMS printer */
+ char pathname[81]; /* Full pathname in file system */
+ Boolean charexists[256];/* True if there is such a character */
+ short bitmapsize[2][256]; /* Width & height of each char bitmap */
+ short widths[256]; /* True width of each char in pixels */
+ long maptable[160]; /* Encoding of troff special sequences */
+ short maptablesize; /* # of entries in map table */
+};
+
+char EOFName[101]; /* Used by pkeofsocleanup & desceofsocleanup */
+char *Whoami; /* argv[0] */
+char *Model; /* Model of printer being used */
+char Orientation = 'P';
+char MountTable[51][21]; /* Max of 50 different fonts in table */
+char *Xxxstring; /* String found in extension commands */
+char *Pxxxstring; /* Pointer used by the lexical analyzer */
+char PKDir[101]; /* Directory PK fonts are in */
+int MaxBlocks; /* # of free blocks w/out ram or rom fonts */
+int CurRamBlocks; /* # of blocks used by ram fonts */
+int CurRomBlocks; /* # of blocks used by rom fonts */
+int DownLoadFNum; /* Number of font currently being downloaded */
+int Origin[2]; /* Origin of a postprocessor graph in pixels */
+FILE *ReadLine; /* Debugger port tty */
+struct sigvec SigStruct;
+struct FontNode *FontList; /* Contains all fonts & their attributes */
+extern char *Host, *User;
+extern FILE *Accting;
+extern Boolean Accounting;
+extern int NumPages;
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ Boolean found, loadnametable(), setnewid();
+ extern int optind;
+ extern char *optarg;
+ int *intptr, *tempintptr;
+ int c;
+ int romlist[41]; /* List of rom font #s */
+ int simplyexit(), callcleanup();
+ void qmsfntfree(), cleanup(), seteoffunction(), process(),
+ troffeofsocleanup(), adjust();
+ PROFILE_VALUE *v, *getbindingvalue();
+ struct qmsram *raminfo;
+ struct qmsfnt *fntinfo;
+ struct fontnode *p;
+ struct FontNode *createfontlist();
+#ifdef DEBUG
+ char *malloc(), orien;
+ int i, fontno, size;
+ FILE *f;
+ struct fontnode *fn;
+#endif
+
+ Whoami = argv[0];
+ while ((c = getopt(argc, argv, "x:y:n:h:w:l:i:")) != EOF)
+ switch (c) {
+ case 'x':
+ if (atoi(optarg) > 2550)
+ Orientation = 'L';
+ break;
+ case 'h':
+ Host = optarg;
+ break;
+ case 'n':
+ User = optarg;
+ break;
+ case 'y':
+ case 'w':
+ case 'l':
+ case 'i':
+ break;
+ default:
+ exit(2);
+ }
+ SigStruct.sv_handler = simplyexit;
+ SigStruct.sv_mask = 0;
+ SigStruct.sv_onstack = 0;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ if (optind < argc) {
+ Accounting = TRUE;
+ if (!(Accting = fopen(argv[optind], "a"))) {
+ fprintf(stderr, "%s: cannot open accounting file %s\n", Whoami,
+ argv[optind]);
+ Accounting = FALSE;
+ }
+ }
+ if (!(v = getbindingvalue("model")) || v->class != PROFILE_STRING &&
+ v->class != PROFILE_OTHER) {
+ fprintf(stderr,
+ "%s: model binding missing or invalid in configuration file\n",
+ Whoami);
+ exit(2);
+ }
+ Model = v->value.s;
+ fputs(QUICON, stdout);
+ printf("%s^Z%s%s", CLEAROVERLAY, CLEARAOVERLAY, ENDCMD);
+ fputs(QUICOFF, stdout);
+ (void)fflush(stdout);
+ if (!(v = getbindingvalue("readline")) || v->class != PROFILE_STRING &&
+ v->class != PROFILE_OTHER) {
+ fprintf(stderr,
+ "%s: readline binding missing or invalid in configuration file\n",
+ Whoami);
+ exit(2);
+ }
+ if (!(ReadLine = fopen(v->value.s, "r"))) {
+ fprintf(stderr, "%s: could not open %s for reading\n", Whoami,
+ v->value.s);
+ exit(2);
+ }
+#ifdef DEBUG
+ raminfo = (struct qmsram *)malloc((unsigned)sizeof(struct qmsram));
+ raminfo->TR = 401;
+ raminfo->AR = 387;
+ raminfo->FR = 13;
+ raminfo->OR = 0;
+#else
+ qmsopen(fileno(stdout), fileno(ReadLine));
+ if (!(raminfo = qmsram())) {
+ fprintf(stderr, "%s: could not get printer ram info\n", Whoami);
+ exit(2);
+ }
+#endif
+ MaxBlocks = raminfo->AR + raminfo->FR;
+ /* Save 5 block for filling with tpic */
+ MaxBlocks -= 5;
+#ifdef DEBUG
+ fntinfo = (struct qmsfnt *)malloc((unsigned)sizeof(struct qmsfnt));
+ fntinfo->ram = fntinfo->rom = NULL;
+ for (i = 0; i < 13; i++) {
+ switch (i) {
+ case 0:
+ fontno = 521;
+ orien = 'L';
+ break;
+ case 1:
+ fontno = 522;
+ orien = 'L';
+ break;
+ case 2:
+ fontno = 523;
+ orien = 'L';
+ break;
+ case 3:
+ fontno = 524;
+ orien = 'L';
+ break;
+ case 4:
+ fontno = 1100;
+ orien = 'P';
+ break;
+ case 5:
+ fontno = 1103;
+ orien = 'P';
+ break;
+ case 6:
+ fontno = 1200;
+ orien = 'P';
+ break;
+ case 7:
+ fontno = 1204;
+ orien = 'P';
+ break;
+ case 8:
+ fontno = 1217;
+ orien = 'L';
+ case 9:
+ fontno = 7009;
+ orien = 'P';
+ break;
+ case 10:
+ fontno = 7010;
+ orien = 'P';
+ break;
+ case 11:
+ fontno = 7036;
+ orien = 'P';
+ break;
+ case 12:
+ fontno = 7037;
+ orien = 'P';
+ break;
+ }
+ fn = (struct fontnode *)malloc((unsigned)sizeof(struct fontnode));
+ fn->next = fntinfo->rom, fntinfo->rom = fn;
+ fn->orientation = orien;
+ fn->number = fontno;
+ fn->bytes = 1024; /* Rom fonts occupy one block */
+ fn->version = '0';
+ fn->class = '1';
+ }
+ /* For testing, ramfonts contains the already loaded fonts. It should
+ * consist of lines containing two numbers and a letter, the first being
+ * the font number, the second being the font size, and the third letter
+ * is an orientation. The orientation should be the character immediately
+ * after the size of the font.
+ */
+ if (f = fopen("ramfonts", "r")) { /* File is optional for testing */
+ while (fscanf(f, "%d%d%c", &fontno, &size, &orien) == 3)
+ {
+ fn = (struct fontnode *)malloc((unsigned)sizeof(struct fontnode));
+ fn->next = fntinfo->ram, fntinfo->ram = fn;
+ fn->orientation = orien;
+ fn->number = fontno;
+ fn->bytes = size;
+ fn->version = '0';
+ fn->class = '1';
+ raminfo->AR -= CEILING(size / 1024.0);
+ raminfo->FR += CEILING(size / 1024.0);
+ }
+ (void)fclose(f);
+ }
+#else
+ if (!(fntinfo = qmsfnt())) {
+ fprintf(stderr, "%s: could not get printer font info\n", Whoami);
+ exit(2);
+ }
+#endif
+ for (CurRomBlocks = 0, p = fntinfo->rom; p; p = p->next)
+ CurRomBlocks += CEILING(p->bytes / (double)1024);
+ CurRamBlocks = raminfo->FR - CurRomBlocks;
+ /* Make an array of rom font #s */
+ for (p = fntinfo->rom, intptr = romlist; p; p = p->next) {
+ for (tempintptr = romlist, found = FALSE; tempintptr < intptr;
+ tempintptr++)
+ if (*tempintptr == p->number)
+ found = TRUE;
+ if (!found)
+ *intptr++ = p->number;
+ }
+ *intptr = 0;
+ if (EQ(Model, "QMS800"))
+ (void)sprintf(PKDir, "%s/wbfonts", FONTDIR);
+ else
+ (void)sprintf(PKDir, "%s/wwfonts", FONTDIR);
+ if (!loadnametable(PKDir, romlist, 10001)) {
+ fprintf(stderr, "%s: could not open font directory %s\n", Whoami,
+ PKDir);
+ exit(2);
+ }
+ FontList = createfontlist(fntinfo);
+ qmsfntfree(fntinfo);
+ if (!setnewid(Host, User)) {
+ fprintf(stderr, "%s: could not change user id to %s\n", Whoami,
+ User);
+ exit(2); /* This is fatal bud */
+ }
+ SigStruct.sv_handler = callcleanup;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ fputs(QUICON, stdout);
+ if (Orientation == 'P')
+ fputs(PORTRAIT, stdout);
+ else
+ fputs(LANDSCAPE, stdout);
+ printf("%s%c%c", TEXTPROC, '0', '0');
+ printf("%s00000%05d", INITMARGVERT, Orientation == 'P' ? 11 * 1000 :
+ (int)(8.5 * 1000));
+ printf("%s00000%05d", INITMARGHORZ, Orientation == 'P' ? (int)(8.5 * 1000)
+ : 11 * 1000);
+ printf("%s0000", CHARSPACING);
+ fputs(FREEOFF, stdout);
+ seteoffunction(troffeofsocleanup);
+ process();
+ cleanup(FontList, SUCCEED);
+}
+
+/* Main routine that interprets the troff file */
+void process()
+{
+ int specialfont = 4; /* Loc of S font in mount table */
+ int c, d, n;
+ int realhpxl = 0, realvpxl = 0,
+ virthpxl = 0, virtvpxl = 0; /*Virt & real cursor locs - pxls*/
+ Boolean switchedtospecial = FALSE;/* T if we switch to Special font */
+ Boolean firstpage = TRUE, fontselected = FALSE, download(), makeroom();
+ char *malloc(), *getstring(), *push(), *pop(), *strcpy(), *s,
+ *findpkfont(), extension[1000], *cgets(), *extractinteger();
+ void endoflist(), spline();
+ double radius, anglestart, angleend, decimalanglestart, a, b,
+ decimalangleend, controlpoints[37][3], curvepoints[500][3];
+ COORDINATE start, end, center, cur, new;
+ struct Stack *tempstack;
+ struct FontNode *fonttolist();
+ struct FontNode *curnode = NULL; /* Current font ditroff has selected */
+ struct FontNode *oldnode; /* 4 saving when trying special font */
+ /* Current font ditroff has selected */
+ struct FontState current;
+ /* For saving font when trying the special font */
+ struct FontState oldcurrent;
+
+ current.font = current.pointsize = 0;
+ bzero((char *)MountTable, sizeof(MountTable));
+ while (TRUE) { /* A non-returning function is called to exit */
+ switch (c = getnonblank(stdin)) {
+ case 's':
+ current.pointsize = getinteger(stdin);
+ curnode = fonttolist(MountTable[current.font], current.pointsize);
+ endoflist(&FontList, curnode);
+ fontselected = FALSE;
+ putchar('\r'); /* Ends the pass */
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ break;
+ case 'f':
+ current.font = getinteger(stdin);
+ curnode = fonttolist(MountTable[current.font], current.pointsize);
+ endoflist(&FontList, curnode);
+ fontselected = FALSE;
+ putchar('\r'); /* Ends the pass */
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ break;
+ case 'c': /* Character at current location */
+ c = cgetchar();
+ /* If we couldn't find the font, don't print anything since we
+ * don't know how to increment the real & virtual pixel locations.
+ */
+ if (!curnode || !curnode->localinfo || !LI(curnode)->charexists[c])
+ {
+ oldcurrent = current;
+ current.font = specialfont;
+ oldnode = curnode;
+ curnode = fonttolist(MountTable[current.font],
+ current.pointsize);
+ if (curnode && curnode->localinfo &&
+ LI(curnode)->charexists[c]) {
+ endoflist(&FontList, curnode);
+ fontselected = FALSE;
+ putchar('\r');
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ switchedtospecial = TRUE;
+ } else {
+ current = oldcurrent;
+ curnode = oldnode;
+ continue;
+ }
+ }
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl);
+ if (!(curnode->flags & LOADED)) {
+ if (!makeroom(FontList, MaxBlocks, &CurRamBlocks, CurRomBlocks,
+ curnode->blocksize)) {
+ fprintf(stderr,
+ "%s: could not free %d blocks for font %s\n", Whoami,
+ curnode->blocksize, LI(curnode)->pathname);
+ goto trytocontinue1;
+ }
+ if (!download(curnode))
+ goto trytocontinue1;
+ realhpxl = realvpxl = 0;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl);
+ }
+ if (!fontselected) {
+ printf("%s%d%s", DEFFONT, curnode->qmsnumber, ENDCMD);
+ fontselected = TRUE;
+ }
+ /* For fonts with width but no bitmap, check the size of the
+ * raster. The QMS will not print (or download) a character with
+ * width and no bitmap so we must not print characters that are not
+ * in the font. If you do, you will get the lowest character in
+ * the font.
+ */
+trytocontinue1:
+ if (LI(curnode)->bitmapsize[0][c] != 0 &&
+ LI(curnode)->bitmapsize[1][c] != 0) {
+ if (c == '^' || c <= 32 || c >= 127)
+ printf("%s%02X", SPECIAL, c);
+ else
+ (void)putchar(c);
+ realhpxl += LI(curnode)->widths[c];
+ }
+ if (switchedtospecial) { /* Switch back */
+ switchedtospecial = FALSE;
+ current = oldcurrent;
+ curnode = oldnode;
+ fontselected = FALSE;
+ }
+ break;
+ case 'C':
+ s = getstring(stdin);
+ if (!curnode || !curnode->localinfo || (c =
+ lookup(LI(curnode)->maptable, LI(curnode)->maptablesize, s)) == -1
+ || !LI(curnode)->charexists[c = LI(curnode)->maptable[c] >> 24 &
+ 0xFF]) {
+ oldcurrent = current;
+ current.font = specialfont;
+ oldnode = curnode;
+ curnode = fonttolist(MountTable[current.font],
+ current.pointsize);
+ if (curnode && curnode->localinfo && (c =
+ lookup(LI(curnode)->maptable, LI(curnode)->maptablesize, s))
+ != -1 && LI(curnode)->charexists[c = LI(curnode)->maptable[c]
+ >> 24 & 0xFF]) {
+ endoflist(&FontList, curnode);
+ fontselected = FALSE;
+ putchar('\r');
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ switchedtospecial = TRUE;
+ } else {
+ current = oldcurrent;
+ curnode = oldnode;
+ continue;
+ }
+ }
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl);
+ if (!(curnode->flags & LOADED)) {
+ if (!makeroom(FontList, MaxBlocks, &CurRamBlocks, CurRomBlocks,
+ curnode->blocksize)) {
+ fprintf(stderr,
+ "%s: could not free %d blocks for font %s\n", Whoami,
+ curnode->blocksize, LI(curnode)->pathname);
+ goto trytocontinue2;
+ }
+ if (!download(curnode))
+ goto trytocontinue2;
+ realhpxl = realvpxl = 0;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl);
+ }
+ if (!fontselected) {
+ printf("%s%d%s", DEFFONT, curnode->qmsnumber, ENDCMD);
+ fontselected = TRUE;
+ }
+trytocontinue2:
+ if (LI(curnode)->bitmapsize[0][c] != 0 &&
+ LI(curnode)->bitmapsize[1][c] != 0) {
+ if (c == '^' || c <= 32 || c >= 127)
+ printf("%s%02X", SPECIAL, c);
+ else
+ (void)putchar(c);
+ realhpxl += LI(curnode)->widths[c];
+ }
+ if (switchedtospecial) { /* Switch back */
+ switchedtospecial = FALSE;
+ current = oldcurrent;
+ curnode = oldnode;
+ fontselected = FALSE;
+ }
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ virthpxl += (c - '0') * 10 + (cgetchar() - '0');
+ c = cgetchar();
+ if (!curnode || !curnode->localinfo || !LI(curnode)->charexists[c])
+ {
+ oldcurrent = current;
+ current.font = specialfont;
+ oldnode = curnode;
+ curnode = fonttolist(MountTable[current.font],
+ current.pointsize);
+ if (curnode && curnode->localinfo &&
+ LI(curnode)->charexists[c]) {
+ endoflist(&FontList, curnode);
+ fontselected = FALSE;
+ putchar('\r');
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ switchedtospecial = TRUE;
+ } else {
+ current = oldcurrent;
+ curnode = oldnode;
+ continue;
+ }
+ }
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl);
+ if (!(curnode->flags & LOADED)) {
+ if (!makeroom(FontList, MaxBlocks, &CurRamBlocks,
+ CurRomBlocks, curnode->blocksize)) {
+ fprintf(stderr,
+ "%s: could not free %d blocks for font %s\n", Whoami,
+ curnode->blocksize, LI(curnode)->pathname);
+ goto trytocontinue3;
+ }
+ if (!download(curnode))
+ goto trytocontinue3;
+ realhpxl = realvpxl = 0;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl);
+ }
+ if (!fontselected) {
+ printf("%s%d%s", DEFFONT, curnode->qmsnumber, ENDCMD);
+ fontselected = TRUE;
+ }
+trytocontinue3:
+ if (LI(curnode)->bitmapsize[0][c] != 0 &&
+ LI(curnode)->bitmapsize[1][c] != 0) {
+ if (c == '^' || c <= 32 || c >= 127)
+ printf("%s%02X", SPECIAL, c);
+ else
+ (void)putchar(c);
+ realhpxl += LI(curnode)->widths[c];
+ }
+ if (switchedtospecial) { /* Switch back */
+ switchedtospecial = FALSE;
+ current = oldcurrent;
+ curnode = oldnode;
+ fontselected = FALSE;
+ }
+ break;
+ case 'p': /* Begin a new page */
+ (void)getinteger(stdin); /* Ignore page number */
+ realhpxl = realvpxl = virthpxl = virtvpxl = 0;
+ printf("%s%05d%s", TAB, 0, ENDCMD);
+ printf("%s%05d%s", JUSTIFYMARGIN, 0, ENDCMD);
+ if (!firstpage)
+ fputs(FORMFEED, stdout), NumPages++;
+ else
+ firstpage = FALSE;
+ break;
+ case 'w': /* Appears between words - ignore */
+ break;
+ case 'H': /* Absolute horizontal */
+ virthpxl = getinteger(stdin);
+ break;
+ case 'h': /* Relative horizontal */
+ virthpxl += getinteger(stdin);
+ break;
+ case 'V': /* Absolute vertical */
+ virtvpxl = getinteger(stdin);
+ break;
+ case 'v': /* Relative vertical */
+ virtvpxl += getinteger(stdin);
+ break;
+ case 'n': /* At end of line */
+ (void)getinteger(stdin); /* Amount of space before line */
+ (void)getinteger(stdin); /* Amount of space after line */
+ break;
+ case '{': /* Push stack */
+ tempstack = (struct Stack *)malloc(sizeof(struct Stack));
+ tempstack->fontstate.pointsize = current.pointsize;
+ tempstack->fontstate.font = current.font;
+ tempstack->h = virthpxl, tempstack->v = virtvpxl;
+ (void)push((char *)&tempstack);
+ break;
+ case '}': /* Pop stack */
+ tempstack = (struct Stack *)pop();
+ current.pointsize = tempstack->fontstate.pointsize;
+ current.font = tempstack->fontstate.font;
+ virthpxl = tempstack->h, virtvpxl = tempstack->v;
+ curnode = fonttolist(MountTable[current.font], current.pointsize);
+ endoflist(&FontList, curnode);
+ free((char *)tempstack);
+ fontselected = FALSE;
+ putchar('\r'); /* Ends the pass */
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ break;
+ case '#': /* Comment */
+ while (cgetchar() != '\n')
+ ;
+ break;
+ case 'D': /* Graphics drawing commands */
+ switch (c = cgetchar()) {
+ case 'l': /* Line */
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl);
+ start.x = virthpxl, start.y = virtvpxl;
+ end.x = start.x + getinteger(stdin), end.y = start.y +
+ getinteger(stdin);
+ /* I don't know what this next character is. It is not
+ * documented.
+ */
+ while ((c = cgetchar()) != '\n');
+ ;
+ fputs(VECTORON, stdout);
+ printf("%s%05d:%05d", PENUP,
+ ROUND(virthpxl/(double)RESOLUTION*1000),
+ ROUND(virtvpxl/(double)RESOLUTION*1000));
+ printf("%s03", PENWIDTH);
+ printf("%s%05d:%05d", PENDOWN, ROUND(end.x / RESOLUTION *
+ 1000), ROUND(end.y / RESOLUTION * 1000));
+ fputs(VECTOROFF, stdout);
+ printf("%s00000%s00000%s\r", TAB, JUSTIFYMARGIN, ENDCMD);
+ virthpxl = ROUND(end.x), virtvpxl = ROUND(end.y);
+ realhpxl = realvpxl = 0;
+ break;
+ case 'c': /* Circle */
+ d = getinteger(stdin);
+ printf("%s%c%05d%c%05d%05d%03d%03d%02d%s", ARC,
+ virthpxl+.5*d>=0.0?'+':'-', ROUND((virthpxl+.5*d)/RESOLUTION
+ *1000.0),
+ virtvpxl>=0?'+':'-', ROUND(virtvpxl/(double)RESOLUTION*1000.0),
+ ROUND(.5*d/RESOLUTION*1000.0),
+ 0,0,3,ENDCMD);
+ printf("%s00000%s00000%s", TAB, JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ virthpxl += d;
+ break;
+ case 'e': /* Ellipse */
+ /* Ellipses satisfy the equation (x^2)/(a^2)+(y^2)/(b^2)=1
+ * where 'a' is the length of the semimajor axis and 'b' is
+ * the length of the semiminor axis. We divide each quadrant
+ * into 200 line segments and connect the line segments.
+ */
+ a = getinteger(stdin) / 2.0 / RESOLUTION, /* In inches */
+ b = getinteger(stdin) / 2.0 / RESOLUTION;
+ center.x = virthpxl / (double)RESOLUTION + a,
+ center.y = virtvpxl / (double)RESOLUTION;
+ cur.x = a, cur.y = 0.0; /* cur and new are */
+ fputs(VECTORON, stdout); /* relative to the origin */
+ printf("%s03", PENWIDTH);
+ for (n = 1; n <= 200; n++, cur = new) {
+ new.x = a*cos((n/200.0)*(PI/2.0)),
+ new.y = b*sin((n/200.0)*(PI/2.0));
+ /* First quadrant */
+ printf("%s%05d:%05d", PENUP,
+ ROUND((center.x+cur.x)*1000.0),
+ ROUND((center.y+cur.y)*1000.0));
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND((center.x+new.x)*1000.0),
+ ROUND((center.y+new.y)*1000.0));
+ /* Second quadrant */
+ printf("%s%05d:%05d", PENUP,
+ ROUND((center.x-cur.x)*1000.0),
+ ROUND((center.y+cur.y)*1000.0));
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND((center.x-new.x)*1000.0),
+ ROUND((center.y+new.y)*1000.0));
+ /* Third quadrant */
+ printf("%s%05d:%05d", PENUP,
+ ROUND((center.x-cur.x)*1000.0),
+ ROUND((center.y-cur.y)*1000.0));
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND((center.x-new.x)*1000.0),
+ ROUND((center.y-new.y)*1000.0));
+ /* Fourth quadrant */
+ printf("%s%05d:%05d", PENUP,
+ ROUND((center.x+cur.x)*1000.0),
+ ROUND((center.y-cur.y)*1000.0));
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND((center.x+new.x)*1000.0),
+ ROUND((center.y-new.y)*1000.0));
+ }
+ fputs(VECTOROFF, stdout);
+ printf("%s00000%s00000\r", TAB, JUSTIFYMARGIN, ENDCMD);
+ virthpxl += ROUND(2.0 * a * RESOLUTION);
+ realhpxl = realvpxl = 0;
+ break;
+ case 'a': /* Arc */
+ start.x = virthpxl, start.y = virtvpxl;
+ center.x = virthpxl + getinteger(stdin), center.y = virtvpxl
+ + getinteger(stdin);
+ end.x = center.x + getinteger(stdin), end.y = center.y +
+ getinteger(stdin);
+ radius = sqrt(pow(start.x - center.x, 2.0) + pow(start.y -
+ center.y, 2.0));
+ /* Ditroff uses reverse cartesian coordinate system */
+ anglestart = atan2(start.x - center.x, center.y - start.y);
+ angleend = atan2(end.x - center.x, center.y - end.y);
+ anglestart -= PI / 2.0;
+ angleend -= PI / 2.0;
+ if (anglestart < 0)
+ anglestart += 2 * PI;
+ if (angleend < 0)
+ angleend += 2 * PI;
+ decimalanglestart = angleend / PI * 500.0;
+ decimalangleend = anglestart / PI * 500.0;
+ printf("%s%c%05d%c%05d%05d%03d%03d%02d%s", DECIMALARC,
+ center.x>0?'+':'-', ROUND(center.x/RESOLUTION*1000.0),
+ center.y>0?'+':'-', ROUND(center.y/RESOLUTION*1000.0),
+ ROUND(radius / RESOLUTION * 1000.0),
+ ROUND(decimalanglestart)>=1000?0:ROUND(decimalanglestart),
+ ROUND(decimalangleend)>=1000?0:ROUND(decimalangleend),
+ 3, ENDCMD);
+ printf("%s00000%s00000%s", TAB, JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ virthpxl = ROUND(end.x), virtvpxl = ROUND(end.y);
+ break;
+ case '~': /* Squiggly line */
+ (void)cgets(extension);
+ s = extension;
+ n = 0;
+ controlpoints[n][0] = virthpxl;
+ controlpoints[n][1] = virtvpxl;
+ controlpoints[n][2] = 0.0;
+ while (s = extractinteger(s, &c)) {
+ if (!(s = extractinteger(s, &d))) {
+ fprintf(stderr,
+ "%s: odd number of spline points given\n", Whoami);
+ break;
+ }
+ n++;
+ controlpoints[n][0] = controlpoints[n-1][0] + c;
+ controlpoints[n][1] = controlpoints[n-1][1] + d;
+ controlpoints[n][2] = 0.0; /* Ignore z axis */
+ }
+ spline(controlpoints, n, curvepoints, 499, 3); /* 2nd degree */
+ fputs(VECTORON, stdout);
+ printf("%s%05d:%05d", PENUP,
+ ROUND(curvepoints[0][0]/RESOLUTION*1000.0),
+ ROUND(curvepoints[0][1]/RESOLUTION*1000.0));
+ printf("%s03", PENWIDTH);
+ for (c = 1; c <= 499; c++)
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND(curvepoints[c][0]/RESOLUTION*1000.0),
+ ROUND(curvepoints[c][1]/RESOLUTION*1000.0));
+ fputs(VECTOROFF, stdout);
+ printf("%s00000%s00000%s\r", TAB, JUSTIFYMARGIN, ENDCMD);
+ virthpxl = ROUND(curvepoints[n][0]), virtvpxl =
+ ROUND(curvepoints[n][1]);
+ realhpxl = realvpxl = 0;
+ break;
+ default:
+ fprintf(stderr, "%s: invalid ditroff draw command %c\n",
+ Whoami, c);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+ break;
+ }
+ break;
+ case 'x': /* Device dependent commands */
+ switch (c = getnonblank(stdin)) {
+ case 'i': /* Init - do nothing */
+ while (!isspace(cgetchar())) /* Find next blank */
+ ;
+ break;
+ case 'T': /* Name of typesetter. -T option */
+ if (!EQ(DEVNAME, s = getstring(stdin))) {
+ fprintf(stderr,"%s: %s input given to ditroff filter\n",
+ Whoami, s);
+ cleanup(FontList, 2);
+ }
+ break;
+ case 'r': /* Resolution */
+ while (!isspace(getchar()))
+ ;
+ if (getinteger(stdin) != RESOLUTION) {
+ fprintf(stderr, "%s: ditroff input resolution != %d\n",
+ Whoami, RESOLUTION);
+ cleanup(FontList, 2);
+ }
+ /* Order of evaluation is immaterial */
+ if (getinteger(stdin) != 1 || getinteger(stdin) != 1) {
+ fprintf(stderr,
+ "%s: incorrect ditroff input increments\n", Whoami);
+ cleanup(FontList, 2);
+ }
+ break;
+ case 'p': /* Pause */
+ while (!isspace(cgetchar()))
+ ;
+ break;
+ case 's': /* Stop */
+ while ((c = getchar()) != EOF) /* Standard I/O getchar */
+ ;
+ callcleanup();
+ break;
+ case 't': /* Trailer */
+ while (!isspace(cgetchar()))
+ ;
+ break;
+ case 'f': /* Load font into mount table */
+ while (!isspace(cgetchar()))
+ ;
+ c = getinteger(stdin);
+ s = getstring(stdin);
+ (void)strcpy(MountTable[c], s);
+ /* The special font must be named S */
+ if (EQ(s, "S"))
+ specialfont = c;
+ if (!findpkfont(s, 10)) /* Just check for font, any size. */
+ fprintf(stderr,
+ "%s: could not find font %s at any magnification\n",
+ Whoami, s);
+ break;
+ case 'H': /* Height - QMS can't do */
+ while (!isspace(cgetchar()))
+ ;
+ (void)getinteger(stdin);
+ break;
+ case 'S': /* Slant - QMS can't do */
+ while (!isspace(cgetchar()))
+ ;
+ (void)getinteger(stdin);
+ break;
+ case 'X': /* Extensions */
+ (void)cgets(extension);
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl);
+ Pxxxstring = Xxxstring = extension;
+ Origin[0] = virthpxl, Origin[1] = virtvpxl;
+ (void)yyparse();
+ fputs(QUICON, stdout);
+ if (Orientation == 'P')
+ fputs(PORTRAIT, stdout);
+ else
+ fputs(LANDSCAPE, stdout);
+ printf("%s%c%c", TEXTPROC, '0', '0');
+ printf("%s00000%05d", INITMARGVERT, Orientation == 'P' ?
+ 11 * 1000 : (int)(8.5 * 1000));
+ printf("%s00000%05d", INITMARGHORZ, Orientation == 'P' ?
+ (int)(8.5 * 1000) : 11 * 1000);
+ printf("%s0000", CHARSPACING);
+ realhpxl = realvpxl = 0;
+ break;
+ default:
+ fprintf(stderr, "%s: invalid ditroff x command %c\n", Whoami,
+ c);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+ break;
+ }
+ break;
+ default:
+ fprintf(stderr, "%s: invalid ditroff command %c\n", Whoami, c);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+ break;
+ }
+ }
+}
+
+/* Returns a pointer to a node on the FontList with the matching name,
+ * pointsize and orientation or NULL if not found.
+ */
+struct FontNode *getnodebyname(head, name, ptsize, or)
+struct FontNode *head;
+char *name;
+int ptsize;
+int or;
+{
+ struct FontNode *p;
+
+ for (p = head; p; p = p->next)
+ if (p->localinfo && LI(p)->pointsize == ptsize && (p->flags & PORT
+ ? 'P' : 'L') == or && EQ(LI(p)->name, name))
+ return p;
+ return NULL;
+}
+
+/* Adds a new font to the font list. All the fields in the LocalInfo
+ * structure are filled in. If the font is loaded on startup, the blocksize
+ * is left as is; otherwise, the blocksize is estimated.
+ */
+struct FontNode *fonttolist(font, pointsize)
+char *font;
+int pointsize;
+{
+ long fontstructoffset; /* Offset at beginning of font structure */
+ long funnycharoffset;/* Offset before funny_char_index_table */
+ long ftell();
+ int qmsfontnum, mag, ds, i, c, fontindex, encodecompare();
+ short size, index;
+ char *fullfontpath, fontname[21], sfontname[21], *tail(), *malloc(),
+ descfilename[81], *findpkfont();
+ Boolean extractinfo();
+ void seteoffunction(), pkeofsocleanup(), desceofsocleanup(),
+ troffeofsocleanup();
+ FILE *f;
+ struct dev devheader;
+ struct font fontheader;
+ struct FontNode *fn, *getfontnode();
+ struct FontInfo *fi, *getfontinfo();
+
+ if (strlen(font) == 0 || pointsize == 0) /* One of the two has not */
+ return NULL; /* been filled in yet. */
+ /* If this works, we don't need to search the font directory */
+ if (fn = getnodebyname(FontList, font, pointsize, Orientation))
+ return fn;
+ if (!(fullfontpath = findpkfont(font, pointsize)))
+ return NULL; /* Try to continue */
+ qmsfontnum = getnumfromtable(tail(fullfontpath));
+ assert(qmsfontnum > 0);
+ if (!(fn = getfontnode(FontList, qmsfontnum, Orientation))) {
+ bzero((char *)(fn = (struct FontNode *)malloc((unsigned)
+ sizeof(struct FontNode))), sizeof(struct FontNode));
+ fn->next = FontList, FontList = fn;
+ }
+ if (fn->localinfo) /* This font is already on the list */
+ return fn;
+ else
+ bzero(fn->localinfo = malloc((unsigned)sizeof(struct LocalInfo)),
+ sizeof(struct LocalInfo));
+ fn->flags |= RAM;
+ if (Orientation == 'P')
+ fn->flags |= PORT;
+ fn->qmsnumber = qmsfontnum;
+ (void)strcpy(LI(fn)->name, font);
+ (void)strcpy(LI(fn)->pathname, fullfontpath);
+ (void)extractinfo(tail(LI(fn)->pathname), fontname, sfontname, &ds, &mag);
+ LI(fn)->pointsize = ROUND(mag / (double)RESOLUTION * UNITWIDTH);
+ (void)strcpy(EOFName, fullfontpath);
+ seteoffunction(pkeofsocleanup);
+ if (!(fi = getfontinfo(fullfontpath, (EQ(Model, "QMS800") ||
+ EQ(Model, "QMS1500")) && Orientation == 'P' || (!EQ(Model, "QMS800") &&
+ !EQ(Model, "QMS1500")) && Orientation == 'L' ? 'X' : 'Y'))) {
+ FontList = FontList->next; /* Bad PK file or not readable */
+ fprintf(stderr, "%s: could not open or bad PK file %s\n", Whoami,
+ fullfontpath);
+ free(fn->localinfo), free((char *)fn);
+ return NULL;
+ }
+ if (!(fn->flags & PRELOADED))
+ fn->blocksize = fi->blocksize;
+ seteoffunction(troffeofsocleanup);
+ LI(fn)->qmsheight = fi->qmsheight;
+ LI(fn)->qmsbaseline = fi->qmsbaseline;
+ for (i = 0; i < 256; i++) {
+ if (fi->chararray[i].tfm > 0 || (fi->chararray[i].w > 0 &&
+ fi->chararray[i].h > 0))
+ LI(fn)->charexists[i] = TRUE;
+ else
+ LI(fn)->charexists[i] = FALSE;
+ LI(fn)->widths[i] = ROUND(fi->chararray[i].tfm * ((fi->ds /
+ (double)FIX) / FIX) / PPI * RESOLUTION * ((double)LI(fn)->pointsize
+ / UNITWIDTH));
+ LI(fn)->bitmapsize[0][i] = fi->chararray[i].w;
+ LI(fn)->bitmapsize[1][i] = fi->chararray[i].h;
+ }
+ (void)sprintf(descfilename, "%s/%s", FONTDIR, "DESC.out");
+ LI(fn)->maptablesize = 0;
+ if (!(f = fopen(descfilename, "r"))) { /* Couldn't access DESC.out! */
+ static Boolean printed = FALSE;
+
+ if (!printed) { /* Only print error message once */
+ fprintf(stderr, "%s: could not open %s file \n", Whoami,
+ descfilename);
+ printed = TRUE;
+ }
+ return fn;
+ }
+ (void)strcpy(EOFName, descfilename);
+ seteoffunction(desceofsocleanup);
+ (void)cfread((char *)&devheader, sizeof(struct dev), 1, f);
+ (void)cfread((char *)&size, sizeof(short), 1, f);
+ while (size)
+ (void)cfread((char *)&size, sizeof(short), 1, f);
+ funnycharoffset = ftell(f);
+ assert(devheader.nchtab <= 160);
+ (void)fseek(f, (long)devheader.nchtab * sizeof(short) + devheader.lchname,
+ 1);
+ for (fontstructoffset = ftell(f); (i = fread((char *)&fontheader,
+ sizeof(struct font), 1, f)) == 1 && !EQ(LI(fn)->name, fontheader.namefont);
+ (void)fseek(f, 3L * fontheader.nwfont + 96 + devheader.nchtab, 1),
+ fontstructoffset = ftell(f))
+ ;
+ if (i != 1) { /* font not found */
+ (void)fclose(f);
+ seteoffunction(troffeofsocleanup);
+ return fn;
+ }
+ for (i = 0; i < devheader.nchtab; i++) {
+ (void)fseek(f, fontstructoffset + sizeof(struct font) + 3 *
+ fontheader.nwfont + 96 + i, 0);
+ if ((fontindex = cgetc(f)) == 0)
+ continue;
+ (void)fseek(f, funnycharoffset + i * sizeof(short), 0);
+ (void)cfread((char *)&index, sizeof(short), 1, f);
+ (void)fseek(f, funnycharoffset + devheader.nchtab * sizeof(short) +
+ index, 0);
+ /* The special strings are encoded, put in the maptable and
+ * sorted for fast lookup using a binary search. The encoding must
+ * preserve the uniqueness of the strings. Assuming special
+ * sequences are 3 bytes or less, we can put the bytes of the strings
+ * in the 3 low order bytes of the maptable[] word and use
+ * the high order byte to store the position in the font.
+ */
+ LI(fn)->maptable[LI(fn)->maptablesize] = 0;
+ while ((c = cgetc(f)) != '\0')
+ LI(fn)->maptable[LI(fn)->maptablesize] =
+ LI(fn)->maptable[LI(fn)->maptablesize] << 8 | c;
+ LI(fn)->maptable[LI(fn)->maptablesize] &= 0xFFFFFF;/*Keep low 3 bytes*/
+ (void)fseek(f, fontstructoffset + sizeof(struct font) + 2 *
+ fontheader.nwfont + fontindex, 0);
+ LI(fn)->maptable[LI(fn)->maptablesize] |= cgetc(f) << 24; /* Put font*/
+ LI(fn)->maptablesize++; /* pos in top byte */
+ }
+ (void)fclose(f);
+ seteoffunction(troffeofsocleanup);
+ qsort((char *)(LI(fn)->maptable), LI(fn)->maptablesize, sizeof(long),
+ encodecompare);
+ return fn;
+}
+
+/* Returns the full pathname of the font whose size most closely matches that
+ * passed as a parameter. Returns NULL if it can't open the directory or it
+ * cannot find the font at any magnification. The return value is static and
+ * overwritten with each call.
+ */
+char *findpkfont(fontname, pointsize)
+char *fontname;
+int pointsize;
+{
+ int closestnumber = MAX_INTEGER;
+ int desiredmagnification = ROUND(RESOLUTION * pointsize /
+ (double)UNITWIDTH);
+ static char returnvalue[101];
+ DIR *dirp;
+ struct direct *direntry;
+ char dirfname[81], dirsfname[81];
+ Boolean extractinfo();
+ int dirdsize, dirmag;
+
+ returnvalue[0] = '\0';
+ if (dirp = opendir(PKDir)) {
+ for (direntry = readdir(dirp); direntry; direntry = readdir(dirp)) {
+ if (direntry->d_namlen < 5 || !extractinfo(direntry->d_name,
+ dirfname, dirsfname, &dirdsize, &dirmag) || !EQ(dirfname,
+ fontname))
+ continue;
+ if (ABS(dirmag - desiredmagnification) < closestnumber) {
+ closestnumber = ABS(dirmag - desiredmagnification);
+ (void)sprintf(returnvalue, "%s/%s", PKDir,
+ direntry->d_name);
+ }
+ }
+ closedir(dirp);
+ }
+ if (strlen(returnvalue) > 0)
+ return returnvalue;
+ return NULL;
+}
+
+/* Adjusts printer coordinates so they correspond to ditroff's coordinates. It
+ * adjusts the real coordinates if necessary.
+ */
+void adjust(realh, realv, virth, virtv)
+int *realh, *realv, virth, virtv;
+{
+ if (*realh != virth) {
+ printf("%s%05d%s", TAB, ROUND(virth / (double)RESOLUTION * 1000.0),
+ ENDCMD);
+ *realh = virth;
+ }
+ if (*realv != virtv) {
+ printf("%s%05d%s", JUSTIFYMARGIN, ROUND(virtv / (double)RESOLUTION *
+ 1000.0), ENDCMD);
+ *realv = virtv;
+ }
+}
+
+/* Compares two encodings of troff special sequences */
+int encodecompare(one, two)
+long *one, *two;
+{
+ return (*one & 0xFFFFFF) == (*two & 0xFFFFFF) ? 0 : (*one & 0xFFFFFF)
+ < (*two & 0xFFFFFF) ? -1 : 1;
+}
+
+/* Looks up a special sequence in the maptable and returns the position
+ * found. It returns -1 if not found. This routine uses a binary search.
+ */
+int lookup(table, numvalues, key)
+long table[];
+int numvalues;
+char *key;
+{
+ int start = 0, end = numvalues - 1, midpoint;
+ long keyencoded; /* An encoded version of the key */
+ char *p;
+
+ for (p = key, keyencoded = 0; p && *p; p++)
+ keyencoded = (keyencoded << 8) | *p;
+ while (start <= end) {
+ midpoint = (start + end) / 2;
+ if ((keyencoded & 0xFFFFFF) == (table[midpoint] & 0xFFFFFF))
+ return midpoint;
+ if ((keyencoded & 0xFFFFFF) > (table[midpoint] & 0xFFFFFF))
+ start = midpoint + 1;
+ else
+ end = midpoint - 1;
+ }
+ return -1;
+}
+
+/* Downloads a font */
+Boolean download(fn)
+struct FontNode *fn;
+{
+ struct CharInfo *ci;
+ char *tail(), *strcpy();
+ void resetpkfile(), seteoffunction(),
+ downloadpkeofsocleanup(), troffeofsocleanup();
+ int downloadinterrupt(), callcleanup();
+ int downloadtype, result, i, truebyteswide, bytestooutput,
+ row, bytes;
+
+ if (!fn || fn->flags & LOADED || !(fn->flags & RAM) || (fn->flags & PORT ?
+ 'P' : 'L') != Orientation)
+ return FALSE;
+ resetpkfile();
+ downloadtype = ((EQ(Model, "QMS800") || EQ(Model, "QMS1500")) &&
+ Orientation == 'P' || (!EQ(Model, "QMS800") && !EQ(Model, "QMS1500"))
+ && Orientation == 'L' ? 'X' : 'Y');
+ DownLoadFNum = fn->qmsnumber;
+ (void)sigblock(SIGINT); /* Temporarily block interrupts */
+ SigStruct.sv_handler = downloadinterrupt;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ (void)strcpy(EOFName, LI(fn)->pathname);
+ seteoffunction(downloadpkeofsocleanup);
+ /* #defining ASCIILOAD causes ASCII characters to be used for the download
+ * sequence. Twice as many characters must be sent but it is useful for
+ * looking at the output when debugging. Also, you can actually see the
+ * bitmaps in the output. ASCII loading must be used when you can't get
+ * hardware flow control to work. Far out.
+ */
+#ifdef ASCIILOAD
+ fputs(FREEFORM, stdout);
+#else
+ fputs(EIGHTBITON, stdout);
+#endif
+ printf("%s%05d%c0%-4.4s%03d%03dT", DOWNLOAD, fn->qmsnumber, Orientation,
+ tail(LI(fn)->pathname), LI(fn)->qmsheight, LI(fn)->qmsbaseline);
+ (void)sigsetmask(sigblock(0) & ~SIGINT); /* Unblock interrupts */
+ while ((result = getnextcharinfo(LI(fn)->pathname, downloadtype, &ci)) !=
+ 1)
+ switch (result) {
+ case 2:
+ fprintf(stderr, "%s: could not open %s\n", Whoami,
+ LI(fn)->pathname);
+ return FALSE;
+ case 3:
+ fprintf(stderr, "%s: %s is not a PK file\n", Whoami,
+ LI(fn)->pathname);
+ return FALSE;
+ case 4:
+ fprintf(stderr, "%s: %s PK version is incorrect\n", Whoami,
+ LI(fn)->pathname);
+ return FALSE;
+ case 0: /* Ok. Got a bitmap */
+ if (ci->h == 0 || ci->w == 0)
+ continue;
+ putchar(',');
+ printf("%02X%03d", ci->cc, LI(fn)->widths[ci->cc]);
+ if (downloadtype == 'X') {
+ printf("%03d%03d", ci->h, ci->w);
+ printf("%c%03d", LI(fn)->qmsbaseline - ci->voff >= 0 ? '+'
+ : '-', ABS(LI(fn)->qmsbaseline - ci->voff));
+ printf("%c%03d", -ci->hoff >= 0 ? '+' : '-', ABS(-ci->hoff));
+ } else {
+ printf("%03d%03d", ci->w, ci->h);
+ printf("%c%03d", -ci->hoff >= 0 ? '+' : '-', ABS(ci->hoff));
+ printf("%c%03d", (LI(fn)->qmsheight - LI(fn)->qmsbaseline) -
+ (ci->h - ci->voff) >= 0 ? '+' : '-', ABS((LI(fn)->qmsheight
+ - LI(fn)->qmsbaseline) - (ci->h - ci->voff)));
+ i = ci->w, ci->w = ci->h, ci->h = i; /* Swaparoo! */
+ }
+ truebyteswide = ci->w + 7 >> 3; /* >> divides by 8 */
+ bytestooutput = (ci->w + 15 >> 4) * 2; /* >> divides by 16 */
+#ifdef ASCIILOAD
+ for (row = 0; row < ci->h; row++) {
+#else
+ for (row = 0; row < ci->h; row++)
+#endif
+ for (bytes = 0; bytes < bytestooutput; bytes++) {
+ if (bytes == truebyteswide - 1)
+ *(ci->bitmap + row * truebyteswide + bytes) &=
+ 0xFF<<7-(ci->w+7)%8;
+ if (bytes < truebyteswide) {
+ i = *(ci->bitmap + row * truebyteswide + bytes) &
+ 0xFF;
+#ifdef ASCIILOAD
+ printf("%c%c", "0123456789ABCDEF"[i >> 4],
+ "0123456789ABCDEF"[i & 0xF]);
+#else
+ if (i == '^')
+ printf("^^");
+ else
+ (void)putchar(i);
+#endif
+ } else
+#ifdef ASCIILOAD
+ printf("00");
+#else
+ (void)putchar(0);
+#endif
+ }
+#ifdef ASCIILOAD
+ putchar('\n');
+ }
+#endif
+ break;
+ } /* End switch */
+#ifdef ASCIILOAD
+ printf("%s%s", ENDCMD, FREEOFF);
+#else
+ printf("%s%s", ENDCMD, EIGHTBITOFF);
+#endif
+ putchar('\r'); /* Ends the pass */
+ (void)sigblock(SIGINT);
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ SigStruct.sv_handler = callcleanup;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ seteoffunction(troffeofsocleanup);
+ CurRamBlocks += fn->blocksize;
+ fn->flags |= LOADED;
+ (void)sigsetmask(sigblock(0) & ~SIGINT);
+ return TRUE;
+}
+
+/* The following are routines called when a SIGINT is received or EOF is
+ * unexpectedly encountered when reading a file.
+ */
+simplyexit()
+{
+ exit(SUCCEED);
+}
+
+callcleanup()
+{
+ void cleanup();
+
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, SUCCEED); /* Interrupting a program is not an error */
+}
+
+void troffeofsocleanup()
+{
+ fprintf(stderr, "%s: unexpected EOF when reading ditroff file\n", Whoami);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+}
+
+void pkeofsocleanup()
+{
+ fprintf(stderr, "%s: unexpected EOF when reading PK file %s\n", Whoami,
+ EOFName);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+}
+
+void desceofsocleanup()
+{
+ fprintf(stderr, "%s: unexpected EOF when reading DESC.out file %s\n",
+ Whoami, EOFName);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+}
+
+downloadinterrupt()
+{
+ fputs(ENDCMD, stdout);
+#ifdef ASCIILOAD
+ fputs(FREEOFF, stdout);
+#else
+ fputs(EIGHTBITOFF, stdout);
+#endif
+ printf("%s%05d%c%s", DOWNLOAD, DownLoadFNum, Orientation, ENDCMD);
+ callcleanup();
+}
+
+void downloadpkeofsocleanup()
+{
+ fputs(ENDCMD, stdout);
+#ifdef ASCIILOAD
+ fputs(FREEOFF, stdout);
+#else
+ fputs(EIGHTBITOFF, stdout);
+#endif
+ printf("%s%05d%c%s", DOWNLOAD, DownLoadFNum, Orientation, ENDCMD);
+ pkeofsocleanup();
+}
+
+#include "xxx.c"
diff --git a/dviware/quicspool/src/of.c b/dviware/quicspool/src/of.c
new file mode 100644
index 0000000000..9bb125fc7e
--- /dev/null
+++ b/dviware/quicspool/src/of.c
@@ -0,0 +1,271 @@
+/* "of" filter - prints banner page */
+#ifndef lint
+static char *rcs = "$Header: of.c,v 1.1 88/01/15 13:04:45 simpson Rel $";
+#endif
+/*
+$Log: of.c,v $
+ * Revision 1.1 88/01/15 13:04:45 simpson
+ * initial release
+ *
+ * Revision 0.2 87/12/22 15:50:06 simpson
+ * added pitch reset
+ *
+ * Revision 0.1 87/12/11 18:31:07 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <signal.h>
+#include <sgtty.h>
+#include <sys/file.h>
+#include <local/standard.h>
+#include <local/profile.h>
+#include <local/qms.h>
+
+static struct Speeds {
+ int speed;
+ int code;
+} Speeds[] = {
+ 50, B50,
+ 75, B75,
+ 110, B110,
+ 134, B134,
+ 300, B300,
+ 600, B600,
+ 1200, B1200,
+ 2400, B2400,
+ 4800, B4800,
+ 9600, B9600,
+ 19200, EXTA,
+ 0, 0
+};
+
+char *Whoami;
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ Boolean oinlist(), vinlist();
+ struct optnode *p;
+ struct qmsopc *opc;
+ void setoption(), qmsopcfree();
+ int c, fc, fs, xc, xs, br;
+ int portraitfont = 1204;
+ float portraitpitch = 12.0;
+ FILE *f;
+ char *readline, *queue, bp[1024];
+ PROFILE_VALUE *v, *class1, *class2, *class3, *class4,
+ *getbindingvalue();
+ struct sgttyb sgtty;
+
+ Whoami = argv[0];
+ while ((c = getopt(argc, argv, "w:l:")) != EOF)
+ switch (c) {
+ case 'w':
+ case 'l':
+ break;
+ case '?':
+ exit(2);
+ }
+ if ((v = getbindingvalue("portraitfont")) && v->class == PROFILE_INTEGER)
+ portraitfont = v->value.i;
+ if ((v = getbindingvalue("portraitpitch")) && (v->class == PROFILE_INTEGER
+ || v->class == PROFILE_FLOAT))
+ if (v->class == PROFILE_INTEGER)
+ portraitpitch = v->value.i;
+ else
+ portraitpitch = v->value.f;
+ class1 = getbindingvalue("class1");
+ class2 = getbindingvalue("class2");
+ class3 = getbindingvalue("class3");
+ class4 = getbindingvalue("class4");
+ if (!(v = getbindingvalue("readline")) || v->class != PROFILE_STRING &&
+ v->class != PROFILE_OTHER) {
+ fprintf(stderr,
+ "%s: missing or invalid readline binding in configuration file\n",
+ Whoami);
+ exit(2);
+ }
+#if defined(sun)
+ (void)flock(fileno(stdout), LOCK_EX);
+#endif
+ readline = v->value.s;
+ if (!(f = fopen(readline, "r"))) {
+ fprintf(stderr, "%s: cannot open read tty %s\n", Whoami, readline);
+ exit(2);
+ }
+ if (!(v = getbindingvalue("queuename")) || v->class != PROFILE_STRING
+ && v->class != PROFILE_OTHER) {
+ fprintf(stderr,
+ "%s: missing or invalid queuename binding in configuration file\n",
+ Whoami);
+ exit(2);
+ }
+ queue = v->value.s;
+ (void)ioctl(fileno(f), TIOCGETP, &sgtty);
+ if (pgetent(bp, queue) != 1) {
+ fprintf(stderr, "%s: can't find queue entry in printcap file!\n",
+ Whoami);
+ exit(2);
+ }
+ /* Set up the tty settings on the debugger port to be the same as the */
+ /* daughter board port, except use hardware flow control (DTR) on the */
+ /* daughter board port and software flow control (XON/XOFF) on the */
+ /* debugger port. Hardware flow control allows us to send ^S and ^Q */
+ /* to the QMS printer but since the debugger port simply passes */
+ /* through the data it receives, it cannot use hardware flow control */
+ /* and must use ^S/^Q. Set up the debugger port tty settings as in */
+ /* the /etc/printcap file but always turn TANDEM on and LMDMBUF off */
+ /* on the debugger port. */
+ if ((fc = tgetnum("fc")) != -1)
+ sgtty.sg_flags &= ~fc;
+ if ((fs = tgetnum("fs")) != -1)
+ sgtty.sg_flags |= fs;
+ sgtty.sg_flags |= RAW | TANDEM; /* Always! */
+ if ((br = tgetnum("br")) != -1)
+ sgtty.sg_ispeed = sgtty.sg_ospeed = convertspeed(br);
+ (void)ioctl(fileno(f), TIOCSETP, &sgtty);
+ if ((xs = tgetnum("xs")) != -1)
+ (void)ioctl(fileno(f), TIOCLBIS, &xs);
+ if ((xc = tgetnum("xc")) != -1)
+ (void)ioctl(fileno(f), TIOCLBIC, &xc);
+ c = LMDMBUF;
+ (void)ioctl(fileno(f), TIOCLBIC, &c); /* Always! */
+#ifdef pyr
+ /* Pyramid specific ioctls that must be set to get everything to */
+ /* really work. */
+ /* Use hardware flow control for the daughter board port. */
+#ifdef ASCIILOAD
+ c = 1;
+ (void)ioctl(fileno(stdout), TIOCHXON, &c);
+#else
+ c = 1;
+ (void)ioctl(fileno(stdout), TIOCHCTS, &c);
+#endif
+ /* Use software flow control for the debugger port. */
+ c = 2;
+ (void)ioctl(fileno(f), TIOCHXON, &c);
+#endif
+ if (!qmsopen(fileno(stdout), fileno(f))) {
+ fprintf(stderr, "%s: qmsopen() failed\n", Whoami);
+ exit(2);
+ }
+ if (!(opc = qmsopc())) {
+ fprintf(stderr, "%s: failed to read option class info\n", Whoami);
+ exit(2);
+ }
+ fputs(QUICON, stdout);
+ /* First turn off the option classes that should not be turned on */
+ for (p = opc->OC1; p; p = p->next)
+ if (!vinlist(class1, p->option))
+ setoption(1, p->option, FALSE);
+ for (p = opc->OC2; p; p = p->next)
+ if (!vinlist(class2, p->option))
+ setoption(2, p->option, FALSE);
+ for (p = opc->OC3; p; p = p->next)
+ if (!vinlist(class3, p->option))
+ setoption(3, p->option, FALSE);
+ for (p = opc->OC4; p; p = p->next)
+ if (!vinlist(class4, p->option))
+ setoption(4, p->option, FALSE);
+ /* Now enable the option classes that should be turned on */
+ for (v = class1; v; v = v->next)
+ if (v->class == PROFILE_INTEGER)
+ if (!oinlist(opc->OC1, (int)v->value.i))
+ setoption(1, (int)v->value.i, TRUE);
+ for (v = class2; v; v = v->next)
+ if (v->class == PROFILE_INTEGER)
+ if (!oinlist(opc->OC2, (int)v->value.i))
+ setoption(2, (int)v->value.i, TRUE);
+ for (v = class3; v; v = v->next)
+ if (v->class == PROFILE_INTEGER)
+ if (!oinlist(opc->OC3, (int)v->value.i))
+ setoption(3, (int)v->value.i, TRUE);
+ for (v = class4; v; v = v->next)
+ if (v->class == PROFILE_INTEGER)
+ if (!oinlist(opc->OC4, (int)v->value.i))
+ setoption(4, (int)v->value.i, TRUE);
+ fputs(PORTRAIT, stdout);
+ printf("%s00000", SYNTAX);
+ printf("%s%04d", LINESPACING, (int)(6.02 * 100));
+ printf("%s0000011000", INITMARGVERT);
+ printf("%s0025008500", INITMARGHORZ);
+ printf("%s%d%s", DEFFONT, portraitfont, ENDCMD);
+ printf("%s%04d", CHARSPACING, (int)(v->value.f * 100.0));
+ fputs(FREEOFF, stdout);
+ fputs(QUICOFF, stdout);
+ while ((c = getchar()) != EOF) {
+ if (c == '\n')
+ printf("\r\n");
+ else if (c == 031)
+ if ((c = getchar()) == '\1') {
+ fputs(QUICON, stdout);
+ printf("%s0000008500", INITMARGHORZ);
+ fputs(QUICOFF, stdout);
+ (void)fflush(stdout);
+ (void)kill(getpid(), SIGSTOP);
+ continue;
+ } else {
+ (void)putchar(031);
+ (void)ungetc(c, stdout);
+ }
+ else
+ (void)putchar(c);
+ }
+ qmsopcfree(opc);
+ qmsclose();
+#if defined(sun)
+ (void)flock(fileno(stdout), LOCK_UN);
+#endif
+ exit(SUCCEED);
+}
+
+/* Returns true if the option class number is set in the passed list */
+static Boolean oinlist(list, option)
+struct optnode *list;
+int option;
+{
+ for (; list; list = list->next)
+ if (list->option == option)
+ return TRUE;
+ return FALSE;
+}
+
+/* Returns true if option class number is set in the passed list */
+static Boolean vinlist(list, option)
+PROFILE_VALUE *list;
+int option;
+{
+ for (; list; list = list->next)
+ if (list->class == PROFILE_INTEGER && list->value.i == option)
+ return TRUE;
+ return FALSE;
+}
+
+/* Enables or disables an option */
+static void setoption(class, option, enable)
+int class;
+int option;
+int enable;
+{
+ if (class * 100 + option < 149 || 499 < class * 100 + option)
+ return;
+ printf("%s%s%d", PCONFIG, enable ? "" : ":", class * 100 + option);
+ fprintf(stderr, "%s: Warning: %s printer option (%d,%d)\n", Whoami,
+ enable ? "enabling" : "disabling", class, option);
+}
+
+/* Converts a baud rate from a number to the number you need to pass to
+ * ioctl(2).
+ */
+static int convertspeed(b)
+int b;
+{
+ struct Speeds *s;
+
+ for (s = Speeds; s->speed; s++)
+ if (s->speed == b)
+ return s->code;
+ return B9600;
+}
diff --git a/dviware/quicspool/src/pk.c b/dviware/quicspool/src/pk.c
new file mode 100644
index 0000000000..09d1b20866
--- /dev/null
+++ b/dviware/quicspool/src/pk.c
@@ -0,0 +1,475 @@
+#ifndef lint
+static char *rcs = "$Header: pk.c,v 1.1 88/01/15 13:04:52 simpson Rel $";
+#endif
+/*
+$Log: pk.c,v $
+ * Revision 1.1 88/01/15 13:04:52 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:31:09 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <assert.h>
+#include <local/standard.h>
+#include "constants.h"
+#include "fontinfo.h"
+#include "pk.h"
+
+/* Routines pertaining to PK files. */
+
+static int BitNumber; /* Count of bits read in a byte */
+static int Byte; /* Byte currently reading bits or nybbles from */
+static int RepeatCount; /* Count found during unpacking of packed number */
+
+/* Resets the bit count so bit and nybble reading start on a byte boundary. */
+static void resetbitcount()
+{
+ BitNumber = 0;
+}
+
+/* Returns the next nybble from the file. This routine uses the cgetc()
+ * function so an appropriate error routine will need to be set.
+ */
+static int getnyb(f)
+FILE *f;
+{
+ if (BitNumber == 0) {
+ Byte = cgetc(f);
+ BitNumber = 8;
+ }
+ if (BitNumber == 8) {
+ BitNumber -= 4;
+ return Byte >> 4 & 0xF;
+ } else {
+ BitNumber -= 4;
+ return Byte & 0xF;
+ }
+}
+
+/* Returns true if the next bit is on, false otherwise. This routine uses the
+ * cgetc() function so an appropriate error routine will need to be set.
+ */
+static Boolean getbit(f)
+FILE *f;
+{
+ if (BitNumber == 0) {
+ Byte = cgetc(f);
+ BitNumber = 8;
+ }
+ return Byte & 1 << --BitNumber ? TRUE : FALSE;
+}
+
+/* Returns the next packed number from the file f. The global variable
+ * RepeatCount is set appropriately if a repeat count is found. This routine
+ * uses the cgetc() function so an appropriate error routine will need to be
+ * set.
+ */
+static int pkpackednum(f, dynf)
+register FILE *f;
+register int dynf;
+{
+ register int i, j;
+
+ i = getnyb(f);
+ if (i == 0) {
+ do {
+ j = getnyb(f);
+ i++;
+ } while (j == 0);
+ while (i-- > 0)
+ j = (j << 4) + getnyb(f);
+ return j - 15 + ((13 - dynf) << 4) + dynf;
+ } else if (i <= dynf)
+ return i;
+ else if (i < 14)
+ return ((i - dynf - 1) << 4) + getnyb(f) + dynf + 1;
+ else {
+ if (i == 14)
+ RepeatCount = pkpackednum(f, dynf);
+ else
+ RepeatCount = 1;
+ return pkpackednum(f, dynf);
+ }
+ /* NOTREACHED */
+}
+
+/* Returns information about a PK file or NULL if it couldn't open the file
+ * or the file is an invalid PK file. The information returned is static and
+ * is overwritten with each call. Downloadtype should be 'X' or 'Y' (see the
+ * QMS Programming Manual). This function uses the cgetc() routine so an
+ * appropriate error recovery function should be set.
+ */
+struct FontInfo *getfontinfo(filename, downloadtype)
+char *filename;
+int downloadtype;
+{
+ unsigned long uinteger(), li, lk;
+ long integer(), pl, cc;
+ static struct FontInfo fi;
+ FILE *f;
+ int wordsneeded = 0, i, j, command, flag;
+ int heightstorage[256][2]; /* 0=h,1=voff f/each char*/
+ int largestvoff; /* Largest voff of all chars */
+
+ if (!(f = fopen(filename, "r")))
+ return NULL;
+ if (cgetc(f) != PKPRE || cgetc(f) != PKID) {
+ (void)fclose(f);
+ return NULL;
+ }
+ bzero((char *)&fi, sizeof(struct FontInfo));
+ bzero((char *)heightstorage, sizeof(heightstorage));
+ for (i = 0, j = cgetc(f); i < j; i++)
+ fi.comment[i] = cgetc(f);
+ fi.comment[i] = '\0';
+ fi.ds = integer(f, 4);
+ fi.cs = integer(f, 4);
+ fi.hppp = integer(f, 4);
+ fi.vppp = integer(f, 4);
+ fi.numchars = fi.qmsheight = largestvoff = 0;
+ while ((command = cgetc(f)) != PKPOST)
+ if (0 <= command && command <= 239) {
+ flag = command;
+ if ((flag & 0x7) == 0x7) { /* Long format preamble */
+ pl = integer(f, 4);
+ cc = integer(f, 4);
+ fi.chararray[cc].tfm = integer(f, 4);
+ fi.chararray[cc].dx = integer(f, 4);
+ fi.chararray[cc].dy = integer(f, 4);
+ fi.chararray[cc].w = integer(f, 4);
+ fi.chararray[cc].h = integer(f, 4);
+ fi.chararray[cc].hoff = integer(f, 4);
+ fi.chararray[cc].voff = integer(f, 4);
+ (void)fseek(f, pl - 28, 1);
+ } else if (0 <= (flag & 0x7) && (flag & 0x7) <= 3) { /* Short */
+ pl = cgetc(f) | (flag & 0x3) << 8;
+ cc = cgetc(f);
+ fi.chararray[cc].tfm = uinteger(f, 3);
+ fi.chararray[cc].dx = fi.chararray[cc].dy = cgetc(f) * SPOINT;
+ fi.chararray[cc].w = cgetc(f);
+ fi.chararray[cc].h = cgetc(f);
+ fi.chararray[cc].hoff = integer(f, 1);
+ fi.chararray[cc].voff = integer(f, 1);
+ (void)fseek(f, pl - 8, 1);
+ } else { /* Extended short form */
+ pl = uinteger(f, 2) | (flag & 0x3) << 16;
+ cc = cgetc(f);
+ fi.chararray[cc].tfm = uinteger(f, 3);
+ fi.chararray[cc].dx = fi.chararray[cc].dy = uinteger(f, 2)
+ * SPOINT;
+ fi.chararray[cc].w = uinteger(f, 2);
+ fi.chararray[cc].h = uinteger(f, 2);
+ fi.chararray[cc].hoff = integer(f, 2);
+ fi.chararray[cc].voff = integer(f, 2);
+ (void)fseek(f, pl - 13, 1);
+ }
+ assert(0 <= cc && cc <=255);
+ fi.numchars++;
+ fi.qmsheight = MAX(fi.qmsheight, fi.chararray[cc].h);
+ largestvoff = MAX(largestvoff, fi.chararray[cc].voff);
+ heightstorage[cc][0] = fi.chararray[cc].h;
+ heightstorage[cc][1] = fi.chararray[cc].voff;
+ if (downloadtype == 'Y')
+ wordsneeded += (int)((fi.chararray[cc].h + 15.0) / 16.0) *
+ fi.chararray[cc].w;
+ else
+ wordsneeded += (int)((fi.chararray[cc].w + 15.0) / 16.0) *
+ fi.chararray[cc].h;
+ } else
+ switch (command) {
+ case PKXXX1:
+ case PKXXX2:
+ case PKXXX3:
+ case PKXXX4:
+ for (li = 0, lk = uinteger(f, command - PKXXX1 + 1); li <
+ lk; li++)
+ (void)cgetc(f);
+ break;
+ case PKYYY:
+ (void)uinteger(f, 4);
+ break;
+ case PKNOOP:
+ break;
+ default:
+ (void)fclose(f);
+ return NULL;
+ }
+ wordsneeded += 800.0 / 2.0 + (fi.numchars * (14.0 + 12.0)) / 2.0;
+ fi.blocksize = CEILING((wordsneeded * 2.0) / 1024.0);
+ fi.qmsbaseline = largestvoff;
+ for (li = 0; li < 256; li++)
+ fi.qmsheight = MAX(fi.qmsheight, largestvoff + (heightstorage[li][0]
+ - heightstorage[li][1]));
+ (void)fclose(f);
+ return &fi;
+}
+
+/* This routine takes a PK font name and extracts the information
+ * contained in its naming convention. PK fonts are named like
+ * <font name><optional design size>.<magnification>pk. The first
+ * parameter is the font name. This is the only input parameter. The
+ * following output parameters are the name of the font (including the
+ * optional design size), the name of the font (without the design size),
+ * the design size and the magnification. For example, parameter
+ * cmr10.200pk would return the values
+ * fontname "cmr10"
+ * shortfontname "cmr"
+ * designsize 10
+ * magnification 200
+ * The function returns TRUE if it was successful parsing the name, FALSE
+ * otherwise. The designsize returned will be -1 if it is left out.
+ */
+Boolean extractinfo(fullfontname, fontname, shortfontname, designsize,
+magnification)
+char *fullfontname;
+char *fontname;
+char *shortfontname;
+int *designsize;
+int *magnification;
+{
+ char *p, *strcpy();
+
+ if (sscanf(fullfontname, "%[^0123456789.]", shortfontname) != 1)
+ return FALSE;
+ p = &fullfontname[strlen(shortfontname)];
+ if ('0' <= *p && *p <= '9') {
+ if (sscanf(p, "%d", designsize) != 1)
+ return FALSE;
+ while ('0' <= *p && *p <= '9')
+ p++;
+ } else
+ *designsize = -1;
+ if (*designsize != -1)
+ (void)sprintf(fontname, "%s%d", shortfontname, *designsize);
+ else
+ (void)strcpy(fontname, shortfontname);
+ if (*p != '.')
+ return FALSE;
+ else
+ p++;
+ if (sscanf(p, "%d", magnification) != 1)
+ return FALSE;
+ while ('0' <= *p && *p <= '9')
+ p++;
+ if (!EQ(p, "pk"))
+ return FALSE;
+ return TRUE;
+}
+
+static FILE *PkFilePtr; /* File pointer used in resetpkfile()
+ * and getnextcharinfo() */
+static struct CharInfo CInfo; /* Structure returned to the user */
+
+/* Resets the getnextcharinfo() function so it reopens the PK file */
+void resetpkfile()
+{
+ if (PkFilePtr) {
+ (void)fclose(PkFilePtr), PkFilePtr = NULL;
+ if (CInfo.bitmap)
+ free(CInfo.bitmap), CInfo.bitmap = NULL;
+ }
+}
+
+/* This function gets information on the next character in a font. If the
+ * font file is not already opened, it will open the font file. The
+ * downloadtype should be 'X' or 'Y'. The routine allocates and deallocates
+ * memory for the character bitmap itself, so you needn't worry about it.
+ * The filename parameter is only consulted when the routine is first called
+ * to get the information on the first character. If you wish to read from a
+ * new PK file, you must use the resetpkfile() function. The routine returns
+ * 0 on success, 1 if there are no more characters, 2 if the PK file could not
+ * be opened, 3 if the file is not a PK file and 4 if the PK version is
+ * incorrect. This routine calls the cgetc() function so the error routine
+ * should be set appropriately.
+ */
+int getnextcharinfo(filename, downloadtype, charinfo)
+char *filename;
+int downloadtype;
+struct CharInfo **charinfo;
+{
+ unsigned long uinteger();
+ char *malloc();
+ int command, flag, dynf, packednum;
+ long pl, li, lj, integer();
+ register Boolean black;
+ register char *bitmap, *rowmap, *putbyte;
+ register int i, j, k, currentw, currenth, mask;
+ register long w, h;
+
+ if (!PkFilePtr) {
+ if (!(PkFilePtr = fopen(filename, "r")))
+ return 2;
+ if (cgetc(PkFilePtr) != PKPRE) {
+ (void)fclose(PkFilePtr), PkFilePtr = NULL;
+ return 3;
+ }
+ if (cgetc(PkFilePtr) != PKID) {
+ (void)fclose(PkFilePtr), PkFilePtr = NULL;
+ return 4;
+ }
+ for (i = 0, j = cgetc(PkFilePtr); i < j; i++) /* Comment */
+ (void)cgetc(PkFilePtr);
+ (void)integer(PkFilePtr, 4); /* Design size */
+ (void)integer(PkFilePtr, 4); /* Checksum */
+ (void)integer(PkFilePtr, 4); /* hppp */
+ (void)integer(PkFilePtr, 4); /* vppp */
+ } else if (CInfo.bitmap)
+ free(CInfo.bitmap), CInfo.bitmap = NULL;
+tryagain:
+ if ((command = cgetc(PkFilePtr)) == PKPOST) { /* No more chars */
+ (void)fseek(PkFilePtr, -1L, 1); /* Back up by 1 byte */
+ return 1;
+ }
+ if (0 <= command && command <= 239) {
+ flag = command;
+ dynf = (flag & DYNF) >> 4;
+ if ((flag & 0x7) == 0x7) { /* Long format preamble */
+ CInfo.preambletype = plong;
+ pl = integer(PkFilePtr, 4);
+ CInfo.cc = integer(PkFilePtr, 4);
+ CInfo.tfm = integer(PkFilePtr, 4);
+ CInfo.dxordm = integer(PkFilePtr, 4);
+ CInfo.dy = integer(PkFilePtr, 4);
+ CInfo.w = integer(PkFilePtr, 4);
+ CInfo.h = integer(PkFilePtr, 4);
+ CInfo.hoff = integer(PkFilePtr, 4);
+ CInfo.voff = integer(PkFilePtr, 4);
+ if (CInfo.h == 0 || CInfo.w == 0)
+ (void)fseek(PkFilePtr, pl - 28L, 1);
+ } else if (0 <= (flag & 0x7) && (flag & 0x7) <= 3) { /* Short */
+ CInfo.preambletype = pshort;
+ pl = cgetc(PkFilePtr) | (flag & 0x3) << 8;
+ CInfo.cc = cgetc(PkFilePtr);
+ CInfo.tfm = uinteger(PkFilePtr, 3);
+ CInfo.dxordm = cgetc(PkFilePtr);
+ CInfo.w = cgetc(PkFilePtr);
+ CInfo.h = cgetc(PkFilePtr);
+ CInfo.hoff = integer(PkFilePtr, 1); /* integer() returns */
+ CInfo.voff = integer(PkFilePtr, 1); /* signed values */
+ if (CInfo.h == 0 || CInfo.w == 0)
+ (void)fseek(PkFilePtr, pl - 8L, 1);
+ } else { /* Extended short form */
+ CInfo.preambletype = pexshort;
+ pl = uinteger(PkFilePtr, 2) | (flag & 0x3) << 16;
+ CInfo.cc = cgetc(PkFilePtr);
+ CInfo.tfm = uinteger(PkFilePtr, 3);
+ CInfo.dxordm = uinteger(PkFilePtr, 2);
+ CInfo.w = uinteger(PkFilePtr, 2);
+ CInfo.h = uinteger(PkFilePtr, 2);
+ CInfo.hoff = integer(PkFilePtr, 2);
+ CInfo.voff = integer(PkFilePtr, 2);
+ if (CInfo.h == 0 || CInfo.w == 0)
+ (void)fseek(PkFilePtr, pl - 13L, 1);
+ }
+ assert(pl > 0);
+ assert(CInfo.h >= 0 && CInfo.w >= 0);
+ assert(0 <= CInfo.cc && CInfo.cc <= 255);
+ *charinfo = &CInfo;
+ h = CInfo.h, w = CInfo.w;
+ if (h == 0 || w == 0)
+ return 0;
+ if (downloadtype == 'X') {
+ /* Shifting right 3 divides by 8 faster than division */
+ bitmap = CInfo.bitmap = malloc((unsigned)((w+7>>3)*h));
+ if (dynf == 14) {
+ bzero(bitmap, (int)((w+7>>3)*h));
+ for (i = 0; i < h; i++)
+ for (j = 0; j < w; j++)
+ if (getbit(PkFilePtr))
+ *(bitmap + i*(w+7>>3) + (j>>3)) |= 1<<7-j%8;
+ } else { /* Get normally packed raster */
+ black = flag & BRUNCOUNT;
+ rowmap = malloc((unsigned)(w+7>>3));
+ bzero(rowmap,(int)(w+7>>3));
+ currenth = currentw = RepeatCount = 0;
+ while (currenth < h && currentw < w) {
+ packednum = pkpackednum(PkFilePtr, dynf);
+ for (i = 0; i < packednum; i++) {
+ if (black)
+ *(rowmap + (currentw>>3)) |= 1<<7-currentw%8;
+ if (++currentw == w) {
+ for (j = 0; j < RepeatCount + 1; j++)
+ bcopy(rowmap, bitmap + currenth++ * (w+7>>3),
+ (w+7>>3));
+ bzero(rowmap, (int)(w+7>>3));
+ currentw = RepeatCount = 0;
+ }
+ }
+ black = !black;
+ }
+ free(rowmap);
+ }
+ } else { /* Y orientation */
+ bitmap = CInfo.bitmap = malloc((unsigned)((h+7>>3)*w));
+ bzero(bitmap, (int)((h+7>>3)*w));
+ if (dynf == 14) { /* Get raster by bits */
+ for (i = 0; i < h; i++)
+ for (j = 0; j < w; j++)
+ if (getbit(PkFilePtr)) {
+ putbyte = bitmap + j*(h+7>>3) + (h-(i+1)>>3);
+ *putbyte |= 1<<7-((h+7)-i)%8;
+ }
+ } else { /* Get normally packed raster */
+ black = flag & BRUNCOUNT;
+ rowmap = malloc((unsigned)(w+7>>3));
+ bzero(rowmap, (int)(w+7>>3));
+ currenth = currentw = RepeatCount = 0;
+ while (currenth < h && currentw < w) {
+ packednum = pkpackednum(PkFilePtr, dynf);
+ for (i = 0; i < packednum; i++) {
+ if (black) {
+ *(rowmap + (currentw>>3)) |= 1<<7-currentw%8;
+ putbyte = bitmap + currentw*(h+7>>3)+
+ (h-(currenth+1)>>3);
+ *putbyte |= 1<<7-((h+7)-currenth)%8;
+ }
+ if (++currentw == w) {
+ currenth++;
+ for (j = 0; j < RepeatCount; j++) {
+ for (k = 0; k < w; k++) {
+ if (k % 8 == 0)
+ mask = 0x80;
+ else
+ mask >>= 1;
+ if (*(rowmap + (k>>3)) & mask) {
+ putbyte = bitmap + k*(h+7>>3) +
+ (h-(currenth+1)>>3);
+ *putbyte |= 1<<7-((h+7)-currenth)%8;
+ }
+ }
+ currenth++;
+ }
+ bzero(rowmap, (int)(w+7>>3));
+ currentw = RepeatCount = 0;
+ }
+ }
+ black = !black;
+ }
+ free(rowmap);
+ } /* End get normally packed raster */
+ } /* End Y orientation */
+ resetbitcount();
+ } else /* End of if (0 <= command && command <= 239) { */
+ switch (command) {
+ case PKXXX1:
+ case PKXXX2:
+ case PKXXX3:
+ case PKXXX4:
+ for (li = 0, lj = uinteger(PkFilePtr, command - PKXXX1 + 1);
+ li < lj; li++)
+ (void)cgetc(PkFilePtr);
+ goto tryagain;
+ case PKYYY:
+ (void)uinteger(PkFilePtr, 4);
+ goto tryagain;
+ default:
+#ifndef lint
+ assert(FALSE);
+#else
+ ;
+#endif
+ }
+ return 0;
+}
diff --git a/dviware/quicspool/src/pk.h b/dviware/quicspool/src/pk.h
new file mode 100644
index 0000000000..302f391a29
--- /dev/null
+++ b/dviware/quicspool/src/pk.h
@@ -0,0 +1,23 @@
+/* $Header: pk.h,v 1.1 88/01/15 13:04:56 simpson Rel $ */
+/*
+$Log: pk.h,v $
+ * Revision 1.1 88/01/15 13:04:56 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:31:10 simpson
+ * beta test
+ *
+*/
+#define PKXXX1 240
+#define PKXXX2 241
+#define PKXXX3 242
+#define PKXXX4 243
+#define PKYYY 244
+#define PKPOST 245
+#define PKNOOP 246
+#define PKPRE 247
+#define PKID 89
+/* Masks */
+#define DYNF 0xF0
+#define BRUNCOUNT 0x8 /* Black run count */
+#define TWOBYTE 0x4
diff --git a/dviware/quicspool/src/pktoch.c b/dviware/quicspool/src/pktoch.c
new file mode 100644
index 0000000000..510ebe91a2
--- /dev/null
+++ b/dviware/quicspool/src/pktoch.c
@@ -0,0 +1,100 @@
+#ifndef lint
+static char *rcs = "$Header: pktoch.c,v 1.1 88/01/15 13:04:58 simpson Rel $";
+#endif
+/*
+$Log: pktoch.c,v $
+ * Revision 1.1 88/01/15 13:04:58 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:31:11 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <local/standard.h>
+#include "fontinfo.h"
+
+char *Usage = "Usage: %s <pk-file> <chr-file>\n";
+char *WhoAmI;
+float Version = 1.0;
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ int c;
+ extern int optind;
+ void printrasters(), seteoffunction(), eofencountered();
+ FILE *output;
+ struct FontInfo *getfontinfo(), *fi;
+
+ WhoAmI = argv[0];
+ while ((c = getopt(argc, argv, "")) != EOF)
+ switch (c) {
+ case '?':
+err: fprintf(stderr, Usage, WhoAmI);
+ exit(FAIL);
+ }
+ if (optind != argc - 2)
+ goto err;
+ printf("This is PKtoCH, Version %.1f\n", Version);
+ seteoffunction(eofencountered);
+ if (!(fi = getfontinfo(argv[optind], 'X'))) {
+ fprintf(stderr, "%s: %s is not readable or is not a pk file\n",
+ WhoAmI, argv[optind]);
+ exit(FAIL);
+ }
+ if (!(output = fopen(argv[++optind], "w"))) {
+ fprintf(stderr, "%s: could not open %s\n", WhoAmI, argv[optind]);
+ exit(FAIL);
+ }
+ fputs("Font file info :", output);
+ fputs(fi->comment, output);
+ (void)putc('\n', output);
+ fprintf(output, "Design Size :%ld\n", fi->ds);
+ fprintf(output, "Checksum :%ld\n", fi->cs);
+ fprintf(output, "hppp :%ld\n", fi->hppp);
+ fprintf(output, "vppp :%ld\n", fi->vppp);
+ printrasters(argv[optind - 1], output);
+ (void)fclose(output);
+ printf("All done.\n");
+ exit(SUCCEED);
+}
+
+void printrasters(infile, output)
+char *infile;
+FILE *output;
+{
+ struct CharInfo *ci;
+ void printbitmap(), resetpkfile();
+
+ resetpkfile();
+ while (getnextcharinfo(infile, 'X', &ci) != 1) {
+ (void)putc('\f', output);
+ fprintf(output, "chrcode :");
+ if (' ' <= ci->cc && ci->cc <= '~')
+ fprintf(output, "'%c'\n", (int)ci->cc);
+ else
+ fprintf(output, "%ld\n", ci->cc);
+ fprintf(output, "tfm width :%ld\n", ci->tfm);
+ if (ci->preambletype == plong) {
+ fprintf(output, "dx :%ld\n", ci->dxordm);
+ fprintf(output, "dy :%ld\n", ci->dy);
+ } else
+ fprintf(output, "dm :%ld\n", ci->dxordm);
+ fprintf(output, "width :%ld\n", ci->w);
+ fprintf(output, "height :%ld\n", ci->h);
+ fprintf(output, "h offset :%ld\n", ci->hoff);
+ fprintf(output, "v offset :%ld\n", ci->voff);
+ fprintf(output, "+\n");
+ printbitmap(output, ci->bitmap, (int)ci->w, (int)ci->h);
+ }
+}
+
+void eofencountered()
+{
+ fprintf(stderr, "%s: premature eof encountered in PK file\n", WhoAmI);
+ exit(FAIL);
+}
+
+
diff --git a/dviware/quicspool/src/profile.c b/dviware/quicspool/src/profile.c
new file mode 100644
index 0000000000..7f6440c539
--- /dev/null
+++ b/dviware/quicspool/src/profile.c
@@ -0,0 +1,40 @@
+#ifndef lint
+static char *rcs = "$Header: profile.c,v 1.1 88/01/15 13:05:09 simpson Rel $";
+#endif
+/*
+$Log: profile.c,v $
+ * Revision 1.1 88/01/15 13:05:09 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:31:15 simpson
+ * beta test
+ *
+*/
+/* Profile(3) related routines */
+
+#include <stdio.h>
+#include <local/profile.h>
+
+/* Returns the value of a binding in the configuration stanza with the key
+ * equal to the formal parameter name. It returns NULL if unsuccessful.
+ */
+PROFILE_VALUE *getbindingvalue(key)
+char *key;
+{
+ FILE *config;
+ static PROFILE_STANZA *s;
+ PROFILE_BINDING *b;
+
+ if (!s)
+ if (config = fopen("configuration", "r")) {
+ if (!(s = profile_read_stanza(config))) {
+ (void)fclose(config);
+ return NULL;
+ }
+ (void)fclose(config);
+ } else
+ return NULL;
+ if (b = profile_has_binding(s, key))
+ return b->value;
+ return NULL;
+}
diff --git a/dviware/quicspool/src/qms.c b/dviware/quicspool/src/qms.c
new file mode 100644
index 0000000000..1159abef85
--- /dev/null
+++ b/dviware/quicspool/src/qms.c
@@ -0,0 +1,66 @@
+#ifndef lint
+static char *rcs = "$Header: qms.c,v 1.1 88/01/15 13:05:14 simpson Rel $";
+#endif
+/*
+$Log: qms.c,v $
+ * Revision 1.1 88/01/15 13:05:14 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:31:16 simpson
+ * beta test
+ *
+*/
+
+/* QMS printer routines */
+
+#include <stdio.h>
+#include <local/qms.h>
+#include "fontnode.h"
+
+
+/* Sets up the printer to portrait mode in a sane state. After the
+ * completion of a job, the banner page of the next job may be printed
+ * without running the "of" filter so we must setup the printer as the "of"
+ * filter does. Also, switch the tray offset in this routine. This
+ * routine is called before every filter exits.
+ */
+void sanestate(portfont)
+int portfont;
+{
+ fputs(QUICON, stdout);
+ fputs(PORTRAIT, stdout);
+ printf("%s00000", SYNTAX);
+ printf("%sXTX1", INITIALIZE);
+ printf("%s0000011000", INITMARGVERT);
+ printf("%s0025008500", INITMARGHORZ);
+ printf("%s%04d", LINESPACING, (int)(6.02 * 100));
+ printf("%s%d%s", DEFFONT, portfont, ENDCMD);
+ fputs(FREEOFF, stdout);
+}
+
+/* Trys to make room for numblocks. Return boolean if successful. */
+Boolean makeroom(head, maxblocks, curramblocks, curromblocks, numblocks)
+struct FontNode *head;
+int maxblocks;
+int *curramblocks; /* This one changes so pass by reference */
+int curromblocks;
+int numblocks;
+{
+ /* This is the number of blocks we need to free */
+ int freeblocks = numblocks - (maxblocks - *curramblocks
+ - curromblocks);
+ struct FontNode *p;
+
+ for (p = head; p && freeblocks > 0; p = p->next)
+ if (p->flags & RAM && p->flags & LOADED) { /* do ! delete rom fonts */
+ printf("%s%d%c%s", DOWNLOAD, p->qmsnumber, p->flags & PORT ? 'P'
+ : 'L', ENDCMD);
+ p->flags &= ~LOADED;
+ freeblocks -= p->blocksize;
+ *curramblocks -= p->blocksize;
+ }
+ if (freeblocks > 0)
+ return FALSE;
+ else
+ return TRUE;
+}
diff --git a/dviware/quicspool/src/qtroff.backup b/dviware/quicspool/src/qtroff.backup
new file mode 100644
index 0000000000..4d963ca231
--- /dev/null
+++ b/dviware/quicspool/src/qtroff.backup
@@ -0,0 +1,60 @@
+#! /bin/sh
+# $Header: qtroff.backup,v 1.1 88/01/15 13:05:19 simpson Rel $
+# $Log: qtroff.backup,v $
+#Revision 1.1 88/01/15 13:05:19 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 18:31:17 simpson
+#beta test
+#
+# Unfortunately it is necessary to use this script for otroff since the
+# troff macro file mount.nr must be read by otroff or the width tables in
+# --OFONT-- will not be read. Two -m (macro) options cannot be given
+# to otroff. If you could, we would name the macro file tmac.ount and use
+# the command
+# otroff -t -mount $* | lpr -t
+# We would still have to resolve the flags to otroff and lpr though.
+troffflags='-rv1 -t -F--OFONT--/ftXX'
+lprflags='-t'
+while [ $# -gt 0 ];do
+ case $1 in
+# Begin of otroff flags
+ -o* | -n* | -m* | -i | -q | -f | -b | -a | -p* | -F* | -z)
+ troffflags="$troffflags $1"
+ shift
+ ;;
+# Begin of lpr flags
+ -P* | -\#* | -w* | -l | -t | -d | -g | -v | -c | -r | -h | -s | -L)
+ lprflags="$lprflags $1"
+ shift
+ ;;
+ -C | -J | -1 | -2 | -3 | -4)
+ lprflags="$lprflags $1 $2"
+ shift; shift
+ ;;
+# Troff extension flags
+ -R*)
+ troffflags="$troffflags `echo $1|sed s/-R/-r/`"
+ shift
+ ;;
+# Lpr extension flags
+ -M)
+ lprflags="$lprflags -m"
+ shift
+ ;;
+# Any remaining flags go to troff
+ -*)
+ troffflags="$troffflags $1"
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+done
+if [ $# -eq 0 ]; then
+ readstdin=-i
+else
+ readstdin=
+fi
+otroff $readstdin $troffflags --FILTER--/mount.nr $* | glpr $lprflags
diff --git a/dviware/quicspool/src/quic.l b/dviware/quicspool/src/quic.l
new file mode 100644
index 0000000000..36d1709669
--- /dev/null
+++ b/dviware/quicspool/src/quic.l
@@ -0,0 +1,60 @@
+/* $Header: quic.l,v 1.1 88/01/15 13:05:21 simpson Rel $ */
+%{
+/*
+$Log: quic.l,v $
+ * Revision 1.1 88/01/15 13:05:21 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 21:37:40 simpson
+ * beta test
+ *
+*/
+/* Scans the data going by the "if" filter */
+%}
+%%
+\^P[YN]\^- {
+ QuicMode = (yytext[2] == 'Y' ? TRUE : FALSE);
+ if (QuicMode)
+ EnteredQuic = TRUE;
+ fputs(yytext, stdout);
+ }
+\^[OF] {
+ if (QuicMode)
+ FreeForm = (yytext[1] == 'F' ? TRUE : FALSE);
+ fputs(yytext, stdout);
+ }
+"^," {
+ if (QuicMode) {
+ NumPages++;
+ if (!Raw)
+ LineNum = 1;
+ }
+ fputs(yytext, stdout);
+ }
+\f {
+ if (!QuicMode || (QuicMode && !FreeForm))
+ NumPages++;
+ fputs(yytext, stdout);
+ }
+\n {
+ if (!Raw) {
+ putchar('\r');
+ if (++LineNum > Length) {
+ NumPages++;
+ LineNum -= Length;
+ }
+ CharCount = 1;
+ }
+ fputs(yytext, stdout);
+ }
+. {
+ short i;
+
+ if (!Raw) {
+ if (CharCount++ == 1 && Indent > 0)
+ for (i = 0; i < Indent; i++)
+ putchar(' ');
+ }
+ fputs(yytext, stdout);
+ }
+%%
diff --git a/dviware/quicspool/src/rf.c b/dviware/quicspool/src/rf.c
new file mode 100644
index 0000000000..0a67539ad8
--- /dev/null
+++ b/dviware/quicspool/src/rf.c
@@ -0,0 +1,163 @@
+/* Fortran filter */
+#ifndef lint
+static char *rcs = "$Header: rf.c,v 1.1 88/01/15 13:05:24 simpson Rel $";
+#endif
+/*
+$Log: rf.c,v $
+ * Revision 1.1 88/01/15 13:05:24 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:31:19 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <signal.h>
+#include <local/qms.h>
+#include <local/standard.h>
+#include <local/profile.h>
+#include "fontnode.h"
+
+char *Whoami; /* argv[0] */
+char Buffer[5001];
+int LineNum = 1;
+int Length, Width;
+int Indent = 0;
+int PortraitFont = 1204;
+int LandscapeFont = 1217;
+struct sigvec SigStruct;
+extern char *User;
+extern char *Host;
+extern Boolean Accounting;
+extern int NumPages;
+extern FILE *Accting;
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ extern int optind;
+ extern char *optarg;
+ PROFILE_VALUE *v, *getbindingvalue();
+ char *gets();
+ int c, i, callcleanup();
+ void sanestate(), cleanup();
+
+ Whoami = argv[0];
+ while ((c = getopt(argc, argv, "x:y:n:h:w:l:i:")) != EOF)
+ switch (c) {
+ case 'x':
+ case 'y':
+ break;
+ case 'i':
+ Indent = atoi(optarg);
+ break;
+ case 'l':
+ Length = atoi(optarg);
+ break;
+ case 'w':
+ Width = atoi(optarg);
+ break;
+ case 'n':
+ User = optarg;
+ break;
+ case 'h':
+ Host = optarg;
+ break;
+ case '?': /* This should not happen */
+ exit(2); /* Page intentionally left blank */
+ } /* Void where prohibited */
+ if (optind < argc) {
+ Accounting = TRUE;
+ if (!(Accting = fopen(argv[optind], "a"))) {
+ fprintf(stderr, "%s: cannot open accounting file %s\r\n", Whoami,
+ argv[optind]);
+ Accounting = FALSE;
+ }
+ }
+ if (Width > 80) {
+ if ((v = getbindingvalue("landscapefont")) && v->class ==
+ PROFILE_INTEGER)
+ LandscapeFont = v->value.i;
+ } else if ((v = getbindingvalue("portraitfont")) && v->class ==
+ PROFILE_INTEGER)
+ PortraitFont = v->value.i;
+ SigStruct.sv_handler = callcleanup;
+ SigStruct.sv_mask = 0;
+ SigStruct.sv_onstack = 0;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ fputs(QUICON, stdout);
+ fputs(Width > 80 ? LANDSCAPE : PORTRAIT, stdout);
+ printf("%s00000", SYNTAX);
+ printf("%s%05d%05d", INITMARGVERT, (int)(.22 * 1000), Width > 80 ?
+ (int)(8.5 * 1000) : 11 * 1000);
+ printf("%s%05d%05d", INITMARGHORZ, (int)(.325 * 1000), Width > 80 ? 11 *
+ 1000 : (int)(8.5 * 1000));
+ printf("%s%04d", LINESPACING, Width > 80 ? 8 * 100 : (int)(6.02 * 100));
+ printf("%s%d%s", DEFFONT, Width > 80 ? LandscapeFont : PortraitFont,
+ ENDCMD);
+ if (Width > 80) {
+ if ((v = getbindingvalue("landscapepitch")) && (v->class ==
+ PROFILE_INTEGER || v->class == PROFILE_FLOAT))
+ if (v->class == PROFILE_INTEGER)
+ printf("%s%04d", CHARSPACING, v->value.i * 100);
+ else
+ printf("%s%04d", CHARSPACING, (int)(v->value.f * 100));
+ } else
+ if ((v = getbindingvalue("portraitpitch")) && (v->class ==
+ PROFILE_INTEGER || v->class == PROFILE_FLOAT))
+ if (v->class == PROFILE_INTEGER)
+ printf("%s%04d", CHARSPACING, v->value.i * 100);
+ else
+ printf("%s%04d", CHARSPACING, (int)(v->value.f * 100));
+ fputs(FREEOFF, stdout);
+ fputs(QUICOFF, stdout);
+ while (gets(Buffer))
+ if (strlen(Buffer) > 0) {
+ switch (Buffer[0]) {
+ case '+':
+ (void)putchar('\r');
+ break;
+ case '1':
+ (void)putchar('\f');
+ NumPages++, LineNum = 1;
+ break;
+ case '0':
+ fputs("\r\n", stdout);
+ if (++LineNum > Length) {
+ LineNum -= Length;
+ NumPages++;
+ }
+ default:
+ fputs("\r\n", stdout);
+ if (++LineNum > Length) {
+ LineNum -= Length;
+ NumPages++;
+ }
+ break;
+ }
+ if (Indent > 0)
+ for (i = 0; i < Indent; i++)
+ putchar(' ');
+ fputs(&Buffer[1], stdout);
+ } else {
+ fputs("\r\n", stdout);
+ if (++LineNum > Length) {
+ LineNum -= Length;
+ NumPages++;
+ }
+ }
+ (void)sigblock(SIGINT);
+ fputs(QUICON, stdout);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup((struct FontNode *)NULL, SUCCEED);
+}
+
+callcleanup()
+{
+ void cleanup();
+
+ fputs(QUICON, stdout);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup((struct FontNode *)NULL, SUCCEED);
+}
diff --git a/dviware/quicspool/src/spline.c b/dviware/quicspool/src/spline.c
new file mode 100644
index 0000000000..73c319463c
--- /dev/null
+++ b/dviware/quicspool/src/spline.c
@@ -0,0 +1,75 @@
+#ifndef lint
+static char *rcs = "$Header: spline.c,v 1.1 88/01/15 13:05:27 simpson Rel $";
+#endif
+/*
+ * $Log: spline.c,v $
+ * Revision 1.1 88/01/15 13:05:27 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/18 11:20:40 simpson
+ * beta test
+ *
+ */
+#include <math.h>
+
+static double U[50];
+
+/* Returns a set of (m+1) spline curve points given a set of (n+1) control
+ * points. (t-1) is the degree of the polynomial used for the B-splines.
+ * Cubic polynomials (i.e., t=4) are usually sufficient. [3] designates
+ * (x,y,z). For a discussion of the spline curve algorithm, see the book
+ * ``Computer Graphics'', Donald Hearn and M. Pauline Baker, Prentice-Hall,
+ * 1986, pp. 200-2.
+ */
+void spline(controlpoints, n, curvepoints, m, t)
+double controlpoints[][3];
+int n;
+double curvepoints[][3];
+int m;
+int t;
+{
+ int j, k;
+ double N(), temp, u;
+
+ for (j = 0; j <= n + t; j++) {
+ if (j < t)
+ U[j] = 0.0;
+ else if (t <= j && j <= n)
+ U[j] = j - t + 1;
+ else
+ U[j] = n - t + 2;
+ }
+ for (j = 0; j <= m; j++) {
+ u = ((double)j / m)*(n-t+2-.00000001);
+ curvepoints[j][0] = curvepoints[j][1] = curvepoints[j][2] = 0.0;
+ for (k = 0; k <= n; k++) {
+ temp = N(k, t, u);
+ curvepoints[j][0] += controlpoints[k][0] * temp;
+ curvepoints[j][1] += controlpoints[k][1] * temp;
+ curvepoints[j][2] += controlpoints[k][2] * temp;
+ }
+ }
+}
+
+static double N(k, t, u)
+int k;
+int t;
+double u;
+{
+ double firstterm, secondterm;
+
+ if (t == 1)
+ if (U[k] <= u && u < U[k+1])
+ return 1.0;
+ else
+ return 0.0;
+ if (U[k+t-1]-U[k] < 1.0e-10) /* Test for zero with real #s */
+ firstterm = 0.0;
+ else
+ firstterm = ((u-U[k])/(U[k+t-1]-U[k]))*N(k,t-1,u);
+ if (U[k+t]-U[k+1] < 1.0e-10)
+ secondterm = 0.0;
+ else
+ secondterm = ((U[k+t]-u)/(U[k+t]-U[k+1]))*N(k+1,t-1,u);
+ return firstterm + secondterm;
+}
diff --git a/dviware/quicspool/src/stack.c b/dviware/quicspool/src/stack.c
new file mode 100644
index 0000000000..e9f168d7ad
--- /dev/null
+++ b/dviware/quicspool/src/stack.c
@@ -0,0 +1,75 @@
+#ifndef lint
+static char *rcs = "$Header: stack.c,v 1.1 88/01/15 13:05:28 simpson Rel $";
+#endif
+/*
+$Log: stack.c,v $
+ * Revision 1.1 88/01/15 13:05:28 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:31:20 simpson
+ * beta test
+ *
+*/
+
+/* Generalized stack manipulation routines. Routines provided are:
+ *
+ * char *push(p)
+ * char *p;
+ *
+ * Pushes the stack with the data in pointer p. Space is not allocated
+ * for the data; that is, the data is by reference. Consequently, you should
+ * not delete the data until you have popped it from the stack. A pointer to
+ * the passed data is returned. NULL is returned if memory could not be
+ * allocated to push the data. If the data passed is larger than
+ * elementsize, then only elementsize bytes will be copied. If it is
+ * smaller, you will probably get a segmentation violation.
+ *
+ * char *pop()
+ *
+ * Pops the stack and returns the popped value. If the stack is empty, NULL
+ * is returned.
+ *
+ * Implementation rationale: We don't copy data by value since we would have
+ * trouble popping the data. When we pop data, we want to free its space but
+ * we also want to return the data popped. We could store the data in a
+ * temporary buffer of the element size but it would get written over with
+ * every pop. Also, copying by value slows things down.
+ */
+#include <local/standard.h>
+#define NULL 0
+
+/* Represent the stack as a linked list of elements */
+static struct element {
+ char *data; /* Pointer to actual data */
+ struct element *next; /* Pointer to next element down */
+} *Head;
+
+/* Push the stack */
+char *push(data)
+char *data;
+{
+ struct element *p;
+ char *malloc();
+
+ if (!data || !(p = (struct element *)malloc((unsigned)sizeof(struct
+ element))))
+ return NULL;
+ p->next = Head, Head = p;
+ p->data = data;
+ return data;
+}
+
+/* Pop the stack */
+char *pop()
+{
+ char *p;
+ struct element *ep;
+
+ if (!Head)
+ return NULL;
+ p = Head->data;
+ ep = Head;
+ Head = Head->next;
+ free((char *)ep);
+ return p;
+}
diff --git a/dviware/quicspool/src/string.c b/dviware/quicspool/src/string.c
new file mode 100644
index 0000000000..7516631ca2
--- /dev/null
+++ b/dviware/quicspool/src/string.c
@@ -0,0 +1,177 @@
+#ifndef lint
+static char *rcs = "$Header: string.c,v 1.1 88/01/15 13:05:31 simpson Rel $";
+#endif
+/*
+$Log: string.c,v $
+ * Revision 1.1 88/01/15 13:05:31 simpson
+ * initial release
+ *
+ * Revision 0.2 87/12/18 11:35:41 simpson
+ * added extractinteger function
+ *
+ * Revision 0.1 87/12/11 18:31:21 simpson
+ * beta test
+ *
+*/
+
+/* String related routines */
+
+#include <stdio.h>
+#include <pwd.h>
+#include <local/standard.h>
+
+/* Return tail of a pathname (Ex: /usr/shar.c => shar.c) */
+char *tail(s)
+char *s;
+{
+ char *t;
+ char *rindex();
+
+ return((t = rindex(s, '/')) ? ++t : s);
+}
+
+/* Set a certain environment variable. If the variable is already set,
+ * it is reset.
+ */
+void setenv(variable, value)
+char *variable;
+char *value;
+{
+ extern char **environ;
+ int i;
+ char **p, **head, **hptr;
+ char *malloc(), *strcpy();
+ char temp[81];
+
+ if (!variable)
+ return;
+ for (i = 0, p = environ; *p; p++, i++)
+ ;
+ hptr = head = (char **)malloc((unsigned)((i + 2) * sizeof(char *)));
+ for (p = environ; *p; p++) {
+ (void)sprintf(temp, "%s=", variable);
+ if (EQN(temp, *p, strlen(temp)))
+ continue;
+ *hptr++ = *p;
+ }
+ if (!value)
+ (void)sprintf(temp, "%s=", variable);
+ else
+ (void)sprintf(temp, "%s=%s", variable, value);
+ (void)strcpy(*hptr++ = malloc((unsigned)(strlen(temp)+1)), temp);
+ *hptr = NULL;
+ environ = head;
+}
+
+/* Returns next component from a list of ':' separated fields such as that
+ * found in a $PATH variable. The return value is static and overwritten
+ * after each call. The passed string value is incremented to point to the
+ * next path. NULL is returned if there is no next component.
+ */
+char *nextcomponent(s)
+char **s;
+{
+ static char comp[81];
+ int i;
+
+ if (!s || !*s)
+ return NULL;
+ while (**s == ':')
+ ++*s;
+ if (**s == '\0')
+ return NULL;
+ for (i = 0; **s != ':' && **s != '\0'; ++*s, i++)
+ comp[i] = **s;
+ comp[i] = '\0';
+ return comp;
+}
+
+/* Returns an expanded file name. An expanded file name is a file name
+ * with a preceding ~ expanded. If a name is not given after the tilde,
+ * the current effective user id is used to look up the name and expand the
+ * file name.
+ */
+char *expandtilde(filename)
+char *filename;
+{
+ char pathname[81];
+ char name[81];
+ char *endptr, *index(), *strcpy(), *strncpy(), *strcat();
+ struct passwd *p;
+
+ if (!filename || strlen(filename) == 0 || filename[0] != '~')
+ return filename;
+ pathname[0] = '\0';
+ if (filename[1] == '\0' || filename[1] == '/') {
+ if (!(p = getpwuid(geteuid())))
+ return filename;
+ if (p->pw_dir)
+ (void)strcpy(pathname, p->pw_dir);
+ (void)strcat(pathname, &filename[1]);
+ } else {
+ if (!(endptr = index(&filename[1], '/')))
+ (void)strcpy(name, &filename[1]);
+ else
+ (void)strncpy(name, &filename[1], endptr - &filename[1]);
+ if (!(p = getpwnam(name)))
+ return filename;
+ if (p->pw_dir)
+ (void)strcpy(pathname, p->pw_dir);
+ (void)strcat(pathname, endptr);
+ }
+ (void)strcpy(filename, pathname);
+ return filename;
+}
+
+/* Returns and expanded file name. An expanded file name is a file name
+ * with a preceding $HOME expanded. For example, the file name
+ * "$HOME/.login" would be expanded to "/staff1/simpson/.login" if the
+ * current effective user id is that of simpson.
+ */
+char *expandhome(filename)
+char *filename;
+{
+ char s[80], *strcpy(), *strcat();
+ struct passwd *p;
+
+ if (!filename || strlen(filename) < 5 || !EQN(filename, "$HOME", 5))
+ return filename;
+ if (!(p = getpwuid(geteuid())))
+ return filename;
+ s[0] = '\0';
+ if (p->pw_dir)
+ (void)strcpy(s, p->pw_dir);
+ (void)strcat(s, &filename[5]);
+ (void)strcpy(filename, s);
+ return filename;
+}
+
+/* Returns the next integer contained in the string or NULL if no integers
+ * are left. The updated string pointer is returned.
+ */
+char *extractinteger(s, i)
+char *s;
+int *i;
+{
+ Boolean negative = FALSE;
+ char *p = s;
+
+ while (p && *p && (*p < '0' || *p > '9') && *p != '-')
+ p++;
+ if (!p || !*p)
+ return NULL;
+ if (*p == '-') {
+ negative = TRUE;
+ p++;
+ }
+ *i = 0;
+ if (*p < '0' || *p > '9')
+ return p;
+ do {
+ *i = *i * 10 + (*p - '0');
+ p++;
+ } while ('0' <= *p && *p <= '9');
+ if (negative)
+ *i = -*i;
+ return p;
+}
diff --git a/dviware/quicspool/src/table.c b/dviware/quicspool/src/table.c
new file mode 100644
index 0000000000..1c492f89f4
--- /dev/null
+++ b/dviware/quicspool/src/table.c
@@ -0,0 +1,89 @@
+#ifndef lint
+static char *rcs = "$Header: table.c,v 1.1 88/01/15 13:05:34 simpson Rel $";
+#endif
+/*
+$Log: table.c,v $
+ * Revision 1.1 88/01/15 13:05:34 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:31:22 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/dir.h>
+#include <local/standard.h>
+
+/* Routines for creating and querying the name table. The name table is a
+ * table of 2-tuples consisting of the name of a font and the font's
+ * corresponding QMS number.
+ */
+
+static char **NameTable;
+static int NameTableSize; /* Current size of name table */
+static int TableEntriesAllocated; /* # of entries allocated */
+static int BaseConstant; /* Base constant to start #s */
+
+/* Loads the names of all the fonts in the system font directory in the name
+ * array. A list of ROM font numbers is passed as an argument. This list
+ * is terminated by 0. Indices occupied by ROM fonts are not given a name.
+ * A base constant is also passed as a parameter. For example, TeX fonts are
+ * numbered 1-10000, inclusive, so the number 1 would be passed. Troff fonts
+ * are numbered 10001-20000 so the number 10001 would be passed. The
+ * routine returns TRUE on success, FALSE if the font directory could not be
+ * opened.
+ */
+Boolean loadnametable(directory, romlist, base)
+char *directory;
+int *romlist;
+int base;
+{
+ DIR *dirp;
+ struct direct *direntry;
+ int *p;
+ char *malloc(), *realloc(), *strcpy();
+
+
+ NameTableSize = 0, NameTable = NULL, BaseConstant = base;
+ if (!(dirp = opendir(directory)))
+ return FALSE;
+ for (direntry = readdir(dirp); direntry; direntry = readdir(dirp)) {
+ if (direntry->d_namlen < 5 || !EQ("pk", &direntry->d_name[
+ direntry->d_namlen - 2]))
+ continue;
+tryagain:if (++NameTableSize + 1 > TableEntriesAllocated)
+ if (!NameTable)
+ NameTable = (char **)malloc((unsigned)(TableEntriesAllocated =
+ 500) * sizeof(char *));
+ else
+ NameTable = (char **)realloc((char *)NameTable, (unsigned)
+ ((TableEntriesAllocated += 500) * sizeof(char *)));
+ if (NameTableSize > 10000)
+ return TRUE; /* Too many fonts, but don't give error */
+ for (p = romlist; p && *p; p++)
+ if (base - 1 + NameTableSize == *p) {
+ NameTable[NameTableSize] = NULL;
+ goto tryagain;
+ }
+ (void)strcpy(NameTable[NameTableSize] = malloc((unsigned)
+ (direntry->d_namlen + 1)), direntry->d_name);
+ }
+ closedir(dirp);
+ return TRUE;
+}
+
+/* Returns the QMS font number in the table NameTable. Returns -1 if not
+ * found
+ */
+int getnumfromtable(s)
+char *s;
+{
+ int i;
+
+ for (i = 1; i <= NameTableSize; i++)
+ if (NameTable[i])
+ if (EQ(NameTable[i], s))
+ return i + BaseConstant - 1;
+ return -1;
+}
diff --git a/dviware/quicspool/src/tf.c_backup b/dviware/quicspool/src/tf.c_backup
new file mode 100644
index 0000000000..c3b7897199
--- /dev/null
+++ b/dviware/quicspool/src/tf.c_backup
@@ -0,0 +1,953 @@
+/* Old troff driver */
+#ifndef lint
+static char *rcs = "$Header: tf.c.backup,v 1.2 88/02/03 08:52:30 simpson Exp $";
+#endif
+/*
+$Log: tf.c.backup,v $
+Revision 1.2 88/02/03 08:52:30 simpson
+added tpic support
+
+Revision 1.1 88/01/15 13:05:39 simpson
+initial release
+
+Revision 0.2 87/12/18 11:38:39 simpson
+added void for lint
+
+Revision 0.1 87/12/11 18:31:22 simpson
+beta test
+
+*/
+#include <stdio.h>
+#include <signal.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/dir.h>
+#include <local/standard.h>
+#include <local/qms.h>
+#include <local/profile.h>
+#include "fontnode.h"
+#include "fontinfo.h"
+#include "constants.h"
+
+#define FONTDIR "--FONTDIR--"
+/* Cast for accessing LocalInfo */
+#define LI(p) ((struct LocalInfo *)p->localinfo)
+
+#define TILT 1 /* 1 == down */
+#define RAIL 2 /* 1 == upper */
+#define MAGAZINE 4 /* 1 == upper */
+#define UPPERHALF 8 /* 1 == upper font half */
+#define ESCFORWARD 16
+#define LEADFORWARD 32
+
+struct LocalInfo {
+ char name[21]; /* Name of font */
+ int pointsize;
+ int qmsheight; /* Height to give QMS printer */
+ int qmsbaseline; /* Baseline height to give QMS printer */
+ char pathname[81]; /* Full pathname in file system */
+ short bitmapsize[2][256]; /* Width & height of each char bitmap */
+ int widths[256]; /* Width in HORCATRESes */
+};
+
+/* Old dumb troff only uses 4 fonts */
+char *Fonts[4] = {"R", "I", "B", "S"};
+char flags; /* ESCFORWARD,LEADFORWARD,UPPER,RAIL,MAGAZINE,TILT */
+char EOFName[101]; /* Used by pkeofsocleanup() */
+char *Whoami; /* argv[0] */
+char *Model; /* Model of printer being used */
+char Orientation = 'P';
+char PKDir[101]; /* Directory location of PK files */
+int MaxBlocks; /* # of free blocks w/out ram or rom fonts */
+int CurRamBlocks; /* # of blocks used by ram fonts */
+int CurRomBlocks; /* # of blocks used by rom fonts */
+int DownLoadFNum; /* Number of font currently being downloaded */
+FILE *ReadLine; /* Debugger port tty */
+struct sigvec SigStruct;
+struct FontNode *FontList; /* Contains all fonts and their attributes */
+extern char *Host, *User;
+extern FILE *Accting;
+extern Boolean Accounting;
+extern int NumPages;
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ Boolean found, loadnametable();
+ extern int optind;
+ extern char *optarg;
+ int *intptr, *tempintptr;
+ int c;
+ int romlist[41]; /* List of rom font #s */
+ int simplyexit(), callcleanup();
+ void qmsfntfree(), cleanup(), seteoffunction(), process(),
+ troffeofsocleanup(), adjust();
+ PROFILE_VALUE *v, *getbindingvalue();
+ struct qmsram *raminfo;
+ struct qmsfnt *fntinfo;
+ struct fontnode *p;
+ struct FontNode *createfontlist();
+#ifdef DEBUG
+ char *malloc(), orien;
+ int i, fontno, size;
+ FILE *f;
+ struct fontnode *fn;
+#endif
+
+ Whoami = argv[0];
+ while ((c = getopt(argc, argv, "x:y:n:h:w:l:i:")) != EOF)
+ switch (c) {
+ case 'x':
+ if (atoi(optarg) > 2550)
+ Orientation = 'L';
+ break;
+ case 'h':
+ Host = optarg;
+ break;
+ case 'n':
+ User = optarg;
+ break;
+ case 'y':
+ case 'w':
+ case 'l':
+ case 'i':
+ break;
+ default:
+ exit(2);
+ }
+ SigStruct.sv_handler = simplyexit;
+ SigStruct.sv_mask = 0;
+ SigStruct.sv_onstack = 0;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ if (optind < argc) {
+ Accounting = TRUE;
+ if (!(Accting = fopen(argv[optind], "a"))) {
+ fprintf(stderr, "%s: cannot open accounting file %s\n", Whoami,
+ argv[optind]);
+ Accounting = FALSE;
+ }
+ }
+ if (!(v = getbindingvalue("model")) || v->class != PROFILE_STRING &&
+ v->class != PROFILE_OTHER) {
+ fprintf(stderr,
+ "%s: model binding missing or invalid in configuration file\n",
+ Whoami);
+ exit(2);
+ }
+ Model = v->value.s;
+ fputs(QUICON, stdout);
+ printf("%s^Z%s%s", CLEAROVERLAY, CLEARAOVERLAY, ENDCMD);
+ fputs(QUICOFF, stdout);
+ (void)fflush(stdout);
+ if (!(v = getbindingvalue("readline")) || v->class != PROFILE_STRING &&
+ v->class != PROFILE_OTHER) {
+ fprintf(stderr,
+ "%s: readline binding missing or invalid in configuration file\n",
+ Whoami);
+ exit(2);
+ }
+ if (!(ReadLine = fopen(v->value.s, "r"))) {
+ fprintf(stderr, "%s: could not open %s for reading\n", Whoami,
+ v->value.s);
+ exit(2);
+ }
+#ifdef DEBUG
+ raminfo = (struct qmsram *)malloc((unsigned)sizeof(struct qmsram));
+ raminfo->TR = 401;
+ raminfo->AR = 387;
+ raminfo->FR = 13;
+ raminfo->OR = 0;
+#else
+ qmsopen(fileno(stdout), fileno(ReadLine));
+ if (!(raminfo = qmsram())) {
+ fprintf(stderr, "%s: could not get printer ram info\n", Whoami);
+ exit(2);
+ }
+#endif
+ MaxBlocks = raminfo->AR + raminfo->FR;
+ /* Save 5 blocks for filling with tpic */
+ MaxBlocks -= 5;
+#ifdef DEBUG
+ fntinfo = (struct qmsfnt *)malloc((unsigned)sizeof(struct qmsfnt));
+ fntinfo->ram = fntinfo->rom = NULL;
+ for (i = 0; i < 13; i++) {
+ switch (i) {
+ case 0:
+ fontno = 521;
+ orien = 'L';
+ break;
+ case 1:
+ fontno = 522;
+ orien = 'L';
+ break;
+ case 2:
+ fontno = 523;
+ orien = 'L';
+ break;
+ case 3:
+ fontno = 524;
+ orien = 'L';
+ break;
+ case 4:
+ fontno = 1100;
+ orien = 'P';
+ break;
+ case 5:
+ fontno = 1103;
+ orien = 'P';
+ break;
+ case 6:
+ fontno = 1200;
+ orien = 'P';
+ break;
+ case 7:
+ fontno = 1204;
+ orien = 'P';
+ break;
+ case 8:
+ fontno = 1217;
+ orien = 'L';
+ case 9:
+ fontno = 7009;
+ orien = 'P';
+ break;
+ case 10:
+ fontno = 7010;
+ orien = 'P';
+ break;
+ case 11:
+ fontno = 7036;
+ orien = 'P';
+ break;
+ case 12:
+ fontno = 7037;
+ orien = 'P';
+ break;
+ }
+ fn = (struct fontnode *)malloc((unsigned)sizeof(struct fontnode));
+ fn->next = fntinfo->rom, fntinfo->rom = fn;
+ fn->orientation = orien;
+ fn->number = fontno;
+ fn->bytes = 1024; /* Rom fonts occupy one block */
+ fn->version = '0';
+ fn->class = '1';
+ }
+ /* For testing, ramfonts contains the already loaded fonts. It should
+ * consist of lines containing two numbers and a letter, the first being
+ * the font number, the second being the font size, and the third letter
+ * is an orientation. The orientation should be the character immediately
+ * after the size of the font.
+ */
+ if (f = fopen("ramfonts", "r")) { /* File is optional for testing */
+ while (fscanf(f, "%d%d%c", &fontno, &size, &orien) == 3)
+ {
+ fn = (struct fontnode *)malloc((unsigned)sizeof(struct fontnode));
+ fn->next = fntinfo->ram, fntinfo->ram = fn;
+ fn->orientation = orien;
+ fn->number = fontno;
+ fn->bytes = size;
+ fn->version = '0';
+ fn->class = '1';
+ raminfo->AR -= CEILING(size / 1024.0);
+ raminfo->FR += CEILING(size / 1024.0);
+ }
+ (void)fclose(f);
+ }
+#else
+ if (!(fntinfo = qmsfnt())) {
+ fprintf(stderr, "%s: could not get printer font info\n", Whoami);
+ exit(2);
+ }
+#endif
+ for (CurRomBlocks = 0, p = fntinfo->rom; p; p = p->next)
+ CurRomBlocks += CEILING(p->bytes / (double)1024);
+ CurRamBlocks = raminfo->FR - CurRomBlocks;
+ /* Make an array of rom font #s */
+ for (p = fntinfo->rom, intptr = romlist; p; p = p->next) {
+ for (tempintptr = romlist, found = FALSE; tempintptr < intptr;
+ tempintptr++)
+ if (*tempintptr == p->number)
+ found = TRUE;
+ if (!found)
+ *intptr++ = p->number;
+ }
+ *intptr = 0;
+ if (EQ(Model, "QMS800"))
+ (void)sprintf(PKDir, "%s/wbfonts", FONTDIR);
+ else
+ (void)sprintf(PKDir, "%s/wwfonts", FONTDIR);
+ if (!loadnametable(PKDir, romlist, 10001)) {
+ fprintf(stderr, "%s: could not open font directory %s\n", Whoami,
+ PKDir);
+ exit(2);
+ }
+ FontList = createfontlist(fntinfo);
+ qmsfntfree(fntinfo);
+ SigStruct.sv_handler = callcleanup;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ fputs(QUICON, stdout);
+ if (Orientation == 'P')
+ fputs(PORTRAIT, stdout);
+ else
+ fputs(LANDSCAPE, stdout);
+ printf("%s%c%c", TEXTPROC, '0', '0');
+ printf("%s00000%05d", INITMARGVERT, Orientation == 'P' ? 11 * 1000 :
+ (int)(8.5 * 1000));
+ printf("%s00000%05d", INITMARGHORZ, Orientation == 'P' ? (int)(8.5 * 1000)
+ : 11 * 1000);
+ printf("%s0000", CHARSPACING);
+ fputs(FREEOFF, stdout);
+ seteoffunction(troffeofsocleanup);
+ process();
+ cleanup(FontList, SUCCEED);
+}
+
+/* Main routine that interprets the troff file */
+void process()
+{
+ struct FontNode *curnode= NULL; /* Current font troff has selected */
+ struct FontNode *fonttolist();
+ int curfont = 0; /* Current font selected in Fonts */
+ int curptsize = 10; /* Current pt size selected */
+ int c, d;
+ int realhpxl, realvpxl; /* Real pixel locations */
+ int virthpxl, virtvpxl; /* Virtual pixel locations */
+ int h; /* In HORCATRES */
+ int v; /* In VERCATRES */
+ Boolean single = TRUE; /* Doubler lens */
+ Boolean fontselected = FALSE, download(), makeroom();
+ /* The first escape and lead are skipped since this sets up the machine */
+ Boolean skipesc = TRUE, skiplead = TRUE;
+ /* Keep track of whether we have printed on the page because the C/A/T */
+ /* does a lot of leads at the end of a job. */
+ Boolean printedonpage = FALSE;
+ int blankpagecount = 0;
+ extern char RegularToAscii[], SpecialToAscii[];
+ void endoflist();
+
+ h = v = realhpxl = realvpxl = virthpxl = virtvpxl = 0;
+ while (TRUE) { /* A non-returning function is called to exit. */
+ c = cgetchar();
+ if (c == 0) /* Ignore nulls */
+ continue;
+ if (c == 0xFF) { /* Alls 1s is an error */
+ fprintf(stderr, "%s: invalid troff command 0xFF\n", Whoami);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+ }
+ virthpxl = ROUND(h / (double)HORCATRES * RESOLUTION);
+ virtvpxl = ROUND(v / (double)VERCATRES * RESOLUTION);
+ if (c & 0x80) { /* Escape code */
+ if (skipesc)
+ skipesc = FALSE;
+ else {
+ d = (c ^ 0x7F) & 0x7F;
+ if (flags & ESCFORWARD)
+ h += d;
+ else
+ h -= d;
+ }
+ continue;
+ }
+ if (c & 0x40) { /* Control code */
+ if (c & 0x20) { /* Lead code */
+ if (skiplead)
+ skiplead = FALSE;
+ else {
+ d = (c ^ 0x1F) & 0x1F;
+ if (flags & LEADFORWARD)
+ v += d;
+ else
+ v -= d;
+ /* The C/A/T formfeeds by running off the page! Well, the
+ * the C/A/T uses (used?) continuous roll paper so this is
+ * not as crazy as it sounds.
+ */
+ if (v > ROUND((Orientation == 'P' ? 11 : 8.5) * VERCATRES))
+ {
+ v -= ROUND((Orientation == 'P' ? 11 : 8.5) * VERCATRES
+ );
+ if (printedonpage) {
+ realhpxl = realvpxl = 0;
+ fputs(FORMFEED, stdout), NumPages++;
+ printedonpage = FALSE;
+ } else
+ blankpagecount++; /* Ignore at end of job but */
+ } /* not in between */
+ }
+ continue;
+ }
+ if (c & 0x10) { /* Size change */
+ switch (c & 0xF) {
+ case 0:
+ if (!single)
+ h += 55;
+ single = TRUE;
+ curptsize = 7;
+ break;
+ case 1:
+ if (!single)
+ h += 55;
+ single = TRUE;
+ curptsize = 8;
+ break;
+ case 2:
+ if (!single)
+ h += 55;
+ single = TRUE;
+ curptsize = 10;
+ break;
+ case 3:
+ if (!single)
+ h += 55;
+ single = TRUE;
+ curptsize = 11;
+ break;
+ case 4:
+ if (!single)
+ h += 55;
+ single = TRUE;
+ curptsize = 12;
+ break;
+ case 5:
+ if (!single)
+ h += 55;
+ single = TRUE;
+ curptsize = 14;
+ break;
+ case 6:
+ if (!single)
+ h += 55;
+ single = TRUE;
+ curptsize = 18;
+ break;
+ case 7:
+ if (!single)
+ h += 55;
+ single = TRUE;
+ curptsize = 9;
+ break;
+ case 8:
+ if (!single)
+ h += 55;
+ single = TRUE;
+ curptsize = 6;
+ break;
+ case 9:
+ if (single)
+ h -= 55;
+ single = FALSE;
+ curptsize = 16;
+ break;
+ case 10:
+ if (single)
+ h -= 55;
+ single = FALSE;
+ curptsize = 20;
+ break;
+ case 11:
+ if (single)
+ h -= 55;
+ single = FALSE;
+ curptsize = 22;
+ break;
+ case 12:
+ if (single)
+ h -= 55;
+ single = FALSE;
+ curptsize = 24;
+ break;
+ case 13:
+ if (single)
+ h -= 55;
+ single = FALSE;
+ curptsize = 28;
+ break;
+ case 14:
+ if (single)
+ h -= 55;
+ single = FALSE;
+ curptsize = 36;
+ break;
+ case 15:
+ fprintf(stderr, "%s: invalid otroff size change 0x5F\n",
+ Whoami);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+ }
+ curnode = fonttolist(Fonts[curfont], curptsize);
+ endoflist(&FontList, curnode);
+ fontselected = FALSE;
+ putchar('\r'); /* Ends the pass */
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ continue;
+ }
+ switch (c & 0xF) { /* Control code command */
+ case 0x0: /* Initialize */
+ flags |= ESCFORWARD | LEADFORWARD | TILT;
+ flags &= ~(MAGAZINE | RAIL | UPPERHALF);
+ break;
+ case 0x9: /* Stop */
+ while (getchar() != EOF)
+ ; /* Consume rest of input */
+ if (printedonpage)
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, SUCCEED);
+ case 0x2: /* Upper rail */
+ flags |= RAIL;
+ goto reloadfont;
+ case 0x1: /* Lower rail */
+ flags &= ~RAIL;
+ goto reloadfont;
+ case 0x3: /* Upper magazine */
+ flags |= MAGAZINE;
+ goto reloadfont;
+ case 0x4: /* Lower magazine */
+ flags &= ~MAGAZINE;
+reloadfont: curfont = flags >> 1 & 0x3; /* Ignore tilt */
+ curnode = fonttolist(Fonts[curfont], curptsize);
+ endoflist(&FontList, curnode);
+ fontselected = FALSE;
+ putchar('\r'); /* Ends the pass */
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ realhpxl = realvpxl = 0;
+ break;
+ case 0xE: /* Tilt up */
+ break; /* No op */
+ case 0xF: /* Tilt down */
+ break; /* No op */
+ case 0x6: /* Upper font half */
+ flags |= UPPERHALF;
+ break;
+ case 0x5: /* Lower font half */
+ flags &= ~UPPERHALF;
+ break;
+ case 0x7:
+ flags |= ESCFORWARD; /* Escape forward */
+ break;
+ case 0x8:
+ flags &= ~ESCFORWARD; /* Escape backward */
+ break;
+ case 0xA: /* Lead forward */
+ flags |= LEADFORWARD;
+ break;
+ case 0xC: /* Lead backward */
+ flags &= ~LEADFORWARD;
+ break;
+ case 0xB: /* Extension */
+ switch (c = cgetchar()) {
+ case 1: /* Big lead */
+ if (flags & LEADFORWARD)
+ v += 64 * cgetchar();
+ else
+ v -= 64 * cgetchar();
+ break;
+ case 2: /* Big escape */
+ if (flags & ESCFORWARD)
+ h += 128 * cgetchar();
+ else
+ h -= 128 * cgetchar();
+ break;
+ case 3: /* Formfeed */
+ fputs(FORMFEED, stdout), NumPages++;
+ realhpxl = realvpxl = 0;
+ printedonpage = FALSE;
+ break;
+ }
+ break;
+ case 0xD: /* Error! */
+ fprintf(stderr, "%s: illegal otroff command 0x4D\n", Whoami);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+ }
+ continue;
+ }
+ d = c & 0x3F; /* Flash code */
+ printedonpage = TRUE;
+ if (blankpagecount > 0) {
+ for (c = 0; c < blankpagecount; c++)
+ fputs(FORMFEED, stdout), NumPages++;
+ blankpagecount = 0;
+ }
+ if (d > 45 && flags & UPPERHALF) {
+ fprintf(stderr, "%s: illegal otroff flash code %d\n", Whoami,
+ d);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+ }
+ if (flags & UPPERHALF)
+ d += 64;
+ d = (curfont == 3 ? SpecialToAscii[d] : RegularToAscii[d]);
+ if (d == 0) /* Character not used */
+ continue;
+ /* If we couldn't find the font, don't anything since we don't know
+ * how to increment the real pixel locations.
+ */
+ if (!curnode || !curnode->localinfo)
+ continue;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ if (!(curnode->flags & LOADED)) {
+ if (!makeroom(FontList, MaxBlocks, &CurRamBlocks, CurRomBlocks,
+ curnode->blocksize)) {
+ fprintf(stderr,
+ "%s: could not free %d blocks for font %s\n", Whoami,
+ curnode->blocksize, LI(curnode)->pathname);
+ goto trytocontinue;
+ }
+ if (!download(curnode))
+ goto trytocontinue;
+ realhpxl = realvpxl = 0;
+ adjust(&realhpxl, &realvpxl, virthpxl, virtvpxl, h, v);
+ }
+ if (!fontselected) {
+ printf("%s%d%s", DEFFONT, curnode->qmsnumber, ENDCMD);
+ fontselected = TRUE;
+ }
+ /* For fonts with width but no bitmap, check the size of the
+ * raster. The QMS will print (or download) a character with width
+ * and no bitmap so we must not print characters that are not in the
+ * font. If you do, you will get the lowest character in the font.
+ */
+trytocontinue:
+ if (LI(curnode)->bitmapsize[0][d] != 0 && LI(curnode)->bitmapsize[1][d]
+ != 0) {
+ if (d == '^' || d <= 32 || d >= 127)
+ printf("%s%02X", SPECIAL, d);
+ else
+ (void)putchar(d);
+ realhpxl += ROUND(LI(curnode)->widths[d] / (double)HORCATRES *
+ RESOLUTION);
+ }
+ }
+}
+
+/* Adjusts printer coordinates so they correspond to otroff's coordinates. It
+ * adjusts the real coordinates if necessary.
+ */
+void adjust(realh, realv, virth, virtv, h, v)
+int *realh, *realv, virth, virtv, h, v;
+{
+ if (*realh != virth) {
+ printf("%s%05d%s", TAB, ROUND(h / (double)HORCATRES * 1000.0),
+ ENDCMD);
+ *realh = virth;
+ }
+ if (*realv != virtv) {
+ printf("%s%05d%s", JUSTIFYMARGIN, ROUND(v / (double)VERCATRES *
+ 1000.0), ENDCMD);
+ *realv = virtv;
+ }
+}
+
+/* Returns a pointer to a node on the FontList with the matching name,
+ * pointsize and orientation or NULL if not found.
+ */
+struct FontNode *getnodebyname(head, name, ptsize, or)
+struct FontNode *head;
+char *name;
+int ptsize;
+int or;
+{
+ struct FontNode *p;
+
+ for (p = head; p; p = p->next)
+ if (p->localinfo && LI(p)->pointsize == ptsize && (p->flags & PORT
+ ? 'P' : 'L') == or && EQ(LI(p)->name, name))
+ return p;
+ return NULL;
+}
+
+/* Returns the full pathname of the font whose size most closely matches that
+ * passed as a parameter. Returns NULL if it can't open the directory or it
+ * cannot find the font at any magnification. The return value is static and
+ * overwritten with each call.
+ */
+char *findpkfont(fontname, pointsize)
+char *fontname;
+int pointsize;
+{
+ int closestnumber = MAX_INTEGER;
+ int desiredmagnification = ROUND(RESOLUTION * pointsize/10.0);
+ static char returnvalue[101];
+ DIR *dirp;
+ struct direct *direntry;
+ char dirfname[81], dirsfname[81];
+ Boolean extractinfo();
+ int dirdsize, dirmag;
+
+ returnvalue[0] = '\0';
+ if (dirp = opendir(PKDir)) {
+ for (direntry = readdir(dirp); direntry; direntry = readdir(dirp)) {
+ if (direntry->d_namlen < 5 || !extractinfo(direntry->d_name,
+ dirfname, dirsfname, &dirdsize, &dirmag) || !EQ(dirfname,
+ fontname))
+ continue;
+ if (ABS(dirmag - desiredmagnification) < closestnumber) {
+ closestnumber = ABS(dirmag - desiredmagnification);
+ (void)sprintf(returnvalue, "%s/%s", PKDir,
+ direntry->d_name);
+ }
+ }
+ closedir(dirp);
+ }
+ if (strlen(returnvalue) > 0)
+ return returnvalue;
+ return NULL;
+}
+
+/* Adds a new font to the font list. All the fields in the LocalInfo
+ * structure are filled in. If the font is loaded on startup, the blocksize
+ * is left as is; otherwise, the blocksize is estimated.
+ */
+struct FontNode *fonttolist(font, pointsize)
+char *font;
+int pointsize;
+{
+ int qmsfontnum, mag, ds, i;
+ char *fullfontpath, fontname[21], sfontname[21], *tail(), *malloc(),
+ *findpkfont(), *strcpy();
+ Boolean extractinfo();
+ void seteoffunction(), pkeofsocleanup(), desceofsocleanup(),
+ troffeofsocleanup();
+ struct FontNode *fn, *getfontnode();
+ struct FontInfo *fi, *getfontinfo();
+
+ if (strlen(font) == 0 || pointsize == 0) /* One of the two has not */
+ return NULL; /* been filled in yet. */
+ /* If this works, we don't need to search the font directory */
+ if (fn = getnodebyname(FontList, font, pointsize, Orientation))
+ return fn;
+ if (!(fullfontpath = findpkfont(font, pointsize)))
+ return NULL; /* Try to continue */
+ qmsfontnum = getnumfromtable(tail(fullfontpath));
+ assert(qmsfontnum > 0);
+ if (!(fn = getfontnode(FontList, qmsfontnum, Orientation))) {
+ bzero((char *)(fn = (struct FontNode *)malloc((unsigned)
+ sizeof(struct FontNode))), sizeof(struct FontNode));
+ fn->next = FontList, FontList = fn;
+ }
+ if (fn->localinfo) /* This font is already on the list */
+ return fn;
+ else
+ bzero(fn->localinfo = malloc((unsigned)sizeof(struct LocalInfo)),
+ sizeof(struct LocalInfo));
+ fn->flags |= RAM;
+ if (Orientation == 'P')
+ fn->flags |= PORT;
+ fn->qmsnumber = qmsfontnum;
+ (void)strcpy(LI(fn)->name, font);
+ (void)strcpy(LI(fn)->pathname, fullfontpath);
+ (void)extractinfo(tail(LI(fn)->pathname), fontname, sfontname, &ds, &mag);
+ LI(fn)->pointsize = ROUND(mag / (double)RESOLUTION * 10);
+ (void)strcpy(EOFName, fullfontpath);
+ seteoffunction(pkeofsocleanup);
+ if (!(fi = getfontinfo(fullfontpath, (EQ(Model, "QMS800") ||
+ EQ(Model, "QMS1500")) && Orientation == 'P' || (!EQ(Model, "QMS800") &&
+ !EQ(Model, "QMS1500")) && Orientation == 'L' ? 'X' : 'Y'))) {
+ FontList = FontList->next; /* Bad PK file or not readable */
+ fprintf(stderr, "%s: could not open or bad PK file %s\n", Whoami,
+ fullfontpath);
+ free(fn->localinfo), free((char *)fn);
+ return NULL;
+ }
+ if (!(fn->flags & PRELOADED))
+ fn->blocksize = fi->blocksize;
+ seteoffunction(troffeofsocleanup);
+ LI(fn)->qmsheight = fi->qmsheight;
+ LI(fn)->qmsbaseline = fi->qmsbaseline;
+ for (i = 0; i < 256; i++) {
+ LI(fn)->widths[i] = ROUND(fi->chararray[i].tfm * ((fi->ds /
+ (double)FIX) / FIX) / PPI * HORCATRES * (LI(fn)->pointsize
+ / 10.0));
+ LI(fn)->bitmapsize[0][i] = fi->chararray[i].w;
+ LI(fn)->bitmapsize[1][i] = fi->chararray[i].h;
+ }
+ return fn;
+}
+
+/* Downloads a font */
+Boolean download(fn)
+struct FontNode *fn;
+{
+ struct CharInfo *ci;
+ char *tail(), *strcpy();
+ void resetpkfile(), seteoffunction(),
+ downloadpkeofsocleanup(), troffeofsocleanup();
+ int downloadinterrupt(), callcleanup();
+ int downloadtype, result, i, truebyteswide, bytestooutput,
+ row, bytes;
+
+ if (!fn || fn->flags & LOADED || !(fn->flags & RAM) || (fn->flags & PORT ?
+ 'P' : 'L') != Orientation)
+ return FALSE;
+ resetpkfile();
+ downloadtype = ((EQ(Model, "QMS800") || EQ(Model, "QMS1500")) &&
+ Orientation == 'P' || (!EQ(Model, "QMS800") && !EQ(Model, "QMS1500"))
+ && Orientation == 'L' ? 'X' : 'Y');
+ DownLoadFNum = fn->qmsnumber;
+ (void)sigblock(SIGINT); /* Temporarily block interrupts */
+ SigStruct.sv_handler = downloadinterrupt;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ (void)strcpy(EOFName, LI(fn)->pathname);
+ seteoffunction(downloadpkeofsocleanup);
+ /* #defining ASCIILOAD causes ASCII characters to be used for the download
+ * sequence. Twice as many characters must be sent but it is useful for
+ * looking at the output when debugging. Also, you can actually see the
+ * bitmaps in the output. ASCII loading must be used when you can't get
+ * hardware flow control to work. Far out.
+ */
+#ifdef ASCIILOAD
+ fputs(FREEFORM, stdout);
+#else
+ fputs(EIGHTBITON, stdout);
+#endif
+ printf("%s%05d%c0%-4.4s%03d%03dT", DOWNLOAD, fn->qmsnumber, Orientation,
+ tail(LI(fn)->pathname), LI(fn)->qmsheight, LI(fn)->qmsbaseline);
+ (void)sigsetmask(sigblock(0) & ~SIGINT); /* Unblock interrupts */
+ while ((result = getnextcharinfo(LI(fn)->pathname, downloadtype, &ci)) !=
+ 1)
+ switch (result) {
+ case 2:
+ fprintf(stderr, "%s: could not open %s\n", Whoami,
+ LI(fn)->pathname);
+ return FALSE;
+ case 3:
+ fprintf(stderr, "%s: %s is not a PK file\n", Whoami,
+ LI(fn)->pathname);
+ return FALSE;
+ case 4:
+ fprintf(stderr, "%s: %s PK version is incorrect\n", Whoami,
+ LI(fn)->pathname);
+ return FALSE;
+ case 0: /* Ok. Got a bitmap */
+ if (ci->h == 0 || ci->w == 0)
+ continue;
+ putchar(',');
+ printf("%02X%03d", ci->cc, ROUND(LI(fn)->widths[ci->cc] /
+ (double)HORCATRES * RESOLUTION));
+ if (downloadtype == 'X') {
+ printf("%03d%03d", ci->h, ci->w);
+ printf("%c%03d", LI(fn)->qmsbaseline - ci->voff >= 0 ? '+'
+ : '-', ABS(LI(fn)->qmsbaseline - ci->voff));
+ printf("%c%03d", -ci->hoff >= 0 ? '+' : '-', ABS(-ci->hoff));
+ } else {
+ printf("%03d%03d", ci->w, ci->h);
+ printf("%c%03d", -ci->hoff >= 0 ? '+' : '-', ABS(ci->hoff));
+ printf("%c%03d", (LI(fn)->qmsheight - LI(fn)->qmsbaseline) -
+ (ci->h - ci->voff) >= 0 ? '+' : '-', ABS((LI(fn)->qmsheight
+ - LI(fn)->qmsbaseline) - (ci->h - ci->voff)));
+ i = ci->w, ci->w = ci->h, ci->h = i; /* Swaparoo! */
+ }
+ truebyteswide = ci->w + 7 >> 3; /* >> divides by 8 */
+ bytestooutput = (ci->w + 15 >> 4) * 2; /* >> divides by 16 */
+#ifdef ASCIILOAD
+ for (row = 0; row < ci->h; row++) {
+#else
+ for (row = 0; row < ci->h; row++)
+#endif
+ for (bytes = 0; bytes < bytestooutput; bytes++) {
+ if (bytes == truebyteswide - 1)
+ *(ci->bitmap + row * truebyteswide + bytes) &=
+ 0xFF<<7-(ci->w+7)%8;
+ if (bytes < truebyteswide) {
+ i = *(ci->bitmap + row * truebyteswide + bytes) &
+ 0xFF;
+#ifdef ASCIILOAD
+ printf("%c%c", "0123456789ABCDEF"[i >> 4],
+ "0123456789ABCDEF"[i & 0xF]);
+#else
+ if (i == '^')
+ printf("^^");
+ else
+ (void)putchar(i);
+#endif
+ } else
+#ifdef ASCIILOAD
+ printf("00");
+#else
+ (void)putchar(0);
+#endif
+ }
+#ifdef ASCIILOAD
+ putchar('\n');
+ }
+#endif
+ break;
+ } /* End switch */
+#ifdef ASCIILOAD
+ printf("%s%s", ENDCMD, FREEOFF);
+#else
+ printf("%s%s", ENDCMD, EIGHTBITOFF);
+#endif
+ putchar('\r'); /* Ends the pass */
+ (void)sigblock(SIGINT);
+ printf("%s00000%s", TAB, ENDCMD);
+ printf("%s00000%s", JUSTIFYMARGIN, ENDCMD);
+ SigStruct.sv_handler = callcleanup;
+ (void)sigvec(SIGINT, &SigStruct, (struct sigvec *)NULL);
+ seteoffunction(troffeofsocleanup);
+ CurRamBlocks += fn->blocksize;
+ fn->flags |= LOADED;
+ (void)sigsetmask(sigblock(0) & ~SIGINT);
+ return TRUE;
+}
+
+/* The following routines are called when a SIGINT is received or EOF is
+ * unexpectedly encountered when reading a file.
+ */
+simplyexit()
+{
+ exit(SUCCEED);
+}
+
+callcleanup()
+{
+ void cleanup();
+
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, SUCCEED); /* Interrupting a program is not an error */
+}
+
+void troffeofsocleanup()
+{
+ fprintf(stderr, "%s: unexpected EOF when reading otroff file\n",
+ Whoami);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+}
+
+void pkeofsocleanup()
+{
+ fprintf(stderr, "%s: unexpected EOF when reading PK file %s\n", Whoami,
+ EOFName);
+ fputs(FORMFEED, stdout), NumPages++;
+ cleanup(FontList, 2);
+}
+
+downloadinterrupt()
+{
+ fputs(ENDCMD, stdout);
+#ifdef ASCIILOAD
+ fputs(FREEOFF, stdout);
+#else
+ fputs(EIGHTBITOFF, stdout);
+#endif
+ printf("%s%05d%c%s", DOWNLOAD, DownLoadFNum, Orientation, ENDCMD);
+ callcleanup();
+}
+
+void downloadpkeofsocleanup()
+{
+ fputs(ENDCMD, stdout);
+#ifdef ASCIILOAD
+ fputs(FREEOFF, stdout);
+#else
+ fputs(EIGHTBITOFF, stdout);
+#endif
+ printf("%s%05d%c%s", DOWNLOAD, DownLoadFNum, Orientation, ENDCMD);
+ pkeofsocleanup();
+}
diff --git a/dviware/quicspool/src/tfm2difont.c b/dviware/quicspool/src/tfm2difont.c
new file mode 100644
index 0000000000..4fa2c12560
--- /dev/null
+++ b/dviware/quicspool/src/tfm2difont.c
@@ -0,0 +1,489 @@
+#ifndef lint
+static char *rcs = "$Header: tfm2difont.c,v 1.1 88/01/15 13:05:47 simpson Rel $";
+#endif
+/*
+$Log: tfm2difont.c,v $
+ * Revision 1.1 88/01/15 13:05:47 simpson
+ * initial release
+ *
+ * Revision 0.2 88/01/06 08:57:45 simpson
+ * added l. and L. for pic dots
+ *
+ * Revision 0.1 87/12/11 18:31:24 simpson
+ * beta test
+ *
+*/
+#include <stdio.h>
+#include <local/standard.h>
+#include "constants.h"
+#include "dev.h"
+
+/* An octal number designates that the character isn't normally in troff */
+char *NormalSequences[][5] = { /* Troff representations */
+ /* Put the 1/6 em \| in the 000 position */
+ /* 000 */ "\\|", NULL, NULL, NULL, NULL,
+ /* 001 */ "fi", NULL, NULL, NULL, NULL,
+ /* 002 */ "fl", NULL, NULL, NULL, NULL,
+ /* 003 */ "ff", NULL, NULL, NULL, NULL,
+ /* 004 */ "\\-", "en", NULL, NULL, NULL,
+ /* 005 */ "ru", NULL, NULL, NULL, NULL,
+ /* 006 */ "em", NULL, NULL, NULL, NULL,
+ /* 007 */ "bu", NULL, NULL, NULL, NULL,
+ /* 010 */ "sq", NULL, NULL, NULL, NULL,
+ /* 011 */ "fI", "Fi", NULL, NULL, NULL,
+ /* 012 */ "fL", "Fl", NULL, NULL, NULL,
+ /* 013 */ "de", NULL, NULL, NULL, NULL,
+ /* 014 */ "dg", NULL, NULL, NULL, NULL,
+ /* 015 */ "fm", NULL, NULL, NULL, NULL,
+ /* 016 */ "co", NULL, NULL, NULL, NULL,
+ /* 017 */ "rg", NULL, NULL, NULL, NULL,
+ /* 020 */ "ct", NULL, NULL, NULL, NULL,
+ /* 021 */ "14", NULL, NULL, NULL, NULL,
+ /* 022 */ "12", NULL, NULL, NULL, NULL,
+ /* 023 */ "34", NULL, NULL, NULL, NULL,
+ /* The following four characters (box, open bullet, umlaut and cedilla) */
+ /* are not in otroff but are in ditroff. */
+ /* 024 */ "bx", NULL, NULL, NULL, NULL,
+ /* 025 */ "ob", NULL, NULL, NULL, NULL,
+ /* 026 */ "..", NULL, NULL, NULL, NULL,
+ /* 027 */ "cd", NULL, NULL, NULL, NULL,
+ /* 030 */ "L.", "l.", NULL, NULL, NULL,
+ /* 031 */ "\031", NULL, NULL, NULL, NULL,
+ /* 032 */ "\032", NULL, NULL, NULL, NULL,
+ /* 033 */ "\033", NULL, NULL, NULL, NULL,
+ /* 034 */ "\034", NULL, NULL, NULL, NULL,
+ /* 035 */ "\035", NULL, NULL, NULL, NULL,
+ /* 036 */ "\036", NULL, NULL, NULL, NULL,
+ /* 037 */ "\037", NULL, NULL, NULL, NULL,
+ /* 040 */ " ", NULL, NULL, NULL, NULL,
+ /* 041 */ "!", NULL, NULL, NULL, NULL,
+ /* 042 */ "\042", NULL, NULL, NULL, NULL,
+ /* 043 */ "\043", NULL, NULL, NULL, NULL,
+ /* 044 */ "$", NULL, NULL, NULL, NULL,
+ /* 045 */ "%", NULL, NULL, NULL, NULL,
+ /* 046 */ "&", NULL, NULL, NULL, NULL,
+ /* 047 */ "\047", NULL, NULL, NULL, NULL,
+ /* 050 */ "(", NULL, NULL, NULL, NULL,
+ /* 051 */ ")", NULL, NULL, NULL, NULL,
+ /* 052 */ "*", NULL, NULL, NULL, NULL,
+ /* 053 */ "+", NULL, NULL, NULL, NULL,
+ /* 054 */ ",", NULL, NULL, NULL, NULL,
+ /* 055 */ "-", "hy", NULL, NULL, NULL,
+ /* 056 */ ".", NULL, NULL, NULL, NULL,
+ /* 057 */ "/", NULL, NULL, NULL, NULL,
+ /* 060 */ "0", NULL, NULL, NULL, NULL,
+ /* 061 */ "1", NULL, NULL, NULL, NULL,
+ /* 062 */ "2", NULL, NULL, NULL, NULL,
+ /* 063 */ "3", NULL, NULL, NULL, NULL,
+ /* 064 */ "4", NULL, NULL, NULL, NULL,
+ /* 065 */ "5", NULL, NULL, NULL, NULL,
+ /* 066 */ "6", NULL, NULL, NULL, NULL,
+ /* 067 */ "7", NULL, NULL, NULL, NULL,
+ /* 070 */ "8", NULL, NULL, NULL, NULL,
+ /* 071 */ "9", NULL, NULL, NULL, NULL,
+ /* 072 */ ":", NULL, NULL, NULL, NULL,
+ /* 073 */ ";", NULL, NULL, NULL, NULL,
+ /* 074 */ "\074", NULL, NULL, NULL, NULL,
+ /* 075 */ "\075", NULL, NULL, NULL, NULL,
+ /* 076 */ "\076", NULL, NULL, NULL, NULL,
+ /* 077 */ "?", NULL, NULL, NULL, NULL,
+ /* 100 */ "\100", NULL, NULL, NULL, NULL,
+ /* 101 */ "A", NULL, NULL, NULL, NULL,
+ /* 102 */ "B", NULL, NULL, NULL, NULL,
+ /* 103 */ "C", NULL, NULL, NULL, NULL,
+ /* 104 */ "D", NULL, NULL, NULL, NULL,
+ /* 105 */ "E", NULL, NULL, NULL, NULL,
+ /* 106 */ "F", NULL, NULL, NULL, NULL,
+ /* 107 */ "G", NULL, NULL, NULL, NULL,
+ /* 110 */ "H", NULL, NULL, NULL, NULL,
+ /* 111 */ "I", NULL, NULL, NULL, NULL,
+ /* 112 */ "J", NULL, NULL, NULL, NULL,
+ /* 113 */ "K", NULL, NULL, NULL, NULL,
+ /* 114 */ "L", NULL, NULL, NULL, NULL,
+ /* 115 */ "M", NULL, NULL, NULL, NULL,
+ /* 116 */ "N", NULL, NULL, NULL, NULL,
+ /* 117 */ "O", NULL, NULL, NULL, NULL,
+ /* 120 */ "P", NULL, NULL, NULL, NULL,
+ /* 121 */ "Q", NULL, NULL, NULL, NULL,
+ /* 122 */ "R", NULL, NULL, NULL, NULL,
+ /* 123 */ "S", NULL, NULL, NULL, NULL,
+ /* 124 */ "T", NULL, NULL, NULL, NULL,
+ /* 125 */ "U", NULL, NULL, NULL, NULL,
+ /* 126 */ "V", NULL, NULL, NULL, NULL,
+ /* 127 */ "W", NULL, NULL, NULL, NULL,
+ /* 130 */ "X", NULL, NULL, NULL, NULL,
+ /* 131 */ "Y", NULL, NULL, NULL, NULL,
+ /* 132 */ "Z", NULL, NULL, NULL, NULL,
+ /* 133 */ "[", NULL, NULL, NULL, NULL,
+ /* 134 */ "\134", NULL, NULL, NULL, NULL,
+ /* 135 */ "]", NULL, NULL, NULL, NULL,
+ /* 136 */ "\136", NULL, NULL, NULL, NULL,
+ /* 137 */ "_", NULL, NULL, NULL, NULL,
+ /* 140 */ "\140", NULL, NULL, NULL, NULL,
+ /* 141 */ "a", NULL, NULL, NULL, NULL,
+ /* 142 */ "b", NULL, NULL, NULL, NULL,
+ /* 143 */ "c", NULL, NULL, NULL, NULL,
+ /* 144 */ "d", NULL, NULL, NULL, NULL,
+ /* 145 */ "e", NULL, NULL, NULL, NULL,
+ /* 146 */ "f", NULL, NULL, NULL, NULL,
+ /* 147 */ "g", NULL, NULL, NULL, NULL,
+ /* 150 */ "h", NULL, NULL, NULL, NULL,
+ /* 151 */ "i", NULL, NULL, NULL, NULL,
+ /* 152 */ "j", NULL, NULL, NULL, NULL,
+ /* 153 */ "k", NULL, NULL, NULL, NULL,
+ /* 154 */ "l", NULL, NULL, NULL, NULL,
+ /* 155 */ "m", NULL, NULL, NULL, NULL,
+ /* 156 */ "n", NULL, NULL, NULL, NULL,
+ /* 157 */ "o", NULL, NULL, NULL, NULL,
+ /* 160 */ "p", NULL, NULL, NULL, NULL,
+ /* 161 */ "q", NULL, NULL, NULL, NULL,
+ /* 162 */ "r", NULL, NULL, NULL, NULL,
+ /* 163 */ "s", NULL, NULL, NULL, NULL,
+ /* 164 */ "t", NULL, NULL, NULL, NULL,
+ /* 165 */ "u", NULL, NULL, NULL, NULL,
+ /* 166 */ "v", NULL, NULL, NULL, NULL,
+ /* 167 */ "w", NULL, NULL, NULL, NULL,
+ /* 170 */ "x", NULL, NULL, NULL, NULL,
+ /* 171 */ "y", NULL, NULL, NULL, NULL,
+ /* 172 */ "z", NULL, NULL, NULL, NULL,
+ /* 173 */ "\173", NULL, NULL, NULL, NULL,
+ /* 174 */ "|", NULL, NULL, NULL, NULL,
+ /* 175 */ "\175", NULL, NULL, NULL, NULL,
+ /* 176 */ "\176", NULL, NULL, NULL, NULL,
+ /* Put the 1/12 em \^ in this position */
+ /* 177 */ "\\^", NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL
+};
+char *SpecialSequences[][5] = { /* Troff representations */
+ /* 000 */ "\000", NULL, NULL, NULL, NULL,
+ /* 001 */ "if", NULL, NULL, NULL, NULL,
+ /* 002 */ "ip", NULL, NULL, NULL, NULL,
+ /* 003 */ "pt", NULL, NULL, NULL, NULL,
+ /* 004 */ "rh", NULL, NULL, NULL, NULL,
+ /* 005 */ "cu", NULL, NULL, NULL, NULL,
+ /* 006 */ "rn", NULL, NULL, NULL, NULL,
+ /* 007 */ "bs", NULL, NULL, NULL, NULL,
+ /* 010 */ "+-", NULL, NULL, NULL, NULL,
+ /* 011 */ "<=", NULL, NULL, NULL, NULL,
+ /* 012 */ ">=", NULL, NULL, NULL, NULL,
+ /* 013 */ "sr", NULL, NULL, NULL, NULL,
+ /* 014 */ "ts", NULL, NULL, NULL, NULL,
+ /* 015 */ "is", NULL, NULL, NULL, NULL,
+ /* 016 */ "sl", NULL, NULL, NULL, NULL,
+ /* 017 */ "bv", NULL, NULL, NULL, NULL,
+ /* 020 */ "lf", NULL, NULL, NULL, NULL,
+ /* 021 */ "rf", NULL, NULL, NULL, NULL,
+ /* 022 */ "lc", NULL, NULL, NULL, NULL,
+ /* 023 */ "rc", NULL, NULL, NULL, NULL,
+ /* 024 */ "lt", NULL, NULL, NULL, NULL,
+ /* 025 */ "lb", NULL, NULL, NULL, NULL,
+ /* 026 */ "rt", NULL, NULL, NULL, NULL,
+ /* 027 */ "rb", NULL, NULL, NULL, NULL,
+ /* 030 */ "lk", NULL, NULL, NULL, NULL,
+ /* 031 */ "rk", NULL, NULL, NULL, NULL,
+ /* 032 */ "sb", NULL, NULL, NULL, NULL,
+ /* 033 */ "sp", NULL, NULL, NULL, NULL,
+ /* 034 */ "ca", NULL, NULL, NULL, NULL,
+ /* 035 */ "no", NULL, NULL, NULL, NULL,
+ /* 036 */ "lh", NULL, NULL, NULL, NULL,
+ /* 037 */ "mo", NULL, NULL, NULL, NULL,
+ /* 040 */ "\040", NULL, NULL, NULL, NULL,
+ /* 041 */ "ul", "\\_", NULL, NULL, NULL,
+ /* 042 */ "\"", NULL, NULL, NULL, NULL,
+ /* 043 */ "#", NULL, NULL, NULL, NULL,
+ /* 044 */ "Sl", NULL, NULL, NULL, NULL,
+ /* 045 */ "\045", NULL, NULL, NULL, NULL,
+ /* 046 */ "\046", NULL, NULL, NULL, NULL,
+ /* 047 */ "'", "aa", NULL, NULL, NULL,
+ /* 050 */ "gr", NULL, NULL, NULL, NULL,
+ /* 051 */ "\051", NULL, NULL, NULL, NULL,
+ /* 052 */ "mu", NULL, NULL, NULL, NULL,
+ /* 053 */ "pl", NULL, NULL, NULL, NULL,
+ /* 054 */ "\054", NULL, NULL, NULL, NULL,
+ /* 055 */ "mi", NULL, NULL, NULL, NULL,
+ /* 056 */ "\056", NULL, NULL, NULL, NULL,
+ /* 057 */ "di", NULL, NULL, NULL, NULL,
+ /* 060 */ "==", NULL, NULL, NULL, NULL,
+ /* 061 */ "~=", "~~", NULL, NULL, NULL,
+ /* 062 */ "ap", NULL, NULL, NULL, NULL,
+ /* 063 */ "!=", NULL, NULL, NULL, NULL,
+ /* 064 */ "<-", NULL, NULL, NULL, NULL,
+ /* 065 */ "->", NULL, NULL, NULL, NULL,
+ /* 066 */ "ua", NULL, NULL, NULL, NULL,
+ /* 067 */ "da", NULL, NULL, NULL, NULL,
+ /* 070 */ "sc", NULL, NULL, NULL, NULL,
+ /* 071 */ "**", NULL, NULL, NULL, NULL,
+ /* 072 */ "\072", NULL, NULL, NULL, NULL,
+ /* 073 */ "\073", NULL, NULL, NULL, NULL,
+ /* 074 */ "<", NULL, NULL, NULL, NULL,
+ /* 075 */ "=", "eq", NULL, NULL, NULL,
+ /* 076 */ ">", NULL, NULL, NULL, NULL,
+ /* 077 */ "\077", NULL, NULL, NULL, NULL,
+ /* 100 */ "@", NULL, NULL, NULL, NULL,
+ /* 101 */ "*A", NULL, NULL, NULL, NULL,
+ /* 102 */ "*B", NULL, NULL, NULL, NULL,
+ /* 103 */ "*G", NULL, NULL, NULL, NULL,
+ /* 104 */ "*D", NULL, NULL, NULL, NULL,
+ /* 105 */ "*E", NULL, NULL, NULL, NULL,
+ /* 106 */ "*Z", NULL, NULL, NULL, NULL,
+ /* 107 */ "*Y", NULL, NULL, NULL, NULL,
+ /* 110 */ "*H", NULL, NULL, NULL, NULL,
+ /* 111 */ "*I", NULL, NULL, NULL, NULL,
+ /* 112 */ "*K", NULL, NULL, NULL, NULL,
+ /* 113 */ "*L", NULL, NULL, NULL, NULL,
+ /* 114 */ "*M", NULL, NULL, NULL, NULL,
+ /* 115 */ "*N", NULL, NULL, NULL, NULL,
+ /* 116 */ "*C", NULL, NULL, NULL, NULL,
+ /* 117 */ "*O", NULL, NULL, NULL, NULL,
+ /* 120 */ "*P", NULL, NULL, NULL, NULL,
+ /* 121 */ "*R", NULL, NULL, NULL, NULL,
+ /* 122 */ "*S", NULL, NULL, NULL, NULL,
+ /* 123 */ "*T", NULL, NULL, NULL, NULL,
+ /* 124 */ "*U", "U", NULL, NULL, NULL,
+ /* 125 */ "*F", NULL, NULL, NULL, NULL,
+ /* 126 */ "*X", NULL, NULL, NULL, NULL,
+ /* 127 */ "*Q", NULL, NULL, NULL, NULL,
+ /* 130 */ "*W", NULL, NULL, NULL, NULL,
+ /* 131 */ "dd", NULL, NULL, NULL, NULL,
+ /* 132 */ "br", NULL, NULL, NULL, NULL,
+ /* 133 */ "ib", NULL, NULL, NULL, NULL,
+ /* 134 */ "\\", NULL, NULL, NULL, NULL,
+ /* 135 */ "ci", NULL, NULL, NULL, NULL,
+ /* 136 */ "^", NULL, NULL, NULL, NULL,
+ /* 137 */ "_", NULL, NULL, NULL, NULL,
+ /* 140 */ "`", "ga", NULL, NULL, NULL,
+ /* 141 */ "*a", NULL, NULL, NULL, NULL,
+ /* 142 */ "*b", NULL, NULL, NULL, NULL,
+ /* 143 */ "*g", NULL, NULL, NULL, NULL,
+ /* 144 */ "*d", NULL, NULL, NULL, NULL,
+ /* 145 */ "*e", NULL, NULL, NULL, NULL,
+ /* 146 */ "*z", NULL, NULL, NULL, NULL,
+ /* 147 */ "*y", NULL, NULL, NULL, NULL,
+ /* 150 */ "*h", NULL, NULL, NULL, NULL,
+ /* 151 */ "*i", NULL, NULL, NULL, NULL,
+ /* 152 */ "*k", NULL, NULL, NULL, NULL,
+ /* 153 */ "*l", NULL, NULL, NULL, NULL,
+ /* 154 */ "*m", NULL, NULL, NULL, NULL,
+ /* 155 */ "*n", NULL, NULL, NULL, NULL,
+ /* 156 */ "*c", NULL, NULL, NULL, NULL,
+ /* 157 */ "*o", NULL, NULL, NULL, NULL,
+ /* 160 */ "*p", NULL, NULL, NULL, NULL,
+ /* 161 */ "*r", NULL, NULL, NULL, NULL,
+ /* 162 */ "*s", NULL, NULL, NULL, NULL,
+ /* 163 */ "*t", NULL, NULL, NULL, NULL,
+ /* 164 */ "*u", NULL, NULL, NULL, NULL,
+ /* 165 */ "*f", NULL, NULL, NULL, NULL,
+ /* 166 */ "*x", NULL, NULL, NULL, NULL,
+ /* 167 */ "*q", NULL, NULL, NULL, NULL,
+ /* 170 */ "*w", NULL, NULL, NULL, NULL,
+ /* 171 */ "pd", NULL, NULL, NULL, NULL,
+ /* 172 */ "es", NULL, NULL, NULL, NULL,
+ /* 173 */ "{", NULL, NULL, NULL, NULL,
+ /* 174 */ "or", "vr", NULL, NULL, NULL,
+ /* 175 */ "}", NULL, NULL, NULL, NULL,
+ /* 176 */ "~", NULL, NULL, NULL, NULL,
+ /* 177 */ "\177", NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL
+};
+
+char TfmName[81]; /* Only used in error routine */
+char *WhoAmI; /* Argv[0] */
+char *Usage = "Usage: %s [-s] [-w width] [-l ligature]... file...\n";
+Boolean Special = FALSE; /* Designates whether font is special. */
+Bits Ligatures; /* Ligatures the font does not contain. */
+int ExitStatus = SUCCEED;
+int Width = -1; /* "spacewidth" in font desc. file. -1==omit */
+
+main(argc,argv)
+int argc;
+char *argv[];
+{
+ extern int optind;
+ extern char *optarg;
+ int c;
+ FILE *infile, *outfile;
+ void seteoffunction(), tfmeofsoexit(), convert();
+ char *strcpy();
+
+ WhoAmI = argv[0];
+ while ((c = getopt(argc, argv, "sl:w:")) != EOF)
+ switch (c) {
+ case 's':
+ Special = TRUE;
+ break;
+ case 'w':
+ Width = atoi(optarg);
+ break;
+ case 'l':
+ if (EQ(optarg, "ff"))
+ Ligatures |= LFF;
+ else if (EQ(optarg, "fi"))
+ Ligatures |= LFI;
+ else if (EQ(optarg, "fl"))
+ Ligatures |= LFL;
+ else if (EQ(optarg, "ffi"))
+ Ligatures |= LFFI;
+ else if (EQ(optarg, "ffl"))
+ Ligatures |= LFFL;
+ 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]);
+ argv[optind][strlen(argv[optind])-4] = '\0';
+ if (!(outfile = fopen(argv[optind], "w"))) {
+ fprintf(stderr, "%s: cannot open output file %s\n", WhoAmI,
+ argv[optind]);
+ 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 a troff width table file.
+ */
+void convert(infile, outfile, outname)
+FILE *infile, *outfile;
+char *outname; /* Output file name */
+{
+ int aheight, i, j, widthindex, heightanddepth, width,
+ height, depth, kerning;
+ unsigned long uinteger(), lh, bc, ec, nw, nh, designsize, utemp;
+ long integer(), temp;
+
+ fprintf(outfile, "name %s\ninternalname %s\n", outname, outname);
+ if (Special)
+ fputs("special\n", outfile);
+ if (!Special && Ligatures != 0x1F) {
+ fputs("ligatures ", outfile);
+ if (!(Ligatures & LFF))
+ fputs("ff ", outfile);
+ if (!(Ligatures & LFI))
+ fputs("fi ", outfile);
+ if (!(Ligatures & LFL))
+ fputs("fl ", outfile);
+ if (!(Ligatures & LFFI))
+ fputs("ffi ", outfile);
+ if (!(Ligatures & LFFL))
+ fputs("ffl ", outfile);
+ fputs("0\n", outfile);
+ }
+ if (Width != -1)
+ fprintf(outfile, "spacewidth %d\n", Width);
+ if (!Special) {
+ if ((aheight = getaheight(infile)) == MAX_INTEGER) {
+ fprintf(stderr, "%s: no letter 'a' in file %s.tfm\n", WhoAmI,
+ outname);
+ fprintf(stderr, "\tsetting height to zero\n");
+ aheight = 0;
+ }
+ (void)fseek(infile, 0L, 0);
+ }
+ fputs("charset\n", outfile);
+ (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);
+ temp = integer(infile, 4);
+ width = ROUND((temp / (double)FIX * designsize) / PPI * RESOLUTION);
+ (void)fseek(infile, 24L + 4*lh + (ec-bc+1)*4 + nw*4 +
+ (heightanddepth>>4)*4, 0);
+ utemp = uinteger(infile, 4);
+ height = ROUND((utemp / (double)FIX * designsize) / PPI * RESOLUTION);
+ (void)fseek(infile, 24L + 4*lh + (ec-bc+1)*4 + nw*4 + nh*4 +
+ (heightanddepth&0xF)*4, 0);
+ utemp = uinteger(infile, 4);
+ depth = ROUND((utemp / (double)FIX * designsize) / PPI * RESOLUTION);
+ kerning = 0;
+ if (height > aheight)
+ kerning |= 2;
+ if (depth > 0)
+ kerning |= 1;
+ for (j = 0; Special ? SpecialSequences[i][j] : NormalSequences[i][j];
+ j++)
+ if (j == 0)
+ fprintf(outfile, "%s\t%d\t%d\t%d\n", Special ?
+ SpecialSequences[i][j] : NormalSequences[i][j], width,
+ Special ? 0 : kerning, i);
+ else
+ fprintf(outfile, "%s\t\"\n", Special ? SpecialSequences[i][j] :
+ NormalSequences[i][j]);
+ }
+}
+
+/* Returns the height of the letter 'a' in the font passed as a parameter.
+ * The height is returned in pixels since troff likes to use pixels as its
+ * unit. If the letter 'a' is not found, MAX_INTEGER is returned.
+ */
+int getaheight(in)
+FILE *in;
+{
+ unsigned long lh, bc, ec, nw, uinteger(), designsize;
+
+ (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 */
+ designsize = uinteger(in, 4) / FIX; /* Convert from FIXes */
+ (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 ROUND((uinteger(in, 4) / (double)FIX * designsize) / PPI *
+ RESOLUTION);
+}
+
+void tfmeofsoexit()
+{
+ fprintf(stderr, "%s: unexpected end of tfm file %s\n", WhoAmI, TfmName);
+ exit(FAIL);
+}
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);
+}
diff --git a/dviware/quicspool/src/xxx.y b/dviware/quicspool/src/xxx.y
new file mode 100644
index 0000000000..304851484e
--- /dev/null
+++ b/dviware/quicspool/src/xxx.y
@@ -0,0 +1,411 @@
+%{
+#ifndef lint
+static char *yrcs = "$Header: xxx.y,v 1.2 88/02/03 08:52:12 simpson Exp $";
+#endif
+/*
+$Log: xxx.y,v $
+ * Revision 1.2 88/02/03 08:52:12 simpson
+ * added tpic support
+ *
+ * Revision 1.1 88/01/15 13:05:57 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:31:27 simpson
+ * beta test
+ *
+*/
+#define TPICRES 1000 /* Tpic uses 1000 dots/inch */
+static int Coordinates[300][2]; /* Coordinates used by tpic */
+static int CoorCount; /* Count of # of coor in above array */
+static int PenWidth;
+static int GraphOrigin[2];
+static double Center[2], Cur[2], New[2];
+static double CurvePts[300][3], SplinePts[500][3];
+static enum {none, white, shade, black} Color;
+%}
+%union {
+ int i;
+ double f;
+ char s[81];
+}
+%token OVERLAY PENSIZE FLUSHPATH FLUSHDASHED FLUSHDOTTED ADDPATH DRAWARC
+%token FLUSHSPLINE SHADELAST WHITENLAST BLACKENLAST TEXTURE
+%token <s> STRING
+%token <i> INTEGER
+%token <f> FLOAT
+%type <s> validfile
+%%
+keywords :
+ keyword ',' keywords
+ |
+ keyword
+ |
+ error ','
+ {
+ yyerrok;
+ }
+ keywords
+ ;
+
+keyword :
+ OVERLAY
+ '('
+ validfile
+ {
+ FILE *f;
+ char filename[81], *expandtilde(), *strcpy();
+ int c;
+
+ (void)strcpy(filename, $3);
+ (void)expandtilde(filename);
+ if (f = fopen(filename, "r")) {
+ while ((c = getc(f)) != EOF)
+ (void)putchar(c);
+ (void)fclose(f);
+ }
+ }
+ ')'
+ |
+ PENSIZE
+ INTEGER
+ {
+ /* A pen command designates the start of a new graph */
+ PenWidth = ROUND($2 / 1000.0 * RESOLUTION);
+ GraphOrigin[0] = Origin[0], GraphOrigin[1] = Origin[1];
+ CoorCount = 0;
+ Color = none;
+ }
+ |
+ FLUSHPATH
+ {
+ if (CoorCount > 1) {
+ int i;
+
+ fputs(VECTORON, stdout);
+ printf("%s%05d:%05d", PENUP,
+ ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[0][0]/(double)TPICRES)*1000),
+ ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[0][1]/(double)TPICRES)*1000));
+ printf("%s%02d", PENWIDTH, PenWidth);
+ for (i = 1; i < CoorCount; i++)
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[i][0]/(double)TPICRES)*1000),
+ ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[i][1]/(double)TPICRES)*1000));
+ fputs(VECTOROFF, stdout);
+ }
+ if (CoorCount >=4 && Color != none) {
+ /* Find midpoint of diagonal */
+ Center[0] = ((GraphOrigin[0]/(double)RESOLUTION+
+ Coordinates[0][0]/(double)TPICRES)+(GraphOrigin[0]/
+ (double)RESOLUTION+Coordinates[2][0]/(double)TPICRES))/2.0;
+ Center[1] = ((GraphOrigin[1]/(double)RESOLUTION+
+ Coordinates[0][1]/(double)TPICRES)+(GraphOrigin[1]/
+ (double)RESOLUTION+Coordinates[2][1]/(double)TPICRES))/2.0;
+ printf("%s%05d%05d", AREAFILL,
+ ROUND(Center[0]*1000),ROUND(Center[1]*1000));
+ switch (Color) {
+ case white:
+ printf("%02d", 0);
+ break;
+ case shade:
+ printf("%02d", 19);
+ break;
+ case black:
+ printf("%02d", 20);
+ break;
+ }
+ printf("%s", ENDCMD);
+ }
+ CoorCount = 0;
+ Color = none;
+ }
+ |
+ FLUSHDASHED
+ FLOAT
+ {
+ if (CoorCount > 1) {
+ int i;
+
+ fputs(VECTORON, stdout);
+ printf("%s%05d:%05d", PENUP,
+ ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[0][0]/(double)TPICRES)*1000),
+ ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[0][1]/(double)TPICRES)*1000));
+ printf("%s%02d", PENWIDTH, PenWidth);
+ printf("%s%d", "^V", 4);
+ for (i = 1; i < CoorCount; i++)
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[i][0]/(double)TPICRES)*1000),
+ ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[i][1]/(double)TPICRES)*1000));
+ fputs(VECTOROFF, stdout);
+ }
+ CoorCount = 0;
+ Color = none;
+ }
+ |
+ FLUSHDOTTED
+ FLOAT
+ {
+ if (CoorCount > 1) {
+ int i;
+
+ fputs(VECTORON, stdout);
+ printf("%s%05d:%05d", PENUP,
+ ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[0][0]/(double)TPICRES)*1000),
+ ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[0][1]/(double)TPICRES)*1000));
+ printf("%s%02d", PENWIDTH, PenWidth);
+ printf("%s%d", "^V", 2);
+ for (i = 1; i < CoorCount; i++)
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[i][0]/(double)TPICRES)*1000),
+ ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[i][1]/(double)TPICRES)*1000));
+ fputs(VECTOROFF, stdout);
+ }
+ CoorCount = 0;
+ Color = none;
+ }
+ |
+ ADDPATH
+ INTEGER
+ INTEGER
+ {
+ Coordinates[CoorCount][0] = $2, Coordinates[CoorCount++][1] = $3;
+ }
+ |
+ DRAWARC
+ INTEGER
+ INTEGER
+ INTEGER
+ INTEGER
+ FLOAT
+ FLOAT
+ {
+ Center[0] = GraphOrigin[0] / (double)RESOLUTION + $2 /
+ (double)TPICRES,
+ Center[1] = GraphOrigin[1] / (double)RESOLUTION + $3 /
+ (double)TPICRES;
+ if ($4 != $5) { /* Ellipse */
+ int i;
+
+ /* Ellipses satisfy the equation (x^2)/(a^2)+(y^2)/(b^2)=1
+ * where 'a' is the length of the semimajor axis and 'b'
+ * is the length of the semiminor axis. We divide each
+ * quadrant into 200 line segments and connect the line
+ * segments.
+ */
+ /* Cur and New are relative to the origin */
+ Cur[0] = $4 / (double)TPICRES, Cur[1] = 0.0;
+ fputs(VECTORON, stdout);
+ printf("%s%02d", PENWIDTH, PenWidth);
+ for (i = 1; i <= 200; i++, Cur[0] = New[0], Cur[1] = New[1]) {
+ New[0] = ($4/(double)TPICRES)*cos((i/200.0)*(PI/2.0)),
+ New[1] = ($5/(double)TPICRES)*sin((i/200.0)*(PI/2.0));
+ /* First quadrant */
+ printf("%s%05d:%05d", PENUP,
+ ROUND((Center[0]+Cur[0])*1000.0),
+ ROUND((Center[1]+Cur[1])*1000.0));
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND((Center[0]+New[0])*1000.0),
+ ROUND((Center[1]+New[1])*1000.0));
+ /* Second quadrant */
+ printf("%s%05d:%05d", PENUP,
+ ROUND((Center[0]-Cur[0])*1000.0),
+ ROUND((Center[1]+Cur[1])*1000.0));
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND((Center[0]-New[0])*1000.0),
+ ROUND((Center[1]+New[1])*1000.0));
+ /* Third quadrant */
+ printf("%s%05d:%05d", PENUP,
+ ROUND((Center[0]-Cur[0])*1000.0),
+ ROUND((Center[1]-Cur[1])*1000.0));
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND((Center[0]-New[0])*1000.0),
+ ROUND((Center[1]-New[1])*1000.0));
+ /* Fourth quadrant */
+ printf("%s%05d:%05d", PENUP,
+ ROUND((Center[0]+Cur[0])*1000.0),
+ ROUND((Center[1]-Cur[1])*1000.0));
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND((Center[0]+New[0])*1000.0),
+ ROUND((Center[1]-New[1])*1000.0));
+ if (Color != none) {
+ printf("%s%05d%05d", AREAFILL,
+ ROUND(Center[0]*1000),ROUND(Center[1]*1000));
+ switch (Color) {
+ case white:
+ printf("%02d", 0);
+ break;
+ case shade:
+ printf("%02d", 19);
+ break;
+ case black:
+ printf("%02d", 20);
+ break;
+ }
+ printf("%s", ENDCMD);
+ Color = none;
+ }
+ }
+ fputs(VECTOROFF, stdout);
+ } else { /* Arc */
+ printf("%s%c%05d%c%05d%05d%03d%03d%02d%s", DECIMALARC,
+ Center[0]>0?'+':'-',
+ Center[0]>0?ROUND(Center[0]*1000):
+ ROUND(-Center[0]*1000),Center[1]>0?'+':'-',
+ Center[1]>0?ROUND(Center[1]*1000):
+ ROUND(-Center[1]*1000),$4,ROUND($6/PI*500.0)>999?999:
+ ROUND($6/PI*500.0),ROUND($7/PI*500.0)>999?999:
+ ROUND($7/PI*500.0), PenWidth, ENDCMD);
+ if ($6 == 0 && ABS($7-2*PI) < 0.01)
+ if (Color != none) {
+ printf("%s%05d%05d", AREAFILL,
+ ROUND(Center[0]*1000),ROUND(Center[1]*1000));
+ switch (Color) {
+ case white:
+ printf("%02d", 0);
+ break;
+ case shade:
+ printf("%02d", 19);
+ break;
+ case black:
+ printf("%02d", 20);
+ break;
+ }
+ printf("%s", ENDCMD);
+ Color = none;
+ }
+ }
+ }
+
+ |
+ FLUSHSPLINE
+ {
+ if (CoorCount > 1) {
+ int i;
+
+ for (i = 0; i < CoorCount; i++) {
+ CurvePts[i][0] = Coordinates[i][0] / (double)TPICRES;
+ CurvePts[i][1] = Coordinates[i][1] / (double)TPICRES;
+ CurvePts[i][2] = 0.0; /* z-axis not used */
+ }
+ spline(CurvePts,CoorCount-1,SplinePts,499,3); /* 2nd degree */
+ fputs(VECTORON, stdout);
+ printf("%s%05d:%05d", PENUP,
+ ROUND((GraphOrigin[0]/(double)RESOLUTION+SplinePts[0][0])*1000),
+ ROUND((GraphOrigin[1]/(double)RESOLUTION+SplinePts[0][1])*1000));
+ printf("%s%02d", PENWIDTH, PenWidth);
+ for (i = 1; i < 500; i++)
+ printf("%s%05d:%05d", PENDOWN,
+ ROUND((GraphOrigin[0]/(double)RESOLUTION+SplinePts[i][0])*1000),
+ ROUND((GraphOrigin[1]/(double)RESOLUTION+SplinePts[i][1])*1000));
+ fputs(VECTOROFF, stdout);
+ }
+ CoorCount = 0;
+ }
+ |
+ TEXTURE
+ textureargs /* Ignore - Imagen only */
+ |
+ SHADELAST
+ {
+ Color = shade;
+ }
+ |
+ WHITENLAST
+ {
+ Color = white;
+ }
+ |
+ BLACKENLAST
+ {
+ Color = black;
+ }
+ ;
+
+validfile :
+ STRING
+ {
+ (void)strcpy($$, $1);
+ }
+ |
+ OVERLAY
+ {
+ (void)strcpy($$, "overlay");
+ }
+ |
+ PENSIZE
+ {
+ (void)strcpy($$, "pn");
+ }
+ |
+ FLUSHPATH
+ {
+ (void)strcpy($$, "fp");
+ }
+ |
+ FLUSHDASHED
+ {
+ (void)strcpy($$, "da");
+ }
+ |
+ FLUSHDOTTED
+ {
+ (void)strcpy($$, "dt");
+ }
+ |
+ ADDPATH
+ {
+ (void)strcpy($$, "pa");
+ }
+ |
+ DRAWARC
+ {
+ (void)strcpy($$, "ar");
+ }
+ |
+ FLUSHSPLINE
+ {
+ (void)strcpy($$, "sp");
+ }
+ |
+ SHADELAST
+ {
+ (void)strcpy($$, "sh");
+ }
+ |
+ WHITENLAST
+ {
+ (void)strcpy($$, "wh");
+ }
+ |
+ BLACKENLAST
+ {
+ (void)strcpy($$, "bk");
+ }
+ |
+ TEXTURE
+ {
+ (void)strcpy($$, "tx");
+ }
+ |
+ INTEGER
+ {
+ (void)sprintf($$, "%d", $1);
+ }
+/* | Unfortunately this won't work since the lexeme
+ FLOAT of a float has been lost when we converted it to a
+ { real number.
+ (void)sprintf($$, "%f", $1);
+ }
+*/
+ ;
+
+textureargs : texturearg textureargs | /* epsilon */ ;
+
+texturearg : STRING | INTEGER ;
+%%
+#include "xxxlex.c"
+
+yyerror(s)
+char *s;
+{
+ return;
+}
diff --git a/dviware/quicspool/src/xxxlex.l b/dviware/quicspool/src/xxxlex.l
new file mode 100644
index 0000000000..5f48bebff1
--- /dev/null
+++ b/dviware/quicspool/src/xxxlex.l
@@ -0,0 +1,52 @@
+/* $Header: xxxlex.l,v 1.2 88/02/03 08:52:10 simpson Exp $ */
+%{
+/*
+$Log: xxxlex.l,v $
+ * Revision 1.2 88/02/03 08:52:10 simpson
+ * added tpic support
+ *
+ * Revision 1.1 88/01/15 13:06:01 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:31:28 simpson
+ * beta test
+ *
+*/
+#undef input
+#define input() (Pxxxstring && *Pxxxstring ? *Pxxxstring++ : 0)
+#undef unput
+#define unput(c) if (Pxxxstring > Xxxstring) *--Pxxxstring = c
+%}
+integer [0-9]+
+real [0-9]+\.[0-9]*|[0-9]*\.[0-9]+
+whitespace [ \t\n]+
+%%
+{integer} {
+ yylval.i = atoi(yytext);
+ return INTEGER;
+ }
+{real} {
+ yylval.f = atof(yytext);
+ return FLOAT;
+ }
+pn return PENSIZE;
+fp return FLUSHPATH;
+da return FLUSHDASHED;
+dt return FLUSHDOTTED;
+pa return ADDPATH;
+ar return DRAWARC;
+sp return FLUSHSPLINE;
+sh return SHADELAST;
+wh return WHITENLAST;
+bk return BLACKENLAST;
+tx return TEXTURE;
+[^\,\)\( \t\n]+ {
+ (void)strcpy(yylval.s, yytext);
+ if (EQ(yytext, "overlay"))
+ return OVERLAY;
+ return STRING;
+ }
+\, |
+\( |
+\) return yytext[0];
+{whitespace} ;
diff --git a/dviware/quicspool/standard/makefile b/dviware/quicspool/standard/makefile
new file mode 100644
index 0000000000..c0e2b528d0
--- /dev/null
+++ b/dviware/quicspool/standard/makefile
@@ -0,0 +1,28 @@
+# $Header: Makefile,v 1.1 88/01/15 13:07:00 simpson Rel $
+# $Log: Makefile,v $
+#Revision 1.1 88/01/15 13:07:00 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 18:34:10 simpson
+#beta test
+#
+INCLUDE=/usr/include/local
+
+all:
+
+# System include files are needed right away
+configure:
+ install -c -m 644 standard.h $(INCLUDE)
+ install -c -m 644 standmacro.h $(INCLUDE)
+ install -c -m 644 standtype.h $(INCLUDE)
+ install -c -m 644 standenviron.h $(INCLUDE)
+ install -c -m 644 standconst.h $(INCLUDE)
+
+install:
+ install -c -m 644 standard.h $(INCLUDE)
+ install -c -m 644 standmacro.h $(INCLUDE)
+ install -c -m 644 standtype.h $(INCLUDE)
+ install -c -m 644 standenviron.h $(INCLUDE)
+ install -c -m 644 standconst.h $(INCLUDE)
+
+clean:
diff --git a/dviware/quicspool/standard/makefile.trw b/dviware/quicspool/standard/makefile.trw
new file mode 100644
index 0000000000..2967f24873
--- /dev/null
+++ b/dviware/quicspool/standard/makefile.trw
@@ -0,0 +1,28 @@
+# $Header: Makefile.TRW,v 1.1 88/01/15 13:07:04 simpson Rel $
+# $Log: Makefile.TRW,v $
+#Revision 1.1 88/01/15 13:07:04 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 18:34:11 simpson
+#beta test
+#
+INCLUDE=/usr/include/local
+
+all:
+
+# System include files are needed right away
+configure:
+ install -c -m 644 standard.h $(INCLUDE)
+ install -c -m 644 standmacro.h $(INCLUDE)
+ install -c -m 644 standtype.h $(INCLUDE)
+ install -c -m 644 standenviron.h $(INCLUDE)
+ install -c -m 644 standconst.h $(INCLUDE)
+
+install:
+ install -c -m 644 standard.h $(INCLUDE)
+ install -c -m 644 standmacro.h $(INCLUDE)
+ install -c -m 644 standtype.h $(INCLUDE)
+ install -c -m 644 standenviron.h $(INCLUDE)
+ install -c -m 644 standconst.h $(INCLUDE)
+
+clean:
diff --git a/dviware/quicspool/standard/standard.h b/dviware/quicspool/standard/standard.h
new file mode 100644
index 0000000000..28ff4aae78
--- /dev/null
+++ b/dviware/quicspool/standard/standard.h
@@ -0,0 +1,14 @@
+/* $Header: standard.h,v 1.1 88/01/15 13:07:06 simpson Rel $ */
+/*
+$Log: standard.h,v $
+ * Revision 1.1 88/01/15 13:07:06 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:34:12 simpson
+ * beta test
+ *
+*/
+#include <local/standenviron.h>
+#include <local/standconst.h>
+#include <local/standtype.h>
+#include <local/standmacro.h>
diff --git a/dviware/quicspool/standard/standconst.h b/dviware/quicspool/standard/standconst.h
new file mode 100644
index 0000000000..aeb06c2bbb
--- /dev/null
+++ b/dviware/quicspool/standard/standconst.h
@@ -0,0 +1,75 @@
+/* $Header: standconst.h,v 1.1 88/01/15 13:07:08 simpson Rel $ */
+/*
+$Log: standconst.h,v $
+ * Revision 1.1 88/01/15 13:07:08 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:34:13 simpson
+ * beta test
+ *
+*/
+/* Standard constants. */
+#ifndef STANDARD_CONST
+#define STANDARD_CONST
+
+/*
+ * These are the only values boolean variables may be set to,
+ * or that boolean functions may return.
+ */
+#define TRUE 1
+#define FALSE 0
+
+/*
+ * Program exit status.
+ * These two codes are intended to be used as arguments to the
+ * exit(2) system call. Obviously, more failure codes may be
+ * defined but for simple programs that need indicate only
+ * success or failure these will suffice.
+ */
+#define SUCCEED 0 /* successful program execution */
+#define FAIL 1 /* some error in running program */
+
+/* All bits on or off. */
+#define ON ~(long)0 /* all bits set */
+#define OFF (long)0 /* all bits off */
+
+/* UNIX file descriptor numbers for standard input, output, and error. */
+#define STANDARD_IN 0
+#define STANDARD_OUT 1
+#define STANDARD_ERROR 2
+
+
+/*
+ * Extreme values.
+ * These constants are the largest and smallest values
+ * that variables of the indicated type may hold.
+ */
+#if defined(vax) || defined(pyr) || defined(sun)
+# define MAX_TINY 0x7f
+# define MIN_TINY 0x80
+
+# define MAX_UNSIGNED_TINY 0xff
+# define MIN_UNSIGNED_TINY 0
+
+# define MAX_SHORT 0x7fff
+# define MIN_SHORT 0x8000
+
+# define MAX_UNSIGNED_SHORT 0xffff
+# define MIN_UNSIGNED_SHORT 0
+
+# define MAX_INTEGER 0x7fffffff
+# define MIN_INTEGER 0x80000000
+
+# define MAX_UNSIGNED_INTEGER 0xffffffff
+# define MIN_UNSIGNED_INTEGER 0
+
+# define MAX_LONG MAX_INTEGER
+# define MIN_LONG MIN_INTEGER
+# define MAX_UNSIGNED_LONG MAX_UNSIGNED_INTEGER
+# define MIN_UNSIGNED_LONG MIN_UNSIGNED_INTEGER
+# define BITS_PER_BYTE 8
+#endif
+
+/* for pointers */
+#define NIL ((long)0)
+#endif STANDARD_CONST
diff --git a/dviware/quicspool/standard/standenviron.h b/dviware/quicspool/standard/standenviron.h
new file mode 100644
index 0000000000..081f01ea1d
--- /dev/null
+++ b/dviware/quicspool/standard/standenviron.h
@@ -0,0 +1,49 @@
+/* $Header: standenviron.h,v 1.1 88/01/15 13:07:12 simpson Rel $ */
+/*
+$Log: standenviron.h,v $
+ * Revision 1.1 88/01/15 13:07:12 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:34:14 simpson
+ * beta test
+ *
+*/
+/*
+ * This file defines the machine/compiler C environment. It defines
+ * pre-processor macros that tell what C features are supported.
+ *
+ * #define HAS_UNSIGNED_SHORT Implies unsigned shorts are supported
+ * #define CHAR_IS_SIGNED Implies chars are signed
+ * #define HAS_UNSIGNED_CHAR Implies unsigned chars are supported
+ * #define HAS_UNSIGNED_LONG Implies unsigned longs are supported
+ * #define BITS_PER_CHAR n Number of bits in a char
+ * #define BITS_PER_INT n Number of bits in an int
+ * #define BITS_PER_LONG n Number of bits in a long
+ * #define BITS_PER_POINTER n Number of bits in a pointer
+ * #define BITS_PER_SHORT n Number of bits in a short
+ * #define HAS_VOID Implies void function type is supported
+ */
+
+#ifndef STANDARD_ENVIRON /* prevent multiple inclusions */
+
+#if defined(vax) || defined(pyr) || defined(sun)
+# define HAS_UNSIGNED_SHORT
+# define CHAR_IS_SIGNED
+# define HAS_UNSIGNED_CHAR
+# define HAS_UNSIGNED_LONG
+# define HAS_VOID
+
+# define BITS_PER_CHAR 8
+# define BITS_PER_SHORT 16
+# define BITS_PER_INT 32
+# define BITS_PER_LONG 32
+# define BITS_PER_POINTER 32
+# define STANDARD_ENVIRON
+#endif
+
+#endif STANDARD_ENVIRON
+
+/* make sure a known processor type was specified */
+#ifndef STANDARD_ENVIRON
+# include "Processor type unknown or unspecified"
+#endif STANDARD_ENVIRON
diff --git a/dviware/quicspool/standard/standmacro.h b/dviware/quicspool/standard/standmacro.h
new file mode 100644
index 0000000000..bfdf987867
--- /dev/null
+++ b/dviware/quicspool/standard/standmacro.h
@@ -0,0 +1,21 @@
+/* $Header: standmacro.h,v 1.1 88/01/15 13:07:14 simpson Rel $ */
+/*
+$Log: standmacro.h,v $
+ * Revision 1.1 88/01/15 13:07:14 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:34:15 simpson
+ * beta test
+ *
+*/
+#ifndef STANDARD_MACRO
+#define STANDARD_MACRO
+#define MAX(x, y) ((x) > (y) ? (x) : (y))
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+#define ROUND(x) ((int)(((x)<0)?((x)-0.5):((x)+0.5)))
+#define CEILING(x) (((x)>=0)?(int)(x)==(x)?(int)(x):(int)((x)+1):(int)(x))
+#define FLOOR(x) (((x)>=0)?(int)(x):(int)(x)==(x)?(int)(x):(int)((x)-1))
+#define EQ(s, t) (!strcmp(s, t))
+#define EQN(s, t, n) (!strncmp(s, t, n))
+#endif STANDARD_MACRO
diff --git a/dviware/quicspool/standard/standtype.h b/dviware/quicspool/standard/standtype.h
new file mode 100644
index 0000000000..7ae0a5a44b
--- /dev/null
+++ b/dviware/quicspool/standard/standtype.h
@@ -0,0 +1,118 @@
+/* $Header: standtype.h,v 1.1 88/01/15 13:07:17 simpson Rel $ */
+/*
+$Log: standtype.h,v $
+ * Revision 1.1 88/01/15 13:07:17 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 18:34:16 simpson
+ * beta test
+ *
+*/
+/* Standard machine independent type definitions. */
+
+#ifndef STANDARD_TYPE /* prevent multiple inclusions */
+#define STANDARD_TYPE
+
+/*
+ * Integers
+ * Tiny/UnsignedTiny 8+ bit integers
+ * Short/UnsignedShort 16+ bit integers
+ * Integer/UnsignedInteger natural machine integer size
+ * Long/UnsignedLong 32+ bit integers
+ *
+ * Bits
+ * TinyBits 8+ bits
+ * Bits 16+ bits
+ * LongBits 32+ bits
+ *
+ * Booleans
+ * TinyBoolean
+ * Boolean
+ *
+ * Void
+ *
+ * Storage Classes
+ * Export Seen in other compilation units
+ * Import Supplied by another compilation unit
+ * Local Unseen outside compilation unit
+ */
+
+/*
+ * Each of the following sections for the integer types defines both
+ * a base type and an extraction macro for the value.
+ */
+
+typedef char Tiny;
+/* Not all machines have signed characters so we may have to simulate them. */
+#ifdef CHAR_IS_SIGNED
+# define TINY(x) (x)
+#else
+# define TINY(x) (((x) & MIN_TINY) ? (~MAX_TINY | (x)) : (x))
+#endif CHAR_IS_SIGNED
+
+/* Not all compilers support unsigned chars so we may have to simulate them. */
+#ifdef HAS_UNSIGNED_CHAR
+ typedef unsigned char UnsignedTiny;
+#else
+ typedef char UnsignedTiny;
+#endif HAS_UNSIGNED_CHAR
+#ifdef CHAR_IS_SIGNED
+# define UNSIGNED_TINY(x) ((x) & MAX_UNSIGNED_TINY)
+#else
+# define UNSIGNED_TINY(x) (x)
+#endif
+
+/*
+ * All compilers have signed short integers. This type is included
+ * for lexical consistency.
+ */
+typedef short Short;
+
+/* Not all compilers support unsigned shorts so we may have to simulate them. */
+#ifdef HAS_UNSIGNED_SHORT
+ typedef unsigned short UnsignedShort;
+#else
+ typedef short UnsignedShort;
+#endif
+# define UNSIGNED_SHORT(x) ((unsigned)(x) & MAX_UNSIGNED_SHORT)
+
+/* These types are solely for lexical consistency. */
+typedef int Integer;
+typedef unsigned int UnsignedInteger;
+
+typedef long Long;
+
+/* Not all compilers support unsigned longs so we may have to simulate them. */
+#ifdef HAS_UNSIGNED_LONG
+ typedef unsigned long UnsignedLong;
+# define UNSIGNED_LONG(s) ((UnsignedLong)(x))
+#else
+ typedef long UnsignedLong;
+# define UNSIGNED_LONG(x) ((long)(x) & MAX_LONG)
+#endif HAS_UNSIGNED_LONG
+
+/* Boolean types take on only the values TRUE or FALSE. */
+typedef char TinyBoolean;
+typedef short Boolean;
+
+/* This type is included for lexical consistency. */
+typedef char Character;
+
+/* Bit types are used only for bit set, clear and test operations. */
+typedef char TinyBits;
+typedef short Bits;
+typedef long LongBits;
+
+/* Not all compilers support void functions so we may have to simulate it. */
+#ifdef HAS_VOID
+# define Void void
+#else
+ typedef int Void;
+#endif
+
+/* Storage classes. */
+#define Export
+#define Import extern
+#define Local static
+
+#endif STANDARD_TYPE
diff --git a/dviware/quicspool/wbfonts/b.mf b/dviware/quicspool/wbfonts/b.mf
new file mode 100644
index 0000000000..09c8d06fb0
--- /dev/null
+++ b/dviware/quicspool/wbfonts/b.mf
@@ -0,0 +1,83 @@
+% $Header: B.mf,v 1.1 88/01/15 13:12:23 simpson Rel $
+% $Log: B.mf,v $
+%Revision 1.1 88/01/15 13:12:23 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:20 simpson
+%beta test
+%
+% Computer Modern Bold Roman 10 point
+if unknown cmbase: input cmbase fi
+
+font_identifier:="CMB"; font_size 10pt#;
+
+u#:=20/36pt#; % unit width
+width_adj#:=10/36pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=6/36pt#; % extra sidebar near uppercase serifs
+letter_fit#:=0pt#; % extra space added to all sidebars
+
+body_height#:=270/36pt#; % height of tallest characters
+asc_height#:=250/36pt#; % height of lowercase ascenders
+cap_height#:=247/36pt#; % height of caps
+fig_height#:=232/36pt#; % height of numerals
+x_height#:=160/36pt#; % height of lowercase without ascenders
+math_axis#:=90/36pt#; % axis of symmetry for math symbols
+bar_height#:=85/36pt#; % height of crossbar in lowercase e
+comma_depth#:=70/36pt#; % depth of comma below baseline
+desc_depth#:=70/36pt#; % depth of lowercase descenders
+
+crisp#:=0pt#; % diameter of serif corners
+tiny#:=13/36pt#; % diameter of rounded corners
+fine#:=10/36pt#; % diameter of sharply rounded corners
+thin_join#:=10/36pt#; % width of extrafine details
+hair#:=17/36pt#; % lowercase hairline breadth
+stem#:=41/36pt#; % lowercase stem breadth
+curve#:=46/36pt#; % lowercase curve breadth
+ess#:=38/36pt#; % breadth in middle of lowercase s
+flare#:=45/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=56/36pt#; % diameter of dots
+cap_hair#:=19/36pt#; % uppercase hairline breadth
+cap_stem#:=51/36pt#; % uppercase stem breadth
+cap_curve#:=55/36pt#; % uppercase curve breadth
+cap_ess#:=53/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=.6pt#; % thickness of lines in math symbols
+
+dish#:=1/36pt#; % amount erased at top or bottom of serifs
+bracket#:=10/36pt#; % vertical distance from serif base to tangent
+jut#:=25/36pt#; % protrusion of lowercase serifs
+cap_jut#:=34/36pt#; % protrusion of uppercase serifs
+beak_jut#:=11/36pt#; % horizontal protrusion of beak serifs
+beak#:=70/36pt#; % vertical protrusion of beak serifs
+vair#:=13/36pt#; % vertical diameter of hairlines
+notch_cut#:=10pt#; % maximum breadth above or below notches
+bar#:=17/36pt#; % lowercase bar thickness
+slab#:=17/36pt#; % serif and arm thickness
+cap_bar#:=17/36pt#; % uppercase bar thickness
+cap_band#:=17/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=10pt#; % max breadth above/below uppercase notches
+serif_drop#:=3/36pt#; % vertical drop of sloped serifs
+stem_corr#:=2/36pt#; % for small refinements of stem breadth
+vair_corr#:=1.5/36pt#; % for small refinements of hairline height
+apex_corr#:=0pt#; % extra width at diagonal junctions
+
+o#:=4/36pt#; % amount of overshoot for curves
+apex_o#:=3/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=0; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=1; % factor applied to weights of heavy characters
+math_spread:=.5; % extra openness of math symbols
+superness:=8/11; % parameter for superellipses
+superpull:=1/8; % extra openness inside bowls
+beak_darkness:=.4; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=false; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=false; % should all characters have the same width?
+variant_g:=false; % should an italic-style g be used?
+low_asterisk:=false; % should the asterisk be centered at the axis?
+math_fitting:=false; % should math-mode spacing be used?
+
+generate troman % switch to the driver file
diff --git a/dviware/quicspool/wbfonts/b.tfm b/dviware/quicspool/wbfonts/b.tfm
new file mode 100644
index 0000000000..7d87d93696
--- /dev/null
+++ b/dviware/quicspool/wbfonts/b.tfm
Binary files differ
diff --git a/dviware/quicspool/wbfonts/cw.mf b/dviware/quicspool/wbfonts/cw.mf
new file mode 100644
index 0000000000..a8a956035c
--- /dev/null
+++ b/dviware/quicspool/wbfonts/cw.mf
@@ -0,0 +1,83 @@
+% $Header: CW.mf,v 1.1 88/01/15 13:12:26 simpson Rel $
+% $Log: CW.mf,v $
+%Revision 1.1 88/01/15 13:12:26 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:21 simpson
+%beta test
+%
+% Computer Modern Typewriter Text for use with 10 point
+if unknown cmbase: input cmbase fi
+
+font_identifier:="CMTT"; font_size 10pt#;
+
+u#:=21/36pt#; % unit width
+width_adj#:=0pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=0pt#; % extra sidebar near uppercase serifs
+letter_fit#:=0pt#; % extra space added to all sidebars
+
+body_height#:=250/36pt#; % height of tallest characters
+asc_height#:=220/36pt#; % height of lowercase ascenders
+cap_height#:=220/36pt#; % height of caps
+fig_height#:=220/36pt#; % height of numerals
+x_height#:=155/36pt#; % height of lowercase without ascenders
+math_axis#:=110/36pt#; % axis of symmetry for math symbols
+bar_height#:=79/36pt#; % height of crossbar in lowercase e
+comma_depth#:=50/36pt#; % depth of comma below baseline
+desc_depth#:=80/36pt#; % depth of lowercase descenders
+
+crisp#:=22/36pt#; % diameter of serif corners
+tiny#:=22/36pt#; % diameter of rounded corners
+fine#:=21/36pt#; % diameter of sharply rounded corners
+thin_join#:=21/36pt#; % width of extrafine details
+hair#:=25/36pt#; % lowercase hairline breadth
+stem#:=25/36pt#; % lowercase stem breadth
+curve#:=25/36pt#; % lowercase curve breadth
+ess#:=22/36pt#; % breadth in middle of lowercase s
+flare#:=32/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=36/36pt#; % diameter of dots
+cap_hair#:=25/36pt#; % uppercase hairline breadth
+cap_stem#:=25/36pt#; % uppercase stem breadth
+cap_curve#:=25/36pt#; % uppercase curve breadth
+cap_ess#:=25/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=25/36pt#; % thickness of lines in math symbols
+
+dish#:=0pt#; % amount erased at top or bottom of serifs
+bracket#:=0pt#; % vertical distance from serif base to tangent
+jut#:=34/36pt#; % protrusion of lowercase serifs
+cap_jut#:=34/36pt#; % protrusion of uppercase serifs
+beak_jut#:=0pt#; % horizontal protrusion of beak serifs
+beak#:=34/36pt#; % vertical protrusion of beak serifs
+vair#:=22/36pt#; % vertical diameter of hairlines
+notch_cut#:=25/36pt#; % maximum breadth above or below notches
+bar#:=22/36pt#; % lowercase bar thickness
+slab#:=22/36pt#; % serif and arm thickness
+cap_bar#:=22/36pt#; % uppercase bar thickness
+cap_band#:=22/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=25/36pt#; % max breadth above/below uppercase notches
+serif_drop#:=0pt#; % vertical drop of sloped serifs
+stem_corr#:=0pt#; % for small refinements of stem breadth
+vair_corr#:=0pt#; % for small refinements of hairline height
+apex_corr#:=10/36pt#; % extra width at diagonal junctions
+
+o#:=4/36pt#; % amount of overshoot for curves
+apex_o#:=3/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=0; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=0.81; % factor applied to weights of heavy characters
+math_spread:=-1; % extra openness of math symbols
+superness:=1/sqrt2; % parameter for superellipses
+superpull:=0; % extra openness inside bowls
+beak_darkness:=0; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=true; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=true; % should all characters have the same width?
+variant_g:=false; % should an italic-style g be used?
+low_asterisk:=true; % should the asterisk be centered at the axis?
+math_fitting:=false; % should math-mode spacing be used?
+
+generate troman % switch to the driver file
diff --git a/dviware/quicspool/wbfonts/cw.tfm b/dviware/quicspool/wbfonts/cw.tfm
new file mode 100644
index 0000000000..b2839c81b7
--- /dev/null
+++ b/dviware/quicspool/wbfonts/cw.tfm
Binary files differ
diff --git a/dviware/quicspool/wbfonts/desc b/dviware/quicspool/wbfonts/desc
new file mode 100644
index 0000000000..f34b3c1527
--- /dev/null
+++ b/dviware/quicspool/wbfonts/desc
@@ -0,0 +1,43 @@
+# QMS QUIC printers
+# $Header: DESC,v 1.1 88/01/15 13:12:21 simpson Rel $
+# $Log: DESC,v $
+#Revision 1.1 88/01/15 13:12:21 simpson
+#initial release
+#
+#Revision 0.3 87/12/18 10:11:12 simpson
+#added l. and L. for pic dot boxes
+#
+#Revision 0.2 87/12/14 09:35:27 simpson
+#Moved S after CW in font list.
+#
+#Revision 0.1 87/12/11 19:03:59 simpson
+#beta test
+#
+fonts 5 R I B CW S
+sizes 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 24 26 28 30 32 34 36 40 44 48 0
+res 300
+hor 1
+vert 1
+unitwidth 10
+paperwidth 2550
+paperlength 3300
+charset
+\| \^ \- \_ \`
+** *A *B *G *D *E *Z *Y *H *I *K *L *M *N *C *O *P *R *S *T *U *F *X *Q *W
+*a *b *c *d *e *f *g *h *i
+*k *l *m *n *o *p *q *r *s *t *u
+*w *x *y *z +- -> <- <=
+== >=
+aa ap br bs bu bv bx ca cd
+ci co ct cu dd de dg di em en
+eq es fe fm ga gr hy
+ib if ip is lh li Li ma mi mo
+mu no ob or pd pl pp pt rg rh ru
+sb sc sl Sl sp sq sr tm tp ts ul vr
+~= ~~ rn
+lf rf lc rc lt rt lb rb
+lk rk != .. l. L.
+ua da
+12
+14 34
+fi fl ff fI fL Fi Fl
diff --git a/dviware/quicspool/wbfonts/i.mf b/dviware/quicspool/wbfonts/i.mf
new file mode 100644
index 0000000000..a017f98a11
--- /dev/null
+++ b/dviware/quicspool/wbfonts/i.mf
@@ -0,0 +1,83 @@
+% $Header: I.mf,v 1.1 88/01/15 13:12:28 simpson Rel $
+% $Log: I.mf,v $
+%Revision 1.1 88/01/15 13:12:28 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:22 simpson
+%beta test
+%
+% Computer Modern Text Italic 10 point
+if unknown cmbase: input cmbase fi
+
+font_identifier:="CMTI"; font_size 10pt#;
+
+u#:=18.4/36pt#; % unit width
+width_adj#:=0pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=5/36pt#; % extra sidebar near uppercase serifs
+letter_fit#:=9.2/36pt#; % extra space added to all sidebars
+
+body_height#:=270/36pt#; % height of tallest characters
+asc_height#:=250/36pt#; % height of lowercase ascenders
+cap_height#:=246/36pt#; % height of caps
+fig_height#:=232/36pt#; % height of numerals
+x_height#:=155/36pt#; % height of lowercase without ascenders
+math_axis#:=90/36pt#; % axis of symmetry for math symbols
+bar_height#:=87/36pt#; % height of crossbar in lowercase e
+comma_depth#:=70/36pt#; % depth of comma below baseline
+desc_depth#:=70/36pt#; % depth of lowercase descenders
+
+crisp#:=8/36pt#; % diameter of serif corners
+tiny#:=8/36pt#; % diameter of rounded corners
+fine#:=7/36pt#; % diameter of sharply rounded corners
+thin_join#:=7/36pt#; % width of extrafine details
+hair#:=11/36pt#; % lowercase hairline breadth
+stem#:=23/36pt#; % lowercase stem breadth
+curve#:=28/36pt#; % lowercase curve breadth
+ess#:=27/36pt#; % breadth in middle of lowercase s
+flare#:=29/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=38/36pt#; % diameter of dots
+cap_hair#:=11/36pt#; % uppercase hairline breadth
+cap_stem#:=29/36pt#; % uppercase stem breadth
+cap_curve#:=34/36pt#; % uppercase curve breadth
+cap_ess#:=31/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=.4pt#; % thickness of lines in math symbols
+
+dish#:=1/36pt#; % amount erased at top or bottom of serifs
+bracket#:=20/36pt#; % vertical distance from serif base to tangent
+jut#:=30/36pt#; % protrusion of lowercase serifs
+cap_jut#:=34/36pt#; % protrusion of uppercase serifs
+beak_jut#:=9/36pt#; % horizontal protrusion of beak serifs
+beak#:=70/36pt#; % vertical protrusion of beak serifs
+vair#:=8/36pt#; % vertical diameter of hairlines
+notch_cut#:=10pt#; % maximum breadth above or below notches
+bar#:=11/36pt#; % lowercase bar thickness
+slab#:=11/36pt#; % serif and arm thickness
+cap_bar#:=11/36pt#; % uppercase bar thickness
+cap_band#:=11/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=10pt#; % max breadth above/below uppercase notches
+serif_drop#:=4/36pt#; % vertical drop of sloped serifs
+stem_corr#:=1/36pt#; % for small refinements of stem breadth
+vair_corr#:=1/36pt#; % for small refinements of hairline height
+apex_corr#:=0pt#; % extra width at diagonal junctions
+
+o#:=8/36pt#; % amount of overshoot for curves
+apex_o#:=8/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=.25; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=1; % factor applied to weights of heavy characters
+math_spread:=0; % extra openness of math symbols
+superness:=1/sqrt2; % parameter for superellipses
+superpull:=1/6; % extra openness inside bowls
+beak_darkness:=11/30; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=false; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=false; % should all characters have the same width?
+variant_g:=true; % should an italic-style g be used?
+low_asterisk:=false; % should the asterisk be centered at the axis?
+math_fitting:=false; % should math-mode spacing be used?
+
+generate ttextit % switch to the driver file
diff --git a/dviware/quicspool/wbfonts/i.tfm b/dviware/quicspool/wbfonts/i.tfm
new file mode 100644
index 0000000000..90110292ec
--- /dev/null
+++ b/dviware/quicspool/wbfonts/i.tfm
Binary files differ
diff --git a/dviware/quicspool/wbfonts/makefile b/dviware/quicspool/wbfonts/makefile
new file mode 100644
index 0000000000..1ad0e0c512
--- /dev/null
+++ b/dviware/quicspool/wbfonts/makefile
@@ -0,0 +1,40 @@
+# $Header: Makefile,v 1.1 88/01/15 13:12:15 simpson Rel $
+# $Log: Makefile,v $
+#Revision 1.1 88/01/15 13:12:15 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 19:03:17 simpson
+#beta test
+#
+OTROFFFONT=/usr/lib/font
+DITROFFFONT=/usr/lib/font/devqms
+
+all: owidths diwidths desc
+
+configure:
+
+owidths:
+ ../src/tfm2ofont R.tfm I.tfm B.tfm CW.tfm
+ ../src/tfm2ofont -s S.tfm
+ cc -c ftR.c ftI.c ftB.c ftS.c ftCW.c
+ for i in ftR.o ftI.o ftB.o ftS.o ftCW.o;do \
+ mv $$i `basename $$i .o`;\
+ done
+
+diwidths:
+ ../src/tfm2difont R.tfm I.tfm B.tfm
+ ../src/tfm2difont -l fi -l ff -l fl -l ffi -l ffl -w 22 CW.tfm
+ ../src/tfm2difont -s S.tfm
+
+desc:
+ -makedev DESC
+
+install:
+ cp *pk $(DITROFFFONT)/wbfonts
+ chmod 644 $(DITROFFFONT)/wbfonts/*pk
+ for i in R I B S CW;do install -m 644 ft$$i $(OTROFFFONT); done
+ -install DESC.out $(DITROFFFONT)
+ -for i in R I B CW S;do install -m 644 $$i.out $(DITROFFFONT); done
+
+clean:
+ -rm *gf *.log *.c ft* *.out R I B S CW
diff --git a/dviware/quicspool/wbfonts/makefile.trw b/dviware/quicspool/wbfonts/makefile.trw
new file mode 100644
index 0000000000..af06a2d4a6
--- /dev/null
+++ b/dviware/quicspool/wbfonts/makefile.trw
@@ -0,0 +1,40 @@
+# $Header: Makefile.TRW,v 1.1 88/01/15 13:12:17 simpson Rel $
+# $Log: Makefile.TRW,v $
+#Revision 1.1 88/01/15 13:12:17 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 19:03:18 simpson
+#beta test
+#
+OTROFFFONT=/usr/lib/font
+DITROFFFONT=/usr/lib/font/devqms
+
+all: owidths diwidths desc
+
+configure:
+
+owidths:
+ ../src/tfm2ofont R.tfm I.tfm B.tfm CW.tfm
+ ../src/tfm2ofont -s S.tfm
+ cc -c ftR.c ftI.c ftB.c ftS.c ftCW.c
+ for i in ftR.o ftI.o ftB.o ftS.o ftCW.o;do \
+ mv $$i `basename $$i .o`;\
+ done
+
+diwidths:
+ ../src/tfm2difont R.tfm I.tfm B.tfm
+ ../src/tfm2difont -l fi -l ff -l fl -l ffi -l ffl -w 22 CW.tfm
+ ../src/tfm2difont -s S.tfm
+
+desc:
+ -makedev DESC
+
+install:
+ cp *pk $(DITROFFFONT)/wbfonts
+ chmod 644 $(DITROFFFONT)/wbfonts/*pk
+ for i in R I B S CW;do install -m 644 ft$$i $(OTROFFFONT); done
+ -install DESC.out $(DITROFFFONT)
+ -for i in R I B CW S;do install -m 644 $$i.out $(DITROFFFONT); done
+
+clean:
+ -rm *gf *.log *.c ft* *.out R I B S CW
diff --git a/dviware/quicspool/wbfonts/makefonts b/dviware/quicspool/wbfonts/makefonts
new file mode 100644
index 0000000000..90ccf303bc
--- /dev/null
+++ b/dviware/quicspool/wbfonts/makefonts
@@ -0,0 +1,30 @@
+#! /bin/sh
+# $Header: makefonts,v 1.1 88/01/15 13:12:19 simpson Rel $
+# $Log: makefonts,v $
+#Revision 1.1 88/01/15 13:12:19 simpson
+#initial release
+#
+#Revision 0.1 88/01/15 13:11:04 simpson
+#beta test
+#
+# Creates the sizes
+# 4 to 20
+# 22 to 36 step 2
+# 40 to 48 step 4
+# using METAFONT
+fontlist="`grep '^fonts' DESC | sed 's/fonts [0-9][0-9]* //'`"
+for font in $fontlist; do
+ i=4
+ while [ $i -le 48 ];do
+# Use mode type imagen for a write-black engine
+ mf '\mode:=imagen;' "mag:=$i/10;" input $font
+ gftopk $font.`expr $i \* 300 / 10`gf
+ if [ $i -ge 20 -a $i -le 34 ]; then
+ i=`expr $i + 2`
+ elif [ $i -ge 36 ]; then
+ i=`expr $i + 4`
+ else
+ i=`expr $i + 1`
+ fi
+ done
+done
diff --git a/dviware/quicspool/wbfonts/r.mf b/dviware/quicspool/wbfonts/r.mf
new file mode 100644
index 0000000000..dc4aa183ed
--- /dev/null
+++ b/dviware/quicspool/wbfonts/r.mf
@@ -0,0 +1,83 @@
+% $Header: R.mf,v 1.1 88/01/15 13:12:30 simpson Rel $
+% $Log: R.mf,v $
+%Revision 1.1 88/01/15 13:12:30 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:23 simpson
+%beta test
+%
+% Computer Modern Roman 10 point
+if unknown cmbase: input cmbase fi
+
+font_identifier:="TCMR"; font_size 10pt#;
+
+u#:=20/36pt#; % unit width
+width_adj#:=0pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=5/36pt#; % extra sidebar near uppercase serifs
+letter_fit#:=0pt#; % extra space added to all sidebars
+
+body_height#:=270/36pt#; % height of tallest characters
+asc_height#:=250/36pt#; % height of lowercase ascenders
+cap_height#:=246/36pt#; % height of caps
+fig_height#:=232/36pt#; % height of numerals
+x_height#:=155/36pt#; % height of lowercase without ascenders
+math_axis#:=90/36pt#; % axis of symmetry for math symbols
+bar_height#:=87/36pt#; % height of crossbar in lowercase e
+comma_depth#:=70/36pt#; % depth of comma below baseline
+desc_depth#:=70/36pt#; % depth of lowercase descenders
+
+crisp#:=0pt#; % diameter of serif corners
+tiny#:=8/36pt#; % diameter of rounded corners
+fine#:=7/36pt#; % diameter of sharply rounded corners
+thin_join#:=7/36pt#; % width of extrafine details
+hair#:=9/36pt#; % lowercase hairline breadth
+stem#:=25/36pt#; % lowercase stem breadth
+curve#:=30/36pt#; % lowercase curve breadth
+ess#:=27/36pt#; % breadth in middle of lowercase s
+flare#:=33/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=38/36pt#; % diameter of dots
+cap_hair#:=11/36pt#; % uppercase hairline breadth
+cap_stem#:=32/36pt#; % uppercase stem breadth
+cap_curve#:=37/36pt#; % uppercase curve breadth
+cap_ess#:=35/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=.4pt#; % thickness of lines in math symbols
+
+dish#:=1/36pt#; % amount erased at top or bottom of serifs
+bracket#:=20/36pt#; % vertical distance from serif base to tangent
+jut#:=28/36pt#; % protrusion of lowercase serifs
+cap_jut#:=37/36pt#; % protrusion of uppercase serifs
+beak_jut#:=10/36pt#; % horizontal protrusion of beak serifs
+beak#:=70/36pt#; % vertical protrusion of beak serifs
+vair#:=8/36pt#; % vertical diameter of hairlines
+notch_cut#:=10pt#; % maximum breadth above or below notches
+bar#:=11/36pt#; % lowercase bar thickness
+slab#:=11/36pt#; % serif and arm thickness
+cap_bar#:=11/36pt#; % uppercase bar thickness
+cap_band#:=11/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=10pt#; % max breadth above/below uppercase notches
+serif_drop#:=4/36pt#; % vertical drop of sloped serifs
+stem_corr#:=1/36pt#; % for small refinements of stem breadth
+vair_corr#:=1/36pt#; % for small refinements of hairline height
+apex_corr#:=0pt#; % extra width at diagonal junctions
+
+o#:=8/36pt#; % amount of overshoot for curves
+apex_o#:=8/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=0; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=1; % factor applied to weights of heavy characters
+math_spread:=0; % extra openness of math symbols
+superness:=1/sqrt2; % parameter for superellipses
+superpull:=1/6; % extra openness inside bowls
+beak_darkness:=11/30; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=false; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=false; % should all characters have the same width?
+variant_g:=false; % should an italic-style g be used?
+low_asterisk:=false; % should the asterisk be centered at the axis?
+math_fitting:=false; % should math-mode spacing be used?
+
+generate troman % switch to the driver file
diff --git a/dviware/quicspool/wbfonts/r.tfm b/dviware/quicspool/wbfonts/r.tfm
new file mode 100644
index 0000000000..6fcd675997
--- /dev/null
+++ b/dviware/quicspool/wbfonts/r.tfm
Binary files differ
diff --git a/dviware/quicspool/wbfonts/s.mf b/dviware/quicspool/wbfonts/s.mf
new file mode 100644
index 0000000000..635b7a4875
--- /dev/null
+++ b/dviware/quicspool/wbfonts/s.mf
@@ -0,0 +1,83 @@
+% $Header: S.mf,v 1.1 88/01/15 13:12:32 simpson Rel $
+% $Log: S.mf,v $
+%Revision 1.1 88/01/15 13:12:32 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:24 simpson
+%beta test
+%
+% Computer Modern Math Italic 10 point
+if unknown cmbase: input cmbase fi
+
+font_identifier:="CMMI"; font_size 10pt#;
+
+u#:=20/36pt#; % unit width
+width_adj#:=0pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=5/36pt#; % extra sidebar near uppercase serifs
+letter_fit#:=0pt#; % extra space added to all sidebars
+
+body_height#:=270/36pt#; % height of tallest characters
+asc_height#:=250/36pt#; % height of lowercase ascenders
+cap_height#:=246/36pt#; % height of caps
+fig_height#:=232/36pt#; % height of numerals
+x_height#:=155/36pt#; % height of lowercase without ascenders
+math_axis#:=90/36pt#; % axis of symmetry for math symbols
+bar_height#:=87/36pt#; % height of crossbar in lowercase e
+comma_depth#:=70/36pt#; % depth of comma below baseline
+desc_depth#:=70/36pt#; % depth of lowercase descenders
+
+crisp#:=8/36pt#; % diameter of serif corners
+tiny#:=8/36pt#; % diameter of rounded corners
+fine#:=7/36pt#; % diameter of sharply rounded corners
+thin_join#:=7/36pt#; % width of extrafine details
+hair#:=9/36pt#; % lowercase hairline breadth
+stem#:=24/36pt#; % lowercase stem breadth
+curve#:=29/36pt#; % lowercase curve breadth
+ess#:=27/36pt#; % breadth in middle of lowercase s
+flare#:=32/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=38/36pt#; % diameter of dots
+cap_hair#:=11/36pt#; % uppercase hairline breadth
+cap_stem#:=30/36pt#; % uppercase stem breadth
+cap_curve#:=35/36pt#; % uppercase curve breadth
+cap_ess#:=33/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=.4pt#; % thickness of lines in math symbols
+
+dish#:=1/36pt#; % amount erased at top or bottom of serifs
+bracket#:=20/36pt#; % vertical distance from serif base to tangent
+jut#:=30/36pt#; % protrusion of lowercase serifs
+cap_jut#:=37/36pt#; % protrusion of uppercase serifs
+beak_jut#:=10/36pt#; % horizontal protrusion of beak serifs
+beak#:=70/36pt#; % vertical protrusion of beak serifs
+vair#:=8/36pt#; % vertical diameter of hairlines
+notch_cut#:=10pt#; % maximum breadth above or below notches
+bar#:=11/36pt#; % lowercase bar thickness
+slab#:=11/36pt#; % serif and arm thickness
+cap_bar#:=11/36pt#; % uppercase bar thickness
+cap_band#:=11/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=10pt#; % max breadth above/below uppercase notches
+serif_drop#:=4/36pt#; % vertical drop of sloped serifs
+stem_corr#:=1/36pt#; % for small refinements of stem breadth
+vair_corr#:=1/36pt#; % for small refinements of hairline height
+apex_corr#:=0pt#; % extra width at diagonal junctions
+
+o#:=8/36pt#; % amount of overshoot for curves
+apex_o#:=8/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=.25; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=1; % factor applied to weights of heavy characters
+math_spread:=0; % extra openness of math symbols
+superness:=1/sqrt2; % parameter for superellipses
+superpull:=1/6; % extra openness inside bowls
+beak_darkness:=11/30; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=false; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=false; % should all characters have the same width?
+variant_g:=true; % should an italic-style g be used?
+low_asterisk:=false; % should the asterisk be centered at the axis?
+math_fitting:=true; % should math-mode spacing be used?
+
+generate tmathit % switch to the driver file
diff --git a/dviware/quicspool/wbfonts/s.tfm b/dviware/quicspool/wbfonts/s.tfm
new file mode 100644
index 0000000000..529fe0dbd0
--- /dev/null
+++ b/dviware/quicspool/wbfonts/s.tfm
Binary files differ
diff --git a/dviware/quicspool/wbfonts/tcomlig.mf b/dviware/quicspool/wbfonts/tcomlig.mf
new file mode 100644
index 0000000000..bf3c521099
--- /dev/null
+++ b/dviware/quicspool/wbfonts/tcomlig.mf
@@ -0,0 +1,21 @@
+% $Header: tcomlig.mf,v 1.1 88/01/15 13:12:35 simpson Rel $
+% $Log: tcomlig.mf,v $
+%Revision 1.1 88/01/15 13:12:35 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:25 simpson
+%beta test
+%
+% This file defines characters common to roman and italic text fonts
+% that appear only when |ligs>0|.
+
+% Character codes \006 is generated
+
+cmchar "Em dash";
+beginchar(oct"006",18u#,x_height#,0);
+italcorr .61803x_height#*slant+.5u#;
+adjust_fit(letter_fit#,letter_fit#);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(.61803h+.5vair); lft x1=-eps; rt x2=w+eps;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
diff --git a/dviware/quicspool/wbfonts/tgreekl.mf b/dviware/quicspool/wbfonts/tgreekl.mf
new file mode 100644
index 0000000000..19f370ed41
--- /dev/null
+++ b/dviware/quicspool/wbfonts/tgreekl.mf
@@ -0,0 +1,418 @@
+% $Header: tgreekl.mf,v 1.1 88/01/15 13:12:37 simpson Rel $
+% $Log: tgreekl.mf,v $
+%Revision 1.1 88/01/15 13:12:37 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:27 simpson
+%beta test
+%
+% This lowercase Greek alphabet was prepared by D. E. Knuth in December, 1979,
+% inspired by the Monotype faces used in {\sl The Art of Computer Programming}.
+% (It has been designed for math formulas, not Greek texts.)
+% The programs were revised for the new \MF\ conventions in 1985.
+
+cmchar "Lowercase Greek alpha";
+beginchar(oct"141",11u#,x_height#,0);
+italcorr max(1/3x_height#*slant+.5hair#+.5u#,x_height#*slant-.5u#);
+adjust_fit(0,0); pickup fine.nib;
+pos0(hair,0); pos1(vair,-90); pos2(curve,-180); pos3(vair,-270);
+z4=(w-3.25u,9/16h); z5=(w-2.75u,.5[vair,y4]);
+numeric theta; theta=angle(z4-z5)-90;
+pos4(stem,theta); pos5(stem,theta);
+pos6(vair,90); pos7(hair,180);
+rt x0r=hround(w-u); x1=x3=.5w-u; lft x2r=hround(1.5u-.5curve);
+x6=w-u; x7+.5hair=hround(w+.5hair-epsilon);
+top y0=vround .8[bar_height,h]; bot y1r=bot y6l=-oo;
+y2=.5[y1,y3]; top y3r=h+oo; y7=1/4bar_height;
+filldraw stroke z0e{down}...pulled_arc.e(1,2) & pulled_arc.e(2,3)
+ ...z4e---z5e...z6e{right}...{up}z7e; % diagonal, bowl, and hook
+math_fit(-.3x_height#*slant+.5curve#-u#,1/3x_height#*slant+.5hair#+.5u#);
+penlabels(0,1,2,3,4,5,6,7); endchar;
+
+cmchar "Lowercase Greek beta";
+beginchar(oct"142",9.5u#,asc_height#,desc_depth#);
+italcorr .5[x_height#,asc_height#]*slant-u#;
+adjust_fit(0,0); pickup fine.nib;
+pos0(hair,180); pos1(hair,180); pos2(vair,90);
+pos3(stem,0); pos4(vair,-90); pos5(hair,-180);
+pos6(vair,-270); pos7(curve,-360); pos8(vair,-450); pos9(hair,-540);
+x0=x1=x9; lft x0l=hround(1.5u-.5hair); x2=x4=x6=x8=.5w+.25u;
+rt x3r=hround(w-1.5u); rt x7r=hround(w-1.5u+.5curve); rt x5l=hround(x4-u);
+bot y0=-d; y1=top y6r=x_height; top y2r=h+oo; y3=.5[y2,y4];
+y5=.5[y4,y6]; top y6r-bot y4r=vstem+eps; bot y8=-oo; y7=y9=.5[y6,y8];
+if y6l<y4l: y6l:=y4l:=y5; fi
+filldraw stroke z0e---z1e...pulled_arc.e(2,3)
+ & pulled_arc.e(3,4)...{up}z5e; % stem and upper bowl
+filldraw stroke z5e{up}...pulled_arc.e(6,7)
+ & pulled_arc.e(7,8)...{up}z9e; % lower bowl
+math_fit(desc_depth#*slant+.5hair#-u#,.7x_height#*slant+.5curve#-1.5u#);
+penlabels(0,1,2,3,4,5,6,7,8,9); endchar;
+
+cmchar "Lowercase Greek gamma";
+beginchar(oct"143",10u#,x_height#,desc_depth#);
+italcorr x_height#*slant-.5u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(hair,180); pos2(vstem+dw,90);
+pos4(hair,0); pos5(vair,-90); pos6(hair,-180); pos7(hair,-180);
+bot y1=.5772156649h; top y2r=h+oo; y4=y6=-.5d;
+bot y5r=-d-o; top y7=h;
+lft x1r=hround(.5u-.5hair); x2=3u; rt x4r=hround(w-2u); x5=.5[x4,x6];
+rt x4r-lft x6r=hround 1/3[hair,stem]+eps; rt x7l=hround(w-u);
+if x4l<x6l: x4l:=x6l:=x5; fi
+pos3(hair,angle(z4-z2)+90); x3=superness[x2,x4]; y3=superness[y4,y2];
+filldraw stroke z1e{up}...z2e{right}...z3e{z4-z2}
+ ...z4e{down}...{left}z5e; % arc
+filldraw stroke z5e{left}...z6e{up}..{2(x7-x6),y7-y6}z7e; % stem
+math_fit(-.5772156649x_height#*slant,ic#-u#);
+penlabels(1,2,3,4,5,6,7); endchar;
+
+cmchar "Lowercase Greek delta";
+beginchar(oct"144",8u#,asc_height#,0);
+italcorr .9asc_height#*slant+.5hair#-1.5u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(hair,-180); pos2(vair,-90);
+numeric theta; theta=angle(18u,-h);
+pos3(stem,theta+90); pos4(stem,theta+90); pos5(1/4[hair,stem],20);
+pos6(vair,-90); pos7(curve,-180); pos8(vair,-270);
+rt x1l=hround(w-2u+.5hair); x2=.5w; x3r=3u; rt x5r=hround(w-u);
+x4=x6=x8=.5w+.5u; lft x7r=hround(1.5u-.5curve);
+y1=.9h; top y2l=h+oo; top y8r=x_height+oo; y4=y8;
+z4-z3=whatever*(18u,-h); y5=y7=.5[y6,y8]; bot y6=-oo;
+filldraw stroke z1e{x2-x1,3(y2-y1)}...z2e{left}...z3e---z4e
+ ....z5e{down}...pulled_arc.e(6,7) & pulled_arc.e(7,8); % hook and bowl
+math_fit(-.3x_height#*slant+.5curve#-u#,.7x_height#*slant-.5u#);
+penlabels(1,2,3,4,5,6,7,8); endchar;
+
+cmchar "Lowercase Greek epsilon";
+beginchar(oct"145",8u#,x_height#,0);
+italcorr x_height#*slant+.5hair#-2u#;
+adjust_fit(0,0); pickup fine.nib;
+pos0(bar,90); pos1(bar,90); pos2(curve,180);
+pos3(vair,270); pos4(hair,300); pos6(bar,90); pos7(bar,90);
+x1=.5w+.5u; x0=x1+u; lft x2r=hround(1.5u-.5curve); x3=.5[x0,x1];
+x4r=good.x(w-u); x5=w+.5u; x6=x0; z7=z2l;
+top y0r=top y1r=h; y2=y5=y6=bar_height; bot y3r=-oo;
+path p; p=z3r{right}...{up}z5;
+numeric t; t=ypart(((x4r,y3r)--(x4r,y5))intersectiontimes p);
+y4r=ypart point t of p;
+filldraw circ_stroke z0e..pulled_arc.e(1,2) & pulled_arc.e(2,3)
+ ...z4e{direction t of p}; % arc
+filldraw circ_stroke z6e--z7e; % bar
+math_fit(-.3x_height#*slant+.5curve#-u#,ic#);
+penlabels(0,1,2,3,4,5,6,7); endchar;
+
+cmchar "Lowercase Greek zeta";
+beginchar(oct"146",9u#,asc_height#,desc_depth#);
+italcorr .75[x_height#,asc_height#]*slant-1.5u#;
+adjust_fit(0,0); pickup fine.nib;
+pos0(hair,-360); pos1(vair,-270); pos2(hair,-180); pos3(vair,-90);
+numeric theta; theta=90-angle(25u,x_height); slope:=-x_height/25u;
+pos6(stem,theta); pos7(vair,-90); pos8(vair,-135);
+lft x0l=hround 3.5u; x1=x3=.5[x0,x2]; rt x2l=hround max(rt x0r,w-2u)+eps;
+top y0=h; top y3l=bot y1l+vstem+eps=vround(y0-.25(h-x_height)); y2=.5[y1,y3];
+if y1r>y3r: y1r:=y3r:=y2; fi
+lft x4l=hround u; x4r-x4l=(hround .6[vair,stem])-fine;
+x6+.5u=x7=w-2u; x8=.5w+.75u;
+y6=-.1d; y8=-3/4d-oo; bot y7r=-d-oo;
+ellipse_set(3l,4l,5l,6l); ellipse_set(3r,4r,5r,6r);
+y4l:=.9[y6,y4l]; y4=y4r:=.9[y6,y4r];
+filldraw circ_stroke z0e{down}...z1e{right}...{up}z2e; % opening hook
+filldraw circ_stroke z8e{x7-x8,2(y7-y8)}...z7e{right}
+ ...z6e---z5e....{up}z4e
+ ..tension 1 and atleast1.5..{right}z3e...{down}z2e; % main stroke
+math_fit(-.2asc_height#*slant-.5u#,0);
+penlabels(0,1,2,3,4,5,6,7,8); endchar;
+
+cmchar "Lowercase Greek eta";
+beginchar(oct"147",9u#,x_height#,desc_depth#);
+italcorr .8x_height#*slant+.5stem#-u#;
+adjust_fit(0,0); pickup fine.nib;
+x0=0; x1=x2; pos2(stem,0); lft x2l=hround(2.5u-.5stem); y2-.5stem=-oo;
+hook_in(0,a,1); % opening hook
+filldraw circ_stroke z2e--z1e; % left stem
+x4+.5stem=hround(w-1.5u+.5stem); ital_arch(2,3,4); % arch
+pos5(stem,0); x5=x4; y5-.5stem=-d-o;
+filldraw circ_stroke z5e--z4e; % right stem
+math_fit(-2/3x_height#*slant+.5hair#+.5u#,ic#-1/3x_height#*slant);
+penlabels(0,a,1,2,3,4,5); endchar;
+
+cmchar "Lowercase Greek theta";
+beginchar(oct"150",8.25u#,asc_height#,0);
+italcorr .7asc_height#*slant+.5curve#-u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(vair,90); pos2(curve,180); pos3(vair,270); pos4(curve,360);
+x1=x3=.5w; lft x2r=hround(1.5u-.5curve); x4=w-x2;
+top y1r=h+oo; y2=y4=.5[y1,y3]; bot y3r=-oo;
+filldraw stroke pulled_arc.e(1,2) & pulled_arc.e(2,3)
+ & pulled_arc.e(3,4) & pulled_arc.e(4,1); % bowl
+pos2'(bar,90); pos4'(bar,90); z2'=z2l; z4'=z4l;
+filldraw stroke z2'e--z4'e; % bar
+math_fit(-.3asc_height#*slant-u#+.5curve#,ic#-.5u#);
+penlabels(1,2,3,4); endchar;
+
+cmchar "Lowercase Greek iota";
+beginchar(oct"151",5u#,x_height#,0);
+italcorr 1/3x_height#*slant+.5hair#+.5u#;
+adjust_fit(if monospace: u#,u# else: 0,0 fi); pickup fine.nib;
+pos1(stem,0); lft x1l=hround(1.5u-.5stem); y1+.5stem=h+oo;
+x2=x1-.25u; x4=w; hook_out(2,3,4)(skewed); % closing hook
+filldraw circ_stroke z1e{down}...{-u,-x_height}z2e; % stem
+math_fit(0,ic#); penlabels(1,2,3,4); endchar;
+
+cmchar "Lowercase Greek kappa";
+beginchar(oct"152",9u#,x_height#,0);
+italcorr 1/3x_height#*slant+.5hair#+.5u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(stem,0); pos2(stem,0); pos3(vair,90); pos4(vair,90); pos5(flare,90);
+x1=x2=x3; lft x1l=hround(1.5u-.5stem); y1+.5stem=h+oo; y2-.5stem=-oo;
+filldraw z1l---z2l..z2r---z1r..cycle; % stem
+y3=bar_height; top y4r=h; x4+.5flare=hround(w-1.5u); z5r=z4r;
+path p,q; p=z3l{right}..{right}z4l; q=z5r{right}..z5l{left}...cycle;
+numeric t; t=ypart(p intersectiontimes q);
+filldraw stroke z3e{right}..{right}z4e; % upper diagonal
+filldraw subpath(0,t) of q--cycle; % bulb
+pos7(stem,0); pos8(vair,90); pos9(hair,180);
+x9+.5hair=hround(w+.5hair-epsilon); y9=1/3x_height;
+lft x7l=hround(w-2.75u-.5stem); y7=1/2y3; x8=w-1.2u; bot y8l=-oo;
+filldraw stroke z3e{right}...z7e{down}
+ ...z8e{right}...{up}z9e; % lower diagonal
+math_fit(0,ic#); penlabels(1,2,3,4,5,7,8,9); endchar;
+
+cmchar "Lowercase Greek lambda";
+beginchar(oct"153",10.5u#,asc_height#,0);
+adjust_fit(0,0); pickup fine.nib;
+pos1(vair,90); lft x1=hround .1u; top y1r=h;
+x2=x1+2u; y2=.7[x_height,h]; x3=w-2u; bot y4=-oo; y3=max(.07h,y4+eps);
+z4-(.25u,0)=whatever[z2,z3]; numeric theta; theta=angle(z2-z3)-90;
+pos2(stem,theta); pos3(stem,theta); pos4(stem,0);
+filldraw circ_stroke z1e{right}...z2e---z3e
+ ...{2(x4e-x3e),y4e-y3e}z4e; % long diagonal
+y5=.5[bar_height,x_height]; z5=whatever[z2,z3];
+x6=1.5u; y6-.5stem=-oo; pos5(hair,theta-90); pos6(stem,angle(z5-z6)-90);
+filldraw circ_stroke z6e--z5e; % short diagonal
+penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Lowercase Greek mu";
+beginchar(oct"154",9u#,x_height#,desc_depth#);
+italcorr 1/3x_height#*slant+.5hair#+.5u#;
+adjust_fit(0,0); pickup fine.nib; interim superness:=more_super;
+pos1(stem,-180); pos2(stem,-180); x1=x2=x3; lft x1r=hround(1.5u-.5stem);
+y1+.5stem=h+oo; y2-.5stem=-d-o;
+filldraw z1r---z2r..z2l---z1l..cycle; % left stem
+pos3(stem,-180); pos4(vair,-90); pos5(hair,0); x4=.5[x3,x5];
+pos6(stem,0); rt x6r=hround(w-2.5u+.5stem);
+x5=x6=x7; x9=w; hook_out(7,8,9); % closing hook
+y3=.7[y4,y5]; bot y4r=-oo; y5=.57h; y6+.5stem=h;
+filldraw stroke super_arc.e(3,4)...{up}z5e; % left stem and arc
+filldraw circ_stroke z6e--z7e; % right stem
+math_fit(desc_depth#*slant+.5stem#-u#,ic#);
+penlabels(1,2,3,4,5,6,7,8,9); endchar;
+
+cmchar "Lowercase Greek nu";
+beginchar(oct"155",8.5u#,x_height#,0);
+italcorr x_height#*slant+.5stem#-u#;
+adjust_fit(0,0); pickup fine.nib;
+pos3(vair,-90); pos4(stem,0); bot y3r=0; y4+.5stem=h+oo;
+x3-.5stem=hround(1.5u-.5stem); x4+.5stem=hround(w-1.5u+.5stem);
+filldraw circ_stroke z4e{down}...{-36u,-h}z3e; % diagonal
+pickup tiny.nib; pos1(stem,0); pos2(stem,0);
+top y1=h+min(oo,serif_drop); bot y2=0; x1=x2=x3;
+z=((z4{down}...{-36u,-h}z3)intersectionpoint((x2r,0)--(x2r,h)));
+filldraw z1l--z2l--z--z1r--cycle; % stem
+sloped_serif.l(1,2,a,1/3,jut,serif_drop); % upper left serif
+math_fit(0,ic#-1/3x_height#*slant-.5u#); penlabels(1,2,3,4); endchar;
+
+cmchar "Lowercase Greek xi";
+beginchar(oct"156",9u#,asc_height#,desc_depth#);
+italcorr .75[x_height#,asc_height#]*slant-2u#;
+adjust_fit(0,0); pickup fine.nib;
+pos10(hair,-720); pos11(vair,-630); pos12(hair,-540); pos13(vair,-450);
+lft x10l=hround 1/3w; x11=x13=.5[x10,x12]; rt x12l=hround(w-2.5u);
+top y10=h; top y13l=bot y11l+vstem+eps=vround(y10-.25(h-x_height));
+y12=.5[y11,y13]; if y11r>y13r: y11r:=y13r:=y12; fi
+pos0(curve,-360); pos1(vair,-270); pos2(hair,-180); pos3(vair,-90);
+numeric theta; theta=90-angle(22u,x_height); slope:=-x_height/22u;
+pos6(stem,theta); pos7(vair,-90); pos8(vair,-135);
+lft x0l=hround u; x1=x3=x11; x2=x12;
+y0=.5[y13,y1]; top y3l=vround .5h=bot y1l+vstem+eps; y2=.5[y1,y3];
+if y1r>y3r: y1r:=y3r:=y2; fi
+lft x4l=hround u; x4r-x4l=hround .5[vair,stem]-fine;
+x6=x7=w-2u; x8=.5w+.5u; y6=-.3d; y8=-3/4d-oo; bot y7r=-d-oo;
+ellipse_set(3l,4l,5l,6l); ellipse_set(3r,4r,5r,6r);
+y4l:=.9[y6,y4l]; y4=y4r:=.9[y6,y4r];
+filldraw circ_stroke z10e{down}...z11e{right}...{up}z12e; % opening hook
+filldraw stroke z12e{up}...z13e{left}...z0e{down}
+ ...z1e{right}...{up}z2e; % upper arc
+filldraw circ_stroke z8e{x7-x8,2(y7-y8)}...z7e{right}...z6e
+ ---z5e...{up}z4e...{right}z3e...{down}z2e; % main stroke
+math_fit(-.2asc_height#*slant-.5u#,0);
+penlabels(0,1,2,3,4,5,6,7,8,10,11,12,13); endchar;
+
+% Stolen from romanl.mf
+cmchar "Lowercase Greek omicron";
+beginchar(oct"157",9u#,x_height#,0);
+italcorr .7x_height#*slant;
+adjust_fit(if monospace: .5u#,.5u# else: 0,0 fi);
+penpos1(vair,90); penpos3(vair',-90);
+penpos2(curve,180); penpos4(curve,0);
+x2r=hround max(.5u,1.25u-.5curve);
+x4r=w-x2r; x1=x3=.5w; y1r=h+vround 1.5oo; y3r=-oo;
+y2=y4=.5h-vair_corr; y2l:=y4l:=.52h;
+penstroke pulled_arc.e(1,2) & pulled_arc.e(2,3)
+ & pulled_arc.e(3,4) & pulled_arc.e(4,1) & cycle; % bowl
+penlabels(1,2,3,4); endchar;
+
+cmchar "Lowercase Greek pi";
+beginchar(oct"160",10u#,x_height#,0);
+italcorr x_height#*slant+.5stem#-u#;
+adjust_fit(0,0); pi_stroke; % hook and bar
+pos4(hair,0); pos6(hair,0); x4=3.5u; x6=w-4u; y4=y6=y2;
+x5=3u; x7=w-2.5u; y5=y7=.5stem-oo;
+pair v[]; v1=(z4-z5) xscaled 3.14159; v2=(z6-z7) xscaled 3.14159;
+pos5(stem,angle v1-90); pos7(stem,angle v2-90);
+filldraw circ_stroke z5e{v1}...{up}z4e; % left stem
+filldraw circ_stroke z7e{v2}...{up}z6e; % right stem
+math_fit(-.7x_height#*slant+.5hair#+.5u#,ic#-1/3x_height#*slant);
+penlabels(1,2,3,4,5,6,7); endchar;
+
+cmchar "Lowercase Greek rho";
+beginchar(oct"161",8.25u#,x_height#,desc_depth#);
+italcorr .7x_height#*slant+.5curve#-u# if math_fitting:-.5u# fi;
+adjust_fit(0,0); pickup fine.nib;
+pos1(stem,180); pos2(stem,180); pos3(vair,90);
+pos4(curve,0); pos5(vair,-90); pos6(hair,-180);
+lft x2r=hround(1.5u-.5stem); x1=x2=x6; x3=x5=.5[x2,x4];
+rt x4r=hround(w-1.5u+.5curve);
+y1-.5stem=-d-o; y2=y4=y6=.5[y3,y5]; top y3r=h+oo; bot y5r=-oo;
+filldraw circ_stroke z1e..pulled_arc.e(2,3) & pulled_arc.e(3,4)
+ & pulled_arc.e(4,5) & pulled_arc.e(5,6); % stem and bowl
+math_fit(desc_depth#*slant+.5stem#-u#,ic#);
+penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Lowercase Greek sigma";
+beginchar(oct"162",10.25u#,x_height#,0);
+italcorr x_height#*slant+.5stem#-u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(vstem,90); pos2(stem,0); pos3(vair,-90);
+pos4(stem,-180); pos5(vstem,-270); pos6(vstem,-270);
+x1=x3=x5=.5[x2,x4]; rt x2r=hround(w-2.5u);
+lft x4r=hround(1.5u-.5curve);x6=w-1.5u;
+top y1r=h; y2=y4=.5[y1,y3]; bot y3r=-oo; y5=y6=y1;
+filldraw circ_stroke z6e..pulled_arc.e(5,4) & pulled_arc.e(4,3)
+ & pulled_arc.e(3,2) & pulled_arc.e(2,1); % ear and bowl
+math_fit(-.3x_height#*slant+.5curve#-u#,ic#-1/3x_height#*slant);
+penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Lowercase Greek tau";
+beginchar(oct"163",9u#,x_height#,0);
+italcorr x_height#*slant+.5stem#-u#;
+adjust_fit(0,0); pi_stroke; % hook and bar
+pos4(hair,0); pos5(stem,0);
+x4=x5; x5-.5stem=hround(.5w-.5u-.5stem); y4=y2; y5-.5stem=-oo;
+filldraw circ_stroke z5e--z4e; % stem
+math_fit(-.7x_height#*slant+.5hair#+.5u#,-.5u#);
+penlabels(1,2,3,4,5); endchar;
+
+cmchar "Lowercase Greek upsilon";
+beginchar(oct"164",9u#,x_height#,0);
+italcorr x_height#*slant;
+adjust_fit(0,0); pickup fine.nib; interim superness:=more_super;
+x0=0; x2=x3+.25u; pos3(stem,-180); lft x3r=hround(2.5u-.5stem);
+hook_in(0,1,2)(skewed); % opening hook
+pos2'(stem,-180); z2'=z2; pos4(vair,-90); pos5(hair,0);
+x4=.5w+u; rt x5r=hround(w-.5u); y3=.7[y4,y5]; bot y4r=-oo; y5=.57h;
+filldraw stroke z2'e{-u,-x_height}...super_arc.e(3,4)
+ ..tension atleast 1.05..{up}z5e; % left stem and arc
+v_bulb(5,6); % closing bulb
+math_fit(-2/3x_height#*slant+.5hair#+.5u#,2/3ic#);
+penlabels(0,1,2,3,4,5,6); endchar;
+
+cmchar "Lowercase Greek phi";
+beginchar(oct"165",11u#,asc_height#,desc_depth#);
+italcorr .7x_height#*slant+.5curve#-u# if math_fitting:-.5u# fi;
+adjust_fit(0,0); pickup fine.nib;
+numeric light_curve; light_curve=hround(.5[stem,curve]-2stem_corr);
+pos1(vair,90); pos2(light_curve,180); pos3(vair,270); pos4(light_curve,360);
+x1=x3=.5w; lft x2r=hround(1.5u-.5light_curve); x4=w-x2;
+top y1=x_height+oo; y2=y4=.5[y1,y3]; bot y3=-oo;
+filldraw stroke pulled_arc.e(1,2) & pulled_arc.e(2,3)
+ & pulled_arc.e(3,4) & pulled_arc.e(4,1); % bowl
+pos5(hair,0); pos6(hair,0); x5=x6=.5w; top y5=h; bot y6=-d-oo;
+filldraw stroke z5e--z6e; % stem
+math_fit(-.3x_height#*slant+.5curve#-u#,ic#);
+penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Lowercase Greek chi";
+beginchar(oct"166",11u#,x_height#,desc_depth#);
+italcorr x_height#*slant+.5hair#-1.5u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(hair,180); pos2(vair,80); pos5(vair,80); pos6(hair,180);
+x1-.5hair=hround-.5hair; x6=w-x1; x2=w-x5=u;
+y1=y2l-h/8; top y2r=h+oo; bot y5l=-d-oo; y6=y5r+h/8;
+z0=.5[z2,z5]; z2'=z2l+(.5u,0); z5'=z5r-(.5u,0);
+numeric theta; theta=angle(z5'-z2')+90;
+pos3(stem,theta); pos4(stem,theta);
+y3r=y2r-h/8; y4l=y5l+h/8; z3l=whatever[z2',z0]; z4r=whatever[z0,z5'];
+filldraw stroke z1e{up}...z2e{right}...z3e{z4r-z3l}
+ ..z4e{z4r-z3l}...{right}z5e...{up}z6e; % major diagonal and hooks
+x8=w-x7=2u; y7+.5hair=h; y8-.5hair=-d;
+numeric theta; theta=angle(z7-z8)-90;
+pos7(hair,theta); pos8(hair,theta);
+filldraw z7l---z8l..z8r---z7r..cycle; % minor diagonal
+math_fit((desc_depth#-x_height#)*slant+ic#,ic#);
+penlabels(0,1,2,2',3,4,5',5,6,7,8); endchar;
+
+cmchar "Lowercase Greek psi";
+beginchar(oct"167",11u#,asc_height#,desc_depth#);
+italcorr x_height#*slant;
+adjust_fit(0,0); pickup fine.nib; interim superness:=more_super;
+x0=0; x2=x3+.25u; pos3(stem,-180); lft x3r=hround(2.5u-.5stem);
+hook_in(0,1,2)(skewed); % opening hook
+pos2'(stem,-180); z2'=z2; pos4(vair,-90); pos5(hair,0);
+x4=.5w+u; rt x5r=hround(w-.5u);
+y3=.7[y4,y5]; bot y4r=-oo; y5=.57x_height;
+filldraw stroke z2'e{-u,-x_height}...super_arc.e(3,4)
+ ..tension atleast 1.05..{up}z5e; % left stem and arc
+v_bulb(5,6); % closing bulb
+pos7(hair,0); pos8(hair,0); x7=x8=.5w+.5u; top y7=h; bot y8=-d-oo;
+filldraw stroke z7e--z8e; % stem
+math_fit(-2/3x_height#*slant+.5hair#+.5u#,2/3ic#);
+penlabels(0,1,2,3,4,5,6,7,8); endchar;
+
+cmchar "Lowercase Greek omega";
+beginchar(oct"170",11u#,x_height#,0);
+italcorr x_height#*slant;
+adjust_fit(0,0); pickup fine.nib;
+pos2(hair,-180); lft x2r=hround.5u; y2=y4=y6=y8=bar_height;
+y1+.5hair=h; x1=x2+.75u; pos1(hair,angle(2(x1-x2),y1-y2)+90);
+pos3(vstem+dw,-90); pos4(hair,0); pos5(vair,90);
+pos6(hair,180); pos7(vstem+dw,270); pos8(hair,360);
+bot y3r=bot y7r=-oo; top y5r=vround(.2[y4,h]+.5vair);
+x3=.5[x2,x4]; x7+.25u=.5[x6,x8]; rt x8r=hround(w-.5u);
+x5+.5stem=hround(.5w+.5stem)+eps;
+x5=.5[x4,x6]; rt x4r-lft x6r=min(stem,2hair)+2eps;
+if x4l<x6l: x4l:=x6l:=x5; fi
+filldraw circ_stroke z1e{2(x2-x1),y2-y1}...z2e{down}...z3e{right}
+ ...{up}z4e...{left}z5e; % left arc
+filldraw stroke z5e{left}...z6e{down}...z7e{right}...{up}z8e; % right arc
+v_bulb(8,9); % closing bulb
+math_fit(-bar_height#*slant,2/3ic#); penlabels(1,2,3,4,5,6,7,8,9); endchar;
+
+cmchar "Variant lowercase Greek sigma";
+beginchar(oct"014",8u#,x_height#,.5min(desc_depth#,.5x_height#));
+italcorr x_height#*slant-.5u#;
+adjust_fit(0,0); pickup fine.nib;
+numeric heavy_vair; heavy_vair=.25[vair,vstem];
+pos1(heavy_vair,-110); pos2(vair,-90);
+x1+.5heavy_vair=hround(w-u); y1=.1[y2r,bar_height];
+x2=min(.5w+u,x1r-eps); top y2l=h+oo;
+filldraw circ_stroke z1e{x2-x1,2(y2-y1)}...{left}z2e; % upper bulb
+numeric theta; theta=90-angle(16u,x_height); slope:=-x_height/16u;
+pos6(stem,theta); pos7(vair,-90); pos8(vair,-135);
+lft x4l=hround u; x4r-x4l=(hround .5[vair,stem])-fine;
+x6=x7=w-2u; x8=.5w+u; y6=.25[y8,y2]; y8=y7+1/8d; bot y7r=-d-oo;
+ellipse_set(2l,4l,5l,6l); ellipse_set(2r,4r,5r,6r); y4=y4r;
+filldraw circ_stroke z8e{x7-x8,2(y7-y8)}...z7e{right}...z6e
+ ---z5e...{up}z4e...{right}z2e; % main stroke
+math_fit(-.5x_height#*slant-.5u#,0); penlabels(1,2,4,5,6,7,8); endchar;
+
diff --git a/dviware/quicspool/wbfonts/tgreeku.mf b/dviware/quicspool/wbfonts/tgreeku.mf
new file mode 100644
index 0000000000..4fae88bd37
--- /dev/null
+++ b/dviware/quicspool/wbfonts/tgreeku.mf
@@ -0,0 +1,611 @@
+% $Header: tgreeku.mf,v 1.1 88/01/15 13:12:41 simpson Rel $
+% $Log: tgreeku.mf,v $
+%Revision 1.1 88/01/15 13:12:41 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:28 simpson
+%beta test
+%
+% Computer Modern Greek caps, analogous to the uppercase Roman letters.
+
+cmchar "Uppercase Greek Gamma";
+beginchar(oct"103",11u#-width_adj#,cap_height#,0);
+italcorr cap_height#*slant-beak_jut#-.25u#;
+adjust_fit(cap_serif_fit#,0);
+h:=vround(h-stem_corr);
+pickup tiny.nib; pos1(cap_stem,0); pos2(cap_stem,0);
+lft x1l=lft x2l=hround max(2u,3u-.5cap_stem); top y1=h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+pickup crisp.nib; pos3(slab,90); pos4(hair,0);
+top y3r=h; x3=x1; rt x4r=hround(w-.75u); y4=good.y(y3l-beak)-eps;
+arm(3,4,e,beak_darkness,beak_jut); % arm and beak
+if serifs: dish_serif(1,2,a,1/3,cap_jut,b,1/3,.5cap_jut); % upper serif
+ dish_serif(2,1,c,1/3,cap_jut,d,1/3,1.25cap_jut); fi % lower serif
+math_fit(0,ic#-2.5u#); penlabels(1,2,3,4); endchar;
+
+cmchar "Uppercase Greek Delta";
+beginchar(oct"104",15u#,cap_height#,0);
+adjust_fit(0,0);
+numeric left_stem,alpha;
+left_stem=cap_hair if hefty: -3stem_corr fi;
+x1l=w-x4r=.75u; y1=y4=0;
+x2-x1=x4-x3; x3r=x2r+apex_corr; y2=y3=h+apex_o+apex_oo;
+alpha=diag_ratio(2,left_stem,y2-y1,x4r-x1l-apex_corr);
+penpos1(alpha*left_stem,0); penpos2(alpha*left_stem,0);
+penpos3(alpha*cap_stem,0); penpos4(alpha*cap_stem,0);
+fill diag_end(2l,1l,1,1,4r,3r)--diag_end(4r,3r,1,1,2l,1l)--cycle; % triangle
+z0=whatever[z1r,z2r]=whatever[z3l,z4l];
+y5=y6=cap_vstem; z5=whatever[z1r,z2r]; z6=whatever[z3l,z4l];
+if y0<h-cap_notch_cut: y0:=h-cap_notch_cut;
+ unfill z0+.5right{down}...{z4-z3}z6--z5{z2-z1}
+ ...{up}z0+.5left--cycle; % counter
+else: unfill z0--z5--z6--cycle; fi % counter
+penlabels(0,1,2,3,4,5,6); endchar;
+
+cmchar "Uppercase Greek Theta";
+beginchar(oct"110",14u#,cap_height#,0);
+italcorr .7cap_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric light_curve; light_curve=hround(cap_curve-2stem_corr);
+penpos1(vair,90); penpos3(vround(vair+.5vair_corr),-90);
+penpos2(light_curve,180); penpos4(light_curve,0);
+if monospace: x2r=hround 1.5u;
+ interim superness:=sqrt superness; % make |"O"|, not |"0"|
+else: x2r=hround u; fi
+x4r=w-x2r; x1=x3=.5w; y1r=h+o; y2=y4=.5h-vair_corr; y3r=-o;
+penstroke pulled_super_arc.e(1,2)(.5superpull)
+ & pulled_super_arc.e(2,3)(.5superpull)
+ & pulled_super_arc.e(3,4)(.5superpull)
+ & pulled_super_arc.e(4,1)(.5superpull) & cycle; % bowl
+pickup crisp.nib; pos5(cap_vstem,90); pos6(cap_vstem,90);
+lft x5=w-rt x6=hround(x2l+u)+1; y5=y6=.5[y1l,y3l];
+filldraw stroke z5e--z6e; % bar
+if serifs: pos7(hair,0); pos8(hair,0); pos9(hair,0); pos10(hair,0);
+ x7l=x8l=x5; x9r=x10r=x6;
+ y7-y5r=y9-y6r=y5l-y8=y6l-y10=vround .05h;
+ filldraw stroke z7e--z8e; % left serif
+ filldraw stroke z9e--z10e; fi % right serif
+math_fit(-.3cap_height#*slant-.5u#,ic#-.5u#);
+penlabels(1,2,3,4,5,6,7,8,9,10); endchar;
+
+cmchar "Uppercase Greek Lambda";
+beginchar(oct"113",12u#,cap_height#,0);
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+numeric left_stem,outer_jut,alpha;
+left_stem=cap_hair if hefty: -3stem_corr fi;
+outer_jut=.7cap_jut; x1l=w-x4r=l+letter_fit+outer_jut+.5u; y1=y4=0;
+x2-x1=x4-x3; x3r=x2r+apex_corr; y2=y3=h+apex_o+apex_oo;
+alpha=diag_ratio(2,left_stem,y2-y1,x4r-x1l-apex_corr);
+penpos1(alpha*left_stem,0); penpos2(alpha*left_stem,0);
+penpos3(alpha*cap_stem,0); penpos4(alpha*cap_stem,0);
+z0=whatever[z1r,z2r]=whatever[z3l,z4l];
+if y0<h-cap_notch_cut: y0:=h-cap_notch_cut;
+ fill z0+.5right{down}...{z4-z3}diag_end(3l,4l,1,1,4r,3r)
+ --diag_end(4r,3r,1,1,2l,1l)--diag_end(2l,1l,1,1,1r,2r){z2-z1}
+ ...{up}z0+.5left--cycle; % left and right diagonals
+else: fill z0--diag_end(0,4l,1,1,4r,3r)--diag_end(4r,3r,1,1,2l,1l)
+ --diag_end(2l,1l,1,1,1r,0)--cycle; fi % left and right diagonals
+if serifs: numeric inner_jut; pickup tiny.nib;
+ prime_points_inside(1,2); prime_points_inside(4,3);
+ if rt x1'r+cap_jut+.5u+1<=lft x4'l-cap_jut: inner_jut=cap_jut;
+ else: rt x1'r+inner_jut+.5u+1=lft x4'l-inner_jut; fi
+ dish_serif(1',2,a,1/2,outer_jut,b,.6,inner_jut)(dark); % left serif
+ dish_serif(4',3,c,1/2,inner_jut,d,1/3,outer_jut); fi % right serif
+penlabels(0,1,2,3,4,5,6); endchar;
+
+cmchar "Uppercase Greek Xi";
+beginchar(oct"116",12u#,cap_height#,0);
+italcorr cap_height#*slant-.35u#;
+adjust_fit(0,0);
+h:=vround(h-2stem_corr);
+numeric shaved_stem; shaved_stem=hround .9[vair,.85cap_stem];
+pickup crisp.nib; pos1(shaved_stem,90); pos2(hair,0);
+top y1r=h; x1=.5w; rt x2r=hround(w-.85u); y2=good.y(y1l-4/9beak)-eps;
+arm(1,2,a,.4beak_darkness,.3beak_jut); % upper right arm and beak
+pos3(hair,180); x3=w-x2; y3=y2;
+arm(1,3,b,.4beak_darkness,-.3beak_jut); % upper left arm and beak
+pos4(shaved_stem,-90); pos5(hair,0);
+bot y4r=0; x4=.5w; rt x5r=hround(w-.75u); y5=good.y(y4l+.5beak)+eps;
+arm(4,5,c,.4beak_darkness,.3beak_jut); % lower right arm and beak
+pos6(hair,180); x6=w-x5; y6=y5;
+arm(4,6,d,.4beak_darkness,-.3beak_jut); % lower left arm and beak
+pos7(shaved_stem,90); pos8(shaved_stem,90);
+lft x7=w-rt x8=hround if serifs: 2.5 else: 2 fi\\ u;
+top y7r=top y8r=vround(.52h+.5shaved_stem);
+filldraw stroke z7e--z8e; % middle bar
+if serifs: numeric xjut;
+ if bot y2>top y7r+.75cap_jut: xjut=.5cap_jut;
+ else: bot y2=top y7r+1.5xjut; fi
+ pos11(hair,0); pos12(hair,0); y11=y12;
+ pos13(hair,0); pos14(hair,0); y13=y14;
+ lft x11l=lft x13l=w-rt x12r=w-rt x14r=hround 2.5u;
+ top y11-bot y13=shaved_stem+2xjut; .5[y11,y13]=y7;
+ filldraw stroke z11e--z13e; filldraw stroke z12e--z14e; fi % middle serifs
+math_fit(0,.5ic#); penlabels(1,2,3,4,5,6,7,8,11,12,13,14); endchar;
+
+cmchar "Uppercase Greek Pi";
+beginchar(oct"120",13u#+width_adj#,cap_height#,0);
+italcorr cap_height#*slant-cap_serif_fit#+cap_jut#-2.5u#+min(.5cap_stem#,u#);
+adjust_fit(cap_serif_fit#,cap_serif_fit#); pickup tiny.nib;
+h:=vround(h-stem_corr);
+pos1(cap_stem,0); pos2(cap_stem,0); pos3(cap_stem,0); pos4(cap_stem,0);
+lft x1l=lft x2l=hround max(2u,3u-.5cap_stem); x3=x4=w-x1;
+top y1=top y3=h; bot y2=bot y4=0;
+filldraw stroke z1e--z2e; % left stem
+filldraw stroke z3e--z4e; % right stem
+penpos5(cap_bar,90); penpos6(cap_bar,90);
+x5=x1; x6=x3; y5r=y6r=h;
+fill stroke z5e--z6e; % bar
+if serifs: numeric inner_jut;
+ if rt x1r+cap_jut+.5u+1<=lft x3l-cap_jut: inner_jut=cap_jut;
+ else: rt x1r+inner_jut+.5u+1=lft x3l-inner_jut; fi
+ dish_serif(1,2,a,1/3,cap_jut,b,1/3,eps); % upper left serif
+ dish_serif(2,1,c,1/3,cap_jut,d,1/3,inner_jut); % lower left serif
+ dish_serif(3,4,e,1/3,eps,f,1/3,cap_jut); % upper left serif
+ dish_serif(4,3,g,1/3,inner_jut,h,1/3,cap_jut); fi % lower left serif
+math_fit(0,.5ic#); penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Uppercase Greek Sigma";
+beginchar(oct"122",13u#,cap_height#,0);
+italcorr cap_height#*slant-beak_jut#-.5u#;
+adjust_fit(0,0);
+numeric bot_arm_thickness;
+bot_arm_thickness=Vround .25[slab,cap_vstem];
+pickup tiny.nib; lft x1l=hround u; x1l=x2l=x4l;
+top y1=h; bot y2=h-slab; bot y4=0; x3l-x1l=4/11(w-2u); y3=.5h;
+numeric alpha[]; alpha1=((x3l-x1l)++(y2-y3))/(y2-y3);
+penpos1(alpha1*(cap_stem-tiny),0); penpos2(alpha1*(cap_stem-tiny),0);
+penpos3(alpha1*(cap_stem-tiny),0);
+alpha2=diag_ratio(1,cap_hair-tiny,y3-y4,x3r-x4l);
+penpos4(alpha2*(cap_hair-tiny),0);
+z0=whatever[z2l,z3l]=z4l+whatever*(z3r-z4r);
+filldraw z1l--z2l--z0--z4l--z4r--z3r--z2r--z1r--cycle; % diagonals
+pickup crisp.nib; pos5(slab,90); pos6(hair,0);
+top y5r=h; x5=x1; rt x6r=hround(w-u); y6=good.y(y5l-beak)-eps;
+arm(5,6,a,beak_darkness,beak_jut); % upper arm and beak
+pos7(bot_arm_thickness,-90); pos8(hair,0);
+bot y7r=0; z7l=whatever[z4,z3]; x7r:=x4; x8=x6; y8=good.y(y7l+beak)+eps;
+arm(7,8,b,beak_darkness,beak_jut); % lower arm and beak
+math_fit(0,.5ic#); penlabels(0,1,2,3,4,5,6,7,8); endchar;
+
+cmchar "Uppercase Greek Upsilon";
+beginchar(oct"124",14u#,cap_height#,0);
+italcorr .8cap_height#*slant-.5u#;
+adjust_fit(0,0);
+pickup tiny.nib; pos1(cap_stem,0); pos2(cap_stem,0);
+lft x1l=lft x2l=hround(.5w-.5cap_stem); y1=.5h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+penpos3(.6cap_stem,0); penpos4(.75cap_curve,90); penpos5(cap_hair,180);
+z3l=lft z1l; x5r=hround u; y5=bot .8h; x4=.61803[x3l,x5l]; y4r=h+o;
+penpos5'(cap_hair,180); x5'=x5; y5'=h;
+fill z3r{up}...z4r{left}...{down}diag_end(5'r,5r,1,1,5l,5'l){up}
+ ...{right}z4l...{down}z3l--cycle; % left arc
+penpos6(.6cap_stem,0); penpos7(.75cap_curve,-90); penpos8(cap_hair,-180);
+z6r=rt z1r; x8=w-x5; y8=y5; x7=w-x4; y7=y4;
+penpos8'(cap_hair,-180); x8'=x8; y8'=h;
+fill z6r{up}...z7r{right}...{down}diag_end(8'r,8r,1,1,8l,8'l){up}
+ ...{left}z7l...{down}z6l--cycle; % right arc
+if serifs: dish_serif(2,1,a,1/3,1.25cap_jut,b,1/3,1.25cap_jut); fi % serif
+math_fit(-.8cap_height#*slant-.5u#,ic#-2.5u#);
+penlabels(1,2,3,4,5,6,7,8); endchar;
+
+cmchar "Uppercase Greek Phi";
+beginchar(oct"125",13u#,cap_height#,0);
+italcorr .5cap_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric shaved_stem,light_curve;
+shaved_stem=cap_stem-hround 2stem_corr;
+light_curve=cap_curve-hround stem_corr;
+pickup tiny.nib; pos1(shaved_stem,0); pos2(shaved_stem,0);
+lft x1l=lft x2l=hround(.5w-.5cap_stem); top y1=h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+penpos3(vair,90); penpos5(vair,-90);
+penpos4(light_curve,180); penpos6(light_curve,0);
+x4r=hround u; x6r=w-x4r; x3=x5=.5w;
+y3r=vround(.85h if serifs:-slab fi); y4=y6=.5[y3,y5];
+y5r=vround(.15h if serifs:+slab fi);
+penstroke pulled_arc.e(3,4) & pulled_arc.e(4,5)
+ & pulled_arc.e(5,6) & pulled_arc.e(6,3) & cycle; % bowl
+if serifs: dish_serif(1,2,a,1/3,1.25cap_jut,b,1/3,1.25cap_jut); % upper serif
+ dish_serif(2,1,c,1/3,1.25cap_jut,d,1/3,1.25cap_jut); fi % lower serif
+math_fit(-.5cap_height#*slant-.5u#,ic#); penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Uppercase Greek Psi";
+beginchar(oct"127",14u#,cap_height#,0);
+italcorr .8cap_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric shaved_stem;
+shaved_stem=cap_stem-hround 2stem_corr;
+pickup tiny.nib; pos1(shaved_stem,0); pos2(shaved_stem,0);
+lft x1l=lft x2l=hround(.5w-.5cap_stem); top y1=h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+pos3(shaved_stem,-180); pos4(shaved_stem,-180);
+pos5(vair,-90); x5=x1; bot y5r=vround(.15h if serifs:+slab fi);
+pos6(shaved_stem,0); pos7(shaved_stem,0);
+lft x3r=hround u; x7=w-x3; lft x4r=hround(3u-.5shaved_stem); x6=w-x4;
+pos3'(vair,90); pos7'(vair,90); z3'r=z3r; z7'r=z7r;
+y3=y7; y4=y6=.6h; y3=good.y(y3+.84h if serifs:-slab fi-y3');
+interim superness:=more_super;
+filldraw z3'l{right}...z4r{down} & super_arc.r(4,5)
+ & super_arc.r(5,6) & z6r{up}...z7'l{right}
+ --z7r---z7l...z6l{down} & super_arc.l(6,5)
+ & super_arc.l(5,4) & z4l{up}...z3l---z3r--cycle; % stroke
+if serifs: dish_serif(1,2,a,1/3,1.25cap_jut,b,1/3,1.25cap_jut); % upper serif
+ dish_serif(2,1,c,1/3,1.25cap_jut,d,1/3,1.25cap_jut); fi % lower serif
+math_fit(-.8cap_height#*slant-.5u#,.4cap_height#*slant-1.25u#);
+penlabels(1,2,3,4,5,6,7); endchar;
+
+cmchar "Uppercase Greek Omega";
+beginchar(oct"130",13u#,cap_height#,0);
+italcorr .75cap_height#*slant-.5u#;
+adjust_fit(0,0);
+pickup tiny.nib; pos1(vair,90); pos2(cap_curve,180);
+pos3(vair,180); pos4(cap_curve,0); pos5(vair,0);
+x1=.5w; top y1r=h+o; lft x2r=hround u; y2=y4=2/3h; x4=w-x2;
+rt x3l=hround(1/3(w+.5u)+.5hair); bot y3=bot y5=0; x5=w-x3;
+filldraw stroke z3e{up}...{up}z2e
+ & pulled_super_arc.e(2,1)(.5superpull)
+ & pulled_super_arc.e(1,4)(.5superpull)
+ & z4e{down}...{down}z5e; % bowl
+numeric arm_thickness; path p; p=z3{up}...{up}z2;
+arm_thickness=Vround(if hefty:slab+2stem_corr else:.75[slab,cap_vstem] fi);
+pickup crisp.nib; pos6(arm_thickness,-90); pos7(fudged.hair,-180);
+bot y6r=0; x6=x3; lft x7r=hround .8u; y7=good.y(y6l+.5beak)+eps;
+(x,y)=p intersectionpoint((0,y6l)--(w,y6l)); x6l:=x;
+arm(6,7,a,.5beak_darkness,-1.2beak_jut); % left arm and beak
+pos8(arm_thickness,-90); pos9(fudged.hair,0);
+y8=y6; y9=y7; x8+x6=x9+x7=w; x8l:=w-x6l;
+arm(8,9,b,.5beak_darkness,1.2beak_jut); % right arm and beak
+math_fit(0,.5ic#); penlabels(1,2,3,4,5,6,7,8,9); endchar;
+
+% The following letters are stolen from cmr10
+cmchar "Uppercase Greek Alpha";
+beginchar(oct"101",13u#,cap_height#,0);
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+numeric left_stem,right_stem,outer_jut,alpha;
+right_stem=cap_stem-stem_corr;
+left_stem=min(cap_hair if hefty: -3stem_corr fi,right_stem);
+outer_jut=.8cap_jut; x1l=w-x4r=l+letter_fit+outer_jut+.5u; y1=y4=0;
+x2-x1=x4-x3; x3r=x2r+apex_corr; y2=y3=h+apex_o+apex_oo;
+alpha=diag_ratio(2,left_stem,y2-y1,x4r-x1l-apex_corr);
+penpos1(alpha*left_stem,0); penpos2(alpha*left_stem,0);
+penpos3(alpha*right_stem,0); penpos4(alpha*right_stem,0);
+z0=whatever[z1r,z2r]=whatever[z3l,z4l];
+if y0<h-cap_notch_cut: y0:=h-cap_notch_cut;
+ fill z0+.5right{down}...{z4-z3}diag_end(3l,4l,1,1,4r,3r)
+ --diag_end(4r,3r,1,1,2l,1l)--diag_end(2l,1l,1,1,1r,2r){z2-z1}
+ ...{up}z0+.5left--cycle; % left and right diagonals
+else: fill z0--diag_end(0,4l,1,1,4r,3r)--diag_end(4r,3r,1,1,2l,1l)
+ --diag_end(2l,1l,1,1,1r,0)--cycle; fi % left and right diagonals
+penpos5(whatever,angle(z2-z1)); z5=whatever[z1,z2];
+penpos6(whatever,angle(z3-z4)); z6=whatever[z3,z4]; y6=y5;
+if hefty: y5r else: y5 fi =5/12y0;
+y5r-y5l=y6r-y6l=cap_band; penstroke z5e--z6e; % bar line
+if serifs: numeric inner_jut; pickup tiny.nib;
+ prime_points_inside(1,2); prime_points_inside(4,3);
+ if rt x1'r+cap_jut+.5u+1<=lft x4'l-cap_jut: inner_jut=cap_jut;
+ else: rt x1'r+inner_jut+.5u+1=lft x4'l-inner_jut; fi
+ dish_serif(1',2,a,1/2,outer_jut,b,.6,inner_jut)(dark); % left serif
+ dish_serif(4',3,c,1/2,inner_jut,d,1/3,outer_jut); fi % right serif
+penlabels(0,1,2,3,4,5,6); endchar;
+
+cmchar "Uppercase Greek Beta";
+beginchar(oct"102",12.5u#,cap_height#,0);
+italcorr .75cap_height#*slant-.5u#;
+adjust_fit(cap_serif_fit#,0);
+numeric left_stem,right_curve,middle_weight;
+left_stem=cap_stem-hround 2stem_corr; middle_weight=.6vair+.5;
+pickup tiny.nib; pos1(left_stem,0); pos2(left_stem,0);
+lft x1l=lft x2l=hround max(2u,3u-.5left_stem); top y1=h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+penpos3(cap_band,90); penpos4(cap_band,90);
+penpos6(middle_weight,-90); penpos7(middle_weight,-90);
+penpos8(middle_weight,90); penpos9(middle_weight,90);
+penpos5(right_curve-stem_corr,0); penpos10(right_curve,0);
+penpos11(cap_band,-90); penpos12(cap_band,-90);
+z3r=top z1; y4=y3; y5=.5[y4,y6]; y6=y7; y7l-y8l=vair;
+z12r=bot z2; y11=y12; y10=.5[y11,y9]; y8=y9; .5[y7l,y8l]=.52h;
+x4=x6; x9=x11=x4+.5u; x7=x8=x1; x9l:=x4+.25u;
+x5r=hround(w-1.5u); x10r=hround(w-u);
+if serifs: right_curve=cap_curve-stem_corr; x4=.5[x1,w-1.5u];
+else: right_curve=cap_curve-3stem_corr; x4=.5[x1,w-2.5u];
+ x4l:=x4l-.5u; x9l:=x9l-.5u; fi
+x6l:=x6l-.5u; x11l:=x11l-.5u;
+fill stroke z3e..super_arc.e(4,5) & super_arc.e(5,6)..z7e; % upper lobe
+fill stroke z8e..super_arc.e(9,10) & super_arc.e(10,11)..z12e; % lower lobe
+if serifs: dish_serif(1,2,a,1/3,cap_jut,b,1/3,.5cap_jut); % upper serif
+ dish_serif(2,1,c,1/3,cap_jut,d,1/3,.5cap_jut); fi % lower serif
+math_fit(0,.5ic#); penlabels(1,2,3,4,5,6,7,8,9,10,11,12); endchar;
+
+cmchar "Uppercase Greek Epsilon";
+beginchar(oct"105",12u#-width_adj#,cap_height#,0);
+italcorr cap_height#*slant-beak_jut#-.5u#;
+adjust_fit(cap_serif_fit#,0);
+h:=vround(h-stem_corr);
+pickup tiny.nib; pos1(cap_stem,0); pos2(cap_stem,0);
+lft x1l=lft x2l=hround max(2u,3u-.5cap_stem); top y1=h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+pickup crisp.nib; pos3(slab,90); pos4(hair,0);
+top y3r=h; x3=x1; rt x4r=hround(w-u); y4=good.y(y3l-beak)-eps;
+arm(3,4,e,beak_darkness,beak_jut); % upper arm and beak
+pos5(cap_bar,-90); pos6(hair,0);
+top y5l=vround(.52[y2,y1]+.5cap_bar); x5=x1;
+pos0(cap_bar,90); pos7(hair,0);
+z0=z5; x6=x7; y6-y5l=y0l-y7;
+if serifs: rt x6r=hround(w-4.4u+.5hair); y6=good.y(y5l+.6beak)+eps;
+ rt x9r=hround(w-.5u);
+else: rt x6r=hround(w-1.5u); y6=y5l+eps; rt x9r=hround(w-.75u); fi
+arm(5,6,f,beak_darkness,0); arm(0,7,g,beak_darkness,0); % middle arm and serif
+pos8(slab if not serifs:+2stem_corr fi,-90); pos9(hair,0);
+bot y8r=0; x8=x2; y9=good.y(y8l+7/6beak)+eps;
+arm(8,9,h,beak_darkness,1.5beak_jut); % lower arm and beak
+if serifs: dish_serif(1,2,a,1/3,cap_jut,b,1/3,.5cap_jut); % upper serif
+ dish_serif(2,1,c,1/3,cap_jut,d,1/3,.5cap_jut); fi % lower serif
+math_fit(0,.5ic#); penlabels(0,1,2,3,4,5,6,7,8,9); endchar;
+
+cmchar "Uppercase Greek Zeta";
+beginchar(oct"106",11u#,cap_height#,0);
+italcorr cap_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric arm_thickness[],z_stem;
+if hefty: arm_thickness1=Vround(slab-vair_corr); arm_thickness2=slab;
+ z_stem=.8[vair,cap_stem];
+else: arm_thickness1=slab; arm_thickness2=vround(slab+vair_corr);
+ z_stem=.9[vair,cap_stem]; fi
+pickup tiny.nib; x3l=x4l=w-x1r=w-x2r; lft x3l=hround u;
+top y1=h; y2=min(y1,h-2/3arm_thickness1);
+bot y4=0; y3=max(y4,2/3arm_thickness2);
+numeric alpha; alpha=diag_ratio(1,z_stem-tiny,y2-y3,x2r-x3l);
+penpos1(alpha*(z_stem-tiny),0); penpos2(alpha*(z_stem-tiny),0);
+penpos3(alpha*(z_stem-tiny),0); penpos4(alpha*(z_stem-tiny),0);
+pair delta; delta=penoffset z3-z2 of currentpen;
+fill top lft z1l--z2l+delta---z3l+delta..lft z3l---lft z4l..bot z4l
+ ---bot rt z4r--z3r-delta---z2r-delta..rt z2r---rt z1r..top z1r
+ ---cycle; % diagonal
+pickup crisp.nib; pos5(arm_thickness1,90); pos6(hair,180);
+top y5r=h; x5=x1; lft x6r=hround 1.25u; y6=good.y(y5l-beak)-eps;
+arm(5,6,a,beak_darkness**.8,-.4beak_jut); % upper arm and beak
+pos7(arm_thickness2,-90); pos8(hair,0);
+bot y7r=0; x7=x4; rt x8r=hround(w-.9u); y8=good.y(y7l+1.2beak)+eps;
+arm(7,8,b,beak_darkness**.9,.6beak_jut); % lower arm and beak
+math_fit(0,.5ic#); penlabels(1,2,3,4,5,6,7,8); endchar;
+
+cmchar "Uppercase Greek Eta";
+beginchar(oct"107",13u#+width_adj#,cap_height#,0);
+italcorr cap_height#*slant-cap_serif_fit#+cap_jut#-2.5u#+min(.5cap_stem#,u#);
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+pickup tiny.nib; pos1(cap_stem,0); pos2(cap_stem,0);
+pos3(cap_stem,0); pos4(cap_stem,0);
+lft x1l=lft x2l=hround max(2u,3u-.5cap_stem); x3=x4=w-x1;
+top y1=top y3=h; bot y2=bot y4=0;
+filldraw stroke z1e--z2e; % left stem
+filldraw stroke z3e--z4e; % right stem
+penpos5(cap_bar,90); penpos6(cap_bar,90);
+x5=x1; x6=x3; y5=y6=.52h;
+fill stroke z5e--z6e; % bar
+if serifs: numeric inner_jut;
+ if rt x1r+cap_jut+.5u+1<=lft x3l-cap_jut: inner_jut=cap_jut;
+ else: rt x1r+inner_jut+.5u+1=lft x3l-inner_jut; fi
+ dish_serif(1,2,a,1/3,cap_jut,b,1/3,inner_jut); % upper left serif
+ dish_serif(2,1,c,1/3,cap_jut,d,1/3,inner_jut); % lower left serif
+ dish_serif(3,4,e,1/3,inner_jut,f,1/3,cap_jut); % upper left serif
+ dish_serif(4,3,g,1/3,inner_jut,h,1/3,cap_jut); fi % lower left serif
+math_fit(0,.5ic#); penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Uppercase Greek Iota";
+beginchar(oct"111",max(6u#,4u#+cap_stem#),cap_height#,0);
+italcorr cap_height#*slant-.25u#;
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+pickup tiny.nib; pos1(cap_stem,0); pos2(cap_stem,0);
+lft x1l=lft x2l=hround(.5w-.5cap_stem); top y1=h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+if serifs: dish_serif(1,2,a,1/3,1.05cap_jut,b,1/3,1.05cap_jut); % upper serif
+ dish_serif(2,1,c,1/3,1.05cap_jut,d,1/3,1.05cap_jut); fi % lower serif
+math_fit(0,.5ic#); penlabels(1,2); endchar;
+
+cmchar "Uppercase Greek Kappa";
+beginchar(oct"112",13.5u#,cap_height#,0);
+italcorr cap_height#*slant-.5u#;
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+numeric right_jut,stem[],alpha[];
+if serifs: right_jut=.6cap_jut;
+else: right_jut=.4tiny; fi
+pickup tiny.nib; pos1(fudged.cap_stem,0); pos2(fudged.cap_stem,0);
+lft x1l=lft x2l=hround max(2u,3u-.5fudged.cap_stem); top y1=h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+stem2=max(tiny.breadth,fudged.cap_stem-3stem_corr);
+stem1=max(tiny.breadth,fudged.hair if hefty:-3stem_corr fi);
+top y3=h; rt x3r=hround(r-letter_fit-u-right_jut);
+bot y6=0; rt x6r=hround(r-letter_fit-.75u-right_jut);
+x4=x1; y4=1/3h;
+alpha1=diag_ratio(1,.5(stem1-tiny),y3-y4,x3r-x4);
+penpos3(alpha1*(stem1-tiny),0); penpos4(whatever,-90);
+alpha2=diag_ratio(1,.5(stem2-tiny),y1-y6,x6r-x1);
+penpos6(alpha2*(stem2-tiny),0);
+forsuffixes $=l,r: y3'$=h; y6'$=0; z4$=z3'$+whatever*(z3-z4);
+ z5$=z6'$+whatever*(z1-z6)=whatever[z3,z4]; endfor
+z5=.5[z5l,z5r];
+z3'r=z3r+penoffset z3-z4 of currentpen+whatever*(z3-z4);
+% we have also |z3'l=z3l+penoffset z4-z3 of currentpen+whatever*(z3-z4)|;\]
+z6'r=z6r+penoffset z1-z6 of currentpen+whatever*(z1-z6);
+z6'l=z6l+penoffset z6-z1 of currentpen+whatever*(z1-z6);
+fill z4r--diag_end(4r,3'r,1,.5,3'l,4l)--z4l--cycle; % upper diagonal
+fill z5l--diag_end(5l,6'l,.5,1,6'r,5r)--z5r--cycle; % lower diagonal
+if serifs: numeric inner_jut;
+ if rt x2r+cap_jut+.5u+1<=lft x6l-cap_jut: inner_jut=cap_jut;
+ else: rt x2r+cap_jut+.5u+1=lft x6l-inner_jut; fi
+ dish_serif(1,2,a,1/3,cap_jut,b,1/3,cap_jut); % upper stem serif
+ dish_serif(2,1,c,1/3,cap_jut,d,1/3,cap_jut); % lower stem serif
+ dish_serif(3,4,e,2/3,1.2cap_jut,f,1/2,right_jut)(dark); % upper diagonal serif
+ dish_serif(6,5,g,1/2,inner_jut,h,1/3,right_jut)(dark);fi % lower diagonal serif
+math_fit(0,.5ic#); penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Uppercase Greek Mu";
+beginchar(oct"114",16u#+width_adj#,cap_height#,0);
+italcorr cap_height#*slant-cap_serif_fit#+cap_jut#-2.5u#+min(.5cap_stem#,u#);
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+numeric stem[]; % thicknesses of the four strokes
+stem1=hround(fudged.hair+stem_corr);
+stem2=hround(fudged.cap_stem-4stem_corr);
+stem3=hround(fudged.hair-stem_corr);
+stem4=hround(fudged.cap_stem-3stem_corr);
+if stem4<stem1: stem4:=stem1; fi
+pickup tiny.nib; pos1(stem1,0); pos2(stem1,0);
+pos3(stem4,0); pos4(stem4,0);
+x1=x2; x3=x4; x1l=w-x3r; rt x3r=hround min(w-2u,w-3u+.5stem4);
+top y1=top y3=h; bot y2=bot y4=0;
+filldraw stroke z1e--z2e; % left stem
+filldraw stroke z3e--z4e; % right stem
+penpos5(stem2,0); penpos6(stem2,0); penpos7(stem3,0); penpos8(stem3,0);
+x5l=x1; x6l=x7l; x8=lft x3l; x6-x5=x8-x7; y5=y8=h; y6=y7;
+if hefty: y6=if monospace: vround 1/3h else: o fi;
+ numeric upper_notch,lower_notch;
+ upper_notch=h-cap_notch_cut; lower_notch=y6+cap_notch_cut;
+ x1'=rt x1r; z1'=whatever[z5l,z6l]; x3'=lft x3l; z3'=whatever[z7r,z8r];
+ z0=whatever[z5r,z6r]=whatever[z7l,z8l];
+ fill z5l..
+ if y1'<upper_notch: {right}(x1'+1,upper_notch){down}... fi
+ {z6-z5}diag_in(5l,6l,1,6r)..diag_out(7l,1,7r,8r){z8-z7}
+ if y3'<upper_notch: ...{up}(x3'-1,upper_notch){right} fi
+ ..z8r--diag_out(8r,1,8l,7l){z7-z8}
+ if y0<=lower_notch: ..{z7-z8}z0{z5-z6}..
+ else: ...{down}(x0+.5,lower_notch)--(x0-.5,lower_notch){up}... fi
+ {z5-z6}diag_in(6r,5r,1,5l)--cycle; % diagonals
+else: y6=0; z0=whatever[z5r,z6r]=whatever[z7l,z8l];
+ fill z5l..{z6-z5}diag_in(5l,6l,1,6r)..diag_out(7l,1,7r,8r){z8-z7}
+ ..z8r--diag_out(8r,1,8l,7l){z7-z8}..{z7-z8}z0{z5-z6}
+ ..{z5-z6}diag_in(6r,5r,1,5l)--cycle; fi % diagonals
+if serifs: serif(1,2,a,1/3,-cap_jut); % upper left serif
+ dish_serif(2,1,b,1/2,cap_jut,c,1/2,cap_jut)(dark); % lower left serif
+ serif(3,4,d,1/3,cap_jut); % upper right serif
+ dish_serif(4,3,e,1/3,cap_jut,f,1/3,cap_jut); fi % lower right serif
+math_fit(0,max(.5ic#-.5u#,0));
+penlabels(0,1,1',2,3,3',4,5,6,7,8); endchar;
+
+cmchar "Uppercase Greek Nu";
+beginchar(oct"115",13u#+width_adj#,cap_height#,0);
+italcorr cap_height#*slant-cap_serif_fit#+cap_jut#-2.5u#+min(.5cap_stem#,u#);
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+numeric thin_stem; thin_stem=hround(fudged.hair+stem_corr);
+pickup tiny.nib; pos1(thin_stem,0); pos2(thin_stem,0);
+pos3(thin_stem,0); pos4(thin_stem,0);
+pickup tiny.nib; top y1=top y3=h; bot y2=bot y4=0;
+x1=x2; x3=x4; x1l=w-x3r;
+rt x3r=hround min(w-2u,w-3u+.5fudged.cap_stem);
+filldraw stroke z1e--z2e; % left stem
+filldraw stroke z3e--z4e; % right stem
+if hefty: penpos5(fudged.cap_stem,0); penpos6(fudged.cap_stem,0);
+ x5l=x1; x6r=x4; y5=h; y6=0;
+ numeric upper_notch,lower_notch;
+ upper_notch=h-cap_notch_cut; lower_notch=cap_notch_cut;
+ x1'=rt x1r; z1'=whatever[z5l,z6l]; x4'=lft x4l; z4'=whatever[z5r,z6r];
+ fill z5l..
+ if y1'<upper_notch: {right}(x1'+1,upper_notch){down}... fi
+ {z6-z5}diag_in(5l,6l,1,6r)--z6r..
+ if y4'>lower_notch: {left}(x4'-1,lower_notch){up}... fi
+ {z5-z6}diag_in(6r,5r,1,5l)--cycle; % diagonal
+else: penpos5(whatever,0); penpos6(whatever,90);
+ z5l=z1l; z6l=z4l;
+ z7=z6l+(max(eps,cap_stem-3stem_corr-tiny),0) rotated (angle(z5l-z6l)-90);
+ z5r=z7+whatever*(z5l-z6l); z6r=z7+whatever*(z5l-z6l);
+ filldraw stroke z5e..z6e; fi % diagonal
+if serifs: if hefty: serif(1,2,a,1/3,-cap_jut); % upper left serif
+ else: serif(5,6,a,1/3,-cap_jut); fi % upper left serif
+ dish_serif(2,1,b,1/2,cap_jut,c,1/2,cap_jut)(dark); % lower left serif
+ dish_serif(3,4,e,1/2,cap_jut,f,1/2,cap_jut)(dark); fi % upper right serif
+math_fit(0,max(.5ic#-.5u#,0)); penlabels(1,1',2,3,4,4',5,6,7); endchar;
+
+cmchar "Uppercase Greek Omicron";
+beginchar(oct"117",14u#-width_adj#,cap_height#,0);
+italcorr .7cap_height#*slant-.5u#;
+adjust_fit(0,0);
+penpos1(vair',90); penpos3(vround(vair+1.5vair_corr),-90);
+penpos2(cap_curve,180); penpos4(cap_curve,0);
+if monospace: x2r=hround 1.5u;
+ interim superness:=sqrt superness; % make |"O"|, not |"0"|
+else: x2r=hround u; fi
+x4r=w-x2r; x1=x3=.5w; y1r=h+o; y3r=-o;
+y2=y4=.5h-vair_corr; y2l:=y4l:=.52h;
+penstroke pulled_super_arc.e(1,2)(.5superpull)
+ & pulled_super_arc.e(2,3)(.5superpull)
+ & pulled_super_arc.e(3,4)(.5superpull)
+ & pulled_super_arc.e(4,1)(.5superpull) & cycle; % bowl
+math_fit(-.3cap_height#*slant-.5u#,ic#-.5u#); penlabels(1,2,3,4); endchar;
+
+cmchar "Uppercase Greek Rho";
+beginchar(oct"121",12u#,cap_height#,0);
+italcorr .75cap_height#*slant-.5u#;
+adjust_fit(cap_serif_fit#,0);
+pickup tiny.nib; penpos1(cap_stem'-tiny,0); penpos2(cap_stem-tiny,0);
+pos0(cap_stem',0); pos0'(cap_stem,0);
+lft x1l=hround max(2u,3u-.5cap_stem'); top y1=h; bot y2=0;
+x1l=x2l=x0l=x0'l; y0=y0'=y7;
+penpos3(cap_band,90); penpos4(cap_band,90);
+penpos5(cap_curve if hefty:-3stem_corr fi,0);
+penpos6(.5[vair,cap_band],-90); penpos7(.5[vair,cap_band],-90);
+z3r=top z1; y4=y3; y5=.5[y4l,y6l]; y6=y7;
+x7=x2; y7l=vround .5h; x4=x6=.5w+.75u; x5r=hround(w-u);
+x4l:=x6l:=x4-.25cap_curve;
+filldraw stroke z1e--z0e--z0'e--z2e; % stem
+fill stroke z3e..pulled_arc.e(4,5) & pulled_arc.e(5,6)..z7e; % lobe
+if serifs: dish_serif(1,0,a,1/3,cap_jut,b,1/3,.5cap_jut); % upper serif
+ dish_serif(2,0',c,1/3,cap_jut,d,1/3,cap_jut); fi % lower serif
+math_fit(0,ic#-2.5u#); penlabels(0,1,2,3,4,5,6,7); endchar;
+
+cmchar "Uppercase Greek Tau";
+beginchar(oct"123",13u#-width_adj#,cap_height#,0);
+italcorr cap_height#*slant-beak_jut#-.25u#;
+adjust_fit(0,0);
+h:=vround(h-2stem_corr);
+pickup tiny.nib; pos1(cap_stem,0); pos2(cap_stem,0);
+lft x1l=lft x2l=hround(.5w-.5cap_stem); top y1=h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+pickup crisp.nib; pos3(slab,90); pos4(hair,0);
+top y3r=h; x3=x1; rt x4r=hround(w-.65u); y4=good.y(y3l-beak)-eps;
+arm(3,4,e,beak_darkness,.7beak_jut); % right arm and beak
+pos5(hair,180); x5=w-x4; y5=y4;
+arm(3,5,f,beak_darkness,-.7beak_jut); % left arm and beak
+if serifs: dish_serif(1,2,a,1/3,.5cap_jut,b,1/3,.5cap_jut); % upper bracketing
+ dish_serif(2,1,c,1/3,1.414cap_jut,d,1/3,1.414cap_jut); fi % lower serif
+math_fit(-.75cap_height#*slant,ic#-2.5u#); penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Uppercase Greek Chi";
+beginchar(oct"126",13u#,cap_height#,0);
+italcorr cap_height#*slant-.25u#;
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+numeric stem[],outer_jut,xjut,alpha[];
+stem1=cap_stem-2stem_corr; stem2=min(cap_hair,stem1);
+outer_jut=.75cap_jut; xjut= if serifs: (stem1-stem2)/4 else: 0 fi;
+x1l=l+letter_fit+.5u+outer_jut; x2r=r-letter_fit-u-outer_jut-xjut;
+x3l=l+letter_fit+.25u+outer_jut+xjut; x4r=r-letter_fit-.25u-outer_jut;
+y1=y2=h; y3=y4=0;
+alpha1=diag_ratio(1,stem1,h,x4r-x1l);
+alpha2=diag_ratio(1,stem2,h,x2r-x3l);
+penpos1(alpha1*stem1,0); penpos2(alpha2*stem2,0);
+penpos3(alpha2*stem2,0); penpos4(alpha1*stem1,0);
+if hefty: z0=whatever[z1,z4]=whatever[z2,z3];
+ x12=x34=x0; y13=y24=y0;
+ z12=whatever[z2l,z3l]; z13=whatever[z2l,z3l];
+ z24=whatever[z2r,z3r]; z34=whatever[z2r,z3r];
+ forsuffixes $=13,24,34: z$'=.1[z$,z0]; endfor
+ fill diag_end(12,1r,.5,1,1l,13')--z13'--diag_end(13',3l,1,.5,3r,34')--z34'
+ --diag_end(34',4l,.5,1,4r,24')--z24'
+ --diag_end(24',2r,1,.5,2l,12)--z12--cycle; % diagonals
+else: fill diag_end(4r,1r,.5,1,1l,4l)
+ --diag_end(1l,4l,.5,1,4r,1r)--cycle; % left diagonal
+ fill diag_end(2l,3l,.5,1,3r,2r)
+ --diag_end(3r,2r,.5,1,2l,3l)--cycle; fi % right diagonal
+if serifs: numeric inner_jut[]; pickup tiny.nib;
+ prime_points_inside(1,4); prime_points_inside(2,3);
+ prime_points_inside(3,2); prime_points_inside(4,1);
+ if rt x1'r+cap_jut+.5u+1<=lft x2'l-cap_jut-xjut: inner_jut1=cap_jut;
+ else: rt x1'r+inner_jut1+.5u+1=lft x2'l-inner_jut1-xjut; fi
+ if rt x3'r+cap_jut+.5u+1<=lft x4'l-cap_jut-xjut: inner_jut2=cap_jut;
+ else: rt x3'r+inner_jut2+.5u+1=lft x4'l-inner_jut2-xjut; fi
+ dish_serif(1',4,a,1/3,outer_jut,b,2/3,inner_jut1); % upper left serif
+ dish_serif(4',1,c,2/3,inner_jut2,d,1/3,outer_jut); % lower right serif
+ dish_serif(2',3,e,2/3,inner_jut1+xjut,
+ f,1/2,outer_jut+xjut)(dark); % upper right serif
+ dish_serif(3',2,g,1/2,outer_jut+xjut,
+ h,2/3,inner_jut2+xjut)(dark); fi % lower left serif
+math_fit(0,.5ic#); penlabels(0,1,2,3,4,12,13,24,34); endchar;
diff --git a/dviware/quicspool/wbfonts/titalig.mf b/dviware/quicspool/wbfonts/titalig.mf
new file mode 100644
index 0000000000..d3bcf87c78
--- /dev/null
+++ b/dviware/quicspool/wbfonts/titalig.mf
@@ -0,0 +1,206 @@
+% $Header: titalig.mf,v 1.1 88/01/15 13:12:46 simpson Rel $
+% $Log: titalig.mf,v $
+%Revision 1.1 88/01/15 13:12:46 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:31 simpson
+%beta test
+%
+% This file describes five italic ligatures that begin with `f'
+% and puts them in code positions \0013--\0017.
+
+numeric itc; % modified italic correction on `f' and `ff'
+itc=(asc_height#-x_height#)*slant+.75u#;
+
+ligtable "f": "i"=:oct"001", "f"=:oct"003", "l"=:oct"002",
+ "?" kern itc, "!" kern itc, ")" kern itc, "]" kern itc;
+ligtable oct"003": "i"=:oct"011", "l"=:oct"012",
+ "?" kern itc, "!" kern itc, ")" kern itc, "]" kern itc;
+
+cmchar "Italic ligature ff";
+beginchar(oct"003",5u#+max(1.5u#,stem#)+max(3.5u#,2flare#)+2letter_fit#,
+ asc_height#,desc_depth#);
+italcorr asc_height#*slant+.75u#;
+adjust_fit(0,0); pickup fine.nib;
+z98-z88=z99-z89=z14-z4=z15-z5=(4.8u+2letter_fit,0);
+.5[x88,x99]=.5w-.1u; x89-x88=u; y98=h; y99=-d;
+numeric theta; theta=angle(z88-z89);
+pos0(flare,0); pos1(hair,0); pos2(vair,90);
+pos3(.5[hair,stem],180); pos4(stem,theta+90);
+pos5(stem,theta-90); pos6(.5[hair,stem],0);
+pos7(vair,-90); pos8(hair,-180); pos9(flare,-180);
+rt x1r=hround(.5w+1.25u); lft x8r=hround-.35u; x2=.5[x1,x4]; x7=.6[x8,x5];
+y9-.5flare=vround -.85d; y2-y0=y9-y7; top y2r=h+oo; bot y7r=-d-oo;
+y4=.25[x_height,h]; y5=.5[-d,y4];
+z4=whatever[z88,z89]; z5=whatever[z88,z89];
+x3=.8[x2+x4-x88,x88]; x6=.8[x7+x5-x89,x89]; y3=.8[y4,y2]; y6=.8[y5,y7];
+bulb(2,1,0); bulb(7,8,9); % left bulbs
+filldraw stroke z2e{left}...z3e...{z89-z88}z4e; % upper middle arc
+filldraw z4r--z5l--z5r--z4l--cycle; % left stem
+filldraw stroke z5e{z89-z88}...z6e...{left}z7e; % lower left arc
+pos10(flare,0); pos11(hair,0); pos12(vair,90);
+pos13(.5[hair,stem],180); pos14(stem,theta+90);
+pos15(stem,theta-90); pos16(.5[hair,stem],0);
+pos17(vair,-90); pos18(hair,-180); pos19(flare,-180);
+rt x11r=hround(w+.25u); lft x18r=hround(.5w-1.25u);
+x12=.6[x11,x14]; x17=.5[x18,x15];
+x13=.8[x12+x14-x98,x98]; x16=.8[x17+x15-x99,x99];
+y0=y10; y2=y12; y3=y13; y6=y16; y7=y17; y9=y19;
+bulb(12,11,10); bulb(17,18,19); % right bulbs
+filldraw stroke z12e{left}...z13e...{z99-z98}z14e; % upper right arc
+filldraw z14r--z15l--z15r--z14l--cycle; % right stem
+filldraw stroke z15e{z99-z98}...z16e...{left}z17e; % lower middle arc
+pickup crisp.nib; pos20(bar,90); pos21(bar,90);
+top y20r=top y21r=x_height;
+lft x20=lft x4r-.5stem-u; rt x21=rt x14l+.5stem+1.5u;
+filldraw stroke z20e--z21e; % crossbar
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
+ 20,21,88,89,98,99); endchar;
+
+cmchar "Italic ligature fi";
+beginchar(oct"001",6.5u#+.5max(1.5u#,stem#)+.5max(3.5u#,2flare#)
+ +2letter_fit#,asc_height#,desc_depth#);
+italcorr max(asc_height#*slant+.5stem#-2u#,1/3x_height#*slant+.5hair#+.5u#);
+adjust_fit(0,0); pickup fine.nib;
+.5[x88,x89]=.5(w-4u-2letter_fit); x89-x88=u; y88=h; y89=-d;
+numeric theta; theta=angle(z88-z89);
+pos0(flare,0); pos1(hair,0); pos2(vair,90);
+pos3(.5[hair,stem],180); pos4(stem,theta+90);
+pos5(stem,theta-90); pos6(.5[hair,stem],0);
+pos7(vair,-90); pos8(hair,-180); pos9(flare,-180);
+pos11(stem,0); rt x11r=hround(w-2.5u+.5stem);
+x12=x11; x14=w; hook_out(12,13,14); % closing hook
+x1r=x11r; lft x8r=hround-.35u; x2=.5[x1,x4]; x7=.6[x8,x5];
+y9-.5flare=vround-.85d; bot y7r=-d-oo;
+y0+.5flare=vround(.85[x_height,h]); top y2r=h+oo;
+y4=.25[x_height,h]; y5=.5[-d,y4];
+z4=whatever[z88,z89]; z5=whatever[z88,z89];
+x3=.8[x2+x4-x88,x88]; x6=.8[x7+x5-x89,x89]; y3=.8[y4,y2]; y6=.8[y5,y7];
+bulb(2,1,0); bulb(7,8,9); % bulbs
+filldraw stroke z2e{left}...z3e...{z89-z88}z4e; % upper arc
+filldraw z4r--z5l--z5r--z4l--cycle; % left stem
+filldraw stroke z5e{z89-z88}...z6e...{left}z7e; % lower arc
+top y11=x_height; filldraw stroke z11e--z12e; % right stem
+pickup crisp.nib; pos20(bar,90); pos21(bar,90);
+top y20r=top y21r=x_height;
+lft x20=lft x4r-.5stem-u; x21=x11;
+filldraw stroke z20e--z21e; % crossbar
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,20,21,88,89); endchar;
+
+cmchar "Italic ligature fl";
+beginchar(oct"002",7u#+.5max(1.5u#,stem#)+.5max(3.5u#,2flare#)
+ +2letter_fit#,asc_height#,desc_depth#);
+italcorr max(asc_height#*slant+.5stem#-2u#,1/3x_height#*slant+.5hair#+.5u#);
+adjust_fit(0,0); pickup fine.nib;
+.5[x88,x89]=.5(w-4.5u-2letter_fit); x89-x88=u; y88=h; y89=-d;
+numeric theta; theta=angle(z88-z89);
+pos0(flare,0); pos1(hair,0); pos2(vair,90);
+pos3(.5[hair,stem],180); pos4(stem,theta+90);
+pos5(stem,theta-90); pos6(.5[hair,stem],0);
+pos7(vair,-90); pos8(hair,-180); pos9(flare,-180);
+pos11(stem,0); rt x11r=hround(w-2.5u+.5stem); rt x1r=lft x11l;
+x12=x11; x14=w; hook_out(12,13,14); % closing hook
+lft x8r=hround-.35u; x2=.5[x1,x4]; x7=.6[x8,x5];
+y9-.5flare=vround -.85d; y2-y0=y9-y7; top y2r=h+oo; bot y7r=-d-oo;
+y4=.25[x_height,h]; y5=.5[-d,y4];
+z4=whatever[z88,z89]; z5=whatever[z88,z89];
+x3=.8[x2+x4-x88,x88]; x6=.8[x7+x5-x89,x89]; y3=.8[y4,y2]; y6=.8[y5,y7];
+bulb(2,1,0); bulb(7,8,9); % bulbs
+filldraw stroke z2e{left}...z3e...{z89-z88}z4e; % upper arc
+filldraw z4r--z5l--z5r--z4l--cycle; % left stem
+filldraw stroke z5e{z89-z88}...z6e...{left}z7e; % lower arc
+top y11=h; filldraw stroke z11e--z12e; % right stem
+pickup crisp.nib; pos20(bar,90); pos21(bar,90);
+top y20r=top y21r=x_height;
+lft x20=lft x4r-.5stem-u; x21=x11;
+filldraw stroke z20e--z21e; % crossbar
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,20,21,88,89); endchar;
+
+cmchar "Italic ligature ffi";
+beginchar(oct"011",11.75u#+.5max(1.5u#,stem#)+.5max(3.5u#,2flare#)
+ +4letter_fit#,asc_height#,desc_depth#);
+italcorr max(asc_height#*slant+.5stem#-2u#,1/3x_height#*slant+.5hair#+.5u#);
+adjust_fit(0,0); pickup fine.nib;
+z98-z88=z99-z89=z14-z4=z15-z5=(5u+2letter_fit,0);
+numeric theta,mid_f;
+mid_f=.5[x88,x99]=.5(w-4.25u-2letter_fit); x89-x88=u;
+y98=h; y99=-d; theta=angle(z88-z89);
+pos21(stem,0); rt x21r=hround(w-2.5u+.5stem);
+x22=x21; x24=w; hook_out(22,23,24); % closing hook
+pos0(flare,0); pos1(hair,0); pos2(vair,90);
+pos3(.5[hair,stem],180); pos4(stem,theta+90);
+pos5(stem,theta-90); pos6(.5[hair,stem],0);
+pos7(vair,-90); pos8(hair,-180); pos9(flare,-180);
+rt x1r=hround(mid_f+1.75u); lft x8r=hround-.35u;
+x2=.5[x1,x4]; x7=.6[x8,x5];
+y9-.5flare=vround -.85d; y2-y0=y9-y7; top y2r=h+oo; bot y7r=-d-oo;
+y4=.25[x_height,h]; y5=.5[-d,y4];
+z4=whatever[z88,z89]; z5=whatever[z88,z89];
+x3=.8[x2+x4-x88,x88]; x6=.8[x7+x5-x89,x89]; y3=.8[y4,y2]; y6=.8[y5,y7];
+bulb(2,1,0); bulb(7,8,9); % left bulbs
+filldraw stroke z2e{left}...z3e...{z89-z88}z4e; % upper middle arc
+filldraw z4r--z5l--z5r--z4l--cycle; % left stem
+filldraw stroke z5e{z89-z88}...z6e...{left}z7e; % lower left arc
+pos10(flare,0); pos11(hair,0); pos12(vair,90);
+pos13(.5[hair,stem],180); pos14(stem,theta+90);
+pos15(stem,theta-90); pos16(.5[hair,stem],0);
+pos17(vair,-90); pos18(hair,-180); pos19(flare,-180);
+x11r=x21r; lft x18r=hround(mid_f-1.25u); x12=.5[x11,x14]; x17=.5[x18,x15];
+x13=.8[x12+x14-x98,x98]; x16=.8[x17+x15-x99,x99];
+y10+.5flare=vround .85[x_height,h];
+y2=y12; y3=y13; y6=y16; y7=y17; y9=y19;
+bulb(12,11,10); bulb(17,18,19); % right bulbs
+filldraw stroke z12e{left}...z13e...{z99-z98}z14e; % upper right arc
+filldraw z14r--z15l--z15r--z14l--cycle; % middle stem
+filldraw stroke z15e{z99-z98}...z16e...{left}z17e; % lower middle arc
+top y21=x_height; filldraw stroke z21e--z22e; % right stem
+pickup crisp.nib; pos30(bar,90); pos31(bar,90);
+top y30r=top y31r=x_height;
+lft x30=lft x4r-.5stem-u; x31=x21;
+filldraw stroke z30e--z31e; % crossbar
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
+ 20,21,22,23,24,30,31,88,89,98,99); endchar;
+
+cmchar "Italic ligature ffl";
+beginchar(oct"012",12u#+.5max(1.5u#,stem#)+.5max(3.5u#,2flare#)
+ +4letter_fit#,asc_height#,desc_depth#);
+italcorr max(asc_height#*slant+.5stem#-2u#,1/3x_height#*slant+.5hair#+.5u#);
+adjust_fit(0,0); pickup fine.nib;
+z98-z88=z99-z89=z14-z4=z15-z5=(5u+2letter_fit,0);
+numeric theta,mid_f;
+mid_f=.5[x88,x99]=.5(w-4.5u-2letter_fit); x89-x88=u;
+y98=h; y99=-d; theta=angle(z88-z89);
+pos21(stem,0); rt x21r=hround(w-2.5u+.5stem);
+x22=x21; x24=w; hook_out(22,23,24); % closing hook
+pos0(flare,0); pos1(hair,0); pos2(vair,90);
+pos3(.5[hair,stem],180); pos4(stem,theta+90);
+pos5(stem,theta-90); pos6(.5[hair,stem],0);
+pos7(vair,-90); pos8(hair,-180); pos9(flare,-180);
+rt x1r=hround(mid_f+1.25u); lft x8r=hround-.35u;
+x2=.5[x1,x4]; x7=.6[x8,x5];
+y9-.5flare=vround -.85d; y2-y0=y9-y7; top y2r=h+oo; bot y7r=-d-oo;
+y4=.25[x_height,h]; y5=.5[-d,y4];
+z4=whatever[z88,z89]; z5=whatever[z88,z89];
+x3=.8[x2+x4-x88,x88]; x6=.8[x7+x5-x89,x89]; y3=.8[y4,y2]; y6=.8[y5,y7];
+bulb(2,1,0); bulb(7,8,9); % left bulbs
+filldraw stroke z2e{left}...z3e...{z89-z88}z4e; % upper middle arc
+filldraw z4r--z5l--z5r--z4l--cycle; % left stem
+filldraw stroke z5e{z89-z88}...z6e...{left}z7e; % lower left arc
+pos10(flare,0); pos11(hair,0); pos12(vair,90);
+pos13(.5[hair,stem],180); pos14(stem,theta+90);
+pos15(stem,theta-90); pos16(.5[hair,stem],0);
+pos17(vair,-90); pos18(hair,-180); pos19(flare,-180); rt x11r=lft x21l;
+lft x18r=hround(mid_f-1.25u); x12=.5[x11,x14]; x17=.5[x18,x15];
+x13=.8[x12+x14-x98,x98]; x16=.8[x17+x15-x99,x99];
+y0=y10; y2=y12; y3=y13; y6=y16; y7=y17; y9=y19;
+bulb(12,11,10); bulb(17,18,19); % right bulbs
+filldraw stroke z12e{left}...z13e...{z99-z98}z14e; % upper right arc
+filldraw z14r--z15l--z15r--z14l--cycle; % middle stem
+filldraw stroke z15e{z99-z98}...z16e...{left}z17e; % lower middle arc
+top y21=h; filldraw stroke z21e--z22e; % right stem
+pickup crisp.nib; pos30(bar,90); pos31(bar,90);
+top y30r=top y31r=x_height;
+lft x30=lft x4r-.5stem-u; x31=x21;
+filldraw stroke z30e--z31e; % crossbar
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
+ 20,21,22,23,24,30,31,88,89,98,99); endchar;
diff --git a/dviware/quicspool/wbfonts/titalms.mf b/dviware/quicspool/wbfonts/titalms.mf
new file mode 100644
index 0000000000..40b30afa9f
--- /dev/null
+++ b/dviware/quicspool/wbfonts/titalms.mf
@@ -0,0 +1,40 @@
+% $Header: titalms.mf,v 1.1 88/01/15 13:12:49 simpson Rel $
+% $Log: titalms.mf,v $
+%Revision 1.1 88/01/15 13:12:49 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:33 simpson
+%beta test
+%
+% This file contains miscellaneous symbols of math italic fonts.
+
+cmchar "Partial differential sign";
+beginchar(oct"171",10u#,asc_height#,0);
+italcorr .7asc_height#*slant+.5curve#-1.5u#;
+adjust_fit(0,0);
+numeric top_thickness,bot_thickness,side_thickness,pull;
+top_thickness=max(fine.breadth,vround(slab-2vair_corr));
+bot_thickness=max(fine.breadth,vround(slab-vair_corr));
+side_thickness=max(fine.breadth,hround 1/3[curve,cap_curve]);
+pull=min(.25,1.5superpull);
+pickup fine.nib; pos2(top_thickness,90);
+pos3(side_thickness,0); pos4(bot_thickness,-90);
+pos5(side_thickness,-180); pos6(vair,-270);
+lft x5r=w-rt x3r=hround max(.75u,1.5u-.5side_thickness);
+x4=x6+.1u=x2+u=.5w;
+top y2r=h+o; y3=.5[y2,y4]; bot y4r=-o;
+y5=.5[y4,y6]; top y6=vround 5/8h+o;
+path p; p=pulled_super_arc.l(3,4)(pull);
+numeric t; t=xpart(p intersectiontimes((x3r,y5)--(x4,y5)));
+pos7(thin_join,0); z7l=point t of p;
+(x,y6r)=whatever[z7l,z6l]; x6r:=max(x,.5[x5r,x6]);
+filldraw stroke pulled_super_arc.e(2,3)(pull)
+ & {{interim superness:=more_super; pulled_super_arc.e(3,4)(pull)}}
+ & {{less_tense; pulled_super_arc.e(4,5)(pull) & pulled_super_arc.e(5,6)(pull)}}
+ & z6e{right}...{direction t of p}z7e; % arc and bowl
+pos1(hair,180); pos0(flare,180);
+lft x0r=min(lft x2-eps,hround 1.2u);
+y0=vround min(.85h-.5flare,.8h+.5flare)+o;
+{{less_tense; bulb(2,1,0)}}; % arc and bulb
+math_fit(-.3x_height#*slant+.5curve#-u#,ic#-u#);
+penlabels(0,1,2,3,4,5,6,7); endchar;
diff --git a/dviware/quicspool/wbfonts/titalp.mf b/dviware/quicspool/wbfonts/titalp.mf
new file mode 100644
index 0000000000..888f650a01
--- /dev/null
+++ b/dviware/quicspool/wbfonts/titalp.mf
@@ -0,0 +1,114 @@
+% $Header: titalp.mf,v 1.1 88/01/15 13:12:51 simpson Rel $
+% $Log: titalp.mf,v $
+%Revision 1.1 88/01/15 13:12:51 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:34 simpson
+%beta test
+%
+% This file contains `\$' and `\&' and `?' in the so-called italic style.
+
+% Codes \0044, \0046, and \0077 are generated, as well as code |spanish_query|
+% (for a Spanish question mark) if that code value is known.
+
+cmchar "Dollar sign";
+beginchar("$",9u#,body_height#,body_height#-asc_height#);
+italcorr fig_height#*slant-.5u#; % same as for digits
+adjust_fit(0,0);
+numeric theta; theta=90-angle(50u,asc_height); slope:=-asc_height/50u;
+pickup fine.nib; pos2(slab,-90);
+pos0(cap_stem,theta); pos7(slab,-90);
+x2=x0=x7=.5w; top y2l=asc_height+oo; bot y7r=-oo;
+y0=.52asc_height; lft x3l=hround u; rt x6r=hround(w-u);
+x3r-x3l=x6r-x6l=hround .35[slab,cap_stem]-fine;
+ellipse_set(2l,3l,4l,0l); ellipse_set(2r,3r,4r,0r); y3=y3r;
+ellipse_set(7l,6l,5l,0l); ellipse_set(7r,6r,5r,0r); y6=y6r;
+filldraw stroke super_arc.e(2,3) & z3e{down}
+ ..z4e---z5e..z6e{down} & super_arc.e(6,7); % main stroke
+if serifs: pos1(hair,0); pos8(hair,180);
+ pos10(flare,0); pos9(flare,180);
+ rt x1r=hround(w-u); lft x8r=hround u; y1=.5[y0,y2]; y8=.5[y0,y7];
+ {{less_tense; pos2'(slab,90); z2'=z2; bulb(2',1,10); % upper arc and bulb
+ bulb(7,8,9)}}; % lower arc and bulb
+else: pos1(.6[slab,flare],-100); pos8(flare,-100);
+ rt x1l=hround(w-1.3u); lft x8r=hround .8u;
+ top y1l=vround .92asc_height+oo; bot y8r=vround .1asc_height-oo;
+ filldraw stroke term.e(2,1,right,.9,4); % upper arc and terminal
+ filldraw stroke term.e(7,8,left,1,4); fi % lower arc and terminal
+pickup crisp.nib; pos12(bar,0); pos11(bar,0);
+lft x12l=lft x11l=hround(.5w-.5bar); top y12=h; bot y11=-d;
+filldraw stroke z12e--z11e; % vertical crossbar
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11,12); endchar;
+
+cmchar "Italic ampersand";
+beginchar("&",14u#,asc_height#,0);
+italcorr asc_height#*slant-1.5u#;
+adjust_fit(if monospace:-u#,-2u# else: 0,0 fi); pickup fine.nib;
+pos1(flare,0); pos2(hair,0); pos3(vair,90);
+rt x2r=hround.5w; x3=1/3(w-u);
+top y3r=h+o; y2=.5[x_height,h]; bulb(3,2,1); % left bulb
+pos4(stem,180); pos5(vair,270); pos6(hair,360); pos7(vair,450);
+pos8(curve,540); pos9(vair,630); pos10(hair,720);
+lft x4r=hround 1.25u; x5=x7=x3+1/6u; rt x6r=hround(x5+1.5u);
+lft x8r=hround u; x9=.5w; rt x10r=hround(w-1.5u);
+y4=.5[y3,y5]; top y5l=vround .77x_height; y6=.5[y5,y7];
+y7l=good.y 1/3[y5,y3]; y8=.5[y7,y9]; bot y9r=-o; y10=bar_height;
+pos12(hair,0); pos13(curve,0); pos14(hair,0); pos15(vair,90); pos16(curve,90);
+rt x12r=rt x13r=hround(w-2u); lft x14l=hround(.5w+.5u);
+x15=x16=rt x14r+u;
+y12=y13=h-.5curve; y14=.5[bar_height,x_height];
+bot y15l=bot y16l=vround y10;
+numeric theta; theta=angle((z12-z14)xscaled 2);
+pos11(hair,theta); x11=w-4u; y11=.5[y13,y16];
+filldraw stroke pulled_arc.e(3,4) & pulled_arc.e(4,5) & pulled_arc.e(5,6)
+ & pulled_arc.e(6,7) & pulled_arc.e(7,8) & pulled_arc.e(8,9)
+ & {{interim superness:=more_super; pulled_arc.e(9,10)}}
+ ..tension .9 and 1..{dir(theta+100)}z11e; % bowls, loop, and stem
+pos11'(hair,theta-90); z11'=z11;
+forsuffixes $=l,r: path p$;
+ p$=z12${down}..z11'${-dir theta}..{down}z14$...{right}z15$; endfor
+filldraw p.l--reverse p.r--cycle; % arms
+path q[]; q1=z13r{up}..z13l{down}..cycle;
+q2=z16l{right}..z16r{left}..cycle;
+filldraw subpath(0,ypart(p.l intersectiontimes q1)) of q1--cycle; % upper bulb
+filldraw subpath(0,ypart(p.r intersectiontimes q2)) of q2--cycle; % lower bulb
+penlabels(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16); endchar;
+
+cmchar "Italic question mark";
+beginchar("?",9u#,asc_height#,0);
+italcorr asc_height#*slant-u#;
+adjust_fit(0,0); pickup tiny.nib; pos10(dot_size,0); pos11(dot_size,90);
+lft x10l=hround(.5w-.5dot_size); bot y11l=0; z10=z11; dot(10,11); % dot
+pickup fine.nib; pos1(flare,180); pos2(hair,180); pos3(vair,90);
+lft x1r=hround u; x3=.5w;
+y1-.5flare=x_height; top y3r=h+o; bulb(3,2,1); % bulb
+pos8(vair,-90); x8=.5w; bot y8r=.25[top y11r,x_height]+1;
+numeric theta; theta=90+angle(10u,y3-y8); slope:=(y3-y8)/10u;
+pos3'(vair,-90); z3'=z3; pos0(vstem,theta); x0=x3; y0=1/3[y8,y3];
+rt x4l=hround(w-1.5u); lft x7r=hround 1/3w;
+x4l-x4r=x7l-x7r=hround .5[vair,vstem]-fine;
+ellipse_set(3'l,4l,5l,0l); ellipse_set(3'r,4r,5r,0r); y4=y4r;
+ellipse_set(8l,7l,6l,0l); ellipse_set(8r,7r,6r,0r); y7=y7r;
+pos9(hair,0); rt x9r=hround(2/3w+.5hair); y9=good.y .5[y8,y0];
+filldraw stroke super_arc.e(3',4) & z4e{down}
+ ..z5e---z6e..z7e{down} & super_arc.e(7,8)...{up}z9e; % main stroke
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11); endchar;
+
+iff known spanish_query: cmchar "Spanish open italic question mark";
+beginchar(spanish_query,9u#,asc_height#-desc_depth#,desc_depth#);
+adjust_fit(0,0); pickup tiny.nib; pos10(dot_size,0); pos11(dot_size,90);
+lft x10l=hround(.5w-.5dot_size); top y11r=h; z10=z11; dot(10,11); % dot
+pickup fine.nib; pos1(flare,0); pos2(hair,0); pos3(vair,-90);
+rt x1r=hround(w-u); x3=.5w; y1+.5flare=asc_height-x_height-d;
+bot y3r=-d-o; bulb(3,2,1); % bulb
+pos8(vair,90); x8=.5w; top y8r=.25[bot y11l,y1+.5flare]-1;
+numeric theta; theta=angle(10u,y8-y3)-90; slope:=(y8-y3)/10u;
+pos3'(vair,90); z3'=z3; pos0(vstem,theta); x0=x3; y0=1/3[y8,y3];
+lft x4l=hround 1.5u; rt x7r=hround 2/3w;
+x4r-x4l=x7r-x7l=hround .5[vair,vstem]-fine;
+ellipse_set(3'l,4l,5l,0l); ellipse_set(3'r,4r,5r,0r); y4=y4r;
+ellipse_set(8l,7l,6l,0l); ellipse_set(8r,7r,6r,0r); y7=y7r;
+pos9(hair,180); lft x9r=hround(1/3w-.5hair); y9=good.y .5[y8,y0];
+filldraw stroke super_arc.e(3',4) & z4e{up}
+ ..z5e---z6e..z7e{up} & super_arc.e(7,8)...{down}z9e; % main stroke
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11); endchar;
diff --git a/dviware/quicspool/wbfonts/tmathit.mf b/dviware/quicspool/wbfonts/tmathit.mf
new file mode 100644
index 0000000000..de364b84e4
--- /dev/null
+++ b/dviware/quicspool/wbfonts/tmathit.mf
@@ -0,0 +1,1015 @@
+% $Header: tmathit.mf,v 1.1 88/01/15 13:12:54 simpson Rel $
+% $Log: tmathit.mf,v $
+%Revision 1.1 88/01/15 13:12:54 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:36 simpson
+%beta test
+%
+% The Computer Modern Math Italic family (by D. E. Knuth, 1979--1985)
+
+font_coding_scheme:="TeX math italic";
+mode_setup; font_setup;
+
+input tgreekl; % lower case Greek letters
+
+% From file italms.mf, font cmmi10 (output with slant)
+cmchar "Lowercase italic script l";
+beginchar(oct"044",4.5u#+max(1.5u#,stem#),asc_height#,0);
+italcorr .8asc_height#*slant-u#;
+adjust_fit(if monospace:u#,u# else: 0,0 fi); pickup fine.nib;
+pos1(hair,-45); pos2(hair,0); pos3(vair,90);
+pos4(stem,180); pos5(vair,270); pos6(hair,315);
+lft x1l=hround(lft x1l-x1); rt x2r=hround(w-1.5u); x3=.5w;
+lft x4r=hround .5u; x5=x3+.75u; x6=x1+w+1;
+y1=y6=.125h; y2=.8h; top y3r=h+oo; y4=.5[y3,y5]; bot y5=-oo;
+filldraw stroke z1e{10u,asc_height}...z2e{up}...pulled_arc.e(3,4)
+ & pulled_arc.e(4,5)...z6e{10u,asc_height}; % bowl and hook
+math_fit(0,ic#); penlabels(1,2,3,4,5,6); endchar;
+
+font_slant slant;
+font_x_height x_height#;
+font_quad 18u#+4letter_fit#;
+
+slant:=mono_charic#:=0; % the remaining characters will not be slanted
+currenttransform:=identity yscaled aspect_ratio scaled granularity;
+
+input titalms; % special symbols for math italic
+input tgreeku; % upper case greek letters
+input tromms; % roman math specials
+
+% The following characters come from a hodge-podge of files.
+
+% My own creation (created in just 1 hour!)
+cmchar "Right hand";
+beginchar(oct"004", 2.1body_height#, body_height#, 0);
+adjust_fit(0,0);
+picture hand;
+% On the graph I drew this on, the hand is 40 units tall and 84 (2.1*40) units
+% wide.
+handunit# := body_height#/40;
+define_pixels(handunit);
+z1=(4handunit,0); z2=(handunit,handunit); z3=(0,4handunit);
+z4=(0,34handunit); z5=(handunit,36handunit); z6=(4handunit,37handunit);
+z7=(9handunit,35handunit); z8=(16handunit,36handunit);
+z9=(30handunit,38handunit); z10=(50handunit,40handunit);
+z11=(70handunit,40handunit); z12=(78handunit,40handunit);
+z13=(84handunit,38handunit); z14=(83handunit,34handunit);
+z15=(80handunit,33handunit); z16=(56handunit,30handunit);
+z17=(52handunit,29handunit); z18=(51handunit,24handunit);
+z19=(46handunit,18handunit); z20=(45handunit,14handunit);
+z21=(40handunit,8handunit); z22=(37handunit,handunit);
+z23=(35handunit,0); z24=(27handunit,handunit); z25=(13handunit,2handunit);
+fill z1{dir 180}..z2{z3-z1}..{dir 90}z3--z4{dir 90}..z5{z6-z4}..z6{dir 0}
+..z7{dir 0}..z8..z9..z10..z11{dir 0}--z12{dir 0}..z13{dir -80}..z14{dir 225}
+..z15{dir 190}--z16..{dir 200}z17 & flex(z17,z18,z19) & flex(z19,z20,z21)
+..z22{dir 225}..z23{dir 180}..z24{z25-z23}..z25..cycle;
+hand:=currentpicture;
+endchar;
+
+% My own creation
+cmchar "Left hand";
+beginchar(oct"036", 2.1body_height#, body_height#, 0);
+adjust_fit(0,0);
+currentpicture:=hand reflectedabout ((.5w,0),(.5w,h));
+endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Subset or equal to sign";
+compute_spread(.45x_height#,.55x_height#);
+spread#':=spread#; spread':=spread; % the spread of `$=$'
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"133",14u#,v_center(spread#'+spread#+rule_thickness#));
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x2=hround 1.5u-eps; x1=x3=w-x2;
+y1-y3=spread; y2=.5[y1,y3]; top y1=h;
+x4=x5=.5w; y4=y1; y5=y3;
+draw z1---z4...z2{down}...z5---z3; % arc and bars
+x8=x1; lft x9=x2; y8=y9; y3-y9=spread'; draw z8--z9; % lower bar
+labels(1,2,3,4,5,8,9); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Superset or equal to sign";
+compute_spread(.45x_height#,.55x_height#);
+spread#':=spread#; spread':=spread; % the spread of `$=$'
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"002",14u#,v_center(spread#'+spread#+rule_thickness#));
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x1=hround 1.5u-eps; x2=w-x1; x3=x1;
+y1-y3=spread; y2=.5[y1,y3]; top y1=h;
+x4=x5=.5w; y4=y1; y5=y3;
+draw z1---z4...z2{down}...z5---z3; % arc and bars
+x8=x1; rt x9=x2; y8=y9; y3-y9=spread'; draw z8--z9; % lower bar
+labels(1,2,3,4,5,8,9); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Times operator";
+beginarithchar(oct"052"); pickup rule.nib;
+x1=good.x(1/sqrt2)[.5w,rt u]; y1=good.y(1/sqrt2)[math_axis,bot h];
+x2=x3=w-x1; x4=x1; .5[y1,y2]=.5[y3,y4]=math_axis; y2=y4;
+draw z1--z2; draw z3--z4; % diagonals
+labels(1,2,3,4); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Asterisk at the axis";
+beginchar(oct"071",9u#,v_center(x_height#));
+adjust_fit(0,0);
+numeric ast_flare; ast_flare=hround .7[thin_join,stem];
+x0=.5w; y0=h-.5x_height;
+for d=-150 step 60 until 150: z[d]=z0+.5dir d xscaled 7.5u yscaled x_height;
+ numeric theta; theta=angle(z[d]-z0);
+ fill z0+.5(0,-thin_join)rotated theta
+ ---z[d]+.5(-ast_flare,-ast_flare)rotated theta
+ ..z[d]..z[d]+.5(-ast_flare,ast_flare)rotated theta
+ ---z0+.5(0,thin_join)rotated theta--cycle; endfor % diagonal at angle |d|
+labels(0,[-150],[-90],[-30],30,90,150); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Elementary division operator";
+beginarithchar(oct"057"); pickup rule.nib;
+x3-.5dot_size=hround(.5w-.5dot_size); w:=r:=2x3;
+y3+.5dot_size=vround(math_axis+math_spread[.5x_height,.6x_height]+.5dot_size);
+lft x1=hround u-eps; x2=w-x1; y1=y2=math_axis;
+draw z1--z2; % bar
+pos3(dot_size,0); pos4(dot_size,90); z3=z4;
+pos5(dot_size,0); pos6(dot_size,90); z5=z6; x5=x3; .5[y3,y5]=math_axis;
+dot(3,4); dot(5,6); % dots
+penlabels(1,2,3,4,5,6); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Similarity sign";
+compute_spread(.45x_height#,.55x_height#);
+beginchar(oct"062",14u#,v_center(spread#+rule_thickness#));
+adjust_fit(0,0);
+pickup pencircle xscaled .7rule_thickness yscaled 1.4rule_thickness;
+if vair#>.8curve#: pickup rule.nib; autorounded; fi % monoline
+lft x1=hround u; x2=4u; x3=w-x2; x4=w-x1;
+bot y1=bot y3=-d; top y2=top y4=h;
+draw z1{up}...z2{right}..{right}z3...{up}z4; % stroke
+labels(1,2,3,4); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Similar or equal sign";
+compute_spread(.45x_height#,.55x_height#);
+beginchar(oct"061",14u#,v_center(2spread#+rule_thickness#));
+adjust_fit(0,0);
+pickup pencircle xscaled .7rule_thickness yscaled 1.4rule_thickness;
+if vair#>.8curve#: pickup rule.nib; autorounded; fi % monoline
+lft x1=hround u; x2=4u; x3=w-x2; x4=w-x1;
+bot y1=bot y3=floor math_axis; top y2=top y4=h;
+draw z1{up}...z2{right}..{right}z3...{up}z4; % stroke
+pickup rule.nib; lft x5=hround u-eps; x6=w-x5; y5=y6=math_axis-spread;
+draw z5--z6; % bar
+labels(1,2,3,4,5,6); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Proportionality sign";
+beginchar(oct"003",16.5u#,x_height#,0);
+italcorr x_height#*slant-.5u#;
+adjust_fit(0,-2.5u#); pickup fine.nib;
+numeric theta,phi; phi=angle(3u,h); theta=angle(5u,-h);
+pos1(vair,180); pos2(.5[vair,stem],90+.5theta); pos3(stem,90+theta);
+pos4(stem,90+theta); pos5(.5[vair,stem],90+.5theta);
+pos6(vair,180); pos7(.2[vair,stem],270+.5phi);
+pos8(.3[vair,stem],270+phi); pos9(.2[vair,stem],270+.5phi);
+lft x1r=w-rt x6l=hround u; x2=x9=.4[x1,x8]; x5=x7=.6[x8,x6];
+if monospace: x2l:=x2r; x5r:=x5l; x7r:=x7l; x9l:=x9r; fi
+y1=y6=.5h; top y2r=top y7l=h+oo; bot y5l=bot y9r=-oo;
+x8=.5[x3,x4]=.5w; y8=.5[y3,y4]=.5h;
+y3-y4=h/3; z3-z4=whatever*dir theta;
+filldraw stroke z1e{up}...z2e{right}...z3e---z4e...z5e{right}...z6e{up}
+ ...z7e{left}...{-dir phi}z8e...{left}z9e...z1e{up}; % `infinity' bowls
+erase fill (w-3.5u,h+o)--(w,h+o)
+ --(w,-o)--(w-3.5u,-o)--cycle; % erase excess
+penlabels(1,2,3,4,5,6,7,8,9); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Empty set symbol";
+beginchar(oct"172",9u#,body_height#,body_height#-asc_height#);
+adjust_fit(0,0);
+penpos1(vair,90); penpos3(vair,-90); penpos2(stem,180); penpos4(stem,0);
+if not monospace: interim superness:=sqrt(more_super*hein_super); fi
+x2r=hround max(.7u,1.45u-.5stem);
+x4r=w-x2r; x1=x3=.5w; y1r=asc_height+o; y3r=-o;
+y2=y4=.5asc_height-vair_corr; y2l:=y4l:=.52asc_height;
+penstroke pulled_arc.e(1,2) & pulled_arc.e(2,3)
+ & pulled_arc.e(3,4) & pulled_arc.e(4,1) & cycle; % bowl
+pickup rule.nib; lft x6=hround 2u-eps; x5=w-x6; top y5=h+o; bot y6=-d-o;
+draw z5--z6; % diagonal
+penlabels(1,2,3,4,5,6); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Nabla or backwards-difference operator";
+beginchar(oct"050",15u#,cap_height#,0);
+adjust_fit(0,0);
+numeric right_stem,alpha;
+right_stem=cap_hair if hefty: -3stem_corr fi;
+x1l=w-x4r=.75u; y1=y4=h;
+x2-x1=x4-x3; x3l=x2l+apex_corr; y2=y3=-apex_o-apex_oo;
+alpha=diag_ratio(2,right_stem,y1-y2,x4r-x1l-apex_corr);
+penpos1(alpha*cap_stem,0); penpos2(alpha*cap_stem,0);
+penpos3(alpha*right_stem,0); penpos4(alpha*right_stem,0);
+fill diag_end(2l,1l,1,1,4r,3r)--diag_end(4r,3r,1,1,2l,1l)--cycle; % triangle
+z0=whatever[z1r,z2r]=whatever[z3l,z4l];
+y5=y6=h-cap_vstem; z5=whatever[z1r,z2r]; z6=whatever[z3l,z4l];
+if y0>cap_notch_cut: y0:=cap_notch_cut;
+ unfill z0+.5right{up}...{z4-z3}z6--z5{z2-z1}
+ ...{down}z0+.5left--cycle; % counter
+else: unfill z0--z5--z6--cycle; fi % counter
+penlabels(0,1,2,3,4,5,6); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Section sign";
+beginchar(oct"070",6.5u#+max(1.5u#,stem#),asc_height#,desc_depth#);
+adjust_fit(0,0); pickup fine.nib;
+numeric sstem; sstem=hround .75[hair,stem];
+pos0(stem,0); pos1(hair,0); pos2(vair,90); pos3(sstem,180); pos4(vair,270);
+pos5'(sstem,0); pos5(sstem,180);
+pos6(vair,90); pos7(sstem,0); pos8(vair,-90); pos9(hair,-180); pos10(stem,-180);
+top y2r=h+oo; bot y8r=-d-oo; y2-y1=y9-y8=(y2-y8)/8;
+y3=.52[y4,y2]; y5=.52[y4,y6]; y7=.52[y6,y8]; y5'=.52[y6,y4];
+y2-y4=y4-y6=y6-y8;
+rt x1r=hround(w-1.5u); lft x3r=hround 1.25u;
+x2=x4=x6=x8=.5w; x5=x7=w-x3; x5'=x3; x9=w-x1;
+bulb(2,1,0); bulb(8,9,10); % bulbs
+filldraw stroke z2e{left}...z3e{down}...z4e{3(x5-x3),y5-y3}
+ ...z5e{down}...{left}z6e; % upper stroke
+filldraw stroke z4e{left}...z5'e{down}...z6e{3(x7-x5'),y7-y5'}
+ ...z7e{down}...{left}z8e; % upper stroke
+penlabels(0,1,2,3,4,5,6,7,8,9,10); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Double dagger mark";
+beginchar(oct"131",8u#,asc_height#,desc_depth#);
+adjust_fit(0,0); pickup fine.nib;
+pos1(stem,0); pos2(thin_join,0); pos3(stem,0);
+pos4(stem,90); pos2'(thin_join,90); pos5(stem,90); z2'=z2;
+x1=x2=x3; x1-.5stem=hround(.5w-.5stem); w:=r:=2x1;
+x4-.5stem=hround u; x5=w-x4;
+y1+.5stem=h+oo; y2=y4=y5=.5[y1,y3]; y3-.5stem=ceiling(.5[-d,h]);
+filldraw circ_stroke z1e{down}..{down}z2e; % top stem
+filldraw circ_stroke z3e{up}..{up}z2e; % upper middle stem
+filldraw circ_stroke z4e{right}..{right}z2'e; % top left bulb
+filldraw circ_stroke z5e{left}..{left}z2'e; % top right bulb
+pos6(stem,0); pos7(thin_join,0); pos8(stem,0);
+pos9(stem,90); pos7'(thin_join,90); pos0(stem,90); z7'=z7;
+x6=x7=x8=x1; x9=x4; x0=x5;
+y6=y3-stem-1; y7=y9=y0=.5[y6,y8]; y8-.5stem=-d-oo;
+filldraw circ_stroke z6e{down}..{down}z7e; % lower middle stem
+filldraw circ_stroke z8e{up}..{up}z7e; % bottom stem
+filldraw circ_stroke z9e{right}..{right}z7'e; % bottom left bulb
+filldraw circ_stroke z0e{left}..{left}z7'e; % bottom right bulb
+penlabels(1,2,3,4,5,6,7,8,9,0); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Minus";
+beginarithchar(oct"055"); pickup rule.nib;
+lft x1=hround 1.5u-eps; x2=w-x1; y1=y2=math_axis;
+draw z1--z2; % bar
+labels(1,2); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Plus-or-minus sign";
+beginarithchar(oct"010"); pickup rule.nib;
+numeric shiftup; shiftup=vround 1.5u;
+x1=x2=.5w; lft x3=lft=x5=hround u-eps; x4=x6=w-x3;
+.5[y1,y2]=y3=y4=math_axis+shiftup; top y1=h+shiftup; y5=y6=y2;
+draw z1--z2; % stem
+draw z3--z4; % plus bar
+draw z5--z6; % minus bar
+labels(1,2,3,4,5,6); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Downward arrow";
+beginchar(oct"067",9u#,asc_height#,asc_depth#);
+adjust_fit(0,0); pickup crisp.nib;
+pos1(rule_thickness,0); pos2(rule_thickness,0);
+pos3(bar,90); pos4(bar,90);
+lft x1l=hround(.5w-.5rule_thickness); y1+.5rule_thickness=h;
+x0=x1=x2; bot y0=-d; x0-x3=x4-x0=3u+eps;
+y3=y4=y0+.24asc_height+eps;
+pos5(bar,angle(z4-z0)); z5l=z0;
+pos6(bar,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+numeric t; path p; p=z4r{z9-z4}..z6r;
+t=xpart(p intersectiontimes((x2r,-d)--(x2r,h))); y2=ypart point t of p;
+filldraw z0..{z4-z9}z4l--subpath (0,t) of\\(z4r{z9-z4}..z6r)
+ --z2r---z1r..z1l---z2l--subpath (t,0) of\\(z3r{z9-z3}..z5r)
+ --z3l{z9-z3}..z0 & cycle; % arrowhead and stem
+penlabels(0,1,2,3,4,5,6,9); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Upward arrow";
+beginchar(oct"066",9u#,asc_height#,asc_depth#);
+italcorr .76asc_height#*slant+.5crisp#-u#;
+adjust_fit(0,0); pickup crisp.nib;
+pos1(rule_thickness,0); pos2(rule_thickness,0);
+pos3(bar,90); pos4(bar,90);
+lft x1l=hround(.5w-.5rule_thickness); y1-.5rule_thickness=-d;
+x0=x1=x2; top y0=h; x0-x3=x4-x0=3u+eps;
+y3=y4=y0-.24asc_height-eps;
+pos5(bar,angle(z4-z0)); z5l=z0;
+pos6(bar,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+numeric t; path p; p=z4l{z9-z4}..z6r;
+t=xpart(p intersectiontimes((x2r,-d)--(x2r,h))); y2=ypart point t of p;
+filldraw z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6r)
+ --z2r---z1r..z1l---z2l--subpath (t,0) of\\(z3l{z9-z3}..z5r)
+ --z3r{z9-z3}..z0 & cycle; % arrowhead and stem
+penlabels(0,1,2,3,4,5,6,9); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Leftward arrow";
+compute_spread(.45x_height#,.55x_height#);
+beginchar(oct"064",18u#,v_center(spread#+rule_thickness#));
+adjust_fit(0,0); pickup crisp.nib;
+pos1(rule_thickness,90); pos2(rule_thickness,90); pos3(bar,0); pos4(bar,0);
+y0=y1=y2=math_axis; x1+.5rule_thickness=hround(w-u); lft x0=hround u;
+y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0+3u+eps;
+pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+numeric t; path p; p=z4r{z9-z4}..z6r;
+t=xpart(p intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p;
+filldraw z0..{z4-z9}z4l--subpath (0,t) of\\(z4r{z9-z4}..z6r)
+ --z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3r{z9-z3}..z5r)
+ --z3l{z9-z3}..z0 & cycle; % arrowhead and stem
+penlabels(0,1,2,3,4,5,6,9); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Rightward arrow";
+compute_spread(.45x_height#,.55x_height#);
+beginchar(oct"065",18u#,v_center(spread#+rule_thickness#));
+adjust_fit(0,0); pickup crisp.nib;
+pos1(rule_thickness,90); pos2(rule_thickness,90); pos3(bar,0); pos4(bar,0);
+y0=y1=y2=math_axis; x1-.5rule_thickness=hround u; rt x0=hround(w-u);
+y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0-3u-eps;
+pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+numeric t; path p; p=z4l{z9-z4}..z6r;
+t=xpart(p intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p;
+filldraw z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6r)
+ --z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3l{z9-z3}..z5r)
+ --z3r{z9-z3}..z0 & cycle; % arrowhead and stem
+penlabels(0,1,2,3,4,5,6,9); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Proper subset sign";
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"032",14u#,v_center(spread#+rule_thickness#));
+italcorr h#*slant-u#;
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x2=hround 1.5u-eps; x1=x3=w-x2;
+y1-y3=spread; y2=.5[y1,y3]=math_axis;
+x4=x5=.5w; y4=y1; y5=y3;
+draw z1---z4...z2{down}...z5---z3; % arc and bars
+labels(1,2,3,4,5); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Proper superset sign";
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"033",14u#,v_center(spread#+rule_thickness#));
+italcorr h#*slant-u#;
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x1=hround 1.5u-eps; x2=w-x1; x3=x1;
+y1-y3=spread; y2=.5[y1,y3]=math_axis;
+x4=x5=.5w; y4=y1; y5=y3;
+draw z1---z4...z2{down}...z5---z3; % arc and bars
+labels(1,2,3,4,5); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Element sign";
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"037",12u#,v_center(spread#+rule_thickness#));
+italcorr h#*slant-u#;
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x2=hround 1.5u-eps; x1=x3=x6=w-x2;
+y1-y3=spread; y2=y6=.5[y1,y3]=math_axis;
+x4=x5=.5w+u; y4=y1; y5=y3;
+draw z1---z4...z2{down}...z5---z3; % arc and bars
+draw z2--z6; % middle bar
+labels(1,2,3,4,5,6); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Logical not sign";
+beginchar(oct"035",12u#,x_height#,0);
+italcorr x_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x1=hround u-eps; x2=x3=w-x1;
+y1=y2=good.y .5[bar_height,h]; y2-y3=1.2(h-bar_height);
+draw z1--z2--z3; % bar and stem
+labels(1,2,3); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Less than sign";
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"074",14u#,v_center(spread#+rule_thickness#));
+italcorr h#*slant-u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x2=hround 1.5u-eps; x1=x3=w-x2;
+y1-y3=spread; y2=.5[y1,y3]=math_axis;
+draw z1--z2--z3; % diagonals
+labels(1,2,3); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Greater than sign";
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"076",14u#,v_center(spread#+rule_thickness#));
+italcorr math_axis#*slant-u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x2=hround(w-1.5u)+eps; x1=x3=w-x2;
+y1-y3=spread; y2=.5[y1,y3]=math_axis;
+draw z1--z2--z3; % diagonals
+labels(1,2,3); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Unequals sign";
+compute_spread(.45x_height#,.55x_height#);
+beginchar(oct"063",14u#,v_center(4spread#+rule_thickness#));
+italcorr h#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x1=hround u-eps; x3=x1; x2=x4=w-x1;
+y1=y2; y3=y4; y1-y3=spread; .5[y1,y3]=math_axis;
+draw z1--z2; draw z3--z4; % bars
+lft x6=hround 3.5u-eps; x5=w-x6; top y5=h+o; bot y6=-d-o;
+draw z5--z6; % diagonal
+labels(1,2,3,4,5,6); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Less than or equal to sign";
+compute_spread(.45x_height#,.55x_height#);
+spread#':=spread#; spread':=spread; % the spread of `$=$'
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"011",14u#,v_center(spread#'+spread#+rule_thickness#));
+italcorr h#*slant-u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x2=hround 1.5u-eps; x1=x3=w-x2;
+y1-y3=spread; y2=.5[y1,y3]; top y1=h;
+draw z1--z2--z3; % diagonals
+x8=x1; x9=x2; y8=y9; y3-y9=spread'; draw z8--z9; % bar
+labels(1,2,3,8,9); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Greater than or equal to sign";
+compute_spread(.45x_height#,.55x_height#);
+spread#':=spread#; spread':=spread; % the spread of `$=$'
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"012",14u#,v_center(spread#'+spread#+rule_thickness#));
+italcorr h#*slant-u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x1=hround 1.5u-eps; x2=w-x1; x3=x1;
+y1-y3=spread; y2=.5[y1,y3]; top y1=h;
+draw z1--z2--z3; % diagonals
+x8=x1; x9=x2; y8=y9; y3-y9=spread'; draw z8--z9; % bar
+labels(1,2,3,8,9); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Equivalence or congruence sign";
+compute_spread(.45x_height#,.55x_height#);
+beginchar(oct"060",14u#,v_center(2spread#+rule_thickness#));
+italcorr h#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x1=hround u-eps; x3=x5=x1; x2=x4=x6=w-x1;
+y1=y2; y3=y4=math_axis; y5=y6; y1-y3=y3-y5=spread;
+draw z1--z2; % upper bar
+draw z3--z4; % middle bar
+draw z5--z6; % lower bar
+labels(1,2,3,4,5,6); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Reverse slash (backslash)";
+beginchar(oct"134",9u#,body_height#,paren_depth#);
+adjust_fit(0,0); pickup rule.nib;
+lft x1=hround u-eps; top y1=h+eps;
+rt x2=hround(w-u)+eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+labels(1,2); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Vertical line";
+beginchar(oct"174",5u#,body_height#,paren_depth#);
+italcorr body_height#*slant+.5rule_thickness#-2u#;
+adjust_fit(0,0); pickup rule.nib;
+x1=x2=good.x .5w; top y1=h+eps; bot y2=-d-eps;
+draw z1--z2; % stem
+labels(1,2); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Left curly brace";
+beginchar(oct"173",9u#,body_height#,paren_depth#);
+italcorr body_height#*slant+.5vair#-u#;
+adjust_fit(0,0); pickup fine.nib;
+forsuffixes $=1,1',4,4',7,7': pos$(vair,0); endfor
+forsuffixes $=2,3,5,6: pos$(stem,0); endfor
+x2=x3=x5=x6; x1=x1'=x7=x7'=w-x4=w-x4';
+lft x4l=hround(1.5u-.5vair); lft x2l=hround(.5w-.5stem);
+top y1=h; bot y7=-d; .5[y4,y4']=.5[y1,y7]=.5[y2,y6]=.5[y3,y5];
+y1-y2=y3-y4=(y1-y4)/4; y1-y1'=y4-y4'=y7'-y7=vair-fine;
+filldraw z1l{left}...z2l---z3l...{left}z4l
+ --z4'l{right}...z5l---z6l...{right}z7l
+ --z7r--z7'r{left}...z6r---z5r...{left}.5[z4r,z4'r]{right}
+ ...z3r---z2r...{right}z1'r--z1r--cycle; % stroke
+penlabels(1,2,3,4,5,6,7); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Right curly brace";
+beginchar(oct"175",9u#,body_height#,paren_depth#);
+italcorr math_axis#*slant+.5vair#-u#;
+adjust_fit(0,0); pickup fine.nib;
+forsuffixes $=1,1',4,4',7,7': pos$(vair,0); endfor
+forsuffixes $=2,3,5,6: pos$(stem,0); endfor
+x2=x3=x5=x6; x1=x1'=x7=x7'=w-x4=w-x4';
+rt x4r=hround(w-1.5u+.5vair); rt x2r=hround(.5w+.5stem);
+top y1=h; bot y7=-d; .5[y4,y4']=.5[y1,y7]=.5[y2,y6]=.5[y3,y5];
+y1-y2=y3-y4=(y1-y4)/4; y1-y1'=y4-y4'=y7'-y7=vair-fine;
+filldraw z1r{right}...z2r---z3r...{right}z4r
+ --z4'r{left}...z5r---z6r...{left}z7r
+ --z7l--z7'l{right}...z6l---z5l...{right}.5[z4l,z4'l]{left}
+ ...z3l---z2l...{left}z1'l--z1l--cycle; % stroke
+penlabels(1,2,3,4,5,6,7); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Straight double quotes";
+beginchar(oct"042",9u#,asc_height#,0);
+numeric top_width#,spread#; top_width#=if serifs: flare# else: stem# fi;
+spread#=max(3u#,top_width#+.5u#); define_pixels(spread);
+italcorr asc_height#*slant+.5top_width#+.5spread#-4u#;
+adjust_fit(0,0);
+x1=x2; x3=x4=w-x1; x3-x1=spread+2; y1=y3;
+y2=y4=max(.5[bar_height,x_height]+.5vair,h-x_height);
+if serifs: pickup crisp.nib; pos1(flare,0); pos2(vair,0);
+ pos3(flare,0); pos4(vair,0);
+ y1+.5stem=h; filldraw circ_stroke z1e--z2e; % left stem and bulb
+ filldraw circ_stroke z3e--z4e; % right stem and bulb
+else: pickup fine.nib; pos1(stem,0); pos2(vair,0);
+ pos3(stem,0); pos4(vair,0);
+ top y1=h; filldraw stroke z1e--z2e; % left stem
+ filldraw stroke z3e--z4e; fi % right stem
+penlabels(1,2,3,4); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Infinity";
+beginchar(oct"001",18u#,x_height#,0);
+italcorr .7x_height#*slant-.5u#;
+adjust_fit(0,0); pickup fine.nib;
+numeric theta,phi;
+if monospace: phi=-theta=90;
+else: phi=angle(4u,h); theta=angle(6u,-h); fi
+pos1(vair,180); pos2(.5[vair,curve],90+.5theta); pos3(curve,90+theta);
+pos4(curve,90+theta); pos5(.5[vair,curve],90+.5theta);
+pos6(vair,180); pos7(.2[vair,curve],270+.5phi);
+pos8(.3[vair,curve],270+phi); pos9(.2[vair,curve],270+.5phi);
+lft x1r=w-rt x6l=hround u; x2=x9=.4[x1,x8]; x5=x7=.6[x8,x6];
+if monospace: x2l:=x2r; x5r:=x5l; x7r:=x7l; x9l:=x9r; fi
+y1=y6=.5h; top y2r=top y7l=h+oo; bot y5l=bot y9r=-oo;
+x8=.5[x3,x4]=.5w; y8=.5[y3,y4]=.5h;
+y3-y4=h/3; z3-z4=whatever*dir theta;
+filldraw stroke z1e{up}...z2e{right}...z3e---z4e...z5e{right}
+ ...z6e{up}...z7e{left}...{-dir phi}z8e...{left}z9e...z1e{up}; % bowls
+penlabels(1,2,3,4,5,6,7,8,9); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Set union sign";
+beginchar(oct"005",12u#,.8asc_height#,0);
+italcorr .8asc_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x1=hround u; x2=x1; x3=w-x3; x4=x5=w-x1;
+y1=good.y h+o; bot y3=-o; y2=y4=2/3[y1,y3]; y5=y1;
+draw z1---z2...z3...z4---z5; % stems and cup
+labels(1,2,3,4,5); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Set intersection sign";
+beginchar(oct"034",12u#,.8asc_height#,0);
+italcorr .8asc_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x1=hround u; x2=x1; x3=w-x3; x4=x5=w-x1;
+y3=good.y h+o; bot y1=-o; y2=y4=2/3[y1,y3]; y5=y1;
+draw z1---z2...z3...z4---z5; % stems and cap
+labels(1,2,3,4,5); endchar;
+
+% My own creation
+cmchar "Square root extender";
+beginchar(oct"006",12u#,14u#,0);
+ adjust_fit(0,0); pickup rule.nib;
+ bot lft z1=(0,h); bot rt z2=(w+2u,h); draw z1--z2;
+ penlabels(1,2);
+endchar;
+
+% From font cmsy10, file symbol.mf (hacked up to be above baseline)
+cmchar "Radical sign";
+beginchar(oct"013",15u#,14u#,2u#);
+ adjust_fit(0,-letter_fit#); pickup rule.nib;
+ x1=good.x 4/9w; x2=good.x(w+.5); bot y1=-2u; bot y2=14u;
+ draw z1--z2; % diagonal
+ pickup crisp.nib; pos3(max(curve,rule_thickness),0);
+ x3l=1.5[x2,x1]; y3=.5[y1,y2];
+ pos4(rule_thickness,0); x4=x1; bot y4=-2u;
+ pos5(vair,-45); x5l=good.x(x3l-u); z5l=whatever[z3r,z2];
+ z6=z5r+whatever*(z2-z3r)=whatever[z3l,z4l];
+ z7=whatever[z1,z2]=z3r+whatever*(z4l-z3l);
+ filldraw z5r--z6--z4l--z4--z7--z3r--z5l--cycle; % left diagonal and serif
+ penlabels(1,2,3,4,5,6,7);
+endchar;
+
+% The following TRW logo is designed by Mike Urban and put in the Bell
+% System logo position. The Bell System logo is not even used by AT&T
+% anymore and I work for TRW---so there. There is some perverse
+% appropriateness in having the escape sequence \(bs.
+def fixpt(expr pta,ptb,theta)=
+ if known xpart pta:
+ ((ypart pta)-(ypart ptb))/((xpart pta)-(xpart ptb))=
+ (sind theta)/(cosd theta);
+ else:
+ ((xpart pta)-(xpart ptb))/((ypart pta)-(ypart ptb))=
+ (cosd theta)/(sind theta);
+ fi;
+enddef;
+
+def over(expr pta,ptb,delta)=
+ xpart pta = (xpart ptb)+(delta/cosd 20);
+enddef;
+
+input logodesign;
+
+a#:=cap_height#/3.91;
+define_pixels(a);
+beginchar(oct"007", 12.82a#, 3.91a#, 0);
+LOGO;
+endchar;
+
+% From the font cmsy10, file sym.mf
+cmchar "Integral sign";
+beginchar(oct"015",5.25u#+max(1.25u#,stem#)+2max(1.5u#,curve#),
+ asc_height#,desc_depth#);
+italcorr asc_height#*slant-.5u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(curve,0); pos2(hair,0); pos3(vair,90); pos4(.6[hair,stem],180);
+pos5(stem,180); pos5'(stem,0); z5'=z5; pos6(.6[hair,stem],0);
+pos7(vair,-90); pos8(hair,-180); pos9(curve,-180);
+x7=w-x3=2.4u; rt x1r=max(rt x3+eps,hround(w-u)); x9=w-x1;
+x5=.5[x4,x6]; x4-x6=1.5u; lft x5r=hround(.5w-.5stem);
+y9-.5curve=vround(-.9d-o+vair); y3-y1=y9-y7;
+top y3r=h+o; bot y7r=-d-o; y5=.5[y3,y7]=.5[y4,y6]; y4-y6=2/3(y3-y7);
+bulb(3,2,1); bulb(7,8,9); % bulbs
+filldraw stroke z3e{left}...z4e{(z5e-z4e)xscaled 1.1}
+ ..tension atleast 1 and atleast .8..{z5-z4}z5e; % upper stem
+filldraw stroke z5'e{z6-z5}..tension atleast.8 and atleast 1
+ ..{(z6e-z5'e)xscaled 1.1}z6e...{left}z7e; % lower stem
+math_fit(0,-2u#);
+% It looks better with troff if we move it over 1 unit to the left
+currentpicture:=currentpicture shifted (-1u,0);
+penlabels(1,2,3,4,5,6,7,8,9); endchar;
+
+% From the font cmr10, file punct.mf
+cmchar "Hash mark (number sign)";
+if monospace: compute_spread(.6x_height#,.7x_height#);
+else: compute_spread(.45x_height#,.55x_height#); fi
+beginchar("#",15u#,asc_height#,asc_depth#);
+italcorr (math_axis#+.5(spread#+rule_thickness#))*slant-.5u#;
+adjust_fit(0,0);
+pickup rule.nib; lft x1=hround u-eps; x3=x1; x2=x4=w-x1;
+y1=y2; y3=y4; y1-y3=spread; .5[y1,y3]=math_axis;
+draw z1--z2; % upper bar
+draw z3--z4; % lower bar
+lft x6=hround 3u; rt x7=hround(w-3u); x5-x6=x7-x8;
+x8=good.x if monospace: .6 else: .5 fi\\w;
+top y5=top y7=h+eps; bot y6=bot y8=-d-eps;
+y15=y1; z15=whatever[z5,z6]; y36=y3; z36=whatever[z5,z6];
+y27=y2; z27=whatever[z7,z8]; y48=y4; z48=whatever[z7,z8];
+draw z5--if x5>x6+1:(good.x(x15+.5),y1)--(good.x(x15-.5),y1)
+ --(good.x(x36+.5),y3)--(good.x(x36-.5),y3)--fi\\z6; % left diagonal
+draw z7--if x7>x8+1:(good.x(x27+.5),y2)--(good.x(x27-.5),y2)
+ --(good.x(x48+.5),y4)--(good.x(x48-.5),y4)--fi\\z8; % right diagonal
+labels(1,2,3,4,5,6,7,8,15,27,36,48); endchar;
+
+% From font cmr10, file punct.mf
+cmchar "Plus sign";
+beginarithchar("+"); pickup rule.nib;
+x1=x2=good.x .5w; top y1=h+eps; .5[y1,y2]=math_axis;
+lft x3=hround u-eps; x4=w-x3; y3=y4=math_axis;
+draw z1--z2; % stem
+draw z3--z4; % crossbar
+labels(1,2,3,4); endchar;
+
+% From font cmr10, file accent.mf
+cmchar "Grave accent";
+beginchar(oct"140",9u#,min(asc_height#,2x_height#),0);
+adjust_fit(0,0);
+if serifs: pickup crisp.nib; x1-.5stem=hround 2u; x2=2/3[x1,w-x1];
+ y1+.5stem=h+eps; y2=max(2/3[h,x_height],x_height+o+hair);
+ numeric theta; theta=angle(z2-z1)+90;
+ pos1(stem,theta); pos2(hair,theta);
+ filldraw circ_stroke z1e--z2e; % diagonal
+else: pickup fine.nib; pos1(stem,0); pos2(vair,0);
+ lft x1l=hround 1.5u; rt x2r=hround(.5w+.25u+.5vair);
+ top y1=h; bot y2=vround 2/3[h,x_height];
+ filldraw stroke z1e--z2e; fi % diagonal
+penlabels(1,2); endchar;
+
+% From font cmr10, file accent.mf
+cmchar "Acute accent";
+beginchar(oct"047",9u#,min(asc_height#,2x_height#),0);
+italcorr h#*slant-if serifs: 1.5 fi u#;
+adjust_fit(0,0);
+if serifs: pickup crisp.nib; x1+.5stem=hround(w-2u); x2=2/3[x1,w-x1];
+ y1+.5stem=h+eps; y2=max(2/3[h,x_height],x_height+o+hair);
+ numeric theta; theta=angle(z2-z1)+90;
+ pos1(stem,theta); pos2(hair,theta);
+ filldraw circ_stroke z1e--z2e; % diagonal
+else: pickup fine.nib; pos1(stem,0); pos2(vair,0);
+ rt x1r=hround(w-1.5u); lft x2l=hround(.5w-.25u-.5vair);
+ top y1=h; bot y2=vround 2/3[h,x_height];
+ filldraw stroke z1e--z2e; fi % diagonal
+penlabels(1,2); endchar;
+
+% From font cmr10, file punct.mf
+cmchar "Equals sign";
+compute_spread(.45x_height#,.55x_height#);
+beginchar("=",14u#,v_center(spread#+rule_thickness#));
+italcorr h#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x1=hround u-eps; x3=x1; x2=x4=w-x1;
+y1=y2; y3=y4; y1-y3=spread; .5[y1,y3]=math_axis;
+draw z1--z2; % upper bar
+draw z3--z4; % lower bar
+labels(1,2,3,4); endchar;
+
+% From font cmr10, file punct.mf
+cmchar "At sign";
+beginchar("@",14u#,asc_height#,0);
+italcorr .7asc_height#*slant-.5u#;
+adjust_fit(0,if hefty or monospace:-2u# else: 0 fi);
+pickup fine.nib; pos0(fudged.hair,0); pos1(vair,90);
+pos2(fudged.stem,180); pos3(vair,270);
+pos4(fudged.stem,-180); pos5(fudged.stem,-180);
+pos6(vair,-90); pos7(fudged.hair,0);
+pos8(vair,90); pos9(fudged.hair,180);
+pos10(vair,270); pos11(.5[vair,flare],360);
+x1=x3=.5[x0,x2]; y0=y2=.5[y1,y3];
+x8=x10=.5w; y7=y9=.5[y8,y10];
+lft x9r=hround u; x7=w-x9; top y8r=h+oo; bot y10r=-oo;
+top y1r=vround(.8[y10,y8]+.5vair); bot y3r=vround(.2[y10,y8]-.5vair);
+x6l=1/3[x5l,x7l]; y6=y3; y11=good.y(.1[y10,y8]-.5);
+x0=x4=x5; y4=.8[y3,y1]; y5=2/3[y7,y6];
+if hefty or monospace: lft x2r=hround(5u-.5fudged.stem);
+ rt x0r=hround(w-3u); x11r=x0r;
+else: lft x2r=hround 3.4u; x0=w-x2; x11r=x7r; fi
+filldraw stroke super_arc.e(1,2) & super_arc.e(2,3); % left inner bowl
+filldraw stroke super_arc.e(3,0) & super_arc.e(0,1); % right inner bowl
+filldraw stroke super_arc.e(8,9) & super_arc.e(9,10)
+ & term.e(10,11,right,1,4); % left outer bowl and terminal
+if hefty or monospace: {{interim superness:=hein_super;
+ filldraw stroke super_arc.e(0,8)}}; % link
+else: (x,y6r)=whatever[z6l,z7l]; x6r:=x;
+ filldraw stroke z4e---z5e...z6e{right}...{up}z7e
+ & super_arc.e(7,8); fi % stem and link
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11); endchar;
+
+% From font cmr10, file accent.mf
+cmchar "Tilde (squiggle) accent";
+beginchar(oct"176",9u#,min(asc_height#,10/7x_height#+.5dot_size#),0);
+italcorr h#*slant-u#;
+adjust_fit(0,0);
+if serifs: numeric theta; theta=angle(1/6(6u-vair),1/4(h-x_height));
+ pickup crisp.nib; numeric mid_width; mid_width=.4[vair,stem];
+ pos1(vair,theta+90); pos2(vair,theta+90);
+ pos3(vair,theta+90); pos4(vair,theta+90);
+ z2-z1=z4-z3=(mid_width-crisp)*dir theta;
+ lft x1r=w-rt x4l=hround 1.5u; top y4r=h;
+ bot y1l=vround(bot y1l+min(2/3[x_height,h],y3l-.25vair)-top y1r);
+ pair delta; ypart delta=3(y3l-y1l); delta=whatever*dir theta;
+ filldraw z1l..controls(z1l+delta)and(z3l-delta)..z3l..z4l
+ --z4r..controls(z4r-delta)and(z2r+delta)..z2r..z1r--cycle; % stroke
+else: pickup fine.nib; pos1(vair,180); pos2(vair,90);
+ pos3(.5[vair,slab],90); pos4(vair,90); pos5(vair,180);
+ lft x1r=w-rt x5l=hround 1.5u; x2-x1=x3-x2=x4-x3=x5-x4;
+ bot y1=bot y4l=vround(.75[x_height,h]-vair);
+ top y2r=top y5=h; y3=.5[y2,y4];
+ filldraw stroke z1e{up}...z2e{right}..z3e..{right}z4e...{up}z5e; fi % stroke
+penlabels(1,2,3,4,5); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Circle for copyright, etc.";
+beginchar(oct"135",18u#,asc_height#,desc_depth#); autorounded;
+adjust_fit(if monospace:-3u#,-3u# else: 0,0 fi); pickup rule.nib;
+lft x6=hround u; x2=w-x6; top y8=h+o; bot y4=-d-o;
+circle_points; draw_circle; % circle
+labels(1,2,3,4,5,6,7,8); endchar;
+
+% From font cmr10, file accent.mf
+cmchar "Circumflex (hat) accent";
+beginchar(oct"041",9u#,min(asc_height#,2x_height#),0);
+if serifs: italcorr .5[x_height#,h#]*slant+.5hair#-1.75u#;
+ adjust_fit(0,0);
+ pickup crisp.nib; pos2(.5[vair,curve],90); top y2r=h; x2=.5w;
+ x1=w-x3=good.x 2.25u; y1=y3=.5[x_height,y2];
+ pos1(hair,angle(z2-z1)+90); pos3(hair,angle(z3-z2)+90);
+ filldraw stroke z1e--z2e--z3e; % diagonals
+else: italcorr 2/3[x_height#,h#]*slant-.5stem#+.5vair#-.75u#;
+ adjust_fit(0,0);
+ pickup fine.nib; pos1(vair,0); pos3(vair,0); x1=w-x3;
+ pos2(stem,0); top y2=h; x2=.5w; bot y1=bot y3=vround 2/3[h,x_height]-eps;
+ lft x1l=hround(rt x2r-3.25u-.5vair); % same slope as in the acute accent
+ z0=whatever[z1r,z2r]=whatever[z2l,z3l];
+ y4l=y4r=y2; x4l=good.x .2[x2l,x2]; x4r=w-x4l;
+ filldraw z4l--z1l--z1r--z0--z3l--z3r--z4r--cycle; fi % diagonals
+penlabels(0,1,2,3,4); endchar;
+
+% From font cmr10, file accent.mf
+cmchar "Circumflex (hat) accent";
+beginchar(oct"136",9u#,min(asc_height#,2x_height#),0);
+if serifs: italcorr .5[x_height#,h#]*slant+.5hair#-1.75u#;
+ adjust_fit(0,0);
+ pickup crisp.nib; pos2(.5[vair,curve],90); top y2r=h; x2=.5w;
+ x1=w-x3=good.x 2.25u; y1=y3=.5[x_height,y2];
+ pos1(hair,angle(z2-z1)+90); pos3(hair,angle(z3-z2)+90);
+ filldraw stroke z1e--z2e--z3e; % diagonals
+else: italcorr 2/3[x_height#,h#]*slant-.5stem#+.5vair#-.75u#;
+ adjust_fit(0,0);
+ pickup fine.nib; pos1(vair,0); pos3(vair,0); x1=w-x3;
+ pos2(stem,0); top y2=h; x2=.5w; bot y1=bot y3=vround 2/3[h,x_height]-eps;
+ lft x1l=hround(rt x2r-3.25u-.5vair); % same slope as in the acute accent
+ z0=whatever[z1r,z2r]=whatever[z2l,z3l];
+ y4l=y4r=y2; x4l=good.x .2[x2l,x2]; x4r=w-x4l;
+ filldraw z4l--z1l--z1r--z0--z3l--z3r--z4r--cycle; fi % diagonals
+penlabels(0,1,2,3,4); endchar;
+
+% My own creation
+cmchar "Box rule";
+beginchar(oct"132",1u#,cap_height#+2u#,4.3u#);
+italcorr body_height#*slant+.5rule_thickness#-2u#;
+adjust_fit(0,0); pickup crisp.nib;
+pos1(vair,0); pos2(vair,0);
+x1=x2=hround 0; y1=h; y2=-d;
+filldraw stroke z1e--z2e; % stem
+penlabels(1,2); endchar;
+
+% My own creation. Only used by otroff. See note below.
+cmchar "Underscore";
+beginchar("_",9.4u#,x_height#,.7u#);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric below_baseline; below_baseline#:=4u#;
+define_pixels(below_baseline);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(-below_baseline); x2=hround(w);
+x1=0;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+% My own creation (This is only used by ditroff. Ditroff's underscore
+% needs to be a frog's hair longer than otroff's.)
+cmchar "Underscore";
+beginchar(oct"041",9.4u#,x_height#,.7u#);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric below_baseline; below_baseline#:=4u#;
+define_pixels(below_baseline);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(-below_baseline); x2=hround(w+1u);
+x1=0;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+% The delimiters are from the font cmex10, file bigdel.mf. I had to hack
+% them up extensively though to get them to work with troff. Troff wants
+% everything lined up in the center and the widths of the floor and ceiling
+% characters are the same as the parentheses.
+cmchar "Extensible left bracket---top";
+beginchar(oct"022",8u#,cap_height#+2u#,4u#);
+adjust_fit(0,0); pickup fine.nib;
+pos1(heavy_rule_thickness,0); pos2(heavy_rule_thickness,0);
+top y1=h; y2=-d; x1=x2=hround(.5w);
+filldraw stroke z1e--z2e; % stem
+pos3(heavy_rule_thickness,90); pos4(heavy_rule_thickness,90);
+x3=x1l; rt x4=hround(w-.75u+.5heavy_rule_thickness); y3r=y4r=y1;
+filldraw stroke z3e--z4e; % upper bar
+penlabels(1,2,3,4); endchar;
+
+cmchar "Extensible left bracket---bottom";
+beginchar(oct"020",8u#,cap_height#+4u#,2u#);
+adjust_fit(0,0); pickup fine.nib;
+pos1(heavy_rule_thickness,0); pos2(heavy_rule_thickness,0);
+y1=h; bot y2=-d; x1=x2=hround(.5w);
+filldraw stroke z1e--z2e; % stem
+pos5(heavy_rule_thickness,90); pos6(heavy_rule_thickness,90);
+x5=x1l; rt x6=hround(w-.75u+.5heavy_rule_thickness); y5l=y6l=y2;
+filldraw stroke z5e--z6e; % lower bar
+penlabels(1,2,5,6); endchar;
+
+cmchar "Extensible right bracket---top";
+beginchar(oct"023",8u#,cap_height#+2u#,4u#);
+adjust_fit(0,0); pickup fine.nib;
+pos1(heavy_rule_thickness,0); pos2(heavy_rule_thickness,0);
+top y1=h; y2=-d; x1=x2=hround(.5w);
+filldraw stroke z1e--z2e; % stem
+pos3(heavy_rule_thickness,90); pos4(heavy_rule_thickness,90);
+x3=x1r; lft x4=hround(.75u-.5heavy_rule_thickness); y3r=y4r=y1;
+filldraw stroke z3e--z4e; % upper bar
+penlabels(1,2,3,4); endchar;
+
+cmchar "Extensible right bracket---bottom";
+beginchar(oct"021",8u#,cap_height#+4u#,2u#);
+adjust_fit(0,0); pickup fine.nib;
+pos1(heavy_rule_thickness,0); pos2(heavy_rule_thickness,0);
+y1=h; bot y2=-d; x1=x2=hround(.5w);
+filldraw stroke z1e--z2e; % stem
+pos5(stem,90); pos6(stem,90);
+x5=x1r; lft x6=hround(.75u-.5heavy_rule_thickness); y5l=y6l=y2;
+filldraw stroke z5e--z6e; % lower bar
+penlabels(1,2,5,6); endchar;
+
+cmchar "Extensible left curly brace---middle";
+beginchar(oct"030",8u#,cap_height#+4u#,4u#);
+adjust_fit(0,0); pickup fine.nib;
+numeric min_breadth; min_breadth=hround(rule_thickness+.6dw);
+pos4(min_breadth,0); pos4'(min_breadth,0);
+forsuffixes $=2,3,5,6: pos$(heavy_rule_thickness,0); endfor
+lft x4l=lft x4'l=hround(1.5u-.5min_breadth);
+x2=x3=x5=x6; x2=hround(.5w);
+y2=h; y6=-d; .5[y4,y4']=.5[y2,y6]=.5[y3,y5];
+y3-y4=(y2-y6)/4; y4-y4'=min_breadth-fine;
+filldraw z2l---z3l...{3(x4l-x3l),y4-y3}z4l
+ --z4'l{3(x5l-x4l),y5-y4'}...z5l---z6l--z6r---z5r
+ ...{3(x4r-x5r),.5[y4,y4']-y5}.5[z4r,z4'r]{3(x3r-x4r),y3-.5[y4,y4']}
+ ...z3r---z2r--cycle; % stroke
+penlabels(2,3,4,5,6); endchar;
+
+cmchar "Extensible right curly brace---middle";
+beginchar(oct"031",8u#,cap_height#+4u#,4u#);
+adjust_fit(0,0); pickup fine.nib;
+numeric min_breadth; min_breadth=hround(rule_thickness+.6dw);
+pos4(min_breadth,0); pos4'(min_breadth,0);
+forsuffixes $=2,3,5,6: pos$(heavy_rule_thickness,0); endfor
+rt x4r=rt x4'r=hround(w-1.5u+.5min_breadth);
+x2=x3=x5=x6; x2=hround(.5w);
+y2=h; y6=-d; .5[y4,y4']=.5[y2,y6]=.5[y3,y5];
+y3-y4=(y2-y6)/4; y4-y4'=min_breadth-fine;
+filldraw z2r---z3r...{3(x4r-x3r),y4-y3}z4r
+ --z4'r{3(x5r-x4r),y5-y4'}...z5r---z6r--z6l---z5l
+ ...{3(x4l-x5l),.5[y4,y4']-y5}.5[z4l,z4'l]{3(x3l-x4l),y3-.5[y4,y4']}
+ ...z3l---z2l--cycle; % stroke
+penlabels(2,3,4,5,6); endchar;
+
+cmchar "Extension module";
+beginchar(oct"017",8u#,cap_height#+4u#,4u#);
+adjust_fit(0,0); pickup fine.nib;
+numeric max_breadth; max_breadth=bold+2dw;
+pos2(heavy_rule_thickness,0); pos2'(heavy_rule_thickness,0);
+x2=x2'=hround(.5w); y2=h; y2'=-d;
+filldraw stroke z2e--z2'e; % link
+penlabels(2,2'); endchar;
+
+cmchar "Extensible left curly brace---top";
+beginchar(oct"024",8u#,cap_height#+2u#,4u#);
+adjust_fit(0,0); pickup fine.nib;
+numeric min_breadth; min_breadth=hround(rule_thickness+.6dw);
+pos1(min_breadth,0); pos1'(min_breadth,0);
+pos2(heavy_rule_thickness,0); pos3(heavy_rule_thickness,0);
+rt x1r=rt x1'r=hround(w-1.5u+.5min_breadth);
+x2=x3=hround(.5w);
+top y1=h; y3=-d; y2=.5[y1,y3]; y1-y1'=min_breadth-fine;
+filldraw z1l{3(x2l-x1l),y2-y1}...z2l---z3l
+ --z3r---z2r...{3(x1r-x2r),y1'-y2}z1'r--z1r--cycle; % stroke
+penlabels(1,2,3); endchar;
+
+cmchar "Extensible left curly brace---bottom";
+beginchar(oct"025",8u#,cap_height#+4u#,2u#);
+adjust_fit(0,0); pickup fine.nib;
+numeric min_breadth; min_breadth=hround(rule_thickness+.6dw);
+pos7(min_breadth,0); pos7'(min_breadth,0);
+pos5(heavy_rule_thickness,0); pos6(heavy_rule_thickness,0);
+rt x7r=rt x7'r=hround(w-1.5u+.5min_breadth);
+x5=x6=hround(.5w);
+y5=h; y7=-d; y6=.5[y5,y7]; y7'-y7=min_breadth-fine;
+filldraw z5l---z6l...{3(x7l-x6l),y7-y6}z7l
+ --z7r--z7'r{3(x6r-x7r),y6-y7'}...z6r---z5r--cycle; % stroke
+penlabels(5,6,7); endchar;
+
+cmchar "Extensible right curly brace---top";
+beginchar(oct"026",8u#,cap_height#+2u#,4u#);
+adjust_fit(0,0); pickup fine.nib;
+numeric min_breadth; min_breadth=hround(rule_thickness+.6dw);
+pos1(min_breadth,0); pos1'(min_breadth,0);
+pos2(heavy_rule_thickness,0); pos3(heavy_rule_thickness,0);
+lft x1l=lft x1'l=hround(1.5u-.5min_breadth);
+x2=x3=hround(.5w);
+top y1=h; y3=-d; y2=.5[y1,y3]; y1-y1'=min_breadth-fine;
+filldraw z1r{3(x2r-x1r),y2-y1}...z2r---z3r
+ --z3l---z2l...{3(x1l-x2l),y1'-y2}z1'l--z1l--cycle; % stroke
+penlabels(1,2,3); endchar;
+
+cmchar "Extensible right curly brace---bottom";
+beginchar(oct"027",8u#,cap_height#+4u#,2u#);
+adjust_fit(0,0); pickup fine.nib;
+numeric min_breadth; min_breadth=hround(rule_thickness+.6dw);
+pos7(min_breadth,0); pos7'(min_breadth,0);
+pos5(heavy_rule_thickness,0); pos6(heavy_rule_thickness,0);
+lft x7l=lft x7'l=hround(1.5u-.5min_breadth);
+x5=x6=hround(.5w);
+top y5=h; bot y7=-d; y6=.5[y5,y7]; y7'-y7=min_breadth-fine;
+filldraw z5r---z6r...{3(x7r-x6r),y7-y6}z7r
+ --z7l--z7'l{3(x6l-x7l),y6-y7'}...z6l---z5l--cycle; % stroke
+penlabels(5,6,7); endchar;
+
+bye.
diff --git a/dviware/quicspool/wbfonts/tpunct.mf b/dviware/quicspool/wbfonts/tpunct.mf
new file mode 100644
index 0000000000..bd3d51b9fe
--- /dev/null
+++ b/dviware/quicspool/wbfonts/tpunct.mf
@@ -0,0 +1,241 @@
+% $Header: tpunct.mf,v 1.1 88/01/15 13:13:01 simpson Rel $
+% $Log: tpunct.mf,v $
+%Revision 1.1 88/01/15 13:13:01 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:40 simpson
+%beta test
+%
+% This file contains punctuation marks common to roman and italic styles.
+
+% Codes \0041, \0043, \0045, \0047--\0054,\ %
+%% \0056, \0057, \0072, \0073, \0075, \0100,\par
+% \0133, \0135, and \0140 are generated, as well as code |spanish_shriek|
+% (for a Spanish exclamation point) if that code value is known.
+
+cmchar "Exclamation point";
+beginchar("!",5u#+width_adj#,asc_height#,0);
+italcorr asc_height#*slant-2u#-.5width_adj#+.5dot_size#;
+adjust_fit(0,0);
+pickup tiny.nib; pos3(dot_size,0); pos4(dot_size,90);
+lft x3l=hround(.5w-.5dot_size); bot y4l=0; z3=z4; dot(3,4); % dot
+numeric bot_width;
+bot_width=if hefty:max(hround .8dot_size,fine.breadth) else: hair fi;
+pickup fine.nib; pos1(dot_size,0); pos2(bot_width,0);
+x1=x2=x3; bot y2=.25[top y4r,x_height]+1;
+if square_dots: top y1=h;
+ filldraw stroke z1e--z2e; % stem
+else: top z0=(x1,h+o); y1+.5dot_size=h+o;
+ filldraw z1r...z0...z1l---z2l--z2r---cycle; fi % stem and bulb
+penlabels(0,1,2,3,4); endchar;
+
+iff known spanish_shriek: cmchar "Spanish open exclamation point";
+beginchar(spanish_shriek,5u#+width_adj#,asc_height#-desc_depth#,desc_depth#);
+italcorr h#*slant-2u#-.5width_adj#+.5dot_size#;
+adjust_fit(0,0);
+pickup tiny.nib; pos3(dot_size,0); pos4(dot_size,90);
+lft x3l=hround(.5w-.5dot_size); top y4r=h; z3=z4; dot(3,4); % dot
+numeric top_width;
+top_width=if hefty:max(hround .8dot_size,fine.breadth) else: hair fi;
+pickup fine.nib; pos1(dot_size,0); pos2(top_width,0);
+x1=x2=x3; top y2=.25[bot y4l,h-x_height]-1;
+if square_dots: bot y1=-d;
+ filldraw stroke z1e--z2e; % stem
+else: bot z0=(x1,-d-o); y1-.5dot_size=-d-o;
+ filldraw z1l...z0...z1r---z2r--z2l---cycle; fi % stem and bulb
+penlabels(0,1,2,3,4); endchar;
+
+cmchar "Per cent sign";
+beginchar("%",9u#+max(6u#,2fudge*(hair#+stem#)),
+ body_height#,body_height#-asc_height#);
+italcorr if hefty: .4asc_height#*slant-.5u# else: h#*slant-u# fi;
+adjust_fit(0,0); pickup fine.nib;
+numeric left_curve,right_curve;
+left_curve=hround 5/6[fudged.hair,fudged.stem];
+right_curve=max(fine.breadth,hround(fudged.hair if hefty:-2stem_corr fi));
+pos1(vair,90); pos2(left_curve,180); pos3(vair,270); pos4(right_curve,360);
+top y1r=h; lft x2r=hround u; rt x4r=hround(.5w-1.5u);
+bot y3r=floor(if monospace: .7 else: .5 fi\\ asc_height);
+x1=x3=.5[x2,x4]; y2=y4=.5[y1,y3];
+filldraw stroke pulled_super_arc.e(1,2)(superpull)
+ & pulled_super_arc.e(2,3)(superpull); % left half of upper bowl
+filldraw stroke super_arc.e(3,4) & super_arc.e(4,1); % right half of upper bowl
+pos5(vair,90); pos6(left_curve,180); pos7(vair,270); pos8(right_curve,360);
+bot y7r=-d; rt x8r=hround(w-u); lft x6r=hround(.5w+1.5u);
+top y5r=vround(if monospace: .3 else: .5 fi\\ asc_height);
+x5=x7=.5[x6,x8]; y6=y8=.5[y5,y7];
+filldraw stroke pulled_super_arc.e(5,6)(superpull)
+ & pulled_super_arc.e(6,7)(superpull); % left half of lower bowl
+filldraw stroke super_arc.e(7,8) & super_arc.e(8,5); % right half of lower bowl
+pickup rule.nib; top y9=h; bot y10=-d;
+if hefty: x9=good.x(x5-eps); x10=good.x(x1+eps);
+ draw z9--z10; % diagonal
+else: rt x9=hround(w-2.5u); lft x10=hround 2.5u; draw z9--z10; % diagonal
+ pickup fine.nib; pos9(rule_thickness,angle(z9-z10)+90);
+ pos11(vair,angle(z1r-z4r)-90); pos12(vair,angle(z9-z10)+90);
+ path p; p=super_arc.r(1,4); z11r=point 2/3 of p; z12r=z9r;
+ filldraw stroke z11e{direction 2/3 of p}...{z9-z10}z12e; fi % link
+penlabels(1,2,3,4,5,6,7,8,9,10,11,12); endchar;
+
+cmchar "Apostrophe";
+beginchar("'",5u#,asc_height#,0);
+italcorr asc_height#*slant+.5dot_size#-2u#;
+adjust_fit(0,0);
+x1-.5dot_size=hround(.5w-.5dot_size); y1+.5dot_size=h;
+if monospace: comma(1,a,dot_size,.28u,vround 1.5comma_depth); % large comma
+else: comma(1,a,dot_size,.25u,comma_depth); fi % comma with increased jut
+penlabels(1); endchar;
+
+cmchar "Left parenthesis";
+beginchar("(",7u# if monospace: -u# fi,body_height#,paren_depth#);
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(vair,0); pos2(.75[hair,stem],0); pos3(vair,0);
+rt x1r=rt x3r=hround(w-u); lft x2l=hround(x1-4u if monospace: +4/3u fi);
+top y1=h; y2=.5[y1,y3]=math_axis;
+filldraw stroke z1e{3(x2e-x1e),y2-y1}...z2e
+ ...{3(x3e-x2e),y3-y2}z3e; % arc
+penlabels(1,2,3); endchar;
+
+cmchar "Right parenthesis";
+beginchar(")",7u# if monospace: -u# fi,body_height#,paren_depth#);
+italcorr math_axis#*slant-.5u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(vair,0); pos2(.75[hair,stem],0); pos3(vair,0);
+lft x1l=lft x3l=hround u; rt x2r=hround(x1+4u if monospace: -4/3u fi);
+top y1=h; y2=.5[y1,y3]=math_axis;
+filldraw stroke z1e{3(x2e-x1e),y2-y1}...z2e
+ ...{3(x3e-x2e),y3-y2}z3e; % arc
+penlabels(1,2,3); endchar;
+
+cmchar "Asterisk";
+beginchar("*",9u#,
+ if low_asterisk:math_axis#+.5x_height# else: body_height# fi,0);
+italcorr h#*slant-.75u#;
+adjust_fit(0,0);
+numeric ast_flare; ast_flare=hround .7[thin_join,stem];
+x0=.5w; y0=h-.5x_height;
+for d=-150 step 60 until 150: z[d]=z0+.5dir d xscaled 7.5u yscaled x_height;
+ numeric theta; theta=angle(z[d]-z0);
+ fill z0+.5(0,-thin_join)rotated theta
+ ---z[d]+.5(-ast_flare,-ast_flare)rotated theta
+ ..z[d]..z[d]+.5(-ast_flare,ast_flare)rotated theta
+ ---z0+.5(0,thin_join)rotated theta--cycle; endfor % diagonal at angle |d|
+labels(0,[-150],[-90],[-30],30,90,150); endchar;
+
+cmchar "Plus sign";
+beginarithchar("+"); pickup rule.nib;
+x1=x2=good.x .5w; top y1=h+eps; .5[y1,y2]=math_axis;
+lft x3=hround u-eps; x4=w-x3; y3=y4=math_axis;
+draw z1--z2; % stem
+draw z3--z4; % crossbar
+labels(1,2,3,4); endchar;
+
+cmchar "Comma";
+numeric dot_diam#; dot_diam#=if monospace: 5/4 fi\\ dot_size#;
+define_whole_blacker_pixels(dot_diam);
+beginchar(",",5u#,dot_diam#,comma_depth#);
+adjust_fit(0,0);
+x1-.5dot_diam=hround(.5w-.5dot_diam); y1-.5dot_diam=0;
+comma(1,a,dot_diam,.2u,comma_depth); % dot and tail
+penlabels(1); endchar;
+
+cmchar "Period";
+numeric dot_diam#; dot_diam#=if monospace: 5/4 fi\\ dot_size#;
+define_whole_blacker_pixels(dot_diam);
+beginchar(".",5u#,dot_diam#,0);
+adjust_fit(0,0); pickup fine.nib;
+pos1(dot_diam,0); pos2(dot_diam,90);
+lft x1l=hround(.5w-.5dot_diam); bot y2l=0; z1=z2; dot(1,2); % dot
+penlabels(1,2); endchar;
+
+cmchar "Virgule (slash)";
+beginchar("/",9u#,body_height#,paren_depth#);
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x1=hround(w-u)+eps; top y1=h+eps;
+lft x2=hround u-eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+penlabels(1,2); endchar;
+
+cmchar "Colon";
+numeric dot_diam#; dot_diam#=if monospace: 5/4 fi\\ dot_size#;
+define_whole_blacker_pixels(dot_diam);
+beginchar(":",5u#,x_height#,0);
+italcorr x_height#*slant+.5dot_diam#-2u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(dot_diam,0); pos2(dot_diam,90);
+lft x1l=hround(.5w-.5dot_diam); top y2r=h; z1=z2; dot(1,2); % upper dot
+pos3(dot_diam,0); pos4(dot_diam,90);
+x3=x1; bot y4l=0; z3=z4; dot(3,4); % lower dot
+penlabels(1,2,3,4); endchar;
+
+cmchar "Semicolon";
+numeric dot_diam#; dot_diam#=if monospace: 5/4 fi\\ dot_size#;
+define_whole_blacker_pixels(dot_diam);
+beginchar(";",5u#,x_height#,comma_depth#);
+italcorr x_height#*slant+.5dot_diam#-2u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(dot_diam,0); pos2(dot_diam,90);
+lft x1l=hround(.5w-.5dot_diam); top y2r=h; z1=z2; dot(1,2); % upper dot
+x3-.5dot_diam=hround(.5w-.5dot_diam); y3-.5dot_diam=0;
+comma(3,a,dot_diam,.05u,comma_depth); % lower dot and tail
+penlabels(1,2,3); endchar;
+
+cmchar "Equals sign";
+compute_spread(.45x_height#,.55x_height#);
+beginchar("=",14u#,v_center(spread#+rule_thickness#));
+italcorr h#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x1=hround u-eps; x3=x1; x2=x4=w-x1;
+y1=y2; y3=y4; y1-y3=spread; .5[y1,y3]=math_axis;
+draw z1--z2; % upper bar
+draw z3--z4; % lower bar
+labels(1,2,3,4); endchar;
+
+cmchar "Left bracket";
+numeric wd#; wd#=max(5u#,4.5u#+.5if hefty:stem# else:rule_thickness# fi);
+beginchar("[",wd#,body_height#,paren_depth#);
+italcorr body_height#*slant;
+adjust_fit(0,0);
+numeric top_thickness,side_thickness;
+if hefty: top_thickness=vair;
+ side_thickness=max(crisp.breadth,stem-2stem_corr);
+else: top_thickness=side_thickness=rule_thickness; fi;
+pickup crisp.nib; pos1(side_thickness,0); pos2(side_thickness,0);
+top y1=h; bot y2=-d; lft x1l=lft x2l=hround(2.5u-.5side_thickness)-1-eps;
+filldraw stroke z1e--z2e; % stem
+pos3(top_thickness,90); pos4(top_thickness,90);
+pos5(top_thickness,90); pos6(top_thickness,90);
+x3=x5=x1l; rt x4=rt x6=ceiling(w-.4u)+eps; y3r=y4r=y1; y5l=y6l=y2;
+filldraw stroke z3e--z4e; % upper bar
+filldraw stroke z5e--z6e; % lower bar
+penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Right bracket";
+numeric wd#; wd#=max(5u#,4.5u#+.5if hefty:stem# else:rule_thickness# fi);
+beginchar("]",wd#,body_height#,paren_depth#);
+italcorr body_height#*slant-2u#+.5if hefty:stem# else:rule_thickness# fi;
+adjust_fit(0,0);
+numeric top_thickness,side_thickness;
+if hefty: top_thickness=vair;
+ side_thickness=max(crisp.breadth,stem-2stem_corr);
+else: top_thickness=side_thickness=rule_thickness; fi;
+pickup crisp.nib; pos1(side_thickness,0); pos2(side_thickness,0);
+top y1=h; bot y2=-d; rt x1r=rt x2r=hround(w-2.5u+.5side_thickness)+1+eps;
+filldraw stroke z1e--z2e; % stem
+pos3(top_thickness,90); pos4(top_thickness,90);
+pos5(top_thickness,90); pos6(top_thickness,90);
+x3=x5=x1r; lft x4=lft x6=floor .4u-eps; y3r=y4r=y1; y5l=y6l=y2;
+filldraw stroke z3e--z4e; % upper bar
+filldraw stroke z5e--z6e; % lower bar
+penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Reverse apostrophe";
+beginchar("`",5u#,asc_height#,0);
+italcorr asc_height#*slant+.5dot_size#-2u#;
+adjust_fit(0,0);
+x1-.5dot_size=hround(.5w-.5dot_size); y1+.5dot_size=h-comma_depth;
+if monospace: ammoc(1,a,dot_size,.28u,vround 1.5comma_depth); % large ammoc
+else: ammoc(1,a,dot_size,.25u,comma_depth); fi % normal ammoc
+penlabels(1); endchar;
diff --git a/dviware/quicspool/wbfonts/troman.mf b/dviware/quicspool/wbfonts/troman.mf
new file mode 100644
index 0000000000..1bb910e62d
--- /dev/null
+++ b/dviware/quicspool/wbfonts/troman.mf
@@ -0,0 +1,341 @@
+% $Header: troman.mf,v 1.1 88/01/15 13:13:05 simpson Rel $
+% $Log: troman.mf,v $
+% Revision 1.1 88/01/15 13:13:05 simpson
+% initial release
+%
+% Revision 0.1 88/01/07 08:18:52 simpson
+% beta test
+%
+% The Computer Modern Roman family of fonts (by D. E. Knuth, 1979--1985)
+
+if ligs>1: font_coding_scheme:="Troff text";
+else: font_coding_scheme:=if ligs=0: "TeX typewriter text"
+ else: "TeX text without f-ligatures" fi;
+ spanish_shriek=oct"016"; spanish_query=oct"017"; fi
+minus=oct"004"; vertical=oct"174";
+
+mode_setup; font_setup;
+
+% We need to create space characters with no bitmap for \| and \^. I put
+% them in oct"000" and oct"177" since these characters are not normally
+% used by ditroff.
+% My own creation (...creation being a generous term), for \|, 1/6 em
+beginchar(oct"000", 16/6u#, 0, 0);
+endchar;
+
+% My own creation, for \^, 1/12 em
+beginchar(oct"177", 16/12u#, 0, 0);
+endchar;
+
+% From the font lasy10.mf, file lasy.mf
+cmchar "Box";
+beginchar(oct"024",2.1math_axis#+4u#,v_center(7u#));
+italcorr math_axis#*slant;
+adjust_fit(0,0); pickup rule.nib;
+numeric a; a=round(2.1math_axis);
+x1=x4=good.x 2u; x2=x3=x1+a;
+y3=y4=.5(cap_height-a); y1=y2=y3+a;
+draw z1--z2--z3--z4--cycle;
+labels(1,2,3,4); endchar;
+
+% Stolen from font cmsy10, file symbol.mf
+cmchar "Open bullet";
+beginchar(oct"025",9u#,v_center(7u#));
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x6=hround u; x2=w-x6; top y8=h; y2=math_axis;
+circle_points; draw_circle; % circle
+labels(1,2,3,4,5,6,7,8); endchar;
+
+% Stolen from the font cmr10, file accent.mf
+cmchar "Umlaut (double dot) accent";
+numeric dot_diam#,dot_diam;
+dot_diam#=max(dot_size#,cap_curve#);
+beginchar(oct"026",9u#,min(asc_height#,10/7x_height#+.5dot_diam#),0);
+dot_diam=max(tiny.breadth,hround(max(dot_size,cap_curve)-2stem_corr));
+italcorr h#*slant+.5dot_diam#-2.25u#;
+adjust_fit(0,0);
+pickup tiny.nib; pos1(dot_diam,0); pos2(dot_diam,90);
+x1=x2=2.75u; top y2r=h+1;
+if bot y2l<x_height+o+slab: y2l:=min(y2r-eps,x_height+o+slab+.5tiny); fi
+y1=.5[y2l,y2r]; dot(1,2); % left dot
+pos3(dot_diam,0); penpos4(y2r-y2l,90); y3=y4=y1; x3=x4=w-x1;
+dot(3,4); % right dot
+penlabels(1,2,3,4); endchar;
+
+% Stolen from the font cmr10.mf, file accent.mf
+cmchar "Cedilla accent";
+beginchar(oct"027",8u#,0,.875desc_depth#);
+adjust_fit(0,0);
+x1=.5w+.5u;
+if serifs: pickup crisp.nib; pos1(stem,0); pos2(stem,0);
+ pos3(vair,90); pos4(stem,0); pos5(vair,-90);
+ x1=x2; z3l=z2l; x4=x2+1.5u; x5=x3-1.5u;
+ bot y1=-o; bot y2=-vround 2/7d-o; y4=.5[y3,y5]; bot y5=-d-o;
+ filldraw stroke z1e--z2e; % stem
+ filldraw stroke z3e{right}...z4e{down}...{left}z5e; % hook
+else: pickup fine.nib; pos1(vair,0); top y1=-o-2;
+ pos2(.5[vair,stem],0); bot y2=-d-o; x2=x1-1.25u;
+ filldraw stroke z1e--z2e; fi % diagonal
+penlabels(1,2,3,4,5); endchar;
+
+% My own creation, a zero width period. Used for dots in pic(1).
+cmchar "Dot for pic boxes";
+numeric dot_diam#; dot_diam#=if monospace: 5/4 fi\\ dot_size#;
+define_whole_blacker_pixels(dot_diam);
+beginchar(oct"030",0,dot_diam#,0);
+period_width#:=5u#; define_pixels(period_width);
+pickup fine.nib;
+pos1(dot_diam,0); pos2(dot_diam,90);
+lft x1l=hround(.5period_width-.5dot_diam); bot y2l=0; z1=z2; dot(1,2); % dot
+penlabels(1,2); endchar;
+
+% My own creation. The fractions look like hell.
+cmchar "1/4 symbol";
+beginchar(oct"021", 12u#, body_height#, paren_depth#);
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x1=hround(w-u)+eps; top y1=h+eps;
+lft x2=hround u-eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+x3=x4=1/4w; y3=38/40h; y4=23/40h;
+draw z3--z4; % number 1
+x5=x6=32/40w; y7=y8=1/8h; y5=-.2d; y6=.37h; x7=26/40w; x8=.85w;
+draw z5--z6--z7--z8;
+endchar;
+
+% My own creation
+cmchar "1/2 symbol";
+beginchar(oct"022", 12u#, body_height#, paren_depth#);
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x1=hround(w-u)+eps; top y1=h+eps;
+lft x2=hround u-eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+x3=x4=1/4w; y3=38/40h; y4=23/40h;
+draw z3--z4; % number 1
+x5=x9=.65w; x10=x7=.85w; x6=.74w;
+y9=y10=-.2d; y6=.37h; y5=.32h; y7=.30h;
+draw z5{dir 45}..z6..z7{dir -90}..{dir 225}z9; % number 2
+draw z9--z10;
+endchar;
+
+% My own creation.
+cmchar "3/4 symbol";
+beginchar(oct"023", 12u#, body_height#, paren_depth#);
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x1=hround(w-u)+eps; top y1=h+eps;
+lft x2=hround u-eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+draw (quartercircle rotated -90 & halfcircle) scaled .1875h shifted
+(.25w,.8562h); % number 3
+draw (halfcircle rotated -180 & quartercircle) scaled .1875h shifted
+(.25w,.6687h);
+x5=x6=32/40w; y7=y8=1/8h; y5=-.2d; y6=.37h; x7=26/40w; x8=.85w;
+draw z5--z6--z7--z8;
+endchar;
+
+% From the font cmsy10, file sym.mf
+iff known vertical: cmchar "Vertical line";
+beginchar(vertical,5u#,body_height#,paren_depth#);
+italcorr body_height#*slant+.5rule_thickness#-2u#;
+adjust_fit(0,0); pickup rule.nib;
+x1=x2=good.x .5w; top y1=h+eps; bot y2=-d-eps;
+draw z1--z2; % stem
+labels(1,2); endchar;
+
+% My own creation
+cmchar "Rule";
+beginchar(oct"005",12u#,x_height#,.7u#);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric below_baseline; below_baseline#:=.2u#;
+define_pixels(below_baseline);
+define_blacker_pixels(thickness);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(-below_baseline); rt x2=hround(w+6u#);
+lft x1=hround(0);
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+% My own creation
+cmchar "Underscore";
+beginchar("_",12u#,x_height#,.7u#);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric below_baseline; below_baseline#:=.2u#;
+define_pixels(below_baseline);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(-below_baseline); x2=hround(w);
+x1=hround 0;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+% Hyphen from cmr10, file comlig.mf
+cmchar "Hyphen";
+beginchar("-",6u#,x_height#,0);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric thickness; thickness=if hefty:bar else:.75[hair,stem] fi;
+pickup crisp.nib; pos1(thickness,90); pos2(thickness,90);
+top y1r=top y2r=vround(.5h+.5thickness); rt x2=hround(w-u)+eps;
+if monospace: x2=w-x1 else: lft x1=hround .2u-eps fi;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+% My own creation
+cmchar "Cent sign";
+beginchar(oct"020",18u#,asc_height#,desc_depth#); autorounded;
+adjust_fit(if monospace:-3u#,-3u# else: 0,0 fi); pickup rule.nib;
+lft x6=hround u; x2=w-x6; top y8=h+o; bot y4=-d-o;
+circle_points;
+x9=x11=.65[x6,x4]; x10=x12=.35[x4,x2];
+y9=y10=.35[y6,y8]; y11=y12=.65[y4,y6];
+x13=x14=.5[x6,x2]-.3u; y13=y4+2u; y14=y8-2u;
+draw z10..z9..z11..z12; draw z13--z14;
+labels(1,2,3,4,5,6,7,8,9,10,11,12,13,14); endchar;
+
+% My own creation
+cmchar "Copyright";
+beginchar(oct"016",18u#,asc_height#,desc_depth#); autorounded;
+adjust_fit(if monospace:-3u#,-3u# else: 0,0 fi); pickup rule.nib;
+lft x6=hround u; x2=w-x6; top y8=h+o; bot y4=-d-o;
+circle_points; draw_circle; % circle
+x9=x11=.65[x6,x4]; x10=x12=.35[x4,x2];
+y9=y10=.35[y6,y8]; y11=y12=.65[y4,y6];
+draw z10..z9..z11..z12;
+labels(1,2,3,4,5,6,7,8,9,10,11,12); endchar;
+
+% My own creation
+cmchar "Registered";
+beginchar(oct"017",18u#,asc_height#,desc_depth#); autorounded;
+adjust_fit(if monospace:-3u#,-3u# else: 0,0 fi); pickup rule.nib;
+lft x6=hround u; x2=w-x6; top y8=h+o; bot y4=-d-o;
+circle_points; draw_circle; % circle
+x9=x11=x12=.7[x6,x8]; x10=x13=.3[x4,x2];
+y12=y13=.5[y4,y6]; y9=.5[y6,y8]; y11=.5[y12,y9]; y10=.5[y11,y9];
+x14=.08[x4,x2]; y14=y9;
+path p;
+p=z9--z14{dir 0}..z10..{dir 180}z11;
+z15=point 2.6 of p;
+draw z12--z9; draw z13--z15; draw p;
+labels(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15); endchar;
+
+% Stolen from the font cmr10, file accent.mf (actually the acute accent)
+cmchar "Footmark";
+beginchar(oct"015",9u#,min(asc_height#,2x_height#),0);
+italcorr h#*slant-if serifs: 1.5 fi u#;
+adjust_fit(0,0);
+if serifs: pickup crisp.nib; x1+.5stem=hround(w-2u); x2=2/3[x1,w-x1];
+ y1+.5stem=h+eps; y2=max(2/3[h,x_height],x_height+o+hair);
+ numeric theta; theta=angle(z2-z1)+90;
+ pos1(stem,theta); pos2(hair,theta);
+ filldraw circ_stroke z1e--z2e; % diagonal
+else: pickup fine.nib; pos1(stem,0); pos2(vair,0);
+ rt x1r=hround(w-1.5u); lft x2l=hround(.5w-.25u-.5vair);
+ top y1=h; bot y2=vround 2/3[h,x_height];
+ filldraw stroke z1e--z2e; fi % diagonal
+penlabels(1,2); endchar;
+
+% Stolen from the font cmsy10, file symbol.mf
+cmchar "Dagger mark";
+beginchar(oct"014",8u#,asc_height#,desc_depth#);
+adjust_fit(0,0); pickup fine.nib;
+pos1(stem,0); pos2(thin_join,0); pos3(stem,0); pos4(hair,0);
+pos5(stem,90); pos2'(thin_join,90); pos6(stem,90); z2'=z2;
+x1=x2=x3=x4; x1-.5stem=hround(.5w-.5stem); w:=r:=2x1;
+x5-.5stem=hround u; x6=w-x5;
+y1+.5stem=h+oo; y2=y5=y6; y3=.57y2; bot y4=-d-o;
+y5+.5stem=floor(x_height+.5stem);
+filldraw circ_stroke z1e{down}..z2e{down}..z3e{down}..z4e; % stem
+filldraw circ_stroke z5e{right}..{right}z2'e; % left bulb
+filldraw circ_stroke z6e{left}..{left}z2'e; % right bulb
+penlabels(1,2,3,4,5,6); endchar;
+
+% Stolen from the font cmr10, file accent.mf (the Scandinavian circle accent)
+cmchar "Degree";
+beginchar(oct"013",13u#+4/3(asc_height#-x_height#)*slant,asc_height#,0);
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+numeric circ_hair,circ_vair;
+circ_hair=hround min(hair,u+.5); circ_vair=vround min(vair,(h-x_height)/6+.5);
+penpos1(circ_vair,90); penpos3(circ_vair,-90);
+penpos2(circ_hair,180); penpos4(circ_hair,0);
+x2r=hround(.5w-1.5u-.5circ_hair);
+x4r=w-x2r; x1=x3=.5w; y1r=h+apex_o; y2=y4=.5[y1,y3];
+y3r=vround(1/3[x_height,h]+apex_o);
+penstroke pulled_arc.e(1,2) & pulled_arc.e(2,3)
+ & pulled_arc.e(3,4) & pulled_arc.e(4,1) & cycle; % bowl
+penlabels(1,2,3,4); endchar;
+
+% My own creation
+cmchar "Square";
+beginchar(oct"010",9u#,v_center(7u#));
+italcorr math_axis#*slant;
+adjust_fit(0,0); pickup rule.nib;
+draw unitsquare scaled 7u shifted (.5w-7u/2,math_axis-7u/2);
+endchar;
+
+% Stolen from the font cmsy10, file symbol.mf
+cmchar "Bullet";
+beginchar(oct"007",9u#,v_center(7u#));
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x6=hround u; x2=w-x6; top y8=h; y2=math_axis; circle_points;
+filldraw z8{right}...z1{z2-z8}...z2{down}...z3{z4-z2}...z4{left}
+ ...z5{z6-z4}...z6{up}...z7{z8-z6}...cycle; % circle and interior
+labels(1,2,3,4,5,6,7,8); endchar;
+
+% Stolen from the font cmsy10, file sym.mf
+iff known minus: cmchar "Minus sign";
+beginarithchar(minus); pickup rule.nib;
+lft x1=hround 1.5u-eps; x2=w-x1; y1=y2=math_axis;
+draw z1--z2; % bar
+labels(1,2); endchar;
+
+input romanu; % upper case (majuscules)
+input romanl; % lower case (minuscules)
+input romand; % numerals
+input romanp; % ampersand, question marks, currency sign
+input tpunct; % punctuation symbols common to roman and italic text
+if ligs>1: input tromlig; fi % letter ligatures
+if ligs>0: input tcomlig; fi % ligatures common with italic text
+if ligs<=1: input romsub; fi % substitutes for ligatures
+
+font_slant slant; font_x_height x_height#;
+if monospace: font_normal_space 9u#; % no stretching or shrinking
+ font_quad 18u#;
+ font_extra_space 9u#;
+else: font_normal_space 6u#+2letter_fit#;
+ font_normal_stretch 3u#; font_normal_shrink 2u#;
+ font_quad 18u#+4letter_fit#;
+ font_extra_space 2u#;
+ k#:=-.5u#; kk#:=-1.5u#; kkk#:=-2u#; % three degrees of kerning
+ ligtable "k": if serifs: "v": "a" kern -u#, fi\\"w": "e" kern k#,
+ "a" kern k#, "o" kern k#, "c" kern k#;
+ ligtable "P": "A" kern kk#,
+ "y": "o" kern k#, "e" kern k#, "a" kern k#, "." kern kk#, "," kern kk#;
+ ligtable "F": "V": "W": if serifs: "o" kern kk#, "e" kern kk#, "u" kern kk#,
+ "r" kern kk#, "a" kern kk#, "A" kern kkk#,
+ else: "o" kern k#, "e" kern k#, "u" kern k#,
+ "r" kern k#, "a" kern k#, "A" kern kk#, fi
+ "K": "X": "O" kern k#, "C" kern k#, "G" kern k#, "Q" kern k#;
+ ligtable "T": "y" kern if serifs: k# else: kk# fi,
+ "Y": "e" kern kk#, "o" kern kk#,
+ "r" kern kk#, "a" kern kk#, "A" kern kk#, "u" kern kk#;
+ ligtable "O": "D": "X" kern k#, "W" kern k#, "A" kern k#,
+ "V" kern k#, "Y" kern k#;
+ if serifs: ligtable "h": "m": "n":
+ "t" kern k#, "u" kern k#, "b" kern k#, "y" kern k#, "v" kern k#, "w" kern k#;
+ ligtable "c": "h" kern k#, "k" kern k#; fi
+ ligtable "o": "b": "p": "e" kern -k#, "o" kern -k#, "x" kern k#,
+ "d" kern -k#, "c" kern -k#, "q" kern -k#,
+ "a": if serifs: "v" kern k#, "j" kern u#, else: "r" kern k#, fi
+ "t": "y" kern k#,
+ "u": "w" kern k#;
+ ligtable "A": if serifs: "R": fi\\ "t" kern k#,
+ "C" kern k#, "O" kern k#, "G" kern k#, "U" kern k#, "Q" kern k#,
+ "L": "T" kern kk#, "Y" kern kk#, "V" kern kkk#, "W" kern kkk#;
+ ligtable "g": "j" kern -k#; % logjam
+ ligtable "I": "I" kern -k#; fi % Richard III
+ % there are ligature/kern programs for |"f"| in the {\tt romlig} file
+ % and for |"-"|, |"`"|, and |"'"| in the {\tt comlig} file
+bye.
diff --git a/dviware/quicspool/wbfonts/tromlig.mf b/dviware/quicspool/wbfonts/tromlig.mf
new file mode 100644
index 0000000000..8b28b2734c
--- /dev/null
+++ b/dviware/quicspool/wbfonts/tromlig.mf
@@ -0,0 +1,171 @@
+% $Header: tromlig.mf,v 1.1 88/01/15 13:13:09 simpson Rel $
+% $Log: tromlig.mf,v $
+%Revision 1.1 88/01/15 13:13:09 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:43 simpson
+%beta test
+%
+% This file describes five roman ligatures that begin with `f'
+% and puts them in code positions \001-\003, \011-\012
+
+numeric itc#; % modified italic correction on `f' and `ff'
+itc#=if serifs: max(0,flare#-.25u#) else: 1.25u# fi;
+
+ligtable "f": "i"=:oct"001", "f"=:oct"003", "l"=:oct"002",
+ "?" kern itc#, "!" kern itc#, ")" kern itc#, "]" kern itc#;
+ligtable oct"003": "i"=:oct"011", "l"=:oct"012",
+ "?" kern itc#, "!" kern itc#, ")" kern itc#, "]" kern itc#;
+
+cmchar "The ligature ff";
+beginchar(oct"003",10.5u#+2letter_fit#,asc_height#,0);
+italcorr asc_height#*slant+if serifs:flare#-.25u# else: 1.25u# fi;
+adjust_fit(0,0);
+pickup tiny.nib; pos1(stem',0); lft x1l=hround(2.5u-.5stem');
+pos11(stem',0); rt x11r=hround(w-3u+.5stem');
+pickup fine.nib; numeric bulb_diam, inner_jut;
+if serifs: bulb_diam=hround .8[stem,flare];
+ pos2(bulb_diam,0); pos12(bulb_diam,0);
+ rt x2r=hround(rt x11r-stem_corr); lft x12l=hround(w-.75u+.5);
+ y2+.5bulb_diam=.85[x_height,h+oo]; y12+.5bulb_diam=.9[x_height,h+oo];
+ if rt x1r+jut+.5u+2<=lft x11l-jut: inner_jut=jut;
+ else: rt x1r+inner_jut+.5u+2=lft x11l-inner_jut; fi
+else: pos2(5/7[vair,flare],90); top y2r=h; rt x2=hround 6.25u;
+ pos12(5/7[vair,flare],90); y12=y2; rt x12=hround(w+.75u); fi
+f_stroke(1,2,a,b,c,jut,inner_jut); % left stem, arc, terminal, serif
+f_stroke(11,12,d,e,f,inner_jut,1.25jut); % right stem, arc, terminal, serif
+pickup crisp.nib; top y3r=top y4r=x_height; lft x3=hround .5u-1;
+pos3(bar,90); pos4(bar,90);
+rt x4=hround(w-1/3u);
+if hefty: pos3'(bar,90); x3'-x1=x4-x11; y3'=y3;
+ pos4'(bar,90); x4'=x11; y4'=y4;
+ filldraw stroke z3e--z3'e; filldraw stroke z4'e--z4e; % bars
+else: filldraw stroke z3e--z4e; fi % bar
+penlabels(1,2,3,4,11,12); endchar;
+
+cmchar "The ligature fi";
+beginchar(oct"001",10u#+2letter_fit#,asc_height#,0);
+italcorr asc_height#*slant-serif_fit#+.5if serifs:stem# else:dot_size# fi-2u#;
+adjust_fit(0,serif_fit#);
+pickup tiny.nib; pos1(stem',0); lft x1l=hround(2.5u-.5stem');
+pos11(stem',0); rt x11r=hround(w-2.5u+.5stem');
+pos12(stem',0); x11=x12; bot y12=0;
+pickup fine.nib; numeric bulb_diam, inner_jut;
+if serifs: bulb_diam=hround 1/4[.8[stem,flare],dot_size];
+ pos2(bulb_diam,0); x2r=x12r;
+ y2+.5bulb_diam=.8[x_height,h+oo]; top y11=x_height+min(oo,serif_drop);
+ if rt x1r+jut+.5u+2<=lft x11l-jut: inner_jut=jut;
+ else: rt x1r+inner_jut+.5u+2=lft x11l-inner_jut; fi
+else: bulb_diam=max(stem,dot_size);
+ pos2(6/7[vair,flare],90); top y2r=h; rt x2=hround 5.3u;
+ pickup tiny.nib; pos13(bulb_diam,0); pos14(bulb_diam,90);
+ x13=x11-.5; top y14r=min(2x_height,h+1); top y11=x_height;
+ if bot y14l-x_height<tiny: y14l:=min(y14r-eps,y11+2tiny); fi
+ x13=x14; y13=.5[y14l,y14r]; dot(13,14); % dot
+fi; % this is the ligature we're drawing
+f_stroke(1,2,a,b,c,jut,inner_jut); % left stem, arc, terminal, serif
+pickup tiny.nib; filldraw stroke z11e--z12e; % right stem
+pickup crisp.nib; top y3r=top y4r=x_height; lft x3=hround .5u-1;
+pos3(bar,90); pos4(bar,90);
+if serifs: x4=x11; % bar will overlap upper right serif
+ sloped_serif.l(11,12,d,1/3,jut,min(oo,serif_drop)); % upper right serif
+ dish_serif(12,11,e,1/3,inner_jut,f,1/3,jut); % lower right serif
+else: rt x4= hround 5.3u; fi
+pickup crisp.nib; filldraw stroke z3e--z4e; % bar
+penlabels(1,2,3,4,11,12,13,14); endchar;
+
+cmchar "The ligature fl";
+beginchar(oct"002",10u#+2letter_fit#,asc_height#,0);
+italcorr asc_height#*slant-serif_fit#+.5stem#-2u#;
+adjust_fit(0,serif_fit#);
+pickup tiny.nib; pos1(stem',0); lft x1l=hround(2.5u-.5stem');
+pos11(stem',0); rt x11r=hround(w-2.5u+.5stem');
+pos12(stem',0); x11=x12; bot y12=0; top y11=h;
+filldraw stroke z11e--z12e; % right stem
+pickup fine.nib; numeric bulb_diam, inner_jut;
+if serifs: bulb_diam=hround .8[stem,flare];
+ pos2(bulb_diam,0); x2r=x11r-stem_corr;
+ y2+.5bulb_diam=.9[x_height,h+oo];
+ sloped_serif.l(11,12,d,1/3,eps,max(serif_drop,oo)); % erase excess at top
+ if rt x1r+jut+.5u+2<=lft x11l-jut: inner_jut=jut;
+ else: rt x1r+inner_jut+.5u+2=lft x11l-inner_jut; fi
+else: pos2(5/7[vair,flare],90); top y2r=h; rt x2=hround 5.3u; fi
+f_stroke(1,2,a,b,c,jut,inner_jut); % left stem, arc, terminal, serif
+pickup crisp.nib; top y3r=top y4r=x_height; lft x3=hround .5u-1;
+pos3(bar,90); pos4(bar,90);
+if serifs: x4=x11;
+ dish_serif(12,11,e,1/3,inner_jut,f,1/3,jut); % lower right serif
+else: rt x4= hround 5.3u; fi
+pickup crisp.nib; filldraw stroke z3e--z4e; % bar
+penlabels(1,2,3,4,11,12); endchar;
+
+cmchar "The ligature ffi";
+beginchar(oct"011",15u#+4letter_fit#,asc_height#,0);
+italcorr asc_height#*slant-serif_fit#+.5if serifs:stem# else:dot_size# fi-2u#;
+adjust_fit(0,serif_fit#);
+pickup tiny.nib; pos1(stem',0); lft x1l=hround(2.5u-.5stem');
+pos11(stem',0); lft x11l=hround(.5w-.5stem');
+pos21(stem',0); rt x21r=hround(w-2.5u+.5stem');
+pos22(stem',0); x21=x22; bot y22=0;
+pickup fine.nib; numeric bulb_diam, inner_jut;
+if serifs: bulb_diam=hround 1/4[.8[stem,flare],dot_size];
+ pos2(bulb_diam,0); x2r=x11r-stem_corr;
+ pos12(bulb_diam,0); x12r=x21r;
+ top y21=x_height+min(oo,serif_drop);
+ y2+.5bulb_diam=.8[x_height,h+oo]; y12=y2;
+ if rt x1r+jut+.5u+2<=lft x11l-jut: inner_jut=jut;
+ else: rt x1r+inner_jut+.5u+2=lft x11l-inner_jut; fi
+else: bulb_diam=max(stem,dot_size);
+ pos2(5/7[vair,flare],90); top y2r=h; rt x2=hround 5.75u;
+ pos12(6/7[vair,flare],90); y12=y2; rt x12=hround(.5w+2.8u);
+ pickup tiny.nib; pos23(bulb_diam,0); pos24(bulb_diam,90);
+ x23=x21-.5; top y24r=min(2x_height,h+1); top y21=x_height;
+ if bot y24l-x_height<tiny: y24l:=min(y24r-eps,y21+2tiny); fi
+ x23=x24; y23=.5[y24l,y24r]; dot(23,24); fi % dot
+f_stroke(1,2,a,b,c,jut,inner_jut); % left stem, arc, terminal, serif
+f_stroke(11,12,d,e,f,inner_jut,inner_jut); % middle ditto
+pickup tiny.nib; filldraw stroke z21e--z22e; % right stem
+pickup crisp.nib; top y3r=top y4r=x_height; lft x3=hround.5u-1;
+pos3(bar,90); pos4(bar,90);
+if serifs: x4=x21; % bar will overlap upper right serif
+ sloped_serif.l(21,22,g,1/3,jut,min(oo,serif_drop)); % upper right serif
+ dish_serif(22,21,h,1/3,inner_jut,i,1/3,jut); % lower right serif
+else: rt x4=hround(.5w+2.8u); fi
+pickup crisp.nib;
+if hefty: pos3'(bar,90); x3'-x1=x4-x11; y3'=y3;
+ pos4'(bar,90); x4'=x11; y4'=y4;
+ filldraw stroke z3e--z3'e; filldraw stroke z4'e--z4e; % bars
+else: filldraw stroke z3e--z4e; fi % bar
+penlabels(1,2,3,4,11,12,21,22,23,24); endchar;
+
+cmchar "The ligature ffl";
+beginchar(oct"012",15u#+4letter_fit#,asc_height#,0);
+italcorr asc_height#*slant-serif_fit#+.5stem#-2u#;
+adjust_fit(0,serif_fit#);
+pickup tiny.nib; pos1(stem',0); lft x1l=hround(2.5u-.5stem');
+pos11(stem',0); lft x11l=hround(.5w-.5stem');
+pos21(stem',0); rt x21r=hround(w-2.5u+.5stem');
+pos22(stem',0); x21=x22; bot y22=0; top y21=h;
+filldraw stroke z21e--z22e; % right stem
+pickup fine.nib; numeric bulb_diam, inner_jut;
+if serifs: bulb_diam=hround .8[stem,flare];
+ pos2(bulb_diam,0); x2r=x11r-stem_corr;
+ pos12(bulb_diam,0); x12r=x21r-stem_corr;
+ y2+.5bulb_diam=.85[x_height,h+oo]; y12+.5bulb_diam=.9[x_height,h+oo];
+ sloped_serif.l(21,22,g,1/3,eps,max(serif_drop,oo)); % erase excess at top
+ if rt x1r+jut+.5u+2<=lft x11l-jut: inner_jut=jut;
+ else: rt x1r+inner_jut+.5u+2=lft x11l-inner_jut; fi
+else: pos2(5/7[vair,flare],90); top y2r=h; rt x2=hround 5.75u;
+ pos12(5/7[vair,flare],90); y12=y2; rt x12=hround(.5w+2.8u); fi
+f_stroke(1,2,a,b,c,jut,inner_jut); % left stem, arc, terminal, serif
+f_stroke(11,12,d,e,f,inner_jut,inner_jut); % middle ditto
+pickup crisp.nib; top y3r=top y4r=x_height; lft x3=hround.5u-1;
+pos3(bar,90); pos4(bar,90);
+if serifs: dish_serif(22,21,h,1/3,inner_jut,i,1/3,jut); % lower right serif
+ pickup crisp.nib; x4=x21;
+else: rt x4=hround(.5w+2.8u); fi
+if hefty: pos3'(bar,90); x3'-x1=x4-x11; y3'=y3;
+ pos4'(bar,90); x4'=x11; y4'=y4;
+ filldraw stroke z3e--z3'e; filldraw stroke z4'e--z4e; % bars
+else: filldraw stroke z3e--z4e; fi % bar
+penlabels(1,2,3,4,11,12,21,22); endchar;
diff --git a/dviware/quicspool/wbfonts/tromms.mf b/dviware/quicspool/wbfonts/tromms.mf
new file mode 100644
index 0000000000..d42534fe28
--- /dev/null
+++ b/dviware/quicspool/wbfonts/tromms.mf
@@ -0,0 +1,42 @@
+% $Header: tromms.mf,v 1.1 88/01/15 13:13:12 simpson Rel $
+% $Log: tromms.mf,v $
+%Revision 1.1 88/01/15 13:13:12 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:45 simpson
+%beta test
+%
+% This file contains special characters of ``math italic'' fonts
+% that actually are not supposed to be slanted.
+
+% The italic corrections are zero in all of these characters.
+
+cmchar "Less than sign";
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar("<",14u#,v_center(spread#+rule_thickness#));
+italcorr h#*slant-u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x2=hround 1.5u-eps; x1=x3=w-x2;
+y1-y3=spread; y2=.5[y1,y3]=math_axis;
+draw z1--z2--z3; % diagonals
+labels(1,2,3); endchar;
+
+cmchar "Virgule (slash)";
+beginchar(oct"016",9u#,body_height#,paren_depth#); % non-ASCII position
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x1=hround(w-u)+eps; top y1=h+eps;
+lft x2=hround u-eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+penlabels(1,2); endchar;
+
+cmchar "Greater than sign";
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(">",14u#,v_center(spread#+rule_thickness#));
+italcorr math_axis#*slant-u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x2=hround(w-1.5u)+eps; x1=x3=w-x2;
+y1-y3=spread; y2=.5[y1,y3]=math_axis;
+draw z1--z2--z3; % diagonals
+labels(1,2,3); endchar;
+
diff --git a/dviware/quicspool/wbfonts/ttextit.mf b/dviware/quicspool/wbfonts/ttextit.mf
new file mode 100644
index 0000000000..309e39bda9
--- /dev/null
+++ b/dviware/quicspool/wbfonts/ttextit.mf
@@ -0,0 +1,336 @@
+% $Header: ttextit.mf,v 1.1 88/01/15 13:13:14 simpson Rel $
+% $Log: ttextit.mf,v $
+% Revision 1.1 88/01/15 13:13:14 simpson
+% initial release
+%
+% Revision 0.2 88/01/14 10:14:09 simpson
+% fixed Rule and Underscore
+%
+% Revision 0.1 88/01/07 08:15:20 simpson
+% beta test
+%
+% The Computer Modern Text Italic family (by D. E. Knuth, 1979--1985)
+
+mode_setup; font_setup;
+
+input itall; % lower case (minuscules)
+if ligs>1: font_coding_scheme:="Troff text";
+ input titalig; % letter ligatures
+else: font_coding_scheme:=if ligs=0: "TeX typewriter text"
+ else: "TeX text without f-ligatures" fi;
+ spanish_shriek=oct"016"; spanish_query=oct"017"; fi
+minus=oct"004"; vertical=oct"174";
+
+font_slant slant; font_x_height x_height#;
+if monospace: font_normal_space 9u#; % no stretching or shrinking
+ font_quad 18u#;
+ font_extra_space 9u#;
+ letter_fit#:=letter_fit:=0;
+else: font_normal_space 6u#+2letter_fit#;
+ font_normal_stretch 3u#; font_normal_shrink 2u#;
+ font_quad 18u#+4letter_fit#;
+ font_extra_space 2u#; fi
+
+% We need to create space characters with no bitmap for \| and \^. I put
+% them in oct"000" and oct"177" since these characters are not normally
+% used by ditroff.
+% My own creation (...creation being a generous term), for \|, 1/6 em
+beginchar(oct"000", 16/6u#, 0, 0);
+endchar;
+
+% My own creation, for \^, 1/12 em
+beginchar(oct"177", 16/12u#, 0, 0);
+endchar;
+
+% From the font lasy10.mf, file lasy.mf
+cmchar "Box";
+beginchar(oct"024",2.1math_axis#+4u#,v_center(7u#));
+italcorr math_axis#*slant;
+adjust_fit(0,0); pickup rule.nib;
+numeric a; a=round(2.1math_axis);
+x1=x4=good.x 2u; x2=x3=x1+a;
+y3=y4=.5(cap_height-a); y1=y2=y3+a;
+draw z1--z2--z3--z4--cycle;
+labels(1,2,3,4); endchar;
+
+% Stolen from font cmsy10, file symbol.mf
+cmchar "Open bullet";
+beginchar(oct"025",9u#,v_center(7u#));
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x6=hround u; x2=w-x6; top y8=h; y2=math_axis;
+circle_points; draw_circle; % circle
+labels(1,2,3,4,5,6,7,8); endchar;
+
+% Stolen from the font cmr10, file accent.mf
+cmchar "Umlaut (double dot) accent";
+numeric dot_diam#,dot_diam;
+dot_diam#=max(dot_size#,cap_curve#);
+beginchar(oct"026",9u#,min(asc_height#,10/7x_height#+.5dot_diam#),0);
+dot_diam=max(tiny.breadth,hround(max(dot_size,cap_curve)-2stem_corr));
+italcorr h#*slant+.5dot_diam#-2.25u#;
+adjust_fit(0,0);
+pickup tiny.nib; pos1(dot_diam,0); pos2(dot_diam,90);
+x1=x2=2.75u; top y2r=h+1;
+if bot y2l<x_height+o+slab: y2l:=min(y2r-eps,x_height+o+slab+.5tiny); fi
+y1=.5[y2l,y2r]; dot(1,2); % left dot
+pos3(dot_diam,0); penpos4(y2r-y2l,90); y3=y4=y1; x3=x4=w-x1;
+dot(3,4); % right dot
+penlabels(1,2,3,4); endchar;
+
+% Stolen from the font cmr10.mf, file accent.mf
+cmchar "Cedilla accent";
+beginchar(oct"027",8u#,0,.875desc_depth#);
+adjust_fit(0,0);
+x1=.5w+.5u;
+if serifs: pickup crisp.nib; pos1(stem,0); pos2(stem,0);
+ pos3(vair,90); pos4(stem,0); pos5(vair,-90);
+ x1=x2; z3l=z2l; x4=x2+1.5u; x5=x3-1.5u;
+ bot y1=-o; bot y2=-vround 2/7d-o; y4=.5[y3,y5]; bot y5=-d-o;
+ filldraw stroke z1e--z2e; % stem
+ filldraw stroke z3e{right}...z4e{down}...{left}z5e; % hook
+else: pickup fine.nib; pos1(vair,0); top y1=-o-2;
+ pos2(.5[vair,stem],0); bot y2=-d-o; x2=x1-1.25u;
+ filldraw stroke z1e--z2e; fi % diagonal
+penlabels(1,2,3,4,5); endchar;
+
+% My own creation, a zero width period. Used for dots in pic(1).
+cmchar "Dot for pic boxes";
+numeric dot_diam#; dot_diam#=if monospace: 5/4 fi\\ dot_size#;
+define_whole_blacker_pixels(dot_diam);
+beginchar(oct"030",0,dot_diam#,0);
+period_width#:=5u#; define_pixels(period_width);
+pickup fine.nib;
+pos1(dot_diam,0); pos2(dot_diam,90);
+lft x1l=hround(.5period_width-.5dot_diam); bot y2l=0; z1=z2; dot(1,2); % dot
+penlabels(1,2); endchar;
+
+% My own creation. The fractions look like hell.
+cmchar "1/4 symbol";
+beginchar(oct"021", 12u#, body_height#, paren_depth#);
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x1=hround(w-u)+eps; top y1=h+eps;
+lft x2=hround u-eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+x3=x4=1/4w; y3=38/40h; y4=23/40h;
+draw z3--z4; % number 1
+x5=x6=32/40w; y7=y8=1/8h; y5=-.2d; y6=.37h; x7=26/40w; x8=.85w;
+draw z5--z6--z7--z8;
+endchar;
+
+% My own creation
+cmchar "1/2 symbol";
+beginchar(oct"022", 12u#, body_height#, paren_depth#);
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x1=hround(w-u)+eps; top y1=h+eps;
+lft x2=hround u-eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+x3=x4=1/4w; y3=38/40h; y4=23/40h;
+draw z3--z4; % number 1
+x5=x9=.65w; x10=x7=.85w; x6=.74w;
+y9=y10=-.2d; y6=.37h; y5=.32h; y7=.30h;
+draw z5{dir 45}..z6..z7{dir -90}..{dir 225}z9; % number 2
+draw z9--z10;
+endchar;
+
+% My own creation.
+cmchar "3/4 symbol";
+beginchar(oct"023", 12u#, body_height#, paren_depth#);
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x1=hround(w-u)+eps; top y1=h+eps;
+lft x2=hround u-eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+draw (quartercircle rotated -90 & halfcircle) scaled .1875h shifted
+(.25w,.8562h); % number 3
+draw (halfcircle rotated -180 & quartercircle) scaled .1875h shifted
+(.25w,.6687h);
+x5=x6=32/40w; y7=y8=1/8h; y5=-.2d; y6=.37h; x7=26/40w; x8=.85w;
+draw z5--z6--z7--z8;
+endchar;
+
+% From the font cmsy10, file sym.mf
+iff known vertical: cmchar "Vertical line";
+beginchar(vertical,5u#,body_height#,paren_depth#);
+italcorr body_height#*slant+.5rule_thickness#-2u#;
+adjust_fit(0,0); pickup rule.nib;
+x1=x2=good.x .5w; top y1=h+eps; bot y2=-d-eps;
+draw z1--z2; % stem
+labels(1,2); endchar;
+
+% My own creation
+cmchar "Rule";
+beginchar(oct"005",12u#,x_height#,.7u#);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric below_baseline; below_baseline#:=.2u#;
+define_pixels(below_baseline);
+define_blacker_pixels(thickness);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(-below_baseline); rt x2=hround(w+6u#);
+lft x1=hround(0);
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+% My own creation
+cmchar "Underscore";
+beginchar("_",12u#,x_height#,.7u#);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric below_baseline; below_baseline#:=.2u#;
+define_pixels(below_baseline);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(-below_baseline); x2=hround(w);
+x1=hround 0;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+% Hyphen from cmr10, file comlig.mf
+cmchar "Hyphen";
+beginchar("-",6u#,x_height#,0);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric thickness; thickness=if hefty:bar else:.75[hair,stem] fi;
+pickup crisp.nib; pos1(thickness,90); pos2(thickness,90);
+top y1r=top y2r=vround(.5h+.5thickness); rt x2=hround(w-u)+eps;
+if monospace: x2=w-x1 else: lft x1=hround .2u-eps fi;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+% My own creation
+cmchar "Cent sign";
+beginchar(oct"020",18u#,asc_height#,desc_depth#); autorounded;
+adjust_fit(if monospace:-3u#,-3u# else: 0,0 fi); pickup rule.nib;
+lft x6=hround u; x2=w-x6; top y8=h+o; bot y4=-d-o;
+circle_points;
+x9=x11=.65[x6,x4]; x10=x12=.35[x4,x2];
+y9=y10=.35[y6,y8]; y11=y12=.65[y4,y6];
+x13=x14=.5[x6,x2]-.3u; y13=y4+2u; y14=y8-2u;
+draw z10..z9..z11..z12; draw z13--z14;
+labels(1,2,3,4,5,6,7,8,9,10,11,12,13,14); endchar;
+
+% My own creation
+cmchar "Copyright";
+beginchar(oct"016",18u#,asc_height#,desc_depth#); autorounded;
+adjust_fit(if monospace:-3u#,-3u# else: 0,0 fi); pickup rule.nib;
+lft x6=hround u; x2=w-x6; top y8=h+o; bot y4=-d-o;
+circle_points; draw_circle; % circle
+x9=x11=.65[x6,x4]; x10=x12=.35[x4,x2];
+y9=y10=.35[y6,y8]; y11=y12=.65[y4,y6];
+draw z10..z9..z11..z12;
+labels(1,2,3,4,5,6,7,8,9,10,11,12); endchar;
+
+% My own creation
+cmchar "Registered";
+beginchar(oct"017",18u#,asc_height#,desc_depth#); autorounded;
+adjust_fit(if monospace:-3u#,-3u# else: 0,0 fi); pickup rule.nib;
+lft x6=hround u; x2=w-x6; top y8=h+o; bot y4=-d-o;
+circle_points; draw_circle; % circle
+x9=x11=x12=.7[x6,x8]; x10=x13=.3[x4,x2];
+y12=y13=.5[y4,y6]; y9=.5[y6,y8]; y11=.5[y12,y9]; y10=.5[y11,y9];
+x14=.08[x4,x2]; y14=y9;
+path p;
+p=z9--z14{dir 0}..z10..{dir 180}z11;
+z15=point 2.6 of p;
+draw z12--z9; draw z13--z15; draw p;
+labels(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15); endchar;
+
+% Stolen from the font cmr10, file accent.mf (actually the acute accent)
+cmchar "Footmark";
+beginchar(oct"015",9u#,min(asc_height#,2x_height#),0);
+italcorr h#*slant-if serifs: 1.5 fi u#;
+adjust_fit(0,0);
+if serifs: pickup crisp.nib; x1+.5stem=hround(w-2u); x2=2/3[x1,w-x1];
+ y1+.5stem=h+eps; y2=max(2/3[h,x_height],x_height+o+hair);
+ numeric theta; theta=angle(z2-z1)+90;
+ pos1(stem,theta); pos2(hair,theta);
+ filldraw circ_stroke z1e--z2e; % diagonal
+else: pickup fine.nib; pos1(stem,0); pos2(vair,0);
+ rt x1r=hround(w-1.5u); lft x2l=hround(.5w-.25u-.5vair);
+ top y1=h; bot y2=vround 2/3[h,x_height];
+ filldraw stroke z1e--z2e; fi % diagonal
+penlabels(1,2); endchar;
+
+% Stolen from the font cmsy10, file symbol.mf
+cmchar "Dagger mark";
+beginchar(oct"014",8u#,asc_height#,desc_depth#);
+adjust_fit(0,0); pickup fine.nib;
+pos1(stem,0); pos2(thin_join,0); pos3(stem,0); pos4(hair,0);
+pos5(stem,90); pos2'(thin_join,90); pos6(stem,90); z2'=z2;
+x1=x2=x3=x4; x1-.5stem=hround(.5w-.5stem); w:=r:=2x1;
+x5-.5stem=hround u; x6=w-x5;
+y1+.5stem=h+oo; y2=y5=y6; y3=.57y2; bot y4=-d-o;
+y5+.5stem=floor(x_height+.5stem);
+filldraw circ_stroke z1e{down}..z2e{down}..z3e{down}..z4e; % stem
+filldraw circ_stroke z5e{right}..{right}z2'e; % left bulb
+filldraw circ_stroke z6e{left}..{left}z2'e; % right bulb
+penlabels(1,2,3,4,5,6); endchar;
+
+% Stolen from the font cmr10, file accent.mf (the Scandinavian circle accent)
+cmchar "Degree";
+beginchar(oct"013",13u#+4/3(asc_height#-x_height#)*slant,asc_height#,0);
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+numeric circ_hair,circ_vair;
+circ_hair=hround min(hair,u+.5); circ_vair=vround min(vair,(h-x_height)/6+.5);
+penpos1(circ_vair,90); penpos3(circ_vair,-90);
+penpos2(circ_hair,180); penpos4(circ_hair,0);
+x2r=hround(.5w-1.5u-.5circ_hair);
+x4r=w-x2r; x1=x3=.5w; y1r=h+apex_o; y2=y4=.5[y1,y3];
+y3r=vround(1/3[x_height,h]+apex_o);
+penstroke pulled_arc.e(1,2) & pulled_arc.e(2,3)
+ & pulled_arc.e(3,4) & pulled_arc.e(4,1) & cycle; % bowl
+penlabels(1,2,3,4); endchar;
+
+% My own creation
+cmchar "Square";
+beginchar(oct"010",9u#,v_center(7u#));
+italcorr math_axis#*slant;
+adjust_fit(0,0); pickup rule.nib;
+draw unitsquare scaled 7u shifted (.5w-7u/2,math_axis-7u/2);
+endchar;
+
+% Stolen from the font cmsy10, file symbol.mf
+cmchar "Bullet";
+beginchar(oct"007",9u#,v_center(7u#));
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x6=hround u; x2=w-x6; top y8=h; y2=math_axis; circle_points;
+filldraw z8{right}...z1{z2-z8}...z2{down}...z3{z4-z2}...z4{left}
+ ...z5{z6-z4}...z6{up}...z7{z8-z6}...cycle; % circle and interior
+labels(1,2,3,4,5,6,7,8); endchar;
+
+% Stolen from the font cmsy10, file sym.mf
+iff known minus: cmchar "Minus sign";
+beginarithchar(minus); pickup rule.nib;
+lft x1=hround 1.5u-eps; x2=w-x1; y1=y2=math_axis;
+draw z1--z2; % bar
+labels(1,2); endchar;
+
+input romanu; % upper case (majuscules)
+input itald; % numerals
+input titalp; % ampersand, question marks, currency sign
+input tpunct; % punctuation symbols common to roman and italic text
+if ligs>0: input tcomlig; fi % ligatures common with roman text
+if ligs<=1: input romsub; fi % substitutes for ligatures
+
+if not monospace:
+ k#:=-.5u#; kk#:=-1.5u#; kkk#:=-2u#; % three degrees of kerning
+ ligtable "d": "w": "l": "l" kern +u#;
+ ligtable "F": "V": "o" kern kk#, "e" kern kk#,
+ "u" kern kk#, "r" kern kk#, "a" kern kk#, "A" kern kkk#,
+ "K": "X": "O" kern k#, "C" kern k#, "G" kern k#, "Q" kern k#;
+ ligtable "T": "y" kern kk#,
+ "Y": "e" kern kk#, "o" kern kk#, "r" kern kk#, "a" kern kk#, "u" kern kk#,
+ "P": "W": "A" kern kk#;
+ ligtable "O": "D": "X" kern k#, "W" kern k#, "A" kern k#,
+ "V" kern k#, "Y" kern k#;
+ ligtable "A": "R": "n" kern k#, "l" kern k#, "r" kern k#, "u" kern k#,
+ "m" kern k#, "t" kern k#, "i" kern k#, "C" kern k#, "O" kern k#, "G" kern k#,
+ "h" kern k#, "b" kern k#, "U" kern k#, "k" kern k#, "v" kern k#, "w" kern k#,
+ "Q" kern k#, "L": "T" kern kk#, "Y" kern kk#, "V" kern kkk#, "W" kern kkk#,
+ "b": "c": "e": "o": "p": "r": "e" kern -u#, "a" kern -u#, "o" kern -u#,
+ "d" kern -u#, "c" kern -u#, "g" kern -u#, "q" kern -u#;
+ fi
+% there are ligature/kern programs for |"f"| in the {\tt romlig} file
+% and for |"-"|, |"`"|, and |"'"| in the {\tt comlig} file
+bye.
diff --git a/dviware/quicspool/wwfonts/b.mf b/dviware/quicspool/wwfonts/b.mf
new file mode 100644
index 0000000000..52ac9160af
--- /dev/null
+++ b/dviware/quicspool/wwfonts/b.mf
@@ -0,0 +1,83 @@
+% $Header: B.mf,v 1.1 88/01/15 13:14:32 simpson Rel $
+% $Log: B.mf,v $
+%Revision 1.1 88/01/15 13:14:32 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:20 simpson
+%beta test
+%
+% Computer Modern Bold Roman 10 point
+if unknown cmbase: input cmbase fi
+
+font_identifier:="CMB"; font_size 10pt#;
+
+u#:=20/36pt#; % unit width
+width_adj#:=10/36pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=6/36pt#; % extra sidebar near uppercase serifs
+letter_fit#:=0pt#; % extra space added to all sidebars
+
+body_height#:=270/36pt#; % height of tallest characters
+asc_height#:=250/36pt#; % height of lowercase ascenders
+cap_height#:=247/36pt#; % height of caps
+fig_height#:=232/36pt#; % height of numerals
+x_height#:=160/36pt#; % height of lowercase without ascenders
+math_axis#:=90/36pt#; % axis of symmetry for math symbols
+bar_height#:=85/36pt#; % height of crossbar in lowercase e
+comma_depth#:=70/36pt#; % depth of comma below baseline
+desc_depth#:=70/36pt#; % depth of lowercase descenders
+
+crisp#:=0pt#; % diameter of serif corners
+tiny#:=13/36pt#; % diameter of rounded corners
+fine#:=10/36pt#; % diameter of sharply rounded corners
+thin_join#:=10/36pt#; % width of extrafine details
+hair#:=17/36pt#; % lowercase hairline breadth
+stem#:=41/36pt#; % lowercase stem breadth
+curve#:=46/36pt#; % lowercase curve breadth
+ess#:=38/36pt#; % breadth in middle of lowercase s
+flare#:=45/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=56/36pt#; % diameter of dots
+cap_hair#:=19/36pt#; % uppercase hairline breadth
+cap_stem#:=51/36pt#; % uppercase stem breadth
+cap_curve#:=55/36pt#; % uppercase curve breadth
+cap_ess#:=53/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=.6pt#; % thickness of lines in math symbols
+
+dish#:=1/36pt#; % amount erased at top or bottom of serifs
+bracket#:=10/36pt#; % vertical distance from serif base to tangent
+jut#:=25/36pt#; % protrusion of lowercase serifs
+cap_jut#:=34/36pt#; % protrusion of uppercase serifs
+beak_jut#:=11/36pt#; % horizontal protrusion of beak serifs
+beak#:=70/36pt#; % vertical protrusion of beak serifs
+vair#:=13/36pt#; % vertical diameter of hairlines
+notch_cut#:=10pt#; % maximum breadth above or below notches
+bar#:=17/36pt#; % lowercase bar thickness
+slab#:=17/36pt#; % serif and arm thickness
+cap_bar#:=17/36pt#; % uppercase bar thickness
+cap_band#:=17/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=10pt#; % max breadth above/below uppercase notches
+serif_drop#:=3/36pt#; % vertical drop of sloped serifs
+stem_corr#:=2/36pt#; % for small refinements of stem breadth
+vair_corr#:=1.5/36pt#; % for small refinements of hairline height
+apex_corr#:=0pt#; % extra width at diagonal junctions
+
+o#:=4/36pt#; % amount of overshoot for curves
+apex_o#:=3/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=0; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=1; % factor applied to weights of heavy characters
+math_spread:=.5; % extra openness of math symbols
+superness:=8/11; % parameter for superellipses
+superpull:=1/8; % extra openness inside bowls
+beak_darkness:=.4; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=false; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=false; % should all characters have the same width?
+variant_g:=false; % should an italic-style g be used?
+low_asterisk:=false; % should the asterisk be centered at the axis?
+math_fitting:=false; % should math-mode spacing be used?
+
+generate troman % switch to the driver file
diff --git a/dviware/quicspool/wwfonts/b.tfm b/dviware/quicspool/wwfonts/b.tfm
new file mode 100644
index 0000000000..7d87d93696
--- /dev/null
+++ b/dviware/quicspool/wwfonts/b.tfm
Binary files differ
diff --git a/dviware/quicspool/wwfonts/cw.mf b/dviware/quicspool/wwfonts/cw.mf
new file mode 100644
index 0000000000..1073f46b76
--- /dev/null
+++ b/dviware/quicspool/wwfonts/cw.mf
@@ -0,0 +1,83 @@
+% $Header: CW.mf,v 1.1 88/01/15 13:14:34 simpson Rel $
+% $Log: CW.mf,v $
+%Revision 1.1 88/01/15 13:14:34 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:21 simpson
+%beta test
+%
+% Computer Modern Typewriter Text for use with 10 point
+if unknown cmbase: input cmbase fi
+
+font_identifier:="CMTT"; font_size 10pt#;
+
+u#:=21/36pt#; % unit width
+width_adj#:=0pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=0pt#; % extra sidebar near uppercase serifs
+letter_fit#:=0pt#; % extra space added to all sidebars
+
+body_height#:=250/36pt#; % height of tallest characters
+asc_height#:=220/36pt#; % height of lowercase ascenders
+cap_height#:=220/36pt#; % height of caps
+fig_height#:=220/36pt#; % height of numerals
+x_height#:=155/36pt#; % height of lowercase without ascenders
+math_axis#:=110/36pt#; % axis of symmetry for math symbols
+bar_height#:=79/36pt#; % height of crossbar in lowercase e
+comma_depth#:=50/36pt#; % depth of comma below baseline
+desc_depth#:=80/36pt#; % depth of lowercase descenders
+
+crisp#:=22/36pt#; % diameter of serif corners
+tiny#:=22/36pt#; % diameter of rounded corners
+fine#:=21/36pt#; % diameter of sharply rounded corners
+thin_join#:=21/36pt#; % width of extrafine details
+hair#:=25/36pt#; % lowercase hairline breadth
+stem#:=25/36pt#; % lowercase stem breadth
+curve#:=25/36pt#; % lowercase curve breadth
+ess#:=22/36pt#; % breadth in middle of lowercase s
+flare#:=32/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=36/36pt#; % diameter of dots
+cap_hair#:=25/36pt#; % uppercase hairline breadth
+cap_stem#:=25/36pt#; % uppercase stem breadth
+cap_curve#:=25/36pt#; % uppercase curve breadth
+cap_ess#:=25/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=25/36pt#; % thickness of lines in math symbols
+
+dish#:=0pt#; % amount erased at top or bottom of serifs
+bracket#:=0pt#; % vertical distance from serif base to tangent
+jut#:=34/36pt#; % protrusion of lowercase serifs
+cap_jut#:=34/36pt#; % protrusion of uppercase serifs
+beak_jut#:=0pt#; % horizontal protrusion of beak serifs
+beak#:=34/36pt#; % vertical protrusion of beak serifs
+vair#:=22/36pt#; % vertical diameter of hairlines
+notch_cut#:=25/36pt#; % maximum breadth above or below notches
+bar#:=22/36pt#; % lowercase bar thickness
+slab#:=22/36pt#; % serif and arm thickness
+cap_bar#:=22/36pt#; % uppercase bar thickness
+cap_band#:=22/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=25/36pt#; % max breadth above/below uppercase notches
+serif_drop#:=0pt#; % vertical drop of sloped serifs
+stem_corr#:=0pt#; % for small refinements of stem breadth
+vair_corr#:=0pt#; % for small refinements of hairline height
+apex_corr#:=10/36pt#; % extra width at diagonal junctions
+
+o#:=4/36pt#; % amount of overshoot for curves
+apex_o#:=3/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=0; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=0.81; % factor applied to weights of heavy characters
+math_spread:=-1; % extra openness of math symbols
+superness:=1/sqrt2; % parameter for superellipses
+superpull:=0; % extra openness inside bowls
+beak_darkness:=0; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=true; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=true; % should all characters have the same width?
+variant_g:=false; % should an italic-style g be used?
+low_asterisk:=true; % should the asterisk be centered at the axis?
+math_fitting:=false; % should math-mode spacing be used?
+
+generate troman % switch to the driver file
diff --git a/dviware/quicspool/wwfonts/cw.tfm b/dviware/quicspool/wwfonts/cw.tfm
new file mode 100644
index 0000000000..b2839c81b7
--- /dev/null
+++ b/dviware/quicspool/wwfonts/cw.tfm
Binary files differ
diff --git a/dviware/quicspool/wwfonts/desc b/dviware/quicspool/wwfonts/desc
new file mode 100644
index 0000000000..0d780bf4b5
--- /dev/null
+++ b/dviware/quicspool/wwfonts/desc
@@ -0,0 +1,43 @@
+# QMS QUIC printers
+# $Header: DESC,v 1.1 88/01/15 13:14:29 simpson Rel $
+# $Log: DESC,v $
+#Revision 1.1 88/01/15 13:14:29 simpson
+#initial release
+#
+#Revision 0.3 87/12/18 10:10:22 simpson
+#added l. and L. for pic dot boxes
+#
+#Revision 0.2 87/12/14 09:36:01 simpson
+#Moved S after CW in font list.
+#
+#Revision 0.1 87/12/11 19:03:59 simpson
+#beta test
+#
+fonts 5 R I B CW S
+sizes 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 24 26 28 30 32 34 36 40 44 48 0
+res 300
+hor 1
+vert 1
+unitwidth 10
+paperwidth 2550
+paperlength 3300
+charset
+\| \^ \- \_ \`
+** *A *B *G *D *E *Z *Y *H *I *K *L *M *N *C *O *P *R *S *T *U *F *X *Q *W
+*a *b *c *d *e *f *g *h *i
+*k *l *m *n *o *p *q *r *s *t *u
+*w *x *y *z +- -> <- <=
+== >=
+aa ap br bs bu bv bx ca cd
+ci co ct cu dd de dg di em en
+eq es fe fm ga gr hy
+ib if ip is lh li Li ma mi mo
+mu no ob or pd pl pp pt rg rh ru
+sb sc sl Sl sp sq sr tm tp ts ul vr
+~= ~~ rn
+lf rf lc rc lt rt lb rb
+lk rk != .. l. L.
+ua da
+12
+14 34
+fi fl ff fI fL Fi Fl
diff --git a/dviware/quicspool/wwfonts/i.mf b/dviware/quicspool/wwfonts/i.mf
new file mode 100644
index 0000000000..844fb51f03
--- /dev/null
+++ b/dviware/quicspool/wwfonts/i.mf
@@ -0,0 +1,83 @@
+% $Header: I.mf,v 1.1 88/01/15 13:14:36 simpson Rel $
+% $Log: I.mf,v $
+%Revision 1.1 88/01/15 13:14:36 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:22 simpson
+%beta test
+%
+% Computer Modern Text Italic 10 point
+if unknown cmbase: input cmbase fi
+
+font_identifier:="CMTI"; font_size 10pt#;
+
+u#:=18.4/36pt#; % unit width
+width_adj#:=0pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=5/36pt#; % extra sidebar near uppercase serifs
+letter_fit#:=9.2/36pt#; % extra space added to all sidebars
+
+body_height#:=270/36pt#; % height of tallest characters
+asc_height#:=250/36pt#; % height of lowercase ascenders
+cap_height#:=246/36pt#; % height of caps
+fig_height#:=232/36pt#; % height of numerals
+x_height#:=155/36pt#; % height of lowercase without ascenders
+math_axis#:=90/36pt#; % axis of symmetry for math symbols
+bar_height#:=87/36pt#; % height of crossbar in lowercase e
+comma_depth#:=70/36pt#; % depth of comma below baseline
+desc_depth#:=70/36pt#; % depth of lowercase descenders
+
+crisp#:=8/36pt#; % diameter of serif corners
+tiny#:=8/36pt#; % diameter of rounded corners
+fine#:=7/36pt#; % diameter of sharply rounded corners
+thin_join#:=7/36pt#; % width of extrafine details
+hair#:=11/36pt#; % lowercase hairline breadth
+stem#:=23/36pt#; % lowercase stem breadth
+curve#:=28/36pt#; % lowercase curve breadth
+ess#:=27/36pt#; % breadth in middle of lowercase s
+flare#:=29/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=38/36pt#; % diameter of dots
+cap_hair#:=11/36pt#; % uppercase hairline breadth
+cap_stem#:=29/36pt#; % uppercase stem breadth
+cap_curve#:=34/36pt#; % uppercase curve breadth
+cap_ess#:=31/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=.4pt#; % thickness of lines in math symbols
+
+dish#:=1/36pt#; % amount erased at top or bottom of serifs
+bracket#:=20/36pt#; % vertical distance from serif base to tangent
+jut#:=30/36pt#; % protrusion of lowercase serifs
+cap_jut#:=34/36pt#; % protrusion of uppercase serifs
+beak_jut#:=9/36pt#; % horizontal protrusion of beak serifs
+beak#:=70/36pt#; % vertical protrusion of beak serifs
+vair#:=8/36pt#; % vertical diameter of hairlines
+notch_cut#:=10pt#; % maximum breadth above or below notches
+bar#:=11/36pt#; % lowercase bar thickness
+slab#:=11/36pt#; % serif and arm thickness
+cap_bar#:=11/36pt#; % uppercase bar thickness
+cap_band#:=11/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=10pt#; % max breadth above/below uppercase notches
+serif_drop#:=4/36pt#; % vertical drop of sloped serifs
+stem_corr#:=1/36pt#; % for small refinements of stem breadth
+vair_corr#:=1/36pt#; % for small refinements of hairline height
+apex_corr#:=0pt#; % extra width at diagonal junctions
+
+o#:=8/36pt#; % amount of overshoot for curves
+apex_o#:=8/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=.25; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=1; % factor applied to weights of heavy characters
+math_spread:=0; % extra openness of math symbols
+superness:=1/sqrt2; % parameter for superellipses
+superpull:=1/6; % extra openness inside bowls
+beak_darkness:=11/30; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=false; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=false; % should all characters have the same width?
+variant_g:=true; % should an italic-style g be used?
+low_asterisk:=false; % should the asterisk be centered at the axis?
+math_fitting:=false; % should math-mode spacing be used?
+
+generate ttextit % switch to the driver file
diff --git a/dviware/quicspool/wwfonts/i.tfm b/dviware/quicspool/wwfonts/i.tfm
new file mode 100644
index 0000000000..90110292ec
--- /dev/null
+++ b/dviware/quicspool/wwfonts/i.tfm
Binary files differ
diff --git a/dviware/quicspool/wwfonts/makefile b/dviware/quicspool/wwfonts/makefile
new file mode 100644
index 0000000000..d7012e4b61
--- /dev/null
+++ b/dviware/quicspool/wwfonts/makefile
@@ -0,0 +1,40 @@
+# $Header: Makefile,v 1.1 88/01/15 13:14:23 simpson Rel $
+# $Log: Makefile,v $
+#Revision 1.1 88/01/15 13:14:23 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 19:09:52 simpson
+#beta test
+#
+OTROFFFONT=/usr/lib/font
+DITROFFFONT=/usr/lib/font/devqms
+
+all: owidths diwidths desc
+
+configure:
+
+owidths:
+ ../src/tfm2ofont R.tfm I.tfm B.tfm CW.tfm
+ ../src/tfm2ofont -s S.tfm
+ cc -c ftR.c ftI.c ftB.c ftS.c ftCW.c
+ for i in ftR.o ftI.o ftB.o ftS.o ftCW.o;do \
+ mv $$i `basename $$i .o`;\
+ done
+
+diwidths:
+ ../src/tfm2difont R.tfm I.tfm B.tfm
+ ../src/tfm2difont -l fi -l ff -l fl -l ffi -l ffl -w 22 CW.tfm
+ ../src/tfm2difont -s S.tfm
+
+desc:
+ -makedev DESC
+
+install:
+ cp *pk $(DITROFFFONT)/wwfonts
+ chmod 644 $(DITROFFFONT)/wwfonts/*pk
+ for i in R I B S CW;do install -m 644 ft$$i $(OTROFFFONT); done
+ -install DESC.out $(DITROFFFONT)
+ -for i in R I B CW S;do install -m 644 $$i.out $(DITROFFFONT); done
+
+clean:
+ -rm *gf *.log *.c ft* *.out R I B S CW
diff --git a/dviware/quicspool/wwfonts/makefile.trw b/dviware/quicspool/wwfonts/makefile.trw
new file mode 100644
index 0000000000..e93ead4479
--- /dev/null
+++ b/dviware/quicspool/wwfonts/makefile.trw
@@ -0,0 +1,40 @@
+# $Header: Makefile.TRW,v 1.1 88/01/15 13:14:25 simpson Rel $
+# $Log: Makefile.TRW,v $
+#Revision 1.1 88/01/15 13:14:25 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 19:09:54 simpson
+#beta test
+#
+OTROFFFONT=/usr/lib/font
+DITROFFFONT=/usr/lib/font/devqms
+
+all: owidths diwidths desc
+
+configure:
+
+owidths:
+ ../src/tfm2ofont R.tfm I.tfm B.tfm CW.tfm
+ ../src/tfm2ofont -s S.tfm
+ cc -c ftR.c ftI.c ftB.c ftS.c ftCW.c
+ for i in ftR.o ftI.o ftB.o ftS.o ftCW.o;do \
+ mv $$i `basename $$i .o`;\
+ done
+
+diwidths:
+ ../src/tfm2difont R.tfm I.tfm B.tfm
+ ../src/tfm2difont -l fi -l ff -l fl -l ffi -l ffl -w 22 CW.tfm
+ ../src/tfm2difont -s S.tfm
+
+desc:
+ -makedev DESC
+
+install:
+ cp *pk $(DITROFFFONT)/wwfonts
+ chmod 644 $(DITROFFFONT)/wwfonts/*pk
+ for i in R I B S CW;do install -m 644 ft$$i $(OTROFFFONT); done
+ -install DESC.out $(DITROFFFONT)
+ -for i in R I B CW S;do install -m 644 $$i.out $(DITROFFFONT); done
+
+clean:
+ -rm *gf *.log *.c ft* *.out R I B S CW
diff --git a/dviware/quicspool/wwfonts/makefonts b/dviware/quicspool/wwfonts/makefonts
new file mode 100644
index 0000000000..920e7e108e
--- /dev/null
+++ b/dviware/quicspool/wwfonts/makefonts
@@ -0,0 +1,30 @@
+#! /bin/sh
+# $Header: makefonts,v 1.1 88/01/15 13:14:27 simpson Rel $
+# $Log: makefonts,v $
+#Revision 1.1 88/01/15 13:14:27 simpson
+#initial release
+#
+#Revision 0.1 87/12/11 19:09:55 simpson
+#beta test
+#
+# Creates the sizes
+# 4 to 20
+# 22 to 36 step 2
+# 40 to 48 step 4
+# using METAFONT
+fontlist="`grep '^fonts' DESC | sed 's/fonts [0-9][0-9]* //'`"
+for font in $fontlist; do
+ i=4
+ while [ $i -le 48 ];do
+# Use mode type qms for a write-white engine
+ mf '\mode:=qms;' "mag:=$i/10;" input $font
+ gftopk $font.`expr $i \* 300 / 10`gf
+ if [ $i -ge 20 -a $i -le 34 ]; then
+ i=`expr $i + 2`
+ elif [ $i -ge 36 ]; then
+ i=`expr $i + 4`
+ else
+ i=`expr $i + 1`
+ fi
+ done
+done
diff --git a/dviware/quicspool/wwfonts/r.mf b/dviware/quicspool/wwfonts/r.mf
new file mode 100644
index 0000000000..8c293d0adc
--- /dev/null
+++ b/dviware/quicspool/wwfonts/r.mf
@@ -0,0 +1,83 @@
+% $Header: R.mf,v 1.1 88/01/15 13:14:38 simpson Rel $
+% $Log: R.mf,v $
+%Revision 1.1 88/01/15 13:14:38 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:23 simpson
+%beta test
+%
+% Computer Modern Roman 10 point
+if unknown cmbase: input cmbase fi
+
+font_identifier:="TCMR"; font_size 10pt#;
+
+u#:=20/36pt#; % unit width
+width_adj#:=0pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=5/36pt#; % extra sidebar near uppercase serifs
+letter_fit#:=0pt#; % extra space added to all sidebars
+
+body_height#:=270/36pt#; % height of tallest characters
+asc_height#:=250/36pt#; % height of lowercase ascenders
+cap_height#:=246/36pt#; % height of caps
+fig_height#:=232/36pt#; % height of numerals
+x_height#:=155/36pt#; % height of lowercase without ascenders
+math_axis#:=90/36pt#; % axis of symmetry for math symbols
+bar_height#:=87/36pt#; % height of crossbar in lowercase e
+comma_depth#:=70/36pt#; % depth of comma below baseline
+desc_depth#:=70/36pt#; % depth of lowercase descenders
+
+crisp#:=0pt#; % diameter of serif corners
+tiny#:=8/36pt#; % diameter of rounded corners
+fine#:=7/36pt#; % diameter of sharply rounded corners
+thin_join#:=7/36pt#; % width of extrafine details
+hair#:=9/36pt#; % lowercase hairline breadth
+stem#:=25/36pt#; % lowercase stem breadth
+curve#:=30/36pt#; % lowercase curve breadth
+ess#:=27/36pt#; % breadth in middle of lowercase s
+flare#:=33/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=38/36pt#; % diameter of dots
+cap_hair#:=11/36pt#; % uppercase hairline breadth
+cap_stem#:=32/36pt#; % uppercase stem breadth
+cap_curve#:=37/36pt#; % uppercase curve breadth
+cap_ess#:=35/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=.4pt#; % thickness of lines in math symbols
+
+dish#:=1/36pt#; % amount erased at top or bottom of serifs
+bracket#:=20/36pt#; % vertical distance from serif base to tangent
+jut#:=28/36pt#; % protrusion of lowercase serifs
+cap_jut#:=37/36pt#; % protrusion of uppercase serifs
+beak_jut#:=10/36pt#; % horizontal protrusion of beak serifs
+beak#:=70/36pt#; % vertical protrusion of beak serifs
+vair#:=8/36pt#; % vertical diameter of hairlines
+notch_cut#:=10pt#; % maximum breadth above or below notches
+bar#:=11/36pt#; % lowercase bar thickness
+slab#:=11/36pt#; % serif and arm thickness
+cap_bar#:=11/36pt#; % uppercase bar thickness
+cap_band#:=11/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=10pt#; % max breadth above/below uppercase notches
+serif_drop#:=4/36pt#; % vertical drop of sloped serifs
+stem_corr#:=1/36pt#; % for small refinements of stem breadth
+vair_corr#:=1/36pt#; % for small refinements of hairline height
+apex_corr#:=0pt#; % extra width at diagonal junctions
+
+o#:=8/36pt#; % amount of overshoot for curves
+apex_o#:=8/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=0; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=1; % factor applied to weights of heavy characters
+math_spread:=0; % extra openness of math symbols
+superness:=1/sqrt2; % parameter for superellipses
+superpull:=1/6; % extra openness inside bowls
+beak_darkness:=11/30; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=false; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=false; % should all characters have the same width?
+variant_g:=false; % should an italic-style g be used?
+low_asterisk:=false; % should the asterisk be centered at the axis?
+math_fitting:=false; % should math-mode spacing be used?
+
+generate troman % switch to the driver file
diff --git a/dviware/quicspool/wwfonts/r.tfm b/dviware/quicspool/wwfonts/r.tfm
new file mode 100644
index 0000000000..6fcd675997
--- /dev/null
+++ b/dviware/quicspool/wwfonts/r.tfm
Binary files differ
diff --git a/dviware/quicspool/wwfonts/s.mf b/dviware/quicspool/wwfonts/s.mf
new file mode 100644
index 0000000000..49ff11ce4c
--- /dev/null
+++ b/dviware/quicspool/wwfonts/s.mf
@@ -0,0 +1,83 @@
+% $Header: S.mf,v 1.1 88/01/15 13:14:41 simpson Rel $
+% $Log: S.mf,v $
+%Revision 1.1 88/01/15 13:14:41 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:24 simpson
+%beta test
+%
+% Computer Modern Math Italic 10 point
+if unknown cmbase: input cmbase fi
+
+font_identifier:="CMMI"; font_size 10pt#;
+
+u#:=20/36pt#; % unit width
+width_adj#:=0pt#; % width adjustment for certain characters
+serif_fit#:=0pt#; % extra sidebar near lowercase serifs
+cap_serif_fit#:=5/36pt#; % extra sidebar near uppercase serifs
+letter_fit#:=0pt#; % extra space added to all sidebars
+
+body_height#:=270/36pt#; % height of tallest characters
+asc_height#:=250/36pt#; % height of lowercase ascenders
+cap_height#:=246/36pt#; % height of caps
+fig_height#:=232/36pt#; % height of numerals
+x_height#:=155/36pt#; % height of lowercase without ascenders
+math_axis#:=90/36pt#; % axis of symmetry for math symbols
+bar_height#:=87/36pt#; % height of crossbar in lowercase e
+comma_depth#:=70/36pt#; % depth of comma below baseline
+desc_depth#:=70/36pt#; % depth of lowercase descenders
+
+crisp#:=8/36pt#; % diameter of serif corners
+tiny#:=8/36pt#; % diameter of rounded corners
+fine#:=7/36pt#; % diameter of sharply rounded corners
+thin_join#:=7/36pt#; % width of extrafine details
+hair#:=9/36pt#; % lowercase hairline breadth
+stem#:=24/36pt#; % lowercase stem breadth
+curve#:=29/36pt#; % lowercase curve breadth
+ess#:=27/36pt#; % breadth in middle of lowercase s
+flare#:=32/36pt#; % diameter of bulbs or breadth of terminals
+dot_size#:=38/36pt#; % diameter of dots
+cap_hair#:=11/36pt#; % uppercase hairline breadth
+cap_stem#:=30/36pt#; % uppercase stem breadth
+cap_curve#:=35/36pt#; % uppercase curve breadth
+cap_ess#:=33/36pt#; % breadth in middle of uppercase s
+rule_thickness#:=.4pt#; % thickness of lines in math symbols
+
+dish#:=1/36pt#; % amount erased at top or bottom of serifs
+bracket#:=20/36pt#; % vertical distance from serif base to tangent
+jut#:=30/36pt#; % protrusion of lowercase serifs
+cap_jut#:=37/36pt#; % protrusion of uppercase serifs
+beak_jut#:=10/36pt#; % horizontal protrusion of beak serifs
+beak#:=70/36pt#; % vertical protrusion of beak serifs
+vair#:=8/36pt#; % vertical diameter of hairlines
+notch_cut#:=10pt#; % maximum breadth above or below notches
+bar#:=11/36pt#; % lowercase bar thickness
+slab#:=11/36pt#; % serif and arm thickness
+cap_bar#:=11/36pt#; % uppercase bar thickness
+cap_band#:=11/36pt#; % uppercase thickness above/below lobes
+cap_notch_cut#:=10pt#; % max breadth above/below uppercase notches
+serif_drop#:=4/36pt#; % vertical drop of sloped serifs
+stem_corr#:=1/36pt#; % for small refinements of stem breadth
+vair_corr#:=1/36pt#; % for small refinements of hairline height
+apex_corr#:=0pt#; % extra width at diagonal junctions
+
+o#:=8/36pt#; % amount of overshoot for curves
+apex_o#:=8/36pt#; % amount of overshoot for diagonal junctions
+
+slant:=.25; % tilt ratio $(\Delta x/\Delta y)$
+fudge:=1; % factor applied to weights of heavy characters
+math_spread:=0; % extra openness of math symbols
+superness:=1/sqrt2; % parameter for superellipses
+superpull:=1/6; % extra openness inside bowls
+beak_darkness:=11/30; % fraction of triangle inside beak serifs
+ligs:=2; % level of ligatures to be included
+
+square_dots:=false; % should dots be square?
+hefty:=false; % should we try hard not to be overweight?
+serifs:=true; % should serifs and bulbs be attached?
+monospace:=false; % should all characters have the same width?
+variant_g:=true; % should an italic-style g be used?
+low_asterisk:=false; % should the asterisk be centered at the axis?
+math_fitting:=true; % should math-mode spacing be used?
+
+generate tmathit % switch to the driver file
diff --git a/dviware/quicspool/wwfonts/s.tfm b/dviware/quicspool/wwfonts/s.tfm
new file mode 100644
index 0000000000..529fe0dbd0
--- /dev/null
+++ b/dviware/quicspool/wwfonts/s.tfm
Binary files differ
diff --git a/dviware/quicspool/wwfonts/tcomlig.mf b/dviware/quicspool/wwfonts/tcomlig.mf
new file mode 100644
index 0000000000..78b5c56935
--- /dev/null
+++ b/dviware/quicspool/wwfonts/tcomlig.mf
@@ -0,0 +1,21 @@
+% $Header: tcomlig.mf,v 1.1 88/01/15 13:14:44 simpson Rel $
+% $Log: tcomlig.mf,v $
+%Revision 1.1 88/01/15 13:14:44 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:25 simpson
+%beta test
+%
+% This file defines characters common to roman and italic text fonts
+% that appear only when |ligs>0|.
+
+% Character codes \006 is generated
+
+cmchar "Em dash";
+beginchar(oct"006",18u#,x_height#,0);
+italcorr .61803x_height#*slant+.5u#;
+adjust_fit(letter_fit#,letter_fit#);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(.61803h+.5vair); lft x1=-eps; rt x2=w+eps;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
diff --git a/dviware/quicspool/wwfonts/tgreekl.mf b/dviware/quicspool/wwfonts/tgreekl.mf
new file mode 100644
index 0000000000..11020b137c
--- /dev/null
+++ b/dviware/quicspool/wwfonts/tgreekl.mf
@@ -0,0 +1,418 @@
+% $Header: tgreekl.mf,v 1.1 88/01/15 13:14:46 simpson Rel $
+% $Log: tgreekl.mf,v $
+%Revision 1.1 88/01/15 13:14:46 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:27 simpson
+%beta test
+%
+% This lowercase Greek alphabet was prepared by D. E. Knuth in December, 1979,
+% inspired by the Monotype faces used in {\sl The Art of Computer Programming}.
+% (It has been designed for math formulas, not Greek texts.)
+% The programs were revised for the new \MF\ conventions in 1985.
+
+cmchar "Lowercase Greek alpha";
+beginchar(oct"141",11u#,x_height#,0);
+italcorr max(1/3x_height#*slant+.5hair#+.5u#,x_height#*slant-.5u#);
+adjust_fit(0,0); pickup fine.nib;
+pos0(hair,0); pos1(vair,-90); pos2(curve,-180); pos3(vair,-270);
+z4=(w-3.25u,9/16h); z5=(w-2.75u,.5[vair,y4]);
+numeric theta; theta=angle(z4-z5)-90;
+pos4(stem,theta); pos5(stem,theta);
+pos6(vair,90); pos7(hair,180);
+rt x0r=hround(w-u); x1=x3=.5w-u; lft x2r=hround(1.5u-.5curve);
+x6=w-u; x7+.5hair=hround(w+.5hair-epsilon);
+top y0=vround .8[bar_height,h]; bot y1r=bot y6l=-oo;
+y2=.5[y1,y3]; top y3r=h+oo; y7=1/4bar_height;
+filldraw stroke z0e{down}...pulled_arc.e(1,2) & pulled_arc.e(2,3)
+ ...z4e---z5e...z6e{right}...{up}z7e; % diagonal, bowl, and hook
+math_fit(-.3x_height#*slant+.5curve#-u#,1/3x_height#*slant+.5hair#+.5u#);
+penlabels(0,1,2,3,4,5,6,7); endchar;
+
+cmchar "Lowercase Greek beta";
+beginchar(oct"142",9.5u#,asc_height#,desc_depth#);
+italcorr .5[x_height#,asc_height#]*slant-u#;
+adjust_fit(0,0); pickup fine.nib;
+pos0(hair,180); pos1(hair,180); pos2(vair,90);
+pos3(stem,0); pos4(vair,-90); pos5(hair,-180);
+pos6(vair,-270); pos7(curve,-360); pos8(vair,-450); pos9(hair,-540);
+x0=x1=x9; lft x0l=hround(1.5u-.5hair); x2=x4=x6=x8=.5w+.25u;
+rt x3r=hround(w-1.5u); rt x7r=hround(w-1.5u+.5curve); rt x5l=hround(x4-u);
+bot y0=-d; y1=top y6r=x_height; top y2r=h+oo; y3=.5[y2,y4];
+y5=.5[y4,y6]; top y6r-bot y4r=vstem+eps; bot y8=-oo; y7=y9=.5[y6,y8];
+if y6l<y4l: y6l:=y4l:=y5; fi
+filldraw stroke z0e---z1e...pulled_arc.e(2,3)
+ & pulled_arc.e(3,4)...{up}z5e; % stem and upper bowl
+filldraw stroke z5e{up}...pulled_arc.e(6,7)
+ & pulled_arc.e(7,8)...{up}z9e; % lower bowl
+math_fit(desc_depth#*slant+.5hair#-u#,.7x_height#*slant+.5curve#-1.5u#);
+penlabels(0,1,2,3,4,5,6,7,8,9); endchar;
+
+cmchar "Lowercase Greek gamma";
+beginchar(oct"143",10u#,x_height#,desc_depth#);
+italcorr x_height#*slant-.5u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(hair,180); pos2(vstem+dw,90);
+pos4(hair,0); pos5(vair,-90); pos6(hair,-180); pos7(hair,-180);
+bot y1=.5772156649h; top y2r=h+oo; y4=y6=-.5d;
+bot y5r=-d-o; top y7=h;
+lft x1r=hround(.5u-.5hair); x2=3u; rt x4r=hround(w-2u); x5=.5[x4,x6];
+rt x4r-lft x6r=hround 1/3[hair,stem]+eps; rt x7l=hround(w-u);
+if x4l<x6l: x4l:=x6l:=x5; fi
+pos3(hair,angle(z4-z2)+90); x3=superness[x2,x4]; y3=superness[y4,y2];
+filldraw stroke z1e{up}...z2e{right}...z3e{z4-z2}
+ ...z4e{down}...{left}z5e; % arc
+filldraw stroke z5e{left}...z6e{up}..{2(x7-x6),y7-y6}z7e; % stem
+math_fit(-.5772156649x_height#*slant,ic#-u#);
+penlabels(1,2,3,4,5,6,7); endchar;
+
+cmchar "Lowercase Greek delta";
+beginchar(oct"144",8u#,asc_height#,0);
+italcorr .9asc_height#*slant+.5hair#-1.5u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(hair,-180); pos2(vair,-90);
+numeric theta; theta=angle(18u,-h);
+pos3(stem,theta+90); pos4(stem,theta+90); pos5(1/4[hair,stem],20);
+pos6(vair,-90); pos7(curve,-180); pos8(vair,-270);
+rt x1l=hround(w-2u+.5hair); x2=.5w; x3r=3u; rt x5r=hround(w-u);
+x4=x6=x8=.5w+.5u; lft x7r=hround(1.5u-.5curve);
+y1=.9h; top y2l=h+oo; top y8r=x_height+oo; y4=y8;
+z4-z3=whatever*(18u,-h); y5=y7=.5[y6,y8]; bot y6=-oo;
+filldraw stroke z1e{x2-x1,3(y2-y1)}...z2e{left}...z3e---z4e
+ ....z5e{down}...pulled_arc.e(6,7) & pulled_arc.e(7,8); % hook and bowl
+math_fit(-.3x_height#*slant+.5curve#-u#,.7x_height#*slant-.5u#);
+penlabels(1,2,3,4,5,6,7,8); endchar;
+
+cmchar "Lowercase Greek epsilon";
+beginchar(oct"145",8u#,x_height#,0);
+italcorr x_height#*slant+.5hair#-2u#;
+adjust_fit(0,0); pickup fine.nib;
+pos0(bar,90); pos1(bar,90); pos2(curve,180);
+pos3(vair,270); pos4(hair,300); pos6(bar,90); pos7(bar,90);
+x1=.5w+.5u; x0=x1+u; lft x2r=hround(1.5u-.5curve); x3=.5[x0,x1];
+x4r=good.x(w-u); x5=w+.5u; x6=x0; z7=z2l;
+top y0r=top y1r=h; y2=y5=y6=bar_height; bot y3r=-oo;
+path p; p=z3r{right}...{up}z5;
+numeric t; t=ypart(((x4r,y3r)--(x4r,y5))intersectiontimes p);
+y4r=ypart point t of p;
+filldraw circ_stroke z0e..pulled_arc.e(1,2) & pulled_arc.e(2,3)
+ ...z4e{direction t of p}; % arc
+filldraw circ_stroke z6e--z7e; % bar
+math_fit(-.3x_height#*slant+.5curve#-u#,ic#);
+penlabels(0,1,2,3,4,5,6,7); endchar;
+
+cmchar "Lowercase Greek zeta";
+beginchar(oct"146",9u#,asc_height#,desc_depth#);
+italcorr .75[x_height#,asc_height#]*slant-1.5u#;
+adjust_fit(0,0); pickup fine.nib;
+pos0(hair,-360); pos1(vair,-270); pos2(hair,-180); pos3(vair,-90);
+numeric theta; theta=90-angle(25u,x_height); slope:=-x_height/25u;
+pos6(stem,theta); pos7(vair,-90); pos8(vair,-135);
+lft x0l=hround 3.5u; x1=x3=.5[x0,x2]; rt x2l=hround max(rt x0r,w-2u)+eps;
+top y0=h; top y3l=bot y1l+vstem+eps=vround(y0-.25(h-x_height)); y2=.5[y1,y3];
+if y1r>y3r: y1r:=y3r:=y2; fi
+lft x4l=hround u; x4r-x4l=(hround .6[vair,stem])-fine;
+x6+.5u=x7=w-2u; x8=.5w+.75u;
+y6=-.1d; y8=-3/4d-oo; bot y7r=-d-oo;
+ellipse_set(3l,4l,5l,6l); ellipse_set(3r,4r,5r,6r);
+y4l:=.9[y6,y4l]; y4=y4r:=.9[y6,y4r];
+filldraw circ_stroke z0e{down}...z1e{right}...{up}z2e; % opening hook
+filldraw circ_stroke z8e{x7-x8,2(y7-y8)}...z7e{right}
+ ...z6e---z5e....{up}z4e
+ ..tension 1 and atleast1.5..{right}z3e...{down}z2e; % main stroke
+math_fit(-.2asc_height#*slant-.5u#,0);
+penlabels(0,1,2,3,4,5,6,7,8); endchar;
+
+cmchar "Lowercase Greek eta";
+beginchar(oct"147",9u#,x_height#,desc_depth#);
+italcorr .8x_height#*slant+.5stem#-u#;
+adjust_fit(0,0); pickup fine.nib;
+x0=0; x1=x2; pos2(stem,0); lft x2l=hround(2.5u-.5stem); y2-.5stem=-oo;
+hook_in(0,a,1); % opening hook
+filldraw circ_stroke z2e--z1e; % left stem
+x4+.5stem=hround(w-1.5u+.5stem); ital_arch(2,3,4); % arch
+pos5(stem,0); x5=x4; y5-.5stem=-d-o;
+filldraw circ_stroke z5e--z4e; % right stem
+math_fit(-2/3x_height#*slant+.5hair#+.5u#,ic#-1/3x_height#*slant);
+penlabels(0,a,1,2,3,4,5); endchar;
+
+cmchar "Lowercase Greek theta";
+beginchar(oct"150",8.25u#,asc_height#,0);
+italcorr .7asc_height#*slant+.5curve#-u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(vair,90); pos2(curve,180); pos3(vair,270); pos4(curve,360);
+x1=x3=.5w; lft x2r=hround(1.5u-.5curve); x4=w-x2;
+top y1r=h+oo; y2=y4=.5[y1,y3]; bot y3r=-oo;
+filldraw stroke pulled_arc.e(1,2) & pulled_arc.e(2,3)
+ & pulled_arc.e(3,4) & pulled_arc.e(4,1); % bowl
+pos2'(bar,90); pos4'(bar,90); z2'=z2l; z4'=z4l;
+filldraw stroke z2'e--z4'e; % bar
+math_fit(-.3asc_height#*slant-u#+.5curve#,ic#-.5u#);
+penlabels(1,2,3,4); endchar;
+
+cmchar "Lowercase Greek iota";
+beginchar(oct"151",5u#,x_height#,0);
+italcorr 1/3x_height#*slant+.5hair#+.5u#;
+adjust_fit(if monospace: u#,u# else: 0,0 fi); pickup fine.nib;
+pos1(stem,0); lft x1l=hround(1.5u-.5stem); y1+.5stem=h+oo;
+x2=x1-.25u; x4=w; hook_out(2,3,4)(skewed); % closing hook
+filldraw circ_stroke z1e{down}...{-u,-x_height}z2e; % stem
+math_fit(0,ic#); penlabels(1,2,3,4); endchar;
+
+cmchar "Lowercase Greek kappa";
+beginchar(oct"152",9u#,x_height#,0);
+italcorr 1/3x_height#*slant+.5hair#+.5u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(stem,0); pos2(stem,0); pos3(vair,90); pos4(vair,90); pos5(flare,90);
+x1=x2=x3; lft x1l=hround(1.5u-.5stem); y1+.5stem=h+oo; y2-.5stem=-oo;
+filldraw z1l---z2l..z2r---z1r..cycle; % stem
+y3=bar_height; top y4r=h; x4+.5flare=hround(w-1.5u); z5r=z4r;
+path p,q; p=z3l{right}..{right}z4l; q=z5r{right}..z5l{left}...cycle;
+numeric t; t=ypart(p intersectiontimes q);
+filldraw stroke z3e{right}..{right}z4e; % upper diagonal
+filldraw subpath(0,t) of q--cycle; % bulb
+pos7(stem,0); pos8(vair,90); pos9(hair,180);
+x9+.5hair=hround(w+.5hair-epsilon); y9=1/3x_height;
+lft x7l=hround(w-2.75u-.5stem); y7=1/2y3; x8=w-1.2u; bot y8l=-oo;
+filldraw stroke z3e{right}...z7e{down}
+ ...z8e{right}...{up}z9e; % lower diagonal
+math_fit(0,ic#); penlabels(1,2,3,4,5,7,8,9); endchar;
+
+cmchar "Lowercase Greek lambda";
+beginchar(oct"153",10.5u#,asc_height#,0);
+adjust_fit(0,0); pickup fine.nib;
+pos1(vair,90); lft x1=hround .1u; top y1r=h;
+x2=x1+2u; y2=.7[x_height,h]; x3=w-2u; bot y4=-oo; y3=max(.07h,y4+eps);
+z4-(.25u,0)=whatever[z2,z3]; numeric theta; theta=angle(z2-z3)-90;
+pos2(stem,theta); pos3(stem,theta); pos4(stem,0);
+filldraw circ_stroke z1e{right}...z2e---z3e
+ ...{2(x4e-x3e),y4e-y3e}z4e; % long diagonal
+y5=.5[bar_height,x_height]; z5=whatever[z2,z3];
+x6=1.5u; y6-.5stem=-oo; pos5(hair,theta-90); pos6(stem,angle(z5-z6)-90);
+filldraw circ_stroke z6e--z5e; % short diagonal
+penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Lowercase Greek mu";
+beginchar(oct"154",9u#,x_height#,desc_depth#);
+italcorr 1/3x_height#*slant+.5hair#+.5u#;
+adjust_fit(0,0); pickup fine.nib; interim superness:=more_super;
+pos1(stem,-180); pos2(stem,-180); x1=x2=x3; lft x1r=hround(1.5u-.5stem);
+y1+.5stem=h+oo; y2-.5stem=-d-o;
+filldraw z1r---z2r..z2l---z1l..cycle; % left stem
+pos3(stem,-180); pos4(vair,-90); pos5(hair,0); x4=.5[x3,x5];
+pos6(stem,0); rt x6r=hround(w-2.5u+.5stem);
+x5=x6=x7; x9=w; hook_out(7,8,9); % closing hook
+y3=.7[y4,y5]; bot y4r=-oo; y5=.57h; y6+.5stem=h;
+filldraw stroke super_arc.e(3,4)...{up}z5e; % left stem and arc
+filldraw circ_stroke z6e--z7e; % right stem
+math_fit(desc_depth#*slant+.5stem#-u#,ic#);
+penlabels(1,2,3,4,5,6,7,8,9); endchar;
+
+cmchar "Lowercase Greek nu";
+beginchar(oct"155",8.5u#,x_height#,0);
+italcorr x_height#*slant+.5stem#-u#;
+adjust_fit(0,0); pickup fine.nib;
+pos3(vair,-90); pos4(stem,0); bot y3r=0; y4+.5stem=h+oo;
+x3-.5stem=hround(1.5u-.5stem); x4+.5stem=hround(w-1.5u+.5stem);
+filldraw circ_stroke z4e{down}...{-36u,-h}z3e; % diagonal
+pickup tiny.nib; pos1(stem,0); pos2(stem,0);
+top y1=h+min(oo,serif_drop); bot y2=0; x1=x2=x3;
+z=((z4{down}...{-36u,-h}z3)intersectionpoint((x2r,0)--(x2r,h)));
+filldraw z1l--z2l--z--z1r--cycle; % stem
+sloped_serif.l(1,2,a,1/3,jut,serif_drop); % upper left serif
+math_fit(0,ic#-1/3x_height#*slant-.5u#); penlabels(1,2,3,4); endchar;
+
+cmchar "Lowercase Greek xi";
+beginchar(oct"156",9u#,asc_height#,desc_depth#);
+italcorr .75[x_height#,asc_height#]*slant-2u#;
+adjust_fit(0,0); pickup fine.nib;
+pos10(hair,-720); pos11(vair,-630); pos12(hair,-540); pos13(vair,-450);
+lft x10l=hround 1/3w; x11=x13=.5[x10,x12]; rt x12l=hround(w-2.5u);
+top y10=h; top y13l=bot y11l+vstem+eps=vround(y10-.25(h-x_height));
+y12=.5[y11,y13]; if y11r>y13r: y11r:=y13r:=y12; fi
+pos0(curve,-360); pos1(vair,-270); pos2(hair,-180); pos3(vair,-90);
+numeric theta; theta=90-angle(22u,x_height); slope:=-x_height/22u;
+pos6(stem,theta); pos7(vair,-90); pos8(vair,-135);
+lft x0l=hround u; x1=x3=x11; x2=x12;
+y0=.5[y13,y1]; top y3l=vround .5h=bot y1l+vstem+eps; y2=.5[y1,y3];
+if y1r>y3r: y1r:=y3r:=y2; fi
+lft x4l=hround u; x4r-x4l=hround .5[vair,stem]-fine;
+x6=x7=w-2u; x8=.5w+.5u; y6=-.3d; y8=-3/4d-oo; bot y7r=-d-oo;
+ellipse_set(3l,4l,5l,6l); ellipse_set(3r,4r,5r,6r);
+y4l:=.9[y6,y4l]; y4=y4r:=.9[y6,y4r];
+filldraw circ_stroke z10e{down}...z11e{right}...{up}z12e; % opening hook
+filldraw stroke z12e{up}...z13e{left}...z0e{down}
+ ...z1e{right}...{up}z2e; % upper arc
+filldraw circ_stroke z8e{x7-x8,2(y7-y8)}...z7e{right}...z6e
+ ---z5e...{up}z4e...{right}z3e...{down}z2e; % main stroke
+math_fit(-.2asc_height#*slant-.5u#,0);
+penlabels(0,1,2,3,4,5,6,7,8,10,11,12,13); endchar;
+
+% Stolen from romanl.mf
+cmchar "Lowercase Greek omicron";
+beginchar(oct"157",9u#,x_height#,0);
+italcorr .7x_height#*slant;
+adjust_fit(if monospace: .5u#,.5u# else: 0,0 fi);
+penpos1(vair,90); penpos3(vair',-90);
+penpos2(curve,180); penpos4(curve,0);
+x2r=hround max(.5u,1.25u-.5curve);
+x4r=w-x2r; x1=x3=.5w; y1r=h+vround 1.5oo; y3r=-oo;
+y2=y4=.5h-vair_corr; y2l:=y4l:=.52h;
+penstroke pulled_arc.e(1,2) & pulled_arc.e(2,3)
+ & pulled_arc.e(3,4) & pulled_arc.e(4,1) & cycle; % bowl
+penlabels(1,2,3,4); endchar;
+
+cmchar "Lowercase Greek pi";
+beginchar(oct"160",10u#,x_height#,0);
+italcorr x_height#*slant+.5stem#-u#;
+adjust_fit(0,0); pi_stroke; % hook and bar
+pos4(hair,0); pos6(hair,0); x4=3.5u; x6=w-4u; y4=y6=y2;
+x5=3u; x7=w-2.5u; y5=y7=.5stem-oo;
+pair v[]; v1=(z4-z5) xscaled 3.14159; v2=(z6-z7) xscaled 3.14159;
+pos5(stem,angle v1-90); pos7(stem,angle v2-90);
+filldraw circ_stroke z5e{v1}...{up}z4e; % left stem
+filldraw circ_stroke z7e{v2}...{up}z6e; % right stem
+math_fit(-.7x_height#*slant+.5hair#+.5u#,ic#-1/3x_height#*slant);
+penlabels(1,2,3,4,5,6,7); endchar;
+
+cmchar "Lowercase Greek rho";
+beginchar(oct"161",8.25u#,x_height#,desc_depth#);
+italcorr .7x_height#*slant+.5curve#-u# if math_fitting:-.5u# fi;
+adjust_fit(0,0); pickup fine.nib;
+pos1(stem,180); pos2(stem,180); pos3(vair,90);
+pos4(curve,0); pos5(vair,-90); pos6(hair,-180);
+lft x2r=hround(1.5u-.5stem); x1=x2=x6; x3=x5=.5[x2,x4];
+rt x4r=hround(w-1.5u+.5curve);
+y1-.5stem=-d-o; y2=y4=y6=.5[y3,y5]; top y3r=h+oo; bot y5r=-oo;
+filldraw circ_stroke z1e..pulled_arc.e(2,3) & pulled_arc.e(3,4)
+ & pulled_arc.e(4,5) & pulled_arc.e(5,6); % stem and bowl
+math_fit(desc_depth#*slant+.5stem#-u#,ic#);
+penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Lowercase Greek sigma";
+beginchar(oct"162",10.25u#,x_height#,0);
+italcorr x_height#*slant+.5stem#-u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(vstem,90); pos2(stem,0); pos3(vair,-90);
+pos4(stem,-180); pos5(vstem,-270); pos6(vstem,-270);
+x1=x3=x5=.5[x2,x4]; rt x2r=hround(w-2.5u);
+lft x4r=hround(1.5u-.5curve);x6=w-1.5u;
+top y1r=h; y2=y4=.5[y1,y3]; bot y3r=-oo; y5=y6=y1;
+filldraw circ_stroke z6e..pulled_arc.e(5,4) & pulled_arc.e(4,3)
+ & pulled_arc.e(3,2) & pulled_arc.e(2,1); % ear and bowl
+math_fit(-.3x_height#*slant+.5curve#-u#,ic#-1/3x_height#*slant);
+penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Lowercase Greek tau";
+beginchar(oct"163",9u#,x_height#,0);
+italcorr x_height#*slant+.5stem#-u#;
+adjust_fit(0,0); pi_stroke; % hook and bar
+pos4(hair,0); pos5(stem,0);
+x4=x5; x5-.5stem=hround(.5w-.5u-.5stem); y4=y2; y5-.5stem=-oo;
+filldraw circ_stroke z5e--z4e; % stem
+math_fit(-.7x_height#*slant+.5hair#+.5u#,-.5u#);
+penlabels(1,2,3,4,5); endchar;
+
+cmchar "Lowercase Greek upsilon";
+beginchar(oct"164",9u#,x_height#,0);
+italcorr x_height#*slant;
+adjust_fit(0,0); pickup fine.nib; interim superness:=more_super;
+x0=0; x2=x3+.25u; pos3(stem,-180); lft x3r=hround(2.5u-.5stem);
+hook_in(0,1,2)(skewed); % opening hook
+pos2'(stem,-180); z2'=z2; pos4(vair,-90); pos5(hair,0);
+x4=.5w+u; rt x5r=hround(w-.5u); y3=.7[y4,y5]; bot y4r=-oo; y5=.57h;
+filldraw stroke z2'e{-u,-x_height}...super_arc.e(3,4)
+ ..tension atleast 1.05..{up}z5e; % left stem and arc
+v_bulb(5,6); % closing bulb
+math_fit(-2/3x_height#*slant+.5hair#+.5u#,2/3ic#);
+penlabels(0,1,2,3,4,5,6); endchar;
+
+cmchar "Lowercase Greek phi";
+beginchar(oct"165",11u#,asc_height#,desc_depth#);
+italcorr .7x_height#*slant+.5curve#-u# if math_fitting:-.5u# fi;
+adjust_fit(0,0); pickup fine.nib;
+numeric light_curve; light_curve=hround(.5[stem,curve]-2stem_corr);
+pos1(vair,90); pos2(light_curve,180); pos3(vair,270); pos4(light_curve,360);
+x1=x3=.5w; lft x2r=hround(1.5u-.5light_curve); x4=w-x2;
+top y1=x_height+oo; y2=y4=.5[y1,y3]; bot y3=-oo;
+filldraw stroke pulled_arc.e(1,2) & pulled_arc.e(2,3)
+ & pulled_arc.e(3,4) & pulled_arc.e(4,1); % bowl
+pos5(hair,0); pos6(hair,0); x5=x6=.5w; top y5=h; bot y6=-d-oo;
+filldraw stroke z5e--z6e; % stem
+math_fit(-.3x_height#*slant+.5curve#-u#,ic#);
+penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Lowercase Greek chi";
+beginchar(oct"166",11u#,x_height#,desc_depth#);
+italcorr x_height#*slant+.5hair#-1.5u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(hair,180); pos2(vair,80); pos5(vair,80); pos6(hair,180);
+x1-.5hair=hround-.5hair; x6=w-x1; x2=w-x5=u;
+y1=y2l-h/8; top y2r=h+oo; bot y5l=-d-oo; y6=y5r+h/8;
+z0=.5[z2,z5]; z2'=z2l+(.5u,0); z5'=z5r-(.5u,0);
+numeric theta; theta=angle(z5'-z2')+90;
+pos3(stem,theta); pos4(stem,theta);
+y3r=y2r-h/8; y4l=y5l+h/8; z3l=whatever[z2',z0]; z4r=whatever[z0,z5'];
+filldraw stroke z1e{up}...z2e{right}...z3e{z4r-z3l}
+ ..z4e{z4r-z3l}...{right}z5e...{up}z6e; % major diagonal and hooks
+x8=w-x7=2u; y7+.5hair=h; y8-.5hair=-d;
+numeric theta; theta=angle(z7-z8)-90;
+pos7(hair,theta); pos8(hair,theta);
+filldraw z7l---z8l..z8r---z7r..cycle; % minor diagonal
+math_fit((desc_depth#-x_height#)*slant+ic#,ic#);
+penlabels(0,1,2,2',3,4,5',5,6,7,8); endchar;
+
+cmchar "Lowercase Greek psi";
+beginchar(oct"167",11u#,asc_height#,desc_depth#);
+italcorr x_height#*slant;
+adjust_fit(0,0); pickup fine.nib; interim superness:=more_super;
+x0=0; x2=x3+.25u; pos3(stem,-180); lft x3r=hround(2.5u-.5stem);
+hook_in(0,1,2)(skewed); % opening hook
+pos2'(stem,-180); z2'=z2; pos4(vair,-90); pos5(hair,0);
+x4=.5w+u; rt x5r=hround(w-.5u);
+y3=.7[y4,y5]; bot y4r=-oo; y5=.57x_height;
+filldraw stroke z2'e{-u,-x_height}...super_arc.e(3,4)
+ ..tension atleast 1.05..{up}z5e; % left stem and arc
+v_bulb(5,6); % closing bulb
+pos7(hair,0); pos8(hair,0); x7=x8=.5w+.5u; top y7=h; bot y8=-d-oo;
+filldraw stroke z7e--z8e; % stem
+math_fit(-2/3x_height#*slant+.5hair#+.5u#,2/3ic#);
+penlabels(0,1,2,3,4,5,6,7,8); endchar;
+
+cmchar "Lowercase Greek omega";
+beginchar(oct"170",11u#,x_height#,0);
+italcorr x_height#*slant;
+adjust_fit(0,0); pickup fine.nib;
+pos2(hair,-180); lft x2r=hround.5u; y2=y4=y6=y8=bar_height;
+y1+.5hair=h; x1=x2+.75u; pos1(hair,angle(2(x1-x2),y1-y2)+90);
+pos3(vstem+dw,-90); pos4(hair,0); pos5(vair,90);
+pos6(hair,180); pos7(vstem+dw,270); pos8(hair,360);
+bot y3r=bot y7r=-oo; top y5r=vround(.2[y4,h]+.5vair);
+x3=.5[x2,x4]; x7+.25u=.5[x6,x8]; rt x8r=hround(w-.5u);
+x5+.5stem=hround(.5w+.5stem)+eps;
+x5=.5[x4,x6]; rt x4r-lft x6r=min(stem,2hair)+2eps;
+if x4l<x6l: x4l:=x6l:=x5; fi
+filldraw circ_stroke z1e{2(x2-x1),y2-y1}...z2e{down}...z3e{right}
+ ...{up}z4e...{left}z5e; % left arc
+filldraw stroke z5e{left}...z6e{down}...z7e{right}...{up}z8e; % right arc
+v_bulb(8,9); % closing bulb
+math_fit(-bar_height#*slant,2/3ic#); penlabels(1,2,3,4,5,6,7,8,9); endchar;
+
+cmchar "Variant lowercase Greek sigma";
+beginchar(oct"014",8u#,x_height#,.5min(desc_depth#,.5x_height#));
+italcorr x_height#*slant-.5u#;
+adjust_fit(0,0); pickup fine.nib;
+numeric heavy_vair; heavy_vair=.25[vair,vstem];
+pos1(heavy_vair,-110); pos2(vair,-90);
+x1+.5heavy_vair=hround(w-u); y1=.1[y2r,bar_height];
+x2=min(.5w+u,x1r-eps); top y2l=h+oo;
+filldraw circ_stroke z1e{x2-x1,2(y2-y1)}...{left}z2e; % upper bulb
+numeric theta; theta=90-angle(16u,x_height); slope:=-x_height/16u;
+pos6(stem,theta); pos7(vair,-90); pos8(vair,-135);
+lft x4l=hround u; x4r-x4l=(hround .5[vair,stem])-fine;
+x6=x7=w-2u; x8=.5w+u; y6=.25[y8,y2]; y8=y7+1/8d; bot y7r=-d-oo;
+ellipse_set(2l,4l,5l,6l); ellipse_set(2r,4r,5r,6r); y4=y4r;
+filldraw circ_stroke z8e{x7-x8,2(y7-y8)}...z7e{right}...z6e
+ ---z5e...{up}z4e...{right}z2e; % main stroke
+math_fit(-.5x_height#*slant-.5u#,0); penlabels(1,2,4,5,6,7,8); endchar;
+
diff --git a/dviware/quicspool/wwfonts/tgreeku.mf b/dviware/quicspool/wwfonts/tgreeku.mf
new file mode 100644
index 0000000000..328b2f2906
--- /dev/null
+++ b/dviware/quicspool/wwfonts/tgreeku.mf
@@ -0,0 +1,611 @@
+% $Header: tgreeku.mf,v 1.1 88/01/15 13:14:50 simpson Rel $
+% $Log: tgreeku.mf,v $
+%Revision 1.1 88/01/15 13:14:50 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:28 simpson
+%beta test
+%
+% Computer Modern Greek caps, analogous to the uppercase Roman letters.
+
+cmchar "Uppercase Greek Gamma";
+beginchar(oct"103",11u#-width_adj#,cap_height#,0);
+italcorr cap_height#*slant-beak_jut#-.25u#;
+adjust_fit(cap_serif_fit#,0);
+h:=vround(h-stem_corr);
+pickup tiny.nib; pos1(cap_stem,0); pos2(cap_stem,0);
+lft x1l=lft x2l=hround max(2u,3u-.5cap_stem); top y1=h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+pickup crisp.nib; pos3(slab,90); pos4(hair,0);
+top y3r=h; x3=x1; rt x4r=hround(w-.75u); y4=good.y(y3l-beak)-eps;
+arm(3,4,e,beak_darkness,beak_jut); % arm and beak
+if serifs: dish_serif(1,2,a,1/3,cap_jut,b,1/3,.5cap_jut); % upper serif
+ dish_serif(2,1,c,1/3,cap_jut,d,1/3,1.25cap_jut); fi % lower serif
+math_fit(0,ic#-2.5u#); penlabels(1,2,3,4); endchar;
+
+cmchar "Uppercase Greek Delta";
+beginchar(oct"104",15u#,cap_height#,0);
+adjust_fit(0,0);
+numeric left_stem,alpha;
+left_stem=cap_hair if hefty: -3stem_corr fi;
+x1l=w-x4r=.75u; y1=y4=0;
+x2-x1=x4-x3; x3r=x2r+apex_corr; y2=y3=h+apex_o+apex_oo;
+alpha=diag_ratio(2,left_stem,y2-y1,x4r-x1l-apex_corr);
+penpos1(alpha*left_stem,0); penpos2(alpha*left_stem,0);
+penpos3(alpha*cap_stem,0); penpos4(alpha*cap_stem,0);
+fill diag_end(2l,1l,1,1,4r,3r)--diag_end(4r,3r,1,1,2l,1l)--cycle; % triangle
+z0=whatever[z1r,z2r]=whatever[z3l,z4l];
+y5=y6=cap_vstem; z5=whatever[z1r,z2r]; z6=whatever[z3l,z4l];
+if y0<h-cap_notch_cut: y0:=h-cap_notch_cut;
+ unfill z0+.5right{down}...{z4-z3}z6--z5{z2-z1}
+ ...{up}z0+.5left--cycle; % counter
+else: unfill z0--z5--z6--cycle; fi % counter
+penlabels(0,1,2,3,4,5,6); endchar;
+
+cmchar "Uppercase Greek Theta";
+beginchar(oct"110",14u#,cap_height#,0);
+italcorr .7cap_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric light_curve; light_curve=hround(cap_curve-2stem_corr);
+penpos1(vair,90); penpos3(vround(vair+.5vair_corr),-90);
+penpos2(light_curve,180); penpos4(light_curve,0);
+if monospace: x2r=hround 1.5u;
+ interim superness:=sqrt superness; % make |"O"|, not |"0"|
+else: x2r=hround u; fi
+x4r=w-x2r; x1=x3=.5w; y1r=h+o; y2=y4=.5h-vair_corr; y3r=-o;
+penstroke pulled_super_arc.e(1,2)(.5superpull)
+ & pulled_super_arc.e(2,3)(.5superpull)
+ & pulled_super_arc.e(3,4)(.5superpull)
+ & pulled_super_arc.e(4,1)(.5superpull) & cycle; % bowl
+pickup crisp.nib; pos5(cap_vstem,90); pos6(cap_vstem,90);
+lft x5=w-rt x6=hround(x2l+u)+1; y5=y6=.5[y1l,y3l];
+filldraw stroke z5e--z6e; % bar
+if serifs: pos7(hair,0); pos8(hair,0); pos9(hair,0); pos10(hair,0);
+ x7l=x8l=x5; x9r=x10r=x6;
+ y7-y5r=y9-y6r=y5l-y8=y6l-y10=vround .05h;
+ filldraw stroke z7e--z8e; % left serif
+ filldraw stroke z9e--z10e; fi % right serif
+math_fit(-.3cap_height#*slant-.5u#,ic#-.5u#);
+penlabels(1,2,3,4,5,6,7,8,9,10); endchar;
+
+cmchar "Uppercase Greek Lambda";
+beginchar(oct"113",12u#,cap_height#,0);
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+numeric left_stem,outer_jut,alpha;
+left_stem=cap_hair if hefty: -3stem_corr fi;
+outer_jut=.7cap_jut; x1l=w-x4r=l+letter_fit+outer_jut+.5u; y1=y4=0;
+x2-x1=x4-x3; x3r=x2r+apex_corr; y2=y3=h+apex_o+apex_oo;
+alpha=diag_ratio(2,left_stem,y2-y1,x4r-x1l-apex_corr);
+penpos1(alpha*left_stem,0); penpos2(alpha*left_stem,0);
+penpos3(alpha*cap_stem,0); penpos4(alpha*cap_stem,0);
+z0=whatever[z1r,z2r]=whatever[z3l,z4l];
+if y0<h-cap_notch_cut: y0:=h-cap_notch_cut;
+ fill z0+.5right{down}...{z4-z3}diag_end(3l,4l,1,1,4r,3r)
+ --diag_end(4r,3r,1,1,2l,1l)--diag_end(2l,1l,1,1,1r,2r){z2-z1}
+ ...{up}z0+.5left--cycle; % left and right diagonals
+else: fill z0--diag_end(0,4l,1,1,4r,3r)--diag_end(4r,3r,1,1,2l,1l)
+ --diag_end(2l,1l,1,1,1r,0)--cycle; fi % left and right diagonals
+if serifs: numeric inner_jut; pickup tiny.nib;
+ prime_points_inside(1,2); prime_points_inside(4,3);
+ if rt x1'r+cap_jut+.5u+1<=lft x4'l-cap_jut: inner_jut=cap_jut;
+ else: rt x1'r+inner_jut+.5u+1=lft x4'l-inner_jut; fi
+ dish_serif(1',2,a,1/2,outer_jut,b,.6,inner_jut)(dark); % left serif
+ dish_serif(4',3,c,1/2,inner_jut,d,1/3,outer_jut); fi % right serif
+penlabels(0,1,2,3,4,5,6); endchar;
+
+cmchar "Uppercase Greek Xi";
+beginchar(oct"116",12u#,cap_height#,0);
+italcorr cap_height#*slant-.35u#;
+adjust_fit(0,0);
+h:=vround(h-2stem_corr);
+numeric shaved_stem; shaved_stem=hround .9[vair,.85cap_stem];
+pickup crisp.nib; pos1(shaved_stem,90); pos2(hair,0);
+top y1r=h; x1=.5w; rt x2r=hround(w-.85u); y2=good.y(y1l-4/9beak)-eps;
+arm(1,2,a,.4beak_darkness,.3beak_jut); % upper right arm and beak
+pos3(hair,180); x3=w-x2; y3=y2;
+arm(1,3,b,.4beak_darkness,-.3beak_jut); % upper left arm and beak
+pos4(shaved_stem,-90); pos5(hair,0);
+bot y4r=0; x4=.5w; rt x5r=hround(w-.75u); y5=good.y(y4l+.5beak)+eps;
+arm(4,5,c,.4beak_darkness,.3beak_jut); % lower right arm and beak
+pos6(hair,180); x6=w-x5; y6=y5;
+arm(4,6,d,.4beak_darkness,-.3beak_jut); % lower left arm and beak
+pos7(shaved_stem,90); pos8(shaved_stem,90);
+lft x7=w-rt x8=hround if serifs: 2.5 else: 2 fi\\ u;
+top y7r=top y8r=vround(.52h+.5shaved_stem);
+filldraw stroke z7e--z8e; % middle bar
+if serifs: numeric xjut;
+ if bot y2>top y7r+.75cap_jut: xjut=.5cap_jut;
+ else: bot y2=top y7r+1.5xjut; fi
+ pos11(hair,0); pos12(hair,0); y11=y12;
+ pos13(hair,0); pos14(hair,0); y13=y14;
+ lft x11l=lft x13l=w-rt x12r=w-rt x14r=hround 2.5u;
+ top y11-bot y13=shaved_stem+2xjut; .5[y11,y13]=y7;
+ filldraw stroke z11e--z13e; filldraw stroke z12e--z14e; fi % middle serifs
+math_fit(0,.5ic#); penlabels(1,2,3,4,5,6,7,8,11,12,13,14); endchar;
+
+cmchar "Uppercase Greek Pi";
+beginchar(oct"120",13u#+width_adj#,cap_height#,0);
+italcorr cap_height#*slant-cap_serif_fit#+cap_jut#-2.5u#+min(.5cap_stem#,u#);
+adjust_fit(cap_serif_fit#,cap_serif_fit#); pickup tiny.nib;
+h:=vround(h-stem_corr);
+pos1(cap_stem,0); pos2(cap_stem,0); pos3(cap_stem,0); pos4(cap_stem,0);
+lft x1l=lft x2l=hround max(2u,3u-.5cap_stem); x3=x4=w-x1;
+top y1=top y3=h; bot y2=bot y4=0;
+filldraw stroke z1e--z2e; % left stem
+filldraw stroke z3e--z4e; % right stem
+penpos5(cap_bar,90); penpos6(cap_bar,90);
+x5=x1; x6=x3; y5r=y6r=h;
+fill stroke z5e--z6e; % bar
+if serifs: numeric inner_jut;
+ if rt x1r+cap_jut+.5u+1<=lft x3l-cap_jut: inner_jut=cap_jut;
+ else: rt x1r+inner_jut+.5u+1=lft x3l-inner_jut; fi
+ dish_serif(1,2,a,1/3,cap_jut,b,1/3,eps); % upper left serif
+ dish_serif(2,1,c,1/3,cap_jut,d,1/3,inner_jut); % lower left serif
+ dish_serif(3,4,e,1/3,eps,f,1/3,cap_jut); % upper left serif
+ dish_serif(4,3,g,1/3,inner_jut,h,1/3,cap_jut); fi % lower left serif
+math_fit(0,.5ic#); penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Uppercase Greek Sigma";
+beginchar(oct"122",13u#,cap_height#,0);
+italcorr cap_height#*slant-beak_jut#-.5u#;
+adjust_fit(0,0);
+numeric bot_arm_thickness;
+bot_arm_thickness=Vround .25[slab,cap_vstem];
+pickup tiny.nib; lft x1l=hround u; x1l=x2l=x4l;
+top y1=h; bot y2=h-slab; bot y4=0; x3l-x1l=4/11(w-2u); y3=.5h;
+numeric alpha[]; alpha1=((x3l-x1l)++(y2-y3))/(y2-y3);
+penpos1(alpha1*(cap_stem-tiny),0); penpos2(alpha1*(cap_stem-tiny),0);
+penpos3(alpha1*(cap_stem-tiny),0);
+alpha2=diag_ratio(1,cap_hair-tiny,y3-y4,x3r-x4l);
+penpos4(alpha2*(cap_hair-tiny),0);
+z0=whatever[z2l,z3l]=z4l+whatever*(z3r-z4r);
+filldraw z1l--z2l--z0--z4l--z4r--z3r--z2r--z1r--cycle; % diagonals
+pickup crisp.nib; pos5(slab,90); pos6(hair,0);
+top y5r=h; x5=x1; rt x6r=hround(w-u); y6=good.y(y5l-beak)-eps;
+arm(5,6,a,beak_darkness,beak_jut); % upper arm and beak
+pos7(bot_arm_thickness,-90); pos8(hair,0);
+bot y7r=0; z7l=whatever[z4,z3]; x7r:=x4; x8=x6; y8=good.y(y7l+beak)+eps;
+arm(7,8,b,beak_darkness,beak_jut); % lower arm and beak
+math_fit(0,.5ic#); penlabels(0,1,2,3,4,5,6,7,8); endchar;
+
+cmchar "Uppercase Greek Upsilon";
+beginchar(oct"124",14u#,cap_height#,0);
+italcorr .8cap_height#*slant-.5u#;
+adjust_fit(0,0);
+pickup tiny.nib; pos1(cap_stem,0); pos2(cap_stem,0);
+lft x1l=lft x2l=hround(.5w-.5cap_stem); y1=.5h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+penpos3(.6cap_stem,0); penpos4(.75cap_curve,90); penpos5(cap_hair,180);
+z3l=lft z1l; x5r=hround u; y5=bot .8h; x4=.61803[x3l,x5l]; y4r=h+o;
+penpos5'(cap_hair,180); x5'=x5; y5'=h;
+fill z3r{up}...z4r{left}...{down}diag_end(5'r,5r,1,1,5l,5'l){up}
+ ...{right}z4l...{down}z3l--cycle; % left arc
+penpos6(.6cap_stem,0); penpos7(.75cap_curve,-90); penpos8(cap_hair,-180);
+z6r=rt z1r; x8=w-x5; y8=y5; x7=w-x4; y7=y4;
+penpos8'(cap_hair,-180); x8'=x8; y8'=h;
+fill z6r{up}...z7r{right}...{down}diag_end(8'r,8r,1,1,8l,8'l){up}
+ ...{left}z7l...{down}z6l--cycle; % right arc
+if serifs: dish_serif(2,1,a,1/3,1.25cap_jut,b,1/3,1.25cap_jut); fi % serif
+math_fit(-.8cap_height#*slant-.5u#,ic#-2.5u#);
+penlabels(1,2,3,4,5,6,7,8); endchar;
+
+cmchar "Uppercase Greek Phi";
+beginchar(oct"125",13u#,cap_height#,0);
+italcorr .5cap_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric shaved_stem,light_curve;
+shaved_stem=cap_stem-hround 2stem_corr;
+light_curve=cap_curve-hround stem_corr;
+pickup tiny.nib; pos1(shaved_stem,0); pos2(shaved_stem,0);
+lft x1l=lft x2l=hround(.5w-.5cap_stem); top y1=h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+penpos3(vair,90); penpos5(vair,-90);
+penpos4(light_curve,180); penpos6(light_curve,0);
+x4r=hround u; x6r=w-x4r; x3=x5=.5w;
+y3r=vround(.85h if serifs:-slab fi); y4=y6=.5[y3,y5];
+y5r=vround(.15h if serifs:+slab fi);
+penstroke pulled_arc.e(3,4) & pulled_arc.e(4,5)
+ & pulled_arc.e(5,6) & pulled_arc.e(6,3) & cycle; % bowl
+if serifs: dish_serif(1,2,a,1/3,1.25cap_jut,b,1/3,1.25cap_jut); % upper serif
+ dish_serif(2,1,c,1/3,1.25cap_jut,d,1/3,1.25cap_jut); fi % lower serif
+math_fit(-.5cap_height#*slant-.5u#,ic#); penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Uppercase Greek Psi";
+beginchar(oct"127",14u#,cap_height#,0);
+italcorr .8cap_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric shaved_stem;
+shaved_stem=cap_stem-hround 2stem_corr;
+pickup tiny.nib; pos1(shaved_stem,0); pos2(shaved_stem,0);
+lft x1l=lft x2l=hround(.5w-.5cap_stem); top y1=h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+pos3(shaved_stem,-180); pos4(shaved_stem,-180);
+pos5(vair,-90); x5=x1; bot y5r=vround(.15h if serifs:+slab fi);
+pos6(shaved_stem,0); pos7(shaved_stem,0);
+lft x3r=hround u; x7=w-x3; lft x4r=hround(3u-.5shaved_stem); x6=w-x4;
+pos3'(vair,90); pos7'(vair,90); z3'r=z3r; z7'r=z7r;
+y3=y7; y4=y6=.6h; y3=good.y(y3+.84h if serifs:-slab fi-y3');
+interim superness:=more_super;
+filldraw z3'l{right}...z4r{down} & super_arc.r(4,5)
+ & super_arc.r(5,6) & z6r{up}...z7'l{right}
+ --z7r---z7l...z6l{down} & super_arc.l(6,5)
+ & super_arc.l(5,4) & z4l{up}...z3l---z3r--cycle; % stroke
+if serifs: dish_serif(1,2,a,1/3,1.25cap_jut,b,1/3,1.25cap_jut); % upper serif
+ dish_serif(2,1,c,1/3,1.25cap_jut,d,1/3,1.25cap_jut); fi % lower serif
+math_fit(-.8cap_height#*slant-.5u#,.4cap_height#*slant-1.25u#);
+penlabels(1,2,3,4,5,6,7); endchar;
+
+cmchar "Uppercase Greek Omega";
+beginchar(oct"130",13u#,cap_height#,0);
+italcorr .75cap_height#*slant-.5u#;
+adjust_fit(0,0);
+pickup tiny.nib; pos1(vair,90); pos2(cap_curve,180);
+pos3(vair,180); pos4(cap_curve,0); pos5(vair,0);
+x1=.5w; top y1r=h+o; lft x2r=hround u; y2=y4=2/3h; x4=w-x2;
+rt x3l=hround(1/3(w+.5u)+.5hair); bot y3=bot y5=0; x5=w-x3;
+filldraw stroke z3e{up}...{up}z2e
+ & pulled_super_arc.e(2,1)(.5superpull)
+ & pulled_super_arc.e(1,4)(.5superpull)
+ & z4e{down}...{down}z5e; % bowl
+numeric arm_thickness; path p; p=z3{up}...{up}z2;
+arm_thickness=Vround(if hefty:slab+2stem_corr else:.75[slab,cap_vstem] fi);
+pickup crisp.nib; pos6(arm_thickness,-90); pos7(fudged.hair,-180);
+bot y6r=0; x6=x3; lft x7r=hround .8u; y7=good.y(y6l+.5beak)+eps;
+(x,y)=p intersectionpoint((0,y6l)--(w,y6l)); x6l:=x;
+arm(6,7,a,.5beak_darkness,-1.2beak_jut); % left arm and beak
+pos8(arm_thickness,-90); pos9(fudged.hair,0);
+y8=y6; y9=y7; x8+x6=x9+x7=w; x8l:=w-x6l;
+arm(8,9,b,.5beak_darkness,1.2beak_jut); % right arm and beak
+math_fit(0,.5ic#); penlabels(1,2,3,4,5,6,7,8,9); endchar;
+
+% The following letters are stolen from cmr10
+cmchar "Uppercase Greek Alpha";
+beginchar(oct"101",13u#,cap_height#,0);
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+numeric left_stem,right_stem,outer_jut,alpha;
+right_stem=cap_stem-stem_corr;
+left_stem=min(cap_hair if hefty: -3stem_corr fi,right_stem);
+outer_jut=.8cap_jut; x1l=w-x4r=l+letter_fit+outer_jut+.5u; y1=y4=0;
+x2-x1=x4-x3; x3r=x2r+apex_corr; y2=y3=h+apex_o+apex_oo;
+alpha=diag_ratio(2,left_stem,y2-y1,x4r-x1l-apex_corr);
+penpos1(alpha*left_stem,0); penpos2(alpha*left_stem,0);
+penpos3(alpha*right_stem,0); penpos4(alpha*right_stem,0);
+z0=whatever[z1r,z2r]=whatever[z3l,z4l];
+if y0<h-cap_notch_cut: y0:=h-cap_notch_cut;
+ fill z0+.5right{down}...{z4-z3}diag_end(3l,4l,1,1,4r,3r)
+ --diag_end(4r,3r,1,1,2l,1l)--diag_end(2l,1l,1,1,1r,2r){z2-z1}
+ ...{up}z0+.5left--cycle; % left and right diagonals
+else: fill z0--diag_end(0,4l,1,1,4r,3r)--diag_end(4r,3r,1,1,2l,1l)
+ --diag_end(2l,1l,1,1,1r,0)--cycle; fi % left and right diagonals
+penpos5(whatever,angle(z2-z1)); z5=whatever[z1,z2];
+penpos6(whatever,angle(z3-z4)); z6=whatever[z3,z4]; y6=y5;
+if hefty: y5r else: y5 fi =5/12y0;
+y5r-y5l=y6r-y6l=cap_band; penstroke z5e--z6e; % bar line
+if serifs: numeric inner_jut; pickup tiny.nib;
+ prime_points_inside(1,2); prime_points_inside(4,3);
+ if rt x1'r+cap_jut+.5u+1<=lft x4'l-cap_jut: inner_jut=cap_jut;
+ else: rt x1'r+inner_jut+.5u+1=lft x4'l-inner_jut; fi
+ dish_serif(1',2,a,1/2,outer_jut,b,.6,inner_jut)(dark); % left serif
+ dish_serif(4',3,c,1/2,inner_jut,d,1/3,outer_jut); fi % right serif
+penlabels(0,1,2,3,4,5,6); endchar;
+
+cmchar "Uppercase Greek Beta";
+beginchar(oct"102",12.5u#,cap_height#,0);
+italcorr .75cap_height#*slant-.5u#;
+adjust_fit(cap_serif_fit#,0);
+numeric left_stem,right_curve,middle_weight;
+left_stem=cap_stem-hround 2stem_corr; middle_weight=.6vair+.5;
+pickup tiny.nib; pos1(left_stem,0); pos2(left_stem,0);
+lft x1l=lft x2l=hround max(2u,3u-.5left_stem); top y1=h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+penpos3(cap_band,90); penpos4(cap_band,90);
+penpos6(middle_weight,-90); penpos7(middle_weight,-90);
+penpos8(middle_weight,90); penpos9(middle_weight,90);
+penpos5(right_curve-stem_corr,0); penpos10(right_curve,0);
+penpos11(cap_band,-90); penpos12(cap_band,-90);
+z3r=top z1; y4=y3; y5=.5[y4,y6]; y6=y7; y7l-y8l=vair;
+z12r=bot z2; y11=y12; y10=.5[y11,y9]; y8=y9; .5[y7l,y8l]=.52h;
+x4=x6; x9=x11=x4+.5u; x7=x8=x1; x9l:=x4+.25u;
+x5r=hround(w-1.5u); x10r=hround(w-u);
+if serifs: right_curve=cap_curve-stem_corr; x4=.5[x1,w-1.5u];
+else: right_curve=cap_curve-3stem_corr; x4=.5[x1,w-2.5u];
+ x4l:=x4l-.5u; x9l:=x9l-.5u; fi
+x6l:=x6l-.5u; x11l:=x11l-.5u;
+fill stroke z3e..super_arc.e(4,5) & super_arc.e(5,6)..z7e; % upper lobe
+fill stroke z8e..super_arc.e(9,10) & super_arc.e(10,11)..z12e; % lower lobe
+if serifs: dish_serif(1,2,a,1/3,cap_jut,b,1/3,.5cap_jut); % upper serif
+ dish_serif(2,1,c,1/3,cap_jut,d,1/3,.5cap_jut); fi % lower serif
+math_fit(0,.5ic#); penlabels(1,2,3,4,5,6,7,8,9,10,11,12); endchar;
+
+cmchar "Uppercase Greek Epsilon";
+beginchar(oct"105",12u#-width_adj#,cap_height#,0);
+italcorr cap_height#*slant-beak_jut#-.5u#;
+adjust_fit(cap_serif_fit#,0);
+h:=vround(h-stem_corr);
+pickup tiny.nib; pos1(cap_stem,0); pos2(cap_stem,0);
+lft x1l=lft x2l=hround max(2u,3u-.5cap_stem); top y1=h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+pickup crisp.nib; pos3(slab,90); pos4(hair,0);
+top y3r=h; x3=x1; rt x4r=hround(w-u); y4=good.y(y3l-beak)-eps;
+arm(3,4,e,beak_darkness,beak_jut); % upper arm and beak
+pos5(cap_bar,-90); pos6(hair,0);
+top y5l=vround(.52[y2,y1]+.5cap_bar); x5=x1;
+pos0(cap_bar,90); pos7(hair,0);
+z0=z5; x6=x7; y6-y5l=y0l-y7;
+if serifs: rt x6r=hround(w-4.4u+.5hair); y6=good.y(y5l+.6beak)+eps;
+ rt x9r=hround(w-.5u);
+else: rt x6r=hround(w-1.5u); y6=y5l+eps; rt x9r=hround(w-.75u); fi
+arm(5,6,f,beak_darkness,0); arm(0,7,g,beak_darkness,0); % middle arm and serif
+pos8(slab if not serifs:+2stem_corr fi,-90); pos9(hair,0);
+bot y8r=0; x8=x2; y9=good.y(y8l+7/6beak)+eps;
+arm(8,9,h,beak_darkness,1.5beak_jut); % lower arm and beak
+if serifs: dish_serif(1,2,a,1/3,cap_jut,b,1/3,.5cap_jut); % upper serif
+ dish_serif(2,1,c,1/3,cap_jut,d,1/3,.5cap_jut); fi % lower serif
+math_fit(0,.5ic#); penlabels(0,1,2,3,4,5,6,7,8,9); endchar;
+
+cmchar "Uppercase Greek Zeta";
+beginchar(oct"106",11u#,cap_height#,0);
+italcorr cap_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric arm_thickness[],z_stem;
+if hefty: arm_thickness1=Vround(slab-vair_corr); arm_thickness2=slab;
+ z_stem=.8[vair,cap_stem];
+else: arm_thickness1=slab; arm_thickness2=vround(slab+vair_corr);
+ z_stem=.9[vair,cap_stem]; fi
+pickup tiny.nib; x3l=x4l=w-x1r=w-x2r; lft x3l=hround u;
+top y1=h; y2=min(y1,h-2/3arm_thickness1);
+bot y4=0; y3=max(y4,2/3arm_thickness2);
+numeric alpha; alpha=diag_ratio(1,z_stem-tiny,y2-y3,x2r-x3l);
+penpos1(alpha*(z_stem-tiny),0); penpos2(alpha*(z_stem-tiny),0);
+penpos3(alpha*(z_stem-tiny),0); penpos4(alpha*(z_stem-tiny),0);
+pair delta; delta=penoffset z3-z2 of currentpen;
+fill top lft z1l--z2l+delta---z3l+delta..lft z3l---lft z4l..bot z4l
+ ---bot rt z4r--z3r-delta---z2r-delta..rt z2r---rt z1r..top z1r
+ ---cycle; % diagonal
+pickup crisp.nib; pos5(arm_thickness1,90); pos6(hair,180);
+top y5r=h; x5=x1; lft x6r=hround 1.25u; y6=good.y(y5l-beak)-eps;
+arm(5,6,a,beak_darkness**.8,-.4beak_jut); % upper arm and beak
+pos7(arm_thickness2,-90); pos8(hair,0);
+bot y7r=0; x7=x4; rt x8r=hround(w-.9u); y8=good.y(y7l+1.2beak)+eps;
+arm(7,8,b,beak_darkness**.9,.6beak_jut); % lower arm and beak
+math_fit(0,.5ic#); penlabels(1,2,3,4,5,6,7,8); endchar;
+
+cmchar "Uppercase Greek Eta";
+beginchar(oct"107",13u#+width_adj#,cap_height#,0);
+italcorr cap_height#*slant-cap_serif_fit#+cap_jut#-2.5u#+min(.5cap_stem#,u#);
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+pickup tiny.nib; pos1(cap_stem,0); pos2(cap_stem,0);
+pos3(cap_stem,0); pos4(cap_stem,0);
+lft x1l=lft x2l=hround max(2u,3u-.5cap_stem); x3=x4=w-x1;
+top y1=top y3=h; bot y2=bot y4=0;
+filldraw stroke z1e--z2e; % left stem
+filldraw stroke z3e--z4e; % right stem
+penpos5(cap_bar,90); penpos6(cap_bar,90);
+x5=x1; x6=x3; y5=y6=.52h;
+fill stroke z5e--z6e; % bar
+if serifs: numeric inner_jut;
+ if rt x1r+cap_jut+.5u+1<=lft x3l-cap_jut: inner_jut=cap_jut;
+ else: rt x1r+inner_jut+.5u+1=lft x3l-inner_jut; fi
+ dish_serif(1,2,a,1/3,cap_jut,b,1/3,inner_jut); % upper left serif
+ dish_serif(2,1,c,1/3,cap_jut,d,1/3,inner_jut); % lower left serif
+ dish_serif(3,4,e,1/3,inner_jut,f,1/3,cap_jut); % upper left serif
+ dish_serif(4,3,g,1/3,inner_jut,h,1/3,cap_jut); fi % lower left serif
+math_fit(0,.5ic#); penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Uppercase Greek Iota";
+beginchar(oct"111",max(6u#,4u#+cap_stem#),cap_height#,0);
+italcorr cap_height#*slant-.25u#;
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+pickup tiny.nib; pos1(cap_stem,0); pos2(cap_stem,0);
+lft x1l=lft x2l=hround(.5w-.5cap_stem); top y1=h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+if serifs: dish_serif(1,2,a,1/3,1.05cap_jut,b,1/3,1.05cap_jut); % upper serif
+ dish_serif(2,1,c,1/3,1.05cap_jut,d,1/3,1.05cap_jut); fi % lower serif
+math_fit(0,.5ic#); penlabels(1,2); endchar;
+
+cmchar "Uppercase Greek Kappa";
+beginchar(oct"112",13.5u#,cap_height#,0);
+italcorr cap_height#*slant-.5u#;
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+numeric right_jut,stem[],alpha[];
+if serifs: right_jut=.6cap_jut;
+else: right_jut=.4tiny; fi
+pickup tiny.nib; pos1(fudged.cap_stem,0); pos2(fudged.cap_stem,0);
+lft x1l=lft x2l=hround max(2u,3u-.5fudged.cap_stem); top y1=h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+stem2=max(tiny.breadth,fudged.cap_stem-3stem_corr);
+stem1=max(tiny.breadth,fudged.hair if hefty:-3stem_corr fi);
+top y3=h; rt x3r=hround(r-letter_fit-u-right_jut);
+bot y6=0; rt x6r=hround(r-letter_fit-.75u-right_jut);
+x4=x1; y4=1/3h;
+alpha1=diag_ratio(1,.5(stem1-tiny),y3-y4,x3r-x4);
+penpos3(alpha1*(stem1-tiny),0); penpos4(whatever,-90);
+alpha2=diag_ratio(1,.5(stem2-tiny),y1-y6,x6r-x1);
+penpos6(alpha2*(stem2-tiny),0);
+forsuffixes $=l,r: y3'$=h; y6'$=0; z4$=z3'$+whatever*(z3-z4);
+ z5$=z6'$+whatever*(z1-z6)=whatever[z3,z4]; endfor
+z5=.5[z5l,z5r];
+z3'r=z3r+penoffset z3-z4 of currentpen+whatever*(z3-z4);
+% we have also |z3'l=z3l+penoffset z4-z3 of currentpen+whatever*(z3-z4)|;\]
+z6'r=z6r+penoffset z1-z6 of currentpen+whatever*(z1-z6);
+z6'l=z6l+penoffset z6-z1 of currentpen+whatever*(z1-z6);
+fill z4r--diag_end(4r,3'r,1,.5,3'l,4l)--z4l--cycle; % upper diagonal
+fill z5l--diag_end(5l,6'l,.5,1,6'r,5r)--z5r--cycle; % lower diagonal
+if serifs: numeric inner_jut;
+ if rt x2r+cap_jut+.5u+1<=lft x6l-cap_jut: inner_jut=cap_jut;
+ else: rt x2r+cap_jut+.5u+1=lft x6l-inner_jut; fi
+ dish_serif(1,2,a,1/3,cap_jut,b,1/3,cap_jut); % upper stem serif
+ dish_serif(2,1,c,1/3,cap_jut,d,1/3,cap_jut); % lower stem serif
+ dish_serif(3,4,e,2/3,1.2cap_jut,f,1/2,right_jut)(dark); % upper diagonal serif
+ dish_serif(6,5,g,1/2,inner_jut,h,1/3,right_jut)(dark);fi % lower diagonal serif
+math_fit(0,.5ic#); penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Uppercase Greek Mu";
+beginchar(oct"114",16u#+width_adj#,cap_height#,0);
+italcorr cap_height#*slant-cap_serif_fit#+cap_jut#-2.5u#+min(.5cap_stem#,u#);
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+numeric stem[]; % thicknesses of the four strokes
+stem1=hround(fudged.hair+stem_corr);
+stem2=hround(fudged.cap_stem-4stem_corr);
+stem3=hround(fudged.hair-stem_corr);
+stem4=hround(fudged.cap_stem-3stem_corr);
+if stem4<stem1: stem4:=stem1; fi
+pickup tiny.nib; pos1(stem1,0); pos2(stem1,0);
+pos3(stem4,0); pos4(stem4,0);
+x1=x2; x3=x4; x1l=w-x3r; rt x3r=hround min(w-2u,w-3u+.5stem4);
+top y1=top y3=h; bot y2=bot y4=0;
+filldraw stroke z1e--z2e; % left stem
+filldraw stroke z3e--z4e; % right stem
+penpos5(stem2,0); penpos6(stem2,0); penpos7(stem3,0); penpos8(stem3,0);
+x5l=x1; x6l=x7l; x8=lft x3l; x6-x5=x8-x7; y5=y8=h; y6=y7;
+if hefty: y6=if monospace: vround 1/3h else: o fi;
+ numeric upper_notch,lower_notch;
+ upper_notch=h-cap_notch_cut; lower_notch=y6+cap_notch_cut;
+ x1'=rt x1r; z1'=whatever[z5l,z6l]; x3'=lft x3l; z3'=whatever[z7r,z8r];
+ z0=whatever[z5r,z6r]=whatever[z7l,z8l];
+ fill z5l..
+ if y1'<upper_notch: {right}(x1'+1,upper_notch){down}... fi
+ {z6-z5}diag_in(5l,6l,1,6r)..diag_out(7l,1,7r,8r){z8-z7}
+ if y3'<upper_notch: ...{up}(x3'-1,upper_notch){right} fi
+ ..z8r--diag_out(8r,1,8l,7l){z7-z8}
+ if y0<=lower_notch: ..{z7-z8}z0{z5-z6}..
+ else: ...{down}(x0+.5,lower_notch)--(x0-.5,lower_notch){up}... fi
+ {z5-z6}diag_in(6r,5r,1,5l)--cycle; % diagonals
+else: y6=0; z0=whatever[z5r,z6r]=whatever[z7l,z8l];
+ fill z5l..{z6-z5}diag_in(5l,6l,1,6r)..diag_out(7l,1,7r,8r){z8-z7}
+ ..z8r--diag_out(8r,1,8l,7l){z7-z8}..{z7-z8}z0{z5-z6}
+ ..{z5-z6}diag_in(6r,5r,1,5l)--cycle; fi % diagonals
+if serifs: serif(1,2,a,1/3,-cap_jut); % upper left serif
+ dish_serif(2,1,b,1/2,cap_jut,c,1/2,cap_jut)(dark); % lower left serif
+ serif(3,4,d,1/3,cap_jut); % upper right serif
+ dish_serif(4,3,e,1/3,cap_jut,f,1/3,cap_jut); fi % lower right serif
+math_fit(0,max(.5ic#-.5u#,0));
+penlabels(0,1,1',2,3,3',4,5,6,7,8); endchar;
+
+cmchar "Uppercase Greek Nu";
+beginchar(oct"115",13u#+width_adj#,cap_height#,0);
+italcorr cap_height#*slant-cap_serif_fit#+cap_jut#-2.5u#+min(.5cap_stem#,u#);
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+numeric thin_stem; thin_stem=hround(fudged.hair+stem_corr);
+pickup tiny.nib; pos1(thin_stem,0); pos2(thin_stem,0);
+pos3(thin_stem,0); pos4(thin_stem,0);
+pickup tiny.nib; top y1=top y3=h; bot y2=bot y4=0;
+x1=x2; x3=x4; x1l=w-x3r;
+rt x3r=hround min(w-2u,w-3u+.5fudged.cap_stem);
+filldraw stroke z1e--z2e; % left stem
+filldraw stroke z3e--z4e; % right stem
+if hefty: penpos5(fudged.cap_stem,0); penpos6(fudged.cap_stem,0);
+ x5l=x1; x6r=x4; y5=h; y6=0;
+ numeric upper_notch,lower_notch;
+ upper_notch=h-cap_notch_cut; lower_notch=cap_notch_cut;
+ x1'=rt x1r; z1'=whatever[z5l,z6l]; x4'=lft x4l; z4'=whatever[z5r,z6r];
+ fill z5l..
+ if y1'<upper_notch: {right}(x1'+1,upper_notch){down}... fi
+ {z6-z5}diag_in(5l,6l,1,6r)--z6r..
+ if y4'>lower_notch: {left}(x4'-1,lower_notch){up}... fi
+ {z5-z6}diag_in(6r,5r,1,5l)--cycle; % diagonal
+else: penpos5(whatever,0); penpos6(whatever,90);
+ z5l=z1l; z6l=z4l;
+ z7=z6l+(max(eps,cap_stem-3stem_corr-tiny),0) rotated (angle(z5l-z6l)-90);
+ z5r=z7+whatever*(z5l-z6l); z6r=z7+whatever*(z5l-z6l);
+ filldraw stroke z5e..z6e; fi % diagonal
+if serifs: if hefty: serif(1,2,a,1/3,-cap_jut); % upper left serif
+ else: serif(5,6,a,1/3,-cap_jut); fi % upper left serif
+ dish_serif(2,1,b,1/2,cap_jut,c,1/2,cap_jut)(dark); % lower left serif
+ dish_serif(3,4,e,1/2,cap_jut,f,1/2,cap_jut)(dark); fi % upper right serif
+math_fit(0,max(.5ic#-.5u#,0)); penlabels(1,1',2,3,4,4',5,6,7); endchar;
+
+cmchar "Uppercase Greek Omicron";
+beginchar(oct"117",14u#-width_adj#,cap_height#,0);
+italcorr .7cap_height#*slant-.5u#;
+adjust_fit(0,0);
+penpos1(vair',90); penpos3(vround(vair+1.5vair_corr),-90);
+penpos2(cap_curve,180); penpos4(cap_curve,0);
+if monospace: x2r=hround 1.5u;
+ interim superness:=sqrt superness; % make |"O"|, not |"0"|
+else: x2r=hround u; fi
+x4r=w-x2r; x1=x3=.5w; y1r=h+o; y3r=-o;
+y2=y4=.5h-vair_corr; y2l:=y4l:=.52h;
+penstroke pulled_super_arc.e(1,2)(.5superpull)
+ & pulled_super_arc.e(2,3)(.5superpull)
+ & pulled_super_arc.e(3,4)(.5superpull)
+ & pulled_super_arc.e(4,1)(.5superpull) & cycle; % bowl
+math_fit(-.3cap_height#*slant-.5u#,ic#-.5u#); penlabels(1,2,3,4); endchar;
+
+cmchar "Uppercase Greek Rho";
+beginchar(oct"121",12u#,cap_height#,0);
+italcorr .75cap_height#*slant-.5u#;
+adjust_fit(cap_serif_fit#,0);
+pickup tiny.nib; penpos1(cap_stem'-tiny,0); penpos2(cap_stem-tiny,0);
+pos0(cap_stem',0); pos0'(cap_stem,0);
+lft x1l=hround max(2u,3u-.5cap_stem'); top y1=h; bot y2=0;
+x1l=x2l=x0l=x0'l; y0=y0'=y7;
+penpos3(cap_band,90); penpos4(cap_band,90);
+penpos5(cap_curve if hefty:-3stem_corr fi,0);
+penpos6(.5[vair,cap_band],-90); penpos7(.5[vair,cap_band],-90);
+z3r=top z1; y4=y3; y5=.5[y4l,y6l]; y6=y7;
+x7=x2; y7l=vround .5h; x4=x6=.5w+.75u; x5r=hround(w-u);
+x4l:=x6l:=x4-.25cap_curve;
+filldraw stroke z1e--z0e--z0'e--z2e; % stem
+fill stroke z3e..pulled_arc.e(4,5) & pulled_arc.e(5,6)..z7e; % lobe
+if serifs: dish_serif(1,0,a,1/3,cap_jut,b,1/3,.5cap_jut); % upper serif
+ dish_serif(2,0',c,1/3,cap_jut,d,1/3,cap_jut); fi % lower serif
+math_fit(0,ic#-2.5u#); penlabels(0,1,2,3,4,5,6,7); endchar;
+
+cmchar "Uppercase Greek Tau";
+beginchar(oct"123",13u#-width_adj#,cap_height#,0);
+italcorr cap_height#*slant-beak_jut#-.25u#;
+adjust_fit(0,0);
+h:=vround(h-2stem_corr);
+pickup tiny.nib; pos1(cap_stem,0); pos2(cap_stem,0);
+lft x1l=lft x2l=hround(.5w-.5cap_stem); top y1=h; bot y2=0;
+filldraw stroke z1e--z2e; % stem
+pickup crisp.nib; pos3(slab,90); pos4(hair,0);
+top y3r=h; x3=x1; rt x4r=hround(w-.65u); y4=good.y(y3l-beak)-eps;
+arm(3,4,e,beak_darkness,.7beak_jut); % right arm and beak
+pos5(hair,180); x5=w-x4; y5=y4;
+arm(3,5,f,beak_darkness,-.7beak_jut); % left arm and beak
+if serifs: dish_serif(1,2,a,1/3,.5cap_jut,b,1/3,.5cap_jut); % upper bracketing
+ dish_serif(2,1,c,1/3,1.414cap_jut,d,1/3,1.414cap_jut); fi % lower serif
+math_fit(-.75cap_height#*slant,ic#-2.5u#); penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Uppercase Greek Chi";
+beginchar(oct"126",13u#,cap_height#,0);
+italcorr cap_height#*slant-.25u#;
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+numeric stem[],outer_jut,xjut,alpha[];
+stem1=cap_stem-2stem_corr; stem2=min(cap_hair,stem1);
+outer_jut=.75cap_jut; xjut= if serifs: (stem1-stem2)/4 else: 0 fi;
+x1l=l+letter_fit+.5u+outer_jut; x2r=r-letter_fit-u-outer_jut-xjut;
+x3l=l+letter_fit+.25u+outer_jut+xjut; x4r=r-letter_fit-.25u-outer_jut;
+y1=y2=h; y3=y4=0;
+alpha1=diag_ratio(1,stem1,h,x4r-x1l);
+alpha2=diag_ratio(1,stem2,h,x2r-x3l);
+penpos1(alpha1*stem1,0); penpos2(alpha2*stem2,0);
+penpos3(alpha2*stem2,0); penpos4(alpha1*stem1,0);
+if hefty: z0=whatever[z1,z4]=whatever[z2,z3];
+ x12=x34=x0; y13=y24=y0;
+ z12=whatever[z2l,z3l]; z13=whatever[z2l,z3l];
+ z24=whatever[z2r,z3r]; z34=whatever[z2r,z3r];
+ forsuffixes $=13,24,34: z$'=.1[z$,z0]; endfor
+ fill diag_end(12,1r,.5,1,1l,13')--z13'--diag_end(13',3l,1,.5,3r,34')--z34'
+ --diag_end(34',4l,.5,1,4r,24')--z24'
+ --diag_end(24',2r,1,.5,2l,12)--z12--cycle; % diagonals
+else: fill diag_end(4r,1r,.5,1,1l,4l)
+ --diag_end(1l,4l,.5,1,4r,1r)--cycle; % left diagonal
+ fill diag_end(2l,3l,.5,1,3r,2r)
+ --diag_end(3r,2r,.5,1,2l,3l)--cycle; fi % right diagonal
+if serifs: numeric inner_jut[]; pickup tiny.nib;
+ prime_points_inside(1,4); prime_points_inside(2,3);
+ prime_points_inside(3,2); prime_points_inside(4,1);
+ if rt x1'r+cap_jut+.5u+1<=lft x2'l-cap_jut-xjut: inner_jut1=cap_jut;
+ else: rt x1'r+inner_jut1+.5u+1=lft x2'l-inner_jut1-xjut; fi
+ if rt x3'r+cap_jut+.5u+1<=lft x4'l-cap_jut-xjut: inner_jut2=cap_jut;
+ else: rt x3'r+inner_jut2+.5u+1=lft x4'l-inner_jut2-xjut; fi
+ dish_serif(1',4,a,1/3,outer_jut,b,2/3,inner_jut1); % upper left serif
+ dish_serif(4',1,c,2/3,inner_jut2,d,1/3,outer_jut); % lower right serif
+ dish_serif(2',3,e,2/3,inner_jut1+xjut,
+ f,1/2,outer_jut+xjut)(dark); % upper right serif
+ dish_serif(3',2,g,1/2,outer_jut+xjut,
+ h,2/3,inner_jut2+xjut)(dark); fi % lower left serif
+math_fit(0,.5ic#); penlabels(0,1,2,3,4,12,13,24,34); endchar;
diff --git a/dviware/quicspool/wwfonts/titalig.mf b/dviware/quicspool/wwfonts/titalig.mf
new file mode 100644
index 0000000000..411d79b003
--- /dev/null
+++ b/dviware/quicspool/wwfonts/titalig.mf
@@ -0,0 +1,206 @@
+% $Header: titalig.mf,v 1.1 88/01/15 13:14:56 simpson Rel $
+% $Log: titalig.mf,v $
+%Revision 1.1 88/01/15 13:14:56 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:31 simpson
+%beta test
+%
+% This file describes five italic ligatures that begin with `f'
+% and puts them in code positions \0013--\0017.
+
+numeric itc; % modified italic correction on `f' and `ff'
+itc=(asc_height#-x_height#)*slant+.75u#;
+
+ligtable "f": "i"=:oct"001", "f"=:oct"003", "l"=:oct"002",
+ "?" kern itc, "!" kern itc, ")" kern itc, "]" kern itc;
+ligtable oct"003": "i"=:oct"011", "l"=:oct"012",
+ "?" kern itc, "!" kern itc, ")" kern itc, "]" kern itc;
+
+cmchar "Italic ligature ff";
+beginchar(oct"003",5u#+max(1.5u#,stem#)+max(3.5u#,2flare#)+2letter_fit#,
+ asc_height#,desc_depth#);
+italcorr asc_height#*slant+.75u#;
+adjust_fit(0,0); pickup fine.nib;
+z98-z88=z99-z89=z14-z4=z15-z5=(4.8u+2letter_fit,0);
+.5[x88,x99]=.5w-.1u; x89-x88=u; y98=h; y99=-d;
+numeric theta; theta=angle(z88-z89);
+pos0(flare,0); pos1(hair,0); pos2(vair,90);
+pos3(.5[hair,stem],180); pos4(stem,theta+90);
+pos5(stem,theta-90); pos6(.5[hair,stem],0);
+pos7(vair,-90); pos8(hair,-180); pos9(flare,-180);
+rt x1r=hround(.5w+1.25u); lft x8r=hround-.35u; x2=.5[x1,x4]; x7=.6[x8,x5];
+y9-.5flare=vround -.85d; y2-y0=y9-y7; top y2r=h+oo; bot y7r=-d-oo;
+y4=.25[x_height,h]; y5=.5[-d,y4];
+z4=whatever[z88,z89]; z5=whatever[z88,z89];
+x3=.8[x2+x4-x88,x88]; x6=.8[x7+x5-x89,x89]; y3=.8[y4,y2]; y6=.8[y5,y7];
+bulb(2,1,0); bulb(7,8,9); % left bulbs
+filldraw stroke z2e{left}...z3e...{z89-z88}z4e; % upper middle arc
+filldraw z4r--z5l--z5r--z4l--cycle; % left stem
+filldraw stroke z5e{z89-z88}...z6e...{left}z7e; % lower left arc
+pos10(flare,0); pos11(hair,0); pos12(vair,90);
+pos13(.5[hair,stem],180); pos14(stem,theta+90);
+pos15(stem,theta-90); pos16(.5[hair,stem],0);
+pos17(vair,-90); pos18(hair,-180); pos19(flare,-180);
+rt x11r=hround(w+.25u); lft x18r=hround(.5w-1.25u);
+x12=.6[x11,x14]; x17=.5[x18,x15];
+x13=.8[x12+x14-x98,x98]; x16=.8[x17+x15-x99,x99];
+y0=y10; y2=y12; y3=y13; y6=y16; y7=y17; y9=y19;
+bulb(12,11,10); bulb(17,18,19); % right bulbs
+filldraw stroke z12e{left}...z13e...{z99-z98}z14e; % upper right arc
+filldraw z14r--z15l--z15r--z14l--cycle; % right stem
+filldraw stroke z15e{z99-z98}...z16e...{left}z17e; % lower middle arc
+pickup crisp.nib; pos20(bar,90); pos21(bar,90);
+top y20r=top y21r=x_height;
+lft x20=lft x4r-.5stem-u; rt x21=rt x14l+.5stem+1.5u;
+filldraw stroke z20e--z21e; % crossbar
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
+ 20,21,88,89,98,99); endchar;
+
+cmchar "Italic ligature fi";
+beginchar(oct"001",6.5u#+.5max(1.5u#,stem#)+.5max(3.5u#,2flare#)
+ +2letter_fit#,asc_height#,desc_depth#);
+italcorr max(asc_height#*slant+.5stem#-2u#,1/3x_height#*slant+.5hair#+.5u#);
+adjust_fit(0,0); pickup fine.nib;
+.5[x88,x89]=.5(w-4u-2letter_fit); x89-x88=u; y88=h; y89=-d;
+numeric theta; theta=angle(z88-z89);
+pos0(flare,0); pos1(hair,0); pos2(vair,90);
+pos3(.5[hair,stem],180); pos4(stem,theta+90);
+pos5(stem,theta-90); pos6(.5[hair,stem],0);
+pos7(vair,-90); pos8(hair,-180); pos9(flare,-180);
+pos11(stem,0); rt x11r=hround(w-2.5u+.5stem);
+x12=x11; x14=w; hook_out(12,13,14); % closing hook
+x1r=x11r; lft x8r=hround-.35u; x2=.5[x1,x4]; x7=.6[x8,x5];
+y9-.5flare=vround-.85d; bot y7r=-d-oo;
+y0+.5flare=vround(.85[x_height,h]); top y2r=h+oo;
+y4=.25[x_height,h]; y5=.5[-d,y4];
+z4=whatever[z88,z89]; z5=whatever[z88,z89];
+x3=.8[x2+x4-x88,x88]; x6=.8[x7+x5-x89,x89]; y3=.8[y4,y2]; y6=.8[y5,y7];
+bulb(2,1,0); bulb(7,8,9); % bulbs
+filldraw stroke z2e{left}...z3e...{z89-z88}z4e; % upper arc
+filldraw z4r--z5l--z5r--z4l--cycle; % left stem
+filldraw stroke z5e{z89-z88}...z6e...{left}z7e; % lower arc
+top y11=x_height; filldraw stroke z11e--z12e; % right stem
+pickup crisp.nib; pos20(bar,90); pos21(bar,90);
+top y20r=top y21r=x_height;
+lft x20=lft x4r-.5stem-u; x21=x11;
+filldraw stroke z20e--z21e; % crossbar
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,20,21,88,89); endchar;
+
+cmchar "Italic ligature fl";
+beginchar(oct"002",7u#+.5max(1.5u#,stem#)+.5max(3.5u#,2flare#)
+ +2letter_fit#,asc_height#,desc_depth#);
+italcorr max(asc_height#*slant+.5stem#-2u#,1/3x_height#*slant+.5hair#+.5u#);
+adjust_fit(0,0); pickup fine.nib;
+.5[x88,x89]=.5(w-4.5u-2letter_fit); x89-x88=u; y88=h; y89=-d;
+numeric theta; theta=angle(z88-z89);
+pos0(flare,0); pos1(hair,0); pos2(vair,90);
+pos3(.5[hair,stem],180); pos4(stem,theta+90);
+pos5(stem,theta-90); pos6(.5[hair,stem],0);
+pos7(vair,-90); pos8(hair,-180); pos9(flare,-180);
+pos11(stem,0); rt x11r=hround(w-2.5u+.5stem); rt x1r=lft x11l;
+x12=x11; x14=w; hook_out(12,13,14); % closing hook
+lft x8r=hround-.35u; x2=.5[x1,x4]; x7=.6[x8,x5];
+y9-.5flare=vround -.85d; y2-y0=y9-y7; top y2r=h+oo; bot y7r=-d-oo;
+y4=.25[x_height,h]; y5=.5[-d,y4];
+z4=whatever[z88,z89]; z5=whatever[z88,z89];
+x3=.8[x2+x4-x88,x88]; x6=.8[x7+x5-x89,x89]; y3=.8[y4,y2]; y6=.8[y5,y7];
+bulb(2,1,0); bulb(7,8,9); % bulbs
+filldraw stroke z2e{left}...z3e...{z89-z88}z4e; % upper arc
+filldraw z4r--z5l--z5r--z4l--cycle; % left stem
+filldraw stroke z5e{z89-z88}...z6e...{left}z7e; % lower arc
+top y11=h; filldraw stroke z11e--z12e; % right stem
+pickup crisp.nib; pos20(bar,90); pos21(bar,90);
+top y20r=top y21r=x_height;
+lft x20=lft x4r-.5stem-u; x21=x11;
+filldraw stroke z20e--z21e; % crossbar
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,20,21,88,89); endchar;
+
+cmchar "Italic ligature ffi";
+beginchar(oct"011",11.75u#+.5max(1.5u#,stem#)+.5max(3.5u#,2flare#)
+ +4letter_fit#,asc_height#,desc_depth#);
+italcorr max(asc_height#*slant+.5stem#-2u#,1/3x_height#*slant+.5hair#+.5u#);
+adjust_fit(0,0); pickup fine.nib;
+z98-z88=z99-z89=z14-z4=z15-z5=(5u+2letter_fit,0);
+numeric theta,mid_f;
+mid_f=.5[x88,x99]=.5(w-4.25u-2letter_fit); x89-x88=u;
+y98=h; y99=-d; theta=angle(z88-z89);
+pos21(stem,0); rt x21r=hround(w-2.5u+.5stem);
+x22=x21; x24=w; hook_out(22,23,24); % closing hook
+pos0(flare,0); pos1(hair,0); pos2(vair,90);
+pos3(.5[hair,stem],180); pos4(stem,theta+90);
+pos5(stem,theta-90); pos6(.5[hair,stem],0);
+pos7(vair,-90); pos8(hair,-180); pos9(flare,-180);
+rt x1r=hround(mid_f+1.75u); lft x8r=hround-.35u;
+x2=.5[x1,x4]; x7=.6[x8,x5];
+y9-.5flare=vround -.85d; y2-y0=y9-y7; top y2r=h+oo; bot y7r=-d-oo;
+y4=.25[x_height,h]; y5=.5[-d,y4];
+z4=whatever[z88,z89]; z5=whatever[z88,z89];
+x3=.8[x2+x4-x88,x88]; x6=.8[x7+x5-x89,x89]; y3=.8[y4,y2]; y6=.8[y5,y7];
+bulb(2,1,0); bulb(7,8,9); % left bulbs
+filldraw stroke z2e{left}...z3e...{z89-z88}z4e; % upper middle arc
+filldraw z4r--z5l--z5r--z4l--cycle; % left stem
+filldraw stroke z5e{z89-z88}...z6e...{left}z7e; % lower left arc
+pos10(flare,0); pos11(hair,0); pos12(vair,90);
+pos13(.5[hair,stem],180); pos14(stem,theta+90);
+pos15(stem,theta-90); pos16(.5[hair,stem],0);
+pos17(vair,-90); pos18(hair,-180); pos19(flare,-180);
+x11r=x21r; lft x18r=hround(mid_f-1.25u); x12=.5[x11,x14]; x17=.5[x18,x15];
+x13=.8[x12+x14-x98,x98]; x16=.8[x17+x15-x99,x99];
+y10+.5flare=vround .85[x_height,h];
+y2=y12; y3=y13; y6=y16; y7=y17; y9=y19;
+bulb(12,11,10); bulb(17,18,19); % right bulbs
+filldraw stroke z12e{left}...z13e...{z99-z98}z14e; % upper right arc
+filldraw z14r--z15l--z15r--z14l--cycle; % middle stem
+filldraw stroke z15e{z99-z98}...z16e...{left}z17e; % lower middle arc
+top y21=x_height; filldraw stroke z21e--z22e; % right stem
+pickup crisp.nib; pos30(bar,90); pos31(bar,90);
+top y30r=top y31r=x_height;
+lft x30=lft x4r-.5stem-u; x31=x21;
+filldraw stroke z30e--z31e; % crossbar
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
+ 20,21,22,23,24,30,31,88,89,98,99); endchar;
+
+cmchar "Italic ligature ffl";
+beginchar(oct"012",12u#+.5max(1.5u#,stem#)+.5max(3.5u#,2flare#)
+ +4letter_fit#,asc_height#,desc_depth#);
+italcorr max(asc_height#*slant+.5stem#-2u#,1/3x_height#*slant+.5hair#+.5u#);
+adjust_fit(0,0); pickup fine.nib;
+z98-z88=z99-z89=z14-z4=z15-z5=(5u+2letter_fit,0);
+numeric theta,mid_f;
+mid_f=.5[x88,x99]=.5(w-4.5u-2letter_fit); x89-x88=u;
+y98=h; y99=-d; theta=angle(z88-z89);
+pos21(stem,0); rt x21r=hround(w-2.5u+.5stem);
+x22=x21; x24=w; hook_out(22,23,24); % closing hook
+pos0(flare,0); pos1(hair,0); pos2(vair,90);
+pos3(.5[hair,stem],180); pos4(stem,theta+90);
+pos5(stem,theta-90); pos6(.5[hair,stem],0);
+pos7(vair,-90); pos8(hair,-180); pos9(flare,-180);
+rt x1r=hround(mid_f+1.25u); lft x8r=hround-.35u;
+x2=.5[x1,x4]; x7=.6[x8,x5];
+y9-.5flare=vround -.85d; y2-y0=y9-y7; top y2r=h+oo; bot y7r=-d-oo;
+y4=.25[x_height,h]; y5=.5[-d,y4];
+z4=whatever[z88,z89]; z5=whatever[z88,z89];
+x3=.8[x2+x4-x88,x88]; x6=.8[x7+x5-x89,x89]; y3=.8[y4,y2]; y6=.8[y5,y7];
+bulb(2,1,0); bulb(7,8,9); % left bulbs
+filldraw stroke z2e{left}...z3e...{z89-z88}z4e; % upper middle arc
+filldraw z4r--z5l--z5r--z4l--cycle; % left stem
+filldraw stroke z5e{z89-z88}...z6e...{left}z7e; % lower left arc
+pos10(flare,0); pos11(hair,0); pos12(vair,90);
+pos13(.5[hair,stem],180); pos14(stem,theta+90);
+pos15(stem,theta-90); pos16(.5[hair,stem],0);
+pos17(vair,-90); pos18(hair,-180); pos19(flare,-180); rt x11r=lft x21l;
+lft x18r=hround(mid_f-1.25u); x12=.5[x11,x14]; x17=.5[x18,x15];
+x13=.8[x12+x14-x98,x98]; x16=.8[x17+x15-x99,x99];
+y0=y10; y2=y12; y3=y13; y6=y16; y7=y17; y9=y19;
+bulb(12,11,10); bulb(17,18,19); % right bulbs
+filldraw stroke z12e{left}...z13e...{z99-z98}z14e; % upper right arc
+filldraw z14r--z15l--z15r--z14l--cycle; % middle stem
+filldraw stroke z15e{z99-z98}...z16e...{left}z17e; % lower middle arc
+top y21=h; filldraw stroke z21e--z22e; % right stem
+pickup crisp.nib; pos30(bar,90); pos31(bar,90);
+top y30r=top y31r=x_height;
+lft x30=lft x4r-.5stem-u; x31=x21;
+filldraw stroke z30e--z31e; % crossbar
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
+ 20,21,22,23,24,30,31,88,89,98,99); endchar;
diff --git a/dviware/quicspool/wwfonts/titalms.mf b/dviware/quicspool/wwfonts/titalms.mf
new file mode 100644
index 0000000000..c783512b95
--- /dev/null
+++ b/dviware/quicspool/wwfonts/titalms.mf
@@ -0,0 +1,40 @@
+% $Header: titalms.mf,v 1.1 88/01/15 13:14:59 simpson Rel $
+% $Log: titalms.mf,v $
+%Revision 1.1 88/01/15 13:14:59 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:33 simpson
+%beta test
+%
+% This file contains miscellaneous symbols of math italic fonts.
+
+cmchar "Partial differential sign";
+beginchar(oct"171",10u#,asc_height#,0);
+italcorr .7asc_height#*slant+.5curve#-1.5u#;
+adjust_fit(0,0);
+numeric top_thickness,bot_thickness,side_thickness,pull;
+top_thickness=max(fine.breadth,vround(slab-2vair_corr));
+bot_thickness=max(fine.breadth,vround(slab-vair_corr));
+side_thickness=max(fine.breadth,hround 1/3[curve,cap_curve]);
+pull=min(.25,1.5superpull);
+pickup fine.nib; pos2(top_thickness,90);
+pos3(side_thickness,0); pos4(bot_thickness,-90);
+pos5(side_thickness,-180); pos6(vair,-270);
+lft x5r=w-rt x3r=hround max(.75u,1.5u-.5side_thickness);
+x4=x6+.1u=x2+u=.5w;
+top y2r=h+o; y3=.5[y2,y4]; bot y4r=-o;
+y5=.5[y4,y6]; top y6=vround 5/8h+o;
+path p; p=pulled_super_arc.l(3,4)(pull);
+numeric t; t=xpart(p intersectiontimes((x3r,y5)--(x4,y5)));
+pos7(thin_join,0); z7l=point t of p;
+(x,y6r)=whatever[z7l,z6l]; x6r:=max(x,.5[x5r,x6]);
+filldraw stroke pulled_super_arc.e(2,3)(pull)
+ & {{interim superness:=more_super; pulled_super_arc.e(3,4)(pull)}}
+ & {{less_tense; pulled_super_arc.e(4,5)(pull) & pulled_super_arc.e(5,6)(pull)}}
+ & z6e{right}...{direction t of p}z7e; % arc and bowl
+pos1(hair,180); pos0(flare,180);
+lft x0r=min(lft x2-eps,hround 1.2u);
+y0=vround min(.85h-.5flare,.8h+.5flare)+o;
+{{less_tense; bulb(2,1,0)}}; % arc and bulb
+math_fit(-.3x_height#*slant+.5curve#-u#,ic#-u#);
+penlabels(0,1,2,3,4,5,6,7); endchar;
diff --git a/dviware/quicspool/wwfonts/titalp.mf b/dviware/quicspool/wwfonts/titalp.mf
new file mode 100644
index 0000000000..1bc7530b36
--- /dev/null
+++ b/dviware/quicspool/wwfonts/titalp.mf
@@ -0,0 +1,114 @@
+% $Header: titalp.mf,v 1.1 88/01/15 13:15:05 simpson Rel $
+% $Log: titalp.mf,v $
+%Revision 1.1 88/01/15 13:15:05 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:34 simpson
+%beta test
+%
+% This file contains `\$' and `\&' and `?' in the so-called italic style.
+
+% Codes \0044, \0046, and \0077 are generated, as well as code |spanish_query|
+% (for a Spanish question mark) if that code value is known.
+
+cmchar "Dollar sign";
+beginchar("$",9u#,body_height#,body_height#-asc_height#);
+italcorr fig_height#*slant-.5u#; % same as for digits
+adjust_fit(0,0);
+numeric theta; theta=90-angle(50u,asc_height); slope:=-asc_height/50u;
+pickup fine.nib; pos2(slab,-90);
+pos0(cap_stem,theta); pos7(slab,-90);
+x2=x0=x7=.5w; top y2l=asc_height+oo; bot y7r=-oo;
+y0=.52asc_height; lft x3l=hround u; rt x6r=hround(w-u);
+x3r-x3l=x6r-x6l=hround .35[slab,cap_stem]-fine;
+ellipse_set(2l,3l,4l,0l); ellipse_set(2r,3r,4r,0r); y3=y3r;
+ellipse_set(7l,6l,5l,0l); ellipse_set(7r,6r,5r,0r); y6=y6r;
+filldraw stroke super_arc.e(2,3) & z3e{down}
+ ..z4e---z5e..z6e{down} & super_arc.e(6,7); % main stroke
+if serifs: pos1(hair,0); pos8(hair,180);
+ pos10(flare,0); pos9(flare,180);
+ rt x1r=hround(w-u); lft x8r=hround u; y1=.5[y0,y2]; y8=.5[y0,y7];
+ {{less_tense; pos2'(slab,90); z2'=z2; bulb(2',1,10); % upper arc and bulb
+ bulb(7,8,9)}}; % lower arc and bulb
+else: pos1(.6[slab,flare],-100); pos8(flare,-100);
+ rt x1l=hround(w-1.3u); lft x8r=hround .8u;
+ top y1l=vround .92asc_height+oo; bot y8r=vround .1asc_height-oo;
+ filldraw stroke term.e(2,1,right,.9,4); % upper arc and terminal
+ filldraw stroke term.e(7,8,left,1,4); fi % lower arc and terminal
+pickup crisp.nib; pos12(bar,0); pos11(bar,0);
+lft x12l=lft x11l=hround(.5w-.5bar); top y12=h; bot y11=-d;
+filldraw stroke z12e--z11e; % vertical crossbar
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11,12); endchar;
+
+cmchar "Italic ampersand";
+beginchar("&",14u#,asc_height#,0);
+italcorr asc_height#*slant-1.5u#;
+adjust_fit(if monospace:-u#,-2u# else: 0,0 fi); pickup fine.nib;
+pos1(flare,0); pos2(hair,0); pos3(vair,90);
+rt x2r=hround.5w; x3=1/3(w-u);
+top y3r=h+o; y2=.5[x_height,h]; bulb(3,2,1); % left bulb
+pos4(stem,180); pos5(vair,270); pos6(hair,360); pos7(vair,450);
+pos8(curve,540); pos9(vair,630); pos10(hair,720);
+lft x4r=hround 1.25u; x5=x7=x3+1/6u; rt x6r=hround(x5+1.5u);
+lft x8r=hround u; x9=.5w; rt x10r=hround(w-1.5u);
+y4=.5[y3,y5]; top y5l=vround .77x_height; y6=.5[y5,y7];
+y7l=good.y 1/3[y5,y3]; y8=.5[y7,y9]; bot y9r=-o; y10=bar_height;
+pos12(hair,0); pos13(curve,0); pos14(hair,0); pos15(vair,90); pos16(curve,90);
+rt x12r=rt x13r=hround(w-2u); lft x14l=hround(.5w+.5u);
+x15=x16=rt x14r+u;
+y12=y13=h-.5curve; y14=.5[bar_height,x_height];
+bot y15l=bot y16l=vround y10;
+numeric theta; theta=angle((z12-z14)xscaled 2);
+pos11(hair,theta); x11=w-4u; y11=.5[y13,y16];
+filldraw stroke pulled_arc.e(3,4) & pulled_arc.e(4,5) & pulled_arc.e(5,6)
+ & pulled_arc.e(6,7) & pulled_arc.e(7,8) & pulled_arc.e(8,9)
+ & {{interim superness:=more_super; pulled_arc.e(9,10)}}
+ ..tension .9 and 1..{dir(theta+100)}z11e; % bowls, loop, and stem
+pos11'(hair,theta-90); z11'=z11;
+forsuffixes $=l,r: path p$;
+ p$=z12${down}..z11'${-dir theta}..{down}z14$...{right}z15$; endfor
+filldraw p.l--reverse p.r--cycle; % arms
+path q[]; q1=z13r{up}..z13l{down}..cycle;
+q2=z16l{right}..z16r{left}..cycle;
+filldraw subpath(0,ypart(p.l intersectiontimes q1)) of q1--cycle; % upper bulb
+filldraw subpath(0,ypart(p.r intersectiontimes q2)) of q2--cycle; % lower bulb
+penlabels(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16); endchar;
+
+cmchar "Italic question mark";
+beginchar("?",9u#,asc_height#,0);
+italcorr asc_height#*slant-u#;
+adjust_fit(0,0); pickup tiny.nib; pos10(dot_size,0); pos11(dot_size,90);
+lft x10l=hround(.5w-.5dot_size); bot y11l=0; z10=z11; dot(10,11); % dot
+pickup fine.nib; pos1(flare,180); pos2(hair,180); pos3(vair,90);
+lft x1r=hround u; x3=.5w;
+y1-.5flare=x_height; top y3r=h+o; bulb(3,2,1); % bulb
+pos8(vair,-90); x8=.5w; bot y8r=.25[top y11r,x_height]+1;
+numeric theta; theta=90+angle(10u,y3-y8); slope:=(y3-y8)/10u;
+pos3'(vair,-90); z3'=z3; pos0(vstem,theta); x0=x3; y0=1/3[y8,y3];
+rt x4l=hround(w-1.5u); lft x7r=hround 1/3w;
+x4l-x4r=x7l-x7r=hround .5[vair,vstem]-fine;
+ellipse_set(3'l,4l,5l,0l); ellipse_set(3'r,4r,5r,0r); y4=y4r;
+ellipse_set(8l,7l,6l,0l); ellipse_set(8r,7r,6r,0r); y7=y7r;
+pos9(hair,0); rt x9r=hround(2/3w+.5hair); y9=good.y .5[y8,y0];
+filldraw stroke super_arc.e(3',4) & z4e{down}
+ ..z5e---z6e..z7e{down} & super_arc.e(7,8)...{up}z9e; % main stroke
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11); endchar;
+
+iff known spanish_query: cmchar "Spanish open italic question mark";
+beginchar(spanish_query,9u#,asc_height#-desc_depth#,desc_depth#);
+adjust_fit(0,0); pickup tiny.nib; pos10(dot_size,0); pos11(dot_size,90);
+lft x10l=hround(.5w-.5dot_size); top y11r=h; z10=z11; dot(10,11); % dot
+pickup fine.nib; pos1(flare,0); pos2(hair,0); pos3(vair,-90);
+rt x1r=hround(w-u); x3=.5w; y1+.5flare=asc_height-x_height-d;
+bot y3r=-d-o; bulb(3,2,1); % bulb
+pos8(vair,90); x8=.5w; top y8r=.25[bot y11l,y1+.5flare]-1;
+numeric theta; theta=angle(10u,y8-y3)-90; slope:=(y8-y3)/10u;
+pos3'(vair,90); z3'=z3; pos0(vstem,theta); x0=x3; y0=1/3[y8,y3];
+lft x4l=hround 1.5u; rt x7r=hround 2/3w;
+x4r-x4l=x7r-x7l=hround .5[vair,vstem]-fine;
+ellipse_set(3'l,4l,5l,0l); ellipse_set(3'r,4r,5r,0r); y4=y4r;
+ellipse_set(8l,7l,6l,0l); ellipse_set(8r,7r,6r,0r); y7=y7r;
+pos9(hair,180); lft x9r=hround(1/3w-.5hair); y9=good.y .5[y8,y0];
+filldraw stroke super_arc.e(3',4) & z4e{up}
+ ..z5e---z6e..z7e{up} & super_arc.e(7,8)...{down}z9e; % main stroke
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11); endchar;
diff --git a/dviware/quicspool/wwfonts/tmathit.mf b/dviware/quicspool/wwfonts/tmathit.mf
new file mode 100644
index 0000000000..54186b8678
--- /dev/null
+++ b/dviware/quicspool/wwfonts/tmathit.mf
@@ -0,0 +1,1015 @@
+% $Header: tmathit.mf,v 1.1 88/01/15 13:15:08 simpson Rel $
+% $Log: tmathit.mf,v $
+%Revision 1.1 88/01/15 13:15:08 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:36 simpson
+%beta test
+%
+% The Computer Modern Math Italic family (by D. E. Knuth, 1979--1985)
+
+font_coding_scheme:="TeX math italic";
+mode_setup; font_setup;
+
+input tgreekl; % lower case Greek letters
+
+% From file italms.mf, font cmmi10 (output with slant)
+cmchar "Lowercase italic script l";
+beginchar(oct"044",4.5u#+max(1.5u#,stem#),asc_height#,0);
+italcorr .8asc_height#*slant-u#;
+adjust_fit(if monospace:u#,u# else: 0,0 fi); pickup fine.nib;
+pos1(hair,-45); pos2(hair,0); pos3(vair,90);
+pos4(stem,180); pos5(vair,270); pos6(hair,315);
+lft x1l=hround(lft x1l-x1); rt x2r=hround(w-1.5u); x3=.5w;
+lft x4r=hround .5u; x5=x3+.75u; x6=x1+w+1;
+y1=y6=.125h; y2=.8h; top y3r=h+oo; y4=.5[y3,y5]; bot y5=-oo;
+filldraw stroke z1e{10u,asc_height}...z2e{up}...pulled_arc.e(3,4)
+ & pulled_arc.e(4,5)...z6e{10u,asc_height}; % bowl and hook
+math_fit(0,ic#); penlabels(1,2,3,4,5,6); endchar;
+
+font_slant slant;
+font_x_height x_height#;
+font_quad 18u#+4letter_fit#;
+
+slant:=mono_charic#:=0; % the remaining characters will not be slanted
+currenttransform:=identity yscaled aspect_ratio scaled granularity;
+
+input titalms; % special symbols for math italic
+input tgreeku; % upper case greek letters
+input tromms; % roman math specials
+
+% The following characters come from a hodge-podge of files.
+
+% My own creation (created in just 1 hour!)
+cmchar "Right hand";
+beginchar(oct"004", 2.1body_height#, body_height#, 0);
+adjust_fit(0,0);
+picture hand;
+% On the graph I drew this on, the hand is 40 units tall and 84 (2.1*40) units
+% wide.
+handunit# := body_height#/40;
+define_pixels(handunit);
+z1=(4handunit,0); z2=(handunit,handunit); z3=(0,4handunit);
+z4=(0,34handunit); z5=(handunit,36handunit); z6=(4handunit,37handunit);
+z7=(9handunit,35handunit); z8=(16handunit,36handunit);
+z9=(30handunit,38handunit); z10=(50handunit,40handunit);
+z11=(70handunit,40handunit); z12=(78handunit,40handunit);
+z13=(84handunit,38handunit); z14=(83handunit,34handunit);
+z15=(80handunit,33handunit); z16=(56handunit,30handunit);
+z17=(52handunit,29handunit); z18=(51handunit,24handunit);
+z19=(46handunit,18handunit); z20=(45handunit,14handunit);
+z21=(40handunit,8handunit); z22=(37handunit,handunit);
+z23=(35handunit,0); z24=(27handunit,handunit); z25=(13handunit,2handunit);
+fill z1{dir 180}..z2{z3-z1}..{dir 90}z3--z4{dir 90}..z5{z6-z4}..z6{dir 0}
+..z7{dir 0}..z8..z9..z10..z11{dir 0}--z12{dir 0}..z13{dir -80}..z14{dir 225}
+..z15{dir 190}--z16..{dir 200}z17 & flex(z17,z18,z19) & flex(z19,z20,z21)
+..z22{dir 225}..z23{dir 180}..z24{z25-z23}..z25..cycle;
+hand:=currentpicture;
+endchar;
+
+% My own creation
+cmchar "Left hand";
+beginchar(oct"036", 2.1body_height#, body_height#, 0);
+adjust_fit(0,0);
+currentpicture:=hand reflectedabout ((.5w,0),(.5w,h));
+endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Subset or equal to sign";
+compute_spread(.45x_height#,.55x_height#);
+spread#':=spread#; spread':=spread; % the spread of `$=$'
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"133",14u#,v_center(spread#'+spread#+rule_thickness#));
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x2=hround 1.5u-eps; x1=x3=w-x2;
+y1-y3=spread; y2=.5[y1,y3]; top y1=h;
+x4=x5=.5w; y4=y1; y5=y3;
+draw z1---z4...z2{down}...z5---z3; % arc and bars
+x8=x1; lft x9=x2; y8=y9; y3-y9=spread'; draw z8--z9; % lower bar
+labels(1,2,3,4,5,8,9); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Superset or equal to sign";
+compute_spread(.45x_height#,.55x_height#);
+spread#':=spread#; spread':=spread; % the spread of `$=$'
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"002",14u#,v_center(spread#'+spread#+rule_thickness#));
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x1=hround 1.5u-eps; x2=w-x1; x3=x1;
+y1-y3=spread; y2=.5[y1,y3]; top y1=h;
+x4=x5=.5w; y4=y1; y5=y3;
+draw z1---z4...z2{down}...z5---z3; % arc and bars
+x8=x1; rt x9=x2; y8=y9; y3-y9=spread'; draw z8--z9; % lower bar
+labels(1,2,3,4,5,8,9); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Times operator";
+beginarithchar(oct"052"); pickup rule.nib;
+x1=good.x(1/sqrt2)[.5w,rt u]; y1=good.y(1/sqrt2)[math_axis,bot h];
+x2=x3=w-x1; x4=x1; .5[y1,y2]=.5[y3,y4]=math_axis; y2=y4;
+draw z1--z2; draw z3--z4; % diagonals
+labels(1,2,3,4); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Asterisk at the axis";
+beginchar(oct"071",9u#,v_center(x_height#));
+adjust_fit(0,0);
+numeric ast_flare; ast_flare=hround .7[thin_join,stem];
+x0=.5w; y0=h-.5x_height;
+for d=-150 step 60 until 150: z[d]=z0+.5dir d xscaled 7.5u yscaled x_height;
+ numeric theta; theta=angle(z[d]-z0);
+ fill z0+.5(0,-thin_join)rotated theta
+ ---z[d]+.5(-ast_flare,-ast_flare)rotated theta
+ ..z[d]..z[d]+.5(-ast_flare,ast_flare)rotated theta
+ ---z0+.5(0,thin_join)rotated theta--cycle; endfor % diagonal at angle |d|
+labels(0,[-150],[-90],[-30],30,90,150); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Elementary division operator";
+beginarithchar(oct"057"); pickup rule.nib;
+x3-.5dot_size=hround(.5w-.5dot_size); w:=r:=2x3;
+y3+.5dot_size=vround(math_axis+math_spread[.5x_height,.6x_height]+.5dot_size);
+lft x1=hround u-eps; x2=w-x1; y1=y2=math_axis;
+draw z1--z2; % bar
+pos3(dot_size,0); pos4(dot_size,90); z3=z4;
+pos5(dot_size,0); pos6(dot_size,90); z5=z6; x5=x3; .5[y3,y5]=math_axis;
+dot(3,4); dot(5,6); % dots
+penlabels(1,2,3,4,5,6); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Similarity sign";
+compute_spread(.45x_height#,.55x_height#);
+beginchar(oct"062",14u#,v_center(spread#+rule_thickness#));
+adjust_fit(0,0);
+pickup pencircle xscaled .7rule_thickness yscaled 1.4rule_thickness;
+if vair#>.8curve#: pickup rule.nib; autorounded; fi % monoline
+lft x1=hround u; x2=4u; x3=w-x2; x4=w-x1;
+bot y1=bot y3=-d; top y2=top y4=h;
+draw z1{up}...z2{right}..{right}z3...{up}z4; % stroke
+labels(1,2,3,4); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Similar or equal sign";
+compute_spread(.45x_height#,.55x_height#);
+beginchar(oct"061",14u#,v_center(2spread#+rule_thickness#));
+adjust_fit(0,0);
+pickup pencircle xscaled .7rule_thickness yscaled 1.4rule_thickness;
+if vair#>.8curve#: pickup rule.nib; autorounded; fi % monoline
+lft x1=hround u; x2=4u; x3=w-x2; x4=w-x1;
+bot y1=bot y3=floor math_axis; top y2=top y4=h;
+draw z1{up}...z2{right}..{right}z3...{up}z4; % stroke
+pickup rule.nib; lft x5=hround u-eps; x6=w-x5; y5=y6=math_axis-spread;
+draw z5--z6; % bar
+labels(1,2,3,4,5,6); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Proportionality sign";
+beginchar(oct"003",16.5u#,x_height#,0);
+italcorr x_height#*slant-.5u#;
+adjust_fit(0,-2.5u#); pickup fine.nib;
+numeric theta,phi; phi=angle(3u,h); theta=angle(5u,-h);
+pos1(vair,180); pos2(.5[vair,stem],90+.5theta); pos3(stem,90+theta);
+pos4(stem,90+theta); pos5(.5[vair,stem],90+.5theta);
+pos6(vair,180); pos7(.2[vair,stem],270+.5phi);
+pos8(.3[vair,stem],270+phi); pos9(.2[vair,stem],270+.5phi);
+lft x1r=w-rt x6l=hround u; x2=x9=.4[x1,x8]; x5=x7=.6[x8,x6];
+if monospace: x2l:=x2r; x5r:=x5l; x7r:=x7l; x9l:=x9r; fi
+y1=y6=.5h; top y2r=top y7l=h+oo; bot y5l=bot y9r=-oo;
+x8=.5[x3,x4]=.5w; y8=.5[y3,y4]=.5h;
+y3-y4=h/3; z3-z4=whatever*dir theta;
+filldraw stroke z1e{up}...z2e{right}...z3e---z4e...z5e{right}...z6e{up}
+ ...z7e{left}...{-dir phi}z8e...{left}z9e...z1e{up}; % `infinity' bowls
+erase fill (w-3.5u,h+o)--(w,h+o)
+ --(w,-o)--(w-3.5u,-o)--cycle; % erase excess
+penlabels(1,2,3,4,5,6,7,8,9); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Empty set symbol";
+beginchar(oct"172",9u#,body_height#,body_height#-asc_height#);
+adjust_fit(0,0);
+penpos1(vair,90); penpos3(vair,-90); penpos2(stem,180); penpos4(stem,0);
+if not monospace: interim superness:=sqrt(more_super*hein_super); fi
+x2r=hround max(.7u,1.45u-.5stem);
+x4r=w-x2r; x1=x3=.5w; y1r=asc_height+o; y3r=-o;
+y2=y4=.5asc_height-vair_corr; y2l:=y4l:=.52asc_height;
+penstroke pulled_arc.e(1,2) & pulled_arc.e(2,3)
+ & pulled_arc.e(3,4) & pulled_arc.e(4,1) & cycle; % bowl
+pickup rule.nib; lft x6=hround 2u-eps; x5=w-x6; top y5=h+o; bot y6=-d-o;
+draw z5--z6; % diagonal
+penlabels(1,2,3,4,5,6); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Nabla or backwards-difference operator";
+beginchar(oct"050",15u#,cap_height#,0);
+adjust_fit(0,0);
+numeric right_stem,alpha;
+right_stem=cap_hair if hefty: -3stem_corr fi;
+x1l=w-x4r=.75u; y1=y4=h;
+x2-x1=x4-x3; x3l=x2l+apex_corr; y2=y3=-apex_o-apex_oo;
+alpha=diag_ratio(2,right_stem,y1-y2,x4r-x1l-apex_corr);
+penpos1(alpha*cap_stem,0); penpos2(alpha*cap_stem,0);
+penpos3(alpha*right_stem,0); penpos4(alpha*right_stem,0);
+fill diag_end(2l,1l,1,1,4r,3r)--diag_end(4r,3r,1,1,2l,1l)--cycle; % triangle
+z0=whatever[z1r,z2r]=whatever[z3l,z4l];
+y5=y6=h-cap_vstem; z5=whatever[z1r,z2r]; z6=whatever[z3l,z4l];
+if y0>cap_notch_cut: y0:=cap_notch_cut;
+ unfill z0+.5right{up}...{z4-z3}z6--z5{z2-z1}
+ ...{down}z0+.5left--cycle; % counter
+else: unfill z0--z5--z6--cycle; fi % counter
+penlabels(0,1,2,3,4,5,6); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Section sign";
+beginchar(oct"070",6.5u#+max(1.5u#,stem#),asc_height#,desc_depth#);
+adjust_fit(0,0); pickup fine.nib;
+numeric sstem; sstem=hround .75[hair,stem];
+pos0(stem,0); pos1(hair,0); pos2(vair,90); pos3(sstem,180); pos4(vair,270);
+pos5'(sstem,0); pos5(sstem,180);
+pos6(vair,90); pos7(sstem,0); pos8(vair,-90); pos9(hair,-180); pos10(stem,-180);
+top y2r=h+oo; bot y8r=-d-oo; y2-y1=y9-y8=(y2-y8)/8;
+y3=.52[y4,y2]; y5=.52[y4,y6]; y7=.52[y6,y8]; y5'=.52[y6,y4];
+y2-y4=y4-y6=y6-y8;
+rt x1r=hround(w-1.5u); lft x3r=hround 1.25u;
+x2=x4=x6=x8=.5w; x5=x7=w-x3; x5'=x3; x9=w-x1;
+bulb(2,1,0); bulb(8,9,10); % bulbs
+filldraw stroke z2e{left}...z3e{down}...z4e{3(x5-x3),y5-y3}
+ ...z5e{down}...{left}z6e; % upper stroke
+filldraw stroke z4e{left}...z5'e{down}...z6e{3(x7-x5'),y7-y5'}
+ ...z7e{down}...{left}z8e; % upper stroke
+penlabels(0,1,2,3,4,5,6,7,8,9,10); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Double dagger mark";
+beginchar(oct"131",8u#,asc_height#,desc_depth#);
+adjust_fit(0,0); pickup fine.nib;
+pos1(stem,0); pos2(thin_join,0); pos3(stem,0);
+pos4(stem,90); pos2'(thin_join,90); pos5(stem,90); z2'=z2;
+x1=x2=x3; x1-.5stem=hround(.5w-.5stem); w:=r:=2x1;
+x4-.5stem=hround u; x5=w-x4;
+y1+.5stem=h+oo; y2=y4=y5=.5[y1,y3]; y3-.5stem=ceiling(.5[-d,h]);
+filldraw circ_stroke z1e{down}..{down}z2e; % top stem
+filldraw circ_stroke z3e{up}..{up}z2e; % upper middle stem
+filldraw circ_stroke z4e{right}..{right}z2'e; % top left bulb
+filldraw circ_stroke z5e{left}..{left}z2'e; % top right bulb
+pos6(stem,0); pos7(thin_join,0); pos8(stem,0);
+pos9(stem,90); pos7'(thin_join,90); pos0(stem,90); z7'=z7;
+x6=x7=x8=x1; x9=x4; x0=x5;
+y6=y3-stem-1; y7=y9=y0=.5[y6,y8]; y8-.5stem=-d-oo;
+filldraw circ_stroke z6e{down}..{down}z7e; % lower middle stem
+filldraw circ_stroke z8e{up}..{up}z7e; % bottom stem
+filldraw circ_stroke z9e{right}..{right}z7'e; % bottom left bulb
+filldraw circ_stroke z0e{left}..{left}z7'e; % bottom right bulb
+penlabels(1,2,3,4,5,6,7,8,9,0); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Minus";
+beginarithchar(oct"055"); pickup rule.nib;
+lft x1=hround 1.5u-eps; x2=w-x1; y1=y2=math_axis;
+draw z1--z2; % bar
+labels(1,2); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Plus-or-minus sign";
+beginarithchar(oct"010"); pickup rule.nib;
+numeric shiftup; shiftup=vround 1.5u;
+x1=x2=.5w; lft x3=lft=x5=hround u-eps; x4=x6=w-x3;
+.5[y1,y2]=y3=y4=math_axis+shiftup; top y1=h+shiftup; y5=y6=y2;
+draw z1--z2; % stem
+draw z3--z4; % plus bar
+draw z5--z6; % minus bar
+labels(1,2,3,4,5,6); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Downward arrow";
+beginchar(oct"067",9u#,asc_height#,asc_depth#);
+adjust_fit(0,0); pickup crisp.nib;
+pos1(rule_thickness,0); pos2(rule_thickness,0);
+pos3(bar,90); pos4(bar,90);
+lft x1l=hround(.5w-.5rule_thickness); y1+.5rule_thickness=h;
+x0=x1=x2; bot y0=-d; x0-x3=x4-x0=3u+eps;
+y3=y4=y0+.24asc_height+eps;
+pos5(bar,angle(z4-z0)); z5l=z0;
+pos6(bar,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+numeric t; path p; p=z4r{z9-z4}..z6r;
+t=xpart(p intersectiontimes((x2r,-d)--(x2r,h))); y2=ypart point t of p;
+filldraw z0..{z4-z9}z4l--subpath (0,t) of\\(z4r{z9-z4}..z6r)
+ --z2r---z1r..z1l---z2l--subpath (t,0) of\\(z3r{z9-z3}..z5r)
+ --z3l{z9-z3}..z0 & cycle; % arrowhead and stem
+penlabels(0,1,2,3,4,5,6,9); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Upward arrow";
+beginchar(oct"066",9u#,asc_height#,asc_depth#);
+italcorr .76asc_height#*slant+.5crisp#-u#;
+adjust_fit(0,0); pickup crisp.nib;
+pos1(rule_thickness,0); pos2(rule_thickness,0);
+pos3(bar,90); pos4(bar,90);
+lft x1l=hround(.5w-.5rule_thickness); y1-.5rule_thickness=-d;
+x0=x1=x2; top y0=h; x0-x3=x4-x0=3u+eps;
+y3=y4=y0-.24asc_height-eps;
+pos5(bar,angle(z4-z0)); z5l=z0;
+pos6(bar,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+numeric t; path p; p=z4l{z9-z4}..z6r;
+t=xpart(p intersectiontimes((x2r,-d)--(x2r,h))); y2=ypart point t of p;
+filldraw z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6r)
+ --z2r---z1r..z1l---z2l--subpath (t,0) of\\(z3l{z9-z3}..z5r)
+ --z3r{z9-z3}..z0 & cycle; % arrowhead and stem
+penlabels(0,1,2,3,4,5,6,9); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Leftward arrow";
+compute_spread(.45x_height#,.55x_height#);
+beginchar(oct"064",18u#,v_center(spread#+rule_thickness#));
+adjust_fit(0,0); pickup crisp.nib;
+pos1(rule_thickness,90); pos2(rule_thickness,90); pos3(bar,0); pos4(bar,0);
+y0=y1=y2=math_axis; x1+.5rule_thickness=hround(w-u); lft x0=hround u;
+y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0+3u+eps;
+pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+numeric t; path p; p=z4r{z9-z4}..z6r;
+t=xpart(p intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p;
+filldraw z0..{z4-z9}z4l--subpath (0,t) of\\(z4r{z9-z4}..z6r)
+ --z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3r{z9-z3}..z5r)
+ --z3l{z9-z3}..z0 & cycle; % arrowhead and stem
+penlabels(0,1,2,3,4,5,6,9); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Rightward arrow";
+compute_spread(.45x_height#,.55x_height#);
+beginchar(oct"065",18u#,v_center(spread#+rule_thickness#));
+adjust_fit(0,0); pickup crisp.nib;
+pos1(rule_thickness,90); pos2(rule_thickness,90); pos3(bar,0); pos4(bar,0);
+y0=y1=y2=math_axis; x1-.5rule_thickness=hround u; rt x0=hround(w-u);
+y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0-3u-eps;
+pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+numeric t; path p; p=z4l{z9-z4}..z6r;
+t=xpart(p intersectiontimes((0,y2l)--(w,y2l))); x2=xpart point t of p;
+filldraw z0..{z4-z9}z4r--subpath (0,t) of\\(z4l{z9-z4}..z6r)
+ --z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3l{z9-z3}..z5r)
+ --z3r{z9-z3}..z0 & cycle; % arrowhead and stem
+penlabels(0,1,2,3,4,5,6,9); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Proper subset sign";
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"032",14u#,v_center(spread#+rule_thickness#));
+italcorr h#*slant-u#;
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x2=hround 1.5u-eps; x1=x3=w-x2;
+y1-y3=spread; y2=.5[y1,y3]=math_axis;
+x4=x5=.5w; y4=y1; y5=y3;
+draw z1---z4...z2{down}...z5---z3; % arc and bars
+labels(1,2,3,4,5); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Proper superset sign";
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"033",14u#,v_center(spread#+rule_thickness#));
+italcorr h#*slant-u#;
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x1=hround 1.5u-eps; x2=w-x1; x3=x1;
+y1-y3=spread; y2=.5[y1,y3]=math_axis;
+x4=x5=.5w; y4=y1; y5=y3;
+draw z1---z4...z2{down}...z5---z3; % arc and bars
+labels(1,2,3,4,5); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Element sign";
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"037",12u#,v_center(spread#+rule_thickness#));
+italcorr h#*slant-u#;
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x2=hround 1.5u-eps; x1=x3=x6=w-x2;
+y1-y3=spread; y2=y6=.5[y1,y3]=math_axis;
+x4=x5=.5w+u; y4=y1; y5=y3;
+draw z1---z4...z2{down}...z5---z3; % arc and bars
+draw z2--z6; % middle bar
+labels(1,2,3,4,5,6); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Logical not sign";
+beginchar(oct"035",12u#,x_height#,0);
+italcorr x_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x1=hround u-eps; x2=x3=w-x1;
+y1=y2=good.y .5[bar_height,h]; y2-y3=1.2(h-bar_height);
+draw z1--z2--z3; % bar and stem
+labels(1,2,3); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Less than sign";
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"074",14u#,v_center(spread#+rule_thickness#));
+italcorr h#*slant-u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x2=hround 1.5u-eps; x1=x3=w-x2;
+y1-y3=spread; y2=.5[y1,y3]=math_axis;
+draw z1--z2--z3; % diagonals
+labels(1,2,3); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Greater than sign";
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"076",14u#,v_center(spread#+rule_thickness#));
+italcorr math_axis#*slant-u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x2=hround(w-1.5u)+eps; x1=x3=w-x2;
+y1-y3=spread; y2=.5[y1,y3]=math_axis;
+draw z1--z2--z3; % diagonals
+labels(1,2,3); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Unequals sign";
+compute_spread(.45x_height#,.55x_height#);
+beginchar(oct"063",14u#,v_center(4spread#+rule_thickness#));
+italcorr h#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x1=hround u-eps; x3=x1; x2=x4=w-x1;
+y1=y2; y3=y4; y1-y3=spread; .5[y1,y3]=math_axis;
+draw z1--z2; draw z3--z4; % bars
+lft x6=hround 3.5u-eps; x5=w-x6; top y5=h+o; bot y6=-d-o;
+draw z5--z6; % diagonal
+labels(1,2,3,4,5,6); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Less than or equal to sign";
+compute_spread(.45x_height#,.55x_height#);
+spread#':=spread#; spread':=spread; % the spread of `$=$'
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"011",14u#,v_center(spread#'+spread#+rule_thickness#));
+italcorr h#*slant-u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x2=hround 1.5u-eps; x1=x3=w-x2;
+y1-y3=spread; y2=.5[y1,y3]; top y1=h;
+draw z1--z2--z3; % diagonals
+x8=x1; x9=x2; y8=y9; y3-y9=spread'; draw z8--z9; % bar
+labels(1,2,3,8,9); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Greater than or equal to sign";
+compute_spread(.45x_height#,.55x_height#);
+spread#':=spread#; spread':=spread; % the spread of `$=$'
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(oct"012",14u#,v_center(spread#'+spread#+rule_thickness#));
+italcorr h#*slant-u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x1=hround 1.5u-eps; x2=w-x1; x3=x1;
+y1-y3=spread; y2=.5[y1,y3]; top y1=h;
+draw z1--z2--z3; % diagonals
+x8=x1; x9=x2; y8=y9; y3-y9=spread'; draw z8--z9; % bar
+labels(1,2,3,8,9); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Equivalence or congruence sign";
+compute_spread(.45x_height#,.55x_height#);
+beginchar(oct"060",14u#,v_center(2spread#+rule_thickness#));
+italcorr h#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x1=hround u-eps; x3=x5=x1; x2=x4=x6=w-x1;
+y1=y2; y3=y4=math_axis; y5=y6; y1-y3=y3-y5=spread;
+draw z1--z2; % upper bar
+draw z3--z4; % middle bar
+draw z5--z6; % lower bar
+labels(1,2,3,4,5,6); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Reverse slash (backslash)";
+beginchar(oct"134",9u#,body_height#,paren_depth#);
+adjust_fit(0,0); pickup rule.nib;
+lft x1=hround u-eps; top y1=h+eps;
+rt x2=hround(w-u)+eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+labels(1,2); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Vertical line";
+beginchar(oct"174",5u#,body_height#,paren_depth#);
+italcorr body_height#*slant+.5rule_thickness#-2u#;
+adjust_fit(0,0); pickup rule.nib;
+x1=x2=good.x .5w; top y1=h+eps; bot y2=-d-eps;
+draw z1--z2; % stem
+labels(1,2); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Left curly brace";
+beginchar(oct"173",9u#,body_height#,paren_depth#);
+italcorr body_height#*slant+.5vair#-u#;
+adjust_fit(0,0); pickup fine.nib;
+forsuffixes $=1,1',4,4',7,7': pos$(vair,0); endfor
+forsuffixes $=2,3,5,6: pos$(stem,0); endfor
+x2=x3=x5=x6; x1=x1'=x7=x7'=w-x4=w-x4';
+lft x4l=hround(1.5u-.5vair); lft x2l=hround(.5w-.5stem);
+top y1=h; bot y7=-d; .5[y4,y4']=.5[y1,y7]=.5[y2,y6]=.5[y3,y5];
+y1-y2=y3-y4=(y1-y4)/4; y1-y1'=y4-y4'=y7'-y7=vair-fine;
+filldraw z1l{left}...z2l---z3l...{left}z4l
+ --z4'l{right}...z5l---z6l...{right}z7l
+ --z7r--z7'r{left}...z6r---z5r...{left}.5[z4r,z4'r]{right}
+ ...z3r---z2r...{right}z1'r--z1r--cycle; % stroke
+penlabels(1,2,3,4,5,6,7); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Right curly brace";
+beginchar(oct"175",9u#,body_height#,paren_depth#);
+italcorr math_axis#*slant+.5vair#-u#;
+adjust_fit(0,0); pickup fine.nib;
+forsuffixes $=1,1',4,4',7,7': pos$(vair,0); endfor
+forsuffixes $=2,3,5,6: pos$(stem,0); endfor
+x2=x3=x5=x6; x1=x1'=x7=x7'=w-x4=w-x4';
+rt x4r=hround(w-1.5u+.5vair); rt x2r=hround(.5w+.5stem);
+top y1=h; bot y7=-d; .5[y4,y4']=.5[y1,y7]=.5[y2,y6]=.5[y3,y5];
+y1-y2=y3-y4=(y1-y4)/4; y1-y1'=y4-y4'=y7'-y7=vair-fine;
+filldraw z1r{right}...z2r---z3r...{right}z4r
+ --z4'r{left}...z5r---z6r...{left}z7r
+ --z7l--z7'l{right}...z6l---z5l...{right}.5[z4l,z4'l]{left}
+ ...z3l---z2l...{left}z1'l--z1l--cycle; % stroke
+penlabels(1,2,3,4,5,6,7); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Straight double quotes";
+beginchar(oct"042",9u#,asc_height#,0);
+numeric top_width#,spread#; top_width#=if serifs: flare# else: stem# fi;
+spread#=max(3u#,top_width#+.5u#); define_pixels(spread);
+italcorr asc_height#*slant+.5top_width#+.5spread#-4u#;
+adjust_fit(0,0);
+x1=x2; x3=x4=w-x1; x3-x1=spread+2; y1=y3;
+y2=y4=max(.5[bar_height,x_height]+.5vair,h-x_height);
+if serifs: pickup crisp.nib; pos1(flare,0); pos2(vair,0);
+ pos3(flare,0); pos4(vair,0);
+ y1+.5stem=h; filldraw circ_stroke z1e--z2e; % left stem and bulb
+ filldraw circ_stroke z3e--z4e; % right stem and bulb
+else: pickup fine.nib; pos1(stem,0); pos2(vair,0);
+ pos3(stem,0); pos4(vair,0);
+ top y1=h; filldraw stroke z1e--z2e; % left stem
+ filldraw stroke z3e--z4e; fi % right stem
+penlabels(1,2,3,4); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Infinity";
+beginchar(oct"001",18u#,x_height#,0);
+italcorr .7x_height#*slant-.5u#;
+adjust_fit(0,0); pickup fine.nib;
+numeric theta,phi;
+if monospace: phi=-theta=90;
+else: phi=angle(4u,h); theta=angle(6u,-h); fi
+pos1(vair,180); pos2(.5[vair,curve],90+.5theta); pos3(curve,90+theta);
+pos4(curve,90+theta); pos5(.5[vair,curve],90+.5theta);
+pos6(vair,180); pos7(.2[vair,curve],270+.5phi);
+pos8(.3[vair,curve],270+phi); pos9(.2[vair,curve],270+.5phi);
+lft x1r=w-rt x6l=hround u; x2=x9=.4[x1,x8]; x5=x7=.6[x8,x6];
+if monospace: x2l:=x2r; x5r:=x5l; x7r:=x7l; x9l:=x9r; fi
+y1=y6=.5h; top y2r=top y7l=h+oo; bot y5l=bot y9r=-oo;
+x8=.5[x3,x4]=.5w; y8=.5[y3,y4]=.5h;
+y3-y4=h/3; z3-z4=whatever*dir theta;
+filldraw stroke z1e{up}...z2e{right}...z3e---z4e...z5e{right}
+ ...z6e{up}...z7e{left}...{-dir phi}z8e...{left}z9e...z1e{up}; % bowls
+penlabels(1,2,3,4,5,6,7,8,9); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Set union sign";
+beginchar(oct"005",12u#,.8asc_height#,0);
+italcorr .8asc_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x1=hround u; x2=x1; x3=w-x3; x4=x5=w-x1;
+y1=good.y h+o; bot y3=-o; y2=y4=2/3[y1,y3]; y5=y1;
+draw z1---z2...z3...z4---z5; % stems and cup
+labels(1,2,3,4,5); endchar;
+
+% From font cmsy10, file sym.mf
+cmchar "Set intersection sign";
+beginchar(oct"034",12u#,.8asc_height#,0);
+italcorr .8asc_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x1=hround u; x2=x1; x3=w-x3; x4=x5=w-x1;
+y3=good.y h+o; bot y1=-o; y2=y4=2/3[y1,y3]; y5=y1;
+draw z1---z2...z3...z4---z5; % stems and cap
+labels(1,2,3,4,5); endchar;
+
+% My own creation
+cmchar "Square root extender";
+beginchar(oct"006",12u#,14u#,0);
+ adjust_fit(0,0); pickup rule.nib;
+ bot lft z1=(0,h); bot rt z2=(w+2u,h); draw z1--z2;
+ penlabels(1,2);
+endchar;
+
+% From font cmsy10, file symbol.mf (hacked up to be above baseline)
+cmchar "Radical sign";
+beginchar(oct"013",15u#,14u#,2u#);
+ adjust_fit(0,-letter_fit#); pickup rule.nib;
+ x1=good.x 4/9w; x2=good.x(w+.5); bot y1=-2u; bot y2=14u;
+ draw z1--z2; % diagonal
+ pickup crisp.nib; pos3(max(curve,rule_thickness),0);
+ x3l=1.5[x2,x1]; y3=.5[y1,y2];
+ pos4(rule_thickness,0); x4=x1; bot y4=-2u;
+ pos5(vair,-45); x5l=good.x(x3l-u); z5l=whatever[z3r,z2];
+ z6=z5r+whatever*(z2-z3r)=whatever[z3l,z4l];
+ z7=whatever[z1,z2]=z3r+whatever*(z4l-z3l);
+ filldraw z5r--z6--z4l--z4--z7--z3r--z5l--cycle; % left diagonal and serif
+ penlabels(1,2,3,4,5,6,7);
+endchar;
+
+% The following TRW logo is designed by Mike Urban and put in the Bell
+% System logo position. The Bell System logo is not even used by AT&T
+% anymore and I work for TRW---so there. There is some perverse
+% appropriateness in having the escape sequence \(bs.
+def fixpt(expr pta,ptb,theta)=
+ if known xpart pta:
+ ((ypart pta)-(ypart ptb))/((xpart pta)-(xpart ptb))=
+ (sind theta)/(cosd theta);
+ else:
+ ((xpart pta)-(xpart ptb))/((ypart pta)-(ypart ptb))=
+ (cosd theta)/(sind theta);
+ fi;
+enddef;
+
+def over(expr pta,ptb,delta)=
+ xpart pta = (xpart ptb)+(delta/cosd 20);
+enddef;
+
+input logodesign;
+
+a#:=cap_height#/3.91;
+define_pixels(a);
+beginchar(oct"007", 12.82a#, 3.91a#, 0);
+LOGO;
+endchar;
+
+% From the font cmsy10, file sym.mf
+cmchar "Integral sign";
+beginchar(oct"015",5.25u#+max(1.25u#,stem#)+2max(1.5u#,curve#),
+ asc_height#,desc_depth#);
+italcorr asc_height#*slant-.5u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(curve,0); pos2(hair,0); pos3(vair,90); pos4(.6[hair,stem],180);
+pos5(stem,180); pos5'(stem,0); z5'=z5; pos6(.6[hair,stem],0);
+pos7(vair,-90); pos8(hair,-180); pos9(curve,-180);
+x7=w-x3=2.4u; rt x1r=max(rt x3+eps,hround(w-u)); x9=w-x1;
+x5=.5[x4,x6]; x4-x6=1.5u; lft x5r=hround(.5w-.5stem);
+y9-.5curve=vround(-.9d-o+vair); y3-y1=y9-y7;
+top y3r=h+o; bot y7r=-d-o; y5=.5[y3,y7]=.5[y4,y6]; y4-y6=2/3(y3-y7);
+bulb(3,2,1); bulb(7,8,9); % bulbs
+filldraw stroke z3e{left}...z4e{(z5e-z4e)xscaled 1.1}
+ ..tension atleast 1 and atleast .8..{z5-z4}z5e; % upper stem
+filldraw stroke z5'e{z6-z5}..tension atleast.8 and atleast 1
+ ..{(z6e-z5'e)xscaled 1.1}z6e...{left}z7e; % lower stem
+math_fit(0,-2u#);
+% It looks better with troff if we move it over 1 unit to the left
+currentpicture:=currentpicture shifted (-1u,0);
+penlabels(1,2,3,4,5,6,7,8,9); endchar;
+
+% From the font cmr10, file punct.mf
+cmchar "Hash mark (number sign)";
+if monospace: compute_spread(.6x_height#,.7x_height#);
+else: compute_spread(.45x_height#,.55x_height#); fi
+beginchar("#",15u#,asc_height#,asc_depth#);
+italcorr (math_axis#+.5(spread#+rule_thickness#))*slant-.5u#;
+adjust_fit(0,0);
+pickup rule.nib; lft x1=hround u-eps; x3=x1; x2=x4=w-x1;
+y1=y2; y3=y4; y1-y3=spread; .5[y1,y3]=math_axis;
+draw z1--z2; % upper bar
+draw z3--z4; % lower bar
+lft x6=hround 3u; rt x7=hround(w-3u); x5-x6=x7-x8;
+x8=good.x if monospace: .6 else: .5 fi\\w;
+top y5=top y7=h+eps; bot y6=bot y8=-d-eps;
+y15=y1; z15=whatever[z5,z6]; y36=y3; z36=whatever[z5,z6];
+y27=y2; z27=whatever[z7,z8]; y48=y4; z48=whatever[z7,z8];
+draw z5--if x5>x6+1:(good.x(x15+.5),y1)--(good.x(x15-.5),y1)
+ --(good.x(x36+.5),y3)--(good.x(x36-.5),y3)--fi\\z6; % left diagonal
+draw z7--if x7>x8+1:(good.x(x27+.5),y2)--(good.x(x27-.5),y2)
+ --(good.x(x48+.5),y4)--(good.x(x48-.5),y4)--fi\\z8; % right diagonal
+labels(1,2,3,4,5,6,7,8,15,27,36,48); endchar;
+
+% From font cmr10, file punct.mf
+cmchar "Plus sign";
+beginarithchar("+"); pickup rule.nib;
+x1=x2=good.x .5w; top y1=h+eps; .5[y1,y2]=math_axis;
+lft x3=hround u-eps; x4=w-x3; y3=y4=math_axis;
+draw z1--z2; % stem
+draw z3--z4; % crossbar
+labels(1,2,3,4); endchar;
+
+% From font cmr10, file accent.mf
+cmchar "Grave accent";
+beginchar(oct"140",9u#,min(asc_height#,2x_height#),0);
+adjust_fit(0,0);
+if serifs: pickup crisp.nib; x1-.5stem=hround 2u; x2=2/3[x1,w-x1];
+ y1+.5stem=h+eps; y2=max(2/3[h,x_height],x_height+o+hair);
+ numeric theta; theta=angle(z2-z1)+90;
+ pos1(stem,theta); pos2(hair,theta);
+ filldraw circ_stroke z1e--z2e; % diagonal
+else: pickup fine.nib; pos1(stem,0); pos2(vair,0);
+ lft x1l=hround 1.5u; rt x2r=hround(.5w+.25u+.5vair);
+ top y1=h; bot y2=vround 2/3[h,x_height];
+ filldraw stroke z1e--z2e; fi % diagonal
+penlabels(1,2); endchar;
+
+% From font cmr10, file accent.mf
+cmchar "Acute accent";
+beginchar(oct"047",9u#,min(asc_height#,2x_height#),0);
+italcorr h#*slant-if serifs: 1.5 fi u#;
+adjust_fit(0,0);
+if serifs: pickup crisp.nib; x1+.5stem=hround(w-2u); x2=2/3[x1,w-x1];
+ y1+.5stem=h+eps; y2=max(2/3[h,x_height],x_height+o+hair);
+ numeric theta; theta=angle(z2-z1)+90;
+ pos1(stem,theta); pos2(hair,theta);
+ filldraw circ_stroke z1e--z2e; % diagonal
+else: pickup fine.nib; pos1(stem,0); pos2(vair,0);
+ rt x1r=hround(w-1.5u); lft x2l=hround(.5w-.25u-.5vair);
+ top y1=h; bot y2=vround 2/3[h,x_height];
+ filldraw stroke z1e--z2e; fi % diagonal
+penlabels(1,2); endchar;
+
+% From font cmr10, file punct.mf
+cmchar "Equals sign";
+compute_spread(.45x_height#,.55x_height#);
+beginchar("=",14u#,v_center(spread#+rule_thickness#));
+italcorr h#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x1=hround u-eps; x3=x1; x2=x4=w-x1;
+y1=y2; y3=y4; y1-y3=spread; .5[y1,y3]=math_axis;
+draw z1--z2; % upper bar
+draw z3--z4; % lower bar
+labels(1,2,3,4); endchar;
+
+% From font cmr10, file punct.mf
+cmchar "At sign";
+beginchar("@",14u#,asc_height#,0);
+italcorr .7asc_height#*slant-.5u#;
+adjust_fit(0,if hefty or monospace:-2u# else: 0 fi);
+pickup fine.nib; pos0(fudged.hair,0); pos1(vair,90);
+pos2(fudged.stem,180); pos3(vair,270);
+pos4(fudged.stem,-180); pos5(fudged.stem,-180);
+pos6(vair,-90); pos7(fudged.hair,0);
+pos8(vair,90); pos9(fudged.hair,180);
+pos10(vair,270); pos11(.5[vair,flare],360);
+x1=x3=.5[x0,x2]; y0=y2=.5[y1,y3];
+x8=x10=.5w; y7=y9=.5[y8,y10];
+lft x9r=hround u; x7=w-x9; top y8r=h+oo; bot y10r=-oo;
+top y1r=vround(.8[y10,y8]+.5vair); bot y3r=vround(.2[y10,y8]-.5vair);
+x6l=1/3[x5l,x7l]; y6=y3; y11=good.y(.1[y10,y8]-.5);
+x0=x4=x5; y4=.8[y3,y1]; y5=2/3[y7,y6];
+if hefty or monospace: lft x2r=hround(5u-.5fudged.stem);
+ rt x0r=hround(w-3u); x11r=x0r;
+else: lft x2r=hround 3.4u; x0=w-x2; x11r=x7r; fi
+filldraw stroke super_arc.e(1,2) & super_arc.e(2,3); % left inner bowl
+filldraw stroke super_arc.e(3,0) & super_arc.e(0,1); % right inner bowl
+filldraw stroke super_arc.e(8,9) & super_arc.e(9,10)
+ & term.e(10,11,right,1,4); % left outer bowl and terminal
+if hefty or monospace: {{interim superness:=hein_super;
+ filldraw stroke super_arc.e(0,8)}}; % link
+else: (x,y6r)=whatever[z6l,z7l]; x6r:=x;
+ filldraw stroke z4e---z5e...z6e{right}...{up}z7e
+ & super_arc.e(7,8); fi % stem and link
+penlabels(0,1,2,3,4,5,6,7,8,9,10,11); endchar;
+
+% From font cmr10, file accent.mf
+cmchar "Tilde (squiggle) accent";
+beginchar(oct"176",9u#,min(asc_height#,10/7x_height#+.5dot_size#),0);
+italcorr h#*slant-u#;
+adjust_fit(0,0);
+if serifs: numeric theta; theta=angle(1/6(6u-vair),1/4(h-x_height));
+ pickup crisp.nib; numeric mid_width; mid_width=.4[vair,stem];
+ pos1(vair,theta+90); pos2(vair,theta+90);
+ pos3(vair,theta+90); pos4(vair,theta+90);
+ z2-z1=z4-z3=(mid_width-crisp)*dir theta;
+ lft x1r=w-rt x4l=hround 1.5u; top y4r=h;
+ bot y1l=vround(bot y1l+min(2/3[x_height,h],y3l-.25vair)-top y1r);
+ pair delta; ypart delta=3(y3l-y1l); delta=whatever*dir theta;
+ filldraw z1l..controls(z1l+delta)and(z3l-delta)..z3l..z4l
+ --z4r..controls(z4r-delta)and(z2r+delta)..z2r..z1r--cycle; % stroke
+else: pickup fine.nib; pos1(vair,180); pos2(vair,90);
+ pos3(.5[vair,slab],90); pos4(vair,90); pos5(vair,180);
+ lft x1r=w-rt x5l=hround 1.5u; x2-x1=x3-x2=x4-x3=x5-x4;
+ bot y1=bot y4l=vround(.75[x_height,h]-vair);
+ top y2r=top y5=h; y3=.5[y2,y4];
+ filldraw stroke z1e{up}...z2e{right}..z3e..{right}z4e...{up}z5e; fi % stroke
+penlabels(1,2,3,4,5); endchar;
+
+% From font cmsy10, file symbol.mf
+cmchar "Circle for copyright, etc.";
+beginchar(oct"135",18u#,asc_height#,desc_depth#); autorounded;
+adjust_fit(if monospace:-3u#,-3u# else: 0,0 fi); pickup rule.nib;
+lft x6=hround u; x2=w-x6; top y8=h+o; bot y4=-d-o;
+circle_points; draw_circle; % circle
+labels(1,2,3,4,5,6,7,8); endchar;
+
+% From font cmr10, file accent.mf
+cmchar "Circumflex (hat) accent";
+beginchar(oct"041",9u#,min(asc_height#,2x_height#),0);
+if serifs: italcorr .5[x_height#,h#]*slant+.5hair#-1.75u#;
+ adjust_fit(0,0);
+ pickup crisp.nib; pos2(.5[vair,curve],90); top y2r=h; x2=.5w;
+ x1=w-x3=good.x 2.25u; y1=y3=.5[x_height,y2];
+ pos1(hair,angle(z2-z1)+90); pos3(hair,angle(z3-z2)+90);
+ filldraw stroke z1e--z2e--z3e; % diagonals
+else: italcorr 2/3[x_height#,h#]*slant-.5stem#+.5vair#-.75u#;
+ adjust_fit(0,0);
+ pickup fine.nib; pos1(vair,0); pos3(vair,0); x1=w-x3;
+ pos2(stem,0); top y2=h; x2=.5w; bot y1=bot y3=vround 2/3[h,x_height]-eps;
+ lft x1l=hround(rt x2r-3.25u-.5vair); % same slope as in the acute accent
+ z0=whatever[z1r,z2r]=whatever[z2l,z3l];
+ y4l=y4r=y2; x4l=good.x .2[x2l,x2]; x4r=w-x4l;
+ filldraw z4l--z1l--z1r--z0--z3l--z3r--z4r--cycle; fi % diagonals
+penlabels(0,1,2,3,4); endchar;
+
+% From font cmr10, file accent.mf
+cmchar "Circumflex (hat) accent";
+beginchar(oct"136",9u#,min(asc_height#,2x_height#),0);
+if serifs: italcorr .5[x_height#,h#]*slant+.5hair#-1.75u#;
+ adjust_fit(0,0);
+ pickup crisp.nib; pos2(.5[vair,curve],90); top y2r=h; x2=.5w;
+ x1=w-x3=good.x 2.25u; y1=y3=.5[x_height,y2];
+ pos1(hair,angle(z2-z1)+90); pos3(hair,angle(z3-z2)+90);
+ filldraw stroke z1e--z2e--z3e; % diagonals
+else: italcorr 2/3[x_height#,h#]*slant-.5stem#+.5vair#-.75u#;
+ adjust_fit(0,0);
+ pickup fine.nib; pos1(vair,0); pos3(vair,0); x1=w-x3;
+ pos2(stem,0); top y2=h; x2=.5w; bot y1=bot y3=vround 2/3[h,x_height]-eps;
+ lft x1l=hround(rt x2r-3.25u-.5vair); % same slope as in the acute accent
+ z0=whatever[z1r,z2r]=whatever[z2l,z3l];
+ y4l=y4r=y2; x4l=good.x .2[x2l,x2]; x4r=w-x4l;
+ filldraw z4l--z1l--z1r--z0--z3l--z3r--z4r--cycle; fi % diagonals
+penlabels(0,1,2,3,4); endchar;
+
+% My own creation
+cmchar "Box rule";
+beginchar(oct"132",1u#,cap_height#+2u#,4.3u#);
+italcorr body_height#*slant+.5rule_thickness#-2u#;
+adjust_fit(0,0); pickup crisp.nib;
+pos1(vair,0); pos2(vair,0);
+x1=x2=hround 0; y1=h; y2=-d;
+filldraw stroke z1e--z2e; % stem
+penlabels(1,2); endchar;
+
+% My own creation. Only used by otroff. See note below.
+cmchar "Underscore";
+beginchar("_",9.4u#,x_height#,.7u#);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric below_baseline; below_baseline#:=4u#;
+define_pixels(below_baseline);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(-below_baseline); x2=hround(w);
+x1=0;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+% My own creation (This is only used by ditroff. Ditroff's underscore
+% needs to be a frog's hair longer than otroff's.)
+cmchar "Underscore";
+beginchar(oct"041",9.4u#,x_height#,.7u#);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric below_baseline; below_baseline#:=4u#;
+define_pixels(below_baseline);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(-below_baseline); x2=hround(w+1u);
+x1=0;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+% The delimiters are from the font cmex10, file bigdel.mf. I had to hack
+% them up extensively though to get them to work with troff. Troff wants
+% everything lined up in the center and the widths of the floor and ceiling
+% characters are the same as the parentheses.
+cmchar "Extensible left bracket---top";
+beginchar(oct"022",8u#,cap_height#+2u#,4u#);
+adjust_fit(0,0); pickup fine.nib;
+pos1(heavy_rule_thickness,0); pos2(heavy_rule_thickness,0);
+top y1=h; y2=-d; x1=x2=hround(.5w);
+filldraw stroke z1e--z2e; % stem
+pos3(heavy_rule_thickness,90); pos4(heavy_rule_thickness,90);
+x3=x1l; rt x4=hround(w-.75u+.5heavy_rule_thickness); y3r=y4r=y1;
+filldraw stroke z3e--z4e; % upper bar
+penlabels(1,2,3,4); endchar;
+
+cmchar "Extensible left bracket---bottom";
+beginchar(oct"020",8u#,cap_height#+4u#,2u#);
+adjust_fit(0,0); pickup fine.nib;
+pos1(heavy_rule_thickness,0); pos2(heavy_rule_thickness,0);
+y1=h; bot y2=-d; x1=x2=hround(.5w);
+filldraw stroke z1e--z2e; % stem
+pos5(heavy_rule_thickness,90); pos6(heavy_rule_thickness,90);
+x5=x1l; rt x6=hround(w-.75u+.5heavy_rule_thickness); y5l=y6l=y2;
+filldraw stroke z5e--z6e; % lower bar
+penlabels(1,2,5,6); endchar;
+
+cmchar "Extensible right bracket---top";
+beginchar(oct"023",8u#,cap_height#+2u#,4u#);
+adjust_fit(0,0); pickup fine.nib;
+pos1(heavy_rule_thickness,0); pos2(heavy_rule_thickness,0);
+top y1=h; y2=-d; x1=x2=hround(.5w);
+filldraw stroke z1e--z2e; % stem
+pos3(heavy_rule_thickness,90); pos4(heavy_rule_thickness,90);
+x3=x1r; lft x4=hround(.75u-.5heavy_rule_thickness); y3r=y4r=y1;
+filldraw stroke z3e--z4e; % upper bar
+penlabels(1,2,3,4); endchar;
+
+cmchar "Extensible right bracket---bottom";
+beginchar(oct"021",8u#,cap_height#+4u#,2u#);
+adjust_fit(0,0); pickup fine.nib;
+pos1(heavy_rule_thickness,0); pos2(heavy_rule_thickness,0);
+y1=h; bot y2=-d; x1=x2=hround(.5w);
+filldraw stroke z1e--z2e; % stem
+pos5(stem,90); pos6(stem,90);
+x5=x1r; lft x6=hround(.75u-.5heavy_rule_thickness); y5l=y6l=y2;
+filldraw stroke z5e--z6e; % lower bar
+penlabels(1,2,5,6); endchar;
+
+cmchar "Extensible left curly brace---middle";
+beginchar(oct"030",8u#,cap_height#+4u#,4u#);
+adjust_fit(0,0); pickup fine.nib;
+numeric min_breadth; min_breadth=hround(rule_thickness+.6dw);
+pos4(min_breadth,0); pos4'(min_breadth,0);
+forsuffixes $=2,3,5,6: pos$(heavy_rule_thickness,0); endfor
+lft x4l=lft x4'l=hround(1.5u-.5min_breadth);
+x2=x3=x5=x6; x2=hround(.5w);
+y2=h; y6=-d; .5[y4,y4']=.5[y2,y6]=.5[y3,y5];
+y3-y4=(y2-y6)/4; y4-y4'=min_breadth-fine;
+filldraw z2l---z3l...{3(x4l-x3l),y4-y3}z4l
+ --z4'l{3(x5l-x4l),y5-y4'}...z5l---z6l--z6r---z5r
+ ...{3(x4r-x5r),.5[y4,y4']-y5}.5[z4r,z4'r]{3(x3r-x4r),y3-.5[y4,y4']}
+ ...z3r---z2r--cycle; % stroke
+penlabels(2,3,4,5,6); endchar;
+
+cmchar "Extensible right curly brace---middle";
+beginchar(oct"031",8u#,cap_height#+4u#,4u#);
+adjust_fit(0,0); pickup fine.nib;
+numeric min_breadth; min_breadth=hround(rule_thickness+.6dw);
+pos4(min_breadth,0); pos4'(min_breadth,0);
+forsuffixes $=2,3,5,6: pos$(heavy_rule_thickness,0); endfor
+rt x4r=rt x4'r=hround(w-1.5u+.5min_breadth);
+x2=x3=x5=x6; x2=hround(.5w);
+y2=h; y6=-d; .5[y4,y4']=.5[y2,y6]=.5[y3,y5];
+y3-y4=(y2-y6)/4; y4-y4'=min_breadth-fine;
+filldraw z2r---z3r...{3(x4r-x3r),y4-y3}z4r
+ --z4'r{3(x5r-x4r),y5-y4'}...z5r---z6r--z6l---z5l
+ ...{3(x4l-x5l),.5[y4,y4']-y5}.5[z4l,z4'l]{3(x3l-x4l),y3-.5[y4,y4']}
+ ...z3l---z2l--cycle; % stroke
+penlabels(2,3,4,5,6); endchar;
+
+cmchar "Extension module";
+beginchar(oct"017",8u#,cap_height#+4u#,4u#);
+adjust_fit(0,0); pickup fine.nib;
+numeric max_breadth; max_breadth=bold+2dw;
+pos2(heavy_rule_thickness,0); pos2'(heavy_rule_thickness,0);
+x2=x2'=hround(.5w); y2=h; y2'=-d;
+filldraw stroke z2e--z2'e; % link
+penlabels(2,2'); endchar;
+
+cmchar "Extensible left curly brace---top";
+beginchar(oct"024",8u#,cap_height#+2u#,4u#);
+adjust_fit(0,0); pickup fine.nib;
+numeric min_breadth; min_breadth=hround(rule_thickness+.6dw);
+pos1(min_breadth,0); pos1'(min_breadth,0);
+pos2(heavy_rule_thickness,0); pos3(heavy_rule_thickness,0);
+rt x1r=rt x1'r=hround(w-1.5u+.5min_breadth);
+x2=x3=hround(.5w);
+top y1=h; y3=-d; y2=.5[y1,y3]; y1-y1'=min_breadth-fine;
+filldraw z1l{3(x2l-x1l),y2-y1}...z2l---z3l
+ --z3r---z2r...{3(x1r-x2r),y1'-y2}z1'r--z1r--cycle; % stroke
+penlabels(1,2,3); endchar;
+
+cmchar "Extensible left curly brace---bottom";
+beginchar(oct"025",8u#,cap_height#+4u#,2u#);
+adjust_fit(0,0); pickup fine.nib;
+numeric min_breadth; min_breadth=hround(rule_thickness+.6dw);
+pos7(min_breadth,0); pos7'(min_breadth,0);
+pos5(heavy_rule_thickness,0); pos6(heavy_rule_thickness,0);
+rt x7r=rt x7'r=hround(w-1.5u+.5min_breadth);
+x5=x6=hround(.5w);
+y5=h; y7=-d; y6=.5[y5,y7]; y7'-y7=min_breadth-fine;
+filldraw z5l---z6l...{3(x7l-x6l),y7-y6}z7l
+ --z7r--z7'r{3(x6r-x7r),y6-y7'}...z6r---z5r--cycle; % stroke
+penlabels(5,6,7); endchar;
+
+cmchar "Extensible right curly brace---top";
+beginchar(oct"026",8u#,cap_height#+2u#,4u#);
+adjust_fit(0,0); pickup fine.nib;
+numeric min_breadth; min_breadth=hround(rule_thickness+.6dw);
+pos1(min_breadth,0); pos1'(min_breadth,0);
+pos2(heavy_rule_thickness,0); pos3(heavy_rule_thickness,0);
+lft x1l=lft x1'l=hround(1.5u-.5min_breadth);
+x2=x3=hround(.5w);
+top y1=h; y3=-d; y2=.5[y1,y3]; y1-y1'=min_breadth-fine;
+filldraw z1r{3(x2r-x1r),y2-y1}...z2r---z3r
+ --z3l---z2l...{3(x1l-x2l),y1'-y2}z1'l--z1l--cycle; % stroke
+penlabels(1,2,3); endchar;
+
+cmchar "Extensible right curly brace---bottom";
+beginchar(oct"027",8u#,cap_height#+4u#,2u#);
+adjust_fit(0,0); pickup fine.nib;
+numeric min_breadth; min_breadth=hround(rule_thickness+.6dw);
+pos7(min_breadth,0); pos7'(min_breadth,0);
+pos5(heavy_rule_thickness,0); pos6(heavy_rule_thickness,0);
+lft x7l=lft x7'l=hround(1.5u-.5min_breadth);
+x5=x6=hround(.5w);
+top y5=h; bot y7=-d; y6=.5[y5,y7]; y7'-y7=min_breadth-fine;
+filldraw z5r---z6r...{3(x7r-x6r),y7-y6}z7r
+ --z7l--z7'l{3(x6l-x7l),y6-y7'}...z6l---z5l--cycle; % stroke
+penlabels(5,6,7); endchar;
+
+bye.
diff --git a/dviware/quicspool/wwfonts/tpunct.mf b/dviware/quicspool/wwfonts/tpunct.mf
new file mode 100644
index 0000000000..80ec5125c4
--- /dev/null
+++ b/dviware/quicspool/wwfonts/tpunct.mf
@@ -0,0 +1,241 @@
+% $Header: tpunct.mf,v 1.1 88/01/15 13:15:17 simpson Rel $
+% $Log: tpunct.mf,v $
+%Revision 1.1 88/01/15 13:15:17 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:40 simpson
+%beta test
+%
+% This file contains punctuation marks common to roman and italic styles.
+
+% Codes \0041, \0043, \0045, \0047--\0054,\ %
+%% \0056, \0057, \0072, \0073, \0075, \0100,\par
+% \0133, \0135, and \0140 are generated, as well as code |spanish_shriek|
+% (for a Spanish exclamation point) if that code value is known.
+
+cmchar "Exclamation point";
+beginchar("!",5u#+width_adj#,asc_height#,0);
+italcorr asc_height#*slant-2u#-.5width_adj#+.5dot_size#;
+adjust_fit(0,0);
+pickup tiny.nib; pos3(dot_size,0); pos4(dot_size,90);
+lft x3l=hround(.5w-.5dot_size); bot y4l=0; z3=z4; dot(3,4); % dot
+numeric bot_width;
+bot_width=if hefty:max(hround .8dot_size,fine.breadth) else: hair fi;
+pickup fine.nib; pos1(dot_size,0); pos2(bot_width,0);
+x1=x2=x3; bot y2=.25[top y4r,x_height]+1;
+if square_dots: top y1=h;
+ filldraw stroke z1e--z2e; % stem
+else: top z0=(x1,h+o); y1+.5dot_size=h+o;
+ filldraw z1r...z0...z1l---z2l--z2r---cycle; fi % stem and bulb
+penlabels(0,1,2,3,4); endchar;
+
+iff known spanish_shriek: cmchar "Spanish open exclamation point";
+beginchar(spanish_shriek,5u#+width_adj#,asc_height#-desc_depth#,desc_depth#);
+italcorr h#*slant-2u#-.5width_adj#+.5dot_size#;
+adjust_fit(0,0);
+pickup tiny.nib; pos3(dot_size,0); pos4(dot_size,90);
+lft x3l=hround(.5w-.5dot_size); top y4r=h; z3=z4; dot(3,4); % dot
+numeric top_width;
+top_width=if hefty:max(hround .8dot_size,fine.breadth) else: hair fi;
+pickup fine.nib; pos1(dot_size,0); pos2(top_width,0);
+x1=x2=x3; top y2=.25[bot y4l,h-x_height]-1;
+if square_dots: bot y1=-d;
+ filldraw stroke z1e--z2e; % stem
+else: bot z0=(x1,-d-o); y1-.5dot_size=-d-o;
+ filldraw z1l...z0...z1r---z2r--z2l---cycle; fi % stem and bulb
+penlabels(0,1,2,3,4); endchar;
+
+cmchar "Per cent sign";
+beginchar("%",9u#+max(6u#,2fudge*(hair#+stem#)),
+ body_height#,body_height#-asc_height#);
+italcorr if hefty: .4asc_height#*slant-.5u# else: h#*slant-u# fi;
+adjust_fit(0,0); pickup fine.nib;
+numeric left_curve,right_curve;
+left_curve=hround 5/6[fudged.hair,fudged.stem];
+right_curve=max(fine.breadth,hround(fudged.hair if hefty:-2stem_corr fi));
+pos1(vair,90); pos2(left_curve,180); pos3(vair,270); pos4(right_curve,360);
+top y1r=h; lft x2r=hround u; rt x4r=hround(.5w-1.5u);
+bot y3r=floor(if monospace: .7 else: .5 fi\\ asc_height);
+x1=x3=.5[x2,x4]; y2=y4=.5[y1,y3];
+filldraw stroke pulled_super_arc.e(1,2)(superpull)
+ & pulled_super_arc.e(2,3)(superpull); % left half of upper bowl
+filldraw stroke super_arc.e(3,4) & super_arc.e(4,1); % right half of upper bowl
+pos5(vair,90); pos6(left_curve,180); pos7(vair,270); pos8(right_curve,360);
+bot y7r=-d; rt x8r=hround(w-u); lft x6r=hround(.5w+1.5u);
+top y5r=vround(if monospace: .3 else: .5 fi\\ asc_height);
+x5=x7=.5[x6,x8]; y6=y8=.5[y5,y7];
+filldraw stroke pulled_super_arc.e(5,6)(superpull)
+ & pulled_super_arc.e(6,7)(superpull); % left half of lower bowl
+filldraw stroke super_arc.e(7,8) & super_arc.e(8,5); % right half of lower bowl
+pickup rule.nib; top y9=h; bot y10=-d;
+if hefty: x9=good.x(x5-eps); x10=good.x(x1+eps);
+ draw z9--z10; % diagonal
+else: rt x9=hround(w-2.5u); lft x10=hround 2.5u; draw z9--z10; % diagonal
+ pickup fine.nib; pos9(rule_thickness,angle(z9-z10)+90);
+ pos11(vair,angle(z1r-z4r)-90); pos12(vair,angle(z9-z10)+90);
+ path p; p=super_arc.r(1,4); z11r=point 2/3 of p; z12r=z9r;
+ filldraw stroke z11e{direction 2/3 of p}...{z9-z10}z12e; fi % link
+penlabels(1,2,3,4,5,6,7,8,9,10,11,12); endchar;
+
+cmchar "Apostrophe";
+beginchar("'",5u#,asc_height#,0);
+italcorr asc_height#*slant+.5dot_size#-2u#;
+adjust_fit(0,0);
+x1-.5dot_size=hround(.5w-.5dot_size); y1+.5dot_size=h;
+if monospace: comma(1,a,dot_size,.28u,vround 1.5comma_depth); % large comma
+else: comma(1,a,dot_size,.25u,comma_depth); fi % comma with increased jut
+penlabels(1); endchar;
+
+cmchar "Left parenthesis";
+beginchar("(",7u# if monospace: -u# fi,body_height#,paren_depth#);
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(vair,0); pos2(.75[hair,stem],0); pos3(vair,0);
+rt x1r=rt x3r=hround(w-u); lft x2l=hround(x1-4u if monospace: +4/3u fi);
+top y1=h; y2=.5[y1,y3]=math_axis;
+filldraw stroke z1e{3(x2e-x1e),y2-y1}...z2e
+ ...{3(x3e-x2e),y3-y2}z3e; % arc
+penlabels(1,2,3); endchar;
+
+cmchar "Right parenthesis";
+beginchar(")",7u# if monospace: -u# fi,body_height#,paren_depth#);
+italcorr math_axis#*slant-.5u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(vair,0); pos2(.75[hair,stem],0); pos3(vair,0);
+lft x1l=lft x3l=hround u; rt x2r=hround(x1+4u if monospace: -4/3u fi);
+top y1=h; y2=.5[y1,y3]=math_axis;
+filldraw stroke z1e{3(x2e-x1e),y2-y1}...z2e
+ ...{3(x3e-x2e),y3-y2}z3e; % arc
+penlabels(1,2,3); endchar;
+
+cmchar "Asterisk";
+beginchar("*",9u#,
+ if low_asterisk:math_axis#+.5x_height# else: body_height# fi,0);
+italcorr h#*slant-.75u#;
+adjust_fit(0,0);
+numeric ast_flare; ast_flare=hround .7[thin_join,stem];
+x0=.5w; y0=h-.5x_height;
+for d=-150 step 60 until 150: z[d]=z0+.5dir d xscaled 7.5u yscaled x_height;
+ numeric theta; theta=angle(z[d]-z0);
+ fill z0+.5(0,-thin_join)rotated theta
+ ---z[d]+.5(-ast_flare,-ast_flare)rotated theta
+ ..z[d]..z[d]+.5(-ast_flare,ast_flare)rotated theta
+ ---z0+.5(0,thin_join)rotated theta--cycle; endfor % diagonal at angle |d|
+labels(0,[-150],[-90],[-30],30,90,150); endchar;
+
+cmchar "Plus sign";
+beginarithchar("+"); pickup rule.nib;
+x1=x2=good.x .5w; top y1=h+eps; .5[y1,y2]=math_axis;
+lft x3=hround u-eps; x4=w-x3; y3=y4=math_axis;
+draw z1--z2; % stem
+draw z3--z4; % crossbar
+labels(1,2,3,4); endchar;
+
+cmchar "Comma";
+numeric dot_diam#; dot_diam#=if monospace: 5/4 fi\\ dot_size#;
+define_whole_blacker_pixels(dot_diam);
+beginchar(",",5u#,dot_diam#,comma_depth#);
+adjust_fit(0,0);
+x1-.5dot_diam=hround(.5w-.5dot_diam); y1-.5dot_diam=0;
+comma(1,a,dot_diam,.2u,comma_depth); % dot and tail
+penlabels(1); endchar;
+
+cmchar "Period";
+numeric dot_diam#; dot_diam#=if monospace: 5/4 fi\\ dot_size#;
+define_whole_blacker_pixels(dot_diam);
+beginchar(".",5u#,dot_diam#,0);
+adjust_fit(0,0); pickup fine.nib;
+pos1(dot_diam,0); pos2(dot_diam,90);
+lft x1l=hround(.5w-.5dot_diam); bot y2l=0; z1=z2; dot(1,2); % dot
+penlabels(1,2); endchar;
+
+cmchar "Virgule (slash)";
+beginchar("/",9u#,body_height#,paren_depth#);
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x1=hround(w-u)+eps; top y1=h+eps;
+lft x2=hround u-eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+penlabels(1,2); endchar;
+
+cmchar "Colon";
+numeric dot_diam#; dot_diam#=if monospace: 5/4 fi\\ dot_size#;
+define_whole_blacker_pixels(dot_diam);
+beginchar(":",5u#,x_height#,0);
+italcorr x_height#*slant+.5dot_diam#-2u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(dot_diam,0); pos2(dot_diam,90);
+lft x1l=hround(.5w-.5dot_diam); top y2r=h; z1=z2; dot(1,2); % upper dot
+pos3(dot_diam,0); pos4(dot_diam,90);
+x3=x1; bot y4l=0; z3=z4; dot(3,4); % lower dot
+penlabels(1,2,3,4); endchar;
+
+cmchar "Semicolon";
+numeric dot_diam#; dot_diam#=if monospace: 5/4 fi\\ dot_size#;
+define_whole_blacker_pixels(dot_diam);
+beginchar(";",5u#,x_height#,comma_depth#);
+italcorr x_height#*slant+.5dot_diam#-2u#;
+adjust_fit(0,0); pickup fine.nib;
+pos1(dot_diam,0); pos2(dot_diam,90);
+lft x1l=hround(.5w-.5dot_diam); top y2r=h; z1=z2; dot(1,2); % upper dot
+x3-.5dot_diam=hround(.5w-.5dot_diam); y3-.5dot_diam=0;
+comma(3,a,dot_diam,.05u,comma_depth); % lower dot and tail
+penlabels(1,2,3); endchar;
+
+cmchar "Equals sign";
+compute_spread(.45x_height#,.55x_height#);
+beginchar("=",14u#,v_center(spread#+rule_thickness#));
+italcorr h#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x1=hround u-eps; x3=x1; x2=x4=w-x1;
+y1=y2; y3=y4; y1-y3=spread; .5[y1,y3]=math_axis;
+draw z1--z2; % upper bar
+draw z3--z4; % lower bar
+labels(1,2,3,4); endchar;
+
+cmchar "Left bracket";
+numeric wd#; wd#=max(5u#,4.5u#+.5if hefty:stem# else:rule_thickness# fi);
+beginchar("[",wd#,body_height#,paren_depth#);
+italcorr body_height#*slant;
+adjust_fit(0,0);
+numeric top_thickness,side_thickness;
+if hefty: top_thickness=vair;
+ side_thickness=max(crisp.breadth,stem-2stem_corr);
+else: top_thickness=side_thickness=rule_thickness; fi;
+pickup crisp.nib; pos1(side_thickness,0); pos2(side_thickness,0);
+top y1=h; bot y2=-d; lft x1l=lft x2l=hround(2.5u-.5side_thickness)-1-eps;
+filldraw stroke z1e--z2e; % stem
+pos3(top_thickness,90); pos4(top_thickness,90);
+pos5(top_thickness,90); pos6(top_thickness,90);
+x3=x5=x1l; rt x4=rt x6=ceiling(w-.4u)+eps; y3r=y4r=y1; y5l=y6l=y2;
+filldraw stroke z3e--z4e; % upper bar
+filldraw stroke z5e--z6e; % lower bar
+penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Right bracket";
+numeric wd#; wd#=max(5u#,4.5u#+.5if hefty:stem# else:rule_thickness# fi);
+beginchar("]",wd#,body_height#,paren_depth#);
+italcorr body_height#*slant-2u#+.5if hefty:stem# else:rule_thickness# fi;
+adjust_fit(0,0);
+numeric top_thickness,side_thickness;
+if hefty: top_thickness=vair;
+ side_thickness=max(crisp.breadth,stem-2stem_corr);
+else: top_thickness=side_thickness=rule_thickness; fi;
+pickup crisp.nib; pos1(side_thickness,0); pos2(side_thickness,0);
+top y1=h; bot y2=-d; rt x1r=rt x2r=hround(w-2.5u+.5side_thickness)+1+eps;
+filldraw stroke z1e--z2e; % stem
+pos3(top_thickness,90); pos4(top_thickness,90);
+pos5(top_thickness,90); pos6(top_thickness,90);
+x3=x5=x1r; lft x4=lft x6=floor .4u-eps; y3r=y4r=y1; y5l=y6l=y2;
+filldraw stroke z3e--z4e; % upper bar
+filldraw stroke z5e--z6e; % lower bar
+penlabels(1,2,3,4,5,6); endchar;
+
+cmchar "Reverse apostrophe";
+beginchar("`",5u#,asc_height#,0);
+italcorr asc_height#*slant+.5dot_size#-2u#;
+adjust_fit(0,0);
+x1-.5dot_size=hround(.5w-.5dot_size); y1+.5dot_size=h-comma_depth;
+if monospace: ammoc(1,a,dot_size,.28u,vround 1.5comma_depth); % large ammoc
+else: ammoc(1,a,dot_size,.25u,comma_depth); fi % normal ammoc
+penlabels(1); endchar;
diff --git a/dviware/quicspool/wwfonts/troman.mf b/dviware/quicspool/wwfonts/troman.mf
new file mode 100644
index 0000000000..bce9d447b7
--- /dev/null
+++ b/dviware/quicspool/wwfonts/troman.mf
@@ -0,0 +1,341 @@
+% $Header: troman.mf,v 1.1 88/01/15 13:15:20 simpson Rel $
+% $Log: troman.mf,v $
+% Revision 1.1 88/01/15 13:15:20 simpson
+% initial release
+%
+% Revision 0.1 88/01/07 08:15:18 simpson
+% beta test
+%
+% The Computer Modern Roman family of fonts (by D. E. Knuth, 1979--1985)
+
+if ligs>1: font_coding_scheme:="Troff text";
+else: font_coding_scheme:=if ligs=0: "TeX typewriter text"
+ else: "TeX text without f-ligatures" fi;
+ spanish_shriek=oct"016"; spanish_query=oct"017"; fi
+minus=oct"004"; vertical=oct"174";
+
+mode_setup; font_setup;
+
+% We need to create space characters with no bitmap for \| and \^. I put
+% them in oct"000" and oct"177" since these characters are not normally
+% used by ditroff.
+% My own creation (...creation being a generous term), for \|, 1/6 em
+beginchar(oct"000", 16/6u#, 0, 0);
+endchar;
+
+% My own creation, for \^, 1/12 em
+beginchar(oct"177", 16/12u#, 0, 0);
+endchar;
+
+% From the font lasy10.mf, file lasy.mf
+cmchar "Box";
+beginchar(oct"024",2.1math_axis#+4u#,v_center(7u#));
+italcorr math_axis#*slant;
+adjust_fit(0,0); pickup rule.nib;
+numeric a; a=round(2.1math_axis);
+x1=x4=good.x 2u; x2=x3=x1+a;
+y3=y4=.5(cap_height-a); y1=y2=y3+a;
+draw z1--z2--z3--z4--cycle;
+labels(1,2,3,4); endchar;
+
+% Stolen from font cmsy10, file symbol.mf
+cmchar "Open bullet";
+beginchar(oct"025",9u#,v_center(7u#));
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x6=hround u; x2=w-x6; top y8=h; y2=math_axis;
+circle_points; draw_circle; % circle
+labels(1,2,3,4,5,6,7,8); endchar;
+
+% Stolen from the font cmr10, file accent.mf
+cmchar "Umlaut (double dot) accent";
+numeric dot_diam#,dot_diam;
+dot_diam#=max(dot_size#,cap_curve#);
+beginchar(oct"026",9u#,min(asc_height#,10/7x_height#+.5dot_diam#),0);
+dot_diam=max(tiny.breadth,hround(max(dot_size,cap_curve)-2stem_corr));
+italcorr h#*slant+.5dot_diam#-2.25u#;
+adjust_fit(0,0);
+pickup tiny.nib; pos1(dot_diam,0); pos2(dot_diam,90);
+x1=x2=2.75u; top y2r=h+1;
+if bot y2l<x_height+o+slab: y2l:=min(y2r-eps,x_height+o+slab+.5tiny); fi
+y1=.5[y2l,y2r]; dot(1,2); % left dot
+pos3(dot_diam,0); penpos4(y2r-y2l,90); y3=y4=y1; x3=x4=w-x1;
+dot(3,4); % right dot
+penlabels(1,2,3,4); endchar;
+
+% Stolen from the font cmr10.mf, file accent.mf
+cmchar "Cedilla accent";
+beginchar(oct"027",8u#,0,.875desc_depth#);
+adjust_fit(0,0);
+x1=.5w+.5u;
+if serifs: pickup crisp.nib; pos1(stem,0); pos2(stem,0);
+ pos3(vair,90); pos4(stem,0); pos5(vair,-90);
+ x1=x2; z3l=z2l; x4=x2+1.5u; x5=x3-1.5u;
+ bot y1=-o; bot y2=-vround 2/7d-o; y4=.5[y3,y5]; bot y5=-d-o;
+ filldraw stroke z1e--z2e; % stem
+ filldraw stroke z3e{right}...z4e{down}...{left}z5e; % hook
+else: pickup fine.nib; pos1(vair,0); top y1=-o-2;
+ pos2(.5[vair,stem],0); bot y2=-d-o; x2=x1-1.25u;
+ filldraw stroke z1e--z2e; fi % diagonal
+penlabels(1,2,3,4,5); endchar;
+
+% My own creation, a zero width period. Used for dots in pic(1).
+cmchar "Dot for pic boxes";
+numeric dot_diam#; dot_diam#=if monospace: 5/4 fi\\ dot_size#;
+define_whole_blacker_pixels(dot_diam);
+beginchar(oct"030",0,dot_diam#,0);
+period_width#:=5u#; define_pixels(period_width);
+pickup fine.nib;
+pos1(dot_diam,0); pos2(dot_diam,90);
+lft x1l=hround(.5period_width-.5dot_diam); bot y2l=0; z1=z2; dot(1,2); % dot
+penlabels(1,2); endchar;
+
+% My own creation. The fractions look like hell.
+cmchar "1/4 symbol";
+beginchar(oct"021", 12u#, body_height#, paren_depth#);
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x1=hround(w-u)+eps; top y1=h+eps;
+lft x2=hround u-eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+x3=x4=1/4w; y3=38/40h; y4=23/40h;
+draw z3--z4; % number 1
+x5=x6=32/40w; y7=y8=1/8h; y5=-.2d; y6=.37h; x7=26/40w; x8=.85w;
+draw z5--z6--z7--z8;
+endchar;
+
+% My own creation
+cmchar "1/2 symbol";
+beginchar(oct"022", 12u#, body_height#, paren_depth#);
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x1=hround(w-u)+eps; top y1=h+eps;
+lft x2=hround u-eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+x3=x4=1/4w; y3=38/40h; y4=23/40h;
+draw z3--z4; % number 1
+x5=x9=.65w; x10=x7=.85w; x6=.74w;
+y9=y10=-.2d; y6=.37h; y5=.32h; y7=.30h;
+draw z5{dir 45}..z6..z7{dir -90}..{dir 225}z9; % number 2
+draw z9--z10;
+endchar;
+
+% My own creation.
+cmchar "3/4 symbol";
+beginchar(oct"023", 12u#, body_height#, paren_depth#);
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x1=hround(w-u)+eps; top y1=h+eps;
+lft x2=hround u-eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+draw (quartercircle rotated -90 & halfcircle) scaled .1875h shifted
+(.25w,.8562h); % number 3
+draw (halfcircle rotated -180 & quartercircle) scaled .1875h shifted
+(.25w,.6687h);
+x5=x6=32/40w; y7=y8=1/8h; y5=-.2d; y6=.37h; x7=26/40w; x8=.85w;
+draw z5--z6--z7--z8;
+endchar;
+
+% From the font cmsy10, file sym.mf
+iff known vertical: cmchar "Vertical line";
+beginchar(vertical,5u#,body_height#,paren_depth#);
+italcorr body_height#*slant+.5rule_thickness#-2u#;
+adjust_fit(0,0); pickup rule.nib;
+x1=x2=good.x .5w; top y1=h+eps; bot y2=-d-eps;
+draw z1--z2; % stem
+labels(1,2); endchar;
+
+% My own creation
+cmchar "Rule";
+beginchar(oct"005",12u#,x_height#,.7u#);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric below_baseline; below_baseline#:=.2u#;
+define_pixels(below_baseline);
+define_blacker_pixels(thickness);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(-below_baseline); rt x2=hround(w+6u#);
+lft x1=hround(0);
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+% My own creation
+cmchar "Underscore";
+beginchar("_",12u#,x_height#,.7u#);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric below_baseline; below_baseline#:=.2u#;
+define_pixels(below_baseline);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(-below_baseline); x2=hround(w);
+x1=hround 0;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+% Hyphen from cmr10, file comlig.mf
+cmchar "Hyphen";
+beginchar("-",6u#,x_height#,0);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric thickness; thickness=if hefty:bar else:.75[hair,stem] fi;
+pickup crisp.nib; pos1(thickness,90); pos2(thickness,90);
+top y1r=top y2r=vround(.5h+.5thickness); rt x2=hround(w-u)+eps;
+if monospace: x2=w-x1 else: lft x1=hround .2u-eps fi;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+% My own creation
+cmchar "Cent sign";
+beginchar(oct"020",18u#,asc_height#,desc_depth#); autorounded;
+adjust_fit(if monospace:-3u#,-3u# else: 0,0 fi); pickup rule.nib;
+lft x6=hround u; x2=w-x6; top y8=h+o; bot y4=-d-o;
+circle_points;
+x9=x11=.65[x6,x4]; x10=x12=.35[x4,x2];
+y9=y10=.35[y6,y8]; y11=y12=.65[y4,y6];
+x13=x14=.5[x6,x2]-.3u; y13=y4+2u; y14=y8-2u;
+draw z10..z9..z11..z12; draw z13--z14;
+labels(1,2,3,4,5,6,7,8,9,10,11,12,13,14); endchar;
+
+% My own creation
+cmchar "Copyright";
+beginchar(oct"016",18u#,asc_height#,desc_depth#); autorounded;
+adjust_fit(if monospace:-3u#,-3u# else: 0,0 fi); pickup rule.nib;
+lft x6=hround u; x2=w-x6; top y8=h+o; bot y4=-d-o;
+circle_points; draw_circle; % circle
+x9=x11=.65[x6,x4]; x10=x12=.35[x4,x2];
+y9=y10=.35[y6,y8]; y11=y12=.65[y4,y6];
+draw z10..z9..z11..z12;
+labels(1,2,3,4,5,6,7,8,9,10,11,12); endchar;
+
+% My own creation
+cmchar "Registered";
+beginchar(oct"017",18u#,asc_height#,desc_depth#); autorounded;
+adjust_fit(if monospace:-3u#,-3u# else: 0,0 fi); pickup rule.nib;
+lft x6=hround u; x2=w-x6; top y8=h+o; bot y4=-d-o;
+circle_points; draw_circle; % circle
+x9=x11=x12=.7[x6,x8]; x10=x13=.3[x4,x2];
+y12=y13=.5[y4,y6]; y9=.5[y6,y8]; y11=.5[y12,y9]; y10=.5[y11,y9];
+x14=.08[x4,x2]; y14=y9;
+path p;
+p=z9--z14{dir 0}..z10..{dir 180}z11;
+z15=point 2.6 of p;
+draw z12--z9; draw z13--z15; draw p;
+labels(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15); endchar;
+
+% Stolen from the font cmr10, file accent.mf (actually the acute accent)
+cmchar "Footmark";
+beginchar(oct"015",9u#,min(asc_height#,2x_height#),0);
+italcorr h#*slant-if serifs: 1.5 fi u#;
+adjust_fit(0,0);
+if serifs: pickup crisp.nib; x1+.5stem=hround(w-2u); x2=2/3[x1,w-x1];
+ y1+.5stem=h+eps; y2=max(2/3[h,x_height],x_height+o+hair);
+ numeric theta; theta=angle(z2-z1)+90;
+ pos1(stem,theta); pos2(hair,theta);
+ filldraw circ_stroke z1e--z2e; % diagonal
+else: pickup fine.nib; pos1(stem,0); pos2(vair,0);
+ rt x1r=hround(w-1.5u); lft x2l=hround(.5w-.25u-.5vair);
+ top y1=h; bot y2=vround 2/3[h,x_height];
+ filldraw stroke z1e--z2e; fi % diagonal
+penlabels(1,2); endchar;
+
+% Stolen from the font cmsy10, file symbol.mf
+cmchar "Dagger mark";
+beginchar(oct"014",8u#,asc_height#,desc_depth#);
+adjust_fit(0,0); pickup fine.nib;
+pos1(stem,0); pos2(thin_join,0); pos3(stem,0); pos4(hair,0);
+pos5(stem,90); pos2'(thin_join,90); pos6(stem,90); z2'=z2;
+x1=x2=x3=x4; x1-.5stem=hround(.5w-.5stem); w:=r:=2x1;
+x5-.5stem=hround u; x6=w-x5;
+y1+.5stem=h+oo; y2=y5=y6; y3=.57y2; bot y4=-d-o;
+y5+.5stem=floor(x_height+.5stem);
+filldraw circ_stroke z1e{down}..z2e{down}..z3e{down}..z4e; % stem
+filldraw circ_stroke z5e{right}..{right}z2'e; % left bulb
+filldraw circ_stroke z6e{left}..{left}z2'e; % right bulb
+penlabels(1,2,3,4,5,6); endchar;
+
+% Stolen from the font cmr10, file accent.mf (the Scandinavian circle accent)
+cmchar "Degree";
+beginchar(oct"013",13u#+4/3(asc_height#-x_height#)*slant,asc_height#,0);
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+numeric circ_hair,circ_vair;
+circ_hair=hround min(hair,u+.5); circ_vair=vround min(vair,(h-x_height)/6+.5);
+penpos1(circ_vair,90); penpos3(circ_vair,-90);
+penpos2(circ_hair,180); penpos4(circ_hair,0);
+x2r=hround(.5w-1.5u-.5circ_hair);
+x4r=w-x2r; x1=x3=.5w; y1r=h+apex_o; y2=y4=.5[y1,y3];
+y3r=vround(1/3[x_height,h]+apex_o);
+penstroke pulled_arc.e(1,2) & pulled_arc.e(2,3)
+ & pulled_arc.e(3,4) & pulled_arc.e(4,1) & cycle; % bowl
+penlabels(1,2,3,4); endchar;
+
+% My own creation
+cmchar "Square";
+beginchar(oct"010",9u#,v_center(7u#));
+italcorr math_axis#*slant;
+adjust_fit(0,0); pickup rule.nib;
+draw unitsquare scaled 7u shifted (.5w-7u/2,math_axis-7u/2);
+endchar;
+
+% Stolen from the font cmsy10, file symbol.mf
+cmchar "Bullet";
+beginchar(oct"007",9u#,v_center(7u#));
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x6=hround u; x2=w-x6; top y8=h; y2=math_axis; circle_points;
+filldraw z8{right}...z1{z2-z8}...z2{down}...z3{z4-z2}...z4{left}
+ ...z5{z6-z4}...z6{up}...z7{z8-z6}...cycle; % circle and interior
+labels(1,2,3,4,5,6,7,8); endchar;
+
+% Stolen from the font cmsy10, file sym.mf
+iff known minus: cmchar "Minus sign";
+beginarithchar(minus); pickup rule.nib;
+lft x1=hround 1.5u-eps; x2=w-x1; y1=y2=math_axis;
+draw z1--z2; % bar
+labels(1,2); endchar;
+
+input romanu; % upper case (majuscules)
+input romanl; % lower case (minuscules)
+input romand; % numerals
+input romanp; % ampersand, question marks, currency sign
+input tpunct; % punctuation symbols common to roman and italic text
+if ligs>1: input tromlig; fi % letter ligatures
+if ligs>0: input tcomlig; fi % ligatures common with italic text
+if ligs<=1: input romsub; fi % substitutes for ligatures
+
+font_slant slant; font_x_height x_height#;
+if monospace: font_normal_space 9u#; % no stretching or shrinking
+ font_quad 18u#;
+ font_extra_space 9u#;
+else: font_normal_space 6u#+2letter_fit#;
+ font_normal_stretch 3u#; font_normal_shrink 2u#;
+ font_quad 18u#+4letter_fit#;
+ font_extra_space 2u#;
+ k#:=-.5u#; kk#:=-1.5u#; kkk#:=-2u#; % three degrees of kerning
+ ligtable "k": if serifs: "v": "a" kern -u#, fi\\"w": "e" kern k#,
+ "a" kern k#, "o" kern k#, "c" kern k#;
+ ligtable "P": "A" kern kk#,
+ "y": "o" kern k#, "e" kern k#, "a" kern k#, "." kern kk#, "," kern kk#;
+ ligtable "F": "V": "W": if serifs: "o" kern kk#, "e" kern kk#, "u" kern kk#,
+ "r" kern kk#, "a" kern kk#, "A" kern kkk#,
+ else: "o" kern k#, "e" kern k#, "u" kern k#,
+ "r" kern k#, "a" kern k#, "A" kern kk#, fi
+ "K": "X": "O" kern k#, "C" kern k#, "G" kern k#, "Q" kern k#;
+ ligtable "T": "y" kern if serifs: k# else: kk# fi,
+ "Y": "e" kern kk#, "o" kern kk#,
+ "r" kern kk#, "a" kern kk#, "A" kern kk#, "u" kern kk#;
+ ligtable "O": "D": "X" kern k#, "W" kern k#, "A" kern k#,
+ "V" kern k#, "Y" kern k#;
+ if serifs: ligtable "h": "m": "n":
+ "t" kern k#, "u" kern k#, "b" kern k#, "y" kern k#, "v" kern k#, "w" kern k#;
+ ligtable "c": "h" kern k#, "k" kern k#; fi
+ ligtable "o": "b": "p": "e" kern -k#, "o" kern -k#, "x" kern k#,
+ "d" kern -k#, "c" kern -k#, "q" kern -k#,
+ "a": if serifs: "v" kern k#, "j" kern u#, else: "r" kern k#, fi
+ "t": "y" kern k#,
+ "u": "w" kern k#;
+ ligtable "A": if serifs: "R": fi\\ "t" kern k#,
+ "C" kern k#, "O" kern k#, "G" kern k#, "U" kern k#, "Q" kern k#,
+ "L": "T" kern kk#, "Y" kern kk#, "V" kern kkk#, "W" kern kkk#;
+ ligtable "g": "j" kern -k#; % logjam
+ ligtable "I": "I" kern -k#; fi % Richard III
+ % there are ligature/kern programs for |"f"| in the {\tt romlig} file
+ % and for |"-"|, |"`"|, and |"'"| in the {\tt comlig} file
+bye.
diff --git a/dviware/quicspool/wwfonts/tromlig.mf b/dviware/quicspool/wwfonts/tromlig.mf
new file mode 100644
index 0000000000..6f96585cae
--- /dev/null
+++ b/dviware/quicspool/wwfonts/tromlig.mf
@@ -0,0 +1,171 @@
+% $Header: tromlig.mf,v 1.1 88/01/15 13:15:24 simpson Rel $
+% $Log: tromlig.mf,v $
+%Revision 1.1 88/01/15 13:15:24 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:43 simpson
+%beta test
+%
+% This file describes five roman ligatures that begin with `f'
+% and puts them in code positions \001-\003, \011-\012
+
+numeric itc#; % modified italic correction on `f' and `ff'
+itc#=if serifs: max(0,flare#-.25u#) else: 1.25u# fi;
+
+ligtable "f": "i"=:oct"001", "f"=:oct"003", "l"=:oct"002",
+ "?" kern itc#, "!" kern itc#, ")" kern itc#, "]" kern itc#;
+ligtable oct"003": "i"=:oct"011", "l"=:oct"012",
+ "?" kern itc#, "!" kern itc#, ")" kern itc#, "]" kern itc#;
+
+cmchar "The ligature ff";
+beginchar(oct"003",10.5u#+2letter_fit#,asc_height#,0);
+italcorr asc_height#*slant+if serifs:flare#-.25u# else: 1.25u# fi;
+adjust_fit(0,0);
+pickup tiny.nib; pos1(stem',0); lft x1l=hround(2.5u-.5stem');
+pos11(stem',0); rt x11r=hround(w-3u+.5stem');
+pickup fine.nib; numeric bulb_diam, inner_jut;
+if serifs: bulb_diam=hround .8[stem,flare];
+ pos2(bulb_diam,0); pos12(bulb_diam,0);
+ rt x2r=hround(rt x11r-stem_corr); lft x12l=hround(w-.75u+.5);
+ y2+.5bulb_diam=.85[x_height,h+oo]; y12+.5bulb_diam=.9[x_height,h+oo];
+ if rt x1r+jut+.5u+2<=lft x11l-jut: inner_jut=jut;
+ else: rt x1r+inner_jut+.5u+2=lft x11l-inner_jut; fi
+else: pos2(5/7[vair,flare],90); top y2r=h; rt x2=hround 6.25u;
+ pos12(5/7[vair,flare],90); y12=y2; rt x12=hround(w+.75u); fi
+f_stroke(1,2,a,b,c,jut,inner_jut); % left stem, arc, terminal, serif
+f_stroke(11,12,d,e,f,inner_jut,1.25jut); % right stem, arc, terminal, serif
+pickup crisp.nib; top y3r=top y4r=x_height; lft x3=hround .5u-1;
+pos3(bar,90); pos4(bar,90);
+rt x4=hround(w-1/3u);
+if hefty: pos3'(bar,90); x3'-x1=x4-x11; y3'=y3;
+ pos4'(bar,90); x4'=x11; y4'=y4;
+ filldraw stroke z3e--z3'e; filldraw stroke z4'e--z4e; % bars
+else: filldraw stroke z3e--z4e; fi % bar
+penlabels(1,2,3,4,11,12); endchar;
+
+cmchar "The ligature fi";
+beginchar(oct"001",10u#+2letter_fit#,asc_height#,0);
+italcorr asc_height#*slant-serif_fit#+.5if serifs:stem# else:dot_size# fi-2u#;
+adjust_fit(0,serif_fit#);
+pickup tiny.nib; pos1(stem',0); lft x1l=hround(2.5u-.5stem');
+pos11(stem',0); rt x11r=hround(w-2.5u+.5stem');
+pos12(stem',0); x11=x12; bot y12=0;
+pickup fine.nib; numeric bulb_diam, inner_jut;
+if serifs: bulb_diam=hround 1/4[.8[stem,flare],dot_size];
+ pos2(bulb_diam,0); x2r=x12r;
+ y2+.5bulb_diam=.8[x_height,h+oo]; top y11=x_height+min(oo,serif_drop);
+ if rt x1r+jut+.5u+2<=lft x11l-jut: inner_jut=jut;
+ else: rt x1r+inner_jut+.5u+2=lft x11l-inner_jut; fi
+else: bulb_diam=max(stem,dot_size);
+ pos2(6/7[vair,flare],90); top y2r=h; rt x2=hround 5.3u;
+ pickup tiny.nib; pos13(bulb_diam,0); pos14(bulb_diam,90);
+ x13=x11-.5; top y14r=min(2x_height,h+1); top y11=x_height;
+ if bot y14l-x_height<tiny: y14l:=min(y14r-eps,y11+2tiny); fi
+ x13=x14; y13=.5[y14l,y14r]; dot(13,14); % dot
+fi; % this is the ligature we're drawing
+f_stroke(1,2,a,b,c,jut,inner_jut); % left stem, arc, terminal, serif
+pickup tiny.nib; filldraw stroke z11e--z12e; % right stem
+pickup crisp.nib; top y3r=top y4r=x_height; lft x3=hround .5u-1;
+pos3(bar,90); pos4(bar,90);
+if serifs: x4=x11; % bar will overlap upper right serif
+ sloped_serif.l(11,12,d,1/3,jut,min(oo,serif_drop)); % upper right serif
+ dish_serif(12,11,e,1/3,inner_jut,f,1/3,jut); % lower right serif
+else: rt x4= hround 5.3u; fi
+pickup crisp.nib; filldraw stroke z3e--z4e; % bar
+penlabels(1,2,3,4,11,12,13,14); endchar;
+
+cmchar "The ligature fl";
+beginchar(oct"002",10u#+2letter_fit#,asc_height#,0);
+italcorr asc_height#*slant-serif_fit#+.5stem#-2u#;
+adjust_fit(0,serif_fit#);
+pickup tiny.nib; pos1(stem',0); lft x1l=hround(2.5u-.5stem');
+pos11(stem',0); rt x11r=hround(w-2.5u+.5stem');
+pos12(stem',0); x11=x12; bot y12=0; top y11=h;
+filldraw stroke z11e--z12e; % right stem
+pickup fine.nib; numeric bulb_diam, inner_jut;
+if serifs: bulb_diam=hround .8[stem,flare];
+ pos2(bulb_diam,0); x2r=x11r-stem_corr;
+ y2+.5bulb_diam=.9[x_height,h+oo];
+ sloped_serif.l(11,12,d,1/3,eps,max(serif_drop,oo)); % erase excess at top
+ if rt x1r+jut+.5u+2<=lft x11l-jut: inner_jut=jut;
+ else: rt x1r+inner_jut+.5u+2=lft x11l-inner_jut; fi
+else: pos2(5/7[vair,flare],90); top y2r=h; rt x2=hround 5.3u; fi
+f_stroke(1,2,a,b,c,jut,inner_jut); % left stem, arc, terminal, serif
+pickup crisp.nib; top y3r=top y4r=x_height; lft x3=hround .5u-1;
+pos3(bar,90); pos4(bar,90);
+if serifs: x4=x11;
+ dish_serif(12,11,e,1/3,inner_jut,f,1/3,jut); % lower right serif
+else: rt x4= hround 5.3u; fi
+pickup crisp.nib; filldraw stroke z3e--z4e; % bar
+penlabels(1,2,3,4,11,12); endchar;
+
+cmchar "The ligature ffi";
+beginchar(oct"011",15u#+4letter_fit#,asc_height#,0);
+italcorr asc_height#*slant-serif_fit#+.5if serifs:stem# else:dot_size# fi-2u#;
+adjust_fit(0,serif_fit#);
+pickup tiny.nib; pos1(stem',0); lft x1l=hround(2.5u-.5stem');
+pos11(stem',0); lft x11l=hround(.5w-.5stem');
+pos21(stem',0); rt x21r=hround(w-2.5u+.5stem');
+pos22(stem',0); x21=x22; bot y22=0;
+pickup fine.nib; numeric bulb_diam, inner_jut;
+if serifs: bulb_diam=hround 1/4[.8[stem,flare],dot_size];
+ pos2(bulb_diam,0); x2r=x11r-stem_corr;
+ pos12(bulb_diam,0); x12r=x21r;
+ top y21=x_height+min(oo,serif_drop);
+ y2+.5bulb_diam=.8[x_height,h+oo]; y12=y2;
+ if rt x1r+jut+.5u+2<=lft x11l-jut: inner_jut=jut;
+ else: rt x1r+inner_jut+.5u+2=lft x11l-inner_jut; fi
+else: bulb_diam=max(stem,dot_size);
+ pos2(5/7[vair,flare],90); top y2r=h; rt x2=hround 5.75u;
+ pos12(6/7[vair,flare],90); y12=y2; rt x12=hround(.5w+2.8u);
+ pickup tiny.nib; pos23(bulb_diam,0); pos24(bulb_diam,90);
+ x23=x21-.5; top y24r=min(2x_height,h+1); top y21=x_height;
+ if bot y24l-x_height<tiny: y24l:=min(y24r-eps,y21+2tiny); fi
+ x23=x24; y23=.5[y24l,y24r]; dot(23,24); fi % dot
+f_stroke(1,2,a,b,c,jut,inner_jut); % left stem, arc, terminal, serif
+f_stroke(11,12,d,e,f,inner_jut,inner_jut); % middle ditto
+pickup tiny.nib; filldraw stroke z21e--z22e; % right stem
+pickup crisp.nib; top y3r=top y4r=x_height; lft x3=hround.5u-1;
+pos3(bar,90); pos4(bar,90);
+if serifs: x4=x21; % bar will overlap upper right serif
+ sloped_serif.l(21,22,g,1/3,jut,min(oo,serif_drop)); % upper right serif
+ dish_serif(22,21,h,1/3,inner_jut,i,1/3,jut); % lower right serif
+else: rt x4=hround(.5w+2.8u); fi
+pickup crisp.nib;
+if hefty: pos3'(bar,90); x3'-x1=x4-x11; y3'=y3;
+ pos4'(bar,90); x4'=x11; y4'=y4;
+ filldraw stroke z3e--z3'e; filldraw stroke z4'e--z4e; % bars
+else: filldraw stroke z3e--z4e; fi % bar
+penlabels(1,2,3,4,11,12,21,22,23,24); endchar;
+
+cmchar "The ligature ffl";
+beginchar(oct"012",15u#+4letter_fit#,asc_height#,0);
+italcorr asc_height#*slant-serif_fit#+.5stem#-2u#;
+adjust_fit(0,serif_fit#);
+pickup tiny.nib; pos1(stem',0); lft x1l=hround(2.5u-.5stem');
+pos11(stem',0); lft x11l=hround(.5w-.5stem');
+pos21(stem',0); rt x21r=hround(w-2.5u+.5stem');
+pos22(stem',0); x21=x22; bot y22=0; top y21=h;
+filldraw stroke z21e--z22e; % right stem
+pickup fine.nib; numeric bulb_diam, inner_jut;
+if serifs: bulb_diam=hround .8[stem,flare];
+ pos2(bulb_diam,0); x2r=x11r-stem_corr;
+ pos12(bulb_diam,0); x12r=x21r-stem_corr;
+ y2+.5bulb_diam=.85[x_height,h+oo]; y12+.5bulb_diam=.9[x_height,h+oo];
+ sloped_serif.l(21,22,g,1/3,eps,max(serif_drop,oo)); % erase excess at top
+ if rt x1r+jut+.5u+2<=lft x11l-jut: inner_jut=jut;
+ else: rt x1r+inner_jut+.5u+2=lft x11l-inner_jut; fi
+else: pos2(5/7[vair,flare],90); top y2r=h; rt x2=hround 5.75u;
+ pos12(5/7[vair,flare],90); y12=y2; rt x12=hround(.5w+2.8u); fi
+f_stroke(1,2,a,b,c,jut,inner_jut); % left stem, arc, terminal, serif
+f_stroke(11,12,d,e,f,inner_jut,inner_jut); % middle ditto
+pickup crisp.nib; top y3r=top y4r=x_height; lft x3=hround.5u-1;
+pos3(bar,90); pos4(bar,90);
+if serifs: dish_serif(22,21,h,1/3,inner_jut,i,1/3,jut); % lower right serif
+ pickup crisp.nib; x4=x21;
+else: rt x4=hround(.5w+2.8u); fi
+if hefty: pos3'(bar,90); x3'-x1=x4-x11; y3'=y3;
+ pos4'(bar,90); x4'=x11; y4'=y4;
+ filldraw stroke z3e--z3'e; filldraw stroke z4'e--z4e; % bars
+else: filldraw stroke z3e--z4e; fi % bar
+penlabels(1,2,3,4,11,12,21,22); endchar;
diff --git a/dviware/quicspool/wwfonts/tromms.mf b/dviware/quicspool/wwfonts/tromms.mf
new file mode 100644
index 0000000000..75cc7c5b9d
--- /dev/null
+++ b/dviware/quicspool/wwfonts/tromms.mf
@@ -0,0 +1,42 @@
+% $Header: tromms.mf,v 1.1 88/01/15 13:15:27 simpson Rel $
+% $Log: tromms.mf,v $
+%Revision 1.1 88/01/15 13:15:27 simpson
+%initial release
+%
+%Revision 0.1 87/12/11 19:01:45 simpson
+%beta test
+%
+% This file contains special characters of ``math italic'' fonts
+% that actually are not supposed to be slanted.
+
+% The italic corrections are zero in all of these characters.
+
+cmchar "Less than sign";
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar("<",14u#,v_center(spread#+rule_thickness#));
+italcorr h#*slant-u#;
+adjust_fit(0,0); pickup rule.nib;
+lft x2=hround 1.5u-eps; x1=x3=w-x2;
+y1-y3=spread; y2=.5[y1,y3]=math_axis;
+draw z1--z2--z3; % diagonals
+labels(1,2,3); endchar;
+
+cmchar "Virgule (slash)";
+beginchar(oct"016",9u#,body_height#,paren_depth#); % non-ASCII position
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x1=hround(w-u)+eps; top y1=h+eps;
+lft x2=hround u-eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+penlabels(1,2); endchar;
+
+cmchar "Greater than sign";
+compute_spread(5/4x_height#,3/2x_height#);
+beginchar(">",14u#,v_center(spread#+rule_thickness#));
+italcorr math_axis#*slant-u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x2=hround(w-1.5u)+eps; x1=x3=w-x2;
+y1-y3=spread; y2=.5[y1,y3]=math_axis;
+draw z1--z2--z3; % diagonals
+labels(1,2,3); endchar;
+
diff --git a/dviware/quicspool/wwfonts/ttextit.mf b/dviware/quicspool/wwfonts/ttextit.mf
new file mode 100644
index 0000000000..ffbad2f774
--- /dev/null
+++ b/dviware/quicspool/wwfonts/ttextit.mf
@@ -0,0 +1,336 @@
+% $Header: ttextit.mf,v 1.1 88/01/15 13:15:30 simpson Rel $
+% $Log: ttextit.mf,v $
+% Revision 1.1 88/01/15 13:15:30 simpson
+% initial release
+%
+% Revision 0.2 88/01/14 10:12:30 simpson
+% fixed Rule and Underscore
+%
+% Revision 0.1 88/01/07 08:15:20 simpson
+% beta test
+%
+% The Computer Modern Text Italic family (by D. E. Knuth, 1979--1985)
+
+mode_setup; font_setup;
+
+input itall; % lower case (minuscules)
+if ligs>1: font_coding_scheme:="Troff text";
+ input titalig; % letter ligatures
+else: font_coding_scheme:=if ligs=0: "TeX typewriter text"
+ else: "TeX text without f-ligatures" fi;
+ spanish_shriek=oct"016"; spanish_query=oct"017"; fi
+minus=oct"004"; vertical=oct"174";
+
+font_slant slant; font_x_height x_height#;
+if monospace: font_normal_space 9u#; % no stretching or shrinking
+ font_quad 18u#;
+ font_extra_space 9u#;
+ letter_fit#:=letter_fit:=0;
+else: font_normal_space 6u#+2letter_fit#;
+ font_normal_stretch 3u#; font_normal_shrink 2u#;
+ font_quad 18u#+4letter_fit#;
+ font_extra_space 2u#; fi
+
+% We need to create space characters with no bitmap for \| and \^. I put
+% them in oct"000" and oct"177" since these characters are not normally
+% used by ditroff.
+% My own creation (...creation being a generous term), for \|, 1/6 em
+beginchar(oct"000", 16/6u#, 0, 0);
+endchar;
+
+% My own creation, for \^, 1/12 em
+beginchar(oct"177", 16/12u#, 0, 0);
+endchar;
+
+% From the font lasy10.mf, file lasy.mf
+cmchar "Box";
+beginchar(oct"024",2.1math_axis#+4u#,v_center(7u#));
+italcorr math_axis#*slant;
+adjust_fit(0,0); pickup rule.nib;
+numeric a; a=round(2.1math_axis);
+x1=x4=good.x 2u; x2=x3=x1+a;
+y3=y4=.5(cap_height-a); y1=y2=y3+a;
+draw z1--z2--z3--z4--cycle;
+labels(1,2,3,4); endchar;
+
+% Stolen from font cmsy10, file symbol.mf
+cmchar "Open bullet";
+beginchar(oct"025",9u#,v_center(7u#));
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x6=hround u; x2=w-x6; top y8=h; y2=math_axis;
+circle_points; draw_circle; % circle
+labels(1,2,3,4,5,6,7,8); endchar;
+
+% Stolen from the font cmr10, file accent.mf
+cmchar "Umlaut (double dot) accent";
+numeric dot_diam#,dot_diam;
+dot_diam#=max(dot_size#,cap_curve#);
+beginchar(oct"026",9u#,min(asc_height#,10/7x_height#+.5dot_diam#),0);
+dot_diam=max(tiny.breadth,hround(max(dot_size,cap_curve)-2stem_corr));
+italcorr h#*slant+.5dot_diam#-2.25u#;
+adjust_fit(0,0);
+pickup tiny.nib; pos1(dot_diam,0); pos2(dot_diam,90);
+x1=x2=2.75u; top y2r=h+1;
+if bot y2l<x_height+o+slab: y2l:=min(y2r-eps,x_height+o+slab+.5tiny); fi
+y1=.5[y2l,y2r]; dot(1,2); % left dot
+pos3(dot_diam,0); penpos4(y2r-y2l,90); y3=y4=y1; x3=x4=w-x1;
+dot(3,4); % right dot
+penlabels(1,2,3,4); endchar;
+
+% Stolen from the font cmr10.mf, file accent.mf
+cmchar "Cedilla accent";
+beginchar(oct"027",8u#,0,.875desc_depth#);
+adjust_fit(0,0);
+x1=.5w+.5u;
+if serifs: pickup crisp.nib; pos1(stem,0); pos2(stem,0);
+ pos3(vair,90); pos4(stem,0); pos5(vair,-90);
+ x1=x2; z3l=z2l; x4=x2+1.5u; x5=x3-1.5u;
+ bot y1=-o; bot y2=-vround 2/7d-o; y4=.5[y3,y5]; bot y5=-d-o;
+ filldraw stroke z1e--z2e; % stem
+ filldraw stroke z3e{right}...z4e{down}...{left}z5e; % hook
+else: pickup fine.nib; pos1(vair,0); top y1=-o-2;
+ pos2(.5[vair,stem],0); bot y2=-d-o; x2=x1-1.25u;
+ filldraw stroke z1e--z2e; fi % diagonal
+penlabels(1,2,3,4,5); endchar;
+
+% My own creation, a zero width period. Used for dots in pic(1).
+cmchar "Dot for pic boxes";
+numeric dot_diam#; dot_diam#=if monospace: 5/4 fi\\ dot_size#;
+define_whole_blacker_pixels(dot_diam);
+beginchar(oct"030",0,dot_diam#,0);
+period_width#:=5u#; define_pixels(period_width);
+pickup fine.nib;
+pos1(dot_diam,0); pos2(dot_diam,90);
+lft x1l=hround(.5period_width-.5dot_diam); bot y2l=0; z1=z2; dot(1,2); % dot
+penlabels(1,2); endchar;
+
+% My own creation. The fractions look like hell.
+cmchar "1/4 symbol";
+beginchar(oct"021", 12u#, body_height#, paren_depth#);
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x1=hround(w-u)+eps; top y1=h+eps;
+lft x2=hround u-eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+x3=x4=1/4w; y3=38/40h; y4=23/40h;
+draw z3--z4; % number 1
+x5=x6=32/40w; y7=y8=1/8h; y5=-.2d; y6=.37h; x7=26/40w; x8=.85w;
+draw z5--z6--z7--z8;
+endchar;
+
+% My own creation
+cmchar "1/2 symbol";
+beginchar(oct"022", 12u#, body_height#, paren_depth#);
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x1=hround(w-u)+eps; top y1=h+eps;
+lft x2=hround u-eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+x3=x4=1/4w; y3=38/40h; y4=23/40h;
+draw z3--z4; % number 1
+x5=x9=.65w; x10=x7=.85w; x6=.74w;
+y9=y10=-.2d; y6=.37h; y5=.32h; y7=.30h;
+draw z5{dir 45}..z6..z7{dir -90}..{dir 225}z9; % number 2
+draw z9--z10;
+endchar;
+
+% My own creation.
+cmchar "3/4 symbol";
+beginchar(oct"023", 12u#, body_height#, paren_depth#);
+italcorr body_height#*slant-.5u#;
+adjust_fit(0,0); pickup rule.nib;
+rt x1=hround(w-u)+eps; top y1=h+eps;
+lft x2=hround u-eps; bot y2=-d-eps;
+draw z1--z2; % diagonal
+draw (quartercircle rotated -90 & halfcircle) scaled .1875h shifted
+(.25w,.8562h); % number 3
+draw (halfcircle rotated -180 & quartercircle) scaled .1875h shifted
+(.25w,.6687h);
+x5=x6=32/40w; y7=y8=1/8h; y5=-.2d; y6=.37h; x7=26/40w; x8=.85w;
+draw z5--z6--z7--z8;
+endchar;
+
+% From the font cmsy10, file sym.mf
+iff known vertical: cmchar "Vertical line";
+beginchar(vertical,5u#,body_height#,paren_depth#);
+italcorr body_height#*slant+.5rule_thickness#-2u#;
+adjust_fit(0,0); pickup rule.nib;
+x1=x2=good.x .5w; top y1=h+eps; bot y2=-d-eps;
+draw z1--z2; % stem
+labels(1,2); endchar;
+
+% My own creation
+cmchar "Rule";
+beginchar(oct"005",12u#,x_height#,.7u#);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric below_baseline; below_baseline#:=.2u#;
+define_pixels(below_baseline);
+define_blacker_pixels(thickness);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(-below_baseline); rt x2=hround(w+6u#);
+lft x1=hround(0);
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+% My own creation
+cmchar "Underscore";
+beginchar("_",12u#,x_height#,.7u#);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric below_baseline; below_baseline#:=.2u#;
+define_pixels(below_baseline);
+pickup crisp.nib; pos1(vair,90); pos2(vair,90);
+top y1r=top y2r=vround(-below_baseline); x2=hround(w);
+x1=hround 0;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+% Hyphen from cmr10, file comlig.mf
+cmchar "Hyphen";
+beginchar("-",6u#,x_height#,0);
+italcorr .5x_height#*slant-.5u#;
+adjust_fit(0,0);
+numeric thickness; thickness=if hefty:bar else:.75[hair,stem] fi;
+pickup crisp.nib; pos1(thickness,90); pos2(thickness,90);
+top y1r=top y2r=vround(.5h+.5thickness); rt x2=hround(w-u)+eps;
+if monospace: x2=w-x1 else: lft x1=hround .2u-eps fi;
+filldraw stroke z1e--z2e; % bar
+penlabels(1,2); endchar;
+
+% My own creation
+cmchar "Cent sign";
+beginchar(oct"020",18u#,asc_height#,desc_depth#); autorounded;
+adjust_fit(if monospace:-3u#,-3u# else: 0,0 fi); pickup rule.nib;
+lft x6=hround u; x2=w-x6; top y8=h+o; bot y4=-d-o;
+circle_points;
+x9=x11=.65[x6,x4]; x10=x12=.35[x4,x2];
+y9=y10=.35[y6,y8]; y11=y12=.65[y4,y6];
+x13=x14=.5[x6,x2]-.3u; y13=y4+2u; y14=y8-2u;
+draw z10..z9..z11..z12; draw z13--z14;
+labels(1,2,3,4,5,6,7,8,9,10,11,12,13,14); endchar;
+
+% My own creation
+cmchar "Copyright";
+beginchar(oct"016",18u#,asc_height#,desc_depth#); autorounded;
+adjust_fit(if monospace:-3u#,-3u# else: 0,0 fi); pickup rule.nib;
+lft x6=hround u; x2=w-x6; top y8=h+o; bot y4=-d-o;
+circle_points; draw_circle; % circle
+x9=x11=.65[x6,x4]; x10=x12=.35[x4,x2];
+y9=y10=.35[y6,y8]; y11=y12=.65[y4,y6];
+draw z10..z9..z11..z12;
+labels(1,2,3,4,5,6,7,8,9,10,11,12); endchar;
+
+% My own creation
+cmchar "Registered";
+beginchar(oct"017",18u#,asc_height#,desc_depth#); autorounded;
+adjust_fit(if monospace:-3u#,-3u# else: 0,0 fi); pickup rule.nib;
+lft x6=hround u; x2=w-x6; top y8=h+o; bot y4=-d-o;
+circle_points; draw_circle; % circle
+x9=x11=x12=.7[x6,x8]; x10=x13=.3[x4,x2];
+y12=y13=.5[y4,y6]; y9=.5[y6,y8]; y11=.5[y12,y9]; y10=.5[y11,y9];
+x14=.08[x4,x2]; y14=y9;
+path p;
+p=z9--z14{dir 0}..z10..{dir 180}z11;
+z15=point 2.6 of p;
+draw z12--z9; draw z13--z15; draw p;
+labels(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15); endchar;
+
+% Stolen from the font cmr10, file accent.mf (actually the acute accent)
+cmchar "Footmark";
+beginchar(oct"015",9u#,min(asc_height#,2x_height#),0);
+italcorr h#*slant-if serifs: 1.5 fi u#;
+adjust_fit(0,0);
+if serifs: pickup crisp.nib; x1+.5stem=hround(w-2u); x2=2/3[x1,w-x1];
+ y1+.5stem=h+eps; y2=max(2/3[h,x_height],x_height+o+hair);
+ numeric theta; theta=angle(z2-z1)+90;
+ pos1(stem,theta); pos2(hair,theta);
+ filldraw circ_stroke z1e--z2e; % diagonal
+else: pickup fine.nib; pos1(stem,0); pos2(vair,0);
+ rt x1r=hround(w-1.5u); lft x2l=hround(.5w-.25u-.5vair);
+ top y1=h; bot y2=vround 2/3[h,x_height];
+ filldraw stroke z1e--z2e; fi % diagonal
+penlabels(1,2); endchar;
+
+% Stolen from the font cmsy10, file symbol.mf
+cmchar "Dagger mark";
+beginchar(oct"014",8u#,asc_height#,desc_depth#);
+adjust_fit(0,0); pickup fine.nib;
+pos1(stem,0); pos2(thin_join,0); pos3(stem,0); pos4(hair,0);
+pos5(stem,90); pos2'(thin_join,90); pos6(stem,90); z2'=z2;
+x1=x2=x3=x4; x1-.5stem=hround(.5w-.5stem); w:=r:=2x1;
+x5-.5stem=hround u; x6=w-x5;
+y1+.5stem=h+oo; y2=y5=y6; y3=.57y2; bot y4=-d-o;
+y5+.5stem=floor(x_height+.5stem);
+filldraw circ_stroke z1e{down}..z2e{down}..z3e{down}..z4e; % stem
+filldraw circ_stroke z5e{right}..{right}z2'e; % left bulb
+filldraw circ_stroke z6e{left}..{left}z2'e; % right bulb
+penlabels(1,2,3,4,5,6); endchar;
+
+% Stolen from the font cmr10, file accent.mf (the Scandinavian circle accent)
+cmchar "Degree";
+beginchar(oct"013",13u#+4/3(asc_height#-x_height#)*slant,asc_height#,0);
+adjust_fit(cap_serif_fit#,cap_serif_fit#);
+numeric circ_hair,circ_vair;
+circ_hair=hround min(hair,u+.5); circ_vair=vround min(vair,(h-x_height)/6+.5);
+penpos1(circ_vair,90); penpos3(circ_vair,-90);
+penpos2(circ_hair,180); penpos4(circ_hair,0);
+x2r=hround(.5w-1.5u-.5circ_hair);
+x4r=w-x2r; x1=x3=.5w; y1r=h+apex_o; y2=y4=.5[y1,y3];
+y3r=vround(1/3[x_height,h]+apex_o);
+penstroke pulled_arc.e(1,2) & pulled_arc.e(2,3)
+ & pulled_arc.e(3,4) & pulled_arc.e(4,1) & cycle; % bowl
+penlabels(1,2,3,4); endchar;
+
+% My own creation
+cmchar "Square";
+beginchar(oct"010",9u#,v_center(7u#));
+italcorr math_axis#*slant;
+adjust_fit(0,0); pickup rule.nib;
+draw unitsquare scaled 7u shifted (.5w-7u/2,math_axis-7u/2);
+endchar;
+
+% Stolen from the font cmsy10, file symbol.mf
+cmchar "Bullet";
+beginchar(oct"007",9u#,v_center(7u#));
+adjust_fit(0,0); pickup rule.nib; autorounded;
+lft x6=hround u; x2=w-x6; top y8=h; y2=math_axis; circle_points;
+filldraw z8{right}...z1{z2-z8}...z2{down}...z3{z4-z2}...z4{left}
+ ...z5{z6-z4}...z6{up}...z7{z8-z6}...cycle; % circle and interior
+labels(1,2,3,4,5,6,7,8); endchar;
+
+% Stolen from the font cmsy10, file sym.mf
+iff known minus: cmchar "Minus sign";
+beginarithchar(minus); pickup rule.nib;
+lft x1=hround 1.5u-eps; x2=w-x1; y1=y2=math_axis;
+draw z1--z2; % bar
+labels(1,2); endchar;
+
+input romanu; % upper case (majuscules)
+input itald; % numerals
+input titalp; % ampersand, question marks, currency sign
+input tpunct; % punctuation symbols common to roman and italic text
+if ligs>0: input tcomlig; fi % ligatures common with roman text
+if ligs<=1: input romsub; fi % substitutes for ligatures
+
+if not monospace:
+ k#:=-.5u#; kk#:=-1.5u#; kkk#:=-2u#; % three degrees of kerning
+ ligtable "d": "w": "l": "l" kern +u#;
+ ligtable "F": "V": "o" kern kk#, "e" kern kk#,
+ "u" kern kk#, "r" kern kk#, "a" kern kk#, "A" kern kkk#,
+ "K": "X": "O" kern k#, "C" kern k#, "G" kern k#, "Q" kern k#;
+ ligtable "T": "y" kern kk#,
+ "Y": "e" kern kk#, "o" kern kk#, "r" kern kk#, "a" kern kk#, "u" kern kk#,
+ "P": "W": "A" kern kk#;
+ ligtable "O": "D": "X" kern k#, "W" kern k#, "A" kern k#,
+ "V" kern k#, "Y" kern k#;
+ ligtable "A": "R": "n" kern k#, "l" kern k#, "r" kern k#, "u" kern k#,
+ "m" kern k#, "t" kern k#, "i" kern k#, "C" kern k#, "O" kern k#, "G" kern k#,
+ "h" kern k#, "b" kern k#, "U" kern k#, "k" kern k#, "v" kern k#, "w" kern k#,
+ "Q" kern k#, "L": "T" kern kk#, "Y" kern kk#, "V" kern kkk#, "W" kern kkk#,
+ "b": "c": "e": "o": "p": "r": "e" kern -u#, "a" kern -u#, "o" kern -u#,
+ "d" kern -u#, "c" kern -u#, "g" kern -u#, "q" kern -u#;
+ fi
+% there are ligature/kern programs for |"f"| in the {\tt romlig} file
+% and for |"-"|, |"`"|, and |"'"| in the {\tt comlig} file
+bye.