dvix27 - DVI to Xerox 2700 driver (Part 2 of 2)
cudcv at warwick.UUCP
cudcv at warwick.UUCP
Sat Feb 7 01:56:25 AEST 1987
<munch>
Here's part 2 of my dvi->x2700 driver
--------------------------- cut here ---------------------------------
#!/bin/sh
echo 'Start of DVI -> 2700 driver, part 02 of 02:'
echo 'x - Makefile'
sed 's/^X//' > Makefile << '/'
X# The following file and directory specifications may need changing at
X# your site:
X#
X# where are the bitmaps stored?
XFONTAREA=/usr/lib/tex/fonts
X#
X# where is the software to be installed
XBINAREA=/usr/local
X#
X# an Apollo-specific spool file
XSPOOLFILE=/usr/spool/laserwriter/apollo
X#
X
XOPTIM= -O
XCFLAGS = -DFONTAREA=\"${FONTAREA}\" \
X -DSPOOLFILE=\"${SPOOLFILE}\" '-DDVI2PS="/usr/local/dvix27 -q"' \
X '-DPOSTF="/usr/local/lib/laserf -c"' \
X '-DTEXTF="/usr/local/lib/laserf"' \
X $(OPTIM)
X
Xall: dvix27
X
Xdvix27: dvix27.o findfile.o
X cc ${CFLAGS} -o dvix27 dvix27.o findfile.o
X
Xinstall: all
X install -s -m 755 dvix27 ${BINAREA}/dvix27
X
X#
X# The following may be useful if you are trying to run this as a
X# printcap filter
X#
X
Xdvix27f: dvix27f.c
X ${CC} -o dvix27f ${CFLAGS} dvix27f.c
/
echo 'x - README'
sed 's/^X//' > README << '/'
XThe use of this program may not be readily apparent. If your
Xprinter's name is "laser", you would use a command sequence that
Xlooked something like this:
X
X % tex myfile
X % lpr -Plaser -d myfile.dvi
X
XIf you are using your own fonts, or want to restrict the range of printing,
Xyou should use something like
X
X % tex myfile
X % dvix27 -a '.:/usr/lib/tex/fonts' -f 1 -t 5 myfile > myfile.x27
X % lpr -Plaser -l myfile.x27
X
X
XInstallation comments:
X======================
X
XThe font area is assumed to be /usr/lib/tex/fonts. I do not believe that
Xthat this filter supports the TEXFONTS environment path. The font area is
Xarranged in a new fashion that will probably be showing up in other device
Xdrivers as well. All the tfm files are contained in /usr/lib/tex/fonts. If
Xa file named SUBDIR is present in /usr/lib/tex/fonts (or whatever directory
Xname you select), then the name of the font is taken as the name of a
Xsubdirectory in searching for the pxl file associated with the font. In
Xother words, amr10.1500pxl will be found in
X/usr/lib/tex/fonts/amr10/amr10.1500pxl. When the file named SUBDIR is not
Xpresent, all pxl files are looked for in the directory itself, in other
Xwords, /usr/lib/tex/fonts/amr10.1500pxl in the above example.
X
XThere are some constants in dvix27 which may need to be changed, TOP
Xand LEFT define the (0,0) point on the page, measured in 1/300" from
Xthe *bottom* and left edge (TOP = 3500 gives the top edge of the paper
Xon A4). The margin setting command is for A4 paper (search for %cm).
X
XNote that the fonts which come ready made with TeX are not much good
Xon the Xerox (they are too pale and weedy) - you should go back to the
XMETAFONT input and re-create them. The 'qms' mode from waits.mf seems
Xto be a good first approximation. Make up a METAFONT which includes
Xthe waits base (insert 'input waits ;' before the 'dump' in inimf),
Xand use lots of lines like
X
X mf \\mode=qms \; mag=magstep 0.5 \; input cmr10
X
Xthen use gftopk on the GF files to produce PK files that dvix27 can
Xread.
X
XI'm afraid there is no man page for this.
X
Xprintcap information
X====================
X
XWarwick use another program called dvix27f when the LaserWriter is
Xused with the /etc/printcap file. dvix27f invokes dvix27 and laserf.
Xlaserf is basically the standard lpf, but is *really* transparent when
Xgiven the -c flag (well almost ...). It uses a file which it expects
Xto find in /usr/local/lib/laser/setup to initialize the printer.
XChange the definition of setup in laserf.c if you want to move this.
XA sample setup file is in laser.setup, this will need changing for
Xprinters with different built in fonts or different paper sizes. Both
Xdvix27f.c and laserf.c are included here. Warwick's printcap entry
Xfor the 2700 reads:
X
X#
X# Laser Printer
X#
Xlaser|Laser Printer:\
X :lp=/dev/laser:br#9600:fs#06360:mx#0:ff=\Eo\f:tr=\f:\
X :of=/usr/local/lib/laserf:if=/usr/local/lib/laserf:\
X :df=/usr/lib/tex/dvix27f:\
X :af=/usr/adm/laseracct:\
X :rf=/usr/local/ansicc:sd=/usr/spool/lpd/laser:xs#20:
X
X
XHistory and acknowledgements
X============================
X
XThe driver was converted by Neal Holtz of Carleton University from a
XSun previewer originally written by Mark Senn and later modified by
Xothers (see dvi2ps for specifics). Additional modifications and
Xenhancements have been done by Scott Jones and Chris Lindblad at MIT.
XConversion to Xerox 2700 and to read PK files was done by Rob McMahon
Xat Warwick University (cudcv at uk.ac.warwick.daisy).
X
X(These notes added by Richard Furuta)
/
echo 'x - commands.h'
sed 's/^X//' > commands.h << '/'
X/*
X *
X * $Revision: 1.1 $
X * $Log: commands.h,v $
X * Revision 1.1 83/11/23 10:56:00 mds
X * Initial revision
X *
X *
X */
X#define SETC_000 0
X#define SETC_001 1
X#define SETC_002 2
X#define SETC_003 3
X#define SETC_004 4
X#define SETC_005 5
X#define SETC_006 6
X#define SETC_007 7
X#define SETC_008 8
X#define SETC_009 9
X#define SETC_010 10
X#define SETC_011 11
X#define SETC_012 12
X#define SETC_013 13
X#define SETC_014 14
X#define SETC_015 15
X#define SETC_016 16
X#define SETC_017 17
X#define SETC_018 18
X#define SETC_019 19
X#define SETC_020 20
X#define SETC_021 21
X#define SETC_022 22
X#define SETC_023 23
X#define SETC_024 24
X#define SETC_025 25
X#define SETC_026 26
X#define SETC_027 27
X#define SETC_028 28
X#define SETC_029 29
X#define SETC_030 30
X#define SETC_031 31
X#define SETC_032 32
X#define SETC_033 33
X#define SETC_034 34
X#define SETC_035 35
X#define SETC_036 36
X#define SETC_037 37
X#define SETC_038 38
X#define SETC_039 39
X#define SETC_040 40
X#define SETC_041 41
X#define SETC_042 42
X#define SETC_043 43
X#define SETC_044 44
X#define SETC_045 45
X#define SETC_046 46
X#define SETC_047 47
X#define SETC_048 48
X#define SETC_049 49
X#define SETC_050 50
X#define SETC_051 51
X#define SETC_052 52
X#define SETC_053 53
X#define SETC_054 54
X#define SETC_055 55
X#define SETC_056 56
X#define SETC_057 57
X#define SETC_058 58
X#define SETC_059 59
X#define SETC_060 60
X#define SETC_061 61
X#define SETC_062 62
X#define SETC_063 63
X#define SETC_064 64
X#define SETC_065 65
X#define SETC_066 66
X#define SETC_067 67
X#define SETC_068 68
X#define SETC_069 69
X#define SETC_070 70
X#define SETC_071 71
X#define SETC_072 72
X#define SETC_073 73
X#define SETC_074 74
X#define SETC_075 75
X#define SETC_076 76
X#define SETC_077 77
X#define SETC_078 78
X#define SETC_079 79
X#define SETC_080 80
X#define SETC_081 81
X#define SETC_082 82
X#define SETC_083 83
X#define SETC_084 84
X#define SETC_085 85
X#define SETC_086 86
X#define SETC_087 87
X#define SETC_088 88
X#define SETC_089 89
X#define SETC_090 90
X#define SETC_091 91
X#define SETC_092 92
X#define SETC_093 93
X#define SETC_094 94
X#define SETC_095 95
X#define SETC_096 96
X#define SETC_097 97
X#define SETC_098 98
X#define SETC_099 99
X#define SETC_100 100
X#define SETC_101 101
X#define SETC_102 102
X#define SETC_103 103
X#define SETC_104 104
X#define SETC_105 105
X#define SETC_106 106
X#define SETC_107 107
X#define SETC_108 108
X#define SETC_109 109
X#define SETC_110 110
X#define SETC_111 111
X#define SETC_112 112
X#define SETC_113 113
X#define SETC_114 114
X#define SETC_115 115
X#define SETC_116 116
X#define SETC_117 117
X#define SETC_118 118
X#define SETC_119 119
X#define SETC_120 120
X#define SETC_121 121
X#define SETC_122 122
X#define SETC_123 123
X#define SETC_124 124
X#define SETC_125 125
X#define SETC_126 126
X#define SETC_127 127
X#define SET1 128
X#define SET2 129
X#define SET3 130
X#define SET4 131
X#define SET_RULE 132
X#define PUT1 133
X#define PUT2 134
X#define PUT3 135
X#define PUT4 136
X#define PUT_RULE 137
X#define NOP 138
X#define BOP 139
X#define EOP 140
X#define PUSH 141
X#define POP 142
X#define RIGHT1 143
X#define RIGHT2 144
X#define RIGHT3 145
X#define RIGHT4 146
X#define W0 147
X#define W1 148
X#define W2 149
X#define W3 150
X#define W4 151
X#define X0 152
X#define X1 153
X#define X2 154
X#define X3 155
X#define X4 156
X#define DOWN1 157
X#define DOWN2 158
X#define DOWN3 159
X#define DOWN4 160
X#define Y0 161
X#define Y1 162
X#define Y2 163
X#define Y3 164
X#define Y4 165
X#define Z0 166
X#define Z1 167
X#define Z2 168
X#define Z3 169
X#define Z4 170
X#define FONT_00 171
X#define FONT_01 172
X#define FONT_02 173
X#define FONT_03 174
X#define FONT_04 175
X#define FONT_05 176
X#define FONT_06 177
X#define FONT_07 178
X#define FONT_08 179
X#define FONT_09 180
X#define FONT_10 181
X#define FONT_11 182
X#define FONT_12 183
X#define FONT_13 184
X#define FONT_14 185
X#define FONT_15 186
X#define FONT_16 187
X#define FONT_17 188
X#define FONT_18 189
X#define FONT_19 190
X#define FONT_20 191
X#define FONT_21 192
X#define FONT_22 193
X#define FONT_23 194
X#define FONT_24 195
X#define FONT_25 196
X#define FONT_26 197
X#define FONT_27 198
X#define FONT_28 199
X#define FONT_29 200
X#define FONT_30 201
X#define FONT_31 202
X#define FONT_32 203
X#define FONT_33 204
X#define FONT_34 205
X#define FONT_35 206
X#define FONT_36 207
X#define FONT_37 208
X#define FONT_38 209
X#define FONT_39 210
X#define FONT_40 211
X#define FONT_41 212
X#define FONT_42 213
X#define FONT_43 214
X#define FONT_44 215
X#define FONT_45 216
X#define FONT_46 217
X#define FONT_47 218
X#define FONT_48 219
X#define FONT_49 220
X#define FONT_50 221
X#define FONT_51 222
X#define FONT_52 223
X#define FONT_53 224
X#define FONT_54 225
X#define FONT_55 226
X#define FONT_56 227
X#define FONT_57 228
X#define FONT_58 229
X#define FONT_59 230
X#define FONT_60 231
X#define FONT_61 232
X#define FONT_62 233
X#define FONT_63 234
X#define FNT1 235
X#define FNT2 236
X#define FNT3 237
X#define FNT4 238
X#define XXX1 239
X#define XXX2 240
X#define XXX3 241
X#define XXX4 242
X#define FNT_DEF1 243
X#define FNT_DEF2 244
X#define FNT_DEF3 245
X#define FNT_DEF4 246
X#define PRE 247
X#define POST 248
X#define POST_POST 249
/
echo 'x - dvix27f.c'
sed 's/^X//' > dvix27f.c << '/'
X/*
X * dvipsf.c - output filter for postscript to printer
X * uses these other programs:
X * /usr/lib/postf (the lpr filter for postscript to laserwriter)
X * /usr/local/bin/dvi2ps (dvi to postscript translator)
X * /usr/lib/tex.ps (the postscript prologue to support TeX)
X *
X * Copyright 1985 Massachusetts Institute of Technology
X * Author: CJL at OZ
X *
X */
X
X/* #define DEBUGGING */
X
X#include <stdio.h>
X#include <signal.h>
X#include <sys/ioctl.h>
X#include <fcntl.h>
X
X#define PROLOGUE "/usr/lib/tex.ps"
X#ifndef DVI2PS
X#define DVI2PS "/usr/local/bin/dvi2ps -q"
X#endif
X#define CAT "/bin/cat"
X#ifndef POSTF
X#define POSTF "/usr/lib/applef"
X#endif
X#ifndef TEXTF
X#define TEXTF "/usr/lib/applef"
X#endif
X
XFILE *popen();
Xchar *user,*host;
X
Xmain(argc, argv)
X int argc;
X char *argv[];
X{
X char tfn[BUFSIZ],cmdbuf[BUFSIZ],efn[BUFSIZ];
X register int ch;
X register FILE *tf;
X int olderrfd,i;
X char *rindex();
X FILE *ef,*of;
X
X if (rindex(argv[0],'/')) argv[0] = rindex(argv[0],'/')+1;
X for (i = 1; i < argc; i++) {
X if (argv[i][0] == '-') switch (argv[i][1]) {
X case 'h':
X host = argv[++i];
X break;
X
X case 'n':
X user = argv[++i];
X break;
X
X default:
X break;
X }
X }
X /* Copy the dvi data to a temp file, since we have to give it by name
X * to dvi2ps.
X */
X if ((tf = fopen(mktemp(strcpy(tfn,"/usr/tmp/dvipsf.XXXXXX")),"w"))
X == NULL) {
X perror(tfn);
X exit(2);
X }
X while (!ferror(stdin) && (ch = getchar()) != EOF) putc(ch,tf);
X fclose(tf);
X if (ferror(stdin)) {
X perror("dvipsf stdin");
X unlink(tfn);
X exit(2);
X }
X
X /* Now divert standard error to a temp file so we can print it later. */
X if ((ef = fopen(mktemp(strcpy(efn,"/usr/tmp/dvipsf.err.XXXXXX")),"w+"))
X == NULL) {
X perror(efn);
X unlink(tfn);
X exit(2);
X }
X unlink(efn);
X fflush(stderr); olderrfd = dup(2); close(2);
X dup(fileno(ef));
X
X /* Run the filters */
X if (user != NULL && host != NULL)
X sprintf(cmdbuf,"%s %s | %s -n %s -h %s",DVI2PS,tfn,POSTF,user,host);
X else
X sprintf(cmdbuf,"%s %s | %s", DVI2PS, tfn, POSTF);
X system(cmdbuf);
X unlink(tfn);
X
X /* Now put back the old stderr */
X fflush(stderr); close(2); dup(olderrfd); close(olderrfd);
X
X /* And send all the messages to the printer */
X if (user != NULL && host != NULL)
X sprintf(cmdbuf,"%s -w80 -l66 -n %s -h %s",TEXTF,user,host);
X else
X sprintf(cmdbuf,"%s -w80 -l66", TEXTF);
X if ((of = popen(cmdbuf,"w")) == NULL) {
X perror(TEXTF);
X exit(2);
X }
X rewind(ef);
X while (!ferror(ef) && (ch = getc(ef)) != EOF) if (ch != '\031') {
X putc(ch,of);
X#ifdef DEBUGGING
X putc(ch,stderr);
X#endif
X }
X fclose(ef); pclose(of);
X if (ferror(ef)) {
X perror(efn);
X exit(2);
X }
X
X exit(0);
X}
/
echo 'x - findfile.c'
sed 's/^X//' > findfile.c << '/'
X/* findfile.c
X * Copyright 1985 Massachusetts Institute of Technology
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/dir.h>
X#include "findfile.h"
X
Xint
Xfindfileindir(area, name, mag, s, nname, nmag)
X char *area,*name,*s,*nname;
X int mag,*nmag;
X{
X FILE *f;
X char buf[BUFSIZ];
X int found = 0;
X char *rindex();
X
X sprintf(s,"%s/SUBDIR",area);
X if (!access(s,0)) sprintf(s,"%s/%s/%s.%dpxl",area,name,name,mag);
X else sprintf(s,"%s/%s.%dpxl",area,name,mag);
X if (!access(s,4)) {
X strcpy(nname,name);
X *nmag = mag;
X return(-1);
X }
X else {
X /* look for the "pk" version */
X (void) sprintf(rindex(s, '.'), ".%dpk", (2*mag+5)/10);
X if (!access(s, 4)) {
X (void) strcpy(nname, name);
X *nmag = mag;
X return (1);
X }
X else {
X sprintf(buf,"%s/NEEDED",area);
X if (!access(buf,2)) {
X sprintf(s,"%s.%dpxl\n",name,mag);
X f = fopen(buf,"r+");
X while (fgets(buf,sizeof(buf),f)) if (!strcmp(buf,s)) found++;
X if (!found) fputs(s,f);
X fclose(f);
X }
X return(0);
X }
X }
X
X}
X
X
X/* -1 for a pxl file, +1 for a pk file, otherwise 0; name in s */
Xint findfile(dirvec,dirveclen,area, name, mag, s, nname, nmag)
X char *dirvec[],*area,*name,*s,*nname;
X int dirveclen,mag,*nmag;
X{
X int i,point;
X char family[128];
X
X strcpy(nname,name);
X *nmag = mag;
X point = -1;
X (void) sscanf(name,"%[^0123456789.]%d",family,&point);
X
X /* First check dir area given in DVI file */
X if (*area && (i = findfileindir(area, name, mag, s, nname, nmag)))
X return(i);
X
X /* Then check along dirvec */
X for (i = 0; i < dirveclen; i++)
X if (i = findfileindir(dirvec[i], name, mag, s, nname, nmag))
X return(i);
X
X /* next check for closest magnification along dirvec */
X return(findanyfile(dirvec,dirveclen,family,point,mag,name,s,nname,nmag));
X}
X
Xint strdiff(s1,s2)
X char *s1,*s2;
X{
X register int diff = 0;
X
X while (*s1 && *s2) diff += abs(*s1++ - *s2++);
X while (*s1) diff += *s1++;
X while (*s2) diff += *s2++;
X return(diff);
X}
X
Xscanpdir(dir,name,
X family,point,mag,
X bestfamily,bestname,bestpoint,bestmag,
X min_df,min_dp,min_dm)
X char *dir,*name,*family,*bestfamily,*bestname;
X int point,mag,*bestpoint,*bestmag,*min_df,*min_dp,*min_dm;
X{
X DIR *dirstream;
X struct direct *dirrecord;
X char qfamily[128];
X char type[4];
X int qpoint,qmag,df,dp,dm;
X
X if (dirstream = opendir(dir)) {
X while (dirrecord = readdir(dirstream)) {
X if (!strcmp(dirrecord->d_name+dirrecord->d_namlen-3,"pxl")
X || !strcmp(dirrecord->d_name+dirrecord->d_namlen-2,"pk")) {
X qpoint = -1; qmag = -1;
X (void) sscanf(dirrecord->d_name,"%[^0123456789.]%d.%d%3s",
X qfamily,&qpoint,&qmag,type);
X if (!strcmp(type, "pk"))
X qmag *= 5;
X df = strdiff(family,qfamily);
X dp = abs(point - qpoint);
X dm = abs(mag - qmag);
X if ((df < *min_df)
X || (df == *min_df && dp < *min_dp)
X || (df == *min_df && dp == *min_dp && dm < *min_dm)) {
X sprintf(bestname,"%s/%s",dir,dirrecord->d_name);
X strcpy(bestfamily,qfamily);
X *bestpoint = qpoint;
X *bestmag = qmag;
X *min_df = df;
X *min_dp = dp;
X *min_dm = dm;
X }
X }
X }
X closedir(dirstream);
X }
X}
X
Xscandir(dir,name,
X family,point,mag,
X bestfamily,bestname,bestpoint,bestmag,
X min_df,min_dp,min_dm)
X char *dir,*name,*family,*bestfamily,*bestname;
X int point,mag,*bestpoint,*bestmag,*min_df,*min_dp,*min_dm;
X{
X DIR *dirstream;
X struct direct *dirrecord;
X int df;
X char pdir[MAXNAMLEN];
X
X if (dirstream = opendir(dir)) {
X while (dirrecord = readdir(dirstream)) {
X if (dirrecord->d_name[0] != '.') {
X df = strdiff(name,dirrecord->d_name);
X if (df <= *min_df) {
X sprintf(pdir,"%s/%s",dir,dirrecord->d_name);
X scanpdir(pdir,name,
X family,point,mag,
X bestfamily,bestname,bestpoint,bestmag,
X min_df,min_dp,min_dm);
X }
X }
X }
X closedir(dirstream);
X }
X}
X
X
X/* finds the best match to the desired font */
Xint findanyfile(dirvec,dirveclen,family,point,mag,name,s,nname,nmag)
X char *dirvec[],*family,*name,*s,*nname;
X int dirveclen,point,mag,*nmag;
X{
X char foo[MAXNAMLEN],bestname[MAXNAMLEN],bestfamily[128];
X int min_df,min_dp,min_dm,df,dp,dm,i,bestpoint,bestmag;
X
X bestname[0] = '\0';
X min_df = min_dp = min_dm = 9999999;
X for (i = 0; i < dirveclen; i++) {
X sprintf(foo,"%s/SUBDIR",dirvec[i]);
X if (!access(foo,0)) scandir(dirvec[i],name,
X family,point,mag,
X bestfamily,bestname,&bestpoint,&bestmag,
X &min_df,&min_dp,&min_dm);
X else scanpdir(dirvec[i],name,
X family,point,mag,
X bestfamily,bestname,&bestpoint,&bestmag,
X &min_df,&min_dp,&min_dm);
X }
X if (bestname[0]) {
X if (bestpoint > 0) sprintf(nname,"%s%d",bestfamily,bestpoint);
X else strcpy(nname,bestfamily);
X *nmag = bestmag;
X strcpy(s,bestname);
X if ((strcmp(bestfamily,family)
X || bestpoint != point || abs(bestmag - mag) > 2))
X fprintf(stderr,
X "Substituted font %s at mag %d for %s at mag %d.\n",
X nname,(bestmag * 4 + 3) / 6,
X name,(mag * 4 + 3) / 6);
X return strcmp(&bestname[strlen(bestname)-3], "pxl") ? (1) : (-1);
X }
X return(0);
X}
X
/
echo 'x - findfile.h'
sed 's/^X//' > findfile.h << '/'
X/* findfile.h
X * Copyright 1985 Massachusetts Institute of Technology
X */
X
Xextern int findfile();
X/* int findfile(dirvec,dirveclen,area, name, mag, s, nname, nmag)
X * char *dirvec[],*area,*name,*s,*nname;
X * int dirveclen,mag,*nmag;
X */
X
/
echo 'x - fontstr.h'
sed 's/^X//' > fontstr.h << '/'
X/****************************************************************************/
X/* */
X/* Structures defining the format of Xerox 2700 (EPS 1200) */
X/* laser printer font files. */
X/* */
X/* Note: these structures only match the format of the external */
X/* file when used on PDP-11s, VAXes, or other machines with the */
X/* same size data types and same byte ordering. */
X/* */
X/* The structures are based on investigative work done by the */
X/* author, and include help from sources at least one of whom */
X/* wishes to remain anonymous. This help is gratefully */
X/* acknowledged. */
X/* */
X/* Tim Clark Computer Unit University of Warwick June 1985 */
X/****************************************************************************/
X
Xstruct xheader { /* The font header - 24 (16 bit) words */
X unsigned short magic; /* should be 0xaaaa */
X unsigned char rev; /* revision number - unused */
X unsigned char flags; /* font type flags */
X unsigned short lo_length; /* length of file in bytes lsb */
X char fname[20]; /* font name in ascii */
X unsigned char ulinedepth; /* posn of underline below base */
X unsigned char ulinesize; /* thickness of underline */
X unsigned char hi_length; /* length of file in bytes msb */
X unsigned char strike_through; /* unused ? */
X unsigned char superdist; /* superscript distance */
X unsigned char subdist; /* subscript distance */
X short descend; /* maximum descender */
X short ascend; /* maximum ascender */
X short fheight; /* font height - 1 */
X unsigned char lowchar; /* first defined character */
X unsigned char highchar; /* last defined character */
X char partno[5]; /* part number - unused */
X char nulls[3]; /* reserved - set to null */
X};
X
Xstruct xchardesc { /* The "look up table" for each character.
X Each is 4 (16 bit words). */
X
X unsigned short nbyte; /* the length of the pattern in bytes */
X
X unsigned short lo_loc; /* the lowest 16 bits of the location of */
X /* the pattern, expressed as a 24-bit */
X /* quantity, which is the offset into the */
X /* font file */
X
X unsigned char hi_loc; /* the highest 8 bits of the pattern */
X /* location offset (0xff equivalent to 0) */
X
X unsigned char blocking; /* if "blocking" is zero then there is no */
X /* pattern information. Otherwise the value */
X /* 63-blocking gives the number of bytes in */
X /* each row of the character pattern */
X
X char orgy; /* in two's complement. How much the */
X /* character is above (or if -ve, below) */
X /* the baseline (portrait) or from the */
X /* typing position (landscape). Units are */
X /* DOUBLE rasters. */
X
X unsigned char width; /* the amount to move the typing position */
X /* on after drawing this character, in */
X /* units of rasters. */
X };
X
Xstruct def_str /* This structure is not found in the font file -
X it is for convenience, holding information for
X each character derived from the "look up table". */
X
X {
X int bytes_per_row; /* derived from xchardesc.blocking to give */
X /* the number of bytes needed for each row */
X /* of the pattern */
X
X char *pattern; /* the start of the pattern */
X
X long location; /* derived from hi_loc and lo_loc to give */
X /* the 24-bit index into the font file */
X };
X
X/* Font type flags */
X#define PORTRAIT 0 /* 8 1/2 is width */
X#define LANDSCAPE 1 /* 8 1/2 is length */
X#define FIXED_SP 0 /* fixed pitch */
X#define PROP_SP 2 /* proportional spacing */
X#define SHORT_FONT 0 /* font fits into 0xffff bytes */
X#define LONG_FONT 4 /* font is more than 0xffff bytes */
X
X/****************************************************************************/
X/* */
X/* The overall structure of the font is then as follows:- */
X/* */
X/* A 24 (16 bit)word header of struct xheader */
X/* */
X/* A 256 byte "qualification table?" */
X/* */
X/* A number of "loook up tables" of struct xchardesc. The number */
X/* is xheader.highchar + 1. */
X/* */
X/* The character patterns. */
X/* */
X/****************************************************************************/
X
X
X/****************************************************************************/
X/* */
X/* vfont format. Taken from vfont(5) */
X/* */
X/****************************************************************************/
X
Xstruct vfontheader {
X short magic;
X unsigned short size;
X short maxx;
X short maxy;
X short xtnd;
X };
X
Xstruct dispatch {
X unsigned short addr;
X short nbytes;
X char up;
X char down;
X char left;
X char right;
X short width;
X };
/
echo 'x - laser.setup'
sed 's/^X//' > laser.setup << '/'
X\E+X
X\E+1XCP12.5iso-L
X\E+2Titan12iso-P
X\Ezl0\E2\Em700,15,20,67,495
/
echo 'x - laserf.c'
sed 's/^X//' > laserf.c << '/'
X#ifndef lint
Xstatic char sccsid[] = "@(#)lpf.c 4.12 (Berkeley) 7/16/83";
X#endif
X
X/*
X * filter which reads the output of nroff and converts lines
X * with ^H's to overwritten lines. Thus this works like 'ul'
X * but is much better: it can handle more than 2 overwrites
X * and it is written with some style.
X * modified by kls to use register references instead of arrays
X * to try to gain a little speed.
X *
X * as a filter for the qume, literal really means it
X */
X
X#include <stdio.h>
X#include <signal.h>
X#include <sys/types.h>
X#include <sys/file.h>
X#include <sys/stat.h>
X
X#define MAXWIDTH 132
X#define MAXREP 10
X
X#define setup "/usr/local/lib/laser/setup" /* file on setup commands */
X#define RESET "\033+X\r\n" /* laser reset command */
X#define OFFSET "\033o" /* offset output */
X/* nroff doesn't let you use all eight bits, so ... */
X#define SO '\016' /* note to | 0200 into next */
Xint soflag = 0; /* we've got to | 0200 next character */
Xint nbs = 0; /* no. of backspaces for literal mode */
X
Xchar buf[MAXREP][MAXWIDTH];
Xint maxcol[MAXREP] = {-1};
Xint lineno;
Xint width = 132; /* default line length */
Xint length = 66; /* page length */
Xint indent; /* indentation length */
Xint npages = 1;
Xint literal; /* print control characters */
Xchar *name; /* user's login name */
Xchar *host; /* user's machine name */
Xchar *acctfile; /* accounting information file */
X
Xstruct stat stbuf; /* to find other execute bit for offsetting */
X
Xmain(argc, argv)
X int argc;
X char *argv[];
X{
X register FILE *p = stdin, *o = stdout;
X register int i, col;
X register char *cp;
X int done, linedone, maxrep;
X char ch, *limit;
X
X while (--argc) {
X if (*(cp = *++argv) == '-') {
X switch (cp[1]) {
X case 'n':
X argc--;
X name = *++argv;
X break;
X
X case 'h':
X argc--;
X host = *++argv;
X break;
X
X case 'w':
X if ((i = atoi(&cp[2])) > 0 && i <= MAXWIDTH)
X width = i;
X break;
X
X case 'l':
X length = atoi(&cp[2]);
X break;
X
X case 'i':
X indent = atoi(&cp[2]);
X break;
X
X case 'c': /* Print control chars */
X literal++;
X break;
X }
X } else
X acctfile = cp;
X }
X
X /*
X * setup printer
X */
X if (name && (i = open(setup, O_RDONLY)) >= 0) {
X while ((col = read(i, buf, MAXREP)) > 0)
X fwrite(buf, col, 1, o);
X (void) close (i);
X } else {
X fprintf(o, "%s", RESET);
X }
X
X for (cp = buf[0], limit = buf[MAXREP]; cp < limit; *cp++ = ' ');
X done = 0;
X
X if (!literal) while (!done) {
X col = indent;
X maxrep = -1;
X linedone = 0;
X while (!linedone) {
X switch (ch = getc(p)) {
X case EOF:
X linedone = done = 1;
X ch = '\n';
X break;
X
X case '\f':
X lineno = length;
X case '\n':
X if (maxrep < 0)
X maxrep = 0;
X linedone = 1;
X break;
X
X case '\b':
X if (--col < indent)
X col = indent;
X break;
X
X case '\r':
X col = indent;
X break;
X
X case '\t':
X col = ((col - indent) | 07) + indent + 1;
X break;
X
X case '\031':
X /*
X * lpd needs to use a different filter to
X * print data so stop what we are doing and
X * wait for lpd to restart us.
X */
X if ((ch = getchar()) == '\1') {
X fflush(stdout);
X kill(getpid(), SIGSTOP);
X break;
X } else {
X ungetc(ch, stdin);
X ch = '\031';
X }
X
X default:
X if (col >= width || !literal && ch < ' ' &&
X ch != '\033') {
X col++;
X break;
X }
X cp = &buf[0][col];
X for (i = 0; i < MAXREP; i++) {
X if (i > maxrep)
X maxrep = i;
X if (*cp == ' ') {
X *cp = ch;
X if (col > maxcol[i])
X maxcol[i] = col;
X break;
X }
X cp += MAXWIDTH;
X }
X col++;
X break;
X }
X }
X
X /* print out lines */
X for (i = 0; i <= maxrep; i++) {
X for (cp = buf[i], limit = cp+maxcol[i]; cp <= limit;) {
X putc(*cp, o);
X *cp++ = ' ';
X }
X if (i < maxrep)
X putc('\r', o);
X else
X putc(ch, o);
X if (++lineno >= length) {
X npages++;
X lineno = 0;
X }
X maxcol[i] = -1;
X }
X } else while (!done) { /* really literal */
X ch = getc(p);
X if (soflag) {
X ch |= 0200;
X soflag = 0;
X }
X
X switch (ch) {
X case EOF:
X done = 1;
X break;
X
X
X case '\f':
X lineno = length;
X case '\n':
X nbs = 0;
X if (++lineno >= length) {
X npages++;
X lineno = 0;
X }
X
X default:
X if (nbs) {
X fprintf(o, "\033rl%d ", nbs*25);
X nbs = 0;
X }
X putc(ch, o);
X break;
X
X case '\b':
X nbs++;
X break;
X
X case SO:
X soflag++;
X break;
X
X }
X }
X
X if (!lineno) { /* charged a sheet just for moving to tof */
X npages--;
X }
X /*
X * reset terminal
X */
X fprintf(o, RESET);
X /*
X * offset output according to other execute bit on printer
X *
X if (!fstat(fileno(o), &stbuf)) {
X if (stbuf.st_mode & 01)
X fprintf(o, OFFSET);
X stbuf.st_mode ^= 01;
X fchmod(fileno(o), stbuf.st_mode);
X }
X */
X
X if (name && acctfile && access(acctfile, 02) >= 0 &&
X freopen(acctfile, "a", stdout) != NULL) {
X printf("%7.2f\t%s:%s\n", (float)npages, host, name);
X }
X exit(0);
X}
/
echo 'Part 02 of DVI -> 2700 driver complete.'
exit
--
UUCP: ...!mcvax!ukc!warwick!cudcv PHONE: +44 203 523037
JANET: cudcv at uk.ac.warwick.daisy ARPA: cudcv at daisy.warwick.ac.uk
Rob McMahon, Computing Services, Warwick University, Coventry CV4 7AL, England
More information about the Comp.sources.unix
mailing list