From "Steven H. Gutfreund " Thu May 14 15:30:08 1987 Flags: 000000000005 Return-Path: Received: from RELAY.CS.NET by SCIENCE.UTAH.EDU with TCP; Thu 14 May 87 15:29:50-MDT Received: from relay2.cs.net by RELAY.CS.NET id aa04336; 14 May 87 17:13 EDT Received: from cs.umass.edu by RELAY.CS.NET id ay16554; 14 May 87 17:08 EDT Date: Thu, 14 May 87 10:42 EDT From: "Steven H. Gutfreund" To: beebe@SCIENCE.UTAH.EDU Subject: /special{} function X-VMS-To: CSNET%"beebe@science.utah.edu" /*-->special*/ /**********************************************************************/ /******************************* special ******************************/ /**********************************************************************/ /* set the resolution in dots per inch */ #define SETRESOLUTION(n) fprintf(plotfp,"\033*t%dR",(n)) /* start raster graphics at top of page */ #define STARTRASTERGRAPHICSATTOP OUTS("\033*r0A") /* start raster graphics at current location */ #define STARTRASTERGRAPHICSHERE OUTS("\033*r1A") /* horizontal move */ #define HORIZONTALMOVE(s) fprintf(plotfp,"\033&a%sH",(s)) /* vertical move */ #define VERTICALMOVE(s) fprintf(plotfp,"\033&a%sV",(s)) char head[4]; /* the escape sequence prefix */ char arg[20]; /* possible numeric argument */ BYTE data[400]; /* Raster data */ int argVal; /* value of numeric argument */ void special(commandText) char *commandText; /* text of the special command */ { int pixelSize = 4; /* at default of 75 dpi, one pixel is a 4x4 square */ int width = 0; /* width in pixels */ int height = 0; /* number of vertical lines */ char command[10]; /* the command -> "include" */ char fileName[80]; /* the file to include */ FILE *jetfd; /* file pointer for bitmap file */ register int i; /* scratch counter */ /******************************************************************* Take a special command of the form \special{commandText} and process it. CommandText is of the form "include filename". The file to be included should contain a bitmap to be included into the output stream for the LaserJet. The format of this file is a stream of 8 bit codes and escape sequences. The minimum contents must be the escape sequence to start raster graphics, the escape sequences to send data, and the end raster graphics sequence. Positioning commands of the H and V forms can also be used. For example: (written on seperate lines for clarity) $E ($ means escape) $*t75R (set dots per inch to 75dpi) $a0C (move to column 0 of the bitmap) * $a0R (move to row 0 of bitmap) * $a+nn.nnH (move relative nn.nn decipoints horizontal) $a+nn.nnV (move relative nn.nn decipoints vertical) $*r1A (start raster graphics, at current loc) $*r0A (start raster graphics, at top of page) $*rb20W........ (20 bytes of raster data) $*rB (end raster graphics) * NOTE: The format of this file was defined to be backward compatible with figures that I produced that existed in stand-alone bitmap files. Thus these files can be sent stand-alone to the LaserJet. $a0C$a0R was the means of repositioning back to the top left corner of the figure. Therefore I continue to interpret it that way, and it does not have the usual meaning of move to row 0, column 0. When using \special from TeX one has to be a bit tricky and make sure that the current cursor position has been updated before the special. For example, the following will produce a centered figure: \begin{center} $\rule{.01mm}{.01mm}\hbox to X.Xtruein{\vtop to X.Xtruein{ \special{include FILENAME}\vss}\hss}$ \end{center} Author: Steven H. Gutfreund, University of Massachusetts, Amherst, MA *******************************************************************/ sscanf(commandText, "%s %s", command, fileName); if (strcmp(command,"include") != 0) { sprintf(message, "special(): TeX \\special{%s} not implemented in this driver", commandText); warning(message); return; } jetfd = fopen(fileName,"r"); DEBUG_OPEN(jetfd,fileName,"r"); if (jetfd == (FILE *)NULL) { sprintf(message, "special(): %s could not be opened, skipping...",fileName); warning(message); return; } while (!feof(jetfd)) { parse(jetfd); if (strcmp(head,"*bW") == 0) { height++; width = argVal * 8; TRANSFERRASTERGRAPHICS(argVal); for (i = 0; i" Sat Jul 18 14:15:10 1987 Flags: 000000000001 Return-Path: Received: from cs.utah.edu by SCIENCE.UTAH.EDU with TCP; Sat 18 Jul 87 14:15:07-MDT Received: by cs.utah.edu (5.54/utah-1.0) id AA17768; Sat, 18 Jul 87 14:17:48 MDT Received: from mcvax.UUCP by seismo.CSS.GOV (5.54/1.14) with UUCP id AA02120; Sat, 18 Jul 87 16:07:05 EDT Received: by mcvax.cwi.nl; Sat, 18 Jul 87 21:50:02 +0200 (MET) Received: from cs.hw.ac.uk by kestrel.Ukc.AC.UK via Janet (UKC CAMEL FTP) id aa14131; 18 Jul 87 18:19 BST Date: Sat, 18 Jul 87 18:23:21 BST Message-Id: <2509.8707181723@brahma.cs.hw.ac.uk> From: Julian Perry To: beebe@cs.utah.edu Subject: LJ+ Landscape Mode Here, as promised, are my mods to dvijep for landscape mode on the HP LaserJet+ .... hope you like them. [3 pieces of mail will follow] I tried (no..make that `tended towards') your style of code but feel free to reimplement bits that need tidying. I humbly apologise for the choice of the -j option but there are so few unused that it seemed like a good idea at the time. Have you added any new features recently? I'm particularly interested in the better method of assigning font and character codes mentioned in the code to try and work around the silly limitations of the LJ+ i.e. 16 fonts/page and max 32 fonts. Also the code for dumping large characters as a raster image would be nice. If these do not look to be on the near horizon then I suppose I might well volunteer, but I'd hate to do work someone else has done already, so could you let me know? And while I'm on the subject of new features....the facility to swap, at will, from landscape to portrait, and back, from a TeX document (presumably via \special{}) would be really cute. At the moment we have a \documentstyle option called `landscape' which sets a whole document in landscape and another command to start a new page in landscape mode, but the user has to manually tell dvijep to print those pages in landscape. Any suggestions? And before I forget, the search paths for PXL and GF files doesn't appear to be the standard Unix path type stuff, can it be changed? The comments in the code imply that if lots of fonts are used then they will get deleted and reloaded as required - this doesn't appear to work. If too many fonts are used then all I seem to get is lots of pages with dots where the characters should be. Please send me a copy of the code if you do reimplement any of my stuff, or if you have some new funky options. Jules IN-REAL-LIFE: Julian Perry E-MAIL: jules@zen.co.uk || ...!mcvax!ukc!zen.co.uk!jules PHONE: +44 532 489048 ext 217 ADDRESS: Zengrange Limited, Greenfield Road, Leeds, England, LS9 8DB From "Julian Perry " Sat Jul 18 14:15:31 1987 Flags: 000000000001 Return-Path: Received: from cs.utah.edu by SCIENCE.UTAH.EDU with TCP; Sat 18 Jul 87 14:15:18-MDT Received: by cs.utah.edu (5.54/utah-1.0) id AA17786; Sat, 18 Jul 87 14:17:58 MDT Received: from mcvax.UUCP by seismo.CSS.GOV (5.54/1.14) with UUCP id AA02133; Sat, 18 Jul 87 16:07:27 EDT Received: by mcvax.cwi.nl; Sat, 18 Jul 87 21:58:19 +0200 (MET) Received: from cs.hw.ac.uk by kestrel.Ukc.AC.UK via Janet (UKC CAMEL FTP) id aa14180; 18 Jul 87 18:25 BST Date: Sat, 18 Jul 87 18:25:37 BST Message-Id: <2561.8707181725@brahma.cs.hw.ac.uk> From: Julian Perry To: beebe@cs.utah.edu Subject: LJ+ Landscape Part 3 of 3 #!/bin/sh # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by jules at zen on Sat Jul 18 17:31:49 1987 # # This archive contains: # dviinit.h prtpage.h # # Error checking via wc(1) will be performed. echo x - dviinit.h cat >dviinit.h <<'@EOF' /* -*-C-*- dviinit.h */ /*-->dviinit*/ /**********************************************************************/ /****************************** dviinit *******************************/ /**********************************************************************/ void dviinit(filestr) /* initialize DVI file processing */ char *filestr; /* command line filename string */ { int i; /* temporary */ INT16 k; /* index in curpath[] and curname[] */ char* tcp; /* temporary string pointers */ char* tcp1; /* temporary string pointers */ #if (OS_TOPS20 | OS_VAXVMS) char* tcp2; /* temporary string pointers */ #endif for (k = 0; k < 10; ++k) tex_counter[k] = (INT32)0L; fontptr = (struct font_entry *)NULL; hfontptr = (struct font_entry *)NULL; pfontptr = (struct font_entry *)NULL; fontfp = (FILE *)NULL; cache_size = 0; nopen = 0; /*********************************************************** Set up file names and open dvi and plot files. Simple filename parsing assumes forms like: Unix: name name.ext /dir/subdir/.../subdir/name /dir/subdir/.../subdir/name.ext TOPS-20: any Unix style (supported by PCC-20) name name.ext name.ext.gen device:name device:name.ext device:name.ext.gen [directory]name [directory]name.ext [directory]name.ext.gen device:[directory]name device:[directory]name.ext device:[directory]name.ext.gen logname:name logname:name.ext logname:name.ext.gen The Unix style should work under IBM PC DOS (backslash can usually be replaced for forward slash), and the TOPS-20 style contains VAX VMS as a subset. Fancier TOPS-20 names are possible (control-V quoting of arbitrary characters, and attributes), but they are rare enough that we do not support them. For TOPS-20 and VAX VMS, generation numbers are recognized as a digit following the last dot, and they are preserved for the DVI file only. For the output files, the highest generation will always be assumed. This is for convenience with the TOPS-20 TeX implementation, which on completion types in a command "TeXspool: foo.dvi.13" and waits for the user to type a carriage return. We only need to extract the directory path, name, and extension, so the parsing is simple-minded. ***********************************************************/ tcp = strrchr(filestr,'/'); /* find end of Unix file path */ #if OS_PCDOS if (tcp == (char*)NULL) /* no Unix-style file path */ tcp = strrchr(filestr, '\\'); /* try \dos\path\ */ #endif #if OS_TOPS20 if (tcp == (char*)NULL) /* no Unix-style file path */ { tcp = strrchr(filestr, '>'); /* try */ if (tcp == (char*)NULL) /* no */ tcp = strrchr(filestr, ']'); /* try [dir] */ if (tcp == (char*)NULL) /* no [dir] */ tcp = strrchr(filestr, ':'); /* try logname: */ } #endif #if OS_VAXVMS if (tcp == (char*)NULL) /* no Unix-style file path */ { tcp = strrchr(filestr, ']'); /* try [dir] */ if (tcp == (char*)NULL) /* no [dir] */ tcp = strrchr(filestr, ':'); /* try logname: */ } #endif if (tcp == (char*)NULL) /* no file path */ { curpath[0] = '\0'; /* empty path */ tcp = filestr; /* point to start of name */ } else /* save path for later use */ { k = (INT16)(tcp-filestr+1); (void)strncpy(curpath, filestr, (int)k); curpath[k] = '\0'; tcp++; /* point to start of name */ } tcp1 = strrchr(tcp, '.'); /* find last dot in filename */ #if (OS_TOPS20 | OS_VAXVMS) if ((tcp1 != (char*)NULL) && isdigit(*(tcp1+1))) { /* then assume generation number */ tcp2 = tcp1; /* remember dot position */ *tcp1 = '\0'; /* discard generation number */ tcp1 = strrchr(tcp,'.');/* find last dot in filename */ *tcp2 = '.'; /* restore dot */ } #endif if (tcp1 == (char*)NULL) { /* no dot, so name has no extension */ (void)strcpy(curname, tcp); /* save name */ tcp1 = strchr(tcp, '\0'); /* set empty extension */ } else /* save name part */ { k = (INT16)(tcp1-tcp); (void)strncpy(curname, tcp, (int)k); curname[k] = '\0'; } (void)strcpy(curext, tcp1); /* save extension */ /* DVI file must always have extension DVIEXT; supply one if necessary (e.g /u/jones/foo.dvi) */ (void)strcpy(dviname, curpath); (void)strcat(dviname, curname); if (curext[0] == '\0') (void)strcat(dviname, DVIEXT); else (void)strcat(dviname, curext); /* Device output file is PATH NAME OUTFILE_EXT (e.g. /u/jones/foo.dvi-alw) */ (void)strcpy(dvoname, curpath); (void)strcat(dvoname, curname); (void)strcat(dvoname, OUTFILE_EXT); /* Font substitution file is PATH NAME SUBEXT (e.g. /u/jones/foo.sub). We do not tell user (via stderr) about it until it is needed. */ if (subfile[0] == '\0') /* no -fsubfile; make default */ { (void)strcpy(subfile, curpath); (void)strcat(subfile, curname); (void)strcat(subfile, subext); } dvifp = FOPEN(dviname,"rb"); DEBUG_OPEN(dvifp,dviname,"rb"); if (dvifp == (FILE*)NULL) { (void)sprintf(message,"dviinit(): %s: can't open [%s]", g_progname, dviname); (void)fatal(message); } #if BBNBITGRAPH strcpy(dvoname,"stdout"); /* BitGraph always goes to stdout */ plotfp = stdout; #else /* NOT BBNBITGRAPH */ #if OS_VAXVMS /* Create fixed-length binary 512-byte instead of stream organization so Kellerman & Smith IMPRINT spooler will handle it. */ #if IMPRESS plotfp = FOPEN(dvoname,"wb","rfm=fix","bls=512","mrs=512"); #else plotfp = FOPEN(dvoname,"wb"); #endif #else plotfp = FOPEN(dvoname,"wb"); #endif #endif /* BBNBITGRAPH */ DEBUG_OPEN(plotfp,dvoname,"wb"); if (plotfp == (FILE*)NULL) { (void)sprintf(message,"dviinit(): %s: can't open [%s]", g_progname, dvoname); (void)fatal(message); } #if OS_TOPS20 /* Because of the PCC-20 arithmetic (instead of logical) shift bug wherein a constant expression (1<<35) evaluates to 0 instead of 400000,,000000, we must set CF_nud using a variable, instead of just using a constant */ /* "ac1 = makefield(CF_nud,1);" */ ac1 = 1; ac1 = makefield(CF_nud,ac1); setfield(ac1,CF_jfn,jfnof(fileno(plotfp))); /* jfn */ setfield(ac1,CF_dsp,FBbyv); /* generation number index in fdb */ ac2 = makefield(FB_ret,-1); ac3 = makefield(FB_ret,0); /* set generation count to 0 (infinite) */ (void)jsys(JSchfdb,acs); /* ignore any errors */ #endif if (!quiet) { (void)fprintf(stderr,"[Input from DVI file %s]",dviname); NEWLINE(stderr); (void)fprintf(stderr,"[Output on file %s]",dvoname); NEWLINE(stderr); } (void)strcpy(g_logname, curpath); (void)strcat(g_logname, curname); #if OS_PCDOS (void)strcat(g_logname, ".err"); #endif #if OS_TOPS20 (void)strcat(g_logname, ".dvi-log.-1"); /* use .-1 so we get new */ /* generation; fopen(,"w+") */ /* otherwise reuses existing */ /* file */ #endif #if OS_UNIX (void)strcat(g_logname, ".err"); #endif #if OS_VAXVMS (void)strcat(g_logname, ".err"); #endif lmargin = (COORDINATE)(leftmargin*((float)XDPI)); tmargin = (COORDINATE)(topmargin*((float)YDPI)); #if (CANON_A2 | IMPRESS | HPJETPLUS) /* Printer has (0,0) origin at (XORIGIN,YORIGIN) near, but not at, upper left corner */ #if HPJETPLUS lmargin -= landscape ? XORIGIN_LANDSCAPE : XORIGIN; tmargin -= landscape ? YORIGIN_LANDSCAPE : YORIGIN; #else lmargin -= XORIGIN; tmargin -= YORIGIN; #endif #endif /* (CANON_A2 | IMPRESS | HPJETPLUS) */ if ((BYTE)nosignex(dvifp,(BYTE)1) != PRE) (void)fatal("dviinit(): PRE doesn't occur first--are you sure \ this is a DVI file?"); i = (int)signex(dvifp,(BYTE)1); if (i != DVIFORMAT) { (void)sprintf(message, "dviinit(): DVI format = %d, can only process DVI format %d files.", i, (int)DVIFORMAT); (void)fatal(message); } } @EOF if test "`wc -lwc prtpage.h <<'@EOF' /* -*-C-*- prtpage.h */ /*-->prtpage*/ /**********************************************************************/ /****************************** prtpage *******************************/ /**********************************************************************/ void prtpage(bytepos) /* print page whose BOP is at bytepos */ long bytepos; { struct stack_entry { INT32 h; COORDINATE hh; INT32 v; COORDINATE vv; INT32 w, x, y, z; /* what's on stack */ }; register BYTE command; /* current command */ register INT16 i; /* command parameter; loop index */ char tc; /* temporary character */ UNSIGN32 ht_rule; /* rule height */ UNSIGN32 wd_rule; /* rule width */ INT32 k,m; /* temporary parameter */ INT16 page_number; /* TeX's \count0 parameter */ BOOLEAN seen_bop; /* flag for noting processing of BOP */ register INT16 sp; /* stack pointer */ struct stack_entry stack[STACKSIZE]; /* stack */ char specstr[MAXSPECIAL+1]; /* \special{} string */ INT32 w; /* current horizontal spacing */ INT32 x; /* current horizontal spacing */ INT32 y; /* current vertical spacing */ INT32 z; /* current vertical spacing */ /*********************************************************************** Process all commands between the BOP at bytepos and the next BOP or POST. The page is printed when the EOP is met, but font changes can also happen between EOP and BOP, so we have to keep going after EOP. ***********************************************************************/ seen_bop = FALSE; /* this is first time through */ (void) FSEEK(dvifp,bytepos,0); /* start at the desired position */ for (;;) /* "infinite" loop - exits when POST or second BOP met */ switch (command=(BYTE)nosignex(dvifp,(BYTE)1)) { case SET1: case SET2: case SET3: case SET4: (void)setchar((BYTE)nosignex(dvifp,(BYTE)(command-SET1+1)),TRUE); break; case SET_RULE: ht_rule = nosignex(dvifp,(BYTE)4); wd_rule = nosignex(dvifp,(BYTE)4); (void)setrule(ht_rule,wd_rule,TRUE); break; case PUT1: case PUT2: case PUT3: case PUT4: (void)setchar((BYTE)nosignex(dvifp,(BYTE)(command-PUT1+1)),FALSE); break; case PUT_RULE: ht_rule = nosignex(dvifp,(BYTE)4); wd_rule = nosignex(dvifp,(BYTE)4); (void)setrule(ht_rule,wd_rule,FALSE); break; case NOP: break; case BOP: if (seen_bop) return; /* we have been here already */ seen_bop = TRUE; for (i=0; i<=9; i++) tex_counter[i] = (INT32)signex(dvifp,(BYTE)4); page_number = (INT16)tex_counter[0]; #if BBNBITGRAPH OUTS("\033[2J"); /* ED Erase in Display */ pbghpos = pbgvpos = -99; cpagep = (long)FTELL(dvifp) - 1L; #else /* not BBNBITGRAPH */ #if POSTSCRIPT if (cur_page_number <= MAXPAGE) { (void)fflush(plotfp); page_loc[cur_page_number] = (long)FTELL(plotfp); page_tex[cur_page_number] = (INT32)page_number; } (void)fprintf(plotfp,"%%%%Page: %d %d", page_number,cur_page_number); NEWLINE(plotfp); if (ps_vmbug) { OUTS(" /SaveImage save def() pop"); NEWLINE(plotfp); } OUTS("BOP"); NEWLINE(plotfp); rule_height = -1; /* reset last rule parameters */ rule_width = -1; str_ycp = -1; /* last string ycp */ #else /* not POSTSCRIPT */ #if HPJETPLUS rule_height = -1; /* reset last rule parameters */ rule_width = -1; str_ycp = -1; /* last string ycp */ if ( landscape ) OUTS("\033&l1O"); #else /* NOT (POSTSCRIPT | HPJETPLUS) */ #if (CANON_A2 | IMPRESS) str_ycp = -1; /* last string ycp */ #else /* NOT (POSTSCRIPT | HPJETPLUS | CANON_A2 | IMPRESS) */ (void)clrbmap(); #endif /* (CANON_A2 | IMPRESS) */ #endif /* HPJETPLUS */ #endif /* POSTSCRIPT */ #endif /* BBNBITGRAPH */ if (!quiet) (void)fprintf(stderr,"{%s}",tctos()); /* TeX page counters */ #if BBNBITGRAPH ppagep = (long)nosignex(dvifp,(BYTE)4); #else /* not BBNBITGRAPH */ (void) nosignex(dvifp,(BYTE)4); /* skip prev. page ptr */ #endif /* BBNBITGRAPH */ h = v = w = x = y = z = 0; hh = lmargin; vv = tmargin; sp = 0; fontptr = (struct font_entry*)NULL; break; case EOP: #if BBNBITGRAPH (void)eopact(); #else /* not BBNBITGRAPH */ #if POSTSCRIPT if (fprintf(plotfp," %d EOP",copies) == EOF) (void)fatal( "prtpage(): Output error -- disk storage probably full"); NEWLINE(plotfp); if (ps_vmbug) { OUTS(" SaveImage restore() pop"); NEWLINE(plotfp); font_switched = TRUE; fontptr = hfontptr; while (fontptr != (struct font_entry *)NULL) { for (k = 0; k < NPXLCHARS; ++k) fontptr->ch[k].isloaded = FALSE; fontptr = fontptr->next; } } for (k = (INT32)copies; k; --k) OUTC('\f'); /* FF's for page accounting */ #else /* not POSTSCRIPT */ #if (CANON_A2 | HPJETPLUS) if (copies > 1) SETCOPIES(copies); PAGEEJECT; #else /* not (CANON_A2 | HPJETPLUS) */ #if IMPRESS PAGEEJECT; #else (void)prtbmap(); #endif /* IMPRESS */ #endif /* (CANON_A2 | HPJETPLUS) */ #endif /* POSTSCRIPT */ #endif /* BBNBITGRAPH */ return; case PUSH: if (sp >= STACKSIZE) (void)fatal("prtpage(): stack overflow"); stack[sp].h = h; stack[sp].hh = hh; stack[sp].v = v; stack[sp].vv = vv; stack[sp].w = w; stack[sp].x = x; stack[sp].y = y; stack[sp].z = z; sp++; break; case POP: --sp; if (sp < 0) (void)fatal("prtpage(): stack underflow"); h = stack[sp].h; hh = stack[sp].hh; v = stack[sp].v; vv = stack[sp].vv; w = stack[sp].w; x = stack[sp].x; y = stack[sp].y; z = stack[sp].z; break; case RIGHT1: case RIGHT2: case RIGHT3: case RIGHT4: (void)moveover(signex(dvifp,(BYTE)(command-RIGHT1+1))); break; case W0: (void)moveover(w); break; case W1: case W2: case W3: case W4: w = (INT32)signex(dvifp,(BYTE)(command-W1+1)); (void)moveover(w); break; case X0: (void)moveover(x); break; case X1: case X2: case X3: case X4: x = (INT32)signex(dvifp,(BYTE)(command-X1+1)); (void)moveover(x); break; case DOWN1: case DOWN2: case DOWN3: case DOWN4: (void)movedown(signex(dvifp,(BYTE)(command-DOWN1+1))); break; case Y0: (void)movedown(y); break; case Y1: case Y2: case Y3: case Y4: y = signex(dvifp,(BYTE)(command-Y1+1)); (void)movedown(y); break; case Z0: (void)movedown(z); break; case Z1: case Z2: case Z3: case Z4: z = signex(dvifp,(BYTE)(command-Z1+1)); (void)movedown(z); break; case FNT1: case FNT2: case FNT3: case FNT4: (void)setfntnm((INT32)nosignex(dvifp, (BYTE)(command-FNT1+1))); break; case XXX1: case XXX2: case XXX3: case XXX4: k = (INT32)nosignex(dvifp,(BYTE)(command-XXX1+1)); if (k > MAXSPECIAL) { (void)sprintf(message, "prtpage(): \\special{} string of %d characters longer \ than DVI driver limit of %d -- truncated.", k,MAXSPECIAL); (void)warning(message); } m = 0; while (k--) { tc = (char)nosignex(dvifp,(BYTE)1); if (m < MAXSPECIAL) specstr[m++] = tc; } specstr[m] = '\0'; (void) special(specstr); break; case FNT_DEF1: case FNT_DEF2: case FNT_DEF3: case FNT_DEF4: if (preload) (void)skipfont ((INT32) nosignex(dvifp, (BYTE)(command-FNT_DEF1+1))); else (void)readfont ((INT32) nosignex(dvifp, (BYTE)(command-FNT_DEF1+1))); break; case PRE: (void)fatal("prtpage(): PRE occurs within file"); break; case POST: (void)devterm(); /* terminate device output */ (void)dviterm(); /* terminate DVI file processing */ (void)alldone(); /* this will never return */ break; case POST_POST: (void)fatal("prtpage(): POST_POST with no preceding POST"); break; default: if (command >= FONT_00 && command <= FONT_63) (void)setfntnm((INT32)(command - FONT_00)); else if (command >= SETC_000 && command <= SETC_127) #if (HPJETPLUS | POSTSCRIPT | IMPRESS | CANON_A2) (void)setstr((BYTE)command); /* this sets several chars */ #else (void)setchar((BYTE)(command-SETC_000), TRUE); #endif /* (HPJETPLUS | POSTSCRIPT | IMPRESS | CANON_A2) */ else { (void)sprintf(message,"prtpage(): %d is an undefined command", command); (void)fatal(message); } break; } } @EOF if test "`wc -lwc " Sat Jul 18 14:15:36 1987 Flags: 000000000001 Return-Path: Received: from cs.utah.edu by SCIENCE.UTAH.EDU with TCP; Sat 18 Jul 87 14:15:09-MDT Received: by cs.utah.edu (5.54/utah-1.0) id AA17773; Sat, 18 Jul 87 14:17:50 MDT Received: from mcvax.UUCP by seismo.CSS.GOV (5.54/1.14) with UUCP id AA02124; Sat, 18 Jul 87 16:07:09 EDT Received: by mcvax.cwi.nl; Sat, 18 Jul 87 21:50:18 +0200 (MET) Received: from cs.hw.ac.uk by kestrel.Ukc.AC.UK via Janet (UKC CAMEL FTP) id aa14156; 18 Jul 87 18:22 BST Date: Sat, 18 Jul 87 18:23:37 BST Message-Id: <2518.8707181723@brahma.cs.hw.ac.uk> From: Julian Perry To: beebe@cs.utah.edu Subject: LJ+ Landscape Part 1 of 3 #!/bin/sh # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by jules at zen on Sat Jul 18 17:30:37 1987 # # This archive contains: # dvijep.c # # Error checking via wc(1) will be performed. echo x - dvijep.c cat >dvijep.c <<'@EOF' /* -*-C-*- dvijep.c */ /*-->dvijep*/ /**********************************************************************/ /******************************* dvijep *******************************/ /**********************************************************************/ #include "dvihead.h" /*********************************************************************** ***********************************************************************/ /**********************************************************************/ /************************ Device Definitions ************************/ /**********************************************************************/ /* All output-device-specific definitions go here. This section must be changed when modifying a dvi driver for use on a new device */ #undef HPJETPLUS #define HPJETPLUS 1 /* conditional compilation flag */ #define VERSION_NO "2.06b" /* DVI driver version number */ #define DEVICE_ID "Hewlett-Packard LaserJet Plus" /* this string is printed at runtime */ #if OS_PCDOS #define OUTFILE_EXT ".jep" #endif #if OS_TOPS20 #define OUTFILE_EXT ".dvi-jep" #endif #if OS_UNIX #define OUTFILE_EXT ".jep" #endif #if OS_VAXVMS #define OUTFILE_EXT ".dvi-jep" #endif #define BYTE_SIZE 8 /* output file byte size */ #undef STDRES #define STDRES 1 /* to get standard font resolution */ #define MAXLINE 4096 /* maximum input file line size */ /* it is needed only in special() */ #define XDPI 300 /* horizontal dots/inch */ #define XPSIZE 8 /* horizontal paper size in inches */ int XSIZE; /* number of horizontal dots */ #define YDPI 300 /* vertical dots/inch */ #define YPSIZE 11 /* vertical paper size in inches */ int YSIZE; /* number of vertical dots */ #define XORIGIN 30 /* measured pixel coordinates of */ #define YORIGIN 162 /* page origin (should be at (0,0) */ #define XORIGIN_LANDSCAPE 60 /* Same but for landscape mode */ #define YORIGIN_LANDSCAPE 147 /* ;; ;; ;; */ /*********************************************************************** Define some useful shorthand macros for all required LaserJet Plus commands. With the exception of the CREATEFONT and DOWNLOADCHAR macros, which require extra data, NO escape sequences appear anywhere else in the text. The LaserJet Plus allows coordinates in dots as well as the decipoints supported by the regular LaserJet. Dot coordinates are more convenient, so we use them exclusively. The Plus puts the page origin in the upper- left corner, while we have it in the lower-left corner, so MOVEY adjusts the coordinate accordingly. With 7-bit fonts, only characters 33..127 are printable, and with 8-bit fonts, 33..127 and 160..255 are printable. Since TeX assumes characters 0..127 are available, we remap character numbers in 0..32 to 160..192 and use 8-bit fonts. The macros conceal the remapping. Whenever possible, escape sequences are combined and 0 parameters omitted, in order to compress the output. ***********************************************************************/ /* CREATEFONT must be followed by a 26-byte font header (see readfont) */ #define CREATEFONT (void)fprintf(plotfp,"\033\051s26W") #define DELETEALLFONTS OUTS("\033*cF") #define DELETEFONT(fontnumber) (void)fprintf(plotfp,"\033*c%dd2F",fontnumber) /* DOWNLOADCHAR is not a complete specification---it must be followed by two-byte values of xoff, yoff, width, height, deltax */ #define DOWNLOADCHAR(nbytes) (void)fprintf(plotfp,"\033\050s%dW",(nbytes)+16) /* Map characters (0..32,33..127) to (160..192,33..127) */ #define MAPCHAR(c) (((c) > 32) ? (c) : ((c) + 160)) /* Move absolute to (x,y), page origin in lower left corner */ #define MOVETO(x,y) (void)fprintf(plotfp,"\033*p%dx%dY",(x),YSIZE-(y)) /* Move absolute to (x,current y), page origin in lower left corner */ #define MOVEX(x) (void)fprintf(plotfp,"\033*p%dX",(x)) /* Move absolute to (current x,y), page origin in lower left corner */ #define MOVEY(y) (void)fprintf(plotfp,"\033*p%dY",YSIZE-(y)) /* Output TeX character number with mapping to HP LaserJet Plus number */ #define OUTCHAR(c) OUTC(MAPCHAR(c)) /* Output a 16-bit binary number in two bytes */ #define OUT16(n) {OUTC((n)>>8); OUTC((n));} /* Eject a page from the printer--this is the last command on each page */ #define PAGEEJECT OUTC('\f') /* Pop current point (push with PUSHCP) */ #define POPCP OUTS("\033&f1S") /* Push current point (pop with POPCP) */ #define PUSHCP OUTS("\033&fS") /* Reset printer at job start. E is global reset which clears everything but permanent fonts, which we do not use. &l0E resets left margin to 0. &a0L resets top margin to 0. Without these, default margins are supplied which lie inside page. Unfortunately, these do not permit negative values, so we have to further correct the origin with (XORIGIN, YORIGIN) defined above; these bias (lmargin, tmargin) set in dviinit(). */ #define RESETPRINTER OUTS("\033&lef0lP\033&alM") /* Move relative by (delx,dely) from current point */ #define RMOVETO(delx,dely) {\ if ((delx) == 0)\ RMOVEY(dely)\ else if ((dely) == 0)\ RMOVEX(delx)\ else\ (void)fprintf(plotfp,"\033*p%c%dx%c%dY",\ ((delx) > 0 ? '+' : '-'),ABS(delx),\ ((dely) < 0 ? '+' : '-'),ABS(dely));\ } /* Move relative to (delx+currentx,currenty), page origin in lower left corner */ #define RMOVEX(delx) {\ if ((delx) > 0)\ (void)fprintf(plotfp,"\033*p+%dX",(delx));\ else if ((delx) < 0)\ (void)fprintf(plotfp,"\033*p%dX",(delx));\ } /* Move relative to (currentx,dely+currenty), page origin in lower left corner */ #define RMOVEY(dely) {\ if ((dely) > 0)\ (void)fprintf(plotfp,"\033*p%dY",-(dely));\ else if ((dely) < 0)\ (void)fprintf(plotfp,"\033*p+%dY",-(dely));\ } /* Round a POSITIVE floating-point value to the nearest integer */ #define ROUND(x) ((int)(x + 0.5)) /* Output a new rule at TeX position (x,y). The device coordinates will be changed on completion. The rule origin is the TeX convention of the lower-left corner, while the LaserJet Plus uses the upper-left corner. */ #define RULE(x,y,width,height) {\ MOVETO(x,(y)+height);\ (void)fprintf(plotfp,"\033*c%da%dbP",width,height);\ } /* Set rule of same size as previous one at TeX position (x,y). The device coordinates will be changed on completion. */ #define RULE2(x,y) {\ MOVETO(x,(y)+rule_height);\ OUTS("\033*cP");\ } /* Set the current font and character in preparation for a DOWNLOADCHAR */ #define SETCHARCODE(fontnumber,ch) {\ if (fontnumber)\ (void)fprintf(plotfp,"\033*c%dd%dE",fontnumber,MAPCHAR(ch));\ else\ (void)fprintf(plotfp,"\033*cd%dE",MAPCHAR(ch));\ } /* Set the number of copies of the current page (issue just before PAGEEJECT) */ #define SETCOPIES(n) (void)fprintf(plotfp,"\033&l%dX",MAX(1,MIN(n,99))) /* Set the font number in preparation for a CREATEFONT */ #define SETFONTID(fontnumber) (void)fprintf(plotfp,"\033*c%dd4F",(fontnumber)); /* Set the current font number */ #define SETCURRENTFONT(fontnumber) {\ if (fontnumber)\ (void)fprintf(plotfp,"\033\050%dX",(fontnumber));\ else\ OUTS("\033\050X");\ } #include "main.h" #include "abortrun.h" #include "actfact.h" #include "alldone.h" #include "chargf.h" #include "charpk.h" #include "charpxl.h" #include "clrrow.h" /*-->devinit*/ /**********************************************************************/ /****************************** devinit *******************************/ /**********************************************************************/ void devinit(argc,argv) /* initialize device */ int argc; char *argv[]; { RESETPRINTER; /* printer reset */ DELETEALLFONTS; /* delete all downloaded fonts */ font_count = 0; /* no font numbers are assigned yet */ font_switched = TRUE; if ( landscape ) { XSIZE = (int) (XDPI * 11); YSIZE = (int) (YDPI * 8); } else { XSIZE = (int) (XDPI * 8); YSIZE = (int) (YDPI * 11); } } /*-->devterm*/ /**********************************************************************/ /****************************** devterm *******************************/ /**********************************************************************/ void devterm() /* terminate device */ { DELETEALLFONTS; /* delete all downloaded fonts */ RESETPRINTER; /* printer reset */ } #include "dvifile.h" #include "dviinit.h" #include "dviterm.h" #if PCC_20 #include "f20open.h" #endif #include "fatal.h" /*-->fillrect*/ /**********************************************************************/ /****************************** fillrect ******************************/ /**********************************************************************/ void fillrect(x,y,width,height) COORDINATE x,y,width,height; /* lower left corner, size */ /*********************************************************************** With the page origin (0,0) at the lower-left corner, draw a filled rectangle at (x,y). For most TeX uses, rules are uncommon, and little optimization is possible. However, for the LaTeX Bezier option, curves are simulated by many small rules (typically 2 x 2) separated by positioning commands. By remembering the size of the last rule set, we can test for the occurrence of repeated rules of the same size, and reduce the output by omitting the rule sizes. The last rule parameters are reset by the begin-page action in prtpage(), so they do not carry across pages. It is not possible to use relative, instead of absolute, moves in these sequences, without stacking rules for the whole page, because each rule is separated in the DVI file by push, pop, and positioning commands, making for an uncertain correspondence between internal (xcp,ycp) pixel page coordinates and external device coordinates. The last string y coordinate, str_ycp, must be reset here to force any later setstring() to reissue new absolute positioning commands. ***********************************************************************/ { str_ycp = -1; /* invalidate string y coordinate */ if ((height != rule_height) || (width != rule_width)) { RULE(x,y,width,height); rule_width = width; /* save current rule parameters */ rule_height = height; } else /* same size rule again */ RULE2(x,y); } #include "findpost.h" #include "fixpos.h" #include "fontfile.h" #include "fontsub.h" #include "getbytes.h" #include "getfntdf.h" #include "getpgtab.h" #include "inch.h" #include "initglob.h" /*-->loadchar*/ /**********************************************************************/ /****************************** loadchar ******************************/ /**********************************************************************/ void loadchar(c) register BYTE c; { void (*charyy)(); /* subterfuge to get around PCC-20 bug */ register struct char_entry *tcharptr; /* temporary char_entry pointer */ register UNSIGN32 nwords; /* how many 32-bit words we need */ COORDINATE nbytes; /* number of bytes per row */ UNSIGN16 words_per_row; /* number of raster words per row */ UNSIGN16 bytes_per_row; /* number of raster bytes to copy */ register INT16 k; /* loop index */ register INT16 l; /* loop index */ register UNSIGN32 *p; /* pointer into img_row[] */ register BYTE the_byte; /* unpacked raster byte */ if ((c < FIRSTPXLCHAR) || (LASTPXLCHAR < c)) /* check character range */ return; tcharptr = &(fontptr->ch[c]); if (!VISIBLE(tcharptr)) return; /* do nothing for invisible fonts */ nwords = (UNSIGN32)(((tcharptr->wp+31) >> 5) * (tcharptr->hp)); tcharptr->rasters = (UNSIGN32*)MALLOC((unsigned)(nwords*sizeof(UNSIGN32))); if (tcharptr->rasters == (UNSIGN32*)NULL) { (void)sprintf(message,"loadchar(): Could not allocate %ld words of \ raster space--used %ld words so far", (long)nwords,(long)cache_size); (void)fatal(message); } tcharptr->refcount = 0; /* clear reference count */ cache_size += (INT32)nwords; /* update cache size record */ if (fontptr != pfontptr) openfont(fontptr->n); if (fontfp == (FILE *)NULL) /* do nothing if no font file */ return; /* Bug fix: PCC-20 otherwise jumps to charxx instead of *charxx */ charyy = fontptr->charxx; (void)(*charyy)(c,outrow); /* output rasters */ (void)clearerr(plotfp); tcharptr->isloaded = TRUE; SETCHARCODE(fontptr->font_number,c); /* Number of bytes in bitmap, possibly reduced because of LaserJet Plus */ /* limits. Large characters really need to be handled as bitmaps */ /* instead of as downloaded characters. */ if ( landscape ) { nbytes = ((tcharptr->hp) + 7) >> 3; /* wp div 8 */ DOWNLOADCHAR(MIN(16,nbytes)*MIN(255,(tcharptr->wp))); } else { nbytes = ((tcharptr->wp) + 7) >> 3; /* wp div 8 */ DOWNLOADCHAR(MIN(16,nbytes)*MIN(255,(tcharptr->hp))); } OUTC(4); /* 4 0 14 1 is fixed sequence */ OUTC(0); OUTC(14); OUTC(1); if ( landscape ) OUTC(1); /* orientation = 1 ==> landscape */ else OUTC(0); /* orientation = 0 ==> portrait */ OUTC(0); if ( landscape ) { OUT16(MAX(-128,MIN(-(tcharptr->yoffp),127))); OUT16(MAX(-128,MIN((tcharptr->wp - tcharptr->xoffp) - 1,127))); OUT16(MIN(255,tcharptr->hp)); OUT16(MIN(128,tcharptr->wp)); OUT16(ROUND(4.0*(tcharptr->tfmw)*conv)); /* delta x to nearest */ /* 1/4 dot */ } else { OUT16(MAX(-128,MIN(-(tcharptr->xoffp),127))); OUT16(MAX(-128,MIN(tcharptr->yoffp,127))); OUT16(MIN(128,tcharptr->wp)); OUT16(MIN(255,tcharptr->hp)); OUT16(ROUND(4.0*(tcharptr->tfmw)*conv)); /* delta x to nearest */ /* 1/4 dot */ } /* shit goes here to output the rasters in the correct way */ words_per_row = (UNSIGN16)(tcharptr->wp + 31) >> 5; if ( landscape ) { bytes_per_row = (UNSIGN16)((tcharptr->hp) + 7) >> 3; /* wp div 8 */ bytes_per_row = MIN(16,bytes_per_row); /* limited to 128 bits/row */ for (k = tcharptr->wp; --k >= 0; ) { the_byte = 0; for (l = 0; l < tcharptr->hp; ++l ) { the_byte <<= 1; the_byte |= ((tcharptr->rasters + l*words_per_row)[k / 32] >> (31 - (k % 32))) & 01; if ( (l % 8) == 7 ) { OUTC(the_byte); the_byte = 0; } } if ( l % 8 ) { the_byte <<= 8 - (l % 8); OUTC(the_byte); } } } else { bytes_per_row = (UNSIGN16)((tcharptr->wp) + 7) >> 3; /* wp div 8 */ bytes_per_row = MIN(16,bytes_per_row); /* limited to 128 bits/row */ for (k = 0; k < tcharptr->hp; ++k) { if (k > 255) /* LaserJet Plus cannot handle big characters */ break; p = tcharptr->rasters + k*words_per_row; for (l = bytes_per_row; l > 0; ++p) { the_byte = (BYTE)((*p) >> 24); OUTC(the_byte); if ((--l) <= 0) break; the_byte = (BYTE)((*p) >> 16); OUTC(the_byte); if ((--l) <= 0) break; the_byte = (BYTE)((*p) >> 8); OUTC(the_byte); if ((--l) <= 0) break; the_byte = (BYTE)(*p); OUTC(the_byte); if ((--l) <= 0) break; } } } if (DISKFULL(plotfp)) (void)fatal("loadchar(): Output error -- disk storage probably full"); } #include "movedown.h" #include "moveover.h" #include "moveto.h" /*-->newfont*/ /**********************************************************************/ /****************************** newfont *******************************/ /**********************************************************************/ void newfont() { struct font_entry *tfontptr;/* temporary font_entry pointer */ register BYTE the_char; /* loop index */ INT16 j; /* loop index */ /* parameters of largest cell */ COORDINATE cell_above; /* dots above baseline */ COORDINATE cell_below; /* dots below baseline */ COORDINATE cell_height; /* total height */ COORDINATE cell_left; /* dots left of character cell */ COORDINATE cell_width; /* total width */ COORDINATE cell_baseline; /* in 0..(cell_height-1) */ /******************************************************************* Each LaserJet Plus font must be assigned a unique number in 0..32767, and only 32 fonts can be active at one time. We keep a table of font pointers for this purpose and store the corresponding table index in font_number. Each time a new font is encountered, we increment font_count and store it in that fonts font_number. TeX produces a unique font number as well, and TeX82 only uses values in the range 0..255. The DVI file supports 32-bit font numbers, so it is better to generate our own, because someday other programs may produce DVI files too. If fonts are freed dynamically, the table entry must be invalidated and a command sent to the printer to delete that font. At present, font freeing happens only in dviterm() at the close of processing of a single DVI file. A subsequent DVI file processed will result in the invocation of devinit() which resets font_count to 0. In order to deal with the limit of 32 active fonts in the LaserJet Plus, we have two choices. The first and best and most difficult, is to entirely discard the matching of TeX fonts with LaserJet Plus fonts---new characters would simply be assigned to the next available entry in the current open font. The second choice is less satisfactory---when 32 fonts have been downloaded, we delete the last 16 of them and reset the isloaded flags for all of them. As a guide to how bad this is, we issue a warning message when it happens. An intermediate solution would be to use the character reference counts to find the least-used fonts and delete them. The Plus also allows deletion of individual characters, so in the first case, we could delete little-used characters to make room in the font tables on the device. <------wp------> ^ ................ | ................ | ................ | ................ | ................ | ................ | ................ hp ................ | ................ | ................ | ................ | .....o.......... <-- character reference point (xcp,ycp) at "o" | ................ ^ | ................ | | ................ |--- (hp - yoffp - 1) | ................ | v +............... v <-- (xcorner,ycorner) at "+" <---> | | xoffp (negative if (xcp,ycp) left of bitmap) The LaserJet Plus font mechanism requires the declaration of cell height, width, and baseline in the CreateFont command. Experiments show that these must be large enough to incorporate the maximum extent above and below the baseline of any characters in the font. The metric correspondences are as follows: ----- ------------- TeX LaserJet Plus ----- ------------- xoffp -(left offset) yoffp top offset max(yoffp) + 1 cell baseline max(wp) cell width max(yoffp) + max(hp-yoff,yoff-hp) + 1 cell height *******************************************************************/ for (the_char = FIRSTPXLCHAR; the_char <= LASTPXLCHAR; the_char++) fontptr->ch[the_char].isloaded = FALSE; if (font_count >= MAXFONTS) /* then 32n fonts have been downloaded */ { (void)warning( "newfont(): HP LaserJet Plus active font storage exceeded.\n\ ---Last 16 downloaded fonts will be deleted, then reloaded on demand.\n\ ---Reprinting of current page may be necessary."); for (j = (INT16)(MAXFONTS>>1); j < (INT16)font_count; ++j) { tfontptr = font_table[j]; DELETEFONT(tfontptr->font_number); for (the_char = 0; the_char < NPXLCHARS; ++the_char) tfontptr->ch[the_char].isloaded = FALSE; font_table[j] = (struct font_entry *)NULL; } font_count = (UNSIGN16)(MAXFONTS>>1); } for (j = 0; j < (INT16)font_count; ++j) if (font_table[j] == fontptr) /* then font already known */ break; if (j >= (INT16)font_count) /* new font */ { fontptr->font_number = font_count; font_table[font_count++] = fontptr; cell_above = 0; cell_baseline = 0; cell_below = 0; cell_height = 0; cell_left = 0; cell_width = 0; for (the_char = FIRSTPXLCHAR; the_char <= LASTPXLCHAR; ++the_char) { cell_above = MAX(cell_above,fontptr->ch[the_char].yoffp); cell_below = MAX(cell_below, ABS(fontptr->ch[the_char].yoffp - fontptr->ch[the_char].hp)); cell_left = MAX(cell_left,-fontptr->ch[the_char].xoffp); cell_width = MAX(cell_width,fontptr->ch[the_char].wp); } cell_baseline = cell_above + 1; cell_height = cell_above + cell_below + 1; if ((cell_width > 255) || (cell_height > 255)) { (void)sprintf(message, "newfont(): Some characters in font [%s] exceed\n\ ---HP LaserJet Plus limit of 255-dot cell size.\n\ ---Some characters may be truncated or lost",fontptr->name); (void)warning(message); cell_height = MIN(cell_height,255); cell_width = MIN(cell_width,255); } if (!IN(-128,cell_left,127) || !IN(-128,cell_above,127)) { (void)sprintf(message, "newfont(): Some characters in font [%s] exceed\n\ ---HP LaserJet Plus range of -128..+127 for left or top offset.\n\ ---Some characters may be truncated or lost",fontptr->name); (void)warning(message); } if (!IN(0,cell_width,128)) { (void)sprintf(message, "newfont(): Some characters in font [%s] exceed\n\ ---HP LaserJet Plus limit of 128-dot width.\n\ ---Some characters may be truncated or lost",fontptr->name); (void)warning(message); cell_width = MIN(cell_width,128); } SETFONTID(fontptr->font_number); CREATEFONT; OUTC(0); OUTC(26); /* descriptor length */ OUTC(0); /* always 0 */ OUTC(1); /* 8-bit font (for more than 95 characters) */ OUT16(0); /* always 0 */ OUT16(cell_baseline); /* baseline position (in 0..cell_height-1))*/ OUT16(cell_width); /* cell width */ OUT16(cell_height); /* cell height */ if ( landscape ) OUTC(1); /* orientation = 1 ==> landscape */ else OUTC(0); /* orientation = 0 ==> portrait */ OUTC(1); /* spacing = 1 ==> proportional */ OUT16(0); /* symbol set (arbitrary) */ OUT16(2); /* pitch (arbitrary in 2..1260) */ OUT16(cell_height); /* font height (arbitrary in 0..10922) */ OUT16(0); /* always 0 */ OUTC(0); /* always 0 */ OUTC(0); /* style = 0 ==> upright */ OUTC(0); /* stroke weight = 0 ==> normal */ OUTC(0); /* typeface = 0 (arbitrary) */ } } #include "nosignex.h" #include "openfont.h" #include "option.h" #include "outrow.h" #include "prtpage.h" #include "readfont.h" #include "readgf.h" #include "readpk.h" #include "readpost.h" #include "readpxl.h" #include "rulepxl.h" /*-->setchar*/ /**********************************************************************/ /****************************** setchar *******************************/ /**********************************************************************/ void setchar(c, update_h) register BYTE c; register BOOLEAN update_h; { register struct char_entry *tcharptr; /* temporary char_entry pointer */ /* BIGCHAR() and ONPAGE() are used here and in setstr() */ #define BIGCHAR(t) ((t->wp > (COORDINATE)size_limit) ||\ (t->hp > (COORDINATE)size_limit)) #define ONPAGE(t) (((hh - t->xoffp + t->pxlw) <= XSIZE) \ && (hh >= 0)\ && (vv <= YSIZE)\ && (vv >= 0)) tcharptr = &(fontptr->ch[c]); moveto(hh,YSIZE-vv); if (ONPAGE(tcharptr)) { /* character fits entirely on page */ if (font_switched) { SETCURRENTFONT(fontptr->font_number); font_switched = FALSE; } if (VISIBLE(tcharptr)) { if (BIGCHAR(tcharptr)) { /* we need to send a graphics bitmap at this point */ (void)warning( "newfont(): No code implemented yet for big characters"); } else { if (!tcharptr->isloaded) loadchar(c); if (ycp != str_ycp) { MOVETO(xcp,ycp); str_ycp = ycp; } else MOVEX(xcp); OUTCHAR(c); } } } else if ((debug_code & 32) && !quiet) { /* character is off page -- discard it */ (void)fprintf(stderr, "setchar(): Char %c [10#%3d 8#%03o 16#%02x] off page.", isprint(c) ? c : '?',c,c,c); NEWLINE(stderr); } if (update_h) { h += (INT32)tcharptr->tfmw; hh += (COORDINATE)tcharptr->pxlw; hh = fixpos(hh-lmargin,h,conv) + lmargin; } } #include "setfntnm.h" #include "setrule.h" /*-->setstr*/ /**********************************************************************/ /******************************* setstr *******************************/ /**********************************************************************/ void setstr(c) register BYTE c; { register struct char_entry *tcharptr; /* temporary char_entry pointer */ register BOOLEAN inside; INT32 h0,v0; /* (h,v) at entry */ COORDINATE hh0,vv0; /* (hh,vv) at entry */ COORDINATE hh_last; /* hh before call to fixpos() */ register UNSIGN16 k; /* loop index */ UNSIGN16 nstr; /* number of characters in str[] */ BYTE str[MAXSTR+1]; /* string accumulator */ BOOLEAN truncated; /* off-page string truncation flag */ /******************************************************************* Set a sequence of characters in SETC_000 .. SETC_127 with a minimal number of LaserJet Plus commands. These sequences tend to occur in long clumps in a DVI file, and setting them together whenever possible substantially decreases the overhead and the size of the output file. A sequence can be set as a single string if * TeX and LaserJet Plus coordinates of each character agree (may not be true, since device coordinates are in multiples of 1/4 pixel; violation of this requirement can be detected if fixpos() changes hh, or if ycp != str_ycp), AND * each character is in the same font (this will always be true in a sequence from a DVI file), AND * each character fits within the page boundaries, AND * each character definition is already loaded, AND * each character is from a visible font, AND * each character bitmap extent is smaller than the size_limit (which is used to enable discarding large characters after each use in order to conserve virtual memory storage on the output device). Whenever any of these conditions does not hold, any string already output is terminated, and a new one begun. Two output optimizations are implemented here. First, up to MAXSTR (in practice more than enough) characters are collected in str[], and any that require downloading are handled. Then the entire string is set at once, subject to the above limitations. Second, by recording the vertical page coordinate, ycp, in the global variable str_ycp (reset in prtpage() at begin-page processing), it is possible to avoid outputting y coordinates unnecessarily, since a single line of text will generally result in many calls to this function. *******************************************************************/ #define BEGINSTRING {inside = TRUE;\ if (ycp != str_ycp)\ {\ MOVETO(xcp,ycp);\ str_ycp = ycp;\ }\ else\ MOVEX(xcp);} #define ENDSTRING {inside = FALSE;} #define OFF_PAGE (-1) /* off-page coordinate value */ if (font_switched) /* output new font selection */ { SETCURRENTFONT(fontptr->font_number); font_switched = FALSE; } inside = FALSE; truncated = FALSE; hh0 = hh; vv0 = vv; h0 = h; v0 = v; nstr = 0; while ((SETC_000 <= c) && (c <= SETC_127) && (nstr < MAXSTR)) { /* loop over character sequence */ tcharptr = &(fontptr->ch[c]); moveto(hh,YSIZE-vv); if (ONPAGE(tcharptr) && VISIBLE(tcharptr)) { /* character fits entirely on page and is visible */ if ((!tcharptr->isloaded) && (!BIGCHAR(tcharptr))) loadchar(c); } /* update horizontal positions in TFM and pixel units */ h += (INT32)tcharptr->tfmw; hh += (COORDINATE)tcharptr->pxlw; str[nstr++] = c; /* save string character */ c = (BYTE)nosignex(dvifp,(BYTE)1); } /* put back character which terminated the loop */ (void)UNGETC((int)(c),dvifp); hh = hh0; /* restore coordinates at entry */ vv = vv0; h = h0; v = v0; for (k = 0; k < nstr; ++k) { /* loop over character sequence */ c = str[k]; tcharptr = &(fontptr->ch[c]); moveto(hh,YSIZE-vv); if (ONPAGE(tcharptr) && VISIBLE(tcharptr)) { /* character fits entirely on page and is visible */ if (tcharptr->isloaded) /* character already downloaded */ { if (!inside) BEGINSTRING; OUTCHAR(c); } else /* character must be downloaded first */ { if (inside) ENDSTRING; /* finish any open string */ if (BIGCHAR(tcharptr)) { /* Large character to be discarded. */ /* we need to send a graphics bitmap at this point */ (void)warning( "setstr(): No code implemented yet for big characters"); str_ycp = OFF_PAGE; tcharptr->isloaded = FALSE; } } } else /* character does not fit on page -- output */ { /* current string and discard the character */ truncated = TRUE; if (inside) ENDSTRING; } /* update horizontal positions in TFM and pixel units */ h += (INT32)tcharptr->tfmw; hh += (COORDINATE)tcharptr->pxlw; hh_last = hh; hh = fixpos(hh-lmargin,h,conv) + lmargin; if (debug_code & 4) { (void)fprintf(stderr, "[%03o] xcp = %d\tycp = %d\thh = %d\thh_last = %d\n", c,xcp,ycp,hh,hh_last); } /* If fixpos() changed position, we need new string next time */ /* around. Actually, since the LaserJet Plus stores character */ /* widths in units of 1/4 dot, we could compute coordinates at */ /* four times the precision, but for now, we start a new string */ /* each time we have one or more dots of error. */ if ((hh != hh_last) && inside) ENDSTRING; } if (truncated && (debug_code & 32) && !quiet) { (void)fprintf(stderr,"setstr(): Text ["); for (k = 0; k < nstr; ++k) (void)fprintf(stderr,isprint(str[k]) ? "%c" : "\\%03o",str[k]); (void)fprintf(stderr,"] truncated at page boundaries."); NEWLINE(stderr); } if (inside) /* finish last string */ ENDSTRING; } #include "signex.h" #include "skgfspec.h" #include "skipfont.h" #include "skpkspec.h" #include "special.h" #include "strchr.h" #include "strcm2.h" #include "strid2.h" #include "strrchr.h" #include "tctos.h" #include "usage.h" #include "warning.h" @EOF if test "`wc -lwc " Sat Jul 18 14:15:41 1987 Flags: 000000000001 Return-Path: Received: from cs.utah.edu by SCIENCE.UTAH.EDU with TCP; Sat 18 Jul 87 14:15:17-MDT Received: by cs.utah.edu (5.54/utah-1.0) id AA17779; Sat, 18 Jul 87 14:17:54 MDT Received: from mcvax.UUCP by seismo.CSS.GOV (5.54/1.14) with UUCP id AA02128; Sat, 18 Jul 87 16:07:18 EDT Received: by mcvax.cwi.nl; Sat, 18 Jul 87 21:50:50 +0200 (MET) Received: from cs.hw.ac.uk by kestrel.Ukc.AC.UK via Janet (UKC CAMEL FTP) id aa14158; 18 Jul 87 18:24 BST Date: Sat, 18 Jul 87 18:24:48 BST Message-Id: <2545.8707181724@brahma.cs.hw.ac.uk> From: Julian Perry To: beebe@cs.utah.edu Subject: LJ+ Landscape Part 2 of 3 #!/bin/sh # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by jules at zen on Sat Jul 18 17:31:28 1987 # # This archive contains: # gblvars.h option.h # # Error checking via wc(1) will be performed. echo x - gblvars.h cat >gblvars.h <<'@EOF' /* -*-C-*- gblvars.h */ /*-->gblvars*/ /**********************************************************************/ /****************************** gblvars *******************************/ /**********************************************************************/ /**********************************************************************/ /********************* General Global Variables *********************/ /**********************************************************************/ char curpath[MAXFNAME]; /* current file area */ char curext[MAXFNAME]; /* current file extension */ char curname[MAXFNAME]; /* current file name */ BYTE debug_code; /* 0 for no debug output */ char dviname[MAXFNAME]; /* DVI filespec */ char dvoname[MAXFNAME]; /* device output filespec */ char fontlist[MAXSTR]; /* FONTLIST environment string */ char fontpath[MAXFNAME]; /* font directory path */ char helpcmd[MAXSTR]; /* where to look for help */ char message[MAXSTR]; /* for formatting error messages */ /*********************************************************************** Magnification table for 144dpi, 200dpi, and 300dpi devices, computed to 20 figures and sorted by magnitude. Column 1 Column 2 Column 3 0.72*sqrt(1.2)**i sqrt(1.2)**I 1.5*sqrt(1.2)**I (I = -16,16) ***********************************************************************/ static float mag_table[] = { 0.16744898601451165028, 0.18343117374303022733, 0.20093878321741398034, 0.22011740849163627280, 0.23256803936137783874, 0.24112653986089677641, 0.25476552262595201888, 0.26414089018996352736, 0.27908164723365340649, 0.28935184783307613169, 0.30571862715114242265, 0.31696906822795623283, 0.33489797668038408779, 0.34722221739969135802, 0.34885205904206675812, 0.36686235258137090718, 0.38036288187354747940, 0.38214828393892802832, 0.40187757201646090535, 0.41666666087962962963, 0.41862247085048010974, 0.44023482309764508862, 0.45643545824825697527, 0.45857794072671363398, 0.48225308641975308642, 0.49999999305555555556, 0.50234696502057613169, 0.52828178771717410634, 0.54772254989790837033, 0.55029352887205636077, 0.57870370370370370370, 0.59999999166666666667, 0.60281635802469135802, 0.63393814526060892761, 0.65726705987749004440, 0.66035223464646763293, 0.69444444444444444444, 0.71999999000000000000, 0.72337962962962962963, 0.76072577431273071313, 0.78872047185298805327, 0.79242268157576115952, 0.83333333333333333333, 0.86399998800000000000, 0.86805555555555555556, 0.91287092917527685576, 0.94646456622358566393, 0.95090721789091339142, 1.00000000000000000000, 1.03679998560000000000, 1.04166666666666666670, 1.09544511501033222690, 1.13575747946830279670, 1.14108866146909606970, 1.20000000000000000000, 1.24415998272000000000, 1.25000000000000000000, 1.31453413801239867230, 1.36290897536196335610, 1.36930639376291528360, 1.44000000000000000000, 1.49299197926400000000, 1.50000000000000000000, 1.57744096561487840680, 1.63549077043435602730, 1.64316767251549834040, 1.72800000000000000000, 1.79159037511680000000, 1.80000000000000000000, 1.89292915873785408810, 1.96258892452122723270, 1.97180120701859800840, 2.07360000000000000000, 2.14990845014016000000, 2.16000000000000000000, 2.27151499048542490570, 2.35510670942547267930, 2.36616144842231761010, 2.48832000000000000000, 2.57989014016819200000, 2.59200000000000000000, 2.72581798858250988690, 2.82612805131056721510, 2.83939373810678113220, 2.98598400000000000000, 3.09586816820183040000, 3.11040000000000000000, 3.27098158629901186430, 3.40727248572813735860, 3.58318080000000000000, 3.73248000000000000000, 3.92517790355881423710, 4.08872698287376483030, 4.29981696000000000000, 4.47897600000000000000, 4.90647237944851779640, 5.37477120000000000000, 5.88776685533822135560, 6.44972544000000000000 }; INT16 mag_index; /* set by actfact */ #define MAGTABSIZE (sizeof(mag_table) / sizeof(float)) int g_errenc = 0; /* has an error been encountered? */ #if BBNBITGRAPH #if (OS_TOPS20 | OS_UNIX) struct sgttyb g_intty; /* information about stdin if interactive */ struct sgttyb tty; /* to see if program is interactive */ #endif /* (OS_TOPS20 | OS_UNIX) */ #endif /* BBNBITGRAPH */ char g_logname[MAXSTR]; /* name of log file, if created */ BOOLEAN g_dolog = TRUE; /* allow log file creation */ FILE *g_logfp = (FILE*)NULL; /* log file pointer (for errors) */ char g_progname[MAXSTR]; /* program name */ FILE *plotfp = (FILE*)NULL; /* plot file pointer */ struct char_entry { /* character entry */ COORDINATE wp, hp; /* width and height in pixels */ COORDINATE xoffp, yoffp; /* x offset and y offset in pixels */ long fontrp; /* font file raster pointer */ UNSIGN32 tfmw; /* TFM width */ INT32 dx, dy; /* character escapements */ UNSIGN16 pxlw; /* pixel width == round(TFM width in */ /* pixels for .PXL files, or */ /* float(char_dx)/65536.0 for .GF and .PK */ /* files) */ INT16 refcount; /* reference count for memory management */ UNSIGN32 *rasters; /* raster description (dynamically loaded) */ #if (HPJETPLUS | POSTSCRIPT | IMPRESS | CANON_A2) BOOLEAN isloaded; /* is the character already downloaded? */ #endif /* (HPJETPLUS | POSTSCRIPT | IMPRESS | CANON_A2) */ #if BBNBITGRAPH BOOLEAN istoobig; /* is the character too big for BitGraph? */ BOOLEAN isloaded; /* is the character loaded in the BitGraph?*/ INT16 bgfont, bgchar; /* BitGraph font and character */ #endif /* BBNBITGRAPH */ }; struct font_entry { /* font entry */ void (*charxx)(); /* pointer to chargf(), charpk(), charpxl() */ FILE *font_file_id; /* file identifier (NULL if none) */ INT32 k; /* font number */ UNSIGN32 c; /* checksum */ UNSIGN32 d; /* design size */ UNSIGN32 s; /* scale factor */ INT32 font_space; /* computed from FNT_DEF s parameter */ UNSIGN32 font_mag; /* computed from FNT_DEF s and d parameters */ UNSIGN32 magnification; /* magnification read from PXL file */ UNSIGN32 designsize; /* design size read from PXL file */ UNSIGN32 hppp; /* horizontal pixels/point * 2**16 */ UNSIGN32 vppp; /* vertical pixels/point * 2**16 */ INT32 min_m; /* GF bounding box values */ INT32 max_m; INT32 min_n; INT32 max_n; struct char_entry ch[NPXLCHARS];/* character information */ struct font_entry *next; /* pointer to next font entry */ #if (HPJETPLUS | IMPRESS | CANON_A2) UNSIGN16 font_number; /* font number (0..32767) */ #endif /* (HPJETPLUS | IMPRESS | CANON_A2) */ BYTE font_type; /* GF, PK, or PXL font file */ BYTE a; /* length of font area in n[] */ BYTE l; /* length of font name in n[] */ char n[MAXSTR]; /* font area and name */ char name[MAXSTR]; /* full name of PXL file */ }; struct font_list { FILE *font_id; /* file identifier */ INT16 use_count; /* count of "opens" */ }; INT32 cache_size; /* record of how much character raster */ /* is actually used */ float conv; /* converts DVI units to pixels */ UNSIGN16 copies; /* number of copies to print of each page */ INT16 cur_page_number; /* sequential output page number in 1..N */ INT16 cur_index; /* current index in page_ptr[] */ COORDINATE xcp,ycp; /* current position */ UNSIGN32 den; /* denominator specified in preamble */ FILE *dvifp = (FILE*)NULL; /* DVI file pointer */ struct font_entry *fontptr; /* font_entry pointer */ struct font_entry *hfontptr = (struct font_entry *)NULL; /* head font_entry pointer */ #if (HPJETPLUS | IMPRESS | CANON_A2) UNSIGN16 font_count; /* used to assign unique font numbers */ struct font_entry *font_table[MAXFONTS]; #endif /* (HPJETPLUS | IMPRESS | CANON_A2) */ #if (HPJETPLUS | POSTSCRIPT | IMPRESS | CANON_A2) BOOLEAN font_switched; /* current font has changed */ #endif /* (HPJETPLUS | POSTSCRIPT | IMPRESS | CANON_A2) */ INT16 gf_index, pk_index, pxl_index; /* indexes into filelist[] in fontfile(); */ /* they define the search order, and are */ /* in initglob(). */ UNSIGN32 gpower[33]; /* gpower[k] = 2**k-1 (k = 0..32) */ INT32 h; /* current horizontal position */ COORDINATE hh; /* current horizontal position in pixels */ #if HPLASERJET INT16 hpres; /* output resolution (75, 100, 150, 300 dpi) */ #endif /* HPLASERJET */ #if HPJETPLUS BOOLEAN landscape = FALSE; /* landscape mode for HP LaserJet+ */ #endif /* HPJETPLUS */ UNSIGN32 img_mask[32]; /* initialized at run-time so that bit k */ /* (counting from high end) is one */ UNSIGN32 img_row[(MAX_M - MIN_M + 1 + 31) >> 5]; /* current character image row of bits */ INT16 max_m, min_m, max_n, min_n; /* current character matrix extents */ UNSIGN16 img_words; /* number of words in use in img_row[] */ float leftmargin; /* left margin in inches */ COORDINATE lmargin; /* left margin offset in pixels */ INT16 nopen; /* number of open PXL files */ INT16 page_count; /* number of entries in page_ptr[] */ long page_ptr[MAXPAGE+1]; /* byte pointers to pages (reverse order) */ #if POSTSCRIPT long page_loc[MAXPAGE+1]; /* byte pointers to output pages */ INT32 page_tex[MAXPAGE+1]; /* TeX's \count0 page numbers */ #endif /* POSTSCRIPT */ INT16 page_begin[MAXREQUEST+1], page_end[MAXREQUEST+1], page_step[MAXREQUEST+1]; /* explicit page range requests */ INT16 npage; /* number of explicit page range requests */ struct font_list font_files[MAXOPEN+1]; /* list of open PXL file identifiers */ UNSIGN32 power[32]; /* power[k] = 1 << k */ #if POSTSCRIPT BOOLEAN ps_vmbug; /* reload fonts on each page when TRUE */ #endif /* POSTSCRIPT */ UNSIGN32 rightones[HOST_WORD_SIZE];/* bit masks */ UNSIGN32 runmag; /* runtime magnification */ UNSIGN32 mag; /* magnification specified in preamble */ UNSIGN32 num; /* numerator specified in preamble */ struct font_entry *pfontptr = (struct font_entry *)NULL; /* previous font_entry pointer */ BOOLEAN preload = TRUE; /* preload the font descriptions? */ FILE *fontfp = (FILE*)NULL; /* font file pointer */ BOOLEAN quiet = FALSE; /* suppress status display when TRUE */ BOOLEAN backwards = FALSE; /* print in backwards order */ #if (CANON_A2 | HPJETPLUS | IMPRESS | POSTSCRIPT) COORDINATE rule_height; /* parameters of last rule set */ COORDINATE rule_width; COORDINATE str_ycp; /* last string ycp value */ UNSIGN16 size_limit; /* character size limit in pixels -- larger */ /* characters are downloaded each time they */ /* are required to avoid PostScript ROM bugs */ #if OS_TOPS20 BOOLEAN spool_output = FALSE; /* offer to send output to spooler */ #endif /* OS_TOPS20 */ #endif /* (CANON_A2 | HPJETPLUS | IMPRESS | POSTSCRIPT) */ char subpath[MAXFNAME]; /* font substitution file path */ char subname[MAXFNAME]; /* font substitution file name field */ char subext[MAXFNAME]; /* font substitution file extension field */ char subfile[MAXFNAME]; /* font substitution filename */ INT32 tex_counter[10]; /* TeX c0..c9 counters on current page */ float topmargin; /* top margin in inches */ COORDINATE tmargin; /* top margin offset in pixels */ INT32 v; /* current vertical position */ #if VIRTUAL_FONTS BOOLEAN virt_font; /* virtual font cache flag */ struct virt_data { int cnt; char *ptr; char *base; }; struct virt_data virt_save[_NFILE];/* space for saving old FILE values */ #endif /* VIRTUAL_FONTS */ COORDINATE vv; /* current vertical position in pixels */ #if BBNBITGRAPH struct char_entry *bgcp[NBGFONTS+(NBGFONTS+2)/3][NPXLCHARS]; /* Pointer to corresponding char_entry for this BitGraph font */ /* and character. These are used to set the char_entry's */ /* status to "not loaded" when we have to reuse the BitGraph */ /* character. The array is cleared initially in devinit(). */ INT16 fullfont = 0; /* full font to load in BitGraph */ BOOLEAN g_interactive=TRUE; /* is the program running interactively */ /* (i.e., standard output not redirected)? */ INT16 partchar = FIRSTBGCHAR; /* partial font character to load in BitGraph*/ INT16 partfont = NBGFONTS; /* partial font to load in BitGraph */ INT16 pbghpos; /* previous BitGraph horizontal position */ INT16 pbgvpos; /* previous BitGraph vertical position */ INT16 pbgf = -1; /* previous BitGraph font */ COORDINATE xdiff; /* x difference */ COORDINATE xscreen; /* x screen adjustment */ COORDINATE ydiff; /* y difference */ COORDINATE yscreen; /* y screen adjustment */ long cpagep; /* pointer to current page in DVI file */ long ppagep; /* pointer to previous page in DVI file */ #if PCC_20 #define jfn_plotfp (jfnof(fileno(plotfp))) int bg_length,bg_width,bg_1ccoc,bg_2ccoc,bg_modeword,bg_sysmsg; #endif /* PCC_20 */ #endif /* BBNBITGRAPH */ @EOF if test "`wc -lwc option.h <<'@EOF' /* -*-C-*- option.h */ /*-->option*/ /**********************************************************************/ /******************************* option *******************************/ /**********************************************************************/ void option(optstr) /* process command-line option */ char *optstr; /* option string (e.g. "-m1500") */ { register UNSIGN32 k; /* magnification */ register int value; /* converted digit string value */ register int m; /* loop index */ char *p; /* pointer into optstr */ int p1,p2,p3; /* temp values for sscanf() */ double fltmag; /* floating-point mag value */ typedef struct { char* envname; char* envvar; } envstruct; static envstruct envlist[] = { /* names and addresses of environment vars (alphabetical order) */ "DVIHELP", helpcmd, "FONTLIST", fontlist, "TEXFONTS", fontpath, "TEXINPUTS", subpath, }; if (*optstr != '-') return; /* return if this is not an option */ switch (*(optstr+1)) { case 'a': /* A selects virtual font caching */ case 'A': #if VIRTUAL_FONTS virt_font = TRUE; #endif break; case 'b': /* b selects backwards printing order */ case 'B': backwards = TRUE; break; case 'c': /* c selects number of copies */ case 'C': copies = (UNSIGN16) atoi(optstr+2); copies = MAX(1,MIN(copies,256)); /* enforce reasonable limits */ break; case 'd': /* d selects debug output */ case 'D': debug_code = (BYTE)atoi(optstr+2); break; case 'e': /* e specifies ``environment'' variable definition */ case 'E': /* We ignore letter case since these come from */ /* the command line */ if (!(p = strrchr(optstr,'='))) { (void)usage(stderr); (void)sprintf(message, "option(): Bad switch [%s]--expected -eENVNAME=value", optstr); (void)fatal(message); } *p = '\0'; /* clobber "=" by string terminator */ for (m = 0; m < sizeof(envlist)/sizeof(envlist[0]); ++m) { if (strcm2(optstr+2,envlist[m].envname) == 0) { (void)strcpy(envlist[m].envvar,p+1); return; } } (void)usage(stderr); (void)sprintf(message,"option(): Bad switch [%s]--expected one of:", optstr); for (m = 0; m < sizeof(envlist)/sizeof(envlist[0]); ++m) { (void)strcat(message," "); (void)strcat(message,envlist[m].envname); } (void)fatal(message); break; case 'f': /* f specifies font substitution file */ case 'F': (void)strcpy(subfile,optstr+2); break; #if HPJETPLUS case 'j': /* j means 'Jules' option for landscape mode */ case 'J': landscape = TRUE; break; #endif case 'l': /* l prohibits logging of errors */ case 'L': g_dolog = FALSE; break; case 'm': /* m selects alternate magnification */ case 'M': /* Collect 2*value initially. Then if value is small, assume user specified magstep value; magstep k means 1.2**k, where k is integral, or half-integral. Otherwise, assume user has specified pxl file magnification (1000 == 200dpi, 1500 == 300dpi, etc.). */ if (strchr(optstr+2,'.') != (char *)NULL) fltmag = (double)(2.0 * atof(optstr+2)); else fltmag = (double)(2 * atoi(optstr+2)); if ((0.0 != fltmag) && (ABS(fltmag) <= 30.0)) /* magstep 15 is limit */ if (fltmag < 0.0) runmag = (UNSIGN32)((1.0/pow((double)sqrt(1.2),-fltmag))* (double)STDMAG); else runmag = (UNSIGN32)(pow((double)sqrt(1.2),fltmag)* (double)STDMAG); else runmag = (UNSIGN32)(fltmag/2.0); k = MAGSIZE(actfact(runmag)); /* rounded magnification */ if (k != runmag) { (void)sprintf(message, "option(): Requested magnification %d not available.", (int)runmag); (void)warning(message); runmag = k; k = (UNSIGN32) MAX(1,MIN(mag_index,(MAGTABSIZE-1))); (void)sprintf(message, " Magnification reset to nearest legal value %d in \ family ..%d..%d..%d..", (int)runmag,(int)MAGSIZE(mag_table[k-1]), (int)MAGSIZE(mag_table[k]), (int)MAGSIZE(mag_table[k+1])); (void)warning(message); } break; case 'o': case 'O': /* o selects output page range (-o# or -o#:# or -o#:#:#) */ p1 = p2 = p3 = 0; value = (int)sscanf(optstr+2,"%d:%d:%d",&p1,&p2,&p3); page_begin[npage] = p1; page_end[npage] = p2; page_step[npage] = p3; switch (value) { case 1: optstr++; /* point past "-" */ do /* skip over digit string */ { optstr++; } while (isdigit(*optstr) || (*optstr == '-') || (*optstr == '+')); if (*optstr) /* trash follows number */ { (void)usage(stderr); (void)sprintf(message, "option(): %s is not a legal page number switch",optstr); (void)fatal(message); } else /* had expected end-of-string */ page_end[npage] = (INT16)page_begin[npage]; page_step[npage] = 1; break; case 2: /* supply default step */ page_step[npage] = 1; /* FALL THROUGH to case 3 for order check */ case 3: /* check for correct ordering */ if (page_begin[npage] > page_end[npage]) { value = (int)page_end[npage]; page_end[npage] = page_begin[npage]; page_begin[npage] = (INT16)value; } if (page_step[npage] <= 0) page_step[npage] = 1; break; default: /* illegal value */ (void)usage(stderr); (void)sprintf(message, "option(): %s is not a legal page number switch",optstr); (void)fatal(message); } npage++; break; case 'p': /* p prohibits pre-font loading */ case 'P': #if (HPLASERJET|HPJETPLUS|GOLDENDAWNGL100|POSTSCRIPT|IMPRESS|CANON_A2) preload = TRUE; /* preloading required for Canon engines */ /* because of reverse printing order */ #else preload = FALSE; #endif /*NOT(HPLASERJET|HPJETPLUS|GOLDENDAWNGL100|POSTSCRIPT|IMPRESS|CANON_A2)*/ break; case 'q': /* q inhibits status display */ case 'Q': quiet = TRUE; break; #if HPLASERJET case 'r': /* r selects output resolution */ case 'R': hpres = (INT16)atoi(optstr+2); if ((hpres != 75) && (hpres != 100) && (hpres != 150) && (hpres != 300)) { (void)sprintf(message, "option(): Output resolution not in [75,100,150,300] dpi; \ reset to %d", DEFAULT_RESOLUTION); (void)warning(message); hpres = DEFAULT_RESOLUTION; } break; #endif /* HPLASERJET */ #if (APPLEIMAGEWRITER | GOLDENDAWNGL100 | TOSHIBAP1351) case 'r': /* r selects run-length coding of output */ case 'R': runlengthcode = TRUE; break; #endif /* (APPLEIMAGEWRITER | GOLDENDAWNGL100 | TOSHIBAP1351) */ #if POSTSCRIPT case 's': /* pixel size limit to force character reloading */ case 'S': size_limit = (UNSIGN16)atoi(optstr+2); break; case 'v': /* vmbug -- reload fonts on each page */ case 'V': ps_vmbug = TRUE; break; #endif /* POSTSCRIPT */ case 'x': case 'X': leftmargin = inch(optstr+2); break; case 'y': case 'Y': topmargin = inch(optstr+2); break; #if (HPJETPLUS | IMPRESS | POSTSCRIPT) #if OS_TOPS20 case 'z': case 'Z': spool_output = TRUE; /* offer to send output to spooler */ break; #endif /* OS_TOPS20 */ #endif /* (HPJETPLUS | IMPRESS | POSTSCRIPT) */ default: (void)usage(stderr); (void)sprintf(message,"option(): %s is not a legal switch", optstr); (void)fatal(message); } } @EOF if test "`wc -lwc " Mon Jul 27 12:51:23 1987 Flags: 000000000001 Return-Path: Received: from cs.utah.edu by SCIENCE.UTAH.EDU with TCP; Mon 27 Jul 87 12:51:18-MDT Received: by cs.utah.edu (5.54/utah-1.0) id AA02864; Mon, 27 Jul 87 12:52:46 MDT Received: from mcvax.UUCP by seismo.CSS.GOV (5.54/1.14) with UUCP id AA08631; Mon, 27 Jul 87 14:40:33 EDT Received: by mcvax.cwi.nl; Mon, 27 Jul 87 20:21:43 +0200 (MET) Received: from cs.hw.ac.uk by kestrel.Ukc.AC.UK via Janet (UKC CAMEL FTP) id aa15158; 27 Jul 87 17:41 BST Date: Mon, 27 Jul 87 17:46:43 BST Message-Id: <14163.8707271646@brahma.cs.hw.ac.uk> From: Julian Perry To: beebe@cs.utah.edu Subject: Re: DVIJEP landscape mods Hi again, Hope you got the last 4 pieces of mail I sent last week. Having looked again at what I sent you, I didn't explain what I sent you very well at all. So these are the details... The files I sent are the only ones which I have changed. The bits I changed can be easily found by searching for the global variable 'landscape'. Other bits which I changed were minor things to suit our Laser Printer spooler (to stop blank pages being fed out), and some changes to a few numbers to suit UK A4 paper. I have since found a bug in the -o option if you specify negative page numbers (for counting back from the end). The problem is in 'option.h' where you check to see the order of the pages is right, this will of course wrongly swap the page order if you use -o1:-2 (as we do a lot). I fixed this by commenting out the test and swap if the page range is apparently wrong; it's not a very clean fix but at that stage the number of pages in the document isn't known so it's not possible to fully validate range. Also I think an error message if it's wrong might be better than silently swapping the start and end numbers. Hope this has cleared up a couple of points. Jules IN-REAL-LIFE: Julian Perry E-MAIL: jules@zen.co.uk || ...!mcvax!ukc!zen.co.uk!jules PHONE: +44 532 489048 ext 217 ADDRESS: Zengrange Limited, Greenfield Road, Leeds, England, LS9 8DB From "Julian Perry " Sat Mar 5 14:00:32 1988 Flags: 000000000001 Return-Path: Received: from uunet.UU.NET by SCIENCE.UTAH.EDU with TCP; Sat 5 Mar 88 13:59:13-MST Received: from mcvax.UUCP by uunet.UU.NET (5.54/1.14) with UUCP id AA17452; Sat, 5 Mar 88 15:58:45 EST Received: by mcvax.cwi.nl; Sat, 5 Mar 88 21:55:28 +0100 (MET) Received: from cs.hw.ac.uk by kestrel.Ukc.AC.UK via Janet (UKC CAMEL FTP) id aa06158; 5 Mar 88 13:35 GMT Message-Id: <5491.8803051333@brahma.cs.hw.ac.uk> From: Julian Perry To: "Nelson H.F. Beebe" Date: Sat, 5 Mar 88 13:01:56 GMT Subject: Re: dvijep landscape mods In-Reply-To: Message from "Nelson H.F. Beebe" of Mar 3, 88 at 12:03 (noon) X-Mailer: Elm [version 1.5b] Here are the context diffs to add the -j (Jules option for landscape) to dvijep. Also note the fix to readpxl is included as are the changes to machdefs.h for our site. Feed this through patch on the source directory. Have fun, Jules IN-REAL-LIFE: Julian Perry E-MAIL: jules@zen.co.uk || ...!mcvax!ukc!zen.co.uk!jules PHONE: +44 532 489048 ext 217 ADDRESS: Zengrange Limited, Greenfield Road, Leeds, England, LS9 8DB *** ORIG_SRCS/dvijep.c Thu Feb 11 14:57:05 1988 --- dvijep.c Sat Mar 5 12:47:27 1988 *************** *** 37,45 #define MAXPAGEFONTS 16 /* silly limit on fonts/page */ #define XDPI 300 /* horizontal dots/inch */ ! #define XPSIZE 8 /* horizontal paper size in inches */ ! #define XSIZE (((XDPI*XPSIZE+2*HOST_WORD_SIZE-1)/\ ! (2*HOST_WORD_SIZE))*(2*HOST_WORD_SIZE)) /* number of horizontal dots; */ /* MUST BE multiple of */ /* 2*HOST_WORD_SIZE */ --- 37,48 ----- #define MAXPAGEFONTS 16 /* silly limit on fonts/page */ #define XDPI 300 /* horizontal dots/inch */ ! #define XPSIZE 9 /* horizontal paper size in inches */ ! #define XSIZE_PORTRAIT 2543 ! #define XSIZE_LANDSCAPE 3508 ! int XSIZE; ! /* #define XSIZE (((XDPI*XPSIZE+2*HOST_WORD_SIZE-1)/\ ! (2*HOST_WORD_SIZE))*(2*HOST_WORD_SIZE)) */ /* number of horizontal dots; */ /* MUST BE multiple of */ /* 2*HOST_WORD_SIZE */ *************** *** 45,52 /* 2*HOST_WORD_SIZE */ #define YDPI 300 /* vertical dots/inch */ ! #define YPSIZE 11 /* vertical paper size in inches */ ! #define YSIZE (YDPI*YPSIZE) /* number of vertical dots */ #define XORIGIN 30 /* measured pixel coordinates of */ #define YORIGIN -15 /* page origin (should be at (0,0) */ --- 48,57 ----- /* 2*HOST_WORD_SIZE */ #define YDPI 300 /* vertical dots/inch */ ! #define YPSIZE 12 /*ish*/ /* vertical paper size in inches */ ! #define YSIZE_PORTRAIT 3508 ! #define YSIZE_LANDSCAPE 2543 ! int YSIZE; #define XORIGIN_PORTRAIT 60 /* measured pixel coordinates of */ #define XORIGIN_LANDSCAPE 55 *************** *** 48,55 #define YPSIZE 11 /* vertical paper size in inches */ #define YSIZE (YDPI*YPSIZE) /* number of vertical dots */ ! #define XORIGIN 30 /* measured pixel coordinates of */ ! #define YORIGIN -15 /* page origin (should be at (0,0) */ /*********************************************************************** Define some useful shorthand macros for all required LaserJet Plus --- 53,60 ----- #define YSIZE_LANDSCAPE 2543 int YSIZE; ! #define XORIGIN_PORTRAIT 60 /* measured pixel coordinates of */ ! #define XORIGIN_LANDSCAPE 55 #define YORIGIN_PORTRAIT 10 /* page origin (should be at (0,0) */ #define YORIGIN_LANDSCAPE 11 *************** *** 51,56 #define XORIGIN 30 /* measured pixel coordinates of */ #define YORIGIN -15 /* page origin (should be at (0,0) */ /*********************************************************************** Define some useful shorthand macros for all required LaserJet Plus commands. With the exception of the CREATEFONT and DOWNLOADCHAR macros, --- 56,64 ----- #define XORIGIN_PORTRAIT 60 /* measured pixel coordinates of */ #define XORIGIN_LANDSCAPE 55 + #define YORIGIN_PORTRAIT 10 /* page origin (should be at (0,0) */ + #define YORIGIN_LANDSCAPE 11 + /*********************************************************************** Define some useful shorthand macros for all required LaserJet Plus commands. With the exception of the CREATEFONT and DOWNLOADCHAR macros, *************** *** 115,121 these do not permit negative values, so we have to further correct the origin with (XORIGIN, YORIGIN) defined above; these bias (lmargin, tmargin) set in dviinit(). */ ! #define RESET_PRINTER OUTS("\033E\033&lE\033&aL") /* Move relative by (delx,dely) from current point */ #define RMOVETO(delx,dely) {\ --- 123,129 ----- these do not permit negative values, so we have to further correct the origin with (XORIGIN, YORIGIN) defined above; these bias (lmargin, tmargin) set in dviinit(). */ ! #define RESET_PRINTER OUTS("") /* Move relative by (delx,dely) from current point */ #define RMOVETO(delx,dely) {\ *************** *** 185,190 #define UNDEFINED_FONT 65535 /* fonts are numbered 0,1,2,... */ /* In order to handle the MAXPAGEFONTS restriction, we keep a set of the fonts in use, accessing them with these two functions. If a later printer model increases MAXFONTS beyond 32, we can transparently change --- 193,201 ----- #define UNDEFINED_FONT 65535 /* fonts are numbered 0,1,2,... */ + #define SET_LANDSCAPE OUTS("\033&l1o0e0L") + #define SET_PORTRAIT OUTS("\033&l0o0e0L") + /* In order to handle the MAXPAGEFONTS restriction, we keep a set of the fonts in use, accessing them with these two functions. If a later printer model increases MAXFONTS beyond 32, we can transparently change *************** *** 216,221 rule_width = -1; str_ycp = -1; /* reset string y coordinate */ } #include "chargf.h" --- 227,237 ----- rule_width = -1; str_ycp = -1; /* reset string y coordinate */ + + if (landscape) + SET_LANDSCAPE; + else + SET_PORTRAIT; } #include "chargf.h" *************** *** 236,241 { RESET_PRINTER; /* printer reset */ DELETE_ALL_FONTS; /* delete all downloaded fonts */ font_count = 0; /* no font numbers are assigned yet */ font_switched = TRUE; } --- 252,267 ----- { RESET_PRINTER; /* printer reset */ DELETE_ALL_FONTS; /* delete all downloaded fonts */ + if (landscape) + { + XSIZE = XSIZE_LANDSCAPE; + YSIZE = YSIZE_LANDSCAPE; + } + else + { + XSIZE = XSIZE_PORTRAIT; + YSIZE = YSIZE_PORTRAIT; + } font_count = 0; /* no font numbers are assigned yet */ font_switched = TRUE; } *************** *** 337,342 { register struct char_entry *tcharptr; /* temporary char_entry pointer */ void (*charyy)(); /* subterfuge to get around PCC-20 bug */ if (fontptr != pfontptr) (void)openfont(fontptr->n); --- 363,374 ----- { register struct char_entry *tcharptr; /* temporary char_entry pointer */ void (*charyy)(); /* subterfuge to get around PCC-20 bug */ + UNSIGN32 nwords; /* how many 32-bit words we need */ + UNSIGN16 words_per_row; /* number of raster words per row */ + UNSIGN16 bytes_per_row; /* number of raster bytes per row */ + INT16 k,l; /* loop indexes */ + UNSIGN32 *p; /* pointer into raster */ + BYTE the_byte; /* unpacked raster byte */ if ((c < FIRSTPXLCHAR) || (LASTPXLCHAR < c)) /* check character range */ return; *************** *** 338,346 register struct char_entry *tcharptr; /* temporary char_entry pointer */ void (*charyy)(); /* subterfuge to get around PCC-20 bug */ ! if (fontptr != pfontptr) ! (void)openfont(fontptr->n); ! if (fontfp == (FILE *)NULL) /* do nothing if no font file */ return; tcharptr = &(fontptr->ch[c]); --- 370,376 ----- UNSIGN32 *p; /* pointer into raster */ BYTE the_byte; /* unpacked raster byte */ ! if ((c < FIRSTPXLCHAR) || (LASTPXLCHAR < c)) /* check character range */ return; tcharptr = &(fontptr->ch[c]); *************** *** 345,351 tcharptr = &(fontptr->ch[c]); ! moveto(hh - tcharptr->xoffp,YSIZE-vv+tcharptr->yoffp); MOVETO(xcp,ycp); BEGIN_RASTER_GRAPHICS; --- 375,384 ----- tcharptr = &(fontptr->ch[c]); ! if (!tcharptr->isloaded) ! { ! if (!VISIBLE(tcharptr)) /* check for empty character rasters */ ! return; nwords = (UNSIGN32)(((tcharptr->wp+31) >> 5) * (tcharptr->hp)); *************** *** 347,354 moveto(hh - tcharptr->xoffp,YSIZE-vv+tcharptr->yoffp); ! MOVETO(xcp,ycp); ! BEGIN_RASTER_GRAPHICS; /* Bug fix: PCC-20 otherwise jumps to charxx instead of *charxx */ charyy = fontptr->charxx; --- 380,386 ----- if (!VISIBLE(tcharptr)) /* check for empty character rasters */ return; ! nwords = (UNSIGN32)(((tcharptr->wp+31) >> 5) * (tcharptr->hp)); tcharptr->rasters = (UNSIGN32*)MALLOC((unsigned)(nwords*sizeof(UNSIGN32))); if (tcharptr->rasters == (UNSIGN32*)NULL) *************** *** 350,358 MOVETO(xcp,ycp); BEGIN_RASTER_GRAPHICS; ! /* Bug fix: PCC-20 otherwise jumps to charxx instead of *charxx */ ! charyy = fontptr->charxx; ! (void)(*charyy)(c,outraster); /* load rasters into device */ END_RASTER_GRAPHICS; str_ycp = -1; /* invalidate string y coordinate */ --- 382,397 ----- nwords = (UNSIGN32)(((tcharptr->wp+31) >> 5) * (tcharptr->hp)); ! tcharptr->rasters = (UNSIGN32*)MALLOC((unsigned)(nwords*sizeof(UNSIGN32))); ! if (tcharptr->rasters == (UNSIGN32*)NULL) ! { ! (void)sprintf(message,"loadbmap(): Could not allocate %ld words of \ ! raster space--used %ld words so far", ! (long)nwords,(long)cache_size); ! (void)fatal(message); ! } ! tcharptr->refcount = 0; /* clear reference count */ ! cache_size += (INT32)nwords; /* update cache size record */ if (fontptr != pfontptr) openfont(fontptr->n); *************** *** 354,359 charyy = fontptr->charxx; (void)(*charyy)(c,outraster); /* load rasters into device */ END_RASTER_GRAPHICS; str_ycp = -1; /* invalidate string y coordinate */ } --- 393,482 ----- tcharptr->refcount = 0; /* clear reference count */ cache_size += (INT32)nwords; /* update cache size record */ + if (fontptr != pfontptr) + openfont(fontptr->n); + + if (fontfp == (FILE *)NULL) /* do nothing if no font file */ + return; + + /* Bug workaround: PCC-20 jumps to charxx instead of *charxx */ + charyy = fontptr->charxx; + (void)(*charyy)(c,outrow); /* load character from font file */ + + (void)clearerr(plotfp); + + tcharptr->isloaded = TRUE; + } + + words_per_row = (UNSIGN16)(tcharptr->wp + 31) >> 5; + if (landscape) + { + bytes_per_row = (UNSIGN16)((tcharptr->hp) + 7) >> 3; /* wp div 8 */ + moveto(hh+(tcharptr->wp-tcharptr->xoffp),YSIZE-vv+tcharptr->yoffp); + + MOVETO(xcp,ycp); + BEGIN_RASTER_GRAPHICS; + + /* Send out the raster - sideways! */ + for (k = tcharptr->wp; --k >= 0; ) + { + TRANSFER_RASTER_GRAPHICS(bytes_per_row); + the_byte = 0; + for (l = 0; l < tcharptr->hp; ++l ) + { + the_byte <<= 1; + the_byte |= ((tcharptr->rasters + l*words_per_row)[k / 32] >> + (31 - (k % 32))) & 01; + if ( (l % 8) == 7 ) + { + OUTC(the_byte); + the_byte = 0; + } + } + if ( l % 8 ) + { + the_byte <<= 8 - (l % 8); + OUTC(the_byte); + } + } + } + else + { + moveto(hh - tcharptr->xoffp,YSIZE-vv+tcharptr->yoffp); + + MOVETO(xcp,ycp); + BEGIN_RASTER_GRAPHICS; + + bytes_per_row = (UNSIGN16)((tcharptr->wp) + 7) >> 3; /* wp div 8 */ + for (k = 0; k < tcharptr->hp; ++k) + { + TRANSFER_RASTER_GRAPHICS(bytes_per_row); + p = tcharptr->rasters + k*words_per_row; + for (l = bytes_per_row; l > 0; ++p) + { + the_byte = (BYTE)((*p) >> 24); + OUTC(the_byte); + if ((--l) <= 0) + break; + + the_byte = (BYTE)((*p) >> 16); + OUTC(the_byte); + if ((--l) <= 0) + break; + + the_byte = (BYTE)((*p) >> 8); + OUTC(the_byte); + if ((--l) <= 0) + break; + + the_byte = (BYTE)(*p); + OUTC(the_byte); + if ((--l) <= 0) + break; + } + } + } + END_RASTER_GRAPHICS; str_ycp = -1; /* invalidate string y coordinate */ } *************** *** 368,375 register BYTE c; { void (*charyy)(); /* subterfuge to get around PCC-20 bug */ ! register struct char_entry *tcharptr; /* temporary char_entry pointer */ ! COORDINATE nbytes; /* number of bytes per row */ float temp; INT16 ntemp; --- 491,502 ----- register BYTE c; { void (*charyy)(); /* subterfuge to get around PCC-20 bug */ ! register UNSIGN32 nwords; /* how many 32-bit words we need */ ! register struct char_entry *tcharptr; ! COORDINATE nbytes; /* number of bytes per row */ ! UNSIGN16 words_per_row; /* number of raster words per row */ ! UNSIGN16 bytes_per_row; /* number of raster bytes per row */ ! INT16 k,l; /* loop indexes */ float temp; INT16 ntemp; UNSIGN32 *p; /* pointer into raster */ *************** *** 372,377 COORDINATE nbytes; /* number of bytes per row */ float temp; INT16 ntemp; if ((c < FIRSTPXLCHAR) || (LASTPXLCHAR < c)) /* check character range */ return; --- 499,506 ----- INT16 k,l; /* loop indexes */ float temp; INT16 ntemp; + UNSIGN32 *p; /* pointer into raster */ + BYTE the_byte; /* unpacked raster byte */ if ((c < FIRSTPXLCHAR) || (LASTPXLCHAR < c)) /* check character range */ return; *************** *** 378,385 tcharptr = &(fontptr->ch[c]); ! if (!VISIBLE(tcharptr)) ! return; /* do nothing for invisible fonts */ if (fontptr != pfontptr) openfont(fontptr->n); --- 507,514 ----- tcharptr = &(fontptr->ch[c]); ! if (!VISIBLE(tcharptr)) /* check for empty character rasters */ ! return; nwords = (UNSIGN32)(((tcharptr->wp+31) >> 5) * (tcharptr->hp)); *************** *** 381,386 if (!VISIBLE(tcharptr)) return; /* do nothing for invisible fonts */ if (fontptr != pfontptr) openfont(fontptr->n); --- 510,528 ----- if (!VISIBLE(tcharptr)) /* check for empty character rasters */ return; + nwords = (UNSIGN32)(((tcharptr->wp+31) >> 5) * (tcharptr->hp)); + + tcharptr->rasters = (UNSIGN32*)MALLOC((unsigned)(nwords*sizeof(UNSIGN32))); + if (tcharptr->rasters == (UNSIGN32*)NULL) + { + (void)sprintf(message,"loadchar(): Could not allocate %ld words of \ + raster space--used %ld words so far", + (long)nwords,(long)cache_size); + (void)fatal(message); + } + tcharptr->refcount = 0; /* clear reference count */ + cache_size += (INT32)nwords; /* update cache size record */ + if (fontptr != pfontptr) openfont(fontptr->n); *************** *** 387,392 if (fontfp == (FILE *)NULL) /* do nothing if no font file */ return; (void)clearerr(plotfp); tcharptr->isloaded = TRUE; --- 529,538 ----- if (fontfp == (FILE *)NULL) /* do nothing if no font file */ return; + /* Bug workaround: PCC-20 otherwise jumps to charxx instead of *charxx */ + charyy = fontptr->charxx; + (void)(*charyy)(c,outrow); /* load character from font file */ + (void)clearerr(plotfp); tcharptr->isloaded = TRUE; *************** *** 397,404 /* limits. Large characters really need to be handled as bitmaps */ /* instead of as downloaded characters. */ ! nbytes = ((tcharptr->wp) + 7) >> 3; /* wp div 8 */ ! DOWNLOAD_CHARACTER(MIN(16,nbytes)*MIN(255,(tcharptr->hp))); OUTC(4); /* 4 0 14 1 is fixed sequence */ OUTC(0); --- 543,558 ----- /* limits. Large characters really need to be handled as bitmaps */ /* instead of as downloaded characters. */ ! if (landscape) ! { ! nbytes = ((tcharptr->hp) + 7) >> 3; /* hp div 8 */ ! DOWNLOAD_CHARACTER(MIN(16,nbytes)*MIN(255,(tcharptr->wp))); ! } ! else ! { ! nbytes = ((tcharptr->wp) + 7) >> 3; /* wp div 8 */ ! DOWNLOAD_CHARACTER(MIN(16,nbytes)*MIN(255,(tcharptr->hp))); ! } OUTC(4); /* 4 0 14 1 is fixed sequence */ OUTC(0); *************** *** 406,412 OUTC(14); OUTC(1); ! OUTC(0); /* orientation = 0 ==> portrait */ OUTC(0); /* Apologies for the temporary variables; the Sun OS 3.2 cc could --- 560,570 ----- OUTC(14); OUTC(1); ! if (landscape) ! OUTC(1); /* orientation = 1 ==> landscape */ ! else ! OUTC(0); /* 0 ==> portrait */ ! OUTC(0); words_per_row = (UNSIGN16)(tcharptr->wp + 31) >> 5; *************** *** 409,414 OUTC(0); /* orientation = 0 ==> portrait */ OUTC(0); /* Apologies for the temporary variables; the Sun OS 3.2 cc could not compile the original expressions. */ ntemp = MIN(-(tcharptr->xoffp),127); --- 567,573 ----- OUTC(0); + words_per_row = (UNSIGN16)(tcharptr->wp + 31) >> 5; /* Apologies for the temporary variables; the Sun OS 3.2 cc could not compile the original expressions. */ if (landscape) *************** *** 411,430 /* Apologies for the temporary variables; the Sun OS 3.2 cc could not compile the original expressions. */ ! ntemp = MIN(-(tcharptr->xoffp),127); ! ntemp = MAX(-128,ntemp); ! OUT16(ntemp); ! ntemp = MIN(tcharptr->yoffp,127); ! ntemp = MAX(-128,ntemp); ! OUT16(ntemp); ! ntemp = MIN(128,tcharptr->wp); ! OUT16(ntemp); ! ntemp = MIN(255,tcharptr->hp); ! OUT16(ntemp); ! temp = (float)(tcharptr->tfmw); ! temp = 4.0*temp*conv; ! ntemp = ROUND(temp); ! OUT16(ntemp); /* delta x to nearest 1/4 dot */ /* Bug fix: PCC-20 otherwise jumps to charxx instead of *charxx */ charyy = fontptr->charxx; --- 570,591 ----- words_per_row = (UNSIGN16)(tcharptr->wp + 31) >> 5; /* Apologies for the temporary variables; the Sun OS 3.2 cc could not compile the original expressions. */ ! if (landscape) ! { ! ntemp = MIN(-(tcharptr->yoffp),127); ! ntemp = MAX(-128,ntemp); ! OUT16(ntemp); ! ntemp = MIN((tcharptr->wp - tcharptr->xoffp) - 1,127); ! ntemp = MAX(-128,ntemp); ! OUT16(ntemp); ! ntemp = MIN(255,tcharptr->hp); ! OUT16(ntemp); ! ntemp = MIN(128,tcharptr->wp); ! OUT16(ntemp); ! temp = (float)(tcharptr->tfmw); ! temp = 4.0*temp*conv; ! ntemp = ROUND(temp); ! OUT16(ntemp); /* delta x to nearest 1/4 dot */ bytes_per_row = (UNSIGN16)((tcharptr->hp) + 7) >> 3; /* wp div 8 */ bytes_per_row = MIN(16,bytes_per_row); /* limited to 128 bits/row */ *************** *** 426,434 ntemp = ROUND(temp); OUT16(ntemp); /* delta x to nearest 1/4 dot */ ! /* Bug fix: PCC-20 otherwise jumps to charxx instead of *charxx */ ! charyy = fontptr->charxx; ! (void)(*charyy)(c,outrow); /* output rasters */ if (DISKFULL(plotfp)) (void)fatal("loadchar(): Output error -- disk storage probably full"); --- 587,631 ----- ntemp = ROUND(temp); OUT16(ntemp); /* delta x to nearest 1/4 dot */ ! bytes_per_row = (UNSIGN16)((tcharptr->hp) + 7) >> 3; /* wp div 8 */ ! bytes_per_row = MIN(16,bytes_per_row); /* limited to 128 bits/row */ ! for (k = tcharptr->wp; --k >= 0; ) ! { ! the_byte = 0; ! for (l = 0; l < tcharptr->hp; ++l ) ! { ! the_byte <<= 1; ! the_byte |= ((tcharptr->rasters + l*words_per_row)[k / 32] >> ! (31 - (k % 32))) & 01; ! if ( (l % 8) == 7 ) ! { ! OUTC(the_byte); ! the_byte = 0; ! } ! } ! if ( l % 8 ) ! { ! the_byte <<= 8 - (l % 8); ! OUTC(the_byte); ! } ! } ! } ! else ! { ! ntemp = MIN(-(tcharptr->xoffp),127); ! ntemp = MAX(-128,ntemp); ! OUT16(ntemp); ! ntemp = MIN(tcharptr->yoffp,127); ! ntemp = MAX(-128,ntemp); ! OUT16(ntemp); ! ntemp = MIN(128,tcharptr->wp); ! OUT16(ntemp); ! ntemp = MIN(255,tcharptr->hp); ! OUT16(ntemp); ! temp = (float)(tcharptr->tfmw); ! temp = 4.0*temp*conv; ! ntemp = ROUND(temp); ! OUT16(ntemp); /* delta x to nearest 1/4 dot */ bytes_per_row = (UNSIGN16)((tcharptr->wp) + 7) >> 3; /* wp div 8 */ bytes_per_row = MIN(16,bytes_per_row); /* limited to 128 bits/row */ *************** *** 430,435 charyy = fontptr->charxx; (void)(*charyy)(c,outrow); /* output rasters */ if (DISKFULL(plotfp)) (void)fatal("loadchar(): Output error -- disk storage probably full"); } --- 627,665 ----- ntemp = ROUND(temp); OUT16(ntemp); /* delta x to nearest 1/4 dot */ + bytes_per_row = (UNSIGN16)((tcharptr->wp) + 7) >> 3; /* wp div 8 */ + bytes_per_row = MIN(16,bytes_per_row); /* limited to 128 bits/row */ + for (k = 0; k < tcharptr->hp; ++k) + { + p = tcharptr->rasters + k*words_per_row; + for (l = bytes_per_row; l > 0; ++p) + { + the_byte = (BYTE)((*p) >> 24); + OUTC(the_byte); + if ((--l) <= 0) + break; + + the_byte = (BYTE)((*p) >> 16); + OUTC(the_byte); + if ((--l) <= 0) + break; + + the_byte = (BYTE)((*p) >> 8); + OUTC(the_byte); + if ((--l) <= 0) + break; + + the_byte = (BYTE)(*p); + OUTC(the_byte); + if ((--l) <= 0) + break; + } + } + } + + free((char *)tcharptr->rasters); /* We don't need it any more */ + tcharptr->rasters = (UNSIGN32*)NULL; + if (DISKFULL(plotfp)) (void)fatal("loadchar(): Output error -- disk storage probably full"); } *************** *** 636,642 OUT16(cell_height); /* cell height */ ! OUTC(0); /* orientation = 0 ==> portrait */ OUTC(1); /* spacing = 1 ==> proportional */ OUT16(0); /* symbol set (arbitrary) */ --- 866,875 ----- OUT16(cell_height); /* cell height */ ! if (landscape) ! OUTC(1); /* orientation = 1 ==> landscape */ ! else ! OUTC(0); /* 1 ==> portrait */ OUTC(1); /* spacing = 1 ==> proportional */ OUT16(0); /* symbol set (arbitrary) */ *************** *** 692,792 #include "nosignex.h" #include "openfont.h" #include "option.h" ! ! /*-->outraster*/ ! /**********************************************************************/ ! /***************************** outraster ******************************/ ! /**********************************************************************/ ! ! void ! outraster(c,yoff)/* print single raster line in bitmap graphics mode */ ! BYTE c; /* current character value */ ! UNSIGN16 yoff; /* offset from top row (0,1,...,hp-1) */ ! { ! UNSIGN16 bytes_per_row; /* number of raster bytes to copy */ ! register UNSIGN16 k; /* loop index */ ! register UNSIGN32 *p; /* pointer into img_row[] */ ! struct char_entry *tcharptr;/* temporary char_entry pointer */ ! register BYTE the_byte; /* unpacked raster byte */ ! ! tcharptr = &(fontptr->ch[c]);/* assume check for valid c has been done */ ! bytes_per_row = (UNSIGN16)((tcharptr->wp) + 7) >> 3; /* wp div 8 */ ! p = img_row; /* we step pointer p along img_row[] */ ! ! TRANSFER_RASTER_GRAPHICS(bytes_per_row); ! ! for (k = bytes_per_row; k > 0; ++p) ! { ! the_byte = (BYTE)((*p) >> 24); ! OUTC(the_byte); ! if ((--k) <= 0) ! break; ! ! the_byte = (BYTE)((*p) >> 16); ! OUTC(the_byte); ! if ((--k) <= 0) ! break; ! ! the_byte = (BYTE)((*p) >> 8); ! OUTC(the_byte); ! if ((--k) <= 0) ! break; ! ! the_byte = (BYTE)(*p); ! OUTC(the_byte); ! if ((--k) <= 0) ! break; ! } ! } ! ! /*-->outrow*/ ! /**********************************************************************/ ! /******************************* outrow *******************************/ ! /**********************************************************************/ ! ! void ! outrow(c,yoff) /* copy img_row[] into rasters[] if allocated, else no-op */ ! BYTE c; /* current character value */ ! UNSIGN16 yoff; /* offset from top row (0,1,...,hp-1) */ ! { ! UNSIGN16 bytes_per_row; /* number of raster bytes to copy */ ! register UNSIGN16 k; /* loop index */ ! register UNSIGN32 *p; /* pointer into img_row[] */ ! struct char_entry *tcharptr;/* temporary char_entry pointer */ ! register BYTE the_byte; /* unpacked raster byte */ ! ! if (yoff > 255) /* LaserJet Plus cannot handle big characters */ ! return; ! ! tcharptr = &(fontptr->ch[c]);/* assume check for valid c has been done */ ! bytes_per_row = (UNSIGN16)((tcharptr->wp) + 7) >> 3; /* wp div 8 */ ! bytes_per_row = MIN(16,bytes_per_row); /* limited to 128 bits/row */ ! p = img_row; /* we step pointer p along img_row[] */ ! ! for (k = bytes_per_row; k > 0; ++p) ! { ! the_byte = (BYTE)((*p) >> 24); ! OUTC(the_byte); ! if ((--k) <= 0) ! break; ! ! the_byte = (BYTE)((*p) >> 16); ! OUTC(the_byte); ! if ((--k) <= 0) ! break; ! ! the_byte = (BYTE)((*p) >> 8); ! OUTC(the_byte); ! if ((--k) <= 0) ! break; ! ! the_byte = (BYTE)(*p); ! OUTC(the_byte); ! if ((--k) <= 0) ! break; ! } ! } ! #include "prtpage.h" #include "readfont.h" #include "readgf.h" --- 925,931 ----- #include "nosignex.h" #include "openfont.h" #include "option.h" ! #include "outrow.h" #include "prtpage.h" #include "readfont.h" #include "readgf.h" *** ORIG_SRCS/dviinit.h Thu Feb 11 14:57:04 1988 --- dviinit.h Tue Feb 9 16:15:22 1988 *************** *** 355,360 #if (CANON_A2 | IMPRESS | HPJETPLUS) /* Printer has (0,0) origin at (XORIGIN,YORIGIN) near, but not at, upper left corner */ lmargin -= XORIGIN; tmargin -= YORIGIN; #endif /* (CANON_A2 | IMPRESS | HPJETPLUS) */ --- 355,364 ----- #if (CANON_A2 | IMPRESS | HPJETPLUS) /* Printer has (0,0) origin at (XORIGIN,YORIGIN) near, but not at, upper left corner */ + #if HPJETPLUS + lmargin -= landscape ? XORIGIN_LANDSCAPE : XORIGIN_PORTRAIT; + tmargin -= landscape ? YORIGIN_LANDSCAPE : YORIGIN_PORTRAIT; + #else lmargin -= XORIGIN; tmargin -= YORIGIN; #endif *************** *** 357,362 upper left corner */ lmargin -= XORIGIN; tmargin -= YORIGIN; #endif /* (CANON_A2 | IMPRESS | HPJETPLUS) */ if ((BYTE)nosignex(dvifp,(BYTE)1) != PRE) --- 361,367 ----- #else lmargin -= XORIGIN; tmargin -= YORIGIN; + #endif #endif /* (CANON_A2 | IMPRESS | HPJETPLUS) */ if ((BYTE)nosignex(dvifp,(BYTE)1) != PRE) *** ORIG_SRCS/gblvars.h Thu Feb 11 14:57:19 1988 --- gblvars.h Sat Mar 5 12:47:53 1988 *************** *** 198,203 INT16 hpres; /* output resolution (75, 100, 150, 300 dpi) */ #endif /* HPLASERJET */ UNSIGN32 img_mask[32]; /* initialized at run-time so that bit k */ /* (counting from high end) is one */ UNSIGN32 img_row[(MAX_M - MIN_M + 1 + 31) >> 5]; --- 198,207 ----- INT16 hpres; /* output resolution (75, 100, 150, 300 dpi) */ #endif /* HPLASERJET */ + #if HPJETPLUS + BOOLEAN landscape = FALSE; /* landscape mode the the HP LaserJet Plus */ + #endif + UNSIGN32 img_mask[32]; /* initialized at run-time so that bit k */ /* (counting from high end) is one */ UNSIGN32 img_row[(MAX_M - MIN_M + 1 + 31) >> 5]; *** ORIG_SRCS/machdefs.h Thu Feb 11 14:57:30 1988 --- machdefs.h Thu Feb 11 12:54:45 1988 *************** *** 119,125 compile time. ***********************************************************************/ ! #define ALLOW_INTERRUPT 0 #define ANSI_PROTOTYPES 0 #ifndef ANSI_LIBRARY /* may be specified at compile time */ --- 119,125 ----- compile time. ***********************************************************************/ ! #define ALLOW_INTERRUPT 1 #define ANSI_PROTOTYPES 0 #ifndef ANSI_LIBRARY /* may be specified at compile time */ *************** *** 134,140 #define ARITHRSHIFT 1 /* most C compilers use arithmetic right shift */ #define DISKFULL(fp) (ferror(fp) && (errno == ENOSPC)) #define DVIEXT ".dvi" ! #define DVIPREFIX "dvi-" #define EXIT exit #define FASTZERO 0 --- 134,140 ----- #define ARITHRSHIFT 1 /* most C compilers use arithmetic right shift */ #define DISKFULL(fp) (ferror(fp) && (errno == ENOSPC)) #define DVIEXT ".dvi" ! #define DVIPREFIX "" #define EXIT exit #define FASTZERO 0 *************** *** 248,253 macro redefinition warning messages. ***********************************************************************/ /*==================== #undef PCC_20 #undef OS_TOPS20 --- 248,258 ----- macro redefinition warning messages. ***********************************************************************/ + #undef HPUX + #undef OS_UNIX + #define HPUX 1 + #define OS_UNIX 1 + /*==================== #undef PCC_20 #undef OS_TOPS20 *************** *** 274,280 #define OS_PCDOS 1 ====================*/ ! #undef IBM_PC_MICROSOFT #undef OS_PCDOS #define IBM_PC_MICROSOFT 1 --- 279,285 ----- #define OS_PCDOS 1 ====================*/ ! /*==================== #undef IBM_PC_MICROSOFT #undef OS_PCDOS #define IBM_PC_MICROSOFT 1 *************** *** 279,284 #undef OS_PCDOS #define IBM_PC_MICROSOFT 1 #define OS_PCDOS 1 /*==================== --- 284,290 ----- #undef OS_PCDOS #define IBM_PC_MICROSOFT 1 #define OS_PCDOS 1 + ====================*/ /*==================== #undef IBM_PC_WIZARD *************** *** 280,286 #define IBM_PC_MICROSOFT 1 #define OS_PCDOS 1 - /*==================== #undef IBM_PC_WIZARD #undef OS_PCDOS --- 286,291 ----- #define OS_PCDOS 1 ====================*/ /*==================== #undef IBM_PC_WIZARD #undef OS_PCDOS *************** *** 682,687 #if OS_UNIX #undef BSD42 #define BSD42 1 /* want DVISPOOL code in dviterm.h */ --- 687,694 ----- #if OS_UNIX + #if HPUX + #else #undef BSD42 #define BSD42 1 /* want DVISPOOL code in dviterm.h */ #endif *************** *** 684,689 #undef BSD42 #define BSD42 1 /* want DVISPOOL code in dviterm.h */ #define DVIHELP "man dvi\nor\napropos dvi" --- 691,697 ----- #else #undef BSD42 #define BSD42 1 /* want DVISPOOL code in dviterm.h */ + #endif #if HPUX #define DVIHELP "man dvi" *************** *** 685,690 #undef BSD42 #define BSD42 1 /* want DVISPOOL code in dviterm.h */ #define DVIHELP "man dvi\nor\napropos dvi" #ifdef FONTLIST /* can be set at compile time */ --- 693,701 ----- #define BSD42 1 /* want DVISPOOL code in dviterm.h */ #endif + #if HPUX + #define DVIHELP "man dvi" + #else #define DVIHELP "man dvi\nor\napropos dvi" #endif *************** *** 686,691 #define BSD42 1 /* want DVISPOOL code in dviterm.h */ #define DVIHELP "man dvi\nor\napropos dvi" #ifdef FONTLIST /* can be set at compile time */ #else --- 697,703 ----- #define DVIHELP "man dvi" #else #define DVIHELP "man dvi\nor\napropos dvi" + #endif #ifdef FONTLIST /* can be set at compile time */ #else *** ORIG_SRCS/option.h Thu Feb 11 14:57:34 1988 --- option.h Tue Feb 9 15:21:33 1988 *************** *** 112,117 #endif case 'l': /* l prohibits logging of errors */ case 'L': g_dolog = FALSE; --- 112,126 ----- #endif + + #if HPJETPLUS + case 'j': /* j means Jules option for landscape - HP LaserJet+ only */ + case 'J': + landscape = TRUE; + break; + #endif + + case 'l': /* l prohibits logging of errors */ case 'L': g_dolog = FALSE; *** ORIG_SRCS/readpost.h Thu Feb 11 14:57:38 1988 --- readpost.h Thu Feb 11 14:18:30 1988 *************** *** 44,50 if (!quiet) { ! (void)fprintf(stderr,"[%d pages]",the_page_count); NEWLINE(stderr); (void)fprintf(stderr,"[%d magnification]",(int)runmag); --- 44,51 ----- if (!quiet) { ! (void)fprintf(stderr,"[%d page%s]",the_page_count, ! the_page_count == 1 ? "" : "s"); NEWLINE(stderr); (void)fprintf(stderr,"[%d magnification]",(int)runmag); *** ORIG_SRCS/readpxl.h Thu Feb 11 14:57:38 1988 --- readpxl.h Fri Feb 12 13:42:52 1988 *************** *** 52,57 return(EOF); } for (the_char = FIRSTPXLCHAR; the_char <= LASTPXLCHAR; the_char++) { tcharptr = &(fontptr->ch[the_char]); --- 52,58 ----- return(EOF); } + #if 0 for (the_char = FIRSTPXLCHAR; the_char <= LASTPXLCHAR; the_char++) #else for (the_char = FIRSTPXLCHAR; the_char <= 127; the_char++) *************** *** 53,58 } for (the_char = FIRSTPXLCHAR; the_char <= LASTPXLCHAR; the_char++) { tcharptr = &(fontptr->ch[the_char]); tcharptr->wp = (COORDINATE)nosignex(fontfp,(BYTE)2); --- 54,62 ----- #if 0 for (the_char = FIRSTPXLCHAR; the_char <= LASTPXLCHAR; the_char++) + #else + for (the_char = FIRSTPXLCHAR; the_char <= 127; the_char++) + #endif { tcharptr = &(fontptr->ch[the_char]); tcharptr->wp = (COORDINATE)nosignex(fontfp,(BYTE)2); *** ORIG_SRCS/usage.h Thu Feb 11 14:57:51 1988 --- usage.h Tue Feb 9 15:53:47 1988 *************** *** 50,55 g_progname); #endif /* HPLASERJET */ #if POSTSCRIPT (void)sprintf(message, "Usage: %s {-a} {-b} {-c#} {-d#} {-eENVNAME=value} {-ffontsubfile} \ --- 50,62 ----- g_progname); #endif /* HPLASERJET */ + #if HPJETPLUS + (void)sprintf(message, + "Usage: %s {-a} {-b} {-c#} {-d#} {-eENVNAME=value} {-ffontsubfile} \ + {-j} {-l} {-m#} {-o#:#:#} {-o#:#} {-o#} {-p} {-x#{units}} {-y#{units}} \ + dvifile(s)", g_progname); + #endif /* HPJETPLUS */ + #if POSTSCRIPT (void)sprintf(message, "Usage: %s {-a} {-b} {-c#} {-d#} {-eENVNAME=value} {-ffontsubfile} \ From "Matthew Self " Wed Oct 12 19:36:18 1988 Flags: 000000000005 Return-Path: Received: from bayes.arc.nasa.gov ([128.102.112.2].#Internet) by SCIENCE.UTAH.EDU with TCP; Wed 12 Oct 88 19:36:15-MDT Received: Wed, 12 Oct 88 18:36:32 PDT by bayes.arc.nasa.gov (5.59/1.6) Date: Wed, 12 Oct 88 18:36:32 PDT From: Matthew Self Message-Id: <8810130136.AA01614@bayes.arc.nasa.gov> To: beebe@science.utah.edu Subject: Sun bitmap /special support for dvijep Nelson, Here are the diffs for my Sun bitmap /special support, which I said I would mail you some months ago.... The patch is crude, but effective. It expects /special commands to be of the form "/special{bitmap }. Really this should also specify the bitmap format (Sun's), and permit magnification by 2, 3, or 4 if desired. Be warned that the patch will compile only on Sun's (it #includes ), so some #ifdefs are probably in order before wider circulation is appropriate. Also, this pach may be applied either before or after the landscape diffs you sent me. On a more general note, it would be nice if general bitmap support were available in all of the drivers. Printing bitmaps is largely device independent, being only resolution dependent, and bitmap format dependent. I think it would be possible to add bitmap support for most of the drivers, and support for many different bitmap formats (X11, X10, Sun bitmap, Sun icon, Sun pointer, ...) in all of them. This way a file which includes a bitmap which prints nicely on some 300dpi device ought to print nicely on any 300dpi device. This is much better than no portability! Also, it might be best for the /special command to indicate the desired resolution (in bpi or something), so the driver could scale the image to guarantee it comes out no larger than expected, if possible. A bitmap which works on a low resolution printer will come out no less than half as small on a printer with higher resolution in the worst case. Of course, bitmaps prepared for high resolution cannot be printed reasonably on lower resolution devices (you can't have everything!). These are my ideas, but has Tug discussed this idea already? Are there any concrete plans? My main suggestion is that the /special command include the following information at a minimum: (1) The word bitmap or some other word distinguishing these commands from any non-bitmap commands. (2) The desired orientation of the bitmap on the page. (3) The desired resolution of the bitmap. (4) The bitmap file-spec. (5) The format of the bitmap file. To print landscape bitmaps may require the driver to translate the bitmap from a row based bitmap format to a column based printer format (e.g. for HP laserjet+), but the drivers already have to deal with this on a small scale for most dot-matrix printers.... So much for bitmaps. I have a couple other dvi projects on the back burner which I'd like to ask you about. I intend to write a /special command which simply informs the driver of the desired page size and orientation. That way, a user can just say lpr foo.dvi and it will come out right even if he has forgotten that it is a landscape file. I believe this was also a subject discussed by Tug. If so, did they reach a consensus on how this should be done? I was planning on simply using /special{landscape} or a /special{legal} at the beginning of the dvi file, or something like that. The driver could search for these before processing the page. This would be especially nice for printers which have multiple paper trays and can thus switch without interupting print service. These may become more common in the future as laser printers are used more widely (I hope). If I haven't touched on enough thorny issues yet, how about color? We have a Mitsubishi G650 (we had a G500) which is a 300dpi color printer (the G500 is 240 dpi). It uses thermal transfer from a colored sheet, and has cyan, magenta, yellow and black sheets the G500 doesn't have black, but makes by dark purple by using the other three). It makes 4 passes to print, but the registration is excellent. It can also print directly on transparencies. I intend to write a driver for it for black and white only in the next week or so (it should be easy since it just wants a big bitmap), but soon I hope to write a color driver for it. My plan is to modify SliTeX to generate only one dvi file, bit to include /special commands to select one of the 6 colors or black. This will require rather extensive modification of teh driver software, since I will need to keep track of four bitmaps, and write characters into one or more of them. Then the four bitmaps will be dumped to the printer much like usual. I would appreciate any advice on how to reorganize the driver software to incorporate these changes. The result should be very nice. You will be able to run slitex and generate color transparencies with no further effort. Is this another issue Tug has discussed? Again, if a plan was made, I would like to conform. That's all of my projects, so that's the end of the hard questions. Thanks for any help/advice you can offer.... Matthew Self NASA Ames Research Center self@bayes.arc.nasa.gov From "Matthew Self " Wed Oct 12 19:42:27 1988 Flags: 000000000005 Return-Path: Received: from bayes.arc.nasa.gov ([128.102.112.2].#Internet) by SCIENCE.UTAH.EDU with TCP; Wed 12 Oct 88 19:42:22-MDT Received: Wed, 12 Oct 88 18:42:38 PDT by bayes.arc.nasa.gov (5.59/1.6) Date: Wed, 12 Oct 88 18:42:38 PDT From: Matthew Self Message-Id: <8810130142.AA01628@bayes.arc.nasa.gov> To: beebe@science.utah.edu Subject: argggh, I can't type. Date: Wed, 12 Oct 88 18:37:40 PDT From: Mail Delivery Subsystem Subject: Returned mail: Host unknown To: self ----- Transcript of session follows ----- 550 beebe@science.uatah.edu... Host unknown ----- Unsent message follows ----- Received: Wed, 12 Oct 88 18:37:40 PDT by bayes.arc.nasa.gov (5.59/1.6) Date: Wed, 12 Oct 88 18:37:40 PDT From: Matthew Self Message-Id: <8810130137.AA01619@bayes.arc.nasa.gov> To: beebe@science.uatah.edu Subject: I always manage to forget something! *** dvijep.c.orig Wed Apr 27 17:13:59 1988 --- dvijep.c Thu May 12 22:30:58 1988 *************** *** 147,152 **** --- 147,158 ---- OUTF("\033*p+%dY",-(dely));\ } + /* Push the current cursor position onto the stack */ + #define PUSH_CURSOR_POSITION OUTS("\033&f0S") + + /* Pop the current cursor position from the stack */ + #define POP_CURSOR_POSITION OUTS("\033&f1S") + /* Round a POSITIVE floating-point value to the nearest integer */ #define ROUND(x) ((int)(x + 0.5)) *************** *** 1110,1116 **** #include "skgfspec.h" #include "skipfont.h" #include "skpkspec.h" - #include "special.h" #include "strchr.h" #include "strcm2.h" #include "strid2.h" --- 1116,1121 ---- *************** *** 1118,1120 **** --- 1123,1291 ---- #include "tctos.h" #include "usage.h" #include "warning.h" + + /*-->special*/ + /**********************************************************************/ + /****************************** special *******************************/ + /**********************************************************************/ + + /*********************************************************************** + This driver now provides support for Sun rasterfile format bibtmaps. + + This code was written by Matthew Self on May 11, 1988. It represents + a merger of Tom Vijlbrief's "prraster" program which was obtained from + the Sun-spots archives on titan.rice.edu and Nelson Beebe's "dvialw" + which provides support for postscript \special commands. To the best + of my knowledge, both the original programs may be freely redistributed, + and my work is not copyrighted and may be freely redistributed. Enjoy. + + Matthew Self + NASA Ames Research Center + self@pluto.arc.nasa.gov + + The original header from prraster.c is reproduced below: + + + This filter converts Sun rasterfile to a format which + can be printed on HP printer and the HP laserjet + + Tom Vijlbrief, Dec 1987 (cogpsi!tom@mcvax.cwi.nl or uunet!mcvax!cogpsi!tom) + + ***********************************************************************/ + + #include /* This will only compile on Suns! */ + + void + special(s) /* process TeX \special{} string in s[] */ + register char *s; + { + char line[MAXLINE+2]; + FILE *specfile; + struct rasterfile header; + INT16 k; + int i; + int n_lines; + int n_bytes; + int l_res = 300; + + /*********************************************************************** + The TeX \special{} command is expected to look like + + \special{bitmap } + + ***********************************************************************/ + + clearerr(plotfp); /* VMS sets the error flag unexpectedly */ + + if ((strncmp("bitmap ",s,7) == 0)) + { + k = 7; + } + else + { + NEWLINE(stderr); + (void)fprintf(stderr, + "[TeX \\special{%s} not implemented in this driver]",s); + NEWLINE(stderr); + (void)fprintf(stderr, + "Expected \\special{bitmap }"); + NEWLINE(stderr); + (void)fprintf(stderr, + "\\special{%s} request ignored",s); + NEWLINE(stderr); + (void)fprintf(stderr, + "Current TeX page counters: [%s]",tctos()); + NEWLINE(stderr); + return; + } + specfile = fopen(&s[k],"r"); + DEBUG_OPEN(specfile,&s[k],"r"); + if (specfile == (FILE *) NULL) + { + NEWLINE(stderr); + (void)fprintf(stderr, + "Open failure on \\special file [%s]",&s[k]); + NEWLINE(stderr); + (void)fprintf(stderr,"\\special{%s} request ignored",s); + NEWLINE(stderr); + (void)fprintf(stderr,"Current TeX page counters: [%s]",tctos()); + NEWLINE(stderr); + return; + } + + (void)REWIND(specfile); /* rewind file */ + + if ((fread(&header, sizeof(header), 1, specfile) != 1) || + (header.ras_magic != 0x59a66a95)) + { + NEWLINE(stderr); + (void)fprintf(stderr, + "\\special file [%s] is not a valid Sun rasterfile", &s[k]); + NEWLINE(stderr); + (void)fprintf(stderr,"\\special{%s} request ignored",s); + NEWLINE(stderr); + (void)fprintf(stderr,"Current TeX page counters: [%s]",tctos()); + NEWLINE(stderr); + return; + } + if ((header.ras_depth > 1) || + (header.ras_maplength > 0) && + (header.ras_maptype != RMT_NONE)) + { + NEWLINE(stderr); + (void)fprintf(stderr, + "\\special file [%s] is not a binary rasterfile", &s[k]); + NEWLINE(stderr); + (void)fprintf(stderr,"\\special{%s} request ignored",s); + NEWLINE(stderr); + (void)fprintf(stderr,"Current TeX page counters: [%s]",tctos()); + NEWLINE(stderr); + return; + } + + if (((n_bytes = (header.ras_width + 7) / 8)) & 1) + n_bytes++; /* even number of bytes */ + + NEWLINE(stderr); + (void)fprintf(stderr,"\t[\\special{%s}] ",s); + NEWLINE(stderr); + + PUSH_CURSOR_POSITION; /* Here we go! */ + + BEGIN_RASTER_GRAPHICS; + + for (n_lines = header.ras_height; + (--n_lines >= 0) && fread(line, n_bytes, 1, specfile);) + { + TRANSFER_RASTER_GRAPHICS(n_bytes); + + for (i = 0; i < n_bytes; i++) + OUTC( (BYTE)line[i]); + } + + END_RASTER_GRAPHICS; + + POP_CURSOR_POSITION; /* Whew! That wasn't too bad */ + + if (n_lines >= 0) + { + NEWLINE(stderr); + (void)fprintf(stderr, + "\\special file [%s] is too short", &s[k]); + NEWLINE(stderr); + (void)fprintf(stderr,"\\special{%s} request ignored",s); + NEWLINE(stderr); + (void)fprintf(stderr,"Current TeX page counters: [%s]",tctos()); + NEWLINE(stderr); + return; + } + + (void)fclose(specfile); + if (!quiet) + { + (void)fprintf(stderr," [OK]"); + NEWLINE(stderr); + } + if (DISKFULL(plotfp)) + (void)fatal("special(): Output error -- disk storage probably full"); + }