|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T U
Length: 101382 (0x18c06) Types: TextFile Notes: Uncompressed file
└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89 └─⟦17e2956c5⟧ »./DVIware/obsolete/imagen.sh.Z« └─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« └─⟦ca79c7339⟧ └─⟦17e2956c5⟧ »DVIware/obsolete/imagen.sh.Z« └─⟦this⟧
#! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # ./imagen # This archive created: Fri Mar 11 16:12:04 1988 export PATH; PATH=/bin:$PATH if test ! -d './imagen' then mkdir './imagen' fi cd './imagen' if test -f 'NOTICE' then echo shar: will not over-write existing file "'NOTICE'" else cat << \SHAR_EOF > 'NOTICE' The imagen driver is obsolete and not maintained. Source code can be found in the imagen.sh file in ../ If you need it uncompress imagen.sh and run it through sh. These empty directories are here for your convenience. SHAR_EOF fi # end of overwriting check if test -f 'NewImagenNote' then echo shar: will not over-write existing file "'NewImagenNote'" else cat << \SHAR_EOF > 'NewImagenNote' From morgan.uci@Rand-Relay Fri Mar 11 02:50:29 1983 Return-Path: <Morgan.UCI.UCI@Rand-Relay> Date: 10 Mar 83 22:50:46 PST (Thu) From: Tim Morgan <morgan.uci@Rand-Relay> Subject: dvi-imagen program To: pavel@Cornell Via: UCI; 10 Mar 83 23:19-PDT Status: R I'm one of the two people here who made slight changes in dvi-imagen.c to make it run with the version of the software in the Imagen we have here. The major problem was that the line @document(language imPress, jobheader on) must appear in the impress file. Fortunately, whenever Imagen changed their software, they provided a switch on ipr to add that information to the imp file when spooled. Actually, there are two switches, -LimPress and -Djobheader on (language imPress and docdoheader "jobheader on"). I'm not sure the -D switch is needed, but without the language spec, the software in the Imagen just prints a fatal error message and stops with only a banner page. The other problem was the information that TeX puts in the DVI file at the beginning, the date and so forth. That apparently was being copied into the impress file, which then was shipped verbatim to the Imagen, resulting in undefined glyph errors. We simply put an #ifndef UciHacks ... #endif around the 2 or so lines of code that put the info into the impress file, and that seemed to fix the problem. I've been using the program in that state for about a day and a half, and things which got to the Imagen all seemed ok. Note that the error routines were not loaded in. Of course, it bombed when a the specified file didn't exist, and I've been able to create some .dvi files which also caused it to bomb. The error routines are being added now, and if that provides some information as to what's going on, I'll let you know. Alternately, I can mail you the .tex file which lead to the error (it's short). Tim Morgan morgan.uci@rand-relay SHAR_EOF fi # end of overwriting check if test -f 'README' then echo shar: will not over-write existing file "'README'" else cat << \SHAR_EOF > 'README' The device driver for the Imagen was originally written by Pavel Curtis of Cornell University. Subsequently, Mike Urban at TRW revised the driver. Ralph Campbell of Berkeley made modifications to bring things over to 4.2 bsd. This software is not supported by the Imagen Corporation. Problems should be reported to the Unix TeX Site Coordinator. The version in this directory is for 4.1bsd. See ./4.2note for information on modifications to get to 4.2bsd. Below are excerpts from messages from Mike Urban describing what is different between this version and the previous one. 1-Nov-83 01:12:19-PST,1733;000000000011 Return-Path: <trw-unix!trwspp!urban@Berkeley> Received: from ucbvax.ARPA (UCB-VAX.ARPA) by WASHINGTON.ARPA with TCP; Tue 1 Nov 83 01:12:15-PST Received: by ucbvax.ARPA (4.16/4.13) id AA27692; Tue, 1 Nov 83 01:12:40 pst From: trw-unix!trwspp!urban@Berkeley (Mike Urban) Date: Friday, 28 Oct 1983 13:59-PDT Subject: dvi-imagen Message-Id: <8310282059.AA17910@trwspp.UUCP> To: Richard Furuta <furuta@WASHINGTON.ARPA> Reply-To: Mike Urban <urban@rand-unix.ARPA> By the way, I've done some heavy mucking with dvi-imagen around here. The major changes are: -s produces its output on standard output instead of making you hunt the output down in /tmp as it previously did. -cN produces N copies. -L produces the output in Landscape mode (this is done rather badly as I stupidly rotate EVERY glyph, but it does work, if slowly); this item is required for the Reference-card thingy. -U disables the usual centering on the page, moving things to the upper-left corner of the page. \special{xxx} now works where xxx is one of insert(filename) overlay(filename) filename is taken to refer to an IMPRESS file which is either inserted with the current point as the origin, or overlaid on the page. This code was adapted from Imagen's dvi-2 driver. As noted, some of the code is somewhat kludgy, but it works well enough for us to get graphics output from the USG "stat" tools onto pretty viewgraphs in landscape mode, which is the sort of thing that management types think is the ultimate purpose of computer science. D'you want me to send you this stuff, should I sit on it until it looks cleaner, or should I send it to someone else? Mike ============================================================= 8-Nov-83 03:15:01-PST,94926;000000000001 Return-Path: <trw-unix!trwspp!urban@Berkeley> Received: from ucbvax.ARPA (UCB-VAX.ARPA) by WASHINGTON.ARPA with TCP; Tue 8 Nov 83 03:13:47-PST Received: by ucbvax.ARPA (4.16/4.13) id AA18261; Tue, 8 Nov 83 03:12:36 pst From: trw-unix!trwspp!urban@Berkeley (Mike Urban) Date: Monday, 7 Nov 1983 11:40-PST Subject: dvi-imagen sources Message-Id: <8311071941.AA00471@trwspp.UUCP> To: furuta@washington.ARPA (Richard Furuta) Following is a uuencoded version of a tar file of my current copy of the dvi-imagen sources. Let me know if you get this message, and were able to extract everything correctly. When I installed the magstep fixes, I noticed that the magnification from the DVI preamble wasn't getting multiplied in. Sure enough, when I ran a document with \magnification=\magstep 2 at the beginning, all the spacing was enlarged, but the glyphs were still unmagnified. I considered that this was a bug, not a feature, and fixed it. As I said before, the rotation stuff is done inefficiently, but it does seem to work. I should also note that attempting to print a document with a width wider than the physical paper width (e.g. forgetting to print a landscape-mode thingy with the -L landscape option) usually causes the Imagen to abort the job with no output and a mysterious error message. At least, OUR machine behaves that way. Finally, I include a copy of the manual page. We name the binary for dvi-imagen "iptex" to make it resemble the other Imagen spooling commands (iprint, ipr, ipq). Many of our users are easily confused by names like "dvi-imagen". Cheers, Mike ================================================================ SHAR_EOF fi # end of overwriting check if test -f '4.2dvif.sh' then echo shar: will not over-write existing file "'4.2dvif.sh'" else cat << \SHAR_EOF > '4.2dvif.sh' #! /bin/csh -f # # DVI 2 filter for the imagen # umask 0 set name=() host=() top: if ($#argv > 0) then switch ($argv[1]) case -n: shift argv if ($#argv > 0) then set name = $argv[1] shift argv endif goto top case -h: shift argv if ($#argv > 0) then set host = $argv[1] shift argv endif goto top default: shift argv goto top endsw endif onintr cleanup echo Converting DVI output > /usr/spool/ipd/status /usr/local/lib/dvi-imagen -s > /tmp/imp$$ (echo -n \@document\(owner \"$name\", site \"$host\", spooldate \"`date`\", \ language \"imPress\", jobheader on, jamresistance on\) ; \ cat /tmp/imp$$ ) | /usr/local/lib/ips -s /bin/rm -f /tmp/imp$$ exit(0) cleanup: /bin/rm -f /tmp/imp$$ exit(1) SHAR_EOF fi # end of overwriting check if test -f '4.2Note' then echo shar: will not over-write existing file "'4.2Note'" else cat << \SHAR_EOF > '4.2Note' Berkeley has moved some include files around in 4.2bsd. If you are running an imagen and 4.2bsd, this will be of interest to you (thanks to Brown University for tracking it down): From jsb Mon Nov 21 23:59:00 1983 Date: 21 Nov 83 (Monday) 23:58 EST From: John Bazik <jsb> To: jsv Subject: changes to =devices/imagen for 4.2 There are two changes that have to be made. In dvi-imagen.c change #include <unctrl.h> to #include <curses.h> In ipr.h change #include <dir.h> to #include <sys/dir.h> ================= It is also possible to integrate this stuff into the Berkeley line printer software as described in the following note and subsequent diff listing. Here's the note: ================= From ralph%ucbarpa@Berkeley Thu Dec 1 11:18:39 1983 Return-Path: <ralph%ucbarpa@Berkeley> Received: from UCB-VAX.ARPA by WASHINGTON.ARPA with TCP; Wed 30 Nov 83 18:31:09-PST Received: from ucbarpa.ARPA by UCB-VAX.ARPA (4.22/4.16) id AA04286; Wed, 30 Nov 83 17:04:09 pst Received: by ucbarpa.ARPA (4.22/4.16) id AA10306; Wed, 30 Nov 83 16:43:07 pst From: ralph%ucbarpa@Berkeley (Ralph Campbell) Message-Id: <8312010043.AA10306@ucbarpa.ARPA> Date: 30 Nov 1983 1643-PST (Wednesday) To: Richard Furuta <Furuta@WASHINGTON.ARPA> Subject: Re: Interested in testing out some Imagen software? Cc: harrison%ucbarpa@Berkeley In-Reply-To: Your message of Thu 17 Nov 83 18:54:43-PST. <8311180254.AA02253@ucbarpa.ARPA> ReSent-date: Thu 1 Dec 83 03:50:05-PST ReSent-from: Richard Furuta <Furuta@WASHINGTON.ARPA> ReSent-to: furuta@UW-JUNE.ARPA I have installed the imagen software you sent as our standard dvi-imagen program and it seems to work. I haven't tried to use the landscape option yet. I did need to make a few changes for 4.2 and the line printer software here (We don't use most of what imagen sends, (ipr, ipq, iprm, etc.). The changes are: dvi-imagen.c: uncntrl.h is in curses.h. dvi-imagen.c: if no file specified, uses stdin. ipr.h: include stat.h & dir.h -> sys/stat.h, sys/dir.h output.c: printf changed to remark so output is valid. ========================== and here's a diff of the changes: ========================== diff -c -r -b tex82work/newimagen/dvi-imagen.c 4.2stuff/imagen/dvi-imagen.c *** tex82work/newimagen/dvi-imagen.c Mon Nov 7 09:45:49 1983 --- 4.2stuff/imagen/dvi-imagen.c Mon Nov 28 11:06:28 1983 *************** *** 22,28 */ #include <stdio.h> ! #include <unctrl.h> #include <pwd.h> #include "dvi.h" #include "font.h" --- 22,28 ----- */ #include <stdio.h> ! #include <curses.h> #include <pwd.h> #include "dvi.h" #include "font.h" *************** *** 36,42 /* 8 inches of printing area */ #define PIXELS_PER_PAGE (11 * 240) /* 11 inches of printing area */ ! #define FONT_DIRECTORY "/usr/lib/tex/fonts" #define pixel_round(x) ((long) (conv * (double) (x) + 0.5)) #define dvi_round(x) ((long) ((double) (x) / conv + 0.5)) --- 36,42 ----- /* 8 inches of printing area */ #define PIXELS_PER_PAGE (11 * 240) /* 11 inches of printing area */ ! #define FONT_DIRECTORY "/usr/local/fonts/pixel" #define pixel_round(x) ((long) (conv * (double) (x) + 0.5)) #define dvi_round(x) ((long) ((double) (x) / conv + 0.5)) *************** *** 73,79 double conv; long numerator, denominator, magnification; char *output_file_name; ! char *Usage_str = "Usage: iptex [-U] [-L] [-v] [-s] [-d] <dvi-file>"; long read_postamble(); unsigned long num(); --- 73,79 ----- double conv; long numerator, denominator, magnification; char *output_file_name; ! char *Usage_str = "Usage: dvi-imagen [-U] [-L] [-v] [-s] [-d] [dvi-file]"; long read_postamble(); unsigned long num(); *************** *** 89,95 long last_page; /* file offset of last page of output */ int nc; ! while (argv[1][0] == '-') { switch (argv[1][1]) { --- 89,95 ----- long last_page; /* file offset of last page of output */ int nc; ! while (argc > 1 && argv[1][0] == '-') { switch (argv[1][1]) { *************** *** 130,136 argc--; } ! if (argc != 2) error(Usage_str); if ((fp = fopen(argv[1], "r")) == NULL) { --- 130,136 ----- argc--; } ! if (argc > 2) error(Usage_str); if (argc == 2) { *************** *** 133,139 if (argc != 2) error(Usage_str); ! if ((fp = fopen(argv[1], "r")) == NULL) { char longername[256]; strcpy (longername, argv[1]); strcat (longername, ".dvi"); --- 133,139 ----- if (argc > 2) error(Usage_str); ! if (argc == 2) { char longername[256]; if ((fp = freopen(argv[1], "r", stdin)) == NULL) { *************** *** 135,140 if ((fp = fopen(argv[1], "r")) == NULL) { char longername[256]; strcpy (longername, argv[1]); strcat (longername, ".dvi"); if ((fp = fopen (longername, "r")) == NULL) --- 135,142 ----- if (argc == 2) { char longername[256]; + + if ((fp = freopen(argv[1], "r", stdin)) == NULL) { strcpy (longername, argv[1]); strcat (longername, ".dvi"); if ((fp = freopen(longername, "r", stdin)) == NULL) *************** *** 137,143 char longername[256]; strcpy (longername, argv[1]); strcat (longername, ".dvi"); ! if ((fp = fopen (longername, "r")) == NULL) error("dvi-imagen: Can't open %s", argv[1]); } strcpy (InputName, argv[1]); --- 139,145 ----- if ((fp = freopen(argv[1], "r", stdin)) == NULL) { strcpy (longername, argv[1]); strcat (longername, ".dvi"); ! if ((fp = freopen(longername, "r", stdin)) == NULL) error("dvi-imagen: Can't open %s", argv[1]); } strcpy (InputName, argv[1]); *************** *** 141,146 error("dvi-imagen: Can't open %s", argv[1]); } strcpy (InputName, argv[1]); process_preamble(fp); --- 143,152 ----- error("dvi-imagen: Can't open %s", argv[1]); } strcpy (InputName, argv[1]); + } else { + fp = stdin; + strcpy (InputName, "stdin"); + } process_preamble(fp); *************** *** 388,393 long glyph_ptr[128]; /* Seek locations of each glyph */ int i, j, k; realsize = (magnification/1000.)*((float) fontp->scale / fontp->design); unmodsize = (realsize * 1000) + 0.5; /* a real hack to correct for rounding in some cases -- rkf */ --- 394,404 ----- long glyph_ptr[128]; /* Seek locations of each glyph */ int i, j, k; + if (debug) + remark("scale = %d, design = %d", fontp->scale, fontp->design); + #ifdef OLD + realsize = ((float) fontp->scale / fontp->design); + #else realsize = (magnification/1000.)*((float) fontp->scale / fontp->design); #endif unmodsize = (realsize * 1000) + 0.5; *************** *** 389,394 int i, j, k; realsize = (magnification/1000.)*((float) fontp->scale / fontp->design); unmodsize = (realsize * 1000) + 0.5; /* a real hack to correct for rounding in some cases -- rkf */ if(unmodsize==1095) realsize = 1.095445; /* stephalf */ --- 400,406 ----- realsize = ((float) fontp->scale / fontp->design); #else realsize = (magnification/1000.)*((float) fontp->scale / fontp->design); + #endif unmodsize = (realsize * 1000) + 0.5; if (debug) remark("real = %g, unmod = %d", realsize, unmodsize); *************** *** 390,395 realsize = (magnification/1000.)*((float) fontp->scale / fontp->design); unmodsize = (realsize * 1000) + 0.5; /* a real hack to correct for rounding in some cases -- rkf */ if(unmodsize==1095) realsize = 1.095445; /* stephalf */ else if(unmodsize==1315) realsize=1.314534; /* stepihalf */ --- 402,409 ----- realsize = (magnification/1000.)*((float) fontp->scale / fontp->design); #endif unmodsize = (realsize * 1000) + 0.5; + if (debug) + remark("real = %g, unmod = %d", realsize, unmodsize); /* a real hack to correct for rounding in some cases -- rkf */ if(unmodsize==1095) realsize = 1.095445; /* stephalf */ else if(unmodsize==1315) realsize=1.314534; /* stepihalf */ *************** *** 413,418 } } fseek(pxlfp, - (5 * 4L), 2); /* Seek to trailer info */ checksum = four(pxlfp); magnify = four(pxlfp); --- 427,435 ----- } } + if (debug) + remark("read font %s", filename); + fseek(pxlfp, - (5 * 4L), 2); /* Seek to trailer info */ checksum = four(pxlfp); magnify = four(pxlfp); *************** *** 532,538 } else ImPressStart((char *)0, job_id, verbose); - } \f --- 549,554 ----- } else ImPressStart((char *)0, job_id, verbose); } \f diff -c -r -b tex82work/newimagen/ipr.h 4.2stuff/imagen/ipr.h *** tex82work/newimagen/ipr.h Fri May 20 11:39:14 1983 --- 4.2stuff/imagen/ipr.h Fri Nov 18 11:38:57 1983 *************** *** 20,27 # define LineSize 128 /* size of a data line */ # include <sys/types.h> ! # include <dir.h> ! # include <stat.h> # include <signal.h> # include <stdio.h> # include "c.h" --- 20,27 ----- # define LineSize 128 /* size of a data line */ # include <sys/types.h> ! # include <sys/dir.h> ! # include <sys/stat.h> # include <signal.h> # include <stdio.h> # include "c.h" diff -c -r -b tex82work/newimagen/output.c 4.2stuff/imagen/output.c *** tex82work/newimagen/output.c Tue Oct 25 14:50:38 1983 --- 4.2stuff/imagen/output.c Wed Nov 23 11:10:09 1983 *************** *** 422,428 register struct font **fp; if (debug) ! printf( "Begin page, Needed = %d, available = %d\n", MemoryNeeded, MemoryAvailable ); if (MemoryNeeded >= MemoryAvailable) ImPressDeleteGlyphs(); --- 422,428 ----- register struct font **fp; if (debug) ! remark( "Begin page, Needed = %d, available = %d\n", MemoryNeeded, MemoryAvailable ); if (MemoryNeeded >= MemoryAvailable) ImPressDeleteGlyphs(); SHAR_EOF fi # end of overwriting check if test -f 'special.c' then echo shar: will not over-write existing file "'special.c'" else cat << \SHAR_EOF > 'special.c' #include <stdio.h> #include "resfonts.h" #include "imPcodes.h" #define white(x) (x==' ' || x=='\t') char *index(),*rindex(); extern int landscape; typedef char bool; #define TRUE 1 #define FALSE 0 DoSpecial(bytes,fp) long bytes; FILE *fp; { static bool initfonts=FALSE; bool first; unsigned long size, tempsize; FILE *tempin; char *ai,*bi,*ci,*di,*ei,*fi; char inchar; int tempi; int i; enum spectype {INSERT, OVERLAY}; enum spectype optype; ai = bi = (char *) malloc((tempsize = bytes)+1); while (tempsize--) *bi++=(char) fgetc(fp); *bi='\0'; /* null out string */ bi = ai; if (size > 132){ fprintf(stderr, "special command > 132 characters\n"); free(ai); return; } while(white(*bi)) bi++; /* skip leading white space */ ei = ci = bi; if (!index(ei,'(') || !rindex(ei,')')){ /* check for leading and trailing *\ fprintf(stderr, "incorrect special format\n"); /* prens */ free(ai); return; } while (!white(*ci) && *ci != '(' ) ci++; /* skip non white till ( or white */ *ci='\0'; /* make a string of it */ while (*ei){ /* and lowercase it all */ if (*ei >= 'A' && *ei <= 'Z') *ei = *ei + 'a' - 'A'; ei++; } if (!strcmp("insert",bi)) /* find include, overlay, or */ optype = INSERT; else if (!strcmp("overlay",bi)) /* else it is an error */ optype = OVERLAY; else { fprintf(stderr, "special command operation must be 'insert' or 'overlay'\n"); free(ai); return; } bi = ++ci; while(white(*bi) || *bi == '(' ) bi++; /* find the file name */ while(white(*bi)) bi++; ci = bi; while(!white(*ci) && *ci != ')') ci++; /* delimited by a ) */ *ci = '\0'; /* make a string of it */ if ((tempin = fopen(bi ,"r")) == NULL){ /* open the file */ fprintf(stderr, " can't open %s \n",bi); free(ai); return; } free(ai); /* no longer need this */ /* UpdPos(); */ ImPressPutc(APUSH); switch (optype){ /* At the moment, only overlay(file) and insert(file) are * recognized. We use a slightly modified 'impen' (from Stanford * via Imagen to produce this stuff, which makes plots come out * in landscape mode. Hence the rotation and stuff. Other * Impress-production software may, of course, behave differently... */ case OVERLAY: ImPressPutc(APAGE); if (landscape) { ImPressPutc(AMS); ImPressPutc(0104); } else { ImPressPutc(ASABSV); ImPressBufWord(2040); /* 8.5 in down */ ImPressPutc(AMS); ImPressPutc(0147); ImPressPutc(APAGE); } break; case INSERT: ImPressPutc(AMS); if (landscape) ImPressPutc(0144); else ImPressPutc(0147); break; } if (!initfonts) { /* Haven't initialized res fonts */ for (i=0;i<N_RES_FONTS; i++) { ImPressPutc(ACREFAM); ImPressPutc(fontTable[i].family); ImPressPutc(1); ImPressPutc(0); ImPressPrintf("%s",fontTable[i].name); ImPressPutc(0); } initfonts=TRUE; } first = TRUE; while ((tempi = getc(tempin)) != EOF) { inchar = (char) tempi; if (inchar == '@' && first) { /* remove document control */ while (((inchar = getc(tempin)) != EOF) && (inchar != ')' )); tempi = getc(tempin); } first = FALSE; ImPressPutc(tempi); } ImPressPutc(APAGE); ImPressPutc(APOP); } SHAR_EOF fi # end of overwriting check if test -f 'rotate.c' then echo shar: will not over-write existing file "'rotate.c'" else cat << \SHAR_EOF > 'rotate.c' char *malloc(); char *rotate (glyph, ht, wd) char *glyph; int ht, wd; { int byteswide; int oldwidth; int byteoff, bitmask, outbitoff, outbit, posn, i; char *opt, *outptr; if (ht == 0 || wd == 0) return (glyph); byteswide = (ht+7)/8; oldwidth = (wd+7)/8; opt = malloc (1 + byteswide*wd); outptr = opt; *outptr = '\0'; for (posn = 0; posn < wd; posn++) /* Pick the nth bit off each row */ { bitmask = 1 << (7 - (posn%8) ); byteoff = posn/8; outbitoff = 7; for (i = 0; i < ht ; i++) /* Get from each row... */ { if (outbitoff < 0) { outbitoff = 7; outptr++; *outptr = '\0'; } outbit =(*(glyph + ((ht-i)-1)*oldwidth + byteoff) & bitmask) != 0; *outptr |= outbit << outbitoff; outbitoff--; } outptr++; *outptr = '\0'; } return (opt); } SHAR_EOF fi # end of overwriting check if test -f 'resfonts.h' then echo shar: will not over-write existing file "'resfonts.h'" else cat << \SHAR_EOF > 'resfonts.h' #define TEXTURE_FAMILY 110 #define N_RES_FONTS 8 typedef struct { short family; char *name; } resfont; resfont fontTable[]= { { TEXTURE_FAMILY+0, "textures"}, { TEXTURE_FAMILY+1, "cmasc8"}, { TEXTURE_FAMILY+2, "cmasc10"}, { TEXTURE_FAMILY+3, "cmasc12"}, { TEXTURE_FAMILY+4, "cmasc14"}, { TEXTURE_FAMILY+5, "cmasc7"}, { TEXTURE_FAMILY+6, "cmb18"}, { TEXTURE_FAMILY+7, "IMAGEN80"} }; SHAR_EOF fi # end of overwriting check if test -f 'output.c' then echo shar: will not over-write existing file "'output.c'" else cat << \SHAR_EOF > 'output.c' /* * output.c - implements the ImPress output primitives * This is the verbose (decoded) version, * along with the encoded version, default unless * * * written by Bill Nowicki, September 1981 * Stanford University * * January 1982 Bill Nowicki * - Added page buffering * - Added glyph deletion */ # include <stdio.h> # include "font.h" # include "imPcodes.h" # include "ipr.h" # include "impress.h" static struct font *CurrentFont = NULL; static FILE *imPressFile = NULL; static int Verbose = 0; static int MemoryAvailable = GlyphSize; static int MemoryNeeded = 0; extern int landscape; /* * The page buffer. A list of Glyphs, i.e. (font,char) pairs * that are needed on this page, and a list of the actual typesetting * commands. */ static struct font *GlyphTable[GlyphsPerPage]; static char GlyphChars[GlyphsPerPage]; static char PageBuffer[InputSize]; static int GlyphPointer = 0, PagePointer = 0; ImPressPutc( c ) { /* * Put the indicated character into the page buffer */ if (PagePointer>=InputSize) fprintf( stderr, "Input Area overflow\n"); PageBuffer[PagePointer++] = c; } ImPressBufWord( w ) { /* * output a (big-endian) word to the ImPress page buffer */ ImPressPutc( (w>>8)&0377 ); ImPressPutc( (w)&0377 ); } ImPressPrintf( s, arg1, arg2, arg3, arg4, arg5 ) { /* * printf the string with arguments into the page buffer */ char buf[512]; int len; sprintf( buf, s, arg1, arg2, arg3, arg4, arg5 ); len = strlen(buf); if (PagePointer+len>=InputSize) fprintf( stderr, "Input Area overflow\n"); strncpy( PageBuffer+PagePointer, buf, len); PagePointer += len; } ImPressFont( f ) struct font *f; { /* * switch to font f */ if (CurrentFont == f) return; if (Verbose) ImPressPrintf( "@F %d@", f->Inumber ); else { ImPressPutc( AF ); ImPressPutc( f->Inumber ); } CurrentFont = f; } ImPressMplus() { if (Verbose) ImPressPrintf("@MPLUS@"); else ImPressPutc( AMP ); } ImPressMminus() { if (Verbose) ImPressPrintf("@MMINUS@"); else ImPressPutc( AMM ); } ImPressMove( deltaX ) { /* * Move the X (major axis) coordinate */ if (-128 <= deltaX && deltaX <= 127) { if (Verbose) ImPressPrintf( "@M %d@\n", deltaX); else { ImPressPutc( AM ); ImPressPutc( deltaX ); ImPressPutc( AM ); } } else { if (Verbose) ImPressPrintf( "@H %d 1@\n", deltaX); else { ImPressPutc( AH ); ImPressPutc( (deltaX >> 7) & 0377 ); ImPressPutc( (deltaX << 1) & 0376 | 01 ); } } } ImPressSetX( x ) { /* * set the X (major axis) coordinate */ if (Verbose) ImPressPrintf( "@H %d 0@\n", x); else { ImPressPutc( AH ); ImPressPutc( (x>>7)&0377 ); ImPressPutc( (x<<1)&0376 ); } } ImPressSetSpace( s ) { /* * set the "word space" value */ if (Verbose) ImPressPrintf( "@SETSP %d@\n", s); else { ImPressPutc( ASETSP ); ImPressBufWord( s ); } } ImPressSpace() { /* * do a default word space */ if (Verbose) ImPressPrintf( "@SP0@\n" ); else ImPressPutc( ASP0 ); } ImPressSetY(y) { /* * set the Y (minor axis) coordinate */ if (Verbose) ImPressPrintf( "@V %d 0@\n", y); else { ImPressPutc( AV ); ImPressPutc( (y>>7)&0377 ); ImPressPutc( (y<<1)&0376 ); } } ImPressCharacter( c ) char c; { /* * Output the character c in the current font at the current * position. First we check its state (loaded, wanted, etc.) */ switch (CurrentFont->state[c]) { case Ready: CurrentFont->state[c]=Wanted; GlyphChars[GlyphPointer ]=c; GlyphTable[GlyphPointer++]=CurrentFont; MemoryNeeded += ImPressSize( CurrentFont, c ); break; case Loaded: CurrentFont->state[c]=Kept; GlyphChars[GlyphPointer ]=c; GlyphTable[GlyphPointer++]=CurrentFont; break; case Wanted: case Kept: case InProm: break; default: remark("Weird state for character %d in font %s\n", c, CurrentFont->fontname ); abort(); } if (Verbose && c=='@') ImPressPrintf( "@AT@" ); else ImPressPutc( c ); } ImPressGlyph( f, c ) struct font *f; unsigned char c; { register char *glyph = f->Glyph[c]; int bytes = (f->W[c]+7) / 8; int row, col; /* * send the indicated glyph in the font f to the Imprint file. * "Small" glyphs have all dimensions less than eight bits. */ if (f->W[c] == 0 || f->H[c] == 0) return; if (Verbose) { if ( abs(f->W[c]) < 128 && abs(f->H[c]) < 128 && abs(f->X[c]) < 128 && abs(f->Y[c]) < 128 ) fprintf( imPressFile, "@SGLY" ); else fprintf( imPressFile, "@BGLY" ); fprintf( imPressFile, " 0 %d %d %d %d %d %d %d\n", f->Inumber, c, f->pxl_adv[c], f->W[c], f->X[c], f->H[c], f->Y[c]); fprintf( imPressFile, "f = %o, f->TeXnumber = %d\n", f, f->TeXnumber); for (row=0; row < f->H[c]; row++) { for (col=0; col<bytes; col++) { static char map[] = { '.', 'O' }; putc( map[ (*glyph >> 7) & 1 ], imPressFile ); putc( map[ (*glyph >> 6) & 1 ], imPressFile ); putc( map[ (*glyph >> 5) & 1 ], imPressFile ); putc( map[ (*glyph >> 4) & 1 ], imPressFile ); putc( map[ (*glyph >> 3) & 1 ], imPressFile ); putc( map[ (*glyph >> 2) & 1 ], imPressFile ); putc( map[ (*glyph >> 1) & 1 ], imPressFile ); putc( map[ (*glyph ) & 1 ], imPressFile ); if (col&1) putc( ' ', imPressFile ); glyph++; } if (bytes&1) fprintf( imPressFile, "........" ); putc( '\n', imPressFile ); } fprintf( imPressFile, "@\n" ); } else { /* * the encoded form of glyph loading */ int rotation; if (landscape) rotation = 0100; else rotation = 0; if ( abs(f->W[c]) < 128 && abs(f->H[c]) < 128 && abs(f->X[c]) < 128 && abs(f->Y[c]) < 128 ) { int temp; putc( ASGLY, imPressFile ); putc(rotation | (f->Inumber>>1), imPressFile ); putc( ( (f->Inumber&1)<<7)|c, imPressFile ); putc( f->pxl_adv[c], imPressFile ); putc( f->W[c], imPressFile ); putc( f->X[c], imPressFile ); putc( f->H[c], imPressFile ); putc( f->Y[c], imPressFile ); } else { putc( ABGLY, imPressFile ); putc(rotation | (f->Inumber>>1), imPressFile ); putc( ((f->Inumber&1)<<7)|c, imPressFile ); ImPressPutWord( f->pxl_adv[c] ); ImPressPutWord( f->W[c] ); ImPressPutWord( f->X[c] ); ImPressPutWord( f->H[c] ); ImPressPutWord( f->Y[c] ); } fwrite( glyph, 1, f->H[c]*bytes, imPressFile ); } f->state[c] = Loaded; } ImPressRule( w, h ) { /* * draw a rule (rectangle) at current point with given dimensions */ if (Verbose) { if ( abs(w) < 127 && abs(h) < 127 ) ImPressPrintf( "@SRULE" ); else ImPressPrintf( "@BRULE" ); ImPressPrintf( " %d %d %d@\n", w, h, -h); return; } if ( abs(w) < 127 && abs(h) < 127 ) { ImPressPutc( ASRULE ); ImPressPutc( w ); ImPressPutc( h ); ImPressPutc(-h ); return; } ImPressPutc( ABRULE ); ImPressBufWord( w ); ImPressBufWord( h ); ImPressBufWord(-h ); } ImPressPutWord( w ) { /* * output a (big-endian) word to the ImPress file */ putc( (w>>8)&0377, imPressFile ); putc( (w)&0377, imPressFile ); } ImPressStart( fileName, jobID, verbosity ) char *fileName; char *jobID; int verbosity; { /* * open the indicated file name for imPress output * Verbosity is true to use the Verbose (decoded) mode. * Here we write a dummy job name and ImPress version. * Returns nonzero if it cannot open the file. */ if (fileName == (char *)0) imPressFile = stdout; else imPressFile = fopen( fileName, "w" ); if (imPressFile==NULL) { if (debug) printf( "Unable to open %s\n", fileName ); return(TRUE); } Verbose = verbosity; #ifdef OLDIMAGEN fprintf( imPressFile, "2 %s", jobID ); putc( 0, imPressFile ); fprintf( imPressFile, "12345678"); #endif if (landscape) { if(Verbose) { fprintf(imPressFile,"@SET-HV-SYSTEM"); fprintf(imPressFile," %o\n",0101); } else { fprintf(imPressFile,"%c%c",AMS,0101); } } MemoryNeeded = 0; MemoryAvailable = GlyphSize; return(FALSE); } ImPressBeginPage() { /* * begin a page of an imPress file */ PagePointer = 0; GlyphPointer = 0; } ImPressEndPage() { /* * end a page of an impress file. * * First we delete glyphs we do not use on this page if necessary, * then output all the glyphs we need, then finally dump the Page buffer. */ register char *glyphc; register struct font **fp; if (debug) printf( "Begin page, Needed = %d, available = %d\n", MemoryNeeded, MemoryAvailable ); if (MemoryNeeded >= MemoryAvailable) ImPressDeleteGlyphs(); for (glyphc=GlyphChars, fp=GlyphTable; glyphc < GlyphChars+GlyphPointer; glyphc++, fp++) switch ( (*fp)->state[ *glyphc] ) { case Wanted: ImPressGlyph( *fp, *glyphc ); default: (*fp)->state[ *glyphc ] = Loaded; } MemoryAvailable -= MemoryNeeded; if (Verbose) fprintf( imPressFile, "@PAGE@\n" ); else putc( APAGE, imPressFile ); fwrite( PageBuffer, 1, PagePointer, imPressFile ); if (Verbose) fprintf( imPressFile, "@END@\n" ); else putc( AEND, imPressFile ); MemoryNeeded = 0; } ImPressFinish() { /* * End and close out the imPress file */ if (Verbose) fprintf( imPressFile, "@EOF@" ); else putc( AEOF, imPressFile ); fclose( imPressFile ); } ImPressSize( f, c ) register struct font *f; register char c; { /* * Returns the size of a glyph in the ImPrint's memory. * VERY dependent on the controller code. */ register int size; int bytes = (f->W[c]+7)/8; if ( ( f->pxl_adv[c] | f->W[c] | f->H[c] | abs(2*f->X[c]) | abs(2*f->Y[c]) ) < 256 ) size = 12; else size = 16; size += bytes*f->H[c]; if (bytes&1) size += f->H[c]; if (bytes<=2 && f->H[c]&1) size += bytes; return(size); } ImPressDeleteGlyphs() { /* * Make a pass through all the fonts we have loaded, * deleting those glyphs that are loaded but not needed onthis page. */ register struct font *f; register char c; for (f=fontListHead; f; f=f->next) for (c=f->bc;c<=f->ec;c++) if (f->state[c]==Loaded) { if (Verbose) fprintf( imPressFile, "@DELG 0 %d %d @\n" , f->Inumber, c ); else { putc( ADELG, imPressFile ); putc( f->Inumber>>1, imPressFile ); putc( (f->Inumber&1)<<7|c, imPressFile ); } MemoryAvailable += ImPressSize( f, c ); f->state[c] = Ready; } if (debug) printf( "After Deleting glyphs, Memory Needed = %d bytes, Available = %d\n", MemoryNeeded, MemoryAvailable ); } ImPressSendIt( fileName, banner, inputName, numberPages, numberCopies, writeFlag, mailFlag) char *fileName; /* name of temporary file */ char *banner; /* banner */ char *inputName; /* name of input file */ int numberPages; /* hint of length */ int numberCopies; /* number of copies wanted */ int writeFlag; /* write when done */ int mailFlag; /* mail when done */ { /* * Use the ipr spooler to send fileName to an ImPress printer. * Use banner as the tag for the spooler, or inputName if banner is null. * Note that this routine execs, so it should normally never return. */ char *tag; char pages[20], copies[20]; char *args[20]; int count = 0; if (banner) tag = banner; else if (inputName) tag = inputName; else tag = "stdin"; args[count++] = "ipr"; if (debug) args[count++] = "-d"; args[count++] = "-Limpress"; args[count++] = "-Djobheader on"; args[count++] = "-r"; args[count++] = "-t"; args[count++] = tag; if (numberPages>0) { sprintf( pages, "-p%d", numberPages ); args[count++] = pages; } if (numberCopies>0) { sprintf( copies, "-c%d", numberCopies ); args[count++] = copies; } if (mailFlag) args[count++] = "-m"; if (writeFlag) args[count++] = "-n"; args[count++] = fileName; args[count++] = NULL; if (debug) { int i; printf( "Command line: " ); for (i=0; i<count; i++) printf( " %s", args[i] ); putchar( '\n' ); fflush(stdout); } execv( COMMAND, args ); fperror("Couldn't execute ipr. ImPress file in %s",fileName); } SHAR_EOF fi # end of overwriting check if test -f 'iptex.1' then echo shar: will not over-write existing file "'iptex.1'" else cat << \SHAR_EOF > 'iptex.1' .ds TX T\h'-.1667m'\v'.22m'E\h'-.125m'\v'-.22m'X .TH IPTEX 1 TRW(9/7/84) .SH NAME iptex \- spool TeX output for Imagen printing .SH SYNOPSIS .B iptex [ flags ] dvi-file .SH DESCRIPTION .I iptex is used to convert \*(TX device-independent (DVI) output files into the appropriate format for the Imagen ImPrint-10 Laser Printer. Only one file can be processed at a time. If the named file cannot be found, then .IB filename .dvi is tried. The output is placed in a file in /tmp which is then spooled by the .IR ipr (1) program. .SS Options .TP \-L Print in landscape mode. Since this involves rotating the bitmaps for each different character and font in the input, this can be quite time-consuming. .TP \-U Uncentered output. Normally, .I iptex will add enough margin to center the page image in the middle of the physical page. This option causes the page image to be flush with the upper left corner of the page. .TP \-I One inch margins. Starts the output one inch from the top and left edges of the physical page. This is a \*(TX standard positioning. Note that you should specify at most one of the \-U and \-I options and that when neither is specified, the output is centered. If both \-U and \-I are specified, the \-I option will take precedence. .TP \-v Verbose output; the Imprint-10 output is listed on standard output in symbolic form, but nothing is queued. .TP \-s .I ipr is not called, and the Impress output is written to standard output. .TP \-c\fIn\fR Requests than .I n copies be produced. Default is one copy. .TP \-d Causes debugging information to be produced. .TP \-D Causes even more debugging information, including dumping the glyphs in each font in a readable format. .SH DIAGNOSTICS .B "scale=\fIn\fB design=\fIm\fR" .br .B "Can't find font:\fI font\fR" .br ...occurs when the bitmap for a font with a particular magnification isn't there. .sp Most (self explanatory) diagnostics start with "dvi-imagen:" for historical reasons, and usually refer to a particularly incomprehensible dvi file. .SH FILES The bitmap for font amr10, scaled at 1:1 (\*(TX's .BR "\escaled 1000" ) will be found in the file /usr/lib/tex/fonts/amr10.1200pxl. 1200 is the basic raster size for the (240 dot/inch) Imagen. If .B "amr10 scaled 1200" is used to create 12-point Roman, the font will be amr10.1440pxl, and so on. .sp /tmp/dviXXXXX\ \ Temporary (output) file. .SH SEE ALSO tex82(1),ipr(1) .br \*(TXware documentation for formats of DVI and TFM files. .SH BUGS The \*(TX fonts and the fonts distributed by Imagen aren't the same. This is a minor annoyance that takes up a lot of disk space unnecessarily. SHAR_EOF fi # end of overwriting check if test -f 'ipr.h' then echo shar: will not over-write existing file "'ipr.h'" else cat << \SHAR_EOF > 'ipr.h' /* * ipr.h -- ImPress printer spooler definitions * * by Bill Nowicki September 29, 1981 * at Stanford University for Imagen Corporation */ # define SPOOLDIR "/usr/spool/ipd" /* the spooling directory */ # define LOCK "/usr/spool/ipd/lock" /* the lock file */ # define LOG "/tmp/implog" /* the error log file */ # define DAEMON "/usr/local/lib/imagen/ipd" /* the unqueuing daemon */ # define PRINTING "/usr/local/lib/imagen/ips" /* the printing program */ # define COMMAND "/usr/local/bin/ipr" /* the command for enqueing */ # define WRITE "/usr/local/lib/imagen/dwrite" /* write to a user */ # define HUMAN "ImPress printer Daemon" /* Human understandable name */ # define KIND "ImPrint" /* kind of printer we use */ # define LOCKTIMEOUT 5*60 /* seconds for the lock timeout */ # define LineSize 128 /* size of a data line */ # include <sys/types.h> # include <dir.h> # include <stat.h> # include <signal.h> # include <stdio.h> # include "c.h" # define bool int /* * I am not sure if the following is documented anywhere, so * I thought I would include it here so nonone else has to go through * what I did to discover how the standard spooling stuff works. * I also added a few of my own codes, which should not conflict * with anything. * * Basically there are files in the spool directory of the form: * dfXXXXXa (where XXXXX is the pid), that have lines with a one * character code followed by informational lines: * B treated like F in ipq.c * C number of copies to print * F File name to print * L User's name responsible for printing * M Mail address to inform when printing is complete * N User to notify when printing is complete * P Pages in body (total) * R "Real" user name for cover sheet * T "Tag" to identify this job, usually the file name * U File to unlink after finishing */ extern int debug; /* for extra debugging messages */ int Copies; /* number of copies to print */ int Pages; /* number of pages (approx) */ SHAR_EOF fi # end of overwriting check if test -f 'impress.h' then echo shar: will not over-write existing file "'impress.h'" else cat << \SHAR_EOF > 'impress.h' /* * impress.h * * header file for finding data bases having to do with the imprint printer * by Bill Nowicki, Stanford University, September 1981 */ # define PixelsPerInch 240 /* Resolution of the printer being used */ /* * size of printable area, 8x10.5 inches */ # define PixelsPageHeight ( (int)( PixelsPerInch*10.5 ) ) # define PixelsPageWidth ( PixelsPerInch*8 ) /* * memory parameters */ # define K 1024 # define GlyphSize (164*K) /* size of printer's Glyph buffer */ # define InputSize (24*K) /* size of printer's input buffer */ # define GlyphsPerPage (10*K) /* number of distinct glyphs per page */ SHAR_EOF fi # end of overwriting check if test -f 'imPcodes.h' then echo shar: will not over-write existing file "'imPcodes.h'" else cat << \SHAR_EOF > 'imPcodes.h' /* command codes */ #define ASP0 128 #define ASP1 129 #define AM 130 #define AMP 131 #define AMM 132 #define ASABSH 135 /* Absolute horizontal */ #define ASABSV 137 /* Absolute vertical */ #define ASRULE 192 #define ABRULE 193 #define AS 194 /* not implemented yet */ #define AH 195 #define AV 196 #define AN 197 #define ASGLY 198 #define ABGLY 199 #define ADELG 200 #define ADELC 201 #define ADELF 202 #define AFONT 203 #define APAGOR 204 #define AMS 205 #define AROTMS 206 #define AF 207 #define ABSKIP 208 #define AMARGIN 209 #define ASETSP 210 #define APUSH 211 #define APOP 212 #define APAGE 213 #define AEND 219 #define ACREFAM 221 #define ANOP 254 #define AEOF 255 SHAR_EOF fi # end of overwriting check if test -f 'font.h' then echo shar: will not over-write existing file "'font.h'" else cat << \SHAR_EOF > 'font.h' /* * font.h - some definitions for the font manipulation routines * **CHANGED at Cornell for the dvi-imagen program ** * * Note that our terminology is slightly different from that of Knuth * and Parc. Since TROFF assumes that fonts are scalable, we must * use a single Knuth font (which we call a family, similar to a Parc face), * at different magnifications (which is what we call a "font"). */ /* * the layout of a font information block * There is one of these for every loaded "font", or * magnification thereof in Knuthian terms. * * Also note the strange units. The design size is in 1/2^20 point * units (also called micro-points), and the individual character widths * are in the TFM file in 1/2^20 ems units, i.e. relative to the design size. */ # define TwoToTheTwenty (1024*1024) # define MAXCHARS 256 /* make 128 for 7 bit characters */ enum CharStatus {NotThere, Ready, Loaded, Wanted, Kept, InProm}; struct font { struct font * next; /* link to next font info block */ int Inumber; /* font number (on Imagen) */ int TeXnumber; /* font number (in DVI file) */ int scale; /* scaled size in DVI units */ int design; /* design size in DVI units */ unsigned char bc; /* beginning char defined */ unsigned char ec; /* ending char defined */ enum CharStatus state[ MAXCHARS ]; /* loaded, existant, or in Prom?? */ /* following are in pixels */ short H[ MAXCHARS ]; /* height for each glyph raster */ short W[ MAXCHARS ]; /* width for each glyph raster */ short Y[ MAXCHARS ]; /* Y-offset for each glyph raster */ short X[ MAXCHARS ]; /* X-offset for each glyph raster */ short pxl_adv[ MAXCHARS ]; /* pixels to move reference point */ long dvi_adv[ MAXCHARS ]; /* DVI units to move reference point */ char *Glyph[ MAXCHARS ]; /* pointers to actual glyph bitmaps */ char fontname[100]; }; extern struct font *fontListHead; /* head of linked list of font structures */ int debug; /* true for debugging information */ SHAR_EOF fi # end of overwriting check if test -f 'error.c' then echo shar: will not over-write existing file "'error.c'" else cat << \SHAR_EOF > 'error.c' /********************************************************************* function: error description: Error message routines programmer: Alan S. Watt history: 11/04/81 original version 07/17/82 fixes for lint 08/10/82 modest cleanup before posting. *********************************************************************/ #ifndef lint static char Sccsid[] = "@(#)error.c 1.1"; #endif !lint #include <stdio.h> #define NOTOK (-1) /* VARARGS1 */ error (mesg, args) char *mesg; { _doprnt (mesg, &args, stderr); putc ('\n', stderr); exit (NOTOK); } extern errno; extern sys_nerr; extern char *sys_errlist[]; #ifdef lint int errno; int sys_nerr; char *sys_errlist[1]; #endif lint static char ehuh[] = "Unknown System Error"; /* VARARGS1 */ fperror (mesg, args) char *mesg; { char *err = ((unsigned)errno >= sys_nerr ? ehuh : sys_errlist[errno]); _doprnt (mesg, &args, stderr); fprintf (stderr, ": %s\n", err); exit (NOTOK); } /*VARARGS1*/ remark (mesg, args) char *mesg; { _doprnt (mesg, &args, stderr); putc ('\n',stderr); } /*VARARGS1*/ fpremark (mesg, args) char *mesg; { char *err = ((unsigned)errno >= sys_nerr ? ehuh : sys_errlist[errno]); _doprnt (mesg, &args, stderr); fprintf (stderr, ":%s\n", err); } SHAR_EOF fi # end of overwriting check if test -f 'dvi.h' then echo shar: will not over-write existing file "'dvi.h'" else cat << \SHAR_EOF > 'dvi.h' #define SETCHAR0 0 #define SET1 128 #define SETRULE 132 #define PUT1 133 #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 */ SHAR_EOF fi # end of overwriting check if test -f 'c.h' then echo shar: will not over-write existing file "'c.h'" else cat << \SHAR_EOF > 'c.h' /* * Standard C macros * ********************************************************************** * HISTORY * 23-Apr-81 Mike Accetta (mja) at Carnegie-Mellon University * Added "sizeofS" and "sizeofA" macros which expand to the size * of a string constant and array respectively. * ********************************************************************** */ #define ABS(x) ((x) >= 0 ? (x):-(x)) #define MAX(a,b) ((a) > (b) ? (a):(b)) #define MIN(a,b) ((a) < (b) ? (a):(b)) #define FALSE 0 #define TRUE 1 #define CERROR (-1) #define sizeofS(string) (sizeof(string) - 1) #define sizeofA(array) (sizeof(array)/sizeof(array[0])) SHAR_EOF fi # end of overwriting check if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else cat << \SHAR_EOF > 'Makefile' CFLAGS= -O dvi-imagen: dvi-imagen.o output.o error.o rotate.o special.o cc -o dvi-imagen dvi-imagen.o output.o error.o rotate.o special.o -lcurses clean: rm -f *.o SHAR_EOF fi # end of overwriting check if test -f 'dvi-imagen.c' then echo shar: will not over-write existing file "'dvi-imagen.c'" else cat << \SHAR_EOF > 'dvi-imagen.c' /* ** dvi-imagen.c Imagen driver for DVI format 2 ** ** Syntax: ** dvi-imagen [options] <dvi-file> ** ** Description: ** Translates the DVI commands in the <dvi-file> into commands ** for the Imagen ImPrint-10 Laser Printer. These are placed ** into a /tmp file which is then handed to the ipr(1) program. ** ** The -L option takes a shot at Landscape mode. ** The -U option disables centering ** The -I option provides one-inch margins ** The -v option makes the output be in decoded (verbose) form ** -v implies -s ** The -s option makes dvi-imagen refrain from calling ipr(1), ** with Impress output on stdout. ** The -cX option requests X copies (default 1) ** The -d option makes dvi-imagen produce debugging information. ** The -D option gets everything -d does and more, including ** dumping out the glyphs in each font in a readable format. */ #include <stdio.h> #include <unctrl.h> #include <pwd.h> #include "dvi.h" #include "font.h" #define MAXFONTS 64 /* Due to 6-bit field in Imagen codes */ /* I may fix this in the next version */ #define PIXELS_PER_INCH 240 #define HARD_XPAGE_OFFSET 160 /* Damn it */ #define PIXELS_PER_LINE (8 * PIXELS_PER_INCH - HARD_XPAGE_OFFSET) /* 8 inches of printing area */ #define PIXELS_PER_PAGE (11 * PIXELS_PER_INCH) /* 11 inches of printing area */ #define FONT_DIRECTORY "/usr/lib/tex/fonts" #define pixel_round(x) ((long) (conv * (double) (x) + 0.5)) #define dvi_round(x) ((long) ((double) (x) / conv + 0.5)) #define one(fp) num (fp, 1) #define sone(fp) snum(fp, 1) #define two(fp) num (fp, 2) #define four(fp) num (fp, 4) #define sfour(fp) snum(fp, 4) typedef unsigned char ubyte; struct frame { long pxl_h, dvi_h, pxl_v, dvi_v, w, x, y, z; }; struct frame *stack; int stackp; extern int landscape; int debug = 0; int verbose = 0; int spoolit = 1; int landscape = 0; int center = 1; int inchmargin = 0; int numcopies = 1; struct font *fontListHead = NULL; char job_id[300]; char InputName[300]; int total_pages, maxstack, Xpage_offset, Ypage_offset; int fontnum = 0; double conv; long numerator, denominator, magnification; char *output_file_name; char *Usage_str = "Usage: iptex [-U] [-I] [-L] [-v] [-s] [-d] <dvi-file>"; long read_postamble(); unsigned long num(); long snum(); char *malloc(); char *mktemp(); main(argc, argv) int argc; char *argv[]; { FILE *fp; long last_page; /* file offset of last page of output */ int nc; while (argv[1][0] == '-') { switch (argv[1][1]) { case 'c': if ((nc=atoi(&argv[1][2])) > 0) numcopies=nc; break; case 's': spoolit = 0; break; case 'd': debug = 1; break; case 'D': debug = 2; break; case 'v': verbose = 1; spoolit = 0; break; case 'L': landscape = 1; break; case 'U': center = 0; break; case 'I': inchmargin = 1; break; default: error(Usage_str); } argv++; argc--; } if (argc != 2) error(Usage_str); if ((fp = fopen(argv[1], "r")) == NULL) { char longername[256]; strcpy (longername, argv[1]); strcat (longername, ".dvi"); if ((fp = fopen (longername, "r")) == NULL) error("dvi-imagen: Can't open %s", argv[1]); } strcpy (InputName, argv[1]); process_preamble(fp); find_postamble(fp); last_page = read_postamble(fp); start_output(); do_pages(fp, last_page); finish_output(); } \f /* ** process_preamble(fp) ** ** fp is a FILE pointer for a DVI file which is positioned at the ** beginning. ** ** process_preamble reads the information in the preamble and stores ** it into global variables for later use. */ process_preamble(fp) FILE *fp; { ubyte k; double fraction; if (one(fp) != PRE) error("dvi-imagen: DVI file doesn't start with preamble"); if (one(fp) != 2) error("dvi-imagen: Wrong version of DVI output for this program"); numerator = four(fp); denominator = four(fp); magnification = four(fp); fraction = (((double) numerator * magnification) / ((double) denominator * 1000.)); conv = ((fraction / 100000) / 2.54) * PIXELS_PER_INCH; k = one(fp); fread(job_id, sizeof(char), k, fp); job_id[k] = '\0'; } \f /* ** find_postamble(fp) ** ** fp is a FILE pointer for a DVI-format file. find_postamble locates ** the beginning of the postamble and leaves the file ready to start ** reading at that location. */ find_postamble(fp) FILE *fp; { ubyte byte; long offset = -4; /* At least 4 TRAILERS */ do { offset--; fseek(fp, offset, 2); byte = one(fp); } while(byte == TRAILER); if (byte != 2) error("dvi-imagen: Wrong version of DVI output for this program"); offset -= 4; fseek(fp, offset, 2); fseek(fp, four(fp), 0); } \f /* ** long ** read_postamble(fp) ** ** fp is a FILE pointer for a DVI-format file. read_postamble reads the ** information in the postamble, storing it into global variables. ** It also takes care of reading in all of the PXL files for the fonts ** used in the job. ** ** read_postamble returns the file offset of the beginning of the last ** page of DVI output. */ long read_postamble(fp) FILE *fp; { long last_page; long tallest, widest; ubyte cmnd; if (one(fp) != POST) error("dvi-imagen: Postamble doesn't begin with POST"); last_page = four(fp); if (numerator != four(fp) || denominator != four(fp) || magnification != four(fp)) error("dvi-imagen: Postamble doesn't match preamble"); tallest = four(fp); if (!landscape) { Ypage_offset = (PIXELS_PER_PAGE - pixel_round(tallest)) / 2; widest = four(fp); Xpage_offset = (PIXELS_PER_LINE - pixel_round(widest)) / 2 + HARD_XPAGE_OFFSET; } else { Ypage_offset = (PIXELS_PER_LINE - pixel_round(tallest))/2 + HARD_XPAGE_OFFSET; widest = four(fp); Xpage_offset = (PIXELS_PER_PAGE - pixel_round(widest))/2; } if (!center) Ypage_offset = Xpage_offset = 0; if (inchmargin) Ypage_offset = Xpage_offset = PIXELS_PER_INCH; maxstack = two(fp); total_pages = two(fp); if (debug) remark("tall, wide, po, stk, pages = %d, %d, %d, %d, %d", tallest, widest, Xpage_offset, maxstack, total_pages); do { switch(cmnd = one(fp)) { case FNTDEF1: case FNTDEF2: case FNTDEF3: case FNTDEF4: define_font(fp, cmnd); break; case POSTPOST: break; default: error("dvi-imagen: Non-fntdef cmnd found in postamble"); } } while (cmnd != POSTPOST); return (last_page); } \f /* ** define_font(fp, cmnd) ** ** fp is a FILE pointer for a DVI file which is positioned right after ** a fntdef command. The opcode for the command is in cmnd. ** ** define_font reads the rest of the fntdef command and then reads in ** the specified PXL file, adding it to the global linked-list holding ** all of the fonts used in the job. */ define_font(fp, cmnd) FILE *fp; ubyte cmnd; { struct font *fontp; long checksum; int len; char fontname[513]; if (fontnum >= MAXFONTS) error("dvi-imagen: Too many fonts. Maximum is %d", MAXFONTS); fontp = (struct font *) malloc( sizeof(struct font) ); if (fontp == NULL) error("dvi-imagen: Out of memory while reading font %d", fontnum); fontp->next = fontListHead; fontListHead = fontp; fontp->TeXnumber = num(fp, cmnd - FNTDEF1 + 1); fontp->Inumber = fontnum++; checksum = four(fp); fontp->scale = four(fp); fontp->design = four(fp); len = one(fp) + one(fp); fread(fontname, sizeof(char), len, fp); fontname[len] = '\0'; strcpy(fontp->fontname, fontname); read_pxl_file(fontp, fontname); if (debug > 1) dump_font(fontp, fontname); } \f /* ** read_pxl_file(fontp, fontname) ** ** fontp points to a (struct font) which has been partially initialised ** with the information in the DVI-file FNTDEF command. fontname is the ** name of a font. ** ** read_pxl_file constructs the expected name of the font's PXL file ** from the info in *fontp and fontname. It then reads the glyph ** bitmaps into memory. ** ** Note: the 'size' of a font (i.e. the 1200 in 'cmr10.1200pxl') is ** given by the following formula (rounded): ** ** scaled-size PIXELS_PER_INCH ** ----------- * --------------- * 1000 ** design-size 200 ** ** In the actual implementation, scaled-size/design-size hasn't been ** stored with sufficient precision, hence the messing around to find ** its actual value. */ char *rotate(); read_pxl_file(fontp, fontname) struct font *fontp; char *fontname; { char filename[1025]; FILE *pxlfp; int unmodsize; float realsize; int size; long checksum, magnify, design_size, font_dir_ptr, pxl_id_word; long glyph_ptr[128]; /* Seek locations of each glyph */ int i, j, k; realsize = (magnification/1000.)*((float) fontp->scale / fontp->design); unmodsize = (realsize * 1000) + 0.5; /* a real hack to correct for rounding in some cases -- rkf */ if(unmodsize==1095) realsize = 1.095445; /* stephalf */ else if(unmodsize==1315) realsize=1.314534; /* stepihalf */ else if(unmodsize==2074) realsize=2.0736; /* stepiv */ else if(unmodsize==2488) realsize=2.48832; /* stepv */ else if(unmodsize==2986) realsize=2.985984; /* stepiv */ /* the remaining magnification steps are represented with sufficient accuracy already */ size = (realsize * PIXELS_PER_INCH * 5) + 0.5; sprintf(filename, "%s.%dpxl", fontname, size); if ((pxlfp = fopen(filename, "r")) == NULL) { sprintf(filename, "%s/%s.%dpxl", FONT_DIRECTORY, fontname, size); if ((pxlfp = fopen(filename, "r")) == NULL) { remark("scale = %d, design = %d",fontp->scale, fontp->design); fperror("Can't find font: \"%s\"", filename); } } fseek(pxlfp, - (5 * 4L), 2); /* Seek to trailer info */ checksum = four(pxlfp); magnify = four(pxlfp); design_size = four(pxlfp); font_dir_ptr = four(pxlfp) * 4; pxl_id_word = four(pxlfp); fseek(pxlfp, font_dir_ptr, 0); /* Seek to font directory */ fontp->bc = 0; fontp->ec = 127; for (i=0; i < 128; i++) { fontp->state[i] = Ready; fontp->W[i] = two(pxlfp); fontp->H[i] = two(pxlfp); fontp->X[i] = two(pxlfp); fontp->Y[i] = two(pxlfp); glyph_ptr[i] = four(pxlfp) * 4; /* ** The TFM-width word is kind of funny in the units ** it is expressed in. It works this way: ** ** If a glyph has width 'w' in a font with design-size ** 'd' (both in same units), the TFM-width word is ** ** (w/d) * 2^20 ** ** Therefore, in order to find the glyph width in ** DVI units (1 / 2^16 points), we take the design-size ** 'd' (in DVI's), the magnification 'm' of the PXL file ** and the TFM-width word 't' to the width (in DVI's) ** as follows: ** ** dmt ** w = ----- ** 2^20 ** ** But the magnification of the PXL file is just the ** scaled size 's' over the design size, so the final ** expression for the width is ** ** st ** w = ---- ** 2^20 ** */ #ifndef UNDEFINED fontp->dvi_adv[i] = ((double) fontp->scale * four(pxlfp)) / (1 << 20); #else fontp->dvi_adv[i] = ((double) fontp->design * four(pxlfp)) / (1 << 20); #endif fontp->pxl_adv[i] = pixel_round(fontp->dvi_adv[i]); } for (i=0; i < 128; i++) { int real_bytes_wide = (fontp->W[i] + 7) / 8; int file_bytes_wide = ((fontp->W[i] + 31) / 32) * 4; char *ptr; char junk; ptr = fontp->Glyph[i] = malloc(fontp->H[i] * real_bytes_wide); if (ptr == NULL) error("Out of memory while reading character %d of font %s\n", i, fontname); fseek(pxlfp, glyph_ptr[i], 0); for (j=0; j < fontp->H[i]; j++) { for (k=0; k < file_bytes_wide; k++) { if (k < real_bytes_wide) *(ptr++) = one(pxlfp); else junk = one(pxlfp); } } if (landscape) { char *holdglyph; int width,height,x,y; holdglyph = fontp->Glyph[i]; fontp->Glyph[i] = rotate(holdglyph, fontp->H[i], fontp->W[i]); /* free(holdglyph); */ width = fontp->W[i]; height=fontp->H[i]; x = fontp->X[i]; y=fontp->Y[i]; fontp->W[i] = height; fontp->H[i] = width; fontp->X[i] = height-y; fontp->Y[i] = x; } } fclose(pxlfp); } \f /* ** start_output() ** ** Arrange for the stuff at the beginning of the output to the Imagen ** to be sent out, including the jobid, etc. ** */ start_output() { char *buffer[50]; struct passwd *pwbuf, *getpwuid(); pwbuf = getpwuid(getuid()); sprintf(buffer, " (%s [%d pages])", pwbuf->pw_name, total_pages); strcat(job_id, buffer); if (spoolit) { output_file_name = mktemp("/tmp/dviXXXXXX"); ImPressStart(output_file_name, job_id, verbose); } else ImPressStart((char *)0, job_id, verbose); } \f /* ** do_pages(fp, last_page) ** ** Process the pages in the FILE fp. last_pages is the offset of the ** last page. (We do the pages in reverse order, of course.) ** */ #define PXL_H stack[stackp].pxl_h #define PXL_V stack[stackp].pxl_v #define DVI_H stack[stackp].dvi_h #define DVI_V stack[stackp].dvi_v #define WW stack[stackp].w #define XX stack[stackp].x #define YY stack[stackp].y #define ZZ stack[stackp].z #define nope(str) error("Can't hack %s", str) #define correct() diff = PXL_H - pixel_round(DVI_H); \ if (diff < 0) \ { \ while (diff++) \ ImPressMplus(); \ } \ else if (diff > 0) \ { \ while (diff--) \ ImPressMminus(); \ } \ PXL_H = pixel_round(DVI_H); do_pages(fp, last_page) FILE *fp; long last_page; { char input_left = 1; long next_page; struct font *curr_font; int diff; struct font *ptr; ubyte ch; stack = (struct frame *) malloc( sizeof(struct frame) * (maxstack+1)); if (stack == NULL) error("Can't allocate stack space."); fseek(fp, last_page, 0); while (input_left) { ch = one(fp); if (ch <= SETCHAR0 + 127) { ImPressCharacter(ch); DVI_H += curr_font->dvi_adv[ch]; PXL_H += curr_font->pxl_adv[ch]; correct(); } else if (FNTNUM0 <= ch && ch <= FNTNUM0 + 63) { for (ptr = fontListHead; ptr != NULL; ptr = ptr->next) if (ptr->TeXnumber == ch - FNTNUM0) break; if (ptr == NULL) error("FNTNUM to non-existant font #%d", ch - FNTNUM0); curr_font = ptr; ImPressFont(ptr); } else { long a, b; switch (ch) { case SET1: nope("SET1"); break; case SETRULE: a = sfour(fp); b = sfour(fp); if (a > 0 && b > 0) { correct(); ImPressRule(pixel_round(b), pixel_round(a)); } DVI_H += b; diff = pixel_round(DVI_H); ImPressMove(diff - PXL_H); PXL_H = diff; break; case PUT1: nope("PUT1"); break; case PUTRULE: a = sfour(fp); b = sfour(fp); if (a > 0 && b > 0) { correct(); ImPressRule(pixel_round(b), pixel_round(a)); } break; case NOP: break; case BOP: a = four(fp); if (debug) remark("Beginning page %d", a); for (a=0; a < 9; a++) four(fp); next_page = sfour(fp); stackp = 0; DVI_H = dvi_round(Xpage_offset); PXL_H = Xpage_offset; DVI_V = dvi_round(Ypage_offset); PXL_V = Ypage_offset; WW = XX = YY = ZZ = 0; curr_font = NULL; ImPressBeginPage(); ImPressSetX(PXL_H); break; case EOP: ImPressEndPage(); if (stackp > 0) remark("Stack not empty at EOP; stackp = %d", stackp); if (next_page < 0) input_left = 0; else fseek(fp, next_page, 0); break; case PUSH: stackp++; if (stackp > maxstack) error("More PUSHes than were promised"); stack[stackp] = stack[stackp - 1]; break; case POP: stackp--; if (stackp < 0) error("More POPs than PUSHes"); ImPressSetX(PXL_H); ImPressSetY(PXL_V); break; case RIGHT1: case RIGHT2: case RIGHT3: case RIGHT4: DVI_H += snum(fp, ch - RIGHT1 + 1); diff = pixel_round(DVI_H); ImPressMove(diff - PXL_H); PXL_H = diff; break; case X0: case X1: case X2: case X3: case X4: if (ch != X0) { XX = snum(fp, ch - X0); ImPressSetSpace(pixel_round(XX)); } ImPressSpace(); DVI_H += XX; PXL_H += pixel_round(XX); correct(); break; case W0: case W1: case W2: case W3: case W4: if (ch != W0) WW = snum(fp, ch - W0); DVI_H += WW; diff = pixel_round(DVI_H); ImPressMove(diff - PXL_H); PXL_H = diff; break; case Y0: case Y1: case Y2: case Y3: case Y4: if (ch != Y0) YY = snum(fp, ch - Y0); DVI_V += YY; PXL_V = pixel_round(DVI_V); ImPressSetY(PXL_V); break; case Z0: case Z1: case Z2: case Z3: case Z4: if (ch != Z0) ZZ = snum(fp, ch - Z0); DVI_V += ZZ; PXL_V = pixel_round(DVI_V); ImPressSetY(PXL_V); break; case DOWN1: case DOWN2: case DOWN3: case DOWN4: DVI_V += snum(fp, ch - DOWN1 + 1); PXL_V = pixel_round(DVI_V); ImPressSetY(PXL_V); break; case FNT1: case FNT2: case FNT3: case FNT4: a = num(fp, ch - FNT1 + 1); for (ptr = fontListHead; ptr != NULL; ptr = ptr->next) if (ptr->TeXnumber == a) break; if (ptr == NULL) error("FNT to non-existant font #%d", a); curr_font = ptr; ImPressFont(ptr); break; case XXX1: case XXX2: case XXX3: case XXX4: /*nope("XXXX");*/ a = num(fp, ch-XXX1+1); if(a > 0) DoSpecial (a, fp); break; case FNTDEF1: case FNTDEF2: case FNTDEF3: case FNTDEF4: fseek(fp, 12 + ch - FNTDEF1 + 1, 1); a = one(fp) + one(fp); fseek(fp, a, 1); break; case PRE: error("Can't Happen: PRE encountered."); break; case POST: error("Can't Happen: POST encountered."); break; case POSTPOST: error("Can't Happen: POSTPOST encountered."); break; default: error("Unknown Op-code: %d; Offset: %d", ch, ftell(fp)); } /* end switch*/ } /* end else (ch not a SETCHAR or FNTNUM) */ } /* end while */ } \f /* ** finish_output() ** ** Wrap it up. This routine does not return, since ImPressSendIt() ** doesn't. ** */ finish_output() { ImPressFinish(); if (! spoolit) exit(0); ImPressSendIt(output_file_name, NULL, InputName, total_pages, numcopies, 0, 0); } \f /* ** num(fp, size) snum(fp, size) ** ** Read size bytes from the FILE fp, constructing them into a ** signed/unsigned integer. ** */ unsigned long num(fp, size) FILE *fp; int size; { int i; long x; x = 0; for (i=0; i < size; i++) { x = x * 256 + (unsigned) fgetc(fp); } return(x); } long snum(fp, size) FILE *fp; int size; { int i; long x; x = fgetc(fp) & 0377; if (x & 0200) x -= 256; for (i=1; i < size; i++) { x = x * 256 + (unsigned) fgetc(fp); } return(x); } \f /* ** dump_font(fontp, fontname) ** ** Debugging routine which prints a representation of the information ** read from a PXL file into a 'struct font'. ** */ dump_font(fontp, fontname) struct font *fontp; char *fontname; { int i, j, k, l; printf("\n+++++DUMP OF FONT \"%s\": ", fontname); printf("TeXnumber, Inumber, scale, design = %d, %d, %d, %d\n", fontp->TeXnumber, fontp->Inumber, fontp->scale, fontp->design); printf("\tfontp = %o\n", fontp); for (i=0; i < 128; i++) { char *ptr; printf("\nCharacter %d (%s): ", i, unctrl(i)); printf("H, W, X, Y = %d, %d, %d, %d\n", fontp->H[i], fontp->W[i], fontp->X[i], fontp->Y[i]); printf("\t\tdvi_adv, pxl_adv = %d, %d\n\n", fontp->dvi_adv[i], fontp->pxl_adv[i]); ptr = fontp->Glyph[i]; for (j=0; j < fontp->H[i]; j++) { for (k=0; k < (fontp->W[i] + 7) / 8; k++) { for (l=7; l >= 0; l--) { if (*ptr & (1 << l)) putchar('@'); else putchar(' '); } ptr++; } putchar('\n'); } } } SHAR_EOF fi # end of overwriting check if test -f 'CROSS-REFERENCES' then echo shar: will not over-write existing file "'CROSS-REFERENCES'" else cat << \SHAR_EOF > 'CROSS-REFERENCES' Imagen owners may also be interested in the programs found in ./tex82/=utils/salkind. 8/300 owners may prefer to look at the files in ../imagen300 SHAR_EOF fi # end of overwriting check if test -f 'dvi-imagen.c_o' then echo shar: will not over-write existing file "'dvi-imagen.c_o'" else cat << \SHAR_EOF > 'dvi-imagen.c_o' /* ** dvi-imagen.c Imagen driver for DVI format 2 ** ** Syntax: ** dvi-imagen [options] <dvi-file> ** ** Description: ** Translates the DVI commands in the <dvi-file> into commands ** for the Imagen ImPrint-10 Laser Printer. These are placed ** into a /tmp file which is then handed to the ipr(1) program. ** ** The -L option takes a shot at Landscape mode. ** The -U option disables centering ** The -v option makes the output be in decoded (verbose) form ** -v implies -s ** The -s option makes dvi-imagen refrain from calling ipr(1), ** with Impress output on stdout. ** The -cX option requests X copies (default 1) ** The -d option makes dvi-imagen produce debugging information. ** The -D option gets everything -d does and more, including ** dumping out the glyphs in each font in a readable format. */ #include <stdio.h> #include <unctrl.h> #include <pwd.h> #include "dvi.h" #include "font.h" #define MAXFONTS 64 /* Due to 6-bit field in Imagen codes */ /* I may fix this in the next version */ #define PIXELS_PER_INCH 240 #define HARD_XPAGE_OFFSET 160 /* Damn it */ #define PIXELS_PER_LINE (8 * 240 - HARD_XPAGE_OFFSET) /* 8 inches of printing area */ #define PIXELS_PER_PAGE (11 * 240) /* 11 inches of printing area */ #define FONT_DIRECTORY "/usr/lib/tex/fonts" #define pixel_round(x) ((long) (conv * (double) (x) + 0.5)) #define dvi_round(x) ((long) ((double) (x) / conv + 0.5)) #define one(fp) num (fp, 1) #define sone(fp) snum(fp, 1) #define two(fp) num (fp, 2) #define four(fp) num (fp, 4) #define sfour(fp) snum(fp, 4) typedef unsigned char ubyte; struct frame { long pxl_h, dvi_h, pxl_v, dvi_v, w, x, y, z; }; struct frame *stack; int stackp; extern int landscape; int debug = 0; int verbose = 0; int spoolit = 1; int landscape = 0; int center = 1; int numcopies = 1; struct font *fontListHead = NULL; char job_id[300]; char InputName[300]; int total_pages, maxstack, Xpage_offset, Ypage_offset; int fontnum = 0; double conv; long numerator, denominator, magnification; char *output_file_name; char *Usage_str = "Usage: iptex [-U] [-L] [-v] [-s] [-d] <dvi-file>"; long read_postamble(); unsigned long num(); long snum(); char *malloc(); char *mktemp(); main(argc, argv) int argc; char *argv[]; { FILE *fp; long last_page; /* file offset of last page of output */ int nc; while (argv[1][0] == '-') { switch (argv[1][1]) { case 'c': if ((nc=atoi(&argv[1][2])) > 0) numcopies=nc; break; case 's': spoolit = 0; break; case 'd': debug = 1; break; case 'D': debug = 2; break; case 'v': verbose = 1; spoolit = 0; break; case 'L': landscape = 1; break; case 'U': center = 0; break; default: error(Usage_str); } argv++; argc--; } if (argc != 2) error(Usage_str); if ((fp = fopen(argv[1], "r")) == NULL) { char longername[256]; strcpy (longername, argv[1]); strcat (longername, ".dvi"); if ((fp = fopen (longername, "r")) == NULL) error("dvi-imagen: Can't open %s", argv[1]); } strcpy (InputName, argv[1]); process_preamble(fp); find_postamble(fp); last_page = read_postamble(fp); start_output(); do_pages(fp, last_page); finish_output(); } \f /* ** process_preamble(fp) ** ** fp is a FILE pointer for a DVI file which is positioned at the ** beginning. ** ** process_preamble reads the information in the preamble and stores ** it into global variables for later use. */ process_preamble(fp) FILE *fp; { ubyte k; double fraction; if (one(fp) != PRE) error("dvi-imagen: DVI file doesn't start with preamble"); if (one(fp) != 2) error("dvi-imagen: Wrong version of DVI output for this program"); numerator = four(fp); denominator = four(fp); magnification = four(fp); fraction = (((double) numerator * magnification) / ((double) denominator * 1000.)); conv = ((fraction / 100000) / 2.54) * PIXELS_PER_INCH; k = one(fp); fread(job_id, sizeof(char), k, fp); job_id[k] = '\0'; } \f /* ** find_postamble(fp) ** ** fp is a FILE pointer for a DVI-format file. find_postamble locates ** the beginning of the postamble and leaves the file ready to start ** reading at that location. */ find_postamble(fp) FILE *fp; { ubyte byte; long offset = -4; /* At least 4 TRAILERS */ do { offset--; fseek(fp, offset, 2); byte = one(fp); } while(byte == TRAILER); if (byte != 2) error("dvi-imagen: Wrong version of DVI output for this program"); offset -= 4; fseek(fp, offset, 2); fseek(fp, four(fp), 0); } \f /* ** long ** read_postamble(fp) ** ** fp is a FILE pointer for a DVI-format file. read_postamble reads the ** information in the postamble, storing it into global variables. ** It also takes care of reading in all of the PXL files for the fonts ** used in the job. ** ** read_postamble returns the file offset of the beginning of the last ** page of DVI output. */ long read_postamble(fp) FILE *fp; { long last_page; long tallest, widest; ubyte cmnd; if (one(fp) != POST) error("dvi-imagen: Postamble doesn't begin with POST"); last_page = four(fp); if (numerator != four(fp) || denominator != four(fp) || magnification != four(fp)) error("dvi-imagen: Postamble doesn't match preamble"); tallest = four(fp); if (!landscape) { Ypage_offset = (PIXELS_PER_PAGE - pixel_round(tallest)) / 2; widest = four(fp); Xpage_offset = (PIXELS_PER_LINE - pixel_round(widest)) / 2 + HARD_XPAGE_OFFSET; } else { Ypage_offset = (PIXELS_PER_LINE - pixel_round(tallest))/2 + HARD_XPAGE_OFFSET; widest = four(fp); Xpage_offset = (PIXELS_PER_PAGE - pixel_round(widest))/2; } if (!center) Ypage_offset = Xpage_offset = 0; maxstack = two(fp); total_pages = two(fp); if (debug) remark("tall, wide, po, stk, pages = %d, %d, %d, %d, %d", tallest, widest, Xpage_offset, maxstack, total_pages); do { switch(cmnd = one(fp)) { case FNTDEF1: case FNTDEF2: case FNTDEF3: case FNTDEF4: define_font(fp, cmnd); break; case POSTPOST: break; default: error("dvi-imagen: Non-fntdef cmnd found in postamble"); } } while (cmnd != POSTPOST); return (last_page); } \f /* ** define_font(fp, cmnd) ** ** fp is a FILE pointer for a DVI file which is positioned right after ** a fntdef command. The opcode for the command is in cmnd. ** ** define_font reads the rest of the fntdef command and then reads in ** the specified PXL file, adding it to the global linked-list holding ** all of the fonts used in the job. */ define_font(fp, cmnd) FILE *fp; ubyte cmnd; { struct font *fontp; long checksum; int len; char fontname[513]; if (fontnum >= MAXFONTS) error("dvi-imagen: Too many fonts. Maximum is %d", MAXFONTS); fontp = (struct font *) malloc( sizeof(struct font) ); if (fontp == NULL) error("dvi-imagen: Out of memory while reading font %d", fontnum); fontp->next = fontListHead; fontListHead = fontp; fontp->TeXnumber = num(fp, cmnd - FNTDEF1 + 1); fontp->Inumber = fontnum++; checksum = four(fp); fontp->scale = four(fp); fontp->design = four(fp); len = one(fp) + one(fp); fread(fontname, sizeof(char), len, fp); fontname[len] = '\0'; strcpy(fontp->fontname, fontname); read_pxl_file(fontp, fontname); if (debug > 1) dump_font(fontp, fontname); } \f /* ** read_pxl_file(fontp, fontname) ** ** fontp points to a (struct font) which has been partially initialised ** with the information in the DVI-file FNTDEF command. fontname is the ** name of a font. ** ** read_pxl_file constructs the expected name of the font's PXL file ** from the info in *fontp and fontname. It then reads the glyph ** bitmaps into memory. ** ** Note: the 'size' of a font (i.e. the 1200 in 'cmr10.1200pxl') is ** given by the following formula (rounded): ** ** scaled-size PIXELS_PER_INCH ** ----------- * --------------- * 1000 ** design-size 200 ** ** In the actual implementation, scaled-size/design-size hasn't been ** stored with sufficient precision, hence the messing around to find ** its actual value. */ char *rotate(); read_pxl_file(fontp, fontname) struct font *fontp; char *fontname; { char filename[1025]; FILE *pxlfp; int unmodsize; float realsize; int size; long checksum, magnify, design_size, font_dir_ptr, pxl_id_word; long glyph_ptr[128]; /* Seek locations of each glyph */ int i, j, k; realsize = (magnification/1000.)*((float) fontp->scale / fontp->design); unmodsize = (realsize * 1000) + 0.5; /* a real hack to correct for rounding in some cases -- rkf */ if(unmodsize==1095) realsize = 1.095445; /* stephalf */ else if(unmodsize==1315) realsize=1.314534; /* stepihalf */ else if(unmodsize==2074) realsize=2.0736; /* stepiv */ else if(unmodsize==2488) realsize=2.48832; /* stepv */ else if(unmodsize==2986) realsize=2.985984; /* stepiv */ /* the remaining magnification steps are represented with sufficient accuracy already */ size = (realsize * PIXELS_PER_INCH * 5) + 0.5; sprintf(filename, "%s.%dpxl", fontname, size); if ((pxlfp = fopen(filename, "r")) == NULL) { sprintf(filename, "%s/%s.%dpxl", FONT_DIRECTORY, fontname, size); if ((pxlfp = fopen(filename, "r")) == NULL) { remark("scale = %d, design = %d",fontp->scale, fontp->design); fperror("Can't find font: \"%s\"", filename); } } fseek(pxlfp, - (5 * 4L), 2); /* Seek to trailer info */ checksum = four(pxlfp); magnify = four(pxlfp); design_size = four(pxlfp); font_dir_ptr = four(pxlfp) * 4; pxl_id_word = four(pxlfp); fseek(pxlfp, font_dir_ptr, 0); /* Seek to font directory */ fontp->bc = 0; fontp->ec = 127; for (i=0; i < 128; i++) { fontp->state[i] = Ready; fontp->W[i] = two(pxlfp); fontp->H[i] = two(pxlfp); fontp->X[i] = two(pxlfp); fontp->Y[i] = two(pxlfp); glyph_ptr[i] = four(pxlfp) * 4; /* ** The TFM-width word is kind of funny in the units ** it is expressed in. It works this way: ** ** If a glyph has width 'w' in a font with design-size ** 'd' (both in same units), the TFM-width word is ** ** (w/d) * 2^20 ** ** Therefore, in order to find the glyph width in ** DVI units (1 / 2^16 points), we take the design-size ** 'd' (in DVI's), the magnification 'm' of the PXL file ** and the TFM-width word 't' to the width (in DVI's) ** as follows: ** ** dmt ** w = ----- ** 2^20 ** ** But the magnification of the PXL file is just the ** scaled size 's' over the design size, so the final ** expression for the width is ** ** st ** w = ---- ** 2^20 ** */ #ifndef UNDEFINED fontp->dvi_adv[i] = ((double) fontp->scale * four(pxlfp)) / (1 << 20); #else fontp->dvi_adv[i] = ((double) fontp->design * four(pxlfp)) / (1 << 20); #endif fontp->pxl_adv[i] = pixel_round(fontp->dvi_adv[i]); } for (i=0; i < 128; i++) { int real_bytes_wide = (fontp->W[i] + 7) / 8; int file_bytes_wide = ((fontp->W[i] + 31) / 32) * 4; char *ptr; char junk; ptr = fontp->Glyph[i] = malloc(fontp->H[i] * real_bytes_wide); if (ptr == NULL) error("Out of memory while reading character %d of font %s\n", i, fontname); fseek(pxlfp, glyph_ptr[i], 0); for (j=0; j < fontp->H[i]; j++) { for (k=0; k < file_bytes_wide; k++) { if (k < real_bytes_wide) *(ptr++) = one(pxlfp); else junk = one(pxlfp); } } if (landscape) { char *holdglyph; int width,height,x,y; holdglyph = fontp->Glyph[i]; fontp->Glyph[i] = rotate(holdglyph, fontp->H[i], fontp->W[i]); /* free(holdglyph); */ width = fontp->W[i]; height=fontp->H[i]; x = fontp->X[i]; y=fontp->Y[i]; fontp->W[i] = height; fontp->H[i] = width; fontp->X[i] = height-y; fontp->Y[i] = x; } } fclose(pxlfp); } \f /* ** start_output() ** ** Arrange for the stuff at the beginning of the output to the Imagen ** to be sent out, including the jobid, etc. ** */ start_output() { char *buffer[50]; struct passwd *pwbuf, *getpwuid(); pwbuf = getpwuid(getuid()); sprintf(buffer, " (%s [%d pages])", pwbuf->pw_name, total_pages); strcat(job_id, buffer); if (spoolit) { output_file_name = mktemp("/tmp/dviXXXXXX"); ImPressStart(output_file_name, job_id, verbose); } else ImPressStart((char *)0, job_id, verbose); } \f /* ** do_pages(fp, last_page) ** ** Process the pages in the FILE fp. last_pages is the offset of the ** last page. (We do the pages in reverse order, of course.) ** */ #define PXL_H stack[stackp].pxl_h #define PXL_V stack[stackp].pxl_v #define DVI_H stack[stackp].dvi_h #define DVI_V stack[stackp].dvi_v #define WW stack[stackp].w #define XX stack[stackp].x #define YY stack[stackp].y #define ZZ stack[stackp].z #define nope(str) error("Can't hack %s", str) #define correct() diff = PXL_H - pixel_round(DVI_H); \ if (diff < 0) \ { \ while (diff++) \ ImPressMplus(); \ } \ else if (diff > 0) \ { \ while (diff--) \ ImPressMminus(); \ } \ PXL_H = pixel_round(DVI_H); do_pages(fp, last_page) FILE *fp; long last_page; { char input_left = 1; long next_page; struct font *curr_font; int diff; struct font *ptr; ubyte ch; stack = (struct frame *) malloc( sizeof(struct frame) * (maxstack+1)); if (stack == NULL) error("Can't allocate stack space."); fseek(fp, last_page, 0); while (input_left) { ch = one(fp); if (ch <= SETCHAR0 + 127) { ImPressCharacter(ch); DVI_H += curr_font->dvi_adv[ch]; PXL_H += curr_font->pxl_adv[ch]; correct(); } else if (FNTNUM0 <= ch && ch <= FNTNUM0 + 63) { for (ptr = fontListHead; ptr != NULL; ptr = ptr->next) if (ptr->TeXnumber == ch - FNTNUM0) break; if (ptr == NULL) error("FNTNUM to non-existant font #%d", ch - FNTNUM0); curr_font = ptr; ImPressFont(ptr); } else { long a, b; switch (ch) { case SET1: nope("SET1"); break; case SETRULE: a = sfour(fp); b = sfour(fp); if (a > 0 && b > 0) { correct(); ImPressRule(pixel_round(b), pixel_round(a)); } DVI_H += b; diff = pixel_round(DVI_H); ImPressMove(diff - PXL_H); PXL_H = diff; break; case PUT1: nope("PUT1"); break; case PUTRULE: a = sfour(fp); b = sfour(fp); if (a > 0 && b > 0) { correct(); ImPressRule(pixel_round(b), pixel_round(a)); } break; case NOP: break; case BOP: a = four(fp); if (debug) remark("Beginning page %d", a); for (a=0; a < 9; a++) four(fp); next_page = sfour(fp); stackp = 0; DVI_H = dvi_round(Xpage_offset); PXL_H = Xpage_offset; DVI_V = dvi_round(Ypage_offset); PXL_V = Ypage_offset; WW = XX = YY = ZZ = 0; curr_font = NULL; ImPressBeginPage(); ImPressSetX(PXL_H); break; case EOP: ImPressEndPage(); if (stackp > 0) remark("Stack not empty at EOP; stackp = %d", stackp); if (next_page < 0) input_left = 0; else fseek(fp, next_page, 0); break; case PUSH: stackp++; if (stackp > maxstack) error("More PUSHes than were promised"); stack[stackp] = stack[stackp - 1]; break; case POP: stackp--; if (stackp < 0) error("More POPs than PUSHes"); ImPressSetX(PXL_H); ImPressSetY(PXL_V); break; case RIGHT1: case RIGHT2: case RIGHT3: case RIGHT4: DVI_H += snum(fp, ch - RIGHT1 + 1); diff = pixel_round(DVI_H); ImPressMove(diff - PXL_H); PXL_H = diff; break; case X0: case X1: case X2: case X3: case X4: if (ch != X0) { XX = snum(fp, ch - X0); ImPressSetSpace(pixel_round(XX)); } ImPressSpace(); DVI_H += XX; PXL_H += pixel_round(XX); correct(); break; case W0: case W1: case W2: case W3: case W4: if (ch != W0) WW = snum(fp, ch - W0); DVI_H += WW; diff = pixel_round(DVI_H); ImPressMove(diff - PXL_H); PXL_H = diff; break; case Y0: case Y1: case Y2: case Y3: case Y4: if (ch != Y0) YY = snum(fp, ch - Y0); DVI_V += YY; PXL_V = pixel_round(DVI_V); ImPressSetY(PXL_V); break; case Z0: case Z1: case Z2: case Z3: case Z4: if (ch != Z0) ZZ = snum(fp, ch - Z0); DVI_V += ZZ; PXL_V = pixel_round(DVI_V); ImPressSetY(PXL_V); break; case DOWN1: case DOWN2: case DOWN3: case DOWN4: DVI_V += snum(fp, ch - DOWN1 + 1); PXL_V = pixel_round(DVI_V); ImPressSetY(PXL_V); break; case FNT1: case FNT2: case FNT3: case FNT4: a = num(fp, ch - FNT1 + 1); for (ptr = fontListHead; ptr != NULL; ptr = ptr->next) if (ptr->TeXnumber == a) break; if (ptr == NULL) error("FNT to non-existant font #%d", a); curr_font = ptr; ImPressFont(ptr); break; case XXX1: case XXX2: case XXX3: case XXX4: /*nope("XXXX");*/ a = num(fp, ch-XXX1+1); if(a > 0) DoSpecial (a, fp); break; case FNTDEF1: case FNTDEF2: case FNTDEF3: case FNTDEF4: fseek(fp, 12 + ch - FNTDEF1 + 1, 1); a = one(fp) + one(fp); fseek(fp, a, 1); break; case PRE: error("Can't Happen: PRE encountered."); break; case POST: error("Can't Happen: POST encountered."); break; case POSTPOST: error("Can't Happen: POSTPOST encountered."); break; default: error("Unknown Op-code: %d; Offset: %d", ch, ftell(fp)); } /* end switch*/ } /* end else (ch not a SETCHAR or FNTNUM) */ } /* end while */ } \f /* ** finish_output() ** ** Wrap it up. This routine does not return, since ImPressSendIt() ** doesn't. ** */ finish_output() { ImPressFinish(); if (! spoolit) exit(0); ImPressSendIt(output_file_name, NULL, InputName, total_pages, numcopies, 0, 0); } \f /* ** num(fp, size) snum(fp, size) ** ** Read size bytes from the FILE fp, constructing them into a ** signed/unsigned integer. ** */ unsigned long num(fp, size) FILE *fp; int size; { int i; long x; x = 0; for (i=0; i < size; i++) { x = x * 256 + (unsigned) fgetc(fp); } return(x); } long snum(fp, size) FILE *fp; int size; { int i; long x; x = fgetc(fp) & 0377; if (x & 0200) x -= 256; for (i=1; i < size; i++) { x = x * 256 + (unsigned) fgetc(fp); } return(x); } \f /* ** dump_font(fontp, fontname) ** ** Debugging routine which prints a representation of the information ** read from a PXL file into a 'struct font'. ** */ dump_font(fontp, fontname) struct font *fontp; char *fontname; { int i, j, k, l; printf("\n+++++DUMP OF FONT \"%s\": ", fontname); printf("TeXnumber, Inumber, scale, design = %d, %d, %d, %d\n", fontp->TeXnumber, fontp->Inumber, fontp->scale, fontp->design); printf("\tfontp = %o\n", fontp); for (i=0; i < 128; i++) { char *ptr; printf("\nCharacter %d (%s): ", i, unctrl(i)); printf("H, W, X, Y = %d, %d, %d, %d\n", fontp->H[i], fontp->W[i], fontp->X[i], fontp->Y[i]); printf("\t\tdvi_adv, pxl_adv = %d, %d\n\n", fontp->dvi_adv[i], fontp->pxl_adv[i]); ptr = fontp->Glyph[i]; for (j=0; j < fontp->H[i]; j++) { for (k=0; k < (fontp->W[i] + 7) / 8; k++) { for (l=7; l >= 0; l--) { if (*ptr & (1 << l)) putchar('@'); else putchar(' '); } ptr++; } putchar('\n'); } } } SHAR_EOF fi # end of overwriting check cd .. # End of shell archive exit 0